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