/[rdesktop]/sourceforge.net/trunk/rdesktop/ssl.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /sourceforge.net/trunk/rdesktop/ssl.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1468 - (show annotations)
Sat Apr 5 07:37:02 2008 UTC (16 years ago) by matthewc
File MIME type: text/plain
File size: 5133 byte(s)
Fix for Windows 2008 Server (see Patch #1744033)

1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Secure sockets abstraction layer
4 Copyright (C) Matthew Chapman 1999-2007
5 Copyright (C) Jay Sorg 2006-2007
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "rdesktop.h"
23 #include "ssl.h"
24
25 void
26 ssl_sha1_init(SSL_SHA1 * sha1)
27 {
28 SHA1_Init(sha1);
29 }
30
31 void
32 ssl_sha1_update(SSL_SHA1 * sha1, uint8 * data, uint32 len)
33 {
34 SHA1_Update(sha1, data, len);
35 }
36
37 void
38 ssl_sha1_final(SSL_SHA1 * sha1, uint8 * out_data)
39 {
40 SHA1_Final(out_data, sha1);
41 }
42
43 void
44 ssl_md5_init(SSL_MD5 * md5)
45 {
46 MD5_Init(md5);
47 }
48
49 void
50 ssl_md5_update(SSL_MD5 * md5, uint8 * data, uint32 len)
51 {
52 MD5_Update(md5, data, len);
53 }
54
55 void
56 ssl_md5_final(SSL_MD5 * md5, uint8 * out_data)
57 {
58 MD5_Final(out_data, md5);
59 }
60
61 void
62 ssl_rc4_set_key(SSL_RC4 * rc4, uint8 * key, uint32 len)
63 {
64 RC4_set_key(rc4, len, key);
65 }
66
67 void
68 ssl_rc4_crypt(SSL_RC4 * rc4, uint8 * in_data, uint8 * out_data, uint32 len)
69 {
70 RC4(rc4, len, in_data, out_data);
71 }
72
73 static void
74 reverse(uint8 * p, int len)
75 {
76 int i, j;
77 uint8 temp;
78
79 for (i = 0, j = len - 1; i < j; i++, j--)
80 {
81 temp = p[i];
82 p[i] = p[j];
83 p[j] = temp;
84 }
85 }
86
87 void
88 ssl_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
89 uint8 * exponent)
90 {
91 BN_CTX *ctx;
92 BIGNUM mod, exp, x, y;
93 uint8 inr[SEC_MAX_MODULUS_SIZE];
94 int outlen;
95
96 reverse(modulus, modulus_size);
97 reverse(exponent, SEC_EXPONENT_SIZE);
98 memcpy(inr, in, len);
99 reverse(inr, len);
100
101 ctx = BN_CTX_new();
102 BN_init(&mod);
103 BN_init(&exp);
104 BN_init(&x);
105 BN_init(&y);
106
107 BN_bin2bn(modulus, modulus_size, &mod);
108 BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
109 BN_bin2bn(inr, len, &x);
110 BN_mod_exp(&y, &x, &exp, &mod, ctx);
111 outlen = BN_bn2bin(&y, out);
112 reverse(out, outlen);
113 if (outlen < (int) modulus_size)
114 memset(out + outlen, 0, modulus_size - outlen);
115
116 BN_free(&y);
117 BN_clear_free(&x);
118 BN_free(&exp);
119 BN_free(&mod);
120 BN_CTX_free(ctx);
121 }
122
123 /* returns newly allocated SSL_CERT or NULL */
124 SSL_CERT *
125 ssl_cert_read(uint8 * data, uint32 len)
126 {
127 /* this will move the data pointer but we don't care, we don't use it again */
128 return d2i_X509(NULL, (D2I_X509_CONST unsigned char **) &data, len);
129 }
130
131 void
132 ssl_cert_free(SSL_CERT * cert)
133 {
134 X509_free(cert);
135 }
136
137 /* returns newly allocated SSL_RKEY or NULL */
138 SSL_RKEY *
139 ssl_cert_to_rkey(SSL_CERT * cert, uint32 * key_len)
140 {
141 EVP_PKEY *epk = NULL;
142 SSL_RKEY *lkey;
143 int nid;
144
145 /* By some reason, Microsoft sets the OID of the Public RSA key to
146 the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
147
148 Kudos to Richard Levitte for the following (. intiutive .)
149 lines of code that resets the OID and let's us extract the key. */
150 nid = OBJ_obj2nid(cert->cert_info->key->algor->algorithm);
151 if ((nid == NID_md5WithRSAEncryption) || (nid == NID_shaWithRSAEncryption))
152 {
153 DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
154 ASN1_OBJECT_free(cert->cert_info->key->algor->algorithm);
155 cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
156 }
157 epk = X509_get_pubkey(cert);
158 if (NULL == epk)
159 {
160 error("Failed to extract public key from certificate\n");
161 return NULL;
162 }
163
164 lkey = RSAPublicKey_dup((RSA *) epk->pkey.ptr);
165 EVP_PKEY_free(epk);
166 *key_len = RSA_size(lkey);
167 return lkey;
168 }
169
170 /* returns boolean */
171 RD_BOOL
172 ssl_certs_ok(SSL_CERT * server_cert, SSL_CERT * cacert)
173 {
174 /* Currently, we don't use the CA Certificate.
175 FIXME:
176 *) Verify the server certificate (server_cert) with the
177 CA certificate.
178 *) Store the CA Certificate with the hostname of the
179 server we are connecting to as key, and compare it
180 when we connect the next time, in order to prevent
181 MITM-attacks.
182 */
183 return True;
184 }
185
186 int
187 ssl_cert_print_fp(FILE * fp, SSL_CERT * cert)
188 {
189 return X509_print_fp(fp, cert);
190 }
191
192 void
193 ssl_rkey_free(SSL_RKEY * rkey)
194 {
195 RSA_free(rkey);
196 }
197
198 /* returns error */
199 int
200 ssl_rkey_get_exp_mod(SSL_RKEY * rkey, uint8 * exponent, uint32 max_exp_len, uint8 * modulus,
201 uint32 max_mod_len)
202 {
203 int len;
204
205 if ((BN_num_bytes(rkey->e) > (int) max_exp_len) ||
206 (BN_num_bytes(rkey->n) > (int) max_mod_len))
207 {
208 return 1;
209 }
210 len = BN_bn2bin(rkey->e, exponent);
211 reverse(exponent, len);
212 len = BN_bn2bin(rkey->n, modulus);
213 reverse(modulus, len);
214 return 0;
215 }
216
217 /* returns boolean */
218 RD_BOOL
219 ssl_sig_ok(uint8 * exponent, uint32 exp_len, uint8 * modulus, uint32 mod_len,
220 uint8 * signature, uint32 sig_len)
221 {
222 /* Currently, we don't check the signature
223 FIXME:
224 */
225 return True;
226 }

  ViewVC Help
Powered by ViewVC 1.1.26