rpm  5.4.10
rpmbc.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 #define _RPMBC_INTERNAL
7 #define _RPMPGP_INTERNAL
8 #include <rpmbc.h>
9 #include "debug.h"
10 
11 /*@access pgpDig @*/
12 /*@access pgpDigParams @*/
13 
14 /*@-redecl@*/
15 /*@unchecked@*/
16 extern int _pgp_debug;
17 
18 /*@unchecked@*/
19 extern int _pgp_print;
20 /*@=redecl@*/
21 
22 /*@unchecked@*/
23 static int _rpmbc_debug;
24 
25 #define SPEW(_t, _rc, _dig) \
26  { if ((_t) || _rpmbc_debug || _pgp_debug < 0) \
27  fprintf(stderr, "<-- %s(%p) %s\t%s\n", __FUNCTION__, (_dig), \
28  ((_rc) ? "OK" : "BAD"), (_dig)->pubkey_algoN); \
29  }
30 
31 static const char * _pgpHashAlgo2Name(uint32_t algo)
32 {
33  return pgpValStr(pgpHashTbl, (rpmuint8_t)algo);
34 }
35 
36 static const char * _pgpPubkeyAlgo2Name(uint32_t algo)
37 {
38  return pgpValStr(pgpPubkeyTbl, (rpmuint8_t)algo);
39 }
40 
46 static
47 unsigned char nibble(char c)
48  /*@*/
49 {
50  if (c >= '0' && c <= '9')
51  return (unsigned char) (c - '0');
52  if (c >= 'A' && c <= 'F')
53  return (unsigned char)((int)(c - 'A') + 10);
54  if (c >= 'a' && c <= 'f')
55  return (unsigned char)((int)(c - 'a') + 10);
56  return (unsigned char) '\0';
57 }
58 
59 #define _spewMPB(_N, _MPB) \
60  { mpbarrett * mpb = &(_MPB); \
61  fprintf(stderr, "\t" _N ": "); mpfprintln(stderr, mpb->size, mpb->modl); \
62  }
63 
64 #define _spewMPN(_N, _MPN) \
65  { mpnumber * mpn = &(_MPN); \
66  fprintf(stderr, "\t" _N ": "); mpfprintln(stderr, mpn->size, mpn->data); \
67  }
68 
69 #ifdef UNUSED
70 static void rpmbcDumpRSA(const char * msg, rpmbc bc)
71 {
72  if (msg) fprintf(stderr, "========== %s\n", msg);
73 
74  {
75  _spewMPB(" n", bc->rsa_keypair.n);
76  _spewMPN(" e", bc->rsa_keypair.e);
77  _spewMPN(" d", bc->rsa_keypair.d);
78  _spewMPB(" p", bc->rsa_keypair.p);
79  _spewMPB(" q", bc->rsa_keypair.q);
80  _spewMPN("dp", bc->rsa_keypair.dp);
81  _spewMPN("dq", bc->rsa_keypair.dq);
82  _spewMPN("qi", bc->rsa_keypair.qi);
83  }
84 
85  _spewMPN(" c", bc->c);
86  _spewMPN("hm", bc->hm);
87 }
88 
89 static void rpmbcDumpDSA(const char * msg, rpmbc bc)
90 {
91  if (msg) fprintf(stderr, "========== %s\n", msg);
92 
93  {
94  _spewMPB(" p", bc->dsa_keypair.param.p);
95  _spewMPB(" q", bc->dsa_keypair.param.q);
96  _spewMPN(" g", bc->dsa_keypair.param.g);
97  _spewMPN(" y", bc->dsa_keypair.y);
98  }
99 
100  _spewMPN(" r", bc->r);
101  _spewMPN(" s", bc->s);
102 
103  _spewMPN("hm", bc->hm);
104 
105 }
106 #endif /* UNUSED */
107 
108 static
109 int rpmbcSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
110  /*@modifies dig @*/
111 {
112  rpmbc bc = (rpmbc) dig->impl;
113  size_t nbits = 0;
114  size_t nb = 0;
115  const char * prefix = rpmDigestASN1(ctx);
116  const char * hexstr;
117  char * tt;
118  int rc = 1; /* assume failure */
119  int xx;
120 pgpDigParams pubp = pgpGetPubkey(dig);
121 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
122 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
123 
124 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
125 assert(prefix != NULL);
126 
127  /*
128  * The no. of bytes for hash + PKCS1 padding is needed.
129  * Either n or c can be used as the size, but different code paths
130  * populate n or c indeterminately. So try c, then n,
131  * and error if the no. of bytes isn't sane.
132  */
133  if (bc->c.size)
134  nbits = (unsigned) MP_WORDS_TO_BITS(bc->c.size);
135  else if (bc->rsa_keypair.n.size)
136  nbits = (unsigned) MP_WORDS_TO_BITS(bc->rsa_keypair.n.size);
137  nb = (nbits + 7) >> 3; /* XXX overkill */
138  if (nb < 64/8 || nb > 65536/8) /* XXX generous "sanity" check */
139  goto exit;
140 
141 /* XXX FIXME: do PKCS1 padding in binary not hex */
142 /* XXX FIXME: should this lazy free be done elsewhere? */
143 bc->digest = _free(bc->digest);
144 bc->digestlen = 0;
145  xx = rpmDigestFinal(ctx, (void **)&bc->digest, &bc->digestlen, 1);
146  ctx = NULL; /* XXX avoid double free */
147  hexstr = tt = (char *) xmalloc(2 * nb + 1);
148  memset(tt, (int) 'f', (2 * nb));
149  tt[0] = '0'; tt[1] = '0';
150  tt[2] = '0'; tt[3] = '1';
151  tt += (2 * nb) - strlen(prefix) - strlen((char *)bc->digest) - 2;
152  *tt++ = '0'; *tt++ = '0';
153  tt = stpcpy(tt, prefix);
154  tt = stpcpy(tt, (char *)bc->digest);
155 
156 /*@-moduncon -noeffectuncon @*/
157 mpnfree(&bc->hm);
158  mpnzero(&bc->hm); (void) mpnsethex(&bc->hm, hexstr);
159 /*@=moduncon =noeffectuncon @*/
160 
161  hexstr = _free(hexstr);
162 
163  /* Compare leading 16 bits of digest for quick check. */
164  { const char *str = (const char *) bc->digest;
165  rpmuint8_t s[2];
166  const rpmuint8_t *t = sigp->signhash16;
167  s[0] = (rpmuint8_t) (nibble(str[0]) << 4) | nibble(str[1]);
168  s[1] = (rpmuint8_t) (nibble(str[2]) << 4) | nibble(str[3]);
169  rc = memcmp(s, t, sizeof(sigp->signhash16));
170  }
171 
172 exit:
173  if (ctx) { /* XXX Free the context on error returns. */
174  xx = rpmDigestFinal(ctx, NULL, NULL, 0);
175  ctx = NULL;
176  }
177 SPEW(0, !rc, dig);
178  return rc;
179 }
180 
181 static
183  /*@*/
184 {
185  rpmbc bc = (rpmbc) dig->impl;
186  int rc;
187 
188  rc = rsavrfy(&bc->rsa_keypair.n, &bc->rsa_keypair.e, &bc->c, &bc->hm);
189 
190 SPEW(0, rc, dig);
191  return rc;
192 }
193 
194 static
195 int rpmbcSignRSA(/*@unused@*/pgpDig dig)
196  /*@*/
197 {
198  rpmbc bc = (rpmbc) dig->impl;
199  int rc = 0; /* Assume failure. */
200  int failures = 0;
201  int xx;
202 
203  mpnzero(&bc->c);
204 #ifdef SLOWER
205  xx = rsapri(&bc->rsa_keypair.n, &bc->rsa_keypair.d, &bc->hm, &bc->c);
206 #else
207  /* XXX RSA w CRT is ~3x-4x faster for signing. */
208  xx = rsapricrt(&bc->rsa_keypair.n, &bc->rsa_keypair.p, &bc->rsa_keypair.q,
209  &bc->rsa_keypair.dp, &bc->rsa_keypair.dq, &bc->rsa_keypair.qi,
210  &bc->hm, &bc->c);
211 #endif
212  if (xx) failures++;
213 
214  rc = (failures == 0);
215 
216 SPEW(!rc, rc, dig);
217  return rc;
218 }
219 
220 static
221 int rpmbcGenerateRSA(/*@unused@*/pgpDig dig)
222  /*@*/
223 {
224  rpmbc bc = (rpmbc) dig->impl;
225  int rc = 0; /* Assume failure. */
226  int failures = 0;
227  int xx;
228 
229 if (bc->nbits == 0) bc->nbits = 1024; /* XXX FIXME */
230 
231 xx = randomGeneratorContextInit(&bc->rngc, randomGeneratorDefault());
232 
233 rsakpFree(&bc->rsa_keypair);
234  xx = rsakpMake(&bc->rsa_keypair, &bc->rngc, bc->nbits);
235  if (xx) failures++;
236 
237  /* generate a random m in the range 0 < m < n */
238  mpnzero(&bc->m);
239  mpbnrnd(&bc->rsa_keypair.n, &bc->rngc, &bc->m);
240 
241  rc = (failures == 0);
242 
243 SPEW(!rc, rc, dig);
244  return rc;
245 }
246 
247 static
248 int rpmbcSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
249  /*@modifies dig @*/
250 {
251  rpmbc bc = (rpmbc) dig->impl;
252  int rc;
253 pgpDigParams pubp = pgpGetPubkey(dig);
254 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
255 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
256 
257 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
258 bc->digest = _free(bc->digest);
259 bc->digestlen = 0;
260  rc = rpmDigestFinal(ctx, (void **)&bc->digest, &bc->digestlen, 0);
261 
262  /* XXX Truncate to 160bits. */
263  rc = mpnsetbin(&bc->hm, (byte *) bc->digest,
264  (bc->digestlen > 160/8 ? 160/8 : bc->digestlen));
265  rc = memcmp(bc->digest, sigp->signhash16, sizeof(sigp->signhash16));
266 
267 SPEW(0, !rc, dig);
268  return rc;
269 }
270 
271 static
273  /*@*/
274 {
275  rpmbc bc = (rpmbc) dig->impl;
276  int rc = 0; /* Assume failure. */
277  int failures = 0;
278  int xx;
279 
280  xx = dsavrfy(&bc->dsa_keypair.param.p, &bc->dsa_keypair.param.q,
281  &bc->dsa_keypair.param.g, &bc->hm, &bc->dsa_keypair.y,
282  &bc->r, &bc->s);
283  if (!xx) failures++;
284 
285  rc = (failures == 0);
286 
287 SPEW(0, rc, dig);
288  return rc;
289 }
290 
291 static
293  /*@*/
294 {
295  rpmbc bc = (rpmbc) dig->impl;
296  int rc = 0; /* Assume failure. */
297  int failures = 0;
298  int xx;
299 
300  mpnzero(&bc->r);
301  mpnzero(&bc->s);
302  xx = dsasign(&bc->dsa_keypair.param.p, &bc->dsa_keypair.param.q,
303  &bc->dsa_keypair.param.g, &bc->rngc, &bc->hm,
304  &bc->dsa_keypair.x, &bc->r, &bc->s);
305  if (xx) failures++;
306 
307  rc = (failures == 0);
308 
309 SPEW(!rc, rc, dig);
310  return rc;
311 }
312 
313 static
315  /*@*/
316 {
317  rpmbc bc = (rpmbc) dig->impl;
318  int rc = 0; /* Assume failure. */
319  int failures = 0;
320  int xx;
321 
322 if (bc->nbits == 0) bc->nbits = 1024; /* XXX FIXME */
323 
324 xx = randomGeneratorContextInit(&bc->rngc, randomGeneratorDefault());
325 
326  xx = dlkp_pInit(&bc->dsa_keypair);
327  if (xx) failures++;
328  xx = dsaparamMake(&bc->dsa_keypair.param, &bc->rngc, bc->nbits);
329  if (xx) failures++;
330 
331  xx = dldp_pPair(&bc->dsa_keypair.param, &bc->rngc, &bc->dsa_keypair.x,
332  &bc->dsa_keypair.y);
333  if (xx) failures++;
334 
335  rc = (failures == 0);
336 
337 SPEW(!rc, rc, dig);
338  return rc;
339 }
340 
341 static
342 int rpmbcSetELG(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
343  /*@*/
344 {
345  int rc = 1; /* XXX always fail. */
346  int xx;
347 pgpDigParams pubp = pgpGetPubkey(dig);
348 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
349 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
350 
351 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
352  xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0);
353 
354  /* Compare leading 16 bits of digest for quick check. */
355 
356 SPEW(rc, !rc, dig);
357  return rc;
358 }
359 
360 #ifdef NOTYET
361 static
362 int rpmbcVerifyELG(pgpDig dig)
363  /*@*/
364 {
365  rpmbc bc = (rpmbc) dig->impl;
366  int rc = 0; /* Assume failure. */
367  int failures = 0;
368  int xx;
369 
370  xx = elgv1vrfy(&bc->elg_keypair.param.p, &bc->elg_keypair.param.n,
371  &bc->elg_keypair.param.g, &bc->hm, &bc->elg_keypair.y,
372  &bc->r, &bc->s);
373  if (xx) failures++;
374 
375  rc = (failures == 0);
376 
377 SPEW(!rc, rc, dig);
378  return rc;
379 }
380 
381 static
382 int rpmbcSignELG(/*@unused@*/pgpDig dig)
383  /*@*/
384 {
385  rpmbc bc = (rpmbc) dig->impl;
386  int rc = 0; /* Assume failure. */
387  int failures = 0;
388  int xx;
389 
390  mpnzero(&bc->r);
391  mpnzero(&bc->s);
392  xx = elgv1sign(&bc->elg_keypair.param.p, &bc->elg_keypair.param.n,
393  &bc->elg_keypair.param.g, &bc->rngc, &bc->hm,
394  &bc->elg_keypair.x, &bc->r, &bc->s);
395  if (xx) failures++;
396 
397  rc = (failures == 0);
398 
399 SPEW(!rc, rc, dig);
400  return rc;
401 }
402 
403 static
404 int rpmbcGenerateELG(/*@unused@*/pgpDig dig)
405  /*@*/
406 {
407 static const char P_2048[] = "fd12e8b7e096a28a00fb548035953cf0eba64ceb5dff0f5672d376d59c196da729f6b5586f18e6f3f1a86c73c5b15662f59439613b309e52aa257488619e5f76a7c4c3f7a426bdeac66bf88343482941413cef06256b39c62744dcb97e7b78e36ec6b885b143f6f3ad0a1cd8a5713e338916613892a264d4a47e72b583fbdaf5bce2bbb0097f7e65cbc86d684882e5bb8196d522dcacd6ad00dfbcd8d21613bdb59c485a65a58325d792272c09ad1173e12c98d865adb4c4d676ada79830c58c37c42dff8536e28f148a23f296513816d3dfed0397a3d4d6e1fa24f07e1b01643a68b4274646a3b876e810206eddacea2b9ef7636a1da5880ef654288b857ea3";
408 static const char P_1024[] = "e64a3deeddb723e2e4db54c2b09567d196367a86b3b302be07e43ffd7f2e016f866de5135e375bdd2fba6ea9b4299010fafa36dc6b02ba3853cceea07ee94bfe30e0cc82a69c73163be26e0c4012dfa0b2839c97d6cd71eee59a303d6177c6a6740ca63bd04c1ba084d6c369dc2fbfaeebe951d58a4824de52b580442d8cae77";
409 
410  rpmbc bc = (rpmbc) dig->impl;
411  int rc = 0; /* Assume failure. */
412  int failures = 0;
413  int xx;
414 
415 xx = randomGeneratorContextInit(&bc->rngc, randomGeneratorDefault());
416 
417  xx = 0;
418 
419  xx = dlkp_pInit(&bc->elg_keypair);
420  if (xx) failures++;
421 
422 #ifdef DYING
423  xx = dldp_pInit(&bc->elg_keypair.param);
424  if (xx) failures++;
425 #endif
426 
427  switch (bc->nbits) {
428 #ifdef NOTYET
429  case 2048:
430  mpbsethex(&bc->elg_keypair.param.p, P_2048);
431  break;
432  case 1024:
433  case 0:
434  mpbsethex(&bc->elg_keypair.param.p, P_1024);
435  break;
436 #endif
437  default:
438  xx = dldp_pgonMakeSafe(&bc->elg_keypair.param, &bc->rngc, bc->nbits);
439  break;
440  }
441 #ifdef NOTYET
442  if (bc->elg_keypair.param.q.size == 0) {
443  mpnumber q;
444 
445  mpnzero(&q);
446  /* set q to half of P */
447  mpnset(&q, bc->elg_keypair.param.p.size, bc->elg_keypair.param.p.modl);
448  mpdivtwo(q.size, q.data);
449  mpbset(&bc->elg_keypair.param.q, q.size, q.data);
450  /* set r to 2 */
451  mpnsetw(&bc->elg_keypair.param.r, 2);
452 
453  /* make a generator, order n */
454  xx = dldp_pgonGenerator(&bc->elg_keypair.param, &bc->rngc);
455 
456  }
457 #endif
458  if (xx) failures++;
459 
460  xx = dldp_pPair(&bc->elg_keypair.param, &bc->rngc,
461  &bc->elg_keypair.x, &bc->elg_keypair.y);
462  if (xx) failures++;
463 
464  mpnfree(&bc->r);
465  mpnfree(&bc->s);
466  mpnfree(&bc->hm);
467 
468 #ifdef DYING
469  dldp_pFree(&bc->elg_params);
470 #endif
471 
472  dlkp_pFree(&bc->elg_keypair);
473 
474  rc = (failures == 0);
475 
476 SPEW(!rc, rc, dig);
477  return rc;
478 }
479 #endif /* NOTYET */
480 
481 static
482 int rpmbcSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
483  /*@*/
484 {
485  int rc = 1; /* XXX always fail. */
486  int xx;
487 pgpDigParams pubp = pgpGetPubkey(dig);
488 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
489 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
490 
491 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
492  xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0);
493 
494  /* Compare leading 16 bits of digest for quick check. */
495 
496 SPEW(rc, !rc, dig);
497  return rc;
498 }
499 
500 #ifdef NOTYET
501 static
502 int rpmbcVerifyECDSA(pgpDig dig)
503  /*@*/
504 {
505  int rc = 0; /* XXX always fail. */
506 
507 assert(bc->hm); /* XXX FIXME: make sure bc->hm is set */
508 
509 SPEW(!rc, rc, dig);
510  return rc;
511 }
512 
513 static
514 int rpmbcSignECDSA(/*@unused@*/pgpDig dig)
515  /*@*/
516 {
517  int rc = 0; /* XXX always fail. */
518 
519 assert(bc->hm); /* XXX FIXME: make sure bc->hm is set */
520 
521 SPEW(!rc, rc, dig);
522  return rc;
523 }
524 
525 static
526 int rpmbcGenerateECDSA(/*@unused@*/pgpDig dig)
527  /*@*/
528 {
529  rpmbc bc = (rpmbc) dig->impl;
530  int rc = 0; /* Assume failure. */
531  int failures = 0;
532  int xx;
533 
534  if (bc->rngc == NULL)
535  xx = randomGeneratorContextInit(&bc->rngc, randomGeneratorDefault());
536 
537  rc = (failures == 0);
538 
539 SPEW(!rc, rc, dig);
540  return rc;
541 }
542 #endif /* NOTYET */
543 
544 static int rpmbcErrChk(pgpDig dig, const char * msg, int rc, unsigned expected)
545 {
546 #ifdef REFERENCE
547 rpmgc gc = dig->impl;
548  /* Was the return code the expected result? */
549  rc = (gcry_err_code(gc->err) != expected);
550  if (rc)
551  fail("%s failed: %s\n", msg, gpg_strerror(gc->err));
552 /* XXX FIXME: rpmbcStrerror */
553 #else
554  rc = (rc == 0); /* XXX impedance match 1 -> 0 on success */
555 #endif
556  return rc; /* XXX 0 on success */
557 }
558 
559 static int rpmbcAvailableCipher(pgpDig dig, int algo)
560 {
561  int rc = 0; /* assume available */
562 #ifdef REFERENCE
563  rc = rpmgbcvailable(dig->impl, algo,
564  (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5));
565 #endif
566  return rc;
567 }
568 
569 static int rpmbcAvailableDigest(pgpDig dig, int algo)
570 {
571  int rc = 0; /* assume available */
572 #ifdef REFERENCE
573  rc = rpmgbcvailable(dig->impl, algo,
574  (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5));
575 #endif
576  return rc;
577 }
578 
579 static int rpmbcAvailablePubkey(pgpDig dig, int algo)
580 {
581  int rc = 0; /* assume available */
582 #ifdef REFERENCE
583  rc = rpmbcAvailable(dig->impl, algo, gcry_pk_test_algo(algo));
584 #endif
585  return rc;
586 }
587 
588 static int rpmbcVerify(pgpDig dig)
589 {
590  int rc = 0; /* assume failure */
591 pgpDigParams pubp = pgpGetPubkey(dig);
592 pgpDigParams sigp = pgpGetSignature(dig);
593 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
594 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
595 
596  switch (pubp->pubkey_algo) {
597  default:
598  break;
599  case PGPPUBKEYALGO_RSA:
600  rc = rpmbcVerifyRSA(dig);
601  break;
602  case PGPPUBKEYALGO_DSA:
603  rc = rpmbcVerifyDSA(dig);
604  break;
605 #ifdef NOTYET
607  rc = rpmbcVerifyELG(dig);
608  break;
609  case PGPPUBKEYALGO_ECDSA:
610  rc = rpmbcVerifyECDSA(dig);
611  break;
612 #endif
613  }
614 SPEW(0, rc, dig); /* XXX FIXME: thkp has known BAD signatures. */
615  return rc;
616 }
617 
618 static int rpmbcSign(pgpDig dig)
619 {
620  int rc = 0; /* assume failure */
621 pgpDigParams pubp = pgpGetPubkey(dig);
622 pgpDigParams sigp = pgpGetSignature(dig);
623 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
624 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
625 
626  switch (pubp->pubkey_algo) {
627  default:
628  break;
629  case PGPPUBKEYALGO_RSA:
630  rc = rpmbcSignRSA(dig);
631  break;
632  case PGPPUBKEYALGO_DSA:
633  rc = rpmbcSignDSA(dig);
634  break;
635 #ifdef NOTYET
637  rc = rpmbcSignELG(dig);
638  break;
639  case PGPPUBKEYALGO_ECDSA:
640  rc = rpmbcSignECDSA(dig);
641  break;
642 #endif
643  }
644 SPEW(!rc, rc, dig);
645  return rc;
646 }
647 
648 static int rpmbcGenerate(pgpDig dig)
649 {
650  int rc = 0; /* assume failure */
651 pgpDigParams pubp = pgpGetPubkey(dig);
652 pgpDigParams sigp = pgpGetSignature(dig);
653 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
654 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
655 
656  switch (pubp->pubkey_algo) {
657  default:
658  break;
659  case PGPPUBKEYALGO_RSA:
660  rc = rpmbcGenerateRSA(dig);
661  break;
662  case PGPPUBKEYALGO_DSA:
663  rc = rpmbcGenerateDSA(dig);
664  break;
665 #ifdef NOTYET
667  rc = rpmbcGenerateELG(dig);
668  break;
669  case PGPPUBKEYALGO_ECDSA:
670  rc = rpmbcGenerateECDSA(dig);
671  break;
672 #endif
673  }
674 SPEW(!rc, rc, dig);
675  return rc;
676 }
677 
680 static /*@only@*/
681 char * pgpMpiHex(const rpmuint8_t *p)
682  /*@*/
683 {
684  size_t nb = pgpMpiLen(p);
685  char * t = (char *) xmalloc(2*nb + 1);
686  (void) pgpHexCvt(t, p+2, nb-2);
687  return t;
688 }
689 
693 static
694 int pgpMpiSet(const char * pre, unsigned int lbits,
695  /*@out@*/ void * dest, const rpmuint8_t * p,
696  /*@null@*/ const rpmuint8_t * pend)
697  /*@globals fileSystem @*/
698  /*@modifies fileSystem @*/
699 {
700  mpnumber * mpn = (mpnumber *) dest;
701  unsigned int mbits = pgpMpiBits(p);
702  unsigned int nbits;
703  unsigned int nbytes;
704  char * t;
705  unsigned int ix;
706 
707  if (pend != NULL && (p + ((mbits+7) >> 3)) > pend)
708  return 1;
709 
710  if (mbits > lbits)
711  return 1;
712 
713  nbits = (lbits > mbits ? lbits : mbits);
714  nbytes = ((nbits + 7) >> 3);
715  t = (char *) xmalloc(2*nbytes+1);
716  ix = 2 * ((nbits - mbits) >> 3);
717 
718 if (_pgp_debug)
719 fprintf(stderr, "*** mbits %u nbits %u nbytes %u t %p[%d] ix %u\n", mbits, nbits, nbytes, t, (2*nbytes+1), ix);
720  if (ix > 0) memset(t, (int)'0', ix);
721  { const char * s = pgpMpiHex(p);
722  strcpy(t+ix, s);
723  s = _free(s);
724  }
725 if (_pgp_debug)
726 fprintf(stderr, "*** %s %s\n", pre, t);
727  (void) mpnsethex(mpn, t);
728  t = _free(t);
729  return 0;
730 }
731 
732 static
733 int rpmbcMpiItem(const char * pre, pgpDig dig, int itemno,
734  const rpmuint8_t * p, /*@null@*/ const rpmuint8_t * pend)
735  /*@globals fileSystem @*/
736  /*@modifies fileSystem @*/
737 {
738  rpmbc bc = (rpmbc) dig->impl;
739  const char * s = NULL;
740  int rc = 0;
741 
742  switch (itemno) {
743  default:
744 assert(0);
745  case 50: /* ECDSA r */
746  case 51: /* ECDSA s */
747  case 60: /* ECDSA curve OID */
748  case 61: /* ECDSA Q */
749  break;
750  case 10: /* RSA m**d */
751  (void) mpnsethex(&bc->c, s = pgpMpiHex(p));
752 if (_pgp_debug && _pgp_print)
753 _spewMPN(" c", bc->c);
754  break;
755  case 20: /* DSA r */
756  rc = pgpMpiSet(pre, 160, &bc->r, p, pend);
757 if (_pgp_debug && _pgp_print)
758 _spewMPN(" r", bc->r);
759  break;
760  case 21: /* DSA s */
761  rc = pgpMpiSet(pre, 160, &bc->s, p, pend);
762 if (_pgp_debug && _pgp_print)
763 _spewMPN(" s", bc->s);
764  break;
765  case 30: /* RSA n */
766  (void) mpbsethex(&bc->rsa_keypair.n, s = pgpMpiHex(p));
767 if (_pgp_debug && _pgp_print)
768 _spewMPB(" n", bc->dsa_keypair.param.n);
769  break;
770  case 31: /* RSA e */
771  (void) mpnsethex(&bc->rsa_keypair.e, s = pgpMpiHex(p));
772 if (_pgp_debug && _pgp_print)
773 _spewMPN(" e", bc->rsa_keypair.e);
774  break;
775  case 40: /* DSA p */
776  (void) mpbsethex(&bc->dsa_keypair.param.p, s = pgpMpiHex(p));
777 if (_pgp_debug && _pgp_print)
778 _spewMPB(" p", bc->dsa_keypair.param.p);
779  break;
780  case 41: /* DSA q */
781  (void) mpbsethex(&bc->dsa_keypair.param.q, s = pgpMpiHex(p));
782 if (_pgp_debug && _pgp_print)
783 _spewMPB(" q", bc->dsa_keypair.param.q);
784  break;
785  case 42: /* DSA g */
786  (void) mpnsethex(&bc->dsa_keypair.param.g, s = pgpMpiHex(p));
787 if (_pgp_debug && _pgp_print)
788 _spewMPN(" g", bc->dsa_keypair.param.g);
789  break;
790  case 43: /* DSA y */
791  (void) mpnsethex(&bc->dsa_keypair.y, s = pgpMpiHex(p));
792 if (_pgp_debug && _pgp_print)
793 _spewMPN(" y", bc->dsa_keypair.y);
794  break;
795  }
796  s = _free(s);
797  return rc;
798 }
799 
800 /*@-mustmod@*/
801 static
802 void rpmbcClean(void * impl)
803  /*@modifies impl @*/
804 {
805  rpmbc bc = (rpmbc) impl;
806  if (bc != NULL) {
807  bc->nbits = 0;
808  bc->err = 0;
809  bc->badok = 0;
810  bc->digest = _free(bc->digest);
811  bc->digestlen = 0;
812 
813  randomGeneratorContextFree(&bc->rngc);
814 
815  rsakpFree(&bc->rsa_keypair);
816 
817  dlkp_pFree(&bc->dsa_keypair);
818 
819  dlkp_pFree(&bc->elg_keypair);
820 #ifdef NOTYET
821 dldp_pFree(&bc->elg_params);
822 #endif
823 
824  mpnfree(&bc->r);
825  mpnfree(&bc->s);
826  mpnfree(&bc->hm);
827  mpnfree(&bc->m);
828  mpnfree(&bc->c);
829  }
830 }
831 /*@=mustmod@*/
832 
833 static /*@null@*/
834 void * rpmbcFree(/*@only@*/ void * impl)
835  /*@modifies impl @*/
836 {
837  rpmbcClean(impl);
838  impl = _free(impl);
839  return NULL;
840 }
841 
842 static
843 void * rpmbcInit(void)
844  /*@*/
845 {
846  rpmbc bc = (rpmbc) xcalloc(1, sizeof(*bc));
847  return (void *) bc;
848 }
849 
851  rpmbcSetRSA,
852  rpmbcSetDSA,
853  rpmbcSetELG,
855 
856  rpmbcErrChk,
859 
862 };
863 
865 {
866  uint8_t pkt[8192];
867  uint8_t * be = pkt;
868  size_t pktlen;
869  time_t now = time(NULL);
870  uint32_t bt = now;
871  uint16_t bn;
872  pgpDigParams pubp = pgpGetPubkey(dig);
873  rpmbc bc = (rpmbc) dig->impl;
874  int xx;
875 
876  *be++ = 0x80 | (PGPTAG_PUBLIC_KEY << 2) | 0x01;
877  be += 2;
878 
879  *be++ = 0x04;
880  *be++ = (bt >> 24);
881  *be++ = (bt >> 16);
882  *be++ = (bt >> 8);
883  *be++ = (bt );
884  *be++ = pubp->pubkey_algo;
885 
886  bn = mpbits(bc->dsa_keypair.param.p.size, bc->dsa_keypair.param.p.modl);
887  bn += 7; bn &= ~7;
888  *be++ = (bn >> 8); *be++ = (bn );
889  xx = i2osp(be, bn/8, bc->dsa_keypair.param.p.modl, bc->dsa_keypair.param.p.size);
890  be += bn/8;
891 
892  bn = mpbits(bc->dsa_keypair.param.q.size, bc->dsa_keypair.param.q.modl);
893  bn += 7; bn &= ~7;
894  *be++ = (bn >> 8); *be++ = (bn );
895  xx = i2osp(be, bn/8, bc->dsa_keypair.param.q.modl, bc->dsa_keypair.param.q.size);
896  be += bn/8;
897 
898  bn = mpbits(bc->dsa_keypair.param.g.size, bc->dsa_keypair.param.g.data);
899  bn += 7; bn &= ~7;
900  *be++ = (bn >> 8); *be++ = (bn );
901  xx = i2osp(be, bn/8, bc->dsa_keypair.param.g.data, bc->dsa_keypair.param.g.size);
902  be += bn/8;
903 
904  bn = mpbits(bc->dsa_keypair.y.size, bc->dsa_keypair.y.data);
905  bn += 7; bn &= ~7;
906  *be++ = (bn >> 8); *be++ = (bn );
907  xx = i2osp(be, bn/8, bc->dsa_keypair.y.data, bc->dsa_keypair.y.size);
908  be += bn/8;
909 
910  pktlen = (be - pkt);
911  bn = pktlen - 3;
912  pkt[1] = (bn >> 8);
913  pkt[2] = (bn );
914 
915  xx = pgpPubkeyFingerprint(pkt, pktlen, pubp->signid);
916 
917  dig->pub = memcpy(xmalloc(pktlen), pkt, pktlen);
918  dig->publen = pktlen;
919 
920  return 0;
921 }
922 
923 int rpmbcExportSignature(pgpDig dig, /*@only@*/ DIGEST_CTX ctx)
924 {
925  uint8_t pkt[8192];
926  uint8_t * be = pkt;
927  uint8_t * h;
928  size_t pktlen;
929  time_t now = time(NULL);
930  uint32_t bt;
931  uint16_t bn;
932  pgpDigParams pubp = pgpGetPubkey(dig);
933  pgpDigParams sigp = pgpGetSignature(dig);
934  rpmbc bc = (rpmbc) dig->impl;
935  int xx;
936 
937  sigp->tag = PGPTAG_SIGNATURE;
938  *be++ = 0x80 | (sigp->tag << 2) | 0x01;
939  be += 2; /* pktlen */
940 
941  sigp->hash = be;
942  *be++ = sigp->version = 0x04; /* version */
943  *be++ = sigp->sigtype = PGPSIGTYPE_BINARY; /* sigtype */
944  *be++ = sigp->pubkey_algo = pubp->pubkey_algo; /* pubkey_algo */
945  *be++ = sigp->hash_algo; /* hash_algo */
946 
947  be += 2; /* skip hashd length */
948  h = (uint8_t *) be;
949 
950  *be++ = 1 + 4; /* signature creation time */
952  bt = now;
953  *be++ = sigp->time[0] = (bt >> 24);
954  *be++ = sigp->time[1] = (bt >> 16);
955  *be++ = sigp->time[2] = (bt >> 8);
956  *be++ = sigp->time[3] = (bt );
957 
958  *be++ = 1 + 4; /* signature expiration time */
960  bt = 30 * 24 * 60 * 60; /* XXX 30 days from creation */
961  *be++ = sigp->expire[0] = (bt >> 24);
962  *be++ = sigp->expire[1] = (bt >> 16);
963  *be++ = sigp->expire[2] = (bt >> 8);
964  *be++ = sigp->expire[3] = (bt );
965 
966 /* key expiration time (only on a self-signature) */
967 
968  *be++ = 1 + 1; /* exportable certification */
970  *be++ = 0;
971 
972  *be++ = 1 + 1; /* revocable */
973  *be++ = PGPSUBTYPE_REVOCABLE;
974  *be++ = 0;
975 
976 /* notation data */
977 
978  sigp->hashlen = (be - h); /* set hashed length */
979  h[-2] = (sigp->hashlen >> 8);
980  h[-1] = (sigp->hashlen );
981  sigp->hashlen += sizeof(struct pgpPktSigV4_s);
982 
983  if (sigp->hash != NULL)
984  xx = rpmDigestUpdate(ctx, sigp->hash, sigp->hashlen);
985 
986  if (sigp->version == (rpmuint8_t) 4) {
987  uint8_t trailer[6];
988  trailer[0] = sigp->version;
989  trailer[1] = (rpmuint8_t)0xff;
990  trailer[2] = (sigp->hashlen >> 24);
991  trailer[3] = (sigp->hashlen >> 16);
992  trailer[4] = (sigp->hashlen >> 8);
993  trailer[5] = (sigp->hashlen );
994  xx = rpmDigestUpdate(ctx, trailer, sizeof(trailer));
995  }
996 
997  sigp->signhash16[0] = 0x00;
998  sigp->signhash16[1] = 0x00;
999  xx = pgpImplSetDSA(ctx, dig, sigp); /* XXX signhash16 check always fails */
1000  h = (uint8_t *) bc->digest;
1001  sigp->signhash16[0] = h[0];
1002  sigp->signhash16[1] = h[1];
1003 
1004  xx = pgpImplSign(dig);
1005 assert(xx == 1);
1006 
1007  be += 2; /* skip unhashed length. */
1008  h = be;
1009 
1010  *be++ = 1 + 8; /* issuer key ID */
1011  *be++ = PGPSUBTYPE_ISSUER_KEYID;
1012  *be++ = pubp->signid[0];
1013  *be++ = pubp->signid[1];
1014  *be++ = pubp->signid[2];
1015  *be++ = pubp->signid[3];
1016  *be++ = pubp->signid[4];
1017  *be++ = pubp->signid[5];
1018  *be++ = pubp->signid[6];
1019  *be++ = pubp->signid[7];
1020 
1021  bt = (be - h); /* set unhashed length */
1022  h[-2] = (bt >> 8);
1023  h[-1] = (bt );
1024 
1025  *be++ = sigp->signhash16[0]; /* signhash16 */
1026  *be++ = sigp->signhash16[1];
1027 
1028  bn = mpbits(bc->r.size, bc->r.data);
1029  bn += 7; bn &= ~7;
1030  *be++ = (bn >> 8);
1031  *be++ = (bn );
1032  xx = i2osp(be, bn/8, bc->r.data, bc->r.size);
1033  be += bn/8;
1034 
1035  bn = mpbits(bc->s.size, bc->s.data);
1036  bn += 7; bn &= ~7;
1037  *be++ = (bn >> 8);
1038  *be++ = (bn );
1039  xx = i2osp(be, bn/8, bc->s.data, bc->s.size);
1040  be += bn/8;
1041 
1042  pktlen = (be - pkt); /* packet length */
1043  bn = pktlen - 3;
1044  pkt[1] = (bn >> 8);
1045  pkt[2] = (bn );
1046 
1047  dig->sig = memcpy(xmalloc(pktlen), pkt, pktlen);
1048  dig->siglen = pktlen;
1049 
1050  return 0;
1051 
1052 }
pgpDigParams pgpGetPubkey(pgpDig dig)
Return OpenPGP pubkey parameters.
Definition: rpmpgp.c:1232
struct pgpImplVecs_s rpmbcImplVecs
Definition: rpmbc.c:850
int _pgp_print
Definition: rpmpgp.c:32
static const char * pgpValStr(pgpValTbl vs, rpmuint8_t val)
Return string representation of am OpenPGP value.
Definition: rpmpgp.h:1200
static const char * _pgpHashAlgo2Name(uint32_t algo)
Definition: rpmbc.c:31
struct rpmgc_s * rpmgc
Definition: rpmgc.h:19
static void * rpmbcFree(void *impl)
Definition: rpmbc.c:834
struct pgpDigParams_s * pgpDigParams
Definition: rpmiotypes.h:87
struct pgpValTbl_s pgpHashTbl[]
Hash (string, value) pairs.
Definition: rpmpgp.c:144
static int rpmbcSetECDSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Definition: rpmbc.c:482
5.2.3.
Definition: rpmpgp.h:417
static int rpmbcGenerateDSA(pgpDig dig)
Definition: rpmbc.c:314
static int pgpImplSign(pgpDig dig)
Definition: rpmpgp.h:1851
static int _rpmbc_debug
Definition: rpmbc.c:23
static int rpmbcSign(pgpDig dig)
Definition: rpmbc.c:618
static int pgpImplSetDSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Definition: rpmpgp.h:1769
static int rpmbcSetRSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Definition: rpmbc.c:109
static int rpmbcErrChk(pgpDig dig, const char *msg, int rc, unsigned expected)
Definition: rpmbc.c:544
void * xcalloc(size_t nmemb, size_t size)
Definition: rpmmalloc.c:301
int rpmDigestUpdate(DIGEST_CTX ctx, const void *data, size_t len)
Update context with next plain text buffer.
Definition: digest.c:907
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Definition: rpmiotypes.h:23
static int rpmbcAvailableCipher(pgpDig dig, int algo)
Definition: rpmbc.c:559
static int rpmbcAvailableDigest(pgpDig dig, int algo)
Definition: rpmbc.c:569
static unsigned int pgpMpiBits(const rpmuint8_t *p)
Return no.
Definition: rpmpgp.h:1115
pgpHashAlgo rpmDigestAlgo(DIGEST_CTX ctx)
Return digest algorithm identifier.
Definition: digest.c:188
static char * pgpHexCvt(char *t, const rpmuint8_t *s, size_t nbytes)
Convert to hex.
Definition: rpmpgp.h:1143
pgpDigParams pgpGetSignature(pgpDig dig)
Return OpenPGP signature parameters.
Definition: rpmpgp.c:1227
int _pgp_debug
Definition: rpmpgp.c:29
Digest private data.
Definition: digest.c:127
static void rpmbcClean(void *impl)
Definition: rpmbc.c:802
struct pgpDig_s * pgpDig
Definition: rpmiotypes.h:83
static int rpmbcGenerate(pgpDig dig)
Definition: rpmbc.c:648
#define _spewMPN(_N, _MPN)
Definition: rpmbc.c:64
static int rpmbcVerifyRSA(pgpDig dig)
Definition: rpmbc.c:182
int rpmbcExportSignature(pgpDig dig, DIGEST_CTX ctx)
Definition: rpmbc.c:923
struct pgpValTbl_s pgpPubkeyTbl[]
Definition: rpmpgp.c:103
static int rpmbcSetDSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Definition: rpmbc.c:248
static int rpmbcGenerateRSA(pgpDig dig)
Definition: rpmbc.c:221
static int rpmbcSetELG(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Definition: rpmbc.c:342
static unsigned int pgpMpiLen(const rpmuint8_t *p)
Return no.
Definition: rpmpgp.h:1128
static const char * prefix[]
Tables for prefixing and suffixing patterns, according to the -w, -x, and -F options.
Definition: rpmgrep.c:183
int pgpPubkeyFingerprint(const rpmuint8_t *pkt, size_t pktlen, rpmuint8_t *keyid)
Print/parse an OpenPGP subtype packet.
Definition: rpmpgp.c:970
struct rpmbc_s * rpmbc
Definition: rpmbc.h:37
static char * pgpMpiHex(const rpmuint8_t *p)
Definition: rpmbc.c:681
char * stpcpy(char *dest, const char *src)
static void * rpmbcInit(void)
Definition: rpmbc.c:843
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
#define _spewMPB(_N, _MPB)
Definition: rpmbc.c:59
#define SPEW(_t, _rc, _dig)
Definition: rpmbc.c:25
static int rpmbcVerify(pgpDig dig)
Definition: rpmbc.c:588
const char * rpmDigestASN1(DIGEST_CTX ctx)
Return digest ASN1 oid string.
Definition: digest.c:203
static int rpmbcMpiItem(const char *pre, pgpDig dig, int itemno, const rpmuint8_t *p, const rpmuint8_t *pend)
Definition: rpmbc.c:733
int rpmDigestFinal(DIGEST_CTX ctx, void *datap, size_t *lenp, int asAscii)
Return digest and destroy context.
Definition: digest.c:921
#define xmalloc
Definition: system.h:33
static int rpmbcAvailablePubkey(pgpDig dig, int algo)
Definition: rpmbc.c:579
static int rpmbcSignRSA(pgpDig dig)
Definition: rpmbc.c:195
int rpmbcExportPubkey(pgpDig dig)
Definition: rpmbc.c:864
static const char * _pgpPubkeyAlgo2Name(uint32_t algo)
Definition: rpmbc.c:36
static int pgpMpiSet(const char *pre, unsigned int lbits, void *dest, const rpmuint8_t *p, const rpmuint8_t *pend)
Definition: rpmbc.c:694
static int rpmbcSignDSA(pgpDig dig)
Definition: rpmbc.c:292
static int rpmbcVerifyDSA(pgpDig dig)
Definition: rpmbc.c:272
static unsigned char nibble(char c)
Convert hex to binary nibble.
Definition: rpmbc.c:47