Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenlicence.c
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 8 -*- 00002 rdesktop: A Remote Desktop Protocol client. 00003 RDP licensing negotiation 00004 Copyright (C) Matthew Chapman 1999-2005 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License along 00017 with this program; if not, write to the Free Software Foundation, Inc., 00018 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 #include <precomp.h> 00022 //#include <openssl/rc4.h> 00023 00024 void * 00025 ssl_rc4_info_create(void); 00026 void 00027 ssl_rc4_info_delete(void * rc4_info); 00028 void 00029 ssl_rc4_set_key(void * rc4_info, char * key, int len); 00030 void 00031 ssl_rc4_crypt(void * rc4_info, char * in_data, char * out_data, int len); 00032 int 00033 ssl_mod_exp(char* out, int out_len, char* in, int in_len, 00034 char* mod, int mod_len, char* exp, int exp_len); 00035 00036 extern char g_username[]; 00037 extern char g_hostname[]; 00038 00039 static uint8 g_licence_key[16]; 00040 static uint8 g_licence_sign_key[16]; 00041 00042 BOOL g_licence_issued = False; 00043 00044 /* Generate a session key and RC4 keys, given client and server randoms */ 00045 static void 00046 licence_generate_keys(uint8 * client_random, uint8 * server_random, uint8 * pre_master_secret) 00047 { 00048 uint8 master_secret[48]; 00049 uint8 key_block[48]; 00050 00051 /* Generate master secret and then key material */ 00052 sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A'); 00053 sec_hash_48(key_block, master_secret, server_random, client_random, 'A'); 00054 00055 /* Store first 16 bytes of session key as MAC secret */ 00056 memcpy(g_licence_sign_key, key_block, 16); 00057 00058 /* Generate RC4 key from next 16 bytes */ 00059 sec_hash_16(g_licence_key, &key_block[16], client_random, server_random); 00060 } 00061 00062 static void 00063 licence_generate_hwid(uint8 * hwid) 00064 { 00065 buf_out_uint32(hwid, 2); 00066 strncpy((char *) (hwid + 4), g_hostname, LICENCE_HWID_SIZE - 4); 00067 } 00068 00069 /* Present an existing licence to the server */ 00070 static void 00071 licence_present(uint8 * client_random, uint8 * rsa_data, 00072 uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature) 00073 { 00074 uint32 sec_flags = SEC_LICENCE_NEG; 00075 uint16 length = 00076 16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE + 00077 licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE; 00078 STREAM s; 00079 00080 s = sec_init(sec_flags, length + 4); 00081 00082 out_uint8(s, LICENCE_TAG_PRESENT); 00083 out_uint8(s, 2); /* version */ 00084 out_uint16_le(s, length); 00085 00086 out_uint32_le(s, 1); 00087 out_uint16(s, 0); 00088 out_uint16_le(s, 0x0201); 00089 00090 out_uint8p(s, client_random, SEC_RANDOM_SIZE); 00091 out_uint16(s, 0); 00092 out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); 00093 out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); 00094 out_uint8s(s, SEC_PADDING_SIZE); 00095 00096 out_uint16_le(s, 1); 00097 out_uint16_le(s, licence_size); 00098 out_uint8p(s, licence_data, licence_size); 00099 00100 out_uint16_le(s, 1); 00101 out_uint16_le(s, LICENCE_HWID_SIZE); 00102 out_uint8p(s, hwid, LICENCE_HWID_SIZE); 00103 00104 out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); 00105 00106 s_mark_end(s); 00107 sec_send(s, sec_flags); 00108 } 00109 00110 /* Send a licence request packet */ 00111 static void 00112 licence_send_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host) 00113 { 00114 uint32 sec_flags = SEC_LICENCE_NEG; 00115 uint16 userlen = strlen(user) + 1; 00116 uint16 hostlen = strlen(host) + 1; 00117 uint16 length = 128 + userlen + hostlen; 00118 STREAM s; 00119 00120 s = sec_init(sec_flags, length + 2); 00121 00122 out_uint8(s, LICENCE_TAG_REQUEST); 00123 out_uint8(s, 2); /* version */ 00124 out_uint16_le(s, length); 00125 00126 out_uint32_le(s, 1); 00127 out_uint16(s, 0); 00128 out_uint16_le(s, 0xff01); 00129 00130 out_uint8p(s, client_random, SEC_RANDOM_SIZE); 00131 out_uint16(s, 0); 00132 out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); 00133 out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); 00134 out_uint8s(s, SEC_PADDING_SIZE); 00135 00136 out_uint16_le(s, LICENCE_TAG_USER); 00137 out_uint16_le(s, userlen); 00138 out_uint8p(s, user, userlen); 00139 00140 out_uint16_le(s, LICENCE_TAG_HOST); 00141 out_uint16_le(s, hostlen); 00142 out_uint8p(s, host, hostlen); 00143 00144 s_mark_end(s); 00145 sec_send(s, sec_flags); 00146 } 00147 00148 /* Process a licence demand packet */ 00149 static void 00150 licence_process_demand(STREAM s) 00151 { 00152 uint8 null_data[SEC_MODULUS_SIZE]; 00153 uint8 *server_random; 00154 uint8 signature[LICENCE_SIGNATURE_SIZE]; 00155 uint8 hwid[LICENCE_HWID_SIZE]; 00156 uint8 *licence_data; 00157 int licence_size; 00158 void * crypt_key; 00159 00160 /* Retrieve the server random from the incoming packet */ 00161 in_uint8p(s, server_random, SEC_RANDOM_SIZE); 00162 00163 /* We currently use null client keys. This is a bit naughty but, hey, 00164 the security of licence negotiation isn't exactly paramount. */ 00165 memset(null_data, 0, sizeof(null_data)); 00166 licence_generate_keys(null_data, server_random, null_data); 00167 00168 licence_size = load_licence(&licence_data); 00169 if (licence_size > 0) 00170 { 00171 /* Generate a signature for the HWID buffer */ 00172 licence_generate_hwid(hwid); 00173 sec_sign(signature, 16, g_licence_sign_key, 16, hwid, sizeof(hwid)); 00174 00175 /* Now encrypt the HWID */ 00176 crypt_key = ssl_rc4_info_create(); 00177 ssl_rc4_set_key(crypt_key, (char *)g_licence_key, 16); 00178 ssl_rc4_crypt(crypt_key, (char *)hwid, (char *)hwid, sizeof(hwid)); 00179 ssl_rc4_info_delete(crypt_key); 00180 00181 licence_present(null_data, null_data, licence_data, licence_size, hwid, signature); 00182 xfree(licence_data); 00183 return; 00184 } 00185 00186 licence_send_request(null_data, null_data, g_username, g_hostname); 00187 } 00188 00189 /* Send an authentication response packet */ 00190 static void 00191 licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature) 00192 { 00193 uint32 sec_flags = SEC_LICENCE_NEG; 00194 uint16 length = 58; 00195 STREAM s; 00196 00197 s = sec_init(sec_flags, length + 2); 00198 00199 out_uint8(s, LICENCE_TAG_AUTHRESP); 00200 out_uint8(s, 2); /* version */ 00201 out_uint16_le(s, length); 00202 00203 out_uint16_le(s, 1); 00204 out_uint16_le(s, LICENCE_TOKEN_SIZE); 00205 out_uint8p(s, token, LICENCE_TOKEN_SIZE); 00206 00207 out_uint16_le(s, 1); 00208 out_uint16_le(s, LICENCE_HWID_SIZE); 00209 out_uint8p(s, crypt_hwid, LICENCE_HWID_SIZE); 00210 00211 out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); 00212 00213 s_mark_end(s); 00214 sec_send(s, sec_flags); 00215 } 00216 00217 /* Parse an authentication request packet */ 00218 static BOOL 00219 licence_parse_authreq(STREAM s, uint8 ** token, uint8 ** signature) 00220 { 00221 uint16 tokenlen; 00222 00223 in_uint8s(s, 6); /* unknown: f8 3d 15 00 04 f6 */ 00224 00225 in_uint16_le(s, tokenlen); 00226 if (tokenlen != LICENCE_TOKEN_SIZE) 00227 { 00228 error("token len %d\n", tokenlen); 00229 return False; 00230 } 00231 00232 in_uint8p(s, *token, tokenlen); 00233 in_uint8p(s, *signature, LICENCE_SIGNATURE_SIZE); 00234 00235 return s_check_end(s); 00236 } 00237 00238 /* Process an authentication request packet */ 00239 static void 00240 licence_process_authreq(STREAM s) 00241 { 00242 uint8 *in_token = NULL, *in_sig; 00243 uint8 out_token[LICENCE_TOKEN_SIZE], decrypt_token[LICENCE_TOKEN_SIZE]; 00244 uint8 hwid[LICENCE_HWID_SIZE], crypt_hwid[LICENCE_HWID_SIZE]; 00245 uint8 sealed_buffer[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE]; 00246 uint8 out_sig[LICENCE_SIGNATURE_SIZE]; 00247 void * crypt_key; 00248 00249 /* Parse incoming packet and save the encrypted token */ 00250 licence_parse_authreq(s, &in_token, &in_sig); 00251 memcpy(out_token, in_token, LICENCE_TOKEN_SIZE); 00252 00253 /* Decrypt the token. It should read TEST in Unicode. */ 00254 crypt_key = ssl_rc4_info_create(); 00255 ssl_rc4_set_key(crypt_key, (char *)g_licence_key, 16); 00256 ssl_rc4_crypt(crypt_key, (char *)in_token, (char *)decrypt_token, LICENCE_TOKEN_SIZE); 00257 ssl_rc4_info_delete(crypt_key); 00258 00259 /* Generate a signature for a buffer of token and HWID */ 00260 licence_generate_hwid(hwid); 00261 memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE); 00262 memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE); 00263 sec_sign(out_sig, 16, g_licence_sign_key, 16, sealed_buffer, sizeof(sealed_buffer)); 00264 00265 /* Now encrypt the HWID */ 00266 crypt_key = ssl_rc4_info_create(); 00267 ssl_rc4_set_key(crypt_key, (char *)g_licence_key, 16); 00268 ssl_rc4_crypt(crypt_key, (char *)hwid, (char *)crypt_hwid, LICENCE_HWID_SIZE); 00269 ssl_rc4_info_delete(crypt_key); 00270 00271 licence_send_authresp(out_token, crypt_hwid, out_sig); 00272 } 00273 00274 /* Process an licence issue packet */ 00275 static void 00276 licence_process_issue(STREAM s) 00277 { 00278 void * crypt_key; 00279 uint32 length; 00280 uint16 check; 00281 int i; 00282 00283 in_uint8s(s, 2); /* 3d 45 - unknown */ 00284 in_uint16_le(s, length); 00285 if (!s_check_rem(s, length)) 00286 return; 00287 00288 crypt_key = ssl_rc4_info_create(); 00289 ssl_rc4_set_key(crypt_key, (char *)g_licence_key, 16); 00290 ssl_rc4_crypt(crypt_key, (char *)s->p, (char *)s->p, length); 00291 ssl_rc4_info_delete(crypt_key); 00292 00293 in_uint16(s, check); 00294 if (check != 0) 00295 return; 00296 00297 g_licence_issued = True; 00298 00299 in_uint8s(s, 2); /* pad */ 00300 00301 /* advance to fourth string */ 00302 length = 0; 00303 for (i = 0; i < 4; i++) 00304 { 00305 in_uint8s(s, length); 00306 in_uint32_le(s, length); 00307 if (!s_check_rem(s, length)) 00308 return; 00309 } 00310 00311 g_licence_issued = True; 00312 save_licence(s->p, length); 00313 } 00314 00315 /* Process a licence packet */ 00316 void 00317 licence_process(STREAM s) 00318 { 00319 uint8 tag; 00320 00321 in_uint8(s, tag); 00322 in_uint8s(s, 3); /* version, length */ 00323 00324 switch (tag) 00325 { 00326 case LICENCE_TAG_DEMAND: 00327 licence_process_demand(s); 00328 break; 00329 00330 case LICENCE_TAG_AUTHREQ: 00331 licence_process_authreq(s); 00332 break; 00333 00334 case LICENCE_TAG_ISSUE: 00335 licence_process_issue(s); 00336 break; 00337 00338 case LICENCE_TAG_REISSUE: 00339 case LICENCE_TAG_RESULT: 00340 break; 00341 00342 default: 00343 unimpl("licence tag 0x%x\n", tag); 00344 } 00345 } Generated on Sun May 27 2012 04:17:10 for ReactOS by
1.7.6.1
|