Modified MSVC intern projectfiles - XCOPY doesn't need the /E option.
[blender.git] / intern / keymaker / key.c
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
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, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31
32 /* ex:ts=4 */
33
34 /**
35  * $Id$
36  * Copyright (C) 2001 NaN Technologies B.V.
37  * Blender Key loader library
38  */
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43
44 #ifdef HAVE_CONFIG_H
45 #include <config.h>
46 #endif
47
48 #include "blenkey.h"    /* external interface */
49 #include "key_internal.h"
50
51 char *Hexify(byte *in, unsigned int length) {
52         unsigned int i;
53         char Tstring[3];
54         char *out = malloc((2*length + 1) * sizeof(char));
55         sprintf(out, "%02X", in[0]);
56         for (i=1; i<length; i++) {
57                 sprintf(Tstring, "%02X", in[i]);
58                 strcat(out, Tstring);
59         }
60         return (out);
61 }
62
63 byte *DeHexify(char *in) {
64         size_t len = strlen(in);
65         byte *out = malloc((len/2) * sizeof(byte));
66         unsigned int hexedbyte;
67         unsigned int i;
68         char *inp = in;
69         byte *outp = out;
70         for (i=0; i<(len/2); i++) {
71                 sscanf(inp, "%2x", &hexedbyte);
72                 inp += 2;
73                 *outp = (byte) hexedbyte;
74                 outp++;
75         }
76         /* printf("\nlen=%d, string=[%s]\n", len, Hexify(out, len/2)); */
77         return (out);
78 }
79
80 int from_hex(char c) {
81         return (c<'A') ? (c-'0') : (c-'A'+10);
82 }
83
84 /* 5 ReadHex helper functions ------------------------------------------
85  read one Hex byte (two characters) and skip newlines if necessary */
86 byte ReadHexByteFp(FILE *fh, int *newlinetracker) {
87         unsigned char a;
88         unsigned char a1, a2;
89         /* read 2 bytes hexcode of ascii data type */
90         fread(&a1, 1, 1, fh);
91         fread(&a2, 1, 1, fh);
92         a = 16 * (from_hex(a1)) + (from_hex(a2));
93         /*printf("Char[%d] = %02X\n", *newlinetracker, a); */
94         *newlinetracker += 2;
95         /* skip the newlines */
96         if (*newlinetracker == 72) {
97                 fseek(fh, 1, SEEK_CUR);
98                 *newlinetracker = 0;
99                 /*printf("LastChar = %02X\n", a); */
100         }
101         return((byte) a);
102 }
103 byte ReadHexByteCp(char **from) {
104         int a;
105         /* read 2 bytes hexcode of ascii data type */
106         sscanf(*from, "%2x", &a);
107         /*printf("Char = %02X\n", a); */
108         *from += 2;
109         return((byte) a);
110 }
111 /* Generic hex2int */
112 int HexToInt(int a) {
113         if (a == 0x20) /* space, count as 0 ;-) */
114                 return 0;
115         else
116                 return(a - '0');
117 }
118 /* Note: this is only to be used for the header type */
119 int HexToIntFp(FILE *fh, int *newlinetracker) {
120         byte a = ReadHexByteFp(fh, newlinetracker);
121         if (DEBUG) printf("%02X = %d\n", a, a); /* note: no HexToInt here */
122         return(a);
123 }
124 int HexToIntCp(char **from) {
125         byte a = ReadHexByteCp(from);
126         if (DEBUG) printf("%02X = %d\n", a, a); /* note: no HexToInt here */
127         return(a);
128 }
129 /* Note: this is only to be used for the header length */
130 int Hex5ToInt(byte a, byte b, byte c, byte d, byte e) {
131         return(HexToInt((int) a) * 10000 +
132                    HexToInt((int) b) * 1000 +
133                    HexToInt((int) c) * 100 +
134                    HexToInt((int) d) * 10 +
135                    HexToInt((int) e));
136 }
137 /* Note: this is only to be used for the header length */
138 int Hex5ToIntFp(FILE *fh, int *newlinetracker) {
139         byte a = ReadHexByteFp(fh, newlinetracker),
140                  b = ReadHexByteFp(fh, newlinetracker),
141                  c = ReadHexByteFp(fh, newlinetracker),
142                  d = ReadHexByteFp(fh, newlinetracker),
143                  e = ReadHexByteFp(fh, newlinetracker);
144         if (DEBUG) printf("\n%02X%02X%02X%02X%02X = %d\n", a, b, c, d, e,
145                 Hex5ToInt(a, b, c, d, e));
146         return(Hex5ToInt(a, b, c, d, e));
147 }
148 int Hex5ToIntCp(char **from) {
149         byte a = ReadHexByteCp(from),
150                  b = ReadHexByteCp(from),
151                  c = ReadHexByteCp(from),
152                  d = ReadHexByteCp(from),
153                  e = ReadHexByteCp(from);
154         if (DEBUG) printf("\n%02X%02X%02X%02X%02X = %d\n", a, b, c, d, e,
155                 Hex5ToInt(a, b, c, d, e));
156         return(Hex5ToInt(a, b, c, d, e));
157 }
158 /* --------------------------------------------------------------------- */
159
160 /* return the biggest */
161 byte checkfunc0(byte a, byte b) {
162         if (a > b) return a;
163         else return b;
164 }
165 /* return |a-b| */
166 byte checkfunc1(byte a, byte b) {
167         if (a > b) return a - b;
168         else return b - a;
169 }
170 /* return the sum mod 256 */
171 byte checkfunc2(byte a, byte b) {
172         return ((a + b) % 256);
173 }
174 /* return the multiplication mod 256 */
175 byte checkfunc3(byte a, byte b) {
176         return ((a * b) % 256);
177 }
178 /* return a/b or 0 */
179 byte checkfunc4(byte a, byte b) {
180         if (b != 0) return (a / b);
181         else return 0;
182 }
183
184 char *scan_ascii(FILE *fh, UserStruct *User) {
185         long ascii_size;
186         char *ascii_data = NULL;
187         char *mdhex = NULL;
188         byte md[RIPEMD160_DIGEST_LENGTH];
189         char string[1024];
190         char dosnewlines = 0;
191         int lines = 0;
192         int oldftell;
193
194         /* NOTE: fscanf is notorious for its buffer overflows. This must be
195          fixed some day, consider this a proof-of-concept version. */
196
197         fscanf(fh, "%1000[^\n]", string);
198         sscanf(string, "%*s %s %s %lu %d %d %d",
199                    User->email,
200                    User->shopid,
201                    &User->reldate,
202                    &User->keytype,
203                    &User->keylevel,
204                    &User->keyformat);
205
206         if (User->keyformat <= BLENKEYFORMAT) {
207                 if (DEBUG) printf(
208                         "Email:[%s] ShopID:[%s] RelDate:[%lu] KeyType[%d] KeyLevel[%d]\n",
209                         User->email, User->shopid, User->reldate, User->keytype,
210                         User->keylevel);
211
212                 /* read /n/n
213                  check if we're reading dow newlines...
214                 */
215                 oldftell = ftell(fh);
216                 getc(fh);
217                 if ((ftell(fh) - oldftell) == 2) {
218                         /* yes ! */
219                         dosnewlines = 1;
220                 }
221                 getc(fh);
222
223                 fscanf(fh, "%1000[^\n]", string);
224                 strncpy(User->name, string, sizeof(User->name) - 1);
225
226                 if (DEBUG) printf("Name:[%s]\n", User->name);
227
228                 getc(fh);
229
230                 /* 4 lines read uptil now... */
231                 lines = 4;
232
233                 while (getc(fh) != EOF) {
234                         fscanf(fh, "%1000[^\n]", string);
235                         lines++;
236                         /* if (DEBUG) printf("%s\n", string); */
237                         if (strcmp(string, BLENKEYSEPERATOR) == 0) {
238                                 getc(fh);
239                                 break;
240                         }
241                 }
242         
243                 /* fh now points at the start of the datablock */
244                 ascii_size = ftell(fh);
245
246                 if (dosnewlines) {
247                         /* if we were reading on dos
248                          ftell will also count the ^M 's in the file; 
249                          substract them
250                         */
251                         ascii_size -= lines;
252                 }
253
254                 ascii_data = malloc((ascii_size+1) * sizeof(char));
255                 fseek(fh, 0, SEEK_SET);
256                 fread(ascii_data, sizeof(char), ascii_size, fh);
257                 ascii_data[ascii_size] = '\0';
258
259                 if (DEBUG)
260                         printf("asciiblock is %ld bytes long:\n[%s]\n", ascii_size, ascii_data);
261
262                 /* calculate the hash checksum */
263                 RIPEMD160(ascii_data, ascii_size, md);
264                 free(ascii_data);
265                 mdhex = Hexify(md, RIPEMD160_DIGEST_LENGTH);
266         }
267
268         return(mdhex);
269 }
270
271 char *ReadHexCryptedData(FILE *fh, int *newlinetracker) {
272         int HexCryptedDataLength = Hex5ToIntFp(fh, newlinetracker);
273         int DataType = HexToIntFp(fh, newlinetracker);
274         char *HexCryptedData = malloc((HexCryptedDataLength+1) * sizeof(char));
275         int i;
276
277         if (DataType != 1) {
278                 /* printf("Error: unexpected datatype for HexCryptedData\n"); */
279                 free(HexCryptedData);
280                 HexCryptedData = 0;
281         } else {
282                 for (i=0; i<(HexCryptedDataLength/2); i++) {
283                         sprintf(HexCryptedData+2*i, "%02X", ReadHexByteFp(fh, newlinetracker));
284                 }
285         }
286
287         return(HexCryptedData);
288 }
289
290 char *ReadHexCryptedKey(FILE *fh, int *newlinetracker) {
291         int HexCryptedKeyLength = Hex5ToIntFp(fh, newlinetracker);
292         int DataType = HexToIntFp(fh, newlinetracker);
293         char *HexCryptedKey = malloc((HexCryptedKeyLength+1) * sizeof(char));
294         int i;
295
296         if (DataType != 2) {
297                 /* printf("Error: unexpected datatype for HexCryptedKey\n"); */
298                 free(HexCryptedKey);
299                 HexCryptedKey = 0;
300         } else {
301                 for (i=0; i<(HexCryptedKeyLength/2); i++) {
302                         sprintf(HexCryptedKey+2*i, "%02X", ReadHexByteFp(fh, newlinetracker));
303                 }
304         }
305
306         return(HexCryptedKey);
307 }
308
309 /* NOTE: CHANGE THIS INTO A KEY OF OUR OWN */
310 void LoadRSApubKey(RSA *Pub) {
311     static unsigned char n[] =
312 "\xD1\x12\x0C\x6A\x34\x0A\xCF\x4C\x6B\x34\xA9\x3C\xDD\x1A\x2A\x68"
313 "\x34\xE5\xB4\xA2\x08\xE8\x9F\xCE\x76\xEF\x4B\x92\x9B\x99\xB4\x57"
314 "\x72\x95\x78\x1D\x9E\x21\x1B\xF9\x5C\x1B\x0E\xC9\xD0\x89\x75\x28"
315 "\x08\x13\x6A\xD8\xA9\xC2\xA4\x31\x91\x53\x5A\xB9\x26\x71\x8C\x05";
316     static unsigned char e[] =
317 "\x01\x00\x01";
318 /*
319         static unsigned char e[] = "\x11";
320     static unsigned char n[] =
321 "\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
322 "\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
323 "\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
324 "\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
325 "\xF5";
326 */
327
328         Pub->e = BN_bin2bn(e, sizeof(e)-1, Pub->e);
329         Pub->n = BN_bin2bn(n, sizeof(n)-1, Pub->n);
330 }
331
332 byte *RSADecryptKey(char *HexCryptedKey) {
333         byte *CryptedKey = NULL;
334         byte *Key = NULL;
335         int KeyLen;
336         int CryptedKeyLen = strlen(HexCryptedKey)/2;
337         RSA *Pub = NULL;
338
339         /* Load RSA public key */
340         Pub = RSA_new();
341         if (Pub == NULL) {
342                 /* printf("Error in RSA_new\n"); */
343         } else {
344                 LoadRSApubKey(Pub);
345
346                 Key = malloc(RSA_size(Pub) * sizeof(byte));
347
348                 CryptedKey = DeHexify(HexCryptedKey);
349
350                 KeyLen = RSA_public_decrypt(CryptedKeyLen, CryptedKey, Key, Pub,
351                                                                         RSA_PKCS1_PADDING);
352                 if (DEBUG)
353                         printf("CryptedKeyLen = %d, KeyLen = %d\n", CryptedKeyLen, KeyLen);
354                 if (KeyLen == -1) {
355 #ifndef NDEBUG
356                         printf("Error in RSA_public_decrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
357 #endif
358                         free(Key);
359                         Key = NULL;
360                 }
361         }
362
363         return (Key);
364 }
365
366 char *DeCryptDatablock(byte *CryptKey, int keylen, char *HexCryptedData) {
367         RC4_KEY key;
368         byte *CryptedData = DeHexify(HexCryptedData);
369         unsigned int datalen = strlen(HexCryptedData)/2;
370         char *KeyDataString = malloc(datalen * sizeof(char));
371
372         RC4_set_key(&key, keylen, CryptKey);
373         RC4(&key, datalen,  CryptedData, KeyDataString);
374         free(CryptedData);
375
376         return(KeyDataString);
377 }
378
379 char *get_from_datablock(char **DataPtr, char *TypeString) {
380         int tstringsize = Hex5ToIntCp(DataPtr);
381         int tstringtype = HexToIntCp(DataPtr);
382         char *HexString = NULL;
383
384         if (atoi(TypeString) != tstringtype) {
385                 /* printf("Unexpected type %d, expected %s\n", tstringtype, TypeString); */
386         } else {
387                 HexString = malloc((tstringsize+1) * sizeof(char));
388
389                 strncpy(HexString, *DataPtr, tstringsize);
390                 *DataPtr += tstringsize;
391                 HexString[tstringsize] = '\0';
392         }
393
394         return(HexString);      
395 }
396
397 int ReadKeyFile(char *filename, UserStruct *User,
398                                 char **Priv, char **Pub, byte **Byte, char **Python) {
399         FILE *rawkeyfile;
400         char *HexAsciiHash = NULL, *HexCryptedData = NULL, *HexCryptedKey =
401                 NULL;
402         int newlinetracker = 0; /* line position, counts from 0-71 */
403         byte *CryptKey = NULL;
404         char *KeyDataString = NULL;
405         char *KeyDataPtr = NULL;
406         char *HexByte = NULL;
407         char *mdhex = NULL;
408         int ret_val = 1;
409
410         if ((rawkeyfile = fopen(filename, "rb")) == NULL) {
411                 /* printf("error, cannot read %s\n", filename); */
412         } else {
413                 /* Scan and interpret the ASCII part */
414                 HexAsciiHash = scan_ascii(rawkeyfile, User);
415                 if (DEBUG) printf("\nHexHash: %s\n", HexAsciiHash);
416
417                 /* Read the HexCryptedData */
418                 HexCryptedData = ReadHexCryptedData(rawkeyfile, &newlinetracker);
419                 if (DEBUG) printf("\nHexCryptedData: %s\n", HexCryptedData);
420
421                 /* Read the HexCryptedKey */
422                 HexCryptedKey = ReadHexCryptedKey(rawkeyfile, &newlinetracker);
423                 if (DEBUG) printf("\nHexCryptedKey: %s\n", HexCryptedKey);
424
425                 /* close keyfile */
426                 fclose(rawkeyfile);
427
428                 if (HexAsciiHash && HexCryptedKey && HexCryptedData) {
429                         /* Decrypt HexCryptedKey */
430                         CryptKey = RSADecryptKey(HexCryptedKey);
431
432                         if (CryptKey) {
433                                 /* Decrypt HexCryptedData */
434                                 KeyDataString = DeCryptDatablock(CryptKey, 16, HexCryptedData);
435                                 free(CryptKey);
436                                 CryptKey = NULL;
437
438                                 if (KeyDataString) {
439                                         if (DEBUG) printf("\nKeyDataString: %s\n", KeyDataString);
440
441                                         /* Extract data from KeyDataString */
442                                         KeyDataPtr = KeyDataString;
443                                         mdhex   = get_from_datablock(&KeyDataPtr, "01");
444                                         *Priv   = get_from_datablock(&KeyDataPtr, "02");
445                                         *Pub    = get_from_datablock(&KeyDataPtr, "03");
446                                         HexByte = get_from_datablock(&KeyDataPtr, "04");
447                                         if (HexByte) {
448                                                 *Byte = DeHexify(HexByte);
449                                                 free(HexByte);
450                                                 HexByte = NULL;
451
452                                                 *Python = get_from_datablock(&KeyDataPtr, "05");
453
454                                                 /* Check ascii hash */
455                                                 if (strcmp(mdhex, HexAsciiHash) != 0) {
456                                                         /* printf("Ascii part checksums do not match !\n");
457                                                          printf("found: %s\n", mdhex);
458                                                          printf("check: %s\n", HexAsciiHash);
459                                                         */
460                                                         ret_val = 2;
461                                                 } else {
462                                                         if (DEBUG) printf("\nThe ascii part checksum matches\n");
463                                                         /* everything ok ! */
464                                                         ret_val = 0;
465                                                 }
466                                                 free(mdhex);
467                                                 mdhex = NULL;
468                                         }
469
470                                         free(KeyDataString);
471                                         KeyDataString = NULL;
472                                 }
473                         }
474                 }
475
476                 /* cleanup */
477
478                 if (HexAsciiHash) {
479                         free(HexAsciiHash);
480                         HexAsciiHash = NULL;
481                 }
482
483                 if (HexCryptedKey) {
484                         free(HexCryptedKey);
485                         HexCryptedKey = NULL;
486                 }
487
488                 if (HexCryptedData) {
489                         free(HexCryptedData);
490                         HexCryptedData = NULL;
491                 }
492         }
493
494         return (ret_val);
495 }
496