File: | rpmio/digest_openssl.c |
Warning: | line 552, column 9 Value stored to 'rc' is never read |
1 | #include "system.h" |
2 | |
3 | #include <openssl/evp.h> |
4 | #include <openssl/rsa.h> |
5 | #include <openssl/dsa.h> |
6 | #include <rpm/rpmpgp.h> |
7 | |
8 | #include "rpmio/digest.h" |
9 | |
10 | |
11 | /* Compatibility functions for OpenSSL 1.0.2 */ |
12 | |
13 | #ifndef HAVE_EVP_MD_CTX_NEW1 |
14 | # define EVP_MD_CTX_new EVP_MD_CTX_create |
15 | # define EVP_MD_CTX_free EVP_MD_CTX_destroy |
16 | #endif |
17 | |
18 | #ifndef HAVE_RSA_SET0_KEY1 |
19 | int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); |
20 | int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) |
21 | { |
22 | if (!r) return 0; |
23 | |
24 | if (n) { |
25 | r->n = n; |
26 | } |
27 | |
28 | if (e) { |
29 | r->e = e; |
30 | } |
31 | |
32 | if (d) { |
33 | r->d = d; |
34 | } |
35 | |
36 | return 1; |
37 | } |
38 | #endif /* HAVE_RSA_SET0_KEY */ |
39 | |
40 | #ifndef HAVE_DSA_SET0_KEY1 |
41 | int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key); |
42 | |
43 | int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) |
44 | { |
45 | if (!d) return 0; |
46 | |
47 | if (pub_key) { |
48 | d->pub_key = pub_key; |
49 | } |
50 | |
51 | if (priv_key) { |
52 | d->priv_key = priv_key; |
53 | } |
54 | |
55 | return 1; |
56 | } |
57 | #endif /* HAVE_DSA_SET0_KEY */ |
58 | |
59 | #ifndef HAVE_DSA_SET0_PQG1 |
60 | int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g); |
61 | |
62 | int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) |
63 | { |
64 | if (!d) return 0; |
65 | |
66 | if (p) { |
67 | d->p = p; |
68 | } |
69 | |
70 | if (q) { |
71 | d->q = q; |
72 | } |
73 | |
74 | if (g) { |
75 | d->g = g; |
76 | } |
77 | |
78 | return 1; |
79 | } |
80 | #endif /* HAVE_DSA_SET0_PQG */ |
81 | |
82 | #ifndef HAVE_DSA_SIG_SET01 |
83 | int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); |
84 | |
85 | int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) |
86 | { |
87 | if (!sig) return 0; |
88 | |
89 | if (r) { |
90 | sig->r = r; |
91 | } |
92 | |
93 | if (s) { |
94 | sig->s = s; |
95 | } |
96 | |
97 | return 1; |
98 | } |
99 | #endif /* HAVE_DSA_SIG_SET0 */ |
100 | |
101 | #ifndef HAVE_BN2BINPAD1 |
102 | static int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) |
103 | { |
104 | int i; |
105 | |
106 | i = BN_num_bytes(a)((BN_num_bits(a)+7)/8); |
107 | if (tolen < i) |
108 | return -1; |
109 | |
110 | /* Add leading zeroes if necessary */ |
111 | if (tolen > i) { |
112 | memset(to, 0, tolen - i); |
113 | to += tolen - i; |
114 | } |
115 | |
116 | BN_bn2bin(a, to); |
117 | |
118 | return tolen; |
119 | } |
120 | #endif /* HAVE_BN2BINPAD */ |
121 | |
122 | struct DIGEST_CTX_s { |
123 | rpmDigestFlags flags; /*!< Bit(s) to control digest operation. */ |
124 | int algo; /*!< Used hash algorithm */ |
125 | |
126 | EVP_MD_CTX *md_ctx; /* Digest context (opaque) */ |
127 | |
128 | }; |
129 | |
130 | /**************************** init ************************************/ |
131 | |
132 | int rpmInitCrypto(void) { |
133 | return 0; |
134 | } |
135 | |
136 | int rpmFreeCrypto(void) { |
137 | return 0; |
138 | } |
139 | |
140 | /**************************** digest ************************************/ |
141 | |
142 | DIGEST_CTX rpmDigestDup(DIGEST_CTX octx) |
143 | { |
144 | if (!octx) return NULL((void*)0); |
145 | |
146 | DIGEST_CTX nctx = NULL((void*)0); |
147 | nctx = xcalloc(1, sizeof(*nctx))rcalloc((1), (sizeof(*nctx))); |
148 | |
149 | nctx->flags = octx->flags; |
150 | nctx->algo = octx->algo; |
151 | nctx->md_ctx = EVP_MD_CTX_new(); |
152 | if (!nctx->md_ctx) { |
153 | free(nctx); |
154 | return NULL((void*)0); |
155 | } |
156 | |
157 | if (!EVP_MD_CTX_copy(nctx->md_ctx, octx->md_ctx)) { |
158 | free(nctx); |
159 | return NULL((void*)0); |
160 | } |
161 | |
162 | return nctx; |
163 | } |
164 | |
165 | static const EVP_MD *getEVPMD(int hashalgo) |
166 | { |
167 | switch (hashalgo) { |
168 | |
169 | case PGPHASHALGO_MD5: |
170 | return EVP_md5(); |
171 | |
172 | case PGPHASHALGO_SHA1: |
173 | return EVP_sha1(); |
174 | |
175 | case PGPHASHALGO_RIPEMD160: |
176 | return EVP_ripemd160(); |
177 | |
178 | case PGPHASHALGO_MD2: |
179 | return EVP_md2(); |
180 | |
181 | case PGPHASHALGO_SHA256: |
182 | return EVP_sha256(); |
183 | |
184 | case PGPHASHALGO_SHA384: |
185 | return EVP_sha384(); |
186 | |
187 | case PGPHASHALGO_SHA512: |
188 | return EVP_sha512(); |
189 | |
190 | case PGPHASHALGO_SHA224: |
191 | return EVP_sha224(); |
192 | |
193 | default: |
194 | return EVP_md_null(); |
195 | } |
196 | } |
197 | |
198 | size_t rpmDigestLength(int hashalgo) |
199 | { |
200 | return EVP_MD_size(getEVPMD(hashalgo)); |
201 | } |
202 | |
203 | DIGEST_CTX rpmDigestInit(int hashalgo, rpmDigestFlags flags) |
204 | { |
205 | DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx))rcalloc((1), (sizeof(*ctx))); |
206 | |
207 | ctx->md_ctx = EVP_MD_CTX_new(); |
208 | if (!ctx->md_ctx) { |
209 | free(ctx); |
210 | return NULL((void*)0); |
211 | } |
212 | |
213 | const EVP_MD *md = getEVPMD(hashalgo); |
214 | if (md == EVP_md_null()) { |
215 | free(ctx->md_ctx); |
216 | free(ctx); |
217 | return NULL((void*)0); |
218 | } |
219 | |
220 | ctx->algo = hashalgo; |
221 | ctx->flags = flags; |
222 | if (!EVP_DigestInit_ex(ctx->md_ctx, md, NULL((void*)0))) { |
223 | free(ctx->md_ctx); |
224 | free(ctx); |
225 | return NULL((void*)0); |
226 | } |
227 | |
228 | return ctx; |
229 | } |
230 | |
231 | int rpmDigestUpdate(DIGEST_CTX ctx, const void *data, size_t len) |
232 | { |
233 | if (ctx == NULL((void*)0)) return -1; |
234 | |
235 | EVP_DigestUpdate(ctx->md_ctx, data, len); |
236 | |
237 | return 0; |
238 | } |
239 | |
240 | int rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii) |
241 | { |
242 | int ret; |
243 | unsigned char *digest = NULL((void*)0); |
244 | unsigned int digestlen; |
245 | |
246 | if (ctx == NULL((void*)0)) return -1; |
247 | |
248 | digestlen = EVP_MD_CTX_size(ctx->md_ctx)EVP_MD_size(EVP_MD_CTX_md(ctx->md_ctx)); |
249 | digest = xcalloc(digestlen, sizeof(*digest))rcalloc((digestlen), (sizeof(*digest))); |
250 | |
251 | ret = EVP_DigestFinal_ex(ctx->md_ctx, digest, &digestlen); |
252 | if (ret != 1) goto done; |
253 | |
254 | if (!asAscii) { |
255 | /* Raw data requested */ |
256 | if (lenp) *lenp = digestlen; |
257 | if (datap) { |
258 | *datap = digest; |
259 | digest = NULL((void*)0); |
260 | } |
261 | } |
262 | |
263 | else { |
264 | /* ASCII requested */ |
265 | if (lenp) *lenp = (2*digestlen) + 1; |
266 | if (datap) { |
267 | const uint8_t * s = (const uint8_t *) digest; |
268 | *datap = pgpHexStr(s, digestlen); |
269 | } |
270 | } |
271 | |
272 | ret = 1; |
273 | |
274 | done: |
275 | if (digest) { |
276 | /* Zero the digest, just in case it's sensitive */ |
277 | memset(digest, 0, digestlen); |
278 | free(digest); |
279 | } |
280 | |
281 | EVP_MD_CTX_free(ctx->md_ctx); |
282 | free(ctx); |
283 | |
284 | if (ret != 1) { |
285 | return -1; |
286 | } |
287 | |
288 | return 0; |
289 | } |
290 | |
291 | |
292 | /****************************** RSA **************************************/ |
293 | |
294 | /* Key */ |
295 | |
296 | struct pgpDigKeyRSA_s { |
297 | size_t nbytes; /* Size of modulus */ |
298 | |
299 | BIGNUM *n; /* Common Modulus */ |
300 | BIGNUM *e; /* Public Exponent */ |
301 | |
302 | EVP_PKEY *evp_pkey; /* Fully constructed key */ |
303 | }; |
304 | |
305 | static int constructRSASigningKey(struct pgpDigKeyRSA_s *key) |
306 | { |
307 | if (key->evp_pkey) { |
308 | /* We've already constructed it, so just reuse it */ |
309 | return 1; |
310 | } |
311 | |
312 | /* Create the RSA key */ |
313 | RSA *rsa = RSA_new(); |
314 | if (!rsa) return 0; |
315 | |
316 | if (!RSA_set0_key(rsa, key->n, key->e, NULL((void*)0))) { |
317 | RSA_free(rsa); |
318 | return 0; |
319 | } |
320 | |
321 | /* Create an EVP_PKEY container to abstract the key-type. */ |
322 | key->evp_pkey = EVP_PKEY_new(); |
323 | if (!key->evp_pkey) { |
324 | RSA_free(rsa); |
325 | return 0; |
326 | } |
327 | |
328 | /* Assign the RSA key to the EVP_PKEY structure. |
329 | This will take over memory management of the RSA key */ |
330 | if (!EVP_PKEY_assign_RSA(key->evp_pkey, rsa)EVP_PKEY_assign((key->evp_pkey),6, (char *)(rsa))) { |
331 | EVP_PKEY_free(key->evp_pkey); |
332 | key->evp_pkey = NULL((void*)0); |
333 | RSA_free(rsa); |
334 | } |
335 | |
336 | return 1; |
337 | } |
338 | |
339 | static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p) |
340 | { |
341 | size_t mlen = pgpMpiLen(p) - 2; |
342 | struct pgpDigKeyRSA_s *key = pgpkey->data; |
343 | |
344 | if (!key) { |
345 | key = pgpkey->data = xcalloc(1, sizeof(*key))rcalloc((1), (sizeof(*key))); |
346 | } |
347 | |
348 | switch (num) { |
349 | case 0: |
350 | /* Modulus */ |
351 | if (key->n) { |
352 | /* This should only ever happen once per key */ |
353 | return 1; |
354 | } |
355 | |
356 | key->nbytes = mlen; |
357 | /* Create a BIGNUM from the pointer. |
358 | Note: this assumes big-endian data as required by PGP */ |
359 | key->n = BN_bin2bn(p+2, mlen, NULL((void*)0)); |
360 | if (!key->n) return 1; |
361 | break; |
362 | |
363 | case 1: |
364 | /* Exponent */ |
365 | if (key->e) { |
366 | /* This should only ever happen once per key */ |
367 | return 1; |
368 | } |
369 | |
370 | /* Create a BIGNUM from the pointer. |
371 | Note: this assumes big-endian data as required by PGP */ |
372 | key->e = BN_bin2bn(p+2, mlen, NULL((void*)0)); |
373 | if (!key->e) return 1; |
374 | break; |
375 | } |
376 | |
377 | return 0; |
378 | } |
379 | |
380 | static void pgpFreeKeyRSA(pgpDigAlg pgpkey) |
381 | { |
382 | struct pgpDigKeyRSA_s *key = pgpkey->data; |
383 | if (key) { |
384 | if (key->evp_pkey) { |
385 | EVP_PKEY_free(key->evp_pkey); |
386 | } else { |
387 | /* If key->evp_pkey was constructed, |
388 | * the memory management of these BNs |
389 | * are freed with it. */ |
390 | BN_clear_free(key->n); |
391 | BN_clear_free(key->e); |
392 | } |
393 | |
394 | free(key); |
395 | } |
396 | } |
397 | |
398 | /* Signature */ |
399 | |
400 | struct pgpDigSigRSA_s { |
401 | BIGNUM *bn; |
402 | size_t len; |
403 | }; |
404 | |
405 | static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num, const uint8_t *p) |
406 | { |
407 | BIGNUM *bn = NULL((void*)0); |
408 | |
409 | int mlen = pgpMpiLen(p) - 2; |
410 | int rc = 1; |
411 | |
412 | struct pgpDigSigRSA_s *sig = pgpsig->data; |
413 | if (!sig) { |
414 | sig = xcalloc(1, sizeof(*sig))rcalloc((1), (sizeof(*sig))); |
415 | } |
416 | |
417 | switch (num) { |
418 | case 0: |
419 | if (sig->bn) { |
420 | /* This should only ever happen once per signature */ |
421 | return 1; |
422 | } |
423 | |
424 | bn = sig->bn = BN_new(); |
425 | if (!bn) return 1; |
426 | |
427 | /* Create a BIGNUM from the signature pointer. |
428 | Note: this assumes big-endian data as required |
429 | by the PGP multiprecision integer format |
430 | (RFC4880, Section 3.2) |
431 | This will be useful later, as we can |
432 | retrieve this value with appropriate |
433 | padding. */ |
434 | bn = BN_bin2bn(p+2, mlen, bn); |
435 | if (!bn) return 1; |
436 | |
437 | sig->bn = bn; |
438 | sig->len = mlen; |
439 | |
440 | pgpsig->data = sig; |
441 | rc = 0; |
442 | break; |
443 | } |
444 | return rc; |
445 | } |
446 | |
447 | static void pgpFreeSigRSA(pgpDigAlg pgpsig) |
448 | { |
449 | struct pgpDigSigRSA_s *sig = pgpsig->data; |
450 | if (sig) { |
451 | BN_clear_free(sig->bn); |
452 | free(pgpsig->data); |
453 | } |
454 | } |
455 | |
456 | static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, |
457 | uint8_t *hash, size_t hashlen, int hash_algo) |
458 | { |
459 | int rc, ret; |
460 | EVP_PKEY_CTX *pkey_ctx = NULL((void*)0); |
461 | struct pgpDigSigRSA_s *sig = pgpsig->data; |
462 | |
463 | void *padded_sig = NULL((void*)0); |
464 | |
465 | struct pgpDigKeyRSA_s *key = pgpkey->data; |
466 | |
467 | if (!constructRSASigningKey(key)) { |
468 | rc = 1; |
469 | goto done; |
470 | } |
471 | |
472 | pkey_ctx = EVP_PKEY_CTX_new(key->evp_pkey, NULL((void*)0)); |
473 | if (!pkey_ctx) { |
474 | rc = 1; |
475 | goto done; |
476 | } |
477 | |
478 | ret = EVP_PKEY_verify_init(pkey_ctx); |
479 | if (ret < 0) { |
480 | rc = 1; |
481 | goto done; |
482 | } |
483 | |
484 | ret = EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PADDING)EVP_PKEY_CTX_ctrl(pkey_ctx, 6, -1, (0x1000 + 1), 1, ((void*)0 )); |
485 | if (ret < 0) { |
486 | rc = 1; |
487 | goto done; |
488 | } |
489 | |
490 | ret = EVP_PKEY_CTX_set_signature_md(pkey_ctx, getEVPMD(hash_algo))EVP_PKEY_CTX_ctrl(pkey_ctx, -1, ((1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7)), 1, 0, (void *)getEVPMD (hash_algo)); |
491 | if (ret < 0) { |
492 | rc = 1; |
493 | goto done; |
494 | } |
495 | |
496 | int pkey_len = EVP_PKEY_size(key->evp_pkey); |
497 | padded_sig = xcalloc(1, pkey_len)rcalloc((1), (pkey_len)); |
498 | if (!BN_bn2binpad(sig->bn, padded_sig, pkey_len)) { |
499 | rc = 1; |
500 | goto done; |
501 | } |
502 | |
503 | ret = EVP_PKEY_verify(pkey_ctx, padded_sig, pkey_len, hash, hashlen); |
504 | if (ret == 1) |
505 | { |
506 | /* Success */ |
507 | rc = 0; |
508 | } |
509 | else |
510 | { |
511 | /* Failure */ |
512 | rc = 1; |
513 | } |
514 | |
515 | done: |
516 | EVP_PKEY_CTX_free(pkey_ctx); |
517 | free(padded_sig); |
518 | return rc; |
519 | } |
520 | |
521 | /****************************** DSA ***************************************/ |
522 | /* Key */ |
523 | |
524 | struct pgpDigKeyDSA_s { |
525 | BIGNUM *p; /* Prime */ |
526 | BIGNUM *q; /* Subprime */ |
527 | BIGNUM *g; /* Base */ |
528 | BIGNUM *y; /* Public Key */ |
529 | |
530 | DSA *dsa_key; /* Fully constructed key */ |
531 | }; |
532 | |
533 | static int constructDSASigningKey(struct pgpDigKeyDSA_s *key) |
534 | { |
535 | int rc; |
536 | |
537 | if (key->dsa_key) { |
538 | /* We've already constructed it, so just reuse it */ |
539 | return 1; |
540 | } |
541 | |
542 | /* Create the DSA key */ |
543 | DSA *dsa = DSA_new(); |
544 | if (!dsa) return 0; |
545 | |
546 | if (!DSA_set0_pqg(dsa, key->p, key->q, key->g)) { |
547 | rc = 0; |
548 | goto done; |
549 | } |
550 | |
551 | if (!DSA_set0_key(dsa, key->y, NULL((void*)0))) { |
552 | rc = 0; |
Value stored to 'rc' is never read | |
553 | } |
554 | |
555 | key->dsa_key = dsa; |
556 | |
557 | rc = 1; |
558 | done: |
559 | if (rc == 0) { |
560 | DSA_free(dsa); |
561 | } |
562 | return rc; |
563 | } |
564 | |
565 | |
566 | static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num, const uint8_t *p) |
567 | { |
568 | BIGNUM *bn; |
569 | size_t mlen = pgpMpiLen(p) - 2; |
570 | struct pgpDigKeyDSA_s *key = pgpkey->data; |
571 | |
572 | if (!key) { |
573 | key = pgpkey->data = xcalloc(1, sizeof(*key))rcalloc((1), (sizeof(*key))); |
574 | } |
575 | |
576 | /* Create a BIGNUM from the key pointer. |
577 | Note: this assumes big-endian data as required |
578 | by the PGP multiprecision integer format |
579 | (RFC4880, Section 3.2) */ |
580 | bn = BN_bin2bn(p+2, mlen, NULL((void*)0)); |
581 | if (!bn) return 1; |
582 | |
583 | switch (num) { |
584 | case 0: |
585 | /* Prime */ |
586 | if (key->p) { |
587 | /* This should only ever happen once per key */ |
588 | return 1; |
589 | } |
590 | key->p = bn; |
591 | break; |
592 | |
593 | case 1: |
594 | /* Subprime */ |
595 | if (key->q) { |
596 | /* This should only ever happen once per key */ |
597 | return 1; |
598 | } |
599 | key->q = bn; |
600 | break; |
601 | case 2: |
602 | /* Base */ |
603 | if (key->g) { |
604 | /* This should only ever happen once per key */ |
605 | return 1; |
606 | } |
607 | key->g = bn; |
608 | break; |
609 | case 3: |
610 | /* Public */ |
611 | if (key->y) { |
612 | /* This should only ever happen once per key */ |
613 | return 1; |
614 | } |
615 | key->y = bn; |
616 | break; |
617 | } |
618 | |
619 | return 0; |
620 | } |
621 | |
622 | static void pgpFreeKeyDSA(pgpDigAlg pgpkey) |
623 | { |
624 | struct pgpDigKeyDSA_s *key = pgpkey->data; |
625 | if (key) { |
626 | if (key->dsa_key) { |
627 | DSA_free(key->dsa_key); |
628 | } else { |
629 | /* If sig->dsa_key was constructed, |
630 | * the memory management of these BNs |
631 | * are freed with it. */ |
632 | BN_clear_free(key->p); |
633 | BN_clear_free(key->q); |
634 | BN_clear_free(key->g); |
635 | BN_clear_free(key->y); |
636 | } |
637 | free(key); |
638 | } |
639 | } |
640 | |
641 | /* Signature */ |
642 | |
643 | struct pgpDigSigDSA_s { |
644 | BIGNUM *r; |
645 | BIGNUM *s; |
646 | |
647 | DSA_SIG *dsa_sig; |
648 | }; |
649 | |
650 | static int constructDSASignature(struct pgpDigSigDSA_s *sig) |
651 | { |
652 | int rc; |
653 | |
654 | if (sig->dsa_sig) { |
655 | /* We've already constructed it, so just reuse it */ |
656 | return 1; |
657 | } |
658 | |
659 | /* Create the DSA signature */ |
660 | DSA_SIG *dsa_sig = DSA_SIG_new(); |
661 | if (!dsa_sig) return 0; |
662 | |
663 | if (!DSA_SIG_set0(dsa_sig, sig->r, sig->s)) { |
664 | rc = 0; |
665 | goto done; |
666 | } |
667 | |
668 | sig->dsa_sig = dsa_sig; |
669 | |
670 | rc = 1; |
671 | done: |
672 | if (rc == 0) { |
673 | DSA_SIG_free(sig->dsa_sig); |
674 | } |
675 | return rc; |
676 | } |
677 | |
678 | static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num, const uint8_t *p) |
679 | { |
680 | BIGNUM *bn = NULL((void*)0); |
681 | |
682 | int mlen = pgpMpiLen(p) - 2; |
683 | int rc = 1; |
684 | |
685 | struct pgpDigSigDSA_s *sig = pgpsig->data; |
686 | if (!sig) { |
687 | sig = xcalloc(1, sizeof(*sig))rcalloc((1), (sizeof(*sig))); |
688 | } |
689 | |
690 | /* Create a BIGNUM from the signature pointer. |
691 | Note: this assumes big-endian data as required |
692 | by the PGP multiprecision integer format |
693 | (RFC4880, Section 3.2) */ |
694 | bn = BN_bin2bn(p+2, mlen, NULL((void*)0)); |
695 | if (!bn) return 1; |
696 | |
697 | switch (num) { |
698 | case 0: |
699 | if (sig->r) { |
700 | /* This should only ever happen once per signature */ |
701 | BN_free(bn); |
702 | return 1; |
703 | } |
704 | sig->r = bn; |
705 | rc = 0; |
706 | break; |
707 | case 1: |
708 | if (sig->s) { |
709 | /* This should only ever happen once per signature */ |
710 | BN_free(bn); |
711 | return 1; |
712 | } |
713 | sig->s = bn; |
714 | rc = 0; |
715 | break; |
716 | } |
717 | |
718 | pgpsig->data = sig; |
719 | |
720 | return rc; |
721 | } |
722 | |
723 | static void pgpFreeSigDSA(pgpDigAlg pgpsig) |
724 | { |
725 | struct pgpDigSigDSA_s *sig = pgpsig->data; |
726 | if (sig) { |
727 | if (sig->dsa_sig) { |
728 | DSA_SIG_free(sig->dsa_sig); |
729 | } else { |
730 | /* If sig->dsa_sig was constructed, |
731 | * the memory management of these BNs |
732 | * are freed with it. */ |
733 | BN_clear_free(sig->r); |
734 | BN_clear_free(sig->s); |
735 | } |
736 | free(pgpsig->data); |
737 | } |
738 | } |
739 | |
740 | static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, |
741 | uint8_t *hash, size_t hashlen, int hash_algo) |
742 | { |
743 | int rc, ret; |
744 | struct pgpDigSigDSA_s *sig = pgpsig->data; |
745 | |
746 | struct pgpDigKeyDSA_s *key = pgpkey->data; |
747 | |
748 | if (!constructDSASigningKey(key)) { |
749 | rc = 1; |
750 | goto done; |
751 | } |
752 | |
753 | if (!constructDSASignature(sig)) { |
754 | rc = 1; |
755 | goto done; |
756 | } |
757 | |
758 | ret = DSA_do_verify(hash, hashlen, sig->dsa_sig, key->dsa_key); |
759 | if (ret == 1) |
760 | { |
761 | /* Success */ |
762 | rc = 0; |
763 | } |
764 | else |
765 | { |
766 | /* Failure */ |
767 | rc = 1; |
768 | } |
769 | |
770 | done: |
771 | return rc; |
772 | } |
773 | |
774 | /****************************** NULL **************************************/ |
775 | |
776 | static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num, const uint8_t *p) |
777 | { |
778 | return 1; |
779 | } |
780 | |
781 | static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig, |
782 | uint8_t *hash, size_t hashlen, int hash_algo) |
783 | { |
784 | return 1; |
785 | } |
786 | |
787 | /****************************** PGP **************************************/ |
788 | pgpDigAlg pgpPubkeyNew(int algo) |
789 | { |
790 | pgpDigAlg ka = xcalloc(1, sizeof(*ka))rcalloc((1), (sizeof(*ka)));; |
791 | |
792 | switch (algo) { |
793 | case PGPPUBKEYALGO_RSA: |
794 | ka->setmpi = pgpSetKeyMpiRSA; |
795 | ka->free = pgpFreeKeyRSA; |
796 | ka->mpis = 2; |
797 | break; |
798 | case PGPPUBKEYALGO_DSA: |
799 | ka->setmpi = pgpSetKeyMpiDSA; |
800 | ka->free = pgpFreeKeyDSA; |
801 | ka->mpis = 4; |
802 | break; |
803 | default: |
804 | ka->setmpi = pgpSetMpiNULL; |
805 | ka->mpis = -1; |
806 | break; |
807 | } |
808 | |
809 | ka->verify = pgpVerifyNULL; /* keys can't be verified */ |
810 | |
811 | return ka; |
812 | } |
813 | |
814 | pgpDigAlg pgpSignatureNew(int algo) |
815 | { |
816 | pgpDigAlg sa = xcalloc(1, sizeof(*sa))rcalloc((1), (sizeof(*sa))); |
817 | |
818 | switch (algo) { |
819 | case PGPPUBKEYALGO_RSA: |
820 | sa->setmpi = pgpSetSigMpiRSA; |
821 | sa->free = pgpFreeSigRSA; |
822 | sa->verify = pgpVerifySigRSA; |
823 | sa->mpis = 1; |
824 | break; |
825 | case PGPPUBKEYALGO_DSA: |
826 | sa->setmpi = pgpSetSigMpiDSA; |
827 | sa->free = pgpFreeSigDSA; |
828 | sa->verify = pgpVerifySigDSA; |
829 | sa->mpis = 2; |
830 | break; |
831 | default: |
832 | sa->setmpi = pgpSetMpiNULL; |
833 | sa->verify = pgpVerifyNULL; |
834 | sa->mpis = -1; |
835 | break; |
836 | } |
837 | return sa; |
838 | } |