4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
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
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.
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.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): none yet.
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
31 * openssl verify wrapper library
38 #include "openssl/rsa.h"
39 #include "openssl/ripemd.h"
40 #include "openssl/objects.h"
43 #include "GEN_messaging.h"
45 #include "BLO_readStreamGlue.h"
46 #include "BLO_verify.h"
47 #include "BLO_sign_verify_Header.h" /* used by verify and encrypt */
49 #include "BLO_signer_info.h" /* external signer info struct */
55 static struct BLO_SignerInfo g_SignerInfo = {"", "", ""};
57 struct verifyStructType {
58 struct readStreamGlueStruct *streamGlue;
59 unsigned int streamDone;
60 unsigned char headerbuffer[SIGNVERIFYHEADERSTRUCTSIZE];
62 struct BLO_sign_verify_HeaderStruct *streamHeader;
63 RIPEMD160_CTX ripemd160_ctx;
64 struct BLO_SignerHeaderStruct *signerHeader;
65 unsigned char signerHeaderBuffer[SIGNERHEADERSTRUCTSIZE];
69 BLO_verifyStructHandle
73 struct verifyStructType *control;
74 control = malloc(sizeof(struct verifyStructType));
75 if (!control) return NULL;
77 control->streamGlue = NULL;
78 control->streamDone = 0;
79 memset(control->headerbuffer, 0, SIGNVERIFYHEADERSTRUCTSIZE);
82 control->streamHeader = malloc(SIGNVERIFYHEADERSTRUCTSIZE);
83 if (!control->streamHeader) {
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;
96 RIPEMD160_Init(&(control->ripemd160_ctx));
98 control->signerHeader = malloc(SIGNERHEADERSTRUCTSIZE);
99 if (!control->signerHeader) {
100 free(control->streamHeader);
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);
111 control->endControl = endControl;
112 return((BLO_verifyStructHandle) control);
117 BLO_verifyStructHandle BLO_verifyHandle,
122 struct verifyStructType *BLO_verify =
123 (struct verifyStructType *) BLO_verifyHandle;
126 err = BRS_SETFUNCTION(BRS_VERIFY) |
127 BRS_SETGENERR(BRS_NULL);
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,
140 BLO_verify->streamDone += processed;
143 if (BLO_verify->streamDone == SIGNVERIFYHEADERSTRUCTSIZE) {
144 /* we have the whole header, absorb it */
145 struct BLO_sign_verify_HeaderStruct *header;
148 header = (struct BLO_sign_verify_HeaderStruct *)
149 BLO_verify->headerbuffer;
150 crc = crc32(0L, (const Bytef *) header,
151 SIGNVERIFYHEADERSTRUCTSIZE - 4);
153 if (header->magic == 'A') {
155 fprintf(GEN_errorstream,
156 "BLO_sign_verify_HeaderStruct Magic confirmed\n");
160 fprintf(GEN_errorstream,
161 "ERROR BLO_sign_verify_HeaderStruct Magic NOT confirmed\n");
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);
172 if (crc == ntohl(header->headercrc)) {
174 fprintf(GEN_errorstream,"BLO_sign_verify_Header CRC correct\n");
178 fprintf(GEN_errorstream,"ERROR BLO_sign_verify_Header CRC NOT correct\n");
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);
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);
199 fprintf(GEN_errorstream,
200 "BLO_verify_process gets %u bytes\n",
201 (unsigned int) BLO_verify->streamHeader->length);
207 /* Is there really (still) new data available ? */
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,
219 BLO_verify->streamDone += 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);
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);
253 /* also update the signature and crc checksum */
254 RIPEMD160_Update(&(BLO_verify->ripemd160_ctx),
255 BLO_verify->signerHeaderBuffer,
256 SIGNERHEADERSTRUCTSIZE);
259 BLO_verify->datacrc = crc32(
260 BLO_verify->datacrc, (const Bytef *)
261 BLO_verify->signerHeaderBuffer,
262 SIGNERHEADERSTRUCTSIZE);
267 /* Is there really (still) new data available ? */
269 RIPEMD160_Update(&(BLO_verify->ripemd160_ctx), data, dataIn);
272 BLO_verify->datacrc = crc32(
273 BLO_verify->datacrc, (const Bytef *) data, dataIn);
275 BLO_verify->streamDone += dataIn;
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,
288 * openssl verify final call and cleanup
289 * @param BLO_verify Pointer to verify control structure
290 * @retval streamGlueRead return value
294 BLO_verifyStructHandle BLO_verifyHandle)
297 unsigned char *digest;
298 static unsigned char rsa_e[] = "\x01\x00\x01";
301 struct verifyStructType *BLO_verify =
302 (struct verifyStructType *) BLO_verifyHandle;
305 err = BRS_SETFUNCTION(BRS_VERIFY) |
306 BRS_SETGENERR(BRS_NULL);
310 if (BLO_verify->streamDone == BLO_verify->streamHeader->length +
311 SIGNVERIFYHEADERSTRUCTSIZE) {
313 fprintf(GEN_errorstream, "Signed data length is correct\n");
317 fprintf(GEN_errorstream, "Signed data length is NOT correct\n");
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);
328 if (BLO_verify->datacrc == BLO_verify->streamHeader->datacrc) {
330 fprintf(GEN_errorstream, "Signed data CRC is correct\n");
334 fprintf(GEN_errorstream, "Signed data CRC is NOT correct\n");
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);
345 digest = malloc(RIPEMD160_DIGEST_LENGTH);
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);
356 RIPEMD160_Final(digest, &(BLO_verify->ripemd160_ctx));
361 fprintf(GEN_errorstream, "Error in RSA_new\n");
363 err = BRS_SETFUNCTION(BRS_VERIFY) |
364 BRS_SETSPECERR(BRS_RSANEWERROR);
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);
372 /* static exponent */
373 rsa->e = BN_bin2bn(rsa_e, sizeof(rsa_e)-1, rsa->e);
375 /* public part into rsa->n */
376 rsa->n = BN_bin2bn(BLO_verify->streamHeader->pubKey,
377 BLO_verify->streamHeader->pubKeyLen,
379 /*DEBUG RSA_print_fp(stdout, rsa, 0); */
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) {
387 fprintf(GEN_errorstream,
388 "Signature verified\n");
392 fprintf(GEN_errorstream,
393 "Signature INCORRECT\n");
395 err = BRS_SETFUNCTION(BRS_VERIFY) |
396 BRS_SETSPECERR(BRS_SIGFAILED);
399 /* copy signer information to external struct */
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);
406 free(BLO_verify->streamGlue);
407 free(BLO_verify->streamHeader);
408 free(BLO_verify->signerHeader);
415 struct BLO_SignerInfo *BLO_getSignerInfo(){
416 return &g_SignerInfo;
419 int BLO_isValidSignerInfo(struct BLO_SignerInfo *info){
420 return info->name[0] != 0;
423 void BLO_clrSignerInfo(struct BLO_SignerInfo *info)