rpm  5.4.14
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 typedef struct keyNV_s {
46 /*@observer@*/
47  const char * N; /* key name */
48  uint32_t V;
49 } keyNV_t;
50 
51 static int
52 keyNVCmp(const void * a, const void * b)
53 {
54  return strcmp(((keyNV_t *)a)->N, ((keyNV_t *)b)->N);
55 }
56 
57 static uint32_t
58 keyNV(keyNV_t * keys, size_t nkeys, /*@null@*/ const char *N)
59 {
60  uint32_t V = 0;
61 
62  if (N && *N) {
63  keyNV_t needle = { .N = N, .V = 0 };
64  keyNV_t *k = (keyNV_t *)
65  bsearch(&needle, keys, nkeys, sizeof(*keys), keyNVCmp);
66  if (k)
67  V = k->V;
68  }
69  return V;
70 }
71 
72 typedef struct keyVN_s {
73  int V;
74 /*@observer@*/
75  const char * N; /* key name */
76 } keyVN_t;
77 
78 static int
79 keyVNCmp(const void * a, const void * b)
80 {
81  return (((keyVN_t *)a)->V - ((keyVN_t *)b)->V);
82 }
83 
84 static const char *
85 keyVN(keyVN_t * keys, size_t nkeys, /*@null@*/ int V)
86 {
87  const char * N = NULL;
88 
89  if (V) {
90  /* XXX bsearch is overkill */
91  keyVN_t needle = {};
92  keyVN_t *k;
93 
94  needle.V = V;
95  needle.N = NULL;
96  k = (keyVN_t *)
97  bsearch(&needle, keys, nkeys, sizeof(*keys), keyVNCmp);
98  if (k)
99  N = k->N;
100  }
101  return N;
102 }
103 
104 static const char * _pgpHashAlgo2Name(uint32_t algo)
105 {
106  return pgpValStr(pgpHashTbl, (rpmuint8_t)algo);
107 }
108 
109 static const char * _pgpPubkeyAlgo2Name(uint32_t algo)
110 {
111  return pgpValStr(pgpPubkeyTbl, (rpmuint8_t)algo);
112 }
113 
114 /*==============================================================*/
115 
116 extern SECStatus
117 EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams);
118 
119 static keyNV_t rpmnssOIDS[] = {
120  { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
121  { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
122  { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
123  { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
124  { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
125  { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
126  { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
127  { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
128  { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
129  { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
130  { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
131  { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
132  { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
133  { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
134  { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
135  { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
136  { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
137  { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
138  { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
139  { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
140  { "nistb163", SEC_OID_SECG_EC_SECT163R2},
141  { "nistb233", SEC_OID_SECG_EC_SECT233R1},
142  { "nistb283", SEC_OID_SECG_EC_SECT283R1},
143  { "nistb409", SEC_OID_SECG_EC_SECT409R1},
144  { "nistb571", SEC_OID_SECG_EC_SECT571R1},
145  { "nistk163", SEC_OID_SECG_EC_SECT163K1},
146  { "nistk233", SEC_OID_SECG_EC_SECT233K1},
147  { "nistk283", SEC_OID_SECG_EC_SECT283K1},
148  { "nistk409", SEC_OID_SECG_EC_SECT409K1},
149  { "nistk571", SEC_OID_SECG_EC_SECT571K1},
150  { "nistp192", SEC_OID_SECG_EC_SECP192R1},
151  { "nistp224", SEC_OID_SECG_EC_SECP224R1},
152  { "nistp256", SEC_OID_SECG_EC_SECP256R1},
153  { "nistp384", SEC_OID_SECG_EC_SECP384R1},
154  { "nistp521", SEC_OID_SECG_EC_SECP521R1},
155  { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
156  { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
157  { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
158  { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
159  { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
160  { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
161  { "secp112r1", SEC_OID_SECG_EC_SECP112R1},
162  { "secp112r2", SEC_OID_SECG_EC_SECP112R2},
163  { "secp128r1", SEC_OID_SECG_EC_SECP128R1},
164  { "secp128r2", SEC_OID_SECG_EC_SECP128R2},
165  { "secp160k1", SEC_OID_SECG_EC_SECP160K1},
166  { "secp160r1", SEC_OID_SECG_EC_SECP160R1},
167  { "secp160r2", SEC_OID_SECG_EC_SECP160R2},
168  { "secp192k1", SEC_OID_SECG_EC_SECP192K1},
169  { "secp192r1", SEC_OID_SECG_EC_SECP192R1},
170  { "secp224k1", SEC_OID_SECG_EC_SECP224K1},
171  { "secp224r1", SEC_OID_SECG_EC_SECP224R1},
172  { "secp256k1", SEC_OID_SECG_EC_SECP256K1},
173  { "secp256r1", SEC_OID_SECG_EC_SECP256R1},
174  { "secp384r1", SEC_OID_SECG_EC_SECP384R1},
175  { "secp521r1", SEC_OID_SECG_EC_SECP521R1},
176  { "sect113r1", SEC_OID_SECG_EC_SECT113R1},
177  { "sect113r2", SEC_OID_SECG_EC_SECT113R2},
178  { "sect131r1", SEC_OID_SECG_EC_SECT131R1},
179  { "sect131r2", SEC_OID_SECG_EC_SECT131R2},
180  { "sect163k1", SEC_OID_SECG_EC_SECT163K1},
181  { "sect163r1", SEC_OID_SECG_EC_SECT163R1},
182  { "sect163r2", SEC_OID_SECG_EC_SECT163R2},
183  { "sect193r1", SEC_OID_SECG_EC_SECT193R1},
184  { "sect193r2", SEC_OID_SECG_EC_SECT193R2},
185  { "sect233k1", SEC_OID_SECG_EC_SECT233K1},
186  { "sect233r1", SEC_OID_SECG_EC_SECT233R1},
187  { "sect239k1", SEC_OID_SECG_EC_SECT239K1},
188  { "sect283k1", SEC_OID_SECG_EC_SECT283K1},
189  { "sect283r1", SEC_OID_SECG_EC_SECT283R1},
190  { "sect409k1", SEC_OID_SECG_EC_SECT409K1},
191  { "sect409r1", SEC_OID_SECG_EC_SECT409R1},
192  { "sect571k1", SEC_OID_SECG_EC_SECT571K1},
193  { "sect571r1", SEC_OID_SECG_EC_SECT571R1},
194 };
195 static size_t nrpmnssOIDS = sizeof(rpmnssOIDS) / sizeof(rpmnssOIDS[0]);
196 
197 #define _ENTRY(_v) { SEC_ERROR_##_v, #_v }
198 /* XXX sorted table */
199 static keyVN_t rpmnssERRS[] = {
200  _ENTRY(IO),
201  _ENTRY(LIBRARY_FAILURE),
202  _ENTRY(BAD_DATA),
203  _ENTRY(OUTPUT_LEN),
204  _ENTRY(INPUT_LEN),
205  _ENTRY(INVALID_ARGS),
206  _ENTRY(INVALID_ALGORITHM),
207  _ENTRY(INVALID_AVA),
208  _ENTRY(INVALID_TIME),
209  _ENTRY(BAD_DER),
210  _ENTRY(BAD_SIGNATURE),
211  _ENTRY(EXPIRED_CERTIFICATE),
212  _ENTRY(REVOKED_CERTIFICATE),
213  _ENTRY(UNKNOWN_ISSUER),
214  _ENTRY(BAD_KEY),
215  _ENTRY(BAD_PASSWORD),
216  _ENTRY(RETRY_PASSWORD),
217  _ENTRY(NO_NODELOCK),
218  _ENTRY(BAD_DATABASE),
219  _ENTRY(NO_MEMORY),
220  _ENTRY(UNTRUSTED_ISSUER),
221  _ENTRY(UNTRUSTED_CERT),
222  _ENTRY(DUPLICATE_CERT),
223  _ENTRY(DUPLICATE_CERT_NAME),
224  _ENTRY(ADDING_CERT),
225  _ENTRY(FILING_KEY),
226  _ENTRY(NO_KEY),
227  _ENTRY(CERT_VALID),
228  _ENTRY(CERT_NOT_VALID),
229  _ENTRY(CERT_NO_RESPONSE),
230  _ENTRY(EXPIRED_ISSUER_CERTIFICATE),
231  _ENTRY(CRL_EXPIRED),
232  _ENTRY(CRL_BAD_SIGNATURE),
233  _ENTRY(CRL_INVALID),
234  _ENTRY(EXTENSION_VALUE_INVALID),
235  _ENTRY(EXTENSION_NOT_FOUND),
236  _ENTRY(CA_CERT_INVALID),
237  _ENTRY(PATH_LEN_CONSTRAINT_INVALID),
238  _ENTRY(CERT_USAGES_INVALID),
239 /* SEC_INTERNAL_ONLY */
240  _ENTRY(INVALID_KEY),
241  _ENTRY(UNKNOWN_CRITICAL_EXTENSION),
242  _ENTRY(OLD_CRL),
243  _ENTRY(NO_EMAIL_CERT),
244  _ENTRY(NO_RECIPIENT_CERTS_QUERY),
245  _ENTRY(NOT_A_RECIPIENT),
246  _ENTRY(PKCS7_KEYALG_MISMATCH),
247  _ENTRY(PKCS7_BAD_SIGNATURE),
248  _ENTRY(UNSUPPORTED_KEYALG),
249  _ENTRY(DECRYPTION_DISALLOWED),
250 /* Fortezza Alerts */
251 /* XP_SEC_FORTEZZA_BAD_CARD */
252 /* XP_SEC_FORTEZZA_NO_CARD */
253 /* XP_SEC_FORTEZZA_NONE_SELECTED */
254 /* XP_SEC_FORTEZZA_MORE_INFO */
255 /* XP_SEC_FORTEZZA_PERSON_NOT_FOUND */
256 /* XP_SEC_FORTEZZA_NO_MORE_INFO */
257 /* XP_SEC_FORTEZZA_BAD_PIN */
258 /* XP_SEC_FORTEZZA_PERSON_ERROR */
259  _ENTRY(NO_KRL),
260  _ENTRY(KRL_EXPIRED),
261  _ENTRY(KRL_BAD_SIGNATURE),
262  _ENTRY(REVOKED_KEY),
263  _ENTRY(KRL_INVALID),
264  _ENTRY(NEED_RANDOM),
265  _ENTRY(NO_MODULE),
266  _ENTRY(NO_TOKEN),
267  _ENTRY(READ_ONLY),
268  _ENTRY(NO_SLOT_SELECTED),
269  _ENTRY(CERT_NICKNAME_COLLISION),
270  _ENTRY(KEY_NICKNAME_COLLISION),
271  _ENTRY(SAFE_NOT_CREATED),
272  _ENTRY(BAGGAGE_NOT_CREATED),
273 /* XP_JAVA_REMOVE_PRINCIPAL_ERROR */
274 /* XP_JAVA_DELETE_PRIVILEGE_ERROR */
275 /* XP_JAVA_CERT_NOT_EXISTS_ERROR */
276  _ENTRY(BAD_EXPORT_ALGORITHM),
277  _ENTRY(EXPORTING_CERTIFICATES),
278  _ENTRY(IMPORTING_CERTIFICATES),
279  _ENTRY(PKCS12_DECODING_PFX),
280  _ENTRY(PKCS12_INVALID_MAC),
281  _ENTRY(PKCS12_UNSUPPORTED_MAC_ALGORITHM),
282  _ENTRY(PKCS12_UNSUPPORTED_TRANSPORT_MODE),
283  _ENTRY(PKCS12_CORRUPT_PFX_STRUCTURE),
284  _ENTRY(PKCS12_UNSUPPORTED_PBE_ALGORITHM),
285  _ENTRY(PKCS12_UNSUPPORTED_VERSION),
286  _ENTRY(PKCS12_PRIVACY_PASSWORD_INCORRECT),
287  _ENTRY(PKCS12_CERT_COLLISION),
288  _ENTRY(USER_CANCELLED),
289  _ENTRY(PKCS12_DUPLICATE_DATA),
290  _ENTRY(MESSAGE_SEND_ABORTED),
291  _ENTRY(INADEQUATE_KEY_USAGE),
292  _ENTRY(INADEQUATE_CERT_TYPE),
293  _ENTRY(CERT_ADDR_MISMATCH),
294  _ENTRY(PKCS12_UNABLE_TO_IMPORT_KEY),
295  _ENTRY(PKCS12_IMPORTING_CERT_CHAIN),
296  _ENTRY(PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME),
297  _ENTRY(PKCS12_UNABLE_TO_EXPORT_KEY),
298  _ENTRY(PKCS12_UNABLE_TO_WRITE),
299  _ENTRY(PKCS12_UNABLE_TO_READ),
300  _ENTRY(PKCS12_KEY_DATABASE_NOT_INITIALIZED),
301  _ENTRY(KEYGEN_FAIL),
302  _ENTRY(INVALID_PASSWORD),
303  _ENTRY(RETRY_OLD_PASSWORD),
304  _ENTRY(BAD_NICKNAME),
305  _ENTRY(NOT_FORTEZZA_ISSUER),
306  _ENTRY(CANNOT_MOVE_SENSITIVE_KEY),
307  _ENTRY(JS_INVALID_MODULE_NAME),
308  _ENTRY(JS_INVALID_DLL),
309  _ENTRY(JS_ADD_MOD_FAILURE),
310  _ENTRY(JS_DEL_MOD_FAILURE),
311  _ENTRY(OLD_KRL),
312  _ENTRY(CKL_CONFLICT),
313  _ENTRY(CERT_NOT_IN_NAME_SPACE),
314  _ENTRY(KRL_NOT_YET_VALID),
315  _ENTRY(CRL_NOT_YET_VALID),
316  _ENTRY(UNKNOWN_CERT),
317  _ENTRY(UNKNOWN_SIGNER),
318  _ENTRY(CERT_BAD_ACCESS_LOCATION),
319  _ENTRY(OCSP_UNKNOWN_RESPONSE_TYPE),
320  _ENTRY(OCSP_BAD_HTTP_RESPONSE),
321  _ENTRY(OCSP_MALFORMED_REQUEST),
322  _ENTRY(OCSP_SERVER_ERROR),
323  _ENTRY(OCSP_TRY_SERVER_LATER),
324  _ENTRY(OCSP_REQUEST_NEEDS_SIG),
325  _ENTRY(OCSP_UNAUTHORIZED_REQUEST),
326  _ENTRY(OCSP_UNKNOWN_RESPONSE_STATUS),
327  _ENTRY(OCSP_UNKNOWN_CERT),
328  _ENTRY(OCSP_NOT_ENABLED),
329  _ENTRY(OCSP_NO_DEFAULT_RESPONDER),
330  _ENTRY(OCSP_MALFORMED_RESPONSE),
331  _ENTRY(OCSP_UNAUTHORIZED_RESPONSE),
332  _ENTRY(OCSP_FUTURE_RESPONSE),
333  _ENTRY(OCSP_OLD_RESPONSE),
334 /* smime stuff */
335  _ENTRY(DIGEST_NOT_FOUND),
336  _ENTRY(UNSUPPORTED_MESSAGE_TYPE),
337  _ENTRY(MODULE_STUCK),
338  _ENTRY(BAD_TEMPLATE),
339  _ENTRY(CRL_NOT_FOUND),
340  _ENTRY(REUSED_ISSUER_AND_SERIAL),
341  _ENTRY(BUSY),
342  _ENTRY(EXTRA_INPUT),
343 /* error codes used by elliptic curve code */
344  _ENTRY(UNSUPPORTED_ELLIPTIC_CURVE),
345  _ENTRY(UNSUPPORTED_EC_POINT_FORM),
346  _ENTRY(UNRECOGNIZED_OID),
347  _ENTRY(OCSP_INVALID_SIGNING_CERT),
348 /* new revocation errors */
349  _ENTRY(REVOKED_CERTIFICATE_CRL),
350  _ENTRY(REVOKED_CERTIFICATE_OCSP),
351  _ENTRY(CRL_INVALID_VERSION),
352  _ENTRY(CRL_V1_CRITICAL_EXTENSION),
353  _ENTRY(CRL_UNKNOWN_CRITICAL_EXTENSION),
354  _ENTRY(UNKNOWN_OBJECT_TYPE),
355  _ENTRY(INCOMPATIBLE_PKCS11),
356  _ENTRY(NO_EVENT),
357  _ENTRY(CRL_ALREADY_EXISTS),
358  _ENTRY(NOT_INITIALIZED),
359  _ENTRY(TOKEN_NOT_LOGGED_IN),
360  _ENTRY(OCSP_RESPONDER_CERT_INVALID),
361  _ENTRY(OCSP_BAD_SIGNATURE),
362  _ENTRY(OUT_OF_SEARCH_LIMITS),
363  _ENTRY(INVALID_POLICY_MAPPING),
364  _ENTRY(POLICY_VALIDATION_FAILED),
365 /* No longer used. Unknown AIA location types are now silently ignored. */
366  _ENTRY(UNKNOWN_AIA_LOCATION_TYPE),
367  _ENTRY(BAD_HTTP_RESPONSE),
368  _ENTRY(BAD_LDAP_RESPONSE),
369  _ENTRY(FAILED_TO_ENCODE_DATA),
370  _ENTRY(BAD_INFO_ACCESS_LOCATION),
371  _ENTRY(LIBPKIX_INTERNAL),
372  _ENTRY(PKCS11_GENERAL_ERROR),
373  _ENTRY(PKCS11_FUNCTION_FAILED),
374  _ENTRY(PKCS11_DEVICE_ERROR),
375 #if defined(SEC_ERROR_BAD_INFO_ACCESS_METHOD)
376  _ENTRY(BAD_INFO_ACCESS_METHOD),
377 #endif
378 #if defined(SEC_ERROR_CRL_IMPORT_FAILED)
379  _ENTRY(CRL_IMPORT_FAILED),
380 #endif
381 #if defined(SEC_ERROR_EXPIRED_PASSWORD)
382  _ENTRY(EXPIRED_PASSWORD),
383 #endif
384 #if defined(SEC_ERROR_LOCKED_PASSWORD)
385  _ENTRY(LOCKED_PASSWORD),
386 #endif
387 #if defined(SEC_ERROR_UNKNOWN_PKCS11_ERROR)
388  _ENTRY(UNKNOWN_PKCS11_ERROR),
389 #endif
390 #if defined(SEC_ERROR_BAD_CRL_DP_URL)
391  _ENTRY(BAD_CRL_DP_URL),
392 #endif
393 #if defined(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED)
394  _ENTRY(CERT_SIGNATURE_ALGORITHM_DISABLED),
395 #endif
396 #if defined(SEC_ERROR_LEGACY_DATABASE)
397  _ENTRY(LEGACY_DATABASE),
398 #endif
399 #if defined(SEC_ERROR_APPLICATION_CALLBACK_ERROR)
400  _ENTRY(APPLICATION_CALLBACK_ERROR),
401 #endif
402 };
403 static size_t nrpmnssERRS = sizeof(rpmnssERRS) / sizeof(rpmnssERRS[0]);
404 #undef _ENTRY
405 
406 static uint32_t curve2oid(const char * name)
407 {
408  uint32_t oid = keyNV(rpmnssOIDS, nrpmnssOIDS, name);
409  if (oid == 0)
410  oid = SEC_OID_UNKNOWN;
411 
412 if (_pgp_debug)
413 fprintf(stderr, "<-- %s(%s) oid %u\n", __FUNCTION__, name, oid);
414 
415  return oid;
416 }
417 
418 static const char * rpmnssStrerror(int err)
419 {
420  static char buf[64];
421  const char * errN = keyVN(rpmnssERRS, nrpmnssERRS, err);
422  if (errN == NULL) {
423  snprintf(buf, sizeof(buf), "SEC_ERROR(%d)", err);
424  errN = buf;
425  }
426  return errN;
427 }
428 
429 static
430 int rpmnssErr(rpmnss nss, const char * msg, int rc)
431  /*@*/
432 {
433 #ifdef REFERENCE
434  /* XXX Don't spew on expected failures ... */
435  if (err && gcry_err_code(err) != gc->badok)
436  fprintf (stderr, "rpmgc: %s(0x%0x): %s/%s\n",
437  msg, (unsigned)err, gcry_strsource(err), gcry_strerror(err));
438 #endif
439  if (rc != SECSuccess) {
440  int err = PORT_GetError();
441  fprintf (stderr, "rpmnss: %s rc(%d) err(%d) %s\n",
442  msg, rc, err, rpmnssStrerror(err));
443  }
444  return rc;
445 }
446 
447 /*==============================================================*/
448 static SECOidTag getEncAlg(unsigned pubkey_algo)
449 {
450  SECOidTag encAlg = SEC_OID_UNKNOWN;
451 
452  switch (pubkey_algo) {
453  case PGPPUBKEYALGO_RSA: encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION; break;
454  case PGPPUBKEYALGO_DSA: encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE; break;
455  case PGPPUBKEYALGO_ECDSA: encAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;break;
456  case PGPPUBKEYALGO_ELGAMAL: /*@fallthrough@*/
457  default:
458  break;
459  }
460  return encAlg;
461 }
462 
463 static SECOidTag getHashAlg(unsigned hash_algo)
464 {
465  SECOidTag hashAlg = SEC_OID_UNKNOWN;
466 
467  switch (hash_algo) {
468  case PGPHASHALGO_MD2: hashAlg = SEC_OID_MD2; break;
469  case PGPHASHALGO_MD4: hashAlg = SEC_OID_MD4; break;
470  case PGPHASHALGO_MD5: hashAlg = SEC_OID_MD5; break;
471  case PGPHASHALGO_SHA1: hashAlg = SEC_OID_SHA1; break;
472  case PGPHASHALGO_SHA224: hashAlg = SEC_OID_SHA224; break;
473  case PGPHASHALGO_SHA256: hashAlg = SEC_OID_SHA256; break;
474  case PGPHASHALGO_SHA384: hashAlg = SEC_OID_SHA384; break;
475  case PGPHASHALGO_SHA512: hashAlg = SEC_OID_SHA512; break;
476  case PGPHASHALGO_RIPEMD160: /*@fallthrough@*/
477  case PGPHASHALGO_TIGER192: /*@fallthrough@*/
478  case PGPHASHALGO_HAVAL_5_160: /*@fallthrough@*/
479  default:
480  break;
481  }
482  return hashAlg;
483 }
484 
485 /*==============================================================*/
486 
487 static
488 int rpmnssSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
489  /*@modifies dig @*/
490 {
491  rpmnss nss = (rpmnss) dig->impl;
492  int rc = 1; /* assume error */
493  int xx;
494 pgpDigParams pubp = pgpGetPubkey(dig);
495 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
496 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
497 
498 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
499 
500 nss->digest = _free(nss->digest);
501 nss->digestlen = 0;
502  xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0);
503 
504  nss->encAlg = getEncAlg(pubp->pubkey_algo);
505  nss->hashAlg = getHashAlg(sigp->hash_algo);
506  if (nss->hashAlg == SEC_OID_UNKNOWN)
507  goto exit;
508 
509  /* Compare leading 16 bits of digest for quick check. */
510  rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16));
511 
512 exit:
513 SPEW(rc, !rc, dig);
514  return rc;
515 }
516 
517 static
518 int rpmnssVerifyRSA(pgpDig dig)
519  /*@*/
520 {
521  rpmnss nss = (rpmnss) dig->impl;
522  int rc = 0; /* assume failure */
523 
524 nss->encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION; /* XXX FIXME */
525 assert(nss->encAlg == SEC_OID_PKCS1_RSA_ENCRYPTION);
526 assert(nss->hashAlg != SEC_OID_UNKNOWN);
527 
528  nss->item.type = siBuffer;
529  nss->item.data = (unsigned char *) nss->digest;
530  nss->item.len = (unsigned) nss->digestlen;
531 
532  rc = rpmnssErr(nss, "VFY_VerifyDigestDirect",
533  VFY_VerifyDigestDirect(&nss->item, nss->pub_key,
534  nss->sig, nss->encAlg, nss->hashAlg, NULL));
535  rc = (rc == SECSuccess);
536 
537 SPEW(!rc, rc, dig);
538  return rc;
539 }
540 
541 static int rpmnssSignRSA(pgpDig dig)
542 {
543  rpmnss nss = (rpmnss) dig->impl;
544  int rc = 0; /* assume failure. */
545 
546 assert(nss->hashAlg != SEC_OID_UNKNOWN);
547 
548  nss->item.type = siBuffer;
549  nss->item.data = (unsigned char *) nss->digest;
550  nss->item.len = (unsigned) nss->digestlen;
551 
552 if (nss->sig != NULL) {
553  SECITEM_ZfreeItem(nss->sig, PR_TRUE);
554  nss->sig = NULL;
555 }
556 nss->sig = SECITEM_AllocItem(NULL, NULL, 0);
557 nss->sig->type = siBuffer;
558 
559  rc = rpmnssErr(nss, "SGN_Digest",
560  SGN_Digest(nss->sec_key, nss->hashAlg, nss->sig, &nss->item));
561  rc = (rc == SECSuccess);
562 
563 SPEW(!rc, rc, dig);
564  return rc;
565 }
566 
567 static int rpmnssGenerateRSA(pgpDig dig)
568 {
569  rpmnss nss = (rpmnss) dig->impl;
570  int rc = 0; /* assume failure */
571 
572 if (nss->nbits == 0) nss->nbits = 1024; /* XXX FIXME */
573 assert(nss->nbits);
574 
575  { void * _cx = NULL;
576  CK_MECHANISM_TYPE _type = CKM_RSA_PKCS_KEY_PAIR_GEN;
577  PK11SlotInfo * _slot = PK11_GetBestSlot(_type, _cx);
578  int _isPerm = PR_FALSE;
579  int _isSensitive = PR_TRUE;
580 
581  if (_slot) {
582  static unsigned _pe = 0x10001; /* XXX FIXME: pass in e */
583  PK11RSAGenParams rsaparams = {};
584  void * params = &rsaparams;
585 
586  rsaparams.keySizeInBits = nss->nbits;
587  rsaparams.pe = _pe;
588 
589  nss->sec_key = PK11_GenerateKeyPair(_slot, _type, params,
590  &nss->pub_key, _isPerm, _isSensitive, _cx);
591 
592  PK11_FreeSlot(_slot);
593  }
594  }
595 
596  rc = (nss->sec_key && nss->pub_key);
597 
598 SPEW(!rc, rc, dig);
599  return rc;
600 }
601 
602 static
603 int rpmnssSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
604  /*@modifies dig @*/
605 {
606  rpmnss nss = (rpmnss) dig->impl;
607  int rc = 1; /* assume error */
608  int xx;
609 pgpDigParams pubp = pgpGetPubkey(dig);
610 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
611 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
612 
613 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
614 
615 nss->digest = _free(nss->digest);
616 nss->digestlen = 0;
617  xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0);
618 
619  nss->encAlg = getEncAlg(pubp->pubkey_algo);
620  nss->hashAlg = getHashAlg(sigp->hash_algo);
621  if (nss->hashAlg == SEC_OID_UNKNOWN) {
622 fprintf(stderr, "*** %s/%s hashAlg %d\n", dig->pubkey_algoN, dig->hash_algoN, (unsigned)nss->hashAlg);
623  goto exit;
624  }
625 
626  /* Compare leading 16 bits of digest for quick check. */
627  rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16));
628 
629 exit:
630 SPEW(rc, !rc, dig);
631  return rc;
632 }
633 
634 static
635 int rpmnssVerifyDSA(pgpDig dig)
636  /*@*/
637 {
638  rpmnss nss = (rpmnss) dig->impl;
639  int rc = 0; /* assume failure */
640 
641 nss->encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE; /* XXX FIXME */
642 assert(nss->encAlg == SEC_OID_ANSIX9_DSA_SIGNATURE);
643 assert(nss->hashAlg != SEC_OID_UNKNOWN);
644 
645  nss->item.type = siBuffer;
646  nss->item.data = (unsigned char *) nss->digest;
647  nss->item.len = (unsigned) nss->digestlen;
648 
649  rc = rpmnssErr(nss, "VFY_VerifyDigestDirect",
650  VFY_VerifyDigestDirect(&nss->item, nss->pub_key,
651  nss->sig, nss->encAlg, nss->hashAlg, NULL));
652  rc = (rc == SECSuccess);
653 
654 SPEW(!rc, rc, dig);
655  return rc;
656 }
657 
658 static int rpmnssSignDSA(pgpDig dig)
659 {
660  rpmnss nss = (rpmnss) dig->impl;
661  int rc = 0; /* assume failure. */
662 SECItem sig = { siBuffer, NULL, 0 };
663 
664 assert(nss->hashAlg != SEC_OID_UNKNOWN);
665 
666  nss->item.type = siBuffer;
667  nss->item.data = (unsigned char *) nss->digest;
668  nss->item.len = (unsigned) nss->digestlen;
669 
670 if (nss->sig != NULL) {
671  SECITEM_ZfreeItem(nss->sig, PR_TRUE);
672  nss->sig = NULL;
673 }
674 
675 nss->sig = SECITEM_AllocItem(NULL, NULL, 0);
676 nss->sig->type = siBuffer;
677 
678  rc = rpmnssErr(nss, "SGN_Digest",
679  SGN_Digest(nss->sec_key, nss->hashAlg, &sig, &nss->item));
680 
681  if (rc == SECSuccess)
682  rc = rpmnssErr(nss, "DSAU_EncodeDerSigWithLen",
683  DSAU_EncodeDerSigWithLen(nss->sig, &sig, sig.len));
684  sig.data = _free(sig.data);
685 
686  rc = (rc == SECSuccess);
687 
688 SPEW(!rc, rc, dig);
689  return rc;
690 }
691 
692 static int rpmnssGenerateDSA(pgpDig dig)
693 {
694  rpmnss nss = (rpmnss) dig->impl;
695  int rc = 0; /* assume failure */
696 unsigned _L = 8;
697 unsigned _N = 0;
698 unsigned _seedBytes = 0;
699 int xx;
700 
701 if (nss->nbits == 0) nss->nbits = 1024; /* XXX FIXME */
702 assert(nss->nbits);
703 if (nss->qbits == 0) nss->qbits = 160; /* XXX FIXME */
704 assert(nss->qbits);
705 
706 /*
707  * Generate PQGParams and PQGVerify structs.
708  * Length of P specified by L.
709  * if L is greater than 1024 then the resulting verify parameters will be
710  * DSA2.
711  * Length of Q specified by N. If zero, The PKCS #11 module will
712  * pick an appropriately sized Q for P. If N is specified and L = 1024, then
713  * the resulting verify parameters will be DSA2, Otherwise DSA1 parameters
714  * will be returned.
715  * Length of SEED in bytes specified in seedBytes.
716  *
717  * The underlying PKCS #11 module will check the values for L, N,
718  * and seedBytes. The rules for softoken are:
719  *
720  * If L <= 1024, then L must be between 512 and 1024 in increments of 64 bits.
721  * If L <= 1024, then N must be 0 or 160.
722  * If L >= 1024, then L and N must match the following table:
723  * L=1024 N=0 or 160
724  * L=2048 N=0 or 224
725  * L=2048 N=256
726  * L=3072 N=0 or 256
727  * if L <= 1024
728  * seedBbytes must be in the range [20..256].
729  * if L >= 1024
730  * seedBbytes must be in the range [20..L/16].
731  */
732 
733  xx = PQG_PBITS_TO_INDEX(nss->nbits);
734  if (xx >= 0 && xx <= 8) { /* FIPS-186-1 */
735  _L = nss->nbits;
736  _N = 0; /* XXX DSA1 */
737  _seedBytes = 0; /* XXX DSA1 */
738  } else { /* FIPS-186-3 */
739  switch (nss->nbits) {
740  default: /* XXX sanity */
741  case 1024:
742  _L = 1024;
743  _N = 160; /* XXX DSA2 */
744  _seedBytes = 20;
745  break;
746  case 2048:
747  _L = 2048;
748  _N = (nss->qbits == 256) ? 256 : 0; /* 256 or 224 */
749  _seedBytes = 20; /* XXX FIXME */
750  break;
751  case 3072:
752  _L = 3072;
753  _N = (nss->qbits == 256) ? 256 : 0; /* always 256 */
754  _seedBytes = 20; /* XXX FIXME */
755  break;
756  }
757  }
758 
759  { void * _cx = NULL;
760  CK_MECHANISM_TYPE _type = CKM_DSA_KEY_PAIR_GEN;
761  PK11SlotInfo * _slot = PK11_GetBestSlot(_type, _cx);
762  int _isPerm = PR_FALSE;
763  int _isSensitive = PR_TRUE;
764 
765  if (_slot) {
766  PQGParams *pqgParams = NULL;
767  PQGVerify *pqgVfy = NULL;
768  void * params = NULL;
769 
770 #ifndef NOTYET
771  xx = rpmnssErr(nss, "PK11_PQG_ParamGenV2",
772  PK11_PQG_ParamGenV2(_L, _N, _seedBytes,
773  &pqgParams, &pqgVfy));
774 #else
775  xx = rpmnssErr(nss, "PK11_PQG_ParamGen",
776  PK11_PQG_ParamGen(0, &pqgParams, &pqgVfy));
777 #endif
778  if (xx != SECSuccess)
779  goto exit;
780  params = pqgParams;
781 
782  nss->sec_key = PK11_GenerateKeyPair(_slot, _type, params,
783  &nss->pub_key, _isPerm, _isSensitive, _cx);
784 
785  if (pqgVfy) PK11_PQG_DestroyVerify(pqgVfy);
786  if (pqgParams) PK11_PQG_DestroyParams(pqgParams);
787 
788  PK11_FreeSlot(_slot);
789  }
790  }
791 
792  rc = (nss->sec_key && nss->pub_key);
793 
794 exit:
795 SPEW(!rc, rc, dig);
796  return rc;
797 }
798 
799 static
800 int rpmnssSetELG(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
801  /*@*/
802 {
803  rpmnss nss = (rpmnss) dig->impl;
804  int rc = 1; /* assume failure */
805  int xx;
806 
807 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
808 nss->digest = _free(nss->digest);
809 nss->digestlen = 0;
810  xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0);
811 
812  /* Compare leading 16 bits of digest for quick check. */
813  rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16));
814  rc = 1; /* XXX always fail */
815 
816 SPEW(rc, !rc, dig);
817  return rc;
818 }
819 
820 static
821 int rpmnssSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
822  /*@*/
823 {
824  rpmnss nss = (rpmnss) dig->impl;
825  int rc = 1; /* assume failure */
826  int xx;
827 pgpDigParams pubp = pgpGetPubkey(dig);
828 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
829 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
830 
831 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
832 
833 nss->digest = _free(nss->digest);
834 nss->digestlen = 0;
835  xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0);
836 
837  nss->encAlg = getEncAlg(pubp->pubkey_algo);
838  nss->hashAlg = getHashAlg(sigp->hash_algo);
839  if (nss->hashAlg == SEC_OID_UNKNOWN)
840  goto exit;
841 
842  /* Compare leading 16 bits of digest for quick check. */
843  rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16));
844 
845 exit:
846 SPEW(rc, !rc, dig);
847  return rc;
848 }
849 
850 static
851 int rpmnssVerifyECDSA(/*@unused@*/pgpDig dig)
852  /*@*/
853 {
854  rpmnss nss = (rpmnss) dig->impl;
855  int rc = 0; /* assume failure */
856 
857 nss->encAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; /* XXX FIXME */
858 assert(nss->encAlg == SEC_OID_ANSIX962_EC_PUBLIC_KEY);
859 assert(nss->hashAlg != SEC_OID_UNKNOWN);
860 
861  nss->item.type = siBuffer;
862  nss->item.data = (unsigned char *) nss->digest;
863  nss->item.len = (unsigned) nss->digestlen;
864 
865  rc = rpmnssErr(nss, "VFY_VerifyDigestDirect",
866  VFY_VerifyDigestDirect(&nss->item, nss->pub_key,
867  nss->sig, nss->encAlg, nss->hashAlg, NULL));
868  rc = (rc == SECSuccess);
869 
870 SPEW(!rc, rc, dig);
871  return rc;
872 }
873 
874 static
875 int rpmnssSignECDSA(pgpDig dig)
876  /*@*/
877 {
878  rpmnss nss = (rpmnss) dig->impl;
879  int rc = 0; /* assume failure. */
880 SECItem sig = { siBuffer, NULL, 0 };
881 
882 assert(nss->hashAlg != SEC_OID_UNKNOWN);
883 
884  nss->item.type = siBuffer;
885  nss->item.data = nss->digest;
886  nss->item.len = (unsigned) nss->digestlen;
887 
888 if (nss->sig != NULL) {
889  SECITEM_ZfreeItem(nss->sig, PR_TRUE);
890  nss->sig = NULL;
891 }
892 nss->sig = SECITEM_AllocItem(NULL, NULL, 0);
893 nss->sig->type = siBuffer;
894 
895  rc = rpmnssErr(nss, "SGN_Digest",
896  SGN_Digest(nss->sec_key, nss->hashAlg, &sig, &nss->item));
897 
898  if (rc == SECSuccess)
899  rc = rpmnssErr(nss, "DSAU_EncodeDerSigWithLen",
900  DSAU_EncodeDerSigWithLen(nss->sig, &sig, sig.len));
901  sig.data = _free(sig.data);
902 
903  rc = (rc == SECSuccess);
904 
905 SPEW(!rc, rc, dig);
906  return rc;
907 }
908 
909 static int rpmnssLoadParams(pgpDig dig)
910 {
911  rpmnss nss = (rpmnss) dig->impl;
912  const char * name;
913  SECOidTag curveOid = SEC_OID_UNKNOWN;
914  SECOidData * oidData = NULL;
915  int rc = 1; /* assume failure. */
916 
917  name = nss->curveN;
918  if (name == NULL)
919  goto exit;
920  nss->curveOid = curveOid = curve2oid(name);
921  if (curveOid == SEC_OID_UNKNOWN)
922  goto exit;
923  oidData = SECOID_FindOIDByTag(curveOid);
924  if (oidData == NULL)
925  goto exit;
926 
927  nss->ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
928  nss->ecparams->data[0] = SEC_ASN1_OBJECT_ID;
929  nss->ecparams->data[1] = oidData->oid.len;
930  memcpy(nss->ecparams->data + 2, oidData->oid.data, oidData->oid.len);
931  rc = 0;
932 
933 exit:
934 if (_pgp_debug)
935 fprintf(stderr, "<-- %s(%p,%s) oid %u params %p\n", __FUNCTION__, dig, name, nss->curveOid, nss->ecparams);
936  return rc;
937 }
938 
939 static
940 int rpmnssGenerateECDSA(/*@unused@*/pgpDig dig)
941  /*@*/
942 {
943  rpmnss nss = (rpmnss) dig->impl;
944  int rc = 0; /* assume failure. */
945 
946 if (nss->sec_key != NULL) {
947  SECKEY_DestroyPrivateKey(nss->sec_key);
948  nss->sec_key = NULL;
949 }
950 if (nss->pub_key != NULL) {
951  SECKEY_DestroyPublicKey(nss->pub_key);
952  nss->pub_key = NULL;
953 }
954 
955  if (nss->nbits == 0) /* XXX FIXME */
956  nss->nbits = 256;
957 assert(nss->nbits);
958 
959  if (nss->curveN == NULL) /* XXX FIXME */
960  switch (nss->nbits) { /* XXX only NIST prime curves for now */
961  default: goto exit; /*@notreached@*/ break;
962  case 192: nss->curveN = xstrdup("nistp192"); break;
963  case 224: nss->curveN = xstrdup("nistp224"); break;
964  case 256: nss->curveN = xstrdup("nistp256"); break;
965  case 384: nss->curveN = xstrdup("nistp384"); break;
966  case 521: nss->curveN = xstrdup("nistp521"); break;
967  }
968 assert(nss->curveN);
969 
970  rc = rpmnssLoadParams(dig);
971 assert(nss->ecparams);
972 
973  { void * _cx = NULL;
974  CK_MECHANISM_TYPE _type = CKM_EC_KEY_PAIR_GEN;
975  PK11SlotInfo * _slot = PK11_GetBestSlot(_type, _cx);
976 #ifdef NOTYET
977 /* Create an EC key pair in any slot able to do so,
978  * This is a "session" (temporary), not "token" (permanent) key.
979  * Because of the high probability that this key will need to be moved to
980  * another token, and the high cost of moving "sensitive" keys, we attempt
981  * to create this key pair without the "sensitive" attribute, but revert to
982  * creating a "sensitive" key if necessary.
983  */
984 
985  PK11AttrFlags _aFlags = (PK11_ATTR_SESSION
986  | PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC);
987  CK_FLAGS _opFlags = CKF_DERIVE;
988  CK_FLAGS _opFlagsMask = CKF_DERIVE | CKF_SIGN;
989 
990  if (_slot) {
991 
992  nss->sec_key = PK11_GenerateKeyPairWithOpFlags(_slot, _type,
993  nss->ecparams,
994  &nss->pub_key, _aFlags, _opFlags, _opFlagsMask, _cx);
995 
996  if (nss->sec_key == NULL) {
997  _aFlags = (PK11_ATTR_SESSION
998  | PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE);
999  nss->sec_key = PK11_GenerateKeyPairWithOpFlags(_slot, _type,
1000  nss->ecparams,
1001  &nss->pub_key, _aFlags, _opFlags, _opFlagsMask, _cx);
1002 
1003  }
1004 #else
1005  int _isPerm = PR_FALSE;
1006  int _isSensitive = PR_TRUE;
1007 
1008  if (_slot) {
1009 
1010  nss->sec_key = PK11_GenerateKeyPair(_slot, _type, nss->ecparams,
1011  &nss->pub_key, _isPerm, _isSensitive, _cx);
1012 #endif
1013 
1014  PK11_FreeSlot(_slot);
1015  }
1016  }
1017 
1018  rc = (nss->sec_key && nss->pub_key);
1019 
1020 exit:
1021 SPEW(!rc, rc, dig);
1022 
1023  return rc;
1024 }
1025 
1026 static int rpmnssErrChk(pgpDig dig, const char * msg, int rc, unsigned expected)
1027 {
1028 #ifdef NOTYET
1029 rpmgc gc = dig->impl;
1030  /* Was the return code the expected result? */
1031  rc = (gcry_err_code(gc->err) != expected);
1032  if (rc)
1033  fail("%s failed: %s\n", msg, gpg_strerror(gc->err));
1034 /* XXX FIXME: rpmnssStrerror */
1035 #else
1036  rc = (rc == 0); /* XXX impedance match 1 -> 0 on success */
1037 #endif
1038  return rc; /* XXX 0 on success */
1039 }
1040 
1041 static int rpmnssAvailableCipher(pgpDig dig, int algo)
1042 {
1043  int rc = 0; /* assume available */
1044  return rc;
1045 }
1046 
1047 static int rpmnssAvailableDigest(pgpDig dig, int algo)
1048 {
1049  int rc = 0; /* assume available */
1050  SECOidTag hashAlgo = getHashAlg(algo);
1051  rc = (hashAlgo == SEC_OID_UNKNOWN); /* XXX C, not boolean, return */
1052  return rc;
1053 }
1054 
1055 static int rpmnssAvailablePubkey(pgpDig dig, int algo)
1056 {
1057  int rc = 0; /* assume available */
1058  SECOidTag encAlgo = getEncAlg(algo);
1059  rc = (encAlgo == SEC_OID_UNKNOWN); /* XXX C, not boolean, return */
1060  return rc;
1061 }
1062 
1063 static int rpmnssVerify(pgpDig dig)
1064 {
1065  int rc = 0; /* assume failure */
1066 pgpDigParams pubp = pgpGetPubkey(dig);
1067 pgpDigParams sigp = pgpGetSignature(dig);
1068 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
1069 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo);
1070 
1071  switch (pubp->pubkey_algo) {
1072  default:
1073  break;
1074  case PGPPUBKEYALGO_RSA:
1075  rc = rpmnssVerifyRSA(dig);
1076  break;
1077  case PGPPUBKEYALGO_DSA:
1078  rc = rpmnssVerifyDSA(dig);
1079  break;
1080  case PGPPUBKEYALGO_ELGAMAL:
1081 #ifdef NOTYET
1082  rc = rpmnssVerifyELG(dig);
1083 #endif
1084  break;
1085  case PGPPUBKEYALGO_ECDSA:
1086  rc = rpmnssVerifyECDSA(dig);
1087  break;
1088  }
1089 SPEW(0, rc, dig);
1090  return rc;
1091 }
1092 
1093 static int rpmnssSign(pgpDig dig)
1094 {
1095  int rc = 0; /* assume failure */
1096 pgpDigParams pubp = pgpGetPubkey(dig);
1097 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
1098 
1099  switch (pubp->pubkey_algo) {
1100  default:
1101  break;
1102  case PGPPUBKEYALGO_RSA:
1103  rc = rpmnssSignRSA(dig);
1104  break;
1105  case PGPPUBKEYALGO_DSA:
1106  rc = rpmnssSignDSA(dig);
1107  break;
1108  case PGPPUBKEYALGO_ELGAMAL:
1109 #ifdef NOTYET
1110  rc = rpmnssSignELG(dig);
1111 #endif
1112  break;
1113  case PGPPUBKEYALGO_ECDSA:
1114  rc = rpmnssSignECDSA(dig);
1115  break;
1116  }
1117 SPEW(!rc, rc, dig);
1118  return rc;
1119 }
1120 
1121 static int rpmnssGenerate(pgpDig dig)
1122 {
1123  int rc = 0; /* assume failure */
1124 pgpDigParams pubp = pgpGetPubkey(dig);
1125 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo);
1126 
1127  switch (pubp->pubkey_algo) {
1128  default:
1129  break;
1130  case PGPPUBKEYALGO_RSA:
1131  rc = rpmnssGenerateRSA(dig);
1132  break;
1133  case PGPPUBKEYALGO_DSA:
1134  rc = rpmnssGenerateDSA(dig);
1135  break;
1136  case PGPPUBKEYALGO_ELGAMAL:
1137 #ifdef NOTYET
1138  rc = rpmnssGenerateELG(dig);
1139 #endif
1140  break;
1141  case PGPPUBKEYALGO_ECDSA:
1142  rc = rpmnssGenerateECDSA(dig);
1143  break;
1144  }
1145 SPEW(!rc, rc, dig);
1146  return rc;
1147 }
1148 
1152 static
1153 int rpmnssMpiSet(const char * pre, unsigned int lbits,
1154  /*@out@*/ void * dest, const rpmuint8_t * p,
1155  /*@null@*/ const rpmuint8_t * pend)
1156  /*@modifies *dest @*/
1157 {
1158  unsigned int mbits = pgpMpiBits(p);
1159  unsigned int nbits;
1160  unsigned int nbytes;
1161  char * t = (char *) dest;
1162  unsigned int ix;
1163 
1164  if (pend != NULL && (p + ((mbits+7) >> 3)) > pend)
1165  return 1;
1166 
1167  if (mbits > lbits)
1168  return 1;
1169 
1170  nbits = (lbits > mbits ? lbits : mbits);
1171  nbytes = ((nbits + 7) >> 3);
1172  ix = ((nbits - mbits) >> 3);
1173 
1174 /*@-modfilesystem @*/
1175 if (_pgp_debug)
1176 fprintf(stderr, "*** mbits %u nbits %u nbytes %u ix %u\n", mbits, nbits, nbytes, ix);
1177  if (ix > 0) memset(t, (int)'\0', ix);
1178  memcpy(t+ix, p+2, nbytes-ix);
1179 if (_pgp_debug && _pgp_print)
1180 fprintf(stderr, "\t %s %s\n", pre, pgpHexStr((rpmuint8_t *)dest, nbytes));
1181 /*@=modfilesystem @*/
1182  return 0;
1183 }
1184 
1188 static
1189 /*@only@*/ /*@null@*/
1190 SECItem * rpmnssMpiCopy(PRArenaPool * arena, /*@returned@*/ SECItem * item,
1191  const rpmuint8_t * p)
1192  /*@modifies item @*/
1193 {
1194  unsigned int nbytes = pgpMpiLen(p)-2;
1195 
1196 /*@-moduncon@*/
1197  if (item == NULL) {
1198  if ((item = SECITEM_AllocItem(arena, item, nbytes)) == NULL)
1199  return item;
1200  } else {
1201  if (arena != NULL)
1202  item->data = (unsigned char *) PORT_ArenaGrow(arena, item->data, item->len, nbytes);
1203  else
1204  item->data = (unsigned char *) PORT_Realloc(item->data, nbytes);
1205 
1206  if (item->data == NULL) {
1207  if (arena == NULL)
1208  SECITEM_FreeItem(item, PR_TRUE);
1209  return NULL;
1210  }
1211  }
1212 /*@=moduncon@*/
1213 
1214  memcpy(item->data, p+2, nbytes);
1215  item->len = nbytes;
1216 /*@-temptrans@*/
1217  return item;
1218 /*@=temptrans@*/
1219 }
1220 
1221 static /*@null@*/
1222 SECKEYPublicKey * rpmnssNewPublicKey(KeyType type)
1223  /*@*/
1224 {
1225  PRArenaPool *arena;
1226  SECKEYPublicKey *key;
1227 
1228 /*@-moduncon@*/
1229  arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1230  if (arena == NULL)
1231  return NULL;
1232 
1233  key = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena, sizeof(*key));
1234 
1235  if (key == NULL) {
1236  PORT_FreeArena(arena, PR_FALSE);
1237  return NULL;
1238  }
1239 /*@=moduncon@*/
1240 
1241  key->keyType = type;
1242  key->pkcs11ID = CK_INVALID_HANDLE;
1243  key->pkcs11Slot = NULL;
1244  key->arena = arena;
1245 /*@-nullret@*/ /* key->pkcs11Slot can be NULL */
1246  return key;
1247 /*@=nullret@*/
1248 }
1249 
1250 static
1251 int rpmnssMpiItem(const char * pre, pgpDig dig, int itemno,
1252  const rpmuint8_t * p, /*@null@*/ const rpmuint8_t * pend)
1253  /*@*/
1254 {
1255  rpmnss nss = (rpmnss) dig->impl;
1256  unsigned int hbits;
1257  size_t nb = (pend >= p ? (pend - p) : 0);
1258  int rc = 0;
1259 
1260 /*@-moduncon@*/
1261  switch (itemno) {
1262  default:
1263 assert(0);
1264  break;
1265  case 10: /* RSA m**d */
1266  nss->sig = rpmnssMpiCopy(NULL, nss->sig, p);
1267  if (nss->sig == NULL)
1268  rc = 1;
1269  break;
1270  case 20: /* DSA r */
1271  hbits = 160;
1272  nss->item.type = (SECItemType) 0;
1273  nss->item.len = 2 * (hbits/8);
1274  nss->item.data = (unsigned char *) xcalloc(1, nss->item.len);
1275  rc = rpmnssMpiSet(pre, hbits, nss->item.data, p, pend);
1276  break;
1277  case 21: /* DSA s */
1278  hbits = 160;
1279  rc = rpmnssMpiSet(pre, hbits, nss->item.data + (hbits/8), p, pend);
1280  if (nss->sig != NULL)
1281  SECITEM_FreeItem(nss->sig, PR_FALSE);
1282  if ((nss->sig = SECITEM_AllocItem(NULL, NULL, 0)) == NULL
1283  || DSAU_EncodeDerSig(nss->sig, &nss->item) != SECSuccess)
1284  rc = 1;
1285  nss->item.data = _free(nss->item.data);
1286  break;
1287  case 30: /* RSA n */
1288  if (nss->pub_key == NULL)
1289  nss->pub_key = rpmnssNewPublicKey(rsaKey);
1290  if (nss->pub_key == NULL)
1291  rc = 1;
1292  else
1293  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.rsa.modulus, p);
1294  break;
1295  case 31: /* RSA e */
1296  if (nss->pub_key == NULL)
1297  nss->pub_key = rpmnssNewPublicKey(rsaKey);
1298  if (nss->pub_key == NULL)
1299  rc = 1;
1300  else
1301  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.rsa.publicExponent, p);
1302  break;
1303  case 40: /* DSA p */
1304  if (nss->pub_key == NULL)
1305  nss->pub_key = rpmnssNewPublicKey(dsaKey);
1306  if (nss->pub_key == NULL)
1307  rc = 1;
1308  else
1309  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.prime, p);
1310  break;
1311  case 41: /* DSA q */
1312  if (nss->pub_key == NULL)
1313  nss->pub_key = rpmnssNewPublicKey(dsaKey);
1314  if (nss->pub_key == NULL)
1315  rc = 1;
1316  else
1317  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.subPrime, p);
1318  break;
1319  case 42: /* DSA g */
1320  if (nss->pub_key == NULL)
1321  nss->pub_key = rpmnssNewPublicKey(dsaKey);
1322  if (nss->pub_key == NULL)
1323  rc = 1;
1324  else
1325  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.base, p);
1326  break;
1327  case 43: /* DSA y */
1328  if (nss->pub_key == NULL)
1329  nss->pub_key = rpmnssNewPublicKey(dsaKey);
1330  if (nss->pub_key == NULL)
1331  rc = 1;
1332  else
1333  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.publicValue, p);
1334  break;
1335  case 50: /* ECDSA r */
1336  hbits = 256;
1337  nss->item.type = (SECItemType) 0;
1338  nss->item.len = 2 * (hbits/8);
1339  nss->item.data = (unsigned char *) xcalloc(1, nss->item.len);
1340  rc = rpmnssMpiSet(pre, hbits, nss->item.data, p, pend);
1341  break;
1342  case 51: /* ECDSA s */
1343  hbits = 256;
1344  rc = rpmnssMpiSet(pre, hbits, nss->item.data + (hbits/8), p, pend);
1345  if (nss->sig != NULL)
1346  SECITEM_FreeItem(nss->sig, PR_FALSE);
1347  if ((nss->sig = SECITEM_AllocItem(NULL, NULL, 0)) == NULL
1348  || DSAU_EncodeDerSigWithLen(nss->sig, &nss->item, nss->item.len) != SECSuccess)
1349  rc = 1;
1350  nss->item.data = _free(nss->item.data);
1351  break;
1352  case 60: /* ECDSA curve OID */
1353 assert(pend > p);
1354  if (nss->pub_key == NULL)
1355  nss->pub_key = rpmnssNewPublicKey(ecKey);
1356  if (nss->pub_key == NULL)
1357  rc = 1;
1358  else {
1359  SECKEYECParams * ecp = &nss->pub_key->u.ec.DEREncodedParams;
1360  ecp->data = (unsigned char *) PORT_ArenaZAlloc(nss->pub_key->arena, nb + 2);
1361  ecp->data[0] = SEC_ASN1_OBJECT_ID;
1362  ecp->data[1] = nb;
1363  memcpy(ecp->data + 2, p, nb);
1364  ecp->len = nb + 2;
1365  }
1366  break;
1367  case 61: /* ECDSA Q */
1368 assert(nss->pub_key);
1369  /* XXX assumes uncompressed Q as a MPI */
1370  nss->pub_key->u.ec.size = ((nb - (2 + 1)) * 8)/2;
1371  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.ec.publicValue, p);
1372  break;
1373  }
1374 /*@=moduncon@*/
1375  return rc;
1376 }
1377 
1378 /*@-mustmod@*/
1379 static
1380 void rpmnssClean(void * impl)
1381  /*@modifies impl @*/
1382 {
1383  rpmnss nss = (rpmnss) impl;
1384 /*@-moduncon@*/
1385  if (nss != NULL) {
1386  nss->nbits = 0;
1387  nss->qbits = 0;
1388  nss->badok = 0;
1389  nss->err = 0;
1390 
1391  nss->digest = _free(nss->digest);
1392  nss->digestlen = 0;
1393 
1394  if (nss->sec_key != NULL) {
1395  SECKEY_DestroyPrivateKey(nss->sec_key);
1396  nss->sec_key = NULL;
1397  }
1398  if (nss->pub_key != NULL) {
1399  SECKEY_DestroyPublicKey(nss->pub_key);
1400  nss->pub_key = NULL;
1401  }
1402  if (nss->sig != NULL) {
1403  SECITEM_ZfreeItem(nss->sig, PR_TRUE);
1404  nss->sig = NULL;
1405  }
1406 
1407  nss->encAlg = SEC_OID_UNKNOWN;
1408  nss->hashAlg = SEC_OID_UNKNOWN;
1409 
1410  nss->item.type = siBuffer;
1411  nss->item.data = (unsigned char *) NULL;
1412  nss->item.len = (unsigned) 0;
1413 
1414  if (nss->ecparams != NULL) {
1415  SECITEM_FreeItem(nss->ecparams, PR_FALSE);
1416  nss->ecparams = NULL;
1417  }
1418  nss->curveN = _free(nss->curveN);
1419  nss->curveOid = SEC_OID_UNKNOWN;
1420 /*@=moduncon@*/
1421  }
1422 }
1423 /*@=mustmod@*/
1424 
1425 static /*@null@*/
1426 void * rpmnssFree(/*@only@*/ void * impl)
1427  /*@*/
1428 {
1429  rpmnssClean(impl);
1430  impl = _free(impl);
1431  return NULL;
1432 }
1433 
1434 static
1435 void * rpmnssInit(void)
1436  /*@globals _rpmnss_init @*/
1437  /*@modifies _rpmnss_init @*/
1438 {
1439  rpmnss nss = (rpmnss) xcalloc(1, sizeof(*nss));
1440  const char * _nssdb_path = rpmExpand("%{?_nssdb_path}", NULL);
1441 
1442 /*@-moduncon@*/
1443  if (_nssdb_path != NULL && *_nssdb_path == '/')
1444  (void) NSS_Init(_nssdb_path);
1445  else
1446  (void) NSS_NoDB_Init(NULL);
1447 /*@=moduncon@*/
1448  _nssdb_path = _free(_nssdb_path);
1449 
1450  _rpmnss_init = 1;
1451 
1452  return (void *) nss;
1453 }
1454 
1455 struct pgpImplVecs_s rpmnssImplVecs = {
1456  rpmnssSetRSA,
1457  rpmnssSetDSA,
1458  rpmnssSetELG,
1459  rpmnssSetECDSA,
1460 
1461  rpmnssErrChk,
1462  rpmnssAvailableCipher, rpmnssAvailableDigest, rpmnssAvailablePubkey,
1463  rpmnssVerify, rpmnssSign, rpmnssGenerate,
1464 
1465  rpmnssMpiItem, rpmnssClean,
1466  rpmnssFree, rpmnssInit
1467 };
1468 
1469 #endif /* WITH_NSS */
1470 
static unsigned int pgpMpiBits(const rpmuint8_t *p)
Return no.
Definition: rpmpgp.h:1114
int xx
Definition: spec.c:744
DIGEST_CTX ctx
Definition: signature.c:785
static const char * _pgpHashAlgo2Name(uint32_t algo)
Definition: rpmbc.c:31
pgpImplVecs_t rpmnssImplVecs
struct rpmgc_s * rpmgc
Definition: rpmgc.h:22
static PyObject *int type
Definition: rpmmi-py.c:151
char * xstrdup(const char *str)
Definition: rpmmalloc.c:321
static char *size_t nb
fgets(3) analogue that reads \ continuations.
Definition: macro.c:409
int rc
Definition: poptALL.c:670
struct rpmnss_s * rpmnss
Definition: rpmnss.h:27
struct pgpDig_s * pgpDig
Definition: rpmiotypes.h:86
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Definition: rpmiotypes.h:26
const char * N
Definition: rpmds.c:2714
goto exit
Definition: db3.c:1903
memset(_r, 0, sizeof(*_r))
void * xcalloc(size_t nmemb, size_t size)
Definition: rpmmalloc.c:300
assert(key->size==sizeof(hdrNum))
struct pgpValTbl_s pgpHashTbl[]
Hash (string, value) pairs.
Definition: rpmpgp.c:143
int ix
Definition: rpmps-py.c:174
char * p
Definition: macro.c:413
static char * pgpHexStr(const rpmuint8_t *p, size_t plen)
Return hex formatted representation of bytes.
Definition: rpmpgp.h:1164
fprintf(stderr,"--> %s(%p,%p,%p) sig %p sigp %p\n", __FUNCTION__, dig, t, rsactx, sig, sigp)
pgpDigParams pgpGetSignature(pgpDig dig)
Return OpenPGP signature parameters.
Definition: rpmpgp.c:1226
Digest private data.
Definition: digest.c:127
key
Definition: macro.c:383
pgpHashAlgo rpmDigestAlgo(DIGEST_CTX ctx)
Return digest algorithm identifier.
Definition: digest.c:188
#define _ENTRY(_v)
Definition: db3.c:236
char * rpmExpand(const char *arg,...)
Return (malloc&#39;ed) concatenated macro expansion(s).
Definition: macro.c:3178
static unsigned
Definition: rpmmtree.c:386
fts keys
Definition: rpmmtree.c:3666
return strcmp(ame->name, bme->name)
char * t
Definition: rpmds.c:2716
static int snprintf(char *buf, int nb, const char *fmt,...)
Definition: rpmps.c:220
static unsigned int pgpMpiLen(const rpmuint8_t *p)
Return no.
Definition: rpmpgp.h:1127
if(__progname==NULL)
Definition: poptALL.c:683
const char * msg
Definition: rpmts-py.c:976
#define SPEW(_t, _rc, _dig)
Definition: rpmbc.c:25
struct pgpDigParams_s * pgpDigParams
Definition: rpmiotypes.h:90
return NULL
Definition: poptALL.c:613
static const char * pgpValStr(pgpValTbl vs, rpmuint8_t val)
Return string representation of am OpenPGP value.
Definition: rpmpgp.h:1199
static void
Print copy of spec file, filling in Group/Description/Summary from specspo.
Definition: spec.c:737
k
Definition: rpmmtree.c:394
static const char * name
char * buf
Parse (and execute) macro undefinition.
Definition: macro.c:703
char * b
Definition: macro.c:746
void rpmDigestFinal(rpmDigestDup(md5ctx),&md5sum,&md5len, 0)
int _pgp_print
Definition: rpmpgp.c:32
static const char * _pgpPubkeyAlgo2Name(uint32_t algo)
Definition: rpmbc.c:36
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
pgpDigParams sigp
Definition: signature.c:748
pgpDig dig
Definition: rpmts-py.c:979
int _pgp_debug
Definition: rpmpgp.c:29
pgpDigParams pgpGetPubkey(pgpDig dig)
Return OpenPGP pubkey parameters.
Definition: rpmpgp.c:1231
struct pgpValTbl_s pgpPubkeyTbl[]
Definition: rpmpgp.c:103