rpm  5.4.10
rpmnss.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 #include <rpmio.h>
7 
8 #include <rpmiotypes.h>
9 #define _RPMPGP_INTERNAL
10 #if defined(WITH_NSS)
11 #define _RPMNSS_INTERNAL
12 #include <rpmnss.h>
13 #endif
14 #include <rpmmacro.h>
15 
16 #include "debug.h"
17 
18 #if defined(WITH_NSS)
19 
20 /*@access pgpDig @*/
21 /*@access pgpDigParams @*/
22 
23 /*@-redecl@*/
24 /*@unchecked@*/
25 extern int _pgp_debug;
26 
27 /*@unchecked@*/
28 extern int _pgp_print;
29 /*@=redecl@*/
30 
31 /*@unchecked@*/
32 extern int _rpmnss_init;
33 
34 /*@unchecked@*/
35 static int _rpmnss_debug;
36 
37 #define SPEW(_t, _rc, _dig) \
38  { if ((_t) || _rpmnss_debug || _pgp_debug < 0) \
39  fprintf(stderr, "<-- %s(%p) %s\t%s\n", __FUNCTION__, (_dig), \
40  ((_rc) ? "OK" : "BAD"), (_dig)->pubkey_algoN); \
41  }
42 
43 /*==============================================================*/
44 
45 #ifdef NOTYET
46 typedef struct key_s {
47 /*@observer@*/
48  const char * name; /* key name */
49  uint32_t value;
50 } KEY;
51 
52 static int
53 keyCmp(const void * a, const void * b)
54 {
55  return strcmp(((KEY *)a)->name, ((KEY *)b)->name);
56 }
57 
58 static uint32_t
59 keyValue(KEY * keys, size_t nkeys, /*@null@*/ const char *name)
60 {
61  uint32_t keyval = 0;
62 
63  if (name && *name) {
64  /* XXX bsearch is overkill */
65  KEY needle = { .name = name, .value = 0 };
66  KEY *k = (KEY *)bsearch(&needle, keys, nkeys, sizeof(*keys), keyCmp);
67  if (k)
68  keyval = k->value;
69  }
70  return keyval;
71 }
72 #endif
73 
74 typedef struct keyVN_s {
75  int V;
76 /*@observer@*/
77  const char * N; /* key name */
78 } keyVN_t;
79 
80 static int
81 keyVNCmp(const void * a, const void * b)
82 {
83  return (((keyVN_t *)a)->V - ((keyVN_t *)b)->V);
84 }
85 
86 static const char *
87 keyVN(keyVN_t * keys, size_t nkeys, /*@null@*/ int V)
88 {
89  const char * N = NULL;
90 
91  if (V) {
92  /* XXX bsearch is overkill */
93  keyVN_t needle = {};
94  keyVN_t *k;
95 
96  needle.V = V;
97  needle.N = NULL;
98  k = (keyVN_t *)
99  bsearch(&needle, keys, nkeys, sizeof(*keys), keyVNCmp);
100  if (k)
101  N = k->N;
102  }
103  return N;
104 }
105 
106 static const char * _pgpHashAlgo2Name(uint32_t algo)
107 {
108  return pgpValStr(pgpHashTbl, (rpmuint8_t)algo);
109 }
110 
111 static const char * _pgpPubkeyAlgo2Name(uint32_t algo)
112 {
113  return pgpValStr(pgpPubkeyTbl, (rpmuint8_t)algo);
114 }
115 
116 /*==============================================================*/
117 
118 #define _ENTRY(_v) { SEC_ERROR_##_v, #_v }
119 /* XXX sorted table */
120 static keyVN_t rpmnssERRS[] = {
121  _ENTRY(IO),
122  _ENTRY(LIBRARY_FAILURE),
123  _ENTRY(BAD_DATA),
124  _ENTRY(OUTPUT_LEN),
125  _ENTRY(INPUT_LEN),
126  _ENTRY(INVALID_ARGS),
127  _ENTRY(INVALID_ALGORITHM),
128  _ENTRY(INVALID_AVA),
129  _ENTRY(INVALID_TIME),
130  _ENTRY(BAD_DER),
131  _ENTRY(BAD_SIGNATURE),
132  _ENTRY(EXPIRED_CERTIFICATE),
133  _ENTRY(REVOKED_CERTIFICATE),
134  _ENTRY(UNKNOWN_ISSUER),
135  _ENTRY(BAD_KEY),
136  _ENTRY(BAD_PASSWORD),
137  _ENTRY(RETRY_PASSWORD),
138  _ENTRY(NO_NODELOCK),
139  _ENTRY(BAD_DATABASE),
140  _ENTRY(NO_MEMORY),
141  _ENTRY(UNTRUSTED_ISSUER),
142  _ENTRY(UNTRUSTED_CERT),
143  _ENTRY(DUPLICATE_CERT),
144  _ENTRY(DUPLICATE_CERT_NAME),
145  _ENTRY(ADDING_CERT),
146  _ENTRY(FILING_KEY),
147  _ENTRY(NO_KEY),
148  _ENTRY(CERT_VALID),
149  _ENTRY(CERT_NOT_VALID),
150  _ENTRY(CERT_NO_RESPONSE),
151  _ENTRY(EXPIRED_ISSUER_CERTIFICATE),
152  _ENTRY(CRL_EXPIRED),
153  _ENTRY(CRL_BAD_SIGNATURE),
154  _ENTRY(CRL_INVALID),
155  _ENTRY(EXTENSION_VALUE_INVALID),
156  _ENTRY(EXTENSION_NOT_FOUND),
157  _ENTRY(CA_CERT_INVALID),
158  _ENTRY(PATH_LEN_CONSTRAINT_INVALID),
159  _ENTRY(CERT_USAGES_INVALID),
160 /* SEC_INTERNAL_ONLY */
161  _ENTRY(INVALID_KEY),
162  _ENTRY(UNKNOWN_CRITICAL_EXTENSION),
163  _ENTRY(OLD_CRL),
164  _ENTRY(NO_EMAIL_CERT),
165  _ENTRY(NO_RECIPIENT_CERTS_QUERY),
166  _ENTRY(NOT_A_RECIPIENT),
167  _ENTRY(PKCS7_KEYALG_MISMATCH),
168  _ENTRY(PKCS7_BAD_SIGNATURE),
169  _ENTRY(UNSUPPORTED_KEYALG),
170  _ENTRY(DECRYPTION_DISALLOWED),
171 /* Fortezza Alerts */
172 /* XP_SEC_FORTEZZA_BAD_CARD */
173 /* XP_SEC_FORTEZZA_NO_CARD */
174 /* XP_SEC_FORTEZZA_NONE_SELECTED */
175 /* XP_SEC_FORTEZZA_MORE_INFO */
176 /* XP_SEC_FORTEZZA_PERSON_NOT_FOUND */
177 /* XP_SEC_FORTEZZA_NO_MORE_INFO */
178 /* XP_SEC_FORTEZZA_BAD_PIN */
179 /* XP_SEC_FORTEZZA_PERSON_ERROR */
180  _ENTRY(NO_KRL),
181  _ENTRY(KRL_EXPIRED),
182  _ENTRY(KRL_BAD_SIGNATURE),
183  _ENTRY(REVOKED_KEY),
184  _ENTRY(KRL_INVALID),
185  _ENTRY(NEED_RANDOM),
186  _ENTRY(NO_MODULE),
187  _ENTRY(NO_TOKEN),
188  _ENTRY(READ_ONLY),
189  _ENTRY(NO_SLOT_SELECTED),
190  _ENTRY(CERT_NICKNAME_COLLISION),
191  _ENTRY(KEY_NICKNAME_COLLISION),
192  _ENTRY(SAFE_NOT_CREATED),
193  _ENTRY(BAGGAGE_NOT_CREATED),
194 /* XP_JAVA_REMOVE_PRINCIPAL_ERROR */
195 /* XP_JAVA_DELETE_PRIVILEGE_ERROR */
196 /* XP_JAVA_CERT_NOT_EXISTS_ERROR */
197  _ENTRY(BAD_EXPORT_ALGORITHM),
198  _ENTRY(EXPORTING_CERTIFICATES),
199  _ENTRY(IMPORTING_CERTIFICATES),
200  _ENTRY(PKCS12_DECODING_PFX),
201  _ENTRY(PKCS12_INVALID_MAC),
202  _ENTRY(PKCS12_UNSUPPORTED_MAC_ALGORITHM),
203  _ENTRY(PKCS12_UNSUPPORTED_TRANSPORT_MODE),
204  _ENTRY(PKCS12_CORRUPT_PFX_STRUCTURE),
205  _ENTRY(PKCS12_UNSUPPORTED_PBE_ALGORITHM),
206  _ENTRY(PKCS12_UNSUPPORTED_VERSION),
207  _ENTRY(PKCS12_PRIVACY_PASSWORD_INCORRECT),
208  _ENTRY(PKCS12_CERT_COLLISION),
209  _ENTRY(USER_CANCELLED),
210  _ENTRY(PKCS12_DUPLICATE_DATA),
211  _ENTRY(MESSAGE_SEND_ABORTED),
212  _ENTRY(INADEQUATE_KEY_USAGE),
213  _ENTRY(INADEQUATE_CERT_TYPE),
214  _ENTRY(CERT_ADDR_MISMATCH),
215  _ENTRY(PKCS12_UNABLE_TO_IMPORT_KEY),
216  _ENTRY(PKCS12_IMPORTING_CERT_CHAIN),
217  _ENTRY(PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME),
218  _ENTRY(PKCS12_UNABLE_TO_EXPORT_KEY),
219  _ENTRY(PKCS12_UNABLE_TO_WRITE),
220  _ENTRY(PKCS12_UNABLE_TO_READ),
221  _ENTRY(PKCS12_KEY_DATABASE_NOT_INITIALIZED),
222  _ENTRY(KEYGEN_FAIL),
223  _ENTRY(INVALID_PASSWORD),
224  _ENTRY(RETRY_OLD_PASSWORD),
225  _ENTRY(BAD_NICKNAME),
226  _ENTRY(NOT_FORTEZZA_ISSUER),
227  _ENTRY(CANNOT_MOVE_SENSITIVE_KEY),
228  _ENTRY(JS_INVALID_MODULE_NAME),
229  _ENTRY(JS_INVALID_DLL),
230  _ENTRY(JS_ADD_MOD_FAILURE),
231  _ENTRY(JS_DEL_MOD_FAILURE),
232  _ENTRY(OLD_KRL),
233  _ENTRY(CKL_CONFLICT),
234  _ENTRY(CERT_NOT_IN_NAME_SPACE),
235  _ENTRY(KRL_NOT_YET_VALID),
236  _ENTRY(CRL_NOT_YET_VALID),
237  _ENTRY(UNKNOWN_CERT),
238  _ENTRY(UNKNOWN_SIGNER),
239  _ENTRY(CERT_BAD_ACCESS_LOCATION),
240  _ENTRY(OCSP_UNKNOWN_RESPONSE_TYPE),
241  _ENTRY(OCSP_BAD_HTTP_RESPONSE),
242  _ENTRY(OCSP_MALFORMED_REQUEST),
243  _ENTRY(OCSP_SERVER_ERROR),
244  _ENTRY(OCSP_TRY_SERVER_LATER),
245  _ENTRY(OCSP_REQUEST_NEEDS_SIG),
246  _ENTRY(OCSP_UNAUTHORIZED_REQUEST),
247  _ENTRY(OCSP_UNKNOWN_RESPONSE_STATUS),
248  _ENTRY(OCSP_UNKNOWN_CERT),
249  _ENTRY(OCSP_NOT_ENABLED),
250  _ENTRY(OCSP_NO_DEFAULT_RESPONDER),
251  _ENTRY(OCSP_MALFORMED_RESPONSE),
252  _ENTRY(OCSP_UNAUTHORIZED_RESPONSE),
253  _ENTRY(OCSP_FUTURE_RESPONSE),
254  _ENTRY(OCSP_OLD_RESPONSE),
255 /* smime stuff */
256  _ENTRY(DIGEST_NOT_FOUND),
257  _ENTRY(UNSUPPORTED_MESSAGE_TYPE),
258  _ENTRY(MODULE_STUCK),
259  _ENTRY(BAD_TEMPLATE),
260  _ENTRY(CRL_NOT_FOUND),
261  _ENTRY(REUSED_ISSUER_AND_SERIAL),
262  _ENTRY(BUSY),
263  _ENTRY(EXTRA_INPUT),
264 /* error codes used by elliptic curve code */
265  _ENTRY(UNSUPPORTED_ELLIPTIC_CURVE),
266  _ENTRY(UNSUPPORTED_EC_POINT_FORM),
267  _ENTRY(UNRECOGNIZED_OID),
268  _ENTRY(OCSP_INVALID_SIGNING_CERT),
269 /* new revocation errors */
270  _ENTRY(REVOKED_CERTIFICATE_CRL),
271  _ENTRY(REVOKED_CERTIFICATE_OCSP),
272  _ENTRY(CRL_INVALID_VERSION),
273  _ENTRY(CRL_V1_CRITICAL_EXTENSION),
274  _ENTRY(CRL_UNKNOWN_CRITICAL_EXTENSION),
275  _ENTRY(UNKNOWN_OBJECT_TYPE),
276  _ENTRY(INCOMPATIBLE_PKCS11),
277  _ENTRY(NO_EVENT),
278  _ENTRY(CRL_ALREADY_EXISTS),
279  _ENTRY(NOT_INITIALIZED),
280  _ENTRY(TOKEN_NOT_LOGGED_IN),
281  _ENTRY(OCSP_RESPONDER_CERT_INVALID),
282  _ENTRY(OCSP_BAD_SIGNATURE),
283  _ENTRY(OUT_OF_SEARCH_LIMITS),
284  _ENTRY(INVALID_POLICY_MAPPING),
285  _ENTRY(POLICY_VALIDATION_FAILED),
286  _ENTRY(UNKNOWN_AIA_LOCATION_TYPE),
287  _ENTRY(BAD_HTTP_RESPONSE),
288  _ENTRY(BAD_LDAP_RESPONSE),
289  _ENTRY(FAILED_TO_ENCODE_DATA),
290  _ENTRY(BAD_INFO_ACCESS_LOCATION),
291  _ENTRY(LIBPKIX_INTERNAL),
292  _ENTRY(PKCS11_GENERAL_ERROR),
293  _ENTRY(PKCS11_FUNCTION_FAILED),
294  _ENTRY(PKCS11_DEVICE_ERROR),
295 #if defined(SEC_ERROR_BAD_INFO_ACCESS_METHOD)
296  _ENTRY(BAD_INFO_ACCESS_METHOD),
297 #endif
298 #if defined(SEC_ERROR_CRL_IMPORT_FAILED)
299  _ENTRY(CRL_IMPORT_FAILED),
300 #endif
301 };
302 static size_t nrpmnssERRS = sizeof(rpmnssERRS) / sizeof(rpmnssERRS[0]);
303 #undef _ENTRY
304 
305 static const char * rpmnssStrerror(int err)
306 {
307  static char buf[64];
308  const char * errN = keyVN(rpmnssERRS, nrpmnssERRS, err);
309  if (errN == NULL) {
310  snprintf(buf, sizeof(buf), "SEC_ERROR(%d)", err);
311  errN = buf;
312  }
313  return errN;
314 }
315 
316 static
317 int rpmnssErr(rpmnss nss, const char * msg, int rc)
318  /*@*/
319 {
320 #ifdef REFERENCE
321  /* XXX Don't spew on expected failures ... */
322  if (err && gcry_err_code(err) != gc->badok)
323  fprintf (stderr, "rpmgc: %s(0x%0x): %s/%s\n",
324  msg, (unsigned)err, gcry_strsource(err), gcry_strerror(err));
325 #endif
326  if (rc != SECSuccess) {
327  int err = PORT_GetError();
328  fprintf (stderr, "rpmnss: %s rc(%d) err(%d) %s\n",
329  msg, rc, err, rpmnssStrerror(err));
330  }
331  return rc;
332 }
333 
334 static
335 int rpmnssSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
336  /*@modifies dig @*/
337 {
338  rpmnss nss = (rpmnss) dig->impl;
339  int rc = 1; /* assume error */
340  int xx;
341 pgpDigParams pubp = pgpGetPubkey(dig);
342 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
343 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
344 
345 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
346  nss->sigalg = SEC_OID_UNKNOWN;
347  switch (sigp->hash_algo) {
348  case PGPHASHALGO_MD5:
349  nss->sigalg = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
350  break;
351  case PGPHASHALGO_SHA1:
352  nss->sigalg = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
353  break;
355  break;
356  case PGPHASHALGO_MD2:
357  nss->sigalg = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;
358  break;
359  case PGPHASHALGO_MD4:
360  nss->sigalg = SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION;
361  break;
363  break;
365  break;
366  case PGPHASHALGO_SHA256:
367  nss->sigalg = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
368  break;
369  case PGPHASHALGO_SHA384:
370  nss->sigalg = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
371  break;
372  case PGPHASHALGO_SHA512:
373  nss->sigalg = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
374  break;
375  case PGPHASHALGO_SHA224:
376  break;
377  default:
378  break;
379  }
380  if (nss->sigalg == SEC_OID_UNKNOWN)
381  goto exit;
382 
383 nss->digest = _free(nss->digest);
384 nss->digestlen = 0;
385  xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0);
386  ctx = NULL; /* XXX avoid double free */
387 
388  /* Compare leading 16 bits of digest for quick check. */
389  rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16));
390 
391 exit:
392  if (ctx) { /* XXX Free the context on error returns. */
393  xx = rpmDigestFinal(ctx, NULL, NULL, 0);
394  ctx = NULL;
395  }
396 SPEW(0, !rc, dig);
397  return rc;
398 }
399 
400 static
401 int rpmnssVerifyRSA(pgpDig dig)
402  /*@*/
403 {
404  rpmnss nss = (rpmnss) dig->impl;
405  int rc;
406 
407  nss->item.type = siBuffer;
408  nss->item.data = (unsigned char *) nss->digest;
409  nss->item.len = (unsigned) nss->digestlen;
410 
411  rc = rpmnssErr(nss, "VFY_VerifyDigest",
412  VFY_VerifyDigest(&nss->item, nss->pub_key,
413  nss->sig, nss->sigalg, NULL));
414  rc = (rc == SECSuccess);
415 
416 SPEW(0, !rc, dig);
417  return rc;
418 }
419 
420 static int rpmnssSignRSA(pgpDig dig)
421 {
422  rpmnss nss = (rpmnss) dig->impl;
423 pgpDigParams sigp = pgpGetSignature(dig);
424  int rc = 0; /* assume failure. */
425 
426 SECOidTag sigalg = SEC_OID_UNKNOWN;
427  switch (sigp->hash_algo) {
428  case PGPHASHALGO_MD5:
429  sigalg = SEC_OID_MD5;
430  break;
431  case PGPHASHALGO_SHA1:
432  sigalg = SEC_OID_SHA1;
433  break;
435  break;
436  case PGPHASHALGO_MD2:
437  sigalg = SEC_OID_MD2;
438  break;
439  case PGPHASHALGO_MD4:
440  sigalg = SEC_OID_MD4;
441  break;
443  break;
445  break;
446  case PGPHASHALGO_SHA256:
447  sigalg = SEC_OID_SHA256;
448  break;
449  case PGPHASHALGO_SHA384:
450  sigalg = SEC_OID_SHA384;
451  break;
452  case PGPHASHALGO_SHA512:
453  sigalg = SEC_OID_SHA512;
454  break;
455  case PGPHASHALGO_SHA224:
456  break;
457  default:
458  break;
459  }
460  if (sigalg == SEC_OID_UNKNOWN)
461  goto exit;
462 
463  nss->item.type = siBuffer;
464  nss->item.data = (unsigned char *) nss->digest;
465  nss->item.len = (unsigned) nss->digestlen;
466 
467 if (nss->sig != NULL) {
468  SECITEM_ZfreeItem(nss->sig, PR_TRUE);
469  nss->sig = NULL;
470 }
471 nss->sig = SECITEM_AllocItem(NULL, NULL, 0);
472 nss->sig->type = siBuffer;
473 
474  rc = rpmnssErr(nss, "SGN_Digest",
475  SGN_Digest(nss->sec_key, sigalg, nss->sig, &nss->item));
476  rc = (rc == SECSuccess);
477 
478 exit:
479 SPEW(!rc, rc, dig);
480  return rc;
481 }
482 
483 static int rpmnssGenerateRSA(pgpDig dig)
484 {
485  rpmnss nss = (rpmnss) dig->impl;
486  int rc = 0; /* assume failure */
487 
488 if (nss->nbits == 0) nss->nbits = 1024; /* XXX FIXME */
489 assert(nss->nbits);
490 
491  { CK_MECHANISM_TYPE _type = CKM_RSA_PKCS_KEY_PAIR_GEN;
492  PK11SlotInfo * _slot = PK11_GetBestSlot(_type, NULL);
493  int _isPerm = PR_FALSE;
494  int _isSensitive = PR_TRUE;
495  void * _cx = NULL;
496 
497  if (_slot) {
498  static unsigned _pe = 0x10001; /* XXX FIXME: pass in e */
499  PK11RSAGenParams rsaparams = {};
500  void * params = &rsaparams;
501 
502  rsaparams.keySizeInBits = nss->nbits;
503  rsaparams.pe = _pe;
504 
505  nss->sec_key = PK11_GenerateKeyPair(_slot, _type, params,
506  &nss->pub_key, _isPerm, _isSensitive, _cx);
507 
508  PK11_FreeSlot(_slot);
509  }
510  }
511 
512  rc = (nss->sec_key && nss->pub_key);
513 
514 SPEW(!rc, rc, dig);
515  return rc;
516 }
517 
518 static
519 int rpmnssSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
520  /*@modifies dig @*/
521 {
522  rpmnss nss = (rpmnss) dig->impl;
523  int rc;
524  int xx;
525 pgpDigParams pubp = pgpGetPubkey(dig);
526 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
527 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
528 
529 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
530 nss->digest = _free(nss->digest);
531 nss->digestlen = 0;
532  xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0);
533 
534  nss->sigalg = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
535 
536  /* Compare leading 16 bits of digest for quick check. */
537  rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16));
538 SPEW(0, !rc, dig);
539  return rc;
540 }
541 
542 static
543 int rpmnssVerifyDSA(pgpDig dig)
544  /*@*/
545 {
546  rpmnss nss = (rpmnss) dig->impl;
547  int rc;
548 
549  nss->item.type = siBuffer;
550  nss->item.data = (unsigned char *) nss->digest;
551  nss->item.len = (unsigned) nss->digestlen;
552 
553  rc = rpmnssErr(nss, "VFY_VerifyDigest",
554  VFY_VerifyDigest(&nss->item, nss->pub_key,
555  nss->sig, nss->sigalg, NULL));
556  rc = (rc == SECSuccess);
557 
558 SPEW(0, rc, dig);
559  return rc;
560 }
561 
562 static int rpmnssSignDSA(pgpDig dig)
563 {
564  rpmnss nss = (rpmnss) dig->impl;
565 pgpDigParams sigp = pgpGetSignature(dig);
566  int rc = 0; /* assume failure. */
567 SECOidTag sigalg = SEC_OID_UNKNOWN;
568 SECItem sig = {};
569 
570  sig.type = siBuffer;
571  sig.len = 0;
572  sig.data = NULL;
573 
574  switch (sigp->hash_algo) {
575  case PGPHASHALGO_MD5:
576  break;
577  case PGPHASHALGO_SHA1:
578  sigalg = SEC_OID_SHA1;
579  break;
581  break;
582  case PGPHASHALGO_MD2:
583  break;
584  case PGPHASHALGO_MD4:
585  break;
587  break;
589  break;
590  case PGPHASHALGO_SHA256:
591  break;
592  case PGPHASHALGO_SHA384:
593  break;
594  case PGPHASHALGO_SHA512:
595  break;
596  case PGPHASHALGO_SHA224:
597  break;
598  default:
599  break;
600  }
601  if (sigalg == SEC_OID_UNKNOWN)
602  goto exit;
603 
604  nss->item.type = siBuffer;
605  nss->item.data = (unsigned char *) nss->digest;
606  nss->item.len = (unsigned) nss->digestlen;
607 
608 if (nss->sig != NULL) {
609  SECITEM_ZfreeItem(nss->sig, PR_TRUE);
610  nss->sig = NULL;
611 }
612 
613 nss->sig = SECITEM_AllocItem(NULL, NULL, 0);
614 nss->sig->type = siBuffer;
615 
616  rc = rpmnssErr(nss, "SGN_Digest",
617  SGN_Digest(nss->sec_key, sigalg, &sig, &nss->item));
618 
619  if (rc == SECSuccess)
620  rc = rpmnssErr(nss, "DSAU_EncodeDerSig",
621  DSAU_EncodeDerSig(nss->sig, &sig));
622 
623  sig.data = _free(sig.data);
624 
625  rc = (rc == SECSuccess);
626 
627 exit:
628 SPEW(!rc, rc, dig);
629  return rc;
630 }
631 
632 static int rpmnssGenerateDSA(pgpDig dig)
633 {
634  rpmnss nss = (rpmnss) dig->impl;
635  int rc = 0; /* assume failure */
636 
637 if (nss->nbits == 0) nss->nbits = 1024; /* XXX FIXME */
638 assert(nss->nbits);
639 
640  { CK_MECHANISM_TYPE _type = CKM_DSA_KEY_PAIR_GEN;
641  PK11SlotInfo * _slot = PK11_GetBestSlot(_type, NULL);
642  int _isPerm = PR_FALSE;
643  int _isSensitive = PR_TRUE;
644  void * _cx = NULL;
645 
646  if (_slot) {
647  PQGParams *pqgParams = NULL;
648  PQGVerify *pqgVfy = NULL;
649  void * params = NULL;
650 int xx;
651 
652  xx = rpmnssErr(nss, "PK11_PQG_ParamGen",
653  PK11_PQG_ParamGen(0, &pqgParams, &pqgVfy));
654  if (xx != SECSuccess)
655  goto exit;
656  params = pqgParams;
657 
658  nss->sec_key = PK11_GenerateKeyPair(_slot, _type, params,
659  &nss->pub_key, _isPerm, _isSensitive, _cx);
660 
661  if (pqgVfy) PK11_PQG_DestroyVerify(pqgVfy);
662  if (pqgParams) PK11_PQG_DestroyParams(pqgParams);
663 
664  PK11_FreeSlot(_slot);
665  }
666  }
667 
668  rc = (nss->sec_key && nss->pub_key);
669 
670 exit:
671 SPEW(!rc, rc, dig);
672  return rc;
673 }
674 
675 static
676 int rpmnssSetELG(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
677  /*@*/
678 {
679  rpmnss nss = (rpmnss) dig->impl;
680  int rc = 1; /* XXX always fail. */
681  int xx;
682 
683 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
684 nss->digest = _free(nss->digest);
685 nss->digestlen = 0;
686  xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0);
687 
688  /* Compare leading 16 bits of digest for quick check. */
689 
690  return rc;
691 }
692 
693 static
694 int rpmnssSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
695  /*@*/
696 {
697  rpmnss nss = (rpmnss) dig->impl;
698  int xx;
699 
700 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
701  nss->sigalg = SEC_OID_UNKNOWN;
702  switch (sigp->hash_algo) {
703  case PGPHASHALGO_SHA1:
704  nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE;
705  break;
706  case PGPHASHALGO_SHA224:
707  nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE;
708  break;
709  case PGPHASHALGO_SHA256:
710  nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE;
711  break;
712  case PGPHASHALGO_SHA384:
713  nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE;
714  break;
715  case PGPHASHALGO_SHA512:
716  nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE;
717  break;
718  default:
719  break;
720  }
721  if (nss->sigalg == SEC_OID_UNKNOWN)
722  return 1;
723 
724 nss->digest = _free(nss->digest);
725 nss->digestlen = 0;
726  xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0);
727 
728  /* Compare leading 16 bits of digest for quick check. */
729  return memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16));
730 }
731 
732 static
733 int rpmnssVerifyECDSA(/*@unused@*/pgpDig dig)
734  /*@*/
735 {
736  rpmnss nss = (rpmnss) dig->impl;
737  int rc;
738 
739  nss->item.type = siBuffer;
740  nss->item.data = (unsigned char *) nss->digest;
741  nss->item.len = (unsigned) nss->digestlen;
742 
743  rc = VFY_VerifyDigest(&nss->item, nss->pub_key, nss->sig, nss->sigalg, NULL);
744  rc = (rc == SECSuccess);
745 
746 SPEW(!rc, rc, dig);
747  return rc;
748 }
749 
750 static
751 int rpmnssSignECDSA(/*@unused@*/pgpDig dig)
752  /*@*/
753 {
754  rpmnss nss = (rpmnss) dig->impl;
755 pgpDigParams sigp = pgpGetSignature(dig);
756  int rc = 0; /* assume failure. */
757 
758 SECOidTag sigalg = SEC_OID_UNKNOWN;
759  switch (sigp->hash_algo) {
760  case PGPHASHALGO_MD5:
761  break;
762  case PGPHASHALGO_SHA1:
763  sigalg = SEC_OID_SHA1;
764  break;
766  break;
767  case PGPHASHALGO_MD2:
768  break;
769  case PGPHASHALGO_MD4:
770  break;
772  break;
774  break;
775  case PGPHASHALGO_SHA256:
776  sigalg = SEC_OID_SHA256;
777  break;
778  case PGPHASHALGO_SHA384:
779  sigalg = SEC_OID_SHA384;
780  break;
781  case PGPHASHALGO_SHA512:
782  sigalg = SEC_OID_SHA512;
783  break;
784  case PGPHASHALGO_SHA224:
785  break;
786  default:
787  break;
788  }
789  if (sigalg == SEC_OID_UNKNOWN)
790  goto exit;
791 
792 if (nss->sig != NULL) {
793  SECITEM_ZfreeItem(nss->sig, PR_TRUE);
794  nss->sig = NULL;
795 }
796 nss->sig = SECITEM_AllocItem(NULL, NULL, 0);
797 nss->sig->type = siBuffer;
798 
799  rc = rpmnssErr(nss, "SGN_Digest",
800  SGN_Digest(nss->sec_key, sigalg, nss->sig, &nss->item));
801 
802  rc = (rc == SECSuccess);
803 
804 exit:
805 SPEW(!rc, rc, dig);
806  return rc;
807 }
808 
809 static
810 int rpmnssGenerateECDSA(/*@unused@*/pgpDig dig)
811  /*@*/
812 {
813  rpmnss nss = (rpmnss) dig->impl;
814  int rc = 0; /* assume failure. */
815 
816  { CK_MECHANISM_TYPE _type = CKM_EC_KEY_PAIR_GEN;
817  PK11SlotInfo * _slot = PK11_GetBestSlot(_type, NULL);
818  int _isPerm = PR_FALSE;
819  int _isSensitive = PR_FALSE;
820  void * _cx = NULL;
821 
822  if (_slot) {
823 
824  nss->sec_key = PK11_GenerateKeyPair(_slot, _type, nss->ecparams,
825  &nss->pub_key, _isPerm, _isSensitive, _cx);
826 
827  PK11_FreeSlot(_slot);
828  }
829  }
830 
831  rc = (nss->sec_key && nss->pub_key);
832 
833 SPEW(!rc, rc, dig);
834 
835  return rc;
836 }
837 
838 static int rpmnssErrChk(pgpDig dig, const char * msg, int rc, unsigned expected)
839 {
840 #ifdef NOTYET
841 rpmgc gc = dig->impl;
842  /* Was the return code the expected result? */
843  rc = (gcry_err_code(gc->err) != expected);
844  if (rc)
845  fail("%s failed: %s\n", msg, gpg_strerror(gc->err));
846 /* XXX FIXME: rpmnssStrerror */
847 #else
848  rc = (rc == 0); /* XXX impedance match 1 -> 0 on success */
849 #endif
850  return rc; /* XXX 0 on success */
851 }
852 
853 static int rpmnssAvailableCipher(pgpDig dig, int algo)
854 {
855  int rc = 0; /* assume available */
856 #ifdef NOTYET
857  rc = rpmgnssvailable(dig->impl, algo,
858  (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5));
859 #endif
860  return rc;
861 }
862 
863 static int rpmnssAvailableDigest(pgpDig dig, int algo)
864 {
865  int rc = 0; /* assume available */
866 #ifdef NOTYET
867  rc = rpmgnssvailable(dig->impl, algo,
868  (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5));
869 #endif
870  return rc;
871 }
872 
873 static int rpmnssAvailablePubkey(pgpDig dig, int algo)
874 {
875  int rc = 0; /* assume available */
876 #ifdef NOTYET
877  rc = rpmnssAvailable(dig->impl, algo, gcry_pk_test_algo(algo));
878 #endif
879  return rc;
880 }
881 
882 static int rpmnssVerify(pgpDig dig)
883 {
884  rpmnss nss = (rpmnss) dig->impl;
885  int rc = 0; /* assume failure */
886 pgpDigParams pubp = pgpGetPubkey(dig);
887 pgpDigParams sigp = pgpGetSignature(dig);
888 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
889 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
890 
891  switch (pubp->pubkey_algo) {
892  default:
893  break;
894  case PGPPUBKEYALGO_RSA:
895  rc = rpmnssVerifyRSA(dig);
896  break;
897  case PGPPUBKEYALGO_DSA:
898  rc = rpmnssVerifyDSA(dig);
899  break;
901 #ifdef NOTYET
902  rc = rpmnssVerifyELG(dig);
903 #endif
904  break;
905  case PGPPUBKEYALGO_ECDSA:
906  if (nss->sigalg != SEC_OID_UNKNOWN)
907  rc = rpmnssVerifyECDSA(dig);
908  break;
909  }
910 SPEW(0, rc, dig);
911  return rc;
912 }
913 
914 static int rpmnssSign(pgpDig dig)
915 {
916  rpmnss nss = (rpmnss) dig->impl;
917  int rc = 0; /* assume failure */
918 pgpDigParams pubp = pgpGetPubkey(dig);
919 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
920  switch (pubp->pubkey_algo) {
921  default:
922  break;
923  case PGPPUBKEYALGO_RSA:
924  rc = rpmnssSignRSA(dig);
925  break;
926  case PGPPUBKEYALGO_DSA:
927  rc = rpmnssSignDSA(dig);
928  break;
930 #ifdef NOTYET
931  rc = rpmnssSignELG(dig);
932 #endif
933  break;
934  case PGPPUBKEYALGO_ECDSA:
935  if (nss->sigalg != SEC_OID_UNKNOWN)
936  rc = rpmnssSignECDSA(dig);
937  break;
938  }
939 SPEW(!rc, rc, dig);
940  return rc;
941 }
942 
943 static int rpmnssLoadParams(pgpDig dig, const char * name)
944 {
945  rpmnss nss = (rpmnss) dig->impl;
946 #ifdef NOTYET
947  SECOidTag curveOidTag = curve2oid(name);
948 #else
949  SECOidTag curveOidTag = !strcmp(name, "nistp256")
950  ? SEC_OID_SECG_EC_SECP256R1 : SEC_OID_UNKNOWN;
951 #endif
952  SECOidData * oidData = SECOID_FindOIDByTag(curveOidTag);
953  int rc = 1; /* assume failure. */
954 
955  if (curveOidTag == SEC_OID_UNKNOWN || oidData == NULL) {
956  nss->sigalg = curveOidTag;
957  goto exit;
958  }
959 
960  nss->sigalg = curveOidTag;
961 
962  nss->ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
963  nss->ecparams->data[0] = SEC_ASN1_OBJECT_ID;
964  nss->ecparams->data[1] = oidData->oid.len;
965  memcpy(nss->ecparams->data + 2, oidData->oid.data, oidData->oid.len);
966  rc = 0;
967 
968 exit:
969 if (1 || _pgp_debug)
970 fprintf(stderr, "<-- %s(%p,%s) oid %u params %p\n", __FUNCTION__, dig, name, nss->sigalg, nss->ecparams);
971  return rc;
972 }
973 
974 static int rpmnssGenerate(pgpDig dig)
975 {
976  int rc = 0; /* assume failure */
977 pgpDigParams pubp = pgpGetPubkey(dig);
978 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
979 
980  switch (pubp->pubkey_algo) {
981  default:
982  break;
983  case PGPPUBKEYALGO_RSA:
984  rc = rpmnssGenerateRSA(dig);
985  break;
986  case PGPPUBKEYALGO_DSA:
987  rc = rpmnssGenerateDSA(dig);
988  break;
990 #ifdef NOTYET
991  rc = rpmnssGenerateELG(dig);
992 #endif
993  break;
994  case PGPPUBKEYALGO_ECDSA:
995  rc = rpmnssLoadParams(dig, "nistp256");
996  if (!rc)
997  rc = rpmnssGenerateECDSA(dig);
998  break;
999  }
1000 SPEW(!rc, rc, dig);
1001  return rc;
1002 }
1003 
1007 static
1008 int rpmnssMpiSet(const char * pre, unsigned int lbits,
1009  /*@out@*/ void * dest, const rpmuint8_t * p,
1010  /*@null@*/ const rpmuint8_t * pend)
1011  /*@modifies *dest @*/
1012 {
1013  unsigned int mbits = pgpMpiBits(p);
1014  unsigned int nbits;
1015  unsigned int nbytes;
1016  char * t = (char *) dest;
1017  unsigned int ix;
1018 
1019  if (pend != NULL && (p + ((mbits+7) >> 3)) > pend)
1020  return 1;
1021 
1022  if (mbits > lbits)
1023  return 1;
1024 
1025  nbits = (lbits > mbits ? lbits : mbits);
1026  nbytes = ((nbits + 7) >> 3);
1027  ix = ((nbits - mbits) >> 3);
1028 
1029 /*@-modfilesystem @*/
1030 if (_pgp_debug)
1031 fprintf(stderr, "*** mbits %u nbits %u nbytes %u ix %u\n", mbits, nbits, nbytes, ix);
1032  if (ix > 0) memset(t, (int)'\0', ix);
1033  memcpy(t+ix, p+2, nbytes-ix);
1034 if (_pgp_debug && _pgp_print)
1035 fprintf(stderr, "\t %s %s\n", pre, pgpHexStr((rpmuint8_t *)dest, nbytes));
1036 /*@=modfilesystem @*/
1037  return 0;
1038 }
1039 
1043 static
1044 /*@only@*/ /*@null@*/
1045 SECItem * rpmnssMpiCopy(PRArenaPool * arena, /*@returned@*/ SECItem * item,
1046  const rpmuint8_t * p)
1047  /*@modifies item @*/
1048 {
1049  unsigned int nbytes = pgpMpiLen(p)-2;
1050 
1051 /*@-moduncon@*/
1052  if (item == NULL) {
1053  if ((item = SECITEM_AllocItem(arena, item, nbytes)) == NULL)
1054  return item;
1055  } else {
1056  if (arena != NULL)
1057  item->data = (unsigned char *) PORT_ArenaGrow(arena, item->data, item->len, nbytes);
1058  else
1059  item->data = (unsigned char *) PORT_Realloc(item->data, nbytes);
1060 
1061  if (item->data == NULL) {
1062  if (arena == NULL)
1063  SECITEM_FreeItem(item, PR_TRUE);
1064  return NULL;
1065  }
1066  }
1067 /*@=moduncon@*/
1068 
1069  memcpy(item->data, p+2, nbytes);
1070  item->len = nbytes;
1071 /*@-temptrans@*/
1072  return item;
1073 /*@=temptrans@*/
1074 }
1075 
1076 static /*@null@*/
1077 SECKEYPublicKey * rpmnssNewPublicKey(KeyType type)
1078  /*@*/
1079 {
1080  PRArenaPool *arena;
1081  SECKEYPublicKey *key;
1082 
1083 /*@-moduncon@*/
1084  arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1085  if (arena == NULL)
1086  return NULL;
1087 
1088  key = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena, sizeof(*key));
1089 
1090  if (key == NULL) {
1091  PORT_FreeArena(arena, PR_FALSE);
1092  return NULL;
1093  }
1094 /*@=moduncon@*/
1095 
1096  key->keyType = type;
1097  key->pkcs11ID = CK_INVALID_HANDLE;
1098  key->pkcs11Slot = NULL;
1099  key->arena = arena;
1100 /*@-nullret@*/ /* key->pkcs11Slot can be NULL */
1101  return key;
1102 /*@=nullret@*/
1103 }
1104 
1105 static
1106 int rpmnssMpiItem(const char * pre, pgpDig dig, int itemno,
1107  const rpmuint8_t * p, /*@null@*/ const rpmuint8_t * pend)
1108  /*@*/
1109 {
1110  rpmnss nss = (rpmnss) dig->impl;
1111  unsigned int hbits;
1112  size_t nb = (pend >= p ? (pend - p) : 0);
1113  int rc = 0;
1114 
1115 /*@-moduncon@*/
1116  switch (itemno) {
1117  default:
1118 assert(0);
1119  break;
1120  case 10: /* RSA m**d */
1121  nss->sig = rpmnssMpiCopy(NULL, nss->sig, p);
1122  if (nss->sig == NULL)
1123  rc = 1;
1124  break;
1125  case 20: /* DSA r */
1126  hbits = 160;
1127  nss->item.type = (SECItemType) 0;
1128  nss->item.len = 2 * (hbits/8);
1129  nss->item.data = (unsigned char *) xcalloc(1, nss->item.len);
1130  rc = rpmnssMpiSet(pre, hbits, nss->item.data, p, pend);
1131  break;
1132  case 21: /* DSA s */
1133  hbits = 160;
1134  rc = rpmnssMpiSet(pre, hbits, nss->item.data + (hbits/8), p, pend);
1135  if (nss->sig != NULL)
1136  SECITEM_FreeItem(nss->sig, PR_FALSE);
1137  if ((nss->sig = SECITEM_AllocItem(NULL, NULL, 0)) == NULL
1138  || DSAU_EncodeDerSig(nss->sig, &nss->item) != SECSuccess)
1139  rc = 1;
1140  nss->item.data = _free(nss->item.data);
1141  break;
1142  case 30: /* RSA n */
1143  if (nss->pub_key == NULL)
1144  nss->pub_key = rpmnssNewPublicKey(rsaKey);
1145  if (nss->pub_key == NULL)
1146  rc = 1;
1147  else
1148  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.rsa.modulus, p);
1149  break;
1150  case 31: /* RSA e */
1151  if (nss->pub_key == NULL)
1152  nss->pub_key = rpmnssNewPublicKey(rsaKey);
1153  if (nss->pub_key == NULL)
1154  rc = 1;
1155  else
1156  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.rsa.publicExponent, p);
1157  break;
1158  case 40: /* DSA p */
1159  if (nss->pub_key == NULL)
1160  nss->pub_key = rpmnssNewPublicKey(dsaKey);
1161  if (nss->pub_key == NULL)
1162  rc = 1;
1163  else
1164  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.prime, p);
1165  break;
1166  case 41: /* DSA q */
1167  if (nss->pub_key == NULL)
1168  nss->pub_key = rpmnssNewPublicKey(dsaKey);
1169  if (nss->pub_key == NULL)
1170  rc = 1;
1171  else
1172  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.subPrime, p);
1173  break;
1174  case 42: /* DSA g */
1175  if (nss->pub_key == NULL)
1176  nss->pub_key = rpmnssNewPublicKey(dsaKey);
1177  if (nss->pub_key == NULL)
1178  rc = 1;
1179  else
1180  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.base, p);
1181  break;
1182  case 43: /* DSA y */
1183  if (nss->pub_key == NULL)
1184  nss->pub_key = rpmnssNewPublicKey(dsaKey);
1185  if (nss->pub_key == NULL)
1186  rc = 1;
1187  else
1188  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.publicValue, p);
1189  break;
1190  case 50: /* ECDSA r */
1191  hbits = 256;
1192  nss->item.type = (SECItemType) 0;
1193  nss->item.len = 2 * (hbits/8);
1194  nss->item.data = (unsigned char *) xcalloc(1, nss->item.len);
1195  rc = rpmnssMpiSet(pre, hbits, nss->item.data, p, pend);
1196  break;
1197  case 51: /* ECDSA s */
1198  hbits = 256;
1199  rc = rpmnssMpiSet(pre, hbits, nss->item.data + (hbits/8), p, pend);
1200  if (nss->sig != NULL)
1201  SECITEM_FreeItem(nss->sig, PR_FALSE);
1202  if ((nss->sig = SECITEM_AllocItem(NULL, NULL, 0)) == NULL
1203  || DSAU_EncodeDerSigWithLen(nss->sig, &nss->item, nss->item.len) != SECSuccess)
1204  rc = 1;
1205  nss->item.data = _free(nss->item.data);
1206  break;
1207  case 60: /* ECDSA curve OID */
1208 assert(pend > p);
1209  if (nss->pub_key == NULL)
1210  nss->pub_key = rpmnssNewPublicKey(ecKey);
1211  if (nss->pub_key == NULL)
1212  rc = 1;
1213  else {
1214  SECKEYECParams * ecp = &nss->pub_key->u.ec.DEREncodedParams;
1215  ecp->data = (unsigned char *) PORT_ArenaZAlloc(nss->pub_key->arena, nb + 2);
1216  ecp->data[0] = SEC_ASN1_OBJECT_ID;
1217  ecp->data[1] = nb;
1218  memcpy(ecp->data + 2, p, nb);
1219  ecp->len = nb + 2;
1220  }
1221  break;
1222  case 61: /* ECDSA Q */
1223 assert(nss->pub_key);
1224  /* XXX assumes uncompressed Q as a MPI */
1225  nss->pub_key->u.ec.size = ((nb - (2 + 1)) * 8)/2;
1226  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.ec.publicValue, p);
1227  break;
1228  }
1229 /*@=moduncon@*/
1230  return rc;
1231 }
1232 
1233 /*@-mustmod@*/
1234 static
1235 void rpmnssClean(void * impl)
1236  /*@modifies impl @*/
1237 {
1238  rpmnss nss = (rpmnss) impl;
1239 /*@-moduncon@*/
1240  if (nss != NULL) {
1241  nss->nbits = 0;
1242  nss->err = 0;
1243  nss->badok = 0;
1244  nss->digest = _free(nss->digest);
1245  nss->digestlen = 0;
1246 
1247  if (nss->sec_key != NULL) {
1248  SECKEY_DestroyPrivateKey(nss->sec_key);
1249  nss->sec_key = NULL;
1250  }
1251  if (nss->pub_key != NULL) {
1252  SECKEY_DestroyPublicKey(nss->pub_key);
1253  nss->pub_key = NULL;
1254  }
1255  if (nss->sig != NULL) {
1256  SECITEM_ZfreeItem(nss->sig, PR_TRUE);
1257  nss->sig = NULL;
1258  }
1259 
1260  if (nss->ecparams != NULL) {
1261  SECITEM_FreeItem(nss->ecparams, PR_FALSE);
1262  nss->ecparams = NULL;
1263  }
1264 /*@=moduncon@*/
1265  }
1266 }
1267 /*@=mustmod@*/
1268 
1269 static /*@null@*/
1270 void * rpmnssFree(/*@only@*/ void * impl)
1271  /*@*/
1272 {
1273  rpmnssClean(impl);
1274  impl = _free(impl);
1275  return NULL;
1276 }
1277 
1278 static
1279 void * rpmnssInit(void)
1280  /*@globals _rpmnss_init @*/
1281  /*@modifies _rpmnss_init @*/
1282 {
1283  rpmnss nss = (rpmnss) xcalloc(1, sizeof(*nss));
1284  const char * _nssdb_path = rpmExpand("%{?_nssdb_path}", NULL);
1285 
1286 /*@-moduncon@*/
1287  if (_nssdb_path != NULL && *_nssdb_path == '/')
1288  (void) NSS_Init(_nssdb_path);
1289  else
1290  (void) NSS_NoDB_Init(NULL);
1291 /*@=moduncon@*/
1292  _nssdb_path = _free(_nssdb_path);
1293 
1294  _rpmnss_init = 1;
1295 
1296  return (void *) nss;
1297 }
1298 
1299 struct pgpImplVecs_s rpmnssImplVecs = {
1300  rpmnssSetRSA,
1301  rpmnssSetDSA,
1302  rpmnssSetELG,
1303  rpmnssSetECDSA,
1304 
1305  rpmnssErrChk,
1306  rpmnssAvailableCipher, rpmnssAvailableDigest, rpmnssAvailablePubkey,
1307  rpmnssVerify, rpmnssSign, rpmnssGenerate,
1308 
1309  rpmnssMpiItem, rpmnssClean,
1310  rpmnssFree, rpmnssInit
1311 };
1312 
1313 #endif
1314