resolved conflict state with HEAD r14096
[blender.git] / source / blender / verify / intern / BLO_verify.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  * openssl verify wrapper library
32  */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include "openssl/rsa.h"
39 #include "openssl/ripemd.h"
40 #include "openssl/objects.h"
41 #include "zlib.h"
42
43 #include "GEN_messaging.h"
44
45 #include "BLO_readStreamGlue.h"
46 #include "BLO_verify.h"
47 #include "BLO_sign_verify_Header.h"     /* used by verify and encrypt */
48
49 #include "BLO_signer_info.h" /* external signer info struct */
50
51 #ifdef HAVE_CONFIG_H
52 #include <config.h>
53 #endif
54
55 static struct BLO_SignerInfo g_SignerInfo = {"", "", ""};
56
57 struct verifyStructType {
58         struct readStreamGlueStruct *streamGlue;
59         unsigned int streamDone;
60         unsigned char headerbuffer[SIGNVERIFYHEADERSTRUCTSIZE];
61         uint32_t datacrc;
62         struct BLO_sign_verify_HeaderStruct *streamHeader;
63         RIPEMD160_CTX ripemd160_ctx;
64         struct BLO_SignerHeaderStruct *signerHeader;
65         unsigned char signerHeaderBuffer[SIGNERHEADERSTRUCTSIZE];
66         void *endControl;
67 };
68
69         BLO_verifyStructHandle
70 BLO_verify_begin(
71         void *endControl)
72 {
73         struct verifyStructType *control;
74         control = malloc(sizeof(struct verifyStructType));
75         if (!control) return NULL;
76
77         control->streamGlue = NULL;
78         control->streamDone = 0;
79         memset(control->headerbuffer, 0, SIGNVERIFYHEADERSTRUCTSIZE);
80         control->datacrc = 0;
81
82         control->streamHeader = malloc(SIGNVERIFYHEADERSTRUCTSIZE);
83         if (!control->streamHeader) {
84                 free(control);
85                 return NULL;
86         }
87         control->streamHeader->magic = 0;
88         control->streamHeader->length = 0;
89         strcpy(control->streamHeader->pubKey, "");
90         control->streamHeader->pubKeyLen = 0;
91         strcpy(control->streamHeader->signature, "");
92         control->streamHeader->signatureLen = 0;
93         control->streamHeader->datacrc = 0;
94         control->streamHeader->headercrc = 0;
95
96         RIPEMD160_Init(&(control->ripemd160_ctx));
97
98         control->signerHeader = malloc(SIGNERHEADERSTRUCTSIZE);
99         if (!control->signerHeader) {
100                 free(control->streamHeader);
101                 free(control);
102                 return NULL;
103         }
104         memset(control->signerHeader->name,       0, MAXSIGNERLEN);
105         memset(control->signerHeader->email,      0, MAXSIGNERLEN);
106         memset(control->signerHeader->homeUrl,    0, MAXSIGNERLEN);
107         memset(control->signerHeader->text,       0, MAXSIGNERLEN);
108         memset(control->signerHeader->pubKeyUrl1, 0, MAXSIGNERLEN);
109         memset(control->signerHeader->pubKeyUrl2, 0, MAXSIGNERLEN);
110
111         control->endControl = endControl;
112         return((BLO_verifyStructHandle) control);
113 }
114
115         int
116 BLO_verify_process(
117         BLO_verifyStructHandle BLO_verifyHandle,
118         unsigned char *data,
119         unsigned int dataIn)
120 {
121         int err = 0;
122         struct verifyStructType *BLO_verify =
123                 (struct verifyStructType *) BLO_verifyHandle;
124
125         if (!BLO_verify) {
126                 err = BRS_SETFUNCTION(BRS_VERIFY) |
127                           BRS_SETGENERR(BRS_NULL);
128                 return err;
129         }
130
131         /* First check if we have our header filled in yet */
132         if (BLO_verify->streamHeader->length == 0) {
133                 unsigned int processed;
134                 if (dataIn == 0) return err;    /* really need data to do anything */
135                 processed = ((dataIn + BLO_verify->streamDone) <=
136                                          SIGNVERIFYHEADERSTRUCTSIZE)
137                                          ? dataIn : SIGNVERIFYHEADERSTRUCTSIZE;
138                 memcpy(BLO_verify->headerbuffer + BLO_verify->streamDone,
139                            data, processed);
140                 BLO_verify->streamDone += processed;
141                 dataIn -= processed;
142                 data += processed;
143                 if (BLO_verify->streamDone == SIGNVERIFYHEADERSTRUCTSIZE) {
144                         /* we have the whole header, absorb it */
145                         struct BLO_sign_verify_HeaderStruct *header;
146                         uint32_t crc;
147
148                         header = (struct BLO_sign_verify_HeaderStruct *)
149                                 BLO_verify->headerbuffer;
150                         crc = crc32(0L, (const Bytef *) header,
151                                                 SIGNVERIFYHEADERSTRUCTSIZE - 4);
152
153                         if (header->magic == 'A') {
154 #ifndef NDEBUG
155                                 fprintf(GEN_errorstream,
156                                                 "BLO_sign_verify_HeaderStruct Magic confirmed\n");
157 #endif
158                         } else {
159 #ifndef NDEBUG
160                                 fprintf(GEN_errorstream,
161                                                 "ERROR BLO_sign_verify_HeaderStruct Magic NOT confirmed\n");
162 #endif
163                                 err = BRS_SETFUNCTION(BRS_VERIFY) |
164                                           BRS_SETGENERR(BRS_MAGIC);
165                                 if (BLO_verify->streamGlue) free(BLO_verify->streamGlue);
166                                 if (BLO_verify->streamHeader) free(BLO_verify->streamHeader);
167                                 if (BLO_verify->signerHeader) free(BLO_verify->signerHeader);
168                                 free(BLO_verify);
169                                 return err;
170                         }
171
172                         if (crc == ntohl(header->headercrc)) {
173 #ifndef NDEBUG                          
174                                 fprintf(GEN_errorstream,"BLO_sign_verify_Header CRC correct\n");
175 #endif
176                         } else {
177 #ifndef NDEBUG
178                                 fprintf(GEN_errorstream,"ERROR BLO_sign_verify_Header CRC NOT correct\n");
179 #endif
180                                 err = BRS_SETFUNCTION(BRS_VERIFY) |
181                                           BRS_SETGENERR(BRS_CRCHEADER);
182                                 if (BLO_verify->streamGlue) free(BLO_verify->streamGlue);
183                                 if (BLO_verify->streamHeader) free(BLO_verify->streamHeader);
184                                 if (BLO_verify->signerHeader) free(BLO_verify->signerHeader);
185                                 free(BLO_verify);
186                                 return err;
187                         }
188                         BLO_verify->streamHeader->length = ntohl(header->length);
189                         BLO_verify->streamHeader->pubKeyLen = ntohl(header->pubKeyLen);
190                         memcpy(BLO_verify->streamHeader->pubKey, header->pubKey,
191                                    BLO_verify->streamHeader->pubKeyLen);
192                         BLO_verify->streamHeader->signatureLen =
193                                 ntohl(header->signatureLen);
194                         memcpy(BLO_verify->streamHeader->signature, header->signature,
195                                    BLO_verify->streamHeader->signatureLen);
196                         BLO_verify->streamHeader->datacrc = ntohl(header->datacrc);
197
198 #ifndef NDEBUG
199                         fprintf(GEN_errorstream,
200                                         "BLO_verify_process gets %u bytes\n",
201                                         (unsigned int) BLO_verify->streamHeader->length);
202 #endif
203
204                 }
205         }
206
207         /* Is there really (still) new data available ? */
208         if (dataIn > 0) {
209                 /* BLO_SignerHeaderStruct */
210                 if (BLO_verify->signerHeader->name[0] == 0) {
211                         /* we don't have our signerHeader complete yet */
212                         unsigned int processed;
213                         processed = ((dataIn + BLO_verify->streamDone -
214                                 SIGNVERIFYHEADERSTRUCTSIZE) <= SIGNERHEADERSTRUCTSIZE)
215                                 ? dataIn : SIGNERHEADERSTRUCTSIZE;
216                         memcpy(BLO_verify->signerHeaderBuffer +
217                                    BLO_verify->streamDone - SIGNVERIFYHEADERSTRUCTSIZE,
218                                    data, processed);
219                         BLO_verify->streamDone += processed;
220                         dataIn -= processed;
221                         data += processed;
222                         if (BLO_verify->streamDone == SIGNVERIFYHEADERSTRUCTSIZE +
223                                 SIGNERHEADERSTRUCTSIZE) {
224                                 /* we have the whole header, absorb it */
225                                 struct BLO_SignerHeaderStruct *signerHeader;
226                                 signerHeader = (struct BLO_SignerHeaderStruct *)
227                                         BLO_verify->signerHeaderBuffer;
228                                 strncpy(BLO_verify->signerHeader->name,
229                                                 signerHeader->name, MAXSIGNERLEN-1);
230                                 strncpy(BLO_verify->signerHeader->email,
231                                                 signerHeader->email, MAXSIGNERLEN-1);
232                                 strncpy(BLO_verify->signerHeader->homeUrl,
233                                            signerHeader->homeUrl, MAXSIGNERLEN-1);
234                                 strncpy(BLO_verify->signerHeader->text,
235                                                 signerHeader->text, MAXSIGNERLEN-1);
236                                 strncpy(BLO_verify->signerHeader->pubKeyUrl1,
237                                            signerHeader->pubKeyUrl1, MAXSIGNERLEN-1);
238                                 strncpy(BLO_verify->signerHeader->pubKeyUrl2,
239                                            signerHeader->pubKeyUrl2, MAXSIGNERLEN-1);
240
241 #ifndef NDEBUG
242                                 fprintf(GEN_errorstream,
243                                         "name %s\nemail %s\nhomeUrl %s\ntext %s\n",
244                                         BLO_verify->signerHeader->name,
245                                         BLO_verify->signerHeader->email,
246                                         BLO_verify->signerHeader->homeUrl,
247                                         BLO_verify->signerHeader->text);
248                                 fprintf(GEN_errorstream,
249                                         "pubKeyUrl1 %s\npubKeyUrl2 %s\n",
250                                         BLO_verify->signerHeader->pubKeyUrl1,
251                                         BLO_verify->signerHeader->pubKeyUrl2);
252 #endif
253                                 /* also update the signature and crc checksum */
254                                 RIPEMD160_Update(&(BLO_verify->ripemd160_ctx),
255                                                                  BLO_verify->signerHeaderBuffer,
256                                                                  SIGNERHEADERSTRUCTSIZE);
257
258                                 /* update datacrc */
259                                 BLO_verify->datacrc = crc32(
260                                         BLO_verify->datacrc, (const Bytef *)
261                                         BLO_verify->signerHeaderBuffer,
262                                         SIGNERHEADERSTRUCTSIZE);
263                         }
264                 }
265         }
266
267         /* Is there really (still) new data available ? */
268         if (dataIn > 0) {
269                 RIPEMD160_Update(&(BLO_verify->ripemd160_ctx), data, dataIn);
270
271                 /* update datacrc */
272                 BLO_verify->datacrc = crc32(
273                         BLO_verify->datacrc, (const Bytef *) data, dataIn);
274
275                 BLO_verify->streamDone += dataIn;
276
277                 /* give data to streamGlueRead, it will find out what to do next */
278                 err = readStreamGlue(
279                         BLO_verify->endControl,
280                         &(BLO_verify->streamGlue),
281                         (unsigned char *) data,
282                         dataIn);
283         }
284         return err;
285 }
286
287 /**
288  * openssl verify final call and cleanup
289  * @param BLO_verify Pointer to verify control structure
290  * @retval streamGlueRead return value
291  */
292         int
293 BLO_verify_end(
294         BLO_verifyStructHandle BLO_verifyHandle)
295 {
296         int err = 0;
297         unsigned char *digest;
298         static unsigned char rsa_e[] = "\x01\x00\x01";
299         RSA *rsa = NULL;
300         int verifySuccess;
301         struct verifyStructType *BLO_verify =
302                 (struct verifyStructType *) BLO_verifyHandle;
303
304         if (!BLO_verify) {
305                 err = BRS_SETFUNCTION(BRS_VERIFY) |
306                           BRS_SETGENERR(BRS_NULL);
307                 return err;
308         }
309
310         if (BLO_verify->streamDone == BLO_verify->streamHeader->length +
311                 SIGNVERIFYHEADERSTRUCTSIZE) {
312 #ifndef NDEBUG
313                 fprintf(GEN_errorstream, "Signed data length is correct\n");
314 #endif
315         } else {
316 #ifndef NDEBUG
317                 fprintf(GEN_errorstream, "Signed data length is NOT correct\n");
318 #endif
319                 err = BRS_SETFUNCTION(BRS_VERIFY) |
320                           BRS_SETGENERR(BRS_DATALEN);
321                 if (BLO_verify->streamGlue) free(BLO_verify->streamGlue);
322                 if (BLO_verify->streamHeader) free(BLO_verify->streamHeader);
323                 if (BLO_verify->signerHeader) free(BLO_verify->signerHeader);
324                 free(BLO_verify);
325                 return err;
326         }
327
328         if (BLO_verify->datacrc == BLO_verify->streamHeader->datacrc) {
329 #ifndef NDEBUG
330                 fprintf(GEN_errorstream, "Signed data CRC is correct\n");
331 #endif
332         } else {
333 #ifndef NDEBUG
334                 fprintf(GEN_errorstream, "Signed data CRC is NOT correct\n");
335 #endif
336                 err = BRS_SETFUNCTION(BRS_VERIFY) |
337                           BRS_SETGENERR(BRS_CRCDATA);
338                 if (BLO_verify->streamGlue) free(BLO_verify->streamGlue);
339                 if (BLO_verify->streamHeader) free(BLO_verify->streamHeader);
340                 if (BLO_verify->signerHeader) free(BLO_verify->signerHeader);
341                 free(BLO_verify);
342                 return err;
343         }
344
345         digest = malloc(RIPEMD160_DIGEST_LENGTH);
346         if (!digest) {
347                 err = BRS_SETFUNCTION(BRS_VERIFY) |
348                           BRS_SETGENERR(BRS_MALLOC);
349                 if (BLO_verify->streamGlue) free(BLO_verify->streamGlue);
350                 if (BLO_verify->streamHeader) free(BLO_verify->streamHeader);
351                 if (BLO_verify->signerHeader) free(BLO_verify->signerHeader);
352                 free(BLO_verify);
353                 return err;
354         }
355
356         RIPEMD160_Final(digest, &(BLO_verify->ripemd160_ctx));
357
358         rsa = RSA_new();
359         if (rsa == NULL) {
360 #ifndef NDEBUG
361                 fprintf(GEN_errorstream, "Error in RSA_new\n");
362 #endif
363                 err = BRS_SETFUNCTION(BRS_VERIFY) |
364                           BRS_SETSPECERR(BRS_RSANEWERROR);
365                 free(digest);
366                 if (BLO_verify->streamGlue) free(BLO_verify->streamGlue);
367                 if (BLO_verify->streamHeader) free(BLO_verify->streamHeader);
368                 if (BLO_verify->signerHeader) free(BLO_verify->signerHeader);
369                 free(BLO_verify);
370                 return err;
371         }
372         /* static exponent */
373         rsa->e = BN_bin2bn(rsa_e, sizeof(rsa_e)-1, rsa->e);
374
375         /* public part into rsa->n */
376         rsa->n = BN_bin2bn(BLO_verify->streamHeader->pubKey,
377                                            BLO_verify->streamHeader->pubKeyLen,
378                                            rsa->n);
379         /*DEBUG RSA_print_fp(stdout, rsa, 0); */
380
381         /* verify the signature */
382         verifySuccess = RSA_verify(NID_ripemd160, digest, RIPEMD160_DIGEST_LENGTH,
383                                BLO_verify->streamHeader->signature,
384                                    BLO_verify->streamHeader->signatureLen, rsa);
385         if (verifySuccess == 1) {
386 #ifndef NDEBUG
387                 fprintf(GEN_errorstream,
388                                 "Signature verified\n");
389 #endif
390         } else {
391 #ifndef NDEBUG
392                 fprintf(GEN_errorstream,
393                                 "Signature INCORRECT\n");
394 #endif
395                 err = BRS_SETFUNCTION(BRS_VERIFY) |
396                           BRS_SETSPECERR(BRS_SIGFAILED);
397         }
398
399 /* copy signer information to external struct  */
400         
401         strncpy(g_SignerInfo.name, BLO_verify->signerHeader->name, MAXSIGNERLEN-1);
402         strncpy(g_SignerInfo.email, BLO_verify->signerHeader->email, MAXSIGNERLEN-1);
403         strncpy(g_SignerInfo.homeUrl, BLO_verify->signerHeader->homeUrl, MAXSIGNERLEN-1);
404
405         free(digest);
406         free(BLO_verify->streamGlue);
407         free(BLO_verify->streamHeader);
408         free(BLO_verify->signerHeader);
409         free(BLO_verify);
410         RSA_free(rsa);
411
412         return err;
413 }
414
415 struct BLO_SignerInfo *BLO_getSignerInfo(){
416         return &g_SignerInfo;
417 }
418
419 int BLO_isValidSignerInfo(struct BLO_SignerInfo *info){
420         return info->name[0] != 0;
421 }
422
423 void BLO_clrSignerInfo(struct BLO_SignerInfo *info)
424 {
425         info->name[0] = 0;
426 }
427