VirtualBox

source: vbox/trunk/src/VBox/RDP/client-1.8.4/ssl.c@ 78048

Last change on this file since 78048 was 76779, checked in by vboxsync, 6 years ago

RDP: add client-1.8.4.
bugref:9356: Update rdesktop-vrdp to 1.8.4
client-1.8.4 is a Subversion copy of 1.8.3 with the upstream 1.8.3 to 1.8.4
patch applied and a couple of fixes and changes after review, namely:

  • Stopped disabling the new pointer data format for our build, as this is no

longer needed.

  • Adjusted some snprintf buffers to make GCC happy.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.1 KB
Line 
1/* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Secure sockets abstraction layer
4 Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
5 Copyright (C) Jay Sorg <j@american-data.com> 2006-2008
6 Copyright (C) Henrik Andersson <hean01@cendio.com> 2016
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22/*
23 * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
24 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
25 * the General Public License version 2 (GPLv2) at this time for any software where
26 * a choice of GPL license versions is made available with the language indicating
27 * that GPLv2 or any later version may be used, or where a choice of which version
28 * of the GPL is applied is otherwise unspecified.
29 */
30
31#include "rdesktop.h"
32#include "ssl.h"
33
34void
35rdssl_sha1_init(RDSSL_SHA1 * sha1)
36{
37 SHA1_Init(sha1);
38}
39
40void
41rdssl_sha1_update(RDSSL_SHA1 * sha1, uint8 * data, uint32 len)
42{
43 SHA1_Update(sha1, data, len);
44}
45
46void
47rdssl_sha1_final(RDSSL_SHA1 * sha1, uint8 * out_data)
48{
49 SHA1_Final(out_data, sha1);
50}
51
52void
53rdssl_md5_init(RDSSL_MD5 * md5)
54{
55 MD5_Init(md5);
56}
57
58void
59rdssl_md5_update(RDSSL_MD5 * md5, uint8 * data, uint32 len)
60{
61 MD5_Update(md5, data, len);
62}
63
64void
65rdssl_md5_final(RDSSL_MD5 * md5, uint8 * out_data)
66{
67 MD5_Final(out_data, md5);
68}
69
70void
71rdssl_rc4_set_key(RDSSL_RC4 * rc4, uint8 * key, uint32 len)
72{
73 RC4_set_key(rc4, len, key);
74}
75
76void
77rdssl_rc4_crypt(RDSSL_RC4 * rc4, uint8 * in_data, uint8 * out_data, uint32 len)
78{
79 RC4(rc4, len, in_data, out_data);
80}
81
82static void
83reverse(uint8 * p, int len)
84{
85 int i, j;
86 uint8 temp;
87
88 for (i = 0, j = len - 1; i < j; i++, j--)
89 {
90 temp = p[i];
91 p[i] = p[j];
92 p[j] = temp;
93 }
94}
95
96void
97rdssl_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
98 uint8 * exponent)
99{
100#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
101 BN_CTX *ctx;
102 BIGNUM *mod, *exp, *x, *y;
103 uint8 inr[SEC_MAX_MODULUS_SIZE];
104 int outlen;
105
106 reverse(modulus, modulus_size);
107 reverse(exponent, SEC_EXPONENT_SIZE);
108 memcpy(inr, in, len);
109 reverse(inr, len);
110
111 ctx = BN_CTX_new();
112 mod = BN_new();
113 exp = BN_new();
114 x = BN_new();
115 y = BN_new();
116
117 BN_bin2bn(modulus, modulus_size, mod);
118 BN_bin2bn(exponent, SEC_EXPONENT_SIZE, exp);
119 BN_bin2bn(inr, len, x);
120 BN_mod_exp(y, x, exp, mod, ctx);
121 outlen = BN_bn2bin(y, out);
122 reverse(out, outlen);
123 if (outlen < (int) modulus_size)
124 memset(out + outlen, 0, modulus_size - outlen);
125
126 BN_free(y);
127 BN_clear_free(x);
128 BN_free(exp);
129 BN_free(mod);
130 BN_CTX_free(ctx);
131#else /* OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER) */
132 BN_CTX *ctx;
133 BIGNUM mod, exp, x, y;
134 uint8 inr[SEC_MAX_MODULUS_SIZE];
135 int outlen;
136
137 reverse(modulus, modulus_size);
138 reverse(exponent, SEC_EXPONENT_SIZE);
139 memcpy(inr, in, len);
140 reverse(inr, len);
141
142 ctx = BN_CTX_new();
143 BN_init(&mod);
144 BN_init(&exp);
145 BN_init(&x);
146 BN_init(&y);
147
148 BN_bin2bn(modulus, modulus_size, &mod);
149 BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
150 BN_bin2bn(inr, len, &x);
151 BN_mod_exp(&y, &x, &exp, &mod, ctx);
152 outlen = BN_bn2bin(&y, out);
153 reverse(out, outlen);
154 if (outlen < (int) modulus_size)
155 memset(out + outlen, 0, modulus_size - outlen);
156
157 BN_free(&y);
158 BN_clear_free(&x);
159 BN_free(&exp);
160 BN_free(&mod);
161 BN_CTX_free(ctx);
162#endif /* OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER) */
163}
164
165/* returns newly allocated RDSSL_CERT or NULL */
166RDSSL_CERT *
167rdssl_cert_read(uint8 * data, uint32 len)
168{
169 /* this will move the data pointer but we don't care, we don't use it again */
170 return d2i_X509(NULL, (D2I_X509_CONST unsigned char **) &data, len);
171}
172
173void
174rdssl_cert_free(RDSSL_CERT * cert)
175{
176 X509_free(cert);
177}
178
179/* returns newly allocated RDSSL_RKEY or NULL */
180RDSSL_RKEY *
181rdssl_cert_to_rkey(RDSSL_CERT * cert, uint32 * key_len)
182{
183 EVP_PKEY *epk = NULL;
184 RDSSL_RKEY *lkey;
185 int nid;
186#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
187 int ret;
188
189 /* By some reason, Microsoft sets the OID of the Public RSA key to
190 the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
191
192 Kudos to Richard Levitte for the following (. intiutive .)
193 lines of code that resets the OID and let's us extract the key. */
194
195 X509_PUBKEY *key = NULL;
196 X509_ALGOR *algor = NULL;
197
198 key = X509_get_X509_PUBKEY(cert);
199 if (key == NULL)
200 {
201 error("Failed to get public key from certificate.\n");
202 return NULL;
203 }
204
205 ret = X509_PUBKEY_get0_param(NULL, NULL, 0, &algor, key);
206 if (ret != 1)
207 {
208 error("Faild to get algorithm used for public key.\n");
209 return NULL;
210 }
211
212 nid = OBJ_obj2nid(algor->algorithm);
213
214 if ((nid == NID_md5WithRSAEncryption) || (nid == NID_shaWithRSAEncryption))
215 {
216 DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
217 X509_PUBKEY_set0_param(key, OBJ_nid2obj(NID_rsaEncryption),
218 0, NULL, NULL, 0);
219 }
220#else /* OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER) */
221 nid = OBJ_obj2nid(cert->cert_info->key->algor->algorithm);
222 if ((nid == NID_md5WithRSAEncryption) || (nid == NID_shaWithRSAEncryption))
223 {
224 DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
225 ASN1_OBJECT_free(cert->cert_info->key->algor->algorithm);
226 cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
227 }
228#endif /* OPENSSL_VERSION_NUMBER < 0x10100000 || && defined(LIBRESSL_VERSION_NUMBER) */
229 epk = X509_get_pubkey(cert);
230 if (NULL == epk)
231 {
232 error("Failed to extract public key from certificate\n");
233 return NULL;
234 }
235
236 lkey = RSAPublicKey_dup(EVP_PKEY_get1_RSA(epk));
237 EVP_PKEY_free(epk);
238 *key_len = RSA_size(lkey);
239 return lkey;
240}
241
242/* returns boolean */
243RD_BOOL
244rdssl_certs_ok(RDSSL_CERT * server_cert, RDSSL_CERT * cacert)
245{
246 /* Currently, we don't use the CA Certificate.
247 FIXME:
248 *) Verify the server certificate (server_cert) with the
249 CA certificate.
250 *) Store the CA Certificate with the hostname of the
251 server we are connecting to as key, and compare it
252 when we connect the next time, in order to prevent
253 MITM-attacks.
254 */
255 return True;
256}
257
258int
259rdssl_cert_print_fp(FILE * fp, RDSSL_CERT * cert)
260{
261 return X509_print_fp(fp, cert);
262}
263
264void
265rdssl_rkey_free(RDSSL_RKEY * rkey)
266{
267 RSA_free(rkey);
268}
269
270/* returns error */
271int
272rdssl_rkey_get_exp_mod(RDSSL_RKEY * rkey, uint8 * exponent, uint32 max_exp_len, uint8 * modulus,
273 uint32 max_mod_len)
274{
275 int len;
276
277#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
278 const BIGNUM *e, *n;
279 RSA_get0_key(rkey, &n, &e, NULL);
280 if ((BN_num_bytes(e) > (int) max_exp_len) ||
281 (BN_num_bytes(n) > (int) max_mod_len))
282 {
283 return 1;
284 }
285 len = BN_bn2bin(e, exponent);
286 reverse(exponent, len);
287 len = BN_bn2bin(n, modulus);
288 reverse(modulus, len);
289#else
290 if ((BN_num_bytes(rkey->e) > (int) max_exp_len) ||
291 (BN_num_bytes(rkey->n) > (int) max_mod_len))
292 {
293 return 1;
294 }
295 len = BN_bn2bin(rkey->e, exponent);
296 reverse(exponent, len);
297 len = BN_bn2bin(rkey->n, modulus);
298 reverse(modulus, len);
299#endif
300 return 0;
301}
302
303/* returns boolean */
304RD_BOOL
305rdssl_sig_ok(uint8 * exponent, uint32 exp_len, uint8 * modulus, uint32 mod_len,
306 uint8 * signature, uint32 sig_len)
307{
308 /* Currently, we don't check the signature
309 FIXME:
310 */
311 return True;
312}
313
314
315void
316rdssl_hmac_md5(const void *key, int key_len, const unsigned char *msg, int msg_len,
317 unsigned char *md)
318{
319#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
320 HMAC_CTX ctx;
321 HMAC_CTX_init(&ctx);
322#endif
323 HMAC(EVP_md5(), key, key_len, msg, msg_len, md, NULL);
324#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
325 HMAC_CTX_cleanup(&ctx);
326#endif
327}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette