rpm  5.4.15
rpmssl.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 #include <rpmlog.h>
7 
8 #include <rpmiotypes.h>
9 #define _RPMPGP_INTERNAL
10 #if defined(WITH_SSL)
11 
12 #if defined(__LCLINT__) && !defined(__i386__)
13 #define __i386__
14 #endif
15 
16 #define _RPMSSL_INTERNAL
17 #include <rpmssl.h>
18 #endif
19 
20 #include "debug.h"
21 
22 #if defined(WITH_SSL)
23 
24 /*@access pgpDig @*/
25 /*@access pgpDigParams @*/
26 
27 /*@-redecl@*/
28 /*@unchecked@*/
29 extern int _pgp_debug;
30 
31 /*@unchecked@*/
32 extern int _pgp_print;
33 /*@=redecl@*/
34 
35 /*@unchecked@*/
36 static int _rpmssl_debug;
37 
38 #define SPEW(_t, _rc, _dig) \
39  { if ((_t) || _rpmssl_debug || _pgp_debug < 0) \
40  fprintf(stderr, "<-- %s(%p) %s\t%s/%s\n", __FUNCTION__, (_dig), \
41  ((_rc) ? "OK" : "BAD"), (_dig)->pubkey_algoN, (_dig)->hash_algoN); \
42  }
43 
49 static
50 unsigned char nibble(char c)
51  /*@*/
52 {
53  if (c >= '0' && c <= '9')
54  return (unsigned char) (c - '0');
55  if (c >= 'A' && c <= 'F')
56  return (unsigned char)((int)(c - 'A') + 10);
57  if (c >= 'a' && c <= 'f')
58  return (unsigned char)((int)(c - 'a') + 10);
59  return (unsigned char) '\0';
60 }
61 
62 static unsigned char * rpmsslBN2bin(const char * msg, const BIGNUM * s, size_t maxn)
63 {
64  unsigned char * t = (unsigned char *) xcalloc(1, maxn);
65 /*@-modunconnomods@*/
66  size_t nt = BN_bn2bin(s, t);
67 /*@=modunconnomods@*/
68 
69  if (nt < maxn) {
70  size_t pad = (maxn - nt);
71  memmove(t+pad, t, nt);
72  memset(t, 0, pad);
73  }
74  return t;
75 }
76 
77 /*==============================================================*/
78 static const EVP_MD * mapHash(unsigned hash_algo)
79 {
80  const EVP_MD * md = NULL;
81 
82  switch (hash_algo) {
83 #ifndef OPENSSL_NO_MD2
84  case PGPHASHALGO_MD2: md = EVP_md2(); break;
85 #endif
86 #ifndef OPENSSL_NO_MD4
87  case PGPHASHALGO_MD4: md = EVP_md4(); break;
88 #endif
89 #ifndef OPENSSL_NO_MD5
90  case PGPHASHALGO_MD5: md = EVP_md5(); break;
91 #endif
92 #ifndef OPENSSL_NO_RIPEMD
93  case PGPHASHALGO_RIPEMD160: md = EVP_ripemd160(); break;
94 #endif
95 #ifndef OPENSSL_NO_SHA
96  case PGPHASHALGO_SHA1: md = EVP_sha1(); break;
97 #endif
98 #ifndef OPENSSL_NO_SHA256
99  case PGPHASHALGO_SHA224: md = EVP_sha224(); break;
100  case PGPHASHALGO_SHA256: md = EVP_sha256(); break;
101 #endif
102 #ifndef OPENSSL_NO_SHA512
103  case PGPHASHALGO_SHA384: md = EVP_sha384(); break;
104  case PGPHASHALGO_SHA512: md = EVP_sha512(); break;
105 #endif
106  /* Anything not enabled above will just fall through... */
107  case PGPHASHALGO_TIGER192: /*@fallthrough@*/
108  case PGPHASHALGO_HAVAL_5_160: /*@fallthrough@*/
109  default:
110  md = EVP_md_null(); /* XXX FIXME */
111  break;
112  }
113  return md;
114 }
115 /*==============================================================*/
116 
117 static
118 int rpmsslSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
119  /*@modifies dig @*/
120 {
121  rpmssl ssl = (rpmssl) dig->impl;
122  unsigned int nb = 0;
123  const char * prefix = rpmDigestASN1(ctx);
124  const char * s;
125  uint8_t *t, *te;
126  int rc = 1; /* assume failure */
127 pgpDigParams pubp = pgpGetPubkey(dig);
128 assert(pubp->pubkey_algo == PGPPUBKEYALGO_RSA);
129 assert(sigp->pubkey_algo == PGPPUBKEYALGO_RSA);
130 dig->pubkey_algoN = pgpPubkeyAlgo2Name(sigp->pubkey_algo);
131 dig->hash_algoN = pgpHashAlgo2Name(sigp->hash_algo);
132 
133 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
134 assert(prefix != NULL);
135 ssl->md = mapHash(sigp->hash_algo); /* XXX unused with RSA */
136 
137 /* XXX FIXME: should this lazy free be done elsewhere? */
138 ssl->digest = _free(ssl->digest);
139 ssl->digestlen = 0;
140  rc = rpmDigestFinal(ctx, (void **)&ssl->digest, &ssl->digestlen, 0);
141 
142  /* Find the size of the RSA keys */
143 assert(ssl->pkey);
144  { RSA * rsa = EVP_PKEY_get0(ssl->pkey);
145 assert(rsa);
146  nb = RSA_size(rsa);
147  }
148 
149  /* Add PKCS1 padding */
150  t = te = (uint8_t *) xmalloc(nb);
151  memset(te, 0xff, nb);
152  te[0] = 0x00;
153  te[1] = 0x01;
154  te += nb - strlen(prefix)/2 - ssl->digestlen - 1;
155  *te++ = 0x00;
156  /* Add digest algorithm ASN1 prefix */
157  for (s = prefix; *s; s += 2)
158  *te++ = (rpmuint8_t) (nibble(s[0]) << 4) | nibble(s[1]);
159  memcpy(te, ssl->digest, ssl->digestlen);
160 
161  /* Set RSA hash. */
162 /*@-moduncon -noeffectuncon @*/
163 /* XXX FIXME: should this lazy free be done elsewhere? */
164  if (ssl->hm)
165  BN_free(ssl->hm);
166  ssl->hm = NULL;
167  ssl->hm = BN_bin2bn(t, nb, NULL);
168 /*@=moduncon =noeffectuncon @*/
169  t = _free(t);
170 
171  /* Compare leading 16 bits of digest for quick check. */
172  rc = memcmp(ssl->digest, sigp->signhash16, sizeof(sigp->signhash16));
173 
174  /* XXX FIXME: avoid spurious "BAD" error msg while signing. */
175  if (rc && sigp->signhash16[0] == 0 && sigp->signhash16[1] == 0)
176  rc = 0;
177 
178 SPEW(0, !rc, dig); /* XXX don't spew on mismatch. */
179  return rc;
180 }
181 
182 static
183 int rpmsslSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
184  /*@modifies dig @*/
185 {
186  rpmssl ssl = (rpmssl) dig->impl;
187  int rc;
188  int xx;
189 pgpDigParams pubp = pgpGetPubkey(dig);
190 assert(pubp->pubkey_algo == PGPPUBKEYALGO_DSA);
191 assert(sigp->pubkey_algo == PGPPUBKEYALGO_DSA);
192 dig->pubkey_algoN = pgpPubkeyAlgo2Name(sigp->pubkey_algo);
193 dig->hash_algoN = pgpHashAlgo2Name(sigp->hash_algo);
194 
195 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
196 ssl->md = mapHash(sigp->hash_algo);
197 
198  /* Set DSA hash. */
199 /* XXX FIXME: should this lazy free be done elsewhere? */
200 ssl->digest = _free(ssl->digest);
201 ssl->digestlen = 0;
202  xx = rpmDigestFinal(ctx, (void **)&ssl->digest, &ssl->digestlen, 0);
203 
204  /* Compare leading 16 bits of digest for quick check. */
205  rc = memcmp(ssl->digest, sigp->signhash16, sizeof(sigp->signhash16));
206 
207  /* XXX FIXME: avoid spurious "BAD" error msg while signing. */
208  if (rc && sigp->signhash16[0] == 0 && sigp->signhash16[1] == 0)
209  rc = 0;
210 
211 SPEW(0, !rc, dig); /* XXX don't spew on mismatch. */
212  return rc;
213 }
214 
215 static
216 int rpmsslSetELG(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
217  /*@*/
218 {
219  rpmssl ssl = (rpmssl) dig->impl;
220  int rc = 1; /* XXX always fail. */
221  int xx;
222 
223 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
224 
225 /* XXX FIXME: should this lazy free be done elsewhere? */
226 ssl->digest = _free(ssl->digest);
227 ssl->digestlen = 0;
228  xx = rpmDigestFinal(ctx, (void **)&ssl->digest, &ssl->digestlen, 0);
229 
230  /* Compare leading 16 bits of digest for quick check. */
231  rc = memcmp(ssl->digest, sigp->signhash16, sizeof(sigp->signhash16));
232 
233  /* XXX FIXME: avoid spurious "BAD" error msg while signing. */
234  if (rc && sigp->signhash16[0] == 0 && sigp->signhash16[1] == 0)
235  rc = 0;
236 
237 SPEW(0, !rc, dig); /* XXX don't spew on mismatch. */
238  return rc;
239 }
240 
241 static
242 int rpmsslSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
243  /*@*/
244 {
245  rpmssl ssl = (rpmssl) dig->impl;
246  int rc = 1; /* assume failure. */
247 pgpDigParams pubp = pgpGetPubkey(dig);
248 assert(pubp->pubkey_algo == PGPPUBKEYALGO_ECDSA);
249 assert(sigp->pubkey_algo == PGPPUBKEYALGO_ECDSA);
250 dig->pubkey_algoN = pgpPubkeyAlgo2Name(sigp->pubkey_algo);
251 dig->hash_algoN = pgpHashAlgo2Name(sigp->hash_algo);
252 
253 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
254 ssl->md = mapHash(sigp->hash_algo);
255 
256 /* XXX FIXME: should this lazy free be done elsewhere? */
257 ssl->digest = _free(ssl->digest);
258 ssl->digestlen = 0;
259  rc = rpmDigestFinal(ctx, &ssl->digest, &ssl->digestlen, 0);
260 
261  /* Compare leading 16 bits of digest for quick check. */
262  rc = memcmp(ssl->digest, sigp->signhash16, sizeof(sigp->signhash16));
263 
264  /* XXX FIXME: avoid spurious "BAD" error msg while signing. */
265  if (rc && sigp->signhash16[0] == 0 && sigp->signhash16[1] == 0)
266  rc = 0;
267 
268 SPEW(0, !rc, dig); /* XXX don't spew on mismatch. */
269  return rc;
270 }
271 
272 static int rpmsslErrChk(pgpDig dig, const char * msg, int rc, unsigned expected)
273 {
274 #ifdef NOTYET
275 rpmgc gc = dig->impl;
276  /* Was the return code the expected result? */
277  rc = (gcry_err_code(gc->err) != expected);
278  if (rc)
279  fail("%s failed: %s\n", msg, gpg_strerror(gc->err));
280 /* XXX FIXME: rpmsslStrerror */
281 #else
282  rc = (rc == 0); /* XXX impedance match 1 -> 0 on success */
283 #endif
284  return rc; /* XXX 0 on success */
285 }
286 
287 static int rpmsslAvailableCipher(pgpDig dig, int algo)
288 {
289  int rc = 0; /* assume available */
290 #ifdef NOTYET
291  rc = rpmgsslvailable(dig->impl, algo,
292  (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5));
293 #endif /* _RPMGC_INTERNAL */
294  return rc;
295 }
296 
297 static int rpmsslAvailableDigest(pgpDig dig, int algo)
298 {
299  int rc = 0; /* assume available */
300 #ifdef NOTYET
301  rc = rpmgsslvailable(dig->impl, algo,
302  (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5));
303 #endif /* _RPMGC_INTERNAL */
304  return rc;
305 }
306 
307 static int rpmsslAvailablePubkey(pgpDig dig, int algo)
308 {
309  int rc = 0; /* assume available */
310 #ifdef NOTYET
311  rc = rpmsslAvailable(dig->impl, algo, gcry_pk_test_algo(algo));
312 #endif /* _RPMGC_INTERNAL */
313  return rc;
314 }
315 
316 static int rpmsslVerify(pgpDig dig)
317 {
318  rpmssl ssl = dig->impl;
319  unsigned char * t = ssl->digest;
320  size_t nt = ssl->digestlen;
321  unsigned char * hm = NULL; /* XXX for RSA */
322  EVP_PKEY_CTX *ctx = NULL;
323  int rc = 0; /* assume failure */
324 pgpDigParams pubp = pgpGetPubkey(dig);
325 
326 assert(ssl->sig != NULL && ssl->siglen > 0);
327 
328  if ((ctx = EVP_PKEY_CTX_new(ssl->pkey, NULL)) == NULL
329  || EVP_PKEY_verify_init(ctx) != 1)
330  goto exit;
331 
332  switch (pubp->pubkey_algo) { /* refactor pubkey_algo to dig? */
333  default:
334  goto exit;
335  break;
336  case PGPPUBKEYALGO_RSA:
337  { RSA * rsa = EVP_PKEY_get0(ssl->pkey);
338  size_t maxn = RSA_size(rsa);
339  size_t i;
340 
341 assert(ssl->hm);
342  /* XXX Find end of PKCS1 padding */
343  hm = rpmsslBN2bin("hm", ssl->hm, maxn);
344  for (i = 2; i < maxn; i++) {
345  if (hm[i] == 0xff)
346  continue;
347  i++;
348  break;
349  }
350  t = hm+i;
351  nt = maxn - i;
352 
353  /* XXX EVP_PKEY_verify(w/o md) -> RSA_public_decrypt */
354  if (!EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING))
355  goto exit;
356 
357  } break;
358  case PGPPUBKEYALGO_DSA:
359  if (!EVP_PKEY_CTX_set_signature_md(ctx, ssl->md))
360  goto exit;
361  break;
363 #ifdef NOTYET
364  rc = rpmsslVerifyELG(dig);
365 #endif
366  goto exit;
367  break;
368  case PGPPUBKEYALGO_ECDSA:
369 #if !defined(OPENSSL_NO_ECDSA)
370  if (!EVP_PKEY_CTX_set_signature_md(ctx, ssl->md))
371 #endif
372  goto exit;
373  break;
374  }
375 
376  if (EVP_PKEY_verify(ctx, ssl->sig, ssl->siglen, t, nt) == 1)
377  rc = 1;
378 
379 exit:
380  if (hm)
381  hm = _free(hm);
382  if (ctx)
383  EVP_PKEY_CTX_free(ctx);
384 SPEW(!rc, rc, dig);
385  return rc;
386 }
387 
388 static int rpmsslSign(pgpDig dig)
389 {
390  rpmssl ssl = dig->impl;
391  unsigned char * t = ssl->digest;
392  size_t nt = ssl->digestlen;
393  unsigned char * hm = NULL; /* XXX for RSA */
394  EVP_PKEY_CTX *ctx = NULL;
395  int rc = 0; /* assume failure */
396 pgpDigParams pubp = pgpGetPubkey(dig);
397 
398 /* XXX FIXME: should this lazy free be done elsewhere? */
399 ssl->sig = _free(ssl->sig);
400 ssl->siglen = 0;
401 
402  if ((ctx = EVP_PKEY_CTX_new(ssl->pkey, NULL)) == NULL
403  || EVP_PKEY_sign_init(ctx) != 1)
404  goto exit;
405 
406  switch (pubp->pubkey_algo) { /* refactor pubkey_algo to dig? */
407  default:
408  goto exit;
409  break;
410  case PGPPUBKEYALGO_RSA:
411  { RSA * rsa = EVP_PKEY_get0(ssl->pkey);
412  size_t maxn = RSA_size(rsa);
413  size_t i;
414 
415 assert(ssl->hm);
416  /* XXX Find end of PKCS1 padding */
417  hm = rpmsslBN2bin("hm", ssl->hm, maxn);
418  for (i = 2; i < maxn; i++) {
419  if (hm[i] == 0xff)
420  continue;
421  i++;
422  break;
423  }
424  t = hm+i;
425  nt = maxn - i;
426 
427  /* XXX EVP_PKEY_sign(w/o md) -> RSA_private_encrypt */
428  if (!EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING))
429  goto exit;
430 
431  } break;
432  case PGPPUBKEYALGO_DSA:
433  if (!EVP_PKEY_CTX_set_signature_md(ctx, ssl->md))
434  goto exit;
435  break;
437 #ifdef NOTYET
438  rc = rpmsslSignELG(dig);
439 #endif
440  goto exit;
441  break;
442  case PGPPUBKEYALGO_ECDSA:
443 #if !defined(OPENSSL_NO_ECDSA)
444  if (!EVP_PKEY_CTX_set_signature_md(ctx, ssl->md))
445  goto exit;
446  { EC_KEY * ec = EVP_PKEY_get0(ssl->pkey);
447  int xx;
448 
449  /* XXX Restore the copy of the private key (which is going AWOL). */
450  if (EC_KEY_get0_private_key(ec) == NULL && ssl->priv != NULL) {
451  xx = EC_KEY_set_private_key(ec, ssl->priv);
452 assert(xx == 1);
453  }
454 
455  }
456 #endif
457  break;
458  }
459 
460  if (EVP_PKEY_sign(ctx, NULL, &ssl->siglen, t, nt) == 1
461  && (ssl->sig = xmalloc(ssl->siglen)) != NULL
462  && EVP_PKEY_sign(ctx, ssl->sig, &ssl->siglen, t, nt) == 1)
463  rc = 1;
464 
465 exit:
466  if (rc != 1) {
467  ssl->sig = _free(ssl->sig);
468  ssl->siglen = 0;
469  }
470  if (hm)
471  hm = _free(hm);
472  if (ctx)
473  EVP_PKEY_CTX_free(ctx);
474 SPEW(!rc, rc, dig);
475  return rc;
476 }
477 
478 static int rpmsslGenerate(pgpDig dig)
479 {
480  rpmssl ssl = dig->impl;
481  EVP_PKEY_CTX * ctx = NULL;
482  EVP_PKEY * param = NULL;
483  BIGNUM * bn = NULL;
484  static unsigned long _e = 0x10001; /* XXX RSA */
485  int rc = 0; /* assume failure */
486 pgpDigParams pubp = pgpGetPubkey(dig);
487 pgpDigParams sigp = pgpGetSignature(dig);
488 assert(pubp->pubkey_algo);
489 assert(sigp->hash_algo);
490 
491 assert(dig->pubkey_algoN);
492 assert(dig->hash_algoN);
493 
494 assert(ssl->pkey == NULL);
495 
496  switch (pubp->pubkey_algo) { /* refactor pubkey_algo to dig? */
497  default:
498  break;
499  case PGPPUBKEYALGO_RSA:
500 if (ssl->nbits == 0) ssl->nbits = 2048; /* XXX FIXME */
501 assert(ssl->nbits);
502  if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) != NULL
503  && EVP_PKEY_keygen_init(ctx) == 1
504  && (bn = BN_new()) != NULL
505  && BN_set_word(bn, _e) == 1
506  && EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, bn) == 1
507  && EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, ssl->nbits) == 1
508  && EVP_PKEY_keygen(ctx, &ssl->pkey) == 1)
509  rc = 1;
510  break;
511  case PGPPUBKEYALGO_DSA:
512  /* XXX Set the no. of qbits based on the digest being used. */
513  if (ssl->qbits == 0)
514  switch (sigp->hash_algo) {
515  default: /* XXX default */
516  case PGPHASHALGO_SHA1: ssl->qbits = 160; break;
517  case PGPHASHALGO_SHA224: ssl->qbits = 224; break;
518  case PGPHASHALGO_SHA256: ssl->qbits = 256; break;
519 #ifdef PAINFUL /* XXX openssl-1.0.1e-16 permits only {160,224,256} */
520  case PGPHASHALGO_SHA384: ssl->qbits = 384; break;
521  case PGPHASHALGO_SHA512: ssl->qbits = 512; break;
522 #else
523  case PGPHASHALGO_SHA384: ssl->qbits = 256; break;
524  case PGPHASHALGO_SHA512: ssl->qbits = 256; break;
525 #endif
526  }
527 assert(ssl->qbits);
528 
529  /* XXX Set the no. of nbits for non-truncated digest in use. */
530  if (ssl->nbits == 0)
531  switch (ssl->qbits) {
532  default: /* XXX default */
533  case 160: ssl->nbits = 1024; break;
534  case 224: ssl->nbits = 2048; break;
535 #ifdef PAINFUL
536  case 256: ssl->nbits = 3072; break;
537  case 384: ssl->nbits = 7680; break;
538  case 512: ssl->nbits = 15360; break;
539 #else
540  case 256: ssl->nbits = 2048; break;
541  case 384: ssl->nbits = 2048; ssl->qbits = 256; break;
542  case 512: ssl->nbits = 2048; ssl->qbits = 256; break;
543 #endif
544  }
545 assert(ssl->nbits);
546 
547  if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL)) == NULL
548  || EVP_PKEY_paramgen_init(ctx) != 1
549  || EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, ssl->nbits) != 1
550  || EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
551  EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, ssl->qbits, NULL) != 1
552  || EVP_PKEY_paramgen(ctx, &param) != 1)
553  goto exit;
554  EVP_PKEY_CTX_free(ctx);
555  if ((ctx = EVP_PKEY_CTX_new(param, NULL)) != NULL
556  && EVP_PKEY_keygen_init(ctx) == 1
557  && EVP_PKEY_keygen(ctx, &ssl->pkey) == 1)
558  rc = 1;
559  break;
561 #ifdef NOTYET
562  rc = rpmsslGenerateELG(dig);
563 #endif
564  break;
565  case PGPPUBKEYALGO_ECDSA:
566 #if !defined(OPENSSL_NO_ECDSA)
567  /* XXX Set the no. of bits based on the digest being used. */
568  if (ssl->nbits == 0)
569  switch (sigp->hash_algo) {
570  case PGPHASHALGO_MD5: ssl->nbits = 128; break;
571  case PGPHASHALGO_TIGER192: ssl->nbits = 192; break;
572  case PGPHASHALGO_SHA224: ssl->nbits = 224; break;
573  default: /* XXX default */
574  case PGPHASHALGO_SHA256: ssl->nbits = 256; break;
575  case PGPHASHALGO_SHA384: ssl->nbits = 384; break;
576  case PGPHASHALGO_SHA512: ssl->nbits = 521; break;
577  }
578 assert(ssl->nbits);
579 
580  /* XXX Choose the curve parameters from the no. of digest bits. */
581  if (ssl->curveN == NULL) /* XXX FIXME */
582  switch (ssl->nbits) { /* XXX only NIST prime curves for now */
583  default: goto exit; /*@notreached@*/ break;
584  case 192:
585  ssl->curveN = xstrdup("nistp192"); ssl->nid = 711;
586  break;
587  case 224:
588  ssl->curveN = xstrdup("nistp224"); ssl->nid = NID_secp224r1;
589  break;
590  case 256:
591  ssl->curveN = xstrdup("nistp256"); ssl->nid = NID_X9_62_prime256v1;
592  break;
593  case 384:
594  ssl->curveN = xstrdup("nistp384"); ssl->nid = NID_secp384r1;
595  break;
596  case 512: /* XXX sanity */
597  case 521:
598  ssl->curveN = xstrdup("nistp521"); ssl->nid = NID_secp521r1;
599  break;
600  }
601 assert(ssl->curveN);
602 
603  if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL
604  || EVP_PKEY_paramgen_init(ctx) != 1
605  || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, ssl->nid) != 1
606  || EVP_PKEY_paramgen(ctx, &param) != 1)
607  goto exit;
608  EVP_PKEY_CTX_free(ctx);
609  if ((ctx = EVP_PKEY_CTX_new(param, NULL)) != NULL
610  && EVP_PKEY_keygen_init(ctx) == 1
611  && EVP_PKEY_keygen(ctx, &ssl->pkey) == 1)
612  rc = 1;
613  /* XXX Save a copy of the private key (which is going AWOL). */
614  {
615  EC_KEY * ec = EVP_PKEY_get0(ssl->pkey);
616  if (ssl->priv)
617  BN_free(ssl->priv);
618  ssl->priv = NULL;
619  ssl->priv = BN_dup(EC_KEY_get0_private_key(ec));
620  }
621 #endif
622  break;
623  }
624 
625 exit:
626  if (rc == 1) {
627  /* XXX OpenSSL BUG(iirc): ensure that the asn1 flag is set. */
628  if (EVP_PKEY_type(ssl->pkey->type) == EVP_PKEY_EC) {
629  EC_KEY * ec = EVP_PKEY_get1_EC_KEY(ssl->pkey);
630  EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
631  EC_KEY_free(ec);
632  }
633  } else {
634  if (ssl->pkey)
635  EVP_PKEY_free(ssl->pkey);
636  ssl->pkey = NULL;
637  }
638  if (param)
639  EVP_PKEY_free(param);
640  if (ctx)
641  EVP_PKEY_CTX_free(ctx);
642 
643 SPEW(!rc, rc, dig);
644  return rc;
645 }
646 
647 static
648 int rpmsslMpiItem(/*@unused@*/ const char * pre, pgpDig dig, int itemno,
649  const rpmuint8_t * p,
650  /*@unused@*/ /*@null@*/ const rpmuint8_t * pend)
651  /*@*/
652 {
653  rpmssl ssl = (rpmssl) dig->impl;
654  unsigned int nb = (pend >= p ? (pend - p) : 0);
655  unsigned int mbits = (((8 * (nb - 2)) + 0x1f) & ~0x1f);
656  unsigned char * q;
657  unsigned int nz;
658  int rc = 0;
659  int xx;
660 
661 /*@-moduncon@*/
662  switch (itemno) {
663  default:
664 assert(0);
665  break;
666  case 10: /* RSA m**d */
667 assert(ssl->sig == NULL);
668  ssl->nbits = mbits;
669  ssl->siglen = mbits/8;
670  ssl->sig = xmalloc(ssl->siglen);
671  nz = ssl->siglen - (nb - 2);
672  if (nz) /* XXX resurrect leading zero bytes. */
673  memset(ssl->sig, 0, nz);
674  memcpy(ssl->sig+nz, p+2, nb-2);
675  break;
676  case 20: /* DSA r */
677 assert(ssl->dsasig == NULL);
678  ssl->qbits = mbits;
679  ssl->dsasig = DSA_SIG_new();
680  ssl->dsasig->r = BN_bin2bn(p+2, nb-2, ssl->dsasig->r);
681  break;
682  case 21: /* DSA s */
683 assert(ssl->dsasig != NULL);
684 assert(mbits == ssl->qbits);
685  ssl->dsasig->s = BN_bin2bn(p+2, nb-2, ssl->dsasig->s);
686  ssl->siglen = i2d_DSA_SIG(ssl->dsasig, NULL);
687  ssl->sig = xmalloc(ssl->siglen);
688  q = ssl->sig;
689  xx = i2d_DSA_SIG(ssl->dsasig, &q);
690 assert(xx == (int)ssl->siglen);
691  DSA_SIG_free(ssl->dsasig);
692  ssl->dsasig = NULL;
693  break;
694  case 30: /* RSA n */
695 assert(ssl->rsa == NULL);
696  ssl->nbits = mbits;
697  ssl->rsa = RSA_new();
698  ssl->rsa->n = BN_bin2bn(p+2, nb-2, ssl->rsa->n);
699  break;
700  case 31: /* RSA e */
701 assert(ssl->rsa != NULL);
702  ssl->rsa->e = BN_bin2bn(p+2, nb-2, ssl->rsa->e);
703 assert(ssl->pkey == NULL);
704  ssl->pkey = EVP_PKEY_new();
705  xx = EVP_PKEY_assign_RSA(ssl->pkey, ssl->rsa);
706 assert(xx);
707  ssl->rsa = NULL;
708  break;
709  case 40: /* DSA p */
710 assert(ssl->dsa == NULL);
711  ssl->nbits = mbits;
712  ssl->dsa = DSA_new();
713  ssl->dsa->p = BN_bin2bn(p+2, nb-2, ssl->dsa->p);
714  break;
715  case 41: /* DSA q */
716 assert(ssl->dsa != NULL);
717  ssl->qbits = mbits;
718  ssl->dsa->q = BN_bin2bn(p+2, nb-2, ssl->dsa->q);
719  break;
720  case 42: /* DSA g */
721 assert(ssl->dsa != NULL);
722 assert(mbits == ssl->nbits);
723  ssl->dsa->g = BN_bin2bn(p+2, nb-2, ssl->dsa->g);
724  break;
725  case 43: /* DSA y */
726 assert(ssl->dsa != NULL);
727 assert(mbits == ssl->nbits);
728  ssl->dsa->pub_key = BN_bin2bn(p+2, nb-2, ssl->dsa->pub_key);
729 assert(ssl->pkey == NULL);
730  ssl->pkey = EVP_PKEY_new();
731  xx = EVP_PKEY_assign_DSA(ssl->pkey, ssl->dsa);
732 assert(xx);
733  ssl->dsa = NULL;
734  break;
735  case 50: /* ECDSA r */
736 assert(ssl->ecdsasig == NULL);
737  ssl->qbits = mbits;
738  ssl->ecdsasig = ECDSA_SIG_new();
739  ssl->ecdsasig->r = BN_bin2bn(p+2, nb-2, ssl->ecdsasig->r);
740  break;
741  case 51: /* ECDSA s */
742 #if !defined(OPENSSL_NO_ECDSA)
743 assert(ssl->ecdsasig != NULL);
744 assert(mbits == ssl->qbits);
745  ssl->ecdsasig->s = BN_bin2bn(p+2, nb-2, ssl->ecdsasig->s);
746  ssl->siglen = i2d_ECDSA_SIG(ssl->ecdsasig, NULL);
747  ssl->sig = xmalloc(ssl->siglen);
748  q = ssl->sig;
749  xx = i2d_ECDSA_SIG(ssl->ecdsasig, &q);
750  ECDSA_SIG_free(ssl->ecdsasig);
751  ssl->ecdsasig = NULL;
752 #endif /* !OPENSSL_NO_ECDSA */
753  break;
754  case 60: /* ECDSA curve OID */
755 #if !defined(OPENSSL_NO_ECDSA)
756  ssl->nid = 0;
757  { size_t nc = EC_get_builtin_curves(NULL, 100);
758  EC_builtin_curve * c = alloca(nc * sizeof(*c));
759  size_t i;
760  (void) EC_get_builtin_curves(c, nc);
761  for (i = 0; i < nc; i++) {
762  ASN1_OBJECT * o = OBJ_nid2obj(c[i].nid);
763  if (nb != (unsigned)o->length)
764  continue;
765  if (memcmp(p, o->data, nb))
766  continue;
767  ssl->curveN = xstrdup(o->sn);
768  ssl->nid = c[i].nid;
769  break;
770  }
771  switch (ssl->nid) {
772  case NID_X9_62_prime192v1:
773  ssl->nbits = 192;
774  break;
775  case NID_secp224r1:
776  ssl->nbits = 224;
777  break;
778  default: /* XXX default to NIST P-256 */
779  ssl->curveN = _free(ssl->curveN);
780  ssl->curveN = xstrdup("nistp256");
781  ssl->nid = NID_X9_62_prime256v1;
782  ssl->nbits = 256; /* coverity #1214083 */
783  break;
784  case NID_X9_62_prime256v1:
785  ssl->nbits = 256;
786  break;
787  case NID_secp384r1:
788  ssl->nbits = 384;
789  break;
790  case NID_secp521r1:
791  ssl->nbits = 521;
792  break;
793  }
794  }
795 #else
796 fprintf(stderr, " OID[%4u]: %s\n", nb, pgpHexStr(p, nb));
797  rc = 1;
798 #endif /* !OPENSSL_NO_ECDSA */
799  break;
800  case 61: /* ECDSA Q */
801  mbits = pgpMpiBits(p);
802  nb = pgpMpiLen(p);
803 #if !defined(OPENSSL_NO_ECDSA)
804 assert(ssl->nid);
805  { EC_KEY * ec = EC_KEY_new_by_curve_name(ssl->nid);
806  const unsigned char *q;
807 
808 assert(ec);
809  q = p+2;
810  ec = o2i_ECPublicKey(&ec, &q, nb-2);
811 assert(ec);
812 
813 if (ssl->pkey) {
814  if (ssl->pkey)
815  EVP_PKEY_free(ssl->pkey);
816  ssl->pkey = NULL;
817 }
818 assert(ssl->pkey == NULL);
819  ssl->pkey = EVP_PKEY_new();
820  xx = EVP_PKEY_assign_EC_KEY(ssl->pkey, ec);
821 assert(xx);
822 #else
823 fprintf(stderr, " Q[%4u]: %s\n", mbits, pgpHexStr(p+2, nb-2));
824  rc = 1;
825 #endif /* !OPENSSL_NO_ECDSA */
826  } break;
827  }
828 /*@=moduncon@*/
829  return rc;
830 }
831 
832 /*@-mustmod@*/
833 static
834 void rpmsslClean(void * impl)
835  /*@modifies impl @*/
836 {
837  rpmssl ssl = (rpmssl) impl;
838 /*@-moduncon@*/
839  if (ssl != NULL) {
840  ssl->nbits = 0;
841  ssl->qbits = 0;
842  ssl->err = 0;
843  ssl->badok = 0;
844  ssl->digest = _free(ssl->digest);
845  ssl->digestlen = 0;
846 
847  ssl->sig = _free(ssl->sig);
848  ssl->siglen = 0;
849 
850  if (ssl->dsa)
851  DSA_free(ssl->dsa);
852  ssl->dsa = NULL;
853  if (ssl->dsasig)
854  DSA_SIG_free(ssl->dsasig);
855  ssl->dsasig = NULL;
856 
857  if (ssl->rsa)
858  RSA_free(ssl->rsa);
859  ssl->rsa = NULL;
860  if (ssl->hm)
861  BN_free(ssl->hm);
862  ssl->hm = NULL;
863 
864  ssl->curveN = _free(ssl->curveN);
865  ssl->nid = 0;
866  if (ssl->ecdsasig)
867  ECDSA_SIG_free(ssl->ecdsasig);
868  ssl->ecdsasig = NULL;
869  if (ssl->priv)
870  BN_free(ssl->priv);
871  ssl->priv = NULL;
872 
873  if (ssl->pkey)
874  EVP_PKEY_free(ssl->pkey);
875  ssl->pkey = NULL;
876  ssl->md = NULL;
877 
878  }
879 /*@=moduncon@*/
880 }
881 /*@=mustmod@*/
882 
883 /*@unchecked@*/
884 static int rpmssl_initialized;
885 
886 static /*@null@*/
887 void * rpmsslFree(/*@only@*/ void * impl)
888  /*@modifies impl @*/
889 {
890  rpmsslClean(impl);
891 
892  if (--rpmssl_initialized == 0) {
893 
894  CONF_modules_unload(1);
895  OBJ_cleanup();
896  EVP_cleanup();
897  ENGINE_cleanup();
898  CRYPTO_cleanup_all_ex_data();
899  ERR_remove_thread_state(NULL);
900  ERR_free_strings();
901  COMP_zlib_cleanup();
902 
903  }
904 
905  impl = _free(impl);
906 
907  return NULL;
908 }
909 
910 #ifdef REFERENCE
911 #include <openssl/evp.h>
912 #include <openssl/crypto.h>
913 #include <openssl/bn.h>
914 # include <openssl/md2.h>
915 # include <openssl/rc4.h>
916 # include <openssl/des.h>
917 # include <openssl/idea.h>
918 # include <openssl/blowfish.h>
919 #include <openssl/engine.h>
920 #endif
921 
922 static const char *rpmsslEngines(char *te)
923 {
924  char *t = te;
925  ENGINE *e;
926 
927  for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e))
928  te = stpcpy(stpcpy(te, " "), ENGINE_get_id(e));
929  *te = '\0';
930 
931  return t;
932 }
933 
934 static void rpmsslVersionLog(void)
935 {
936  static int oneshot = 0;
937  int msglvl = RPMLOG_DEBUG;
938  char b[8192];
939 
940  if (oneshot++)
941  return;
942 
943  rpmlog(msglvl, "---------- openssl %s configuration:\n",
944  SSLeay_version(SSLEAY_VERSION));
945 
946 #ifdef REDUNDANT
947  if (SSLeay() == SSLEAY_VERSION_NUMBER)
948  rpmlog(msglvl, "%s\n", SSLeay_version(SSLEAY_VERSION));
949  else
950  rpmlog(msglvl, "%s (Library: %s)\n",
951  OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
952 #endif
953 
954  rpmlog(msglvl, " %s\n", SSLeay_version(SSLEAY_BUILT_ON));
955  rpmlog(msglvl, " %s\n", SSLeay_version(SSLEAY_PLATFORM));
956  rpmlog(msglvl, " options: %s\n", BN_options());
957  rpmlog(msglvl, " %s\n", SSLeay_version(SSLEAY_CFLAGS));
958  rpmlog(msglvl, "%s\n", SSLeay_version(SSLEAY_DIR));
959  rpmlog(msglvl, " engines:%s\n", rpmsslEngines(b));
960  rpmlog(msglvl, " FIPS: %s\n",
961  (FIPS_mode() ? "enabled" : "disabled"));
962 
963 #ifdef REFERENCE
964 { ASN1_OBJECT * o = OBJ_nid2obj(ssl->nid);
965  fprintf(stderr, " sn: %s\n", o->sn);
966  fprintf(stderr, " ln: %s\n", o->ln);
967  fprintf(stderr, " nid: %d\n", o->nid);
968  fprintf(stderr, " data: %p[%u] %s\n", o->data, o->length, pgpHexStr(o->data, o->length));
969  fprintf(stderr, "flags: %08X\n", o->flags);
970 }
971 #endif
972 
973  { size_t nc = EC_get_builtin_curves(NULL, 100);
974  EC_builtin_curve * c = alloca(nc * sizeof(*c));
975  size_t i;
976  (void) EC_get_builtin_curves(c, nc);
977  for (i = 0; i < nc; i++) {
978  ASN1_OBJECT * o = OBJ_nid2obj(c[i].nid);
979 
980  if (i == 0)
981  rpmlog(msglvl, " EC curves:\n");
982  rpmlog(msglvl, " %s\n", c[i].comment);
983  rpmlog(msglvl, " %12s%5d %s\t%s\n",
984  o->sn, c[i].nid, pgpHexStr(o->data, o->length), o->ln);
985  }
986  }
987 
988  rpmlog(msglvl, "----------\n");
989 }
990 
991 static
992 void * rpmsslInit(void)
993  /*@*/
994 {
995  rpmssl ssl = (rpmssl) xcalloc(1, sizeof(*ssl));
996 
997  if (rpmssl_initialized++ == 0) {
998  int xx;
999 
1000 /*@-moduncon@*/
1001 #ifdef NOTYET
1002  CRYPTO_malloc_init();
1003 #endif
1004  ERR_load_crypto_strings();
1005  OpenSSL_add_all_algorithms();
1006  ENGINE_load_builtin_engines();
1007 
1008  xx = FIPS_mode_set(1);
1009 
1010 /*@=moduncon@*/
1011 
1012  rpmsslVersionLog();
1013 
1014  }
1015 
1016  return (void *) ssl;
1017 }
1018 
1019 struct pgpImplVecs_s rpmsslImplVecs = {
1020  OPENSSL_VERSION_TEXT,
1021  rpmsslSetRSA,
1022  rpmsslSetDSA,
1023  rpmsslSetELG,
1024  rpmsslSetECDSA,
1025 
1026  rpmsslErrChk,
1027  rpmsslAvailableCipher, rpmsslAvailableDigest, rpmsslAvailablePubkey,
1028  rpmsslVerify, rpmsslSign, rpmsslGenerate,
1029 
1030  rpmsslMpiItem, rpmsslClean,
1031  rpmsslFree, rpmsslInit
1032 };
1033 
1034 int rpmsslExportPubkey(pgpDig dig)
1035 {
1036  uint8_t pkt[8192];
1037  uint8_t * be = pkt;
1038  size_t pktlen;
1039  time_t now = time(NULL);
1040  uint32_t bt = now;
1041  uint16_t bn;
1042  pgpDigParams pubp = pgpGetPubkey(dig);
1043  rpmssl ssl = (rpmssl) dig->impl;
1044  int rc = 0; /* assume failure */
1045  int xx;
1046 
1047  *be++ = 0x80 | (PGPTAG_PUBLIC_KEY << 2) | 0x01;
1048  be += 2;
1049 
1050  *be++ = 0x04;
1051  *be++ = (bt >> 24);
1052  *be++ = (bt >> 16);
1053  *be++ = (bt >> 8);
1054  *be++ = (bt );
1055  *be++ = pubp->pubkey_algo;
1056 
1057 assert(ssl->pkey);
1058  switch (pubp->pubkey_algo) {
1059  default:
1060 assert(0);
1061  break;
1062  case PGPPUBKEYALGO_RSA:
1063  {
1064  RSA * rsa = EVP_PKEY_get0(ssl->pkey);
1065 
1066  bn = BN_num_bits(rsa->n);
1067  *be++ = (bn >> 8); *be++ = (bn );
1068  bn += 7; bn &= ~7;
1069  xx = BN_bn2bin(rsa->n, be);
1070  be += bn/8;
1071 
1072  bn = BN_num_bits(rsa->e);
1073  *be++ = (bn >> 8); *be++ = (bn );
1074  bn += 7; bn &= ~7;
1075  xx = BN_bn2bin(rsa->e, be);
1076  be += bn/8;
1077  } break;
1078  case PGPPUBKEYALGO_DSA:
1079  {
1080  DSA * dsa = EVP_PKEY_get0(ssl->pkey);
1081 
1082  bn = BN_num_bits(dsa->p);
1083  *be++ = (bn >> 8); *be++ = (bn );
1084  bn += 7; bn &= ~7;
1085  xx = BN_bn2bin(dsa->p, be);
1086  be += bn/8;
1087 
1088  bn = BN_num_bits(dsa->q);
1089  *be++ = (bn >> 8); *be++ = (bn );
1090  bn += 7; bn &= ~7;
1091  xx = BN_bn2bin(dsa->q, be);
1092  be += bn/8;
1093 
1094  bn = BN_num_bits(dsa->g);
1095  *be++ = (bn >> 8); *be++ = (bn );
1096  bn += 7; bn &= ~7;
1097  xx = BN_bn2bin(dsa->g, be);
1098  be += bn/8;
1099 
1100  bn = BN_num_bits(dsa->pub_key);
1101  *be++ = (bn >> 8); *be++ = (bn );
1102  bn += 7; bn &= ~7;
1103  xx = BN_bn2bin(dsa->pub_key, be);
1104  be += bn/8;
1105  } break;
1106  case PGPPUBKEYALGO_ECDSA:
1107  {
1108  EC_KEY * ec = EVP_PKEY_get0(ssl->pkey);
1109  ASN1_OBJECT * o = OBJ_nid2obj(ssl->nid);
1110  unsigned char *q;
1111 
1112  /* OID */
1113  *be++ = o->length;
1114  memcpy(be, o->data, o->length);
1115  be += o->length;
1116 
1117  /* Q */
1118  /* XXX uncompressed {x,y} starts with 0x04 (i.e. 5 leading zero bits) */
1119  q = be+2;
1120  bn = 8 * i2o_ECPublicKey(ec, &q) - 5;
1121  *be++ = (bn >> 8); *be++ = (bn );
1122  bn += 7; bn &= ~7;
1123  be += bn/8;
1124 assert(be == q);
1125 
1126  } break;
1127  }
1128 
1129  pktlen = (be - pkt);
1130  bn = pktlen - 3;
1131  pkt[1] = (bn >> 8);
1132  pkt[2] = (bn );
1133 
1134  xx = pgpPubkeyFingerprint(pkt, pktlen, pubp->signid);
1135 
1136  dig->pub = memcpy(xmalloc(pktlen), pkt, pktlen);
1137  dig->publen = pktlen;
1138  rc = 1;
1139 
1140 SPEW(!rc, rc, dig);
1141  return rc;
1142 }
1143 
1144 int rpmsslExportSignature(pgpDig dig, /*@only@*/ DIGEST_CTX ctx)
1145 {
1146  const unsigned char * q;
1147  uint8_t pkt[8192];
1148  uint8_t * be = pkt;
1149  uint8_t * h;
1150  size_t pktlen;
1151  time_t now = time(NULL);
1152  uint32_t bt;
1153  uint16_t bn;
1154  pgpDigParams pubp = pgpGetPubkey(dig);
1155  pgpDigParams sigp = pgpGetSignature(dig);
1156  rpmssl ssl = (rpmssl) dig->impl;
1157  int rc = 0; /* assume failure */
1158  int xx;
1159 
1160  sigp->tag = PGPTAG_SIGNATURE;
1161  *be++ = 0x80 | (sigp->tag << 2) | 0x01;
1162  be += 2; /* pktlen */
1163 
1164  sigp->hash = be;
1165  *be++ = sigp->version = 0x04; /* version */
1166  *be++ = sigp->sigtype = PGPSIGTYPE_BINARY; /* sigtype */
1167  *be++ = sigp->pubkey_algo = pubp->pubkey_algo; /* pubkey_algo */
1168  *be++ = sigp->hash_algo; /* hash_algo */
1169 
1170  be += 2; /* skip hashd length */
1171  h = (uint8_t *) be;
1172 
1173  *be++ = 1 + 4; /* signature creation time */
1175  bt = now;
1176  *be++ = sigp->time[0] = (bt >> 24);
1177  *be++ = sigp->time[1] = (bt >> 16);
1178  *be++ = sigp->time[2] = (bt >> 8);
1179  *be++ = sigp->time[3] = (bt );
1180 
1181  *be++ = 1 + 4; /* signature expiration time */
1183  bt = 30 * 24 * 60 * 60; /* XXX 30 days from creation */
1184  *be++ = sigp->expire[0] = (bt >> 24);
1185  *be++ = sigp->expire[1] = (bt >> 16);
1186  *be++ = sigp->expire[2] = (bt >> 8);
1187  *be++ = sigp->expire[3] = (bt );
1188 
1189 /* key expiration time (only on a self-signature) */
1190 
1191  *be++ = 1 + 1; /* exportable certification */
1193  *be++ = 0;
1194 
1195  *be++ = 1 + 1; /* revocable */
1196  *be++ = PGPSUBTYPE_REVOCABLE;
1197  *be++ = 0;
1198 
1199 /* notation data */
1200 
1201  sigp->hashlen = (be - h); /* set hashed length */
1202  h[-2] = (sigp->hashlen >> 8);
1203  h[-1] = (sigp->hashlen );
1204  sigp->hashlen += sizeof(struct pgpPktSigV4_s);
1205 
1206  if (sigp->hash != NULL)
1207  xx = rpmDigestUpdate(ctx, sigp->hash, sigp->hashlen);
1208 
1209  if (sigp->version == (rpmuint8_t) 4) {
1210  uint8_t trailer[6];
1211  trailer[0] = sigp->version;
1212  trailer[1] = (rpmuint8_t)0xff;
1213  trailer[2] = (sigp->hashlen >> 24);
1214  trailer[3] = (sigp->hashlen >> 16);
1215  trailer[4] = (sigp->hashlen >> 8);
1216  trailer[5] = (sigp->hashlen );
1217  xx = rpmDigestUpdate(ctx, trailer, sizeof(trailer));
1218  }
1219 
1220  sigp->signhash16[0] = 0x00;
1221  sigp->signhash16[1] = 0x00;
1222  switch (pubp->pubkey_algo) {
1223  default:
1224 assert(0);
1225  break;
1226  case PGPPUBKEYALGO_RSA:
1227  xx = pgpImplSetRSA(ctx, dig, sigp); /* XXX signhash16 check fails */
1228  break;
1229  case PGPPUBKEYALGO_DSA:
1230  xx = pgpImplSetDSA(ctx, dig, sigp); /* XXX signhash16 check fails */
1231  break;
1232  case PGPPUBKEYALGO_ECDSA:
1233  xx = pgpImplSetECDSA(ctx, dig, sigp); /* XXX signhash16 check fails */
1234  break;
1235  }
1236  h = (uint8_t *) ssl->digest;
1237  sigp->signhash16[0] = h[0];
1238  sigp->signhash16[1] = h[1];
1239 
1240  /* XXX pgpImplVec forces "--usecrypto foo" to also be used */
1241  xx = pgpImplSign(dig);
1242 assert(xx == 1);
1243 
1244  be += 2; /* skip unhashed length. */
1245  h = be;
1246 
1247  *be++ = 1 + 8; /* issuer key ID */
1248  *be++ = PGPSUBTYPE_ISSUER_KEYID;
1249  *be++ = pubp->signid[0];
1250  *be++ = pubp->signid[1];
1251  *be++ = pubp->signid[2];
1252  *be++ = pubp->signid[3];
1253  *be++ = pubp->signid[4];
1254  *be++ = pubp->signid[5];
1255  *be++ = pubp->signid[6];
1256  *be++ = pubp->signid[7];
1257 
1258  bt = (be - h); /* set unhashed length */
1259  h[-2] = (bt >> 8);
1260  h[-1] = (bt );
1261 
1262  *be++ = sigp->signhash16[0]; /* signhash16 */
1263  *be++ = sigp->signhash16[1];
1264 
1265  switch (pubp->pubkey_algo) {
1266  default:
1267 assert(0);
1268  break;
1269  case PGPPUBKEYALGO_RSA:
1270  { BIGNUM * md = BN_bin2bn(ssl->sig, ssl->siglen, BN_new());
1271  bn = BN_num_bits(md);
1272  *be++ = (bn >> 8);
1273  *be++ = (bn );
1274  bn += 7; bn &= ~7;
1275  xx = BN_bn2bin(md, be);
1276  be += bn/8;
1277  BN_free(md);
1278  } break;
1279  case PGPPUBKEYALGO_DSA:
1280 assert(ssl->dsasig == NULL);
1281  q = ssl->sig;
1282  ssl->dsasig = d2i_DSA_SIG(NULL, &q, ssl->siglen);
1283 
1284  bn = BN_num_bits(ssl->dsasig->r);
1285  *be++ = (bn >> 8);
1286  *be++ = (bn );
1287  bn += 7; bn &= ~7;
1288  xx = BN_bn2bin(ssl->dsasig->r, be);
1289  be += bn/8;
1290 
1291  bn = BN_num_bits(ssl->dsasig->s);
1292  *be++ = (bn >> 8);
1293  *be++ = (bn );
1294  bn += 7; bn &= ~7;
1295  xx = BN_bn2bin(ssl->dsasig->s, be);
1296  be += bn/8;
1297 
1298  DSA_SIG_free(ssl->dsasig);
1299  ssl->dsasig = NULL;
1300  break;
1301  case PGPPUBKEYALGO_ECDSA:
1302 assert(ssl->ecdsasig == NULL);
1303  q = ssl->sig;
1304  ssl->ecdsasig = d2i_ECDSA_SIG(NULL, &q, ssl->siglen);
1305 
1306  bn = BN_num_bits(ssl->ecdsasig->r);
1307  *be++ = (bn >> 8);
1308  *be++ = (bn );
1309  bn += 7; bn &= ~7;
1310  xx = BN_bn2bin(ssl->ecdsasig->r, be);
1311  be += bn/8;
1312 
1313  bn = BN_num_bits(ssl->ecdsasig->s);
1314  *be++ = (bn >> 8);
1315  *be++ = (bn );
1316  bn += 7; bn &= ~7;
1317  xx = BN_bn2bin(ssl->ecdsasig->s, be);
1318  be += bn/8;
1319 
1320  ECDSA_SIG_free(ssl->ecdsasig);
1321  ssl->ecdsasig = NULL;
1322  break;
1323  }
1324 
1325  pktlen = (be - pkt); /* packet length */
1326  bn = pktlen - 3;
1327  pkt[1] = (bn >> 8);
1328  pkt[2] = (bn );
1329 
1330  dig->sig = memcpy(xmalloc(pktlen), pkt, pktlen);
1331  dig->siglen = pktlen;
1332  rc = 1;
1333 
1334 SPEW(!rc, rc, dig);
1335  return rc;
1336 
1337 }
1338 
1339 #endif /* WITH_SSL */
const bson * b
Definition: bson.h:280
pgpDigParams pgpGetPubkey(pgpDig dig)
Return OpenPGP pubkey parameters.
Definition: rpmpgp.c:1397
struct rpmgc_s * rpmgc
Definition: rpmgc.h:22
char * xstrdup(const char *str)
Definition: rpmmalloc.c:321
struct rpmssl_s * rpmssl
Definition: rpmssl.h:31
struct pgpDigParams_s * pgpDigParams
Definition: rpmiotypes.h:101
const char int time
Definition: bson.h:1005
static unsigned char nibble(char c)
Convert hex to binary nibble.
Definition: pack.c:628
5.2.3.
Definition: rpmpgp.h:376
static void rpmlog(int code, const char *fmt,...)
Definition: rpmlog.h:299
static int pgpImplSign(pgpDig dig)
Definition: rpmpgp.h:1867
const char * pgpPubkeyAlgo2Name(uint32_t algo)
Definition: rpmpgp.c:1193
static int pgpImplSetDSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Definition: rpmpgp.h:1785
char * alloca()
Yet Another syslog(3) API clone.
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
#define SPEW(_list)
Definition: rpmns.c:45
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 rpmsslExportSignature(pgpDig dig, DIGEST_CTX ctx)
#define fail(_err)
Definition: yarn.c:199
Digest private data.
Definition: digest.c:130
struct pgpDig_s * pgpDig
Definition: rpmiotypes.h:97
pgpImplVecs_t rpmsslImplVecs
Implementation specific parameter storage.
static int pgpImplSetECDSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Definition: rpmpgp.h:1803
static int pgpImplSetRSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Definition: rpmpgp.h:1776
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
char * stpcpy(char *dest, const char *src)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:756
int rpmsslExportPubkey(pgpDig dig)
const char * rpmDigestASN1(DIGEST_CTX ctx)
Return digest ASN1 oid string.
Definition: digest.c:206
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 char * pgpHexStr(const rpmuint8_t *p, size_t plen)
Return hex formatted representation of bytes.
Definition: rpmpgp.h:1124
int _pgp_print
Definition: rpmpgp.c:45
int _pgp_debug
Definition: rpmpgp.c:42