rpm  5.4.15
rpmnss.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_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 extern void * _rpmnss_context;
36 
37 /*@unchecked@*/
38 static int _rpmnss_debug;
39 
40 #define SPEW(_t, _rc, _dig) \
41  { if ((_t) || _rpmnss_debug || _pgp_debug < 0) \
42  fprintf(stderr, "<-- %s(%p) %s\t%s/%s\n", __FUNCTION__, (_dig), \
43  ((_rc) ? "OK" : "BAD"), (_dig)->pubkey_algoN, (_dig)->hash_algoN); \
44  }
45 
46 /* XXX gcc has __builtin_clz */
47 # if !defined __GNUC__ || __GNUC__ < 3
48 static int __builtin_clz(uint32_t x)
49 {
50  int n = 0;
51 
52  if (x == 0)
53  return 32;
54  if ((x & 0xffff0000) == 0) { n += 16; x << 16; }
55  if ((x & 0xff000000) == 0) { n += 8; x << 8; }
56  if ((x & 0xf0000000) == 0) { n += 4; x << 4; }
57  if ((x & 0xc0000000) == 0) { n += 2; x << 2; }
58  if ((x & 0x80000000) == 0) { n += 1; x << 1; }
59  return n;
60 }
61 #endif
62 
63 /*==============================================================*/
64 
65 typedef struct keyNV_s {
66 /*@observer@*/
67  const char * N; /* key name */
68  uint32_t V;
69 } keyNV_t;
70 
71 static int
72 keyNVCmp(const void * a, const void * b)
73 {
74  return strcmp(((keyNV_t *)a)->N, ((keyNV_t *)b)->N);
75 }
76 
77 static uint32_t
78 keyNV(keyNV_t * keys, size_t nkeys, /*@null@*/ const char *N)
79 {
80  uint32_t V = 0;
81 
82  if (N && *N) {
83  keyNV_t needle = { .N = N, .V = 0 };
84  keyNV_t *k = (keyNV_t *)
85  bsearch(&needle, keys, nkeys, sizeof(*keys), keyNVCmp);
86  if (k)
87  V = k->V;
88  }
89  return V;
90 }
91 
92 typedef struct keyVN_s {
93  int V;
94 /*@observer@*/
95  const char * N; /* key name */
96 } keyVN_t;
97 
98 static int
99 keyVNCmp(const void * a, const void * b)
100 {
101  return (((keyVN_t *)a)->V - ((keyVN_t *)b)->V);
102 }
103 
104 static const char *
105 keyVN(keyVN_t * keys, size_t nkeys, /*@null@*/ int V)
106 {
107  const char * N = NULL;
108 
109  if (V) {
110  /* XXX bsearch is overkill */
111  keyVN_t needle = {};
112  keyVN_t *k;
113 
114  needle.V = V;
115  needle.N = NULL;
116  k = (keyVN_t *)
117  bsearch(&needle, keys, nkeys, sizeof(*keys), keyVNCmp);
118  if (k)
119  N = k->N;
120  }
121  return N;
122 }
123 
124 /*==============================================================*/
125 
126 extern SECStatus
127 EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams);
128 
129 static keyNV_t rpmnssOIDS[] = {
130  { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
131  { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
132  { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
133  { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
134  { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
135  { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
136  { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
137  { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
138  { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
139  { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
140  { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
141  { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
142  { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
143  { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
144  { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
145  { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
146  { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
147  { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
148  { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
149  { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
150  { "nistb163", SEC_OID_SECG_EC_SECT163R2},
151  { "nistb233", SEC_OID_SECG_EC_SECT233R1},
152  { "nistb283", SEC_OID_SECG_EC_SECT283R1},
153  { "nistb409", SEC_OID_SECG_EC_SECT409R1},
154  { "nistb571", SEC_OID_SECG_EC_SECT571R1},
155  { "nistk163", SEC_OID_SECG_EC_SECT163K1},
156  { "nistk233", SEC_OID_SECG_EC_SECT233K1},
157  { "nistk283", SEC_OID_SECG_EC_SECT283K1},
158  { "nistk409", SEC_OID_SECG_EC_SECT409K1},
159  { "nistk571", SEC_OID_SECG_EC_SECT571K1},
160  { "nistp192", SEC_OID_SECG_EC_SECP192R1},
161  { "nistp224", SEC_OID_SECG_EC_SECP224R1},
162  { "nistp256", SEC_OID_SECG_EC_SECP256R1},
163  { "nistp384", SEC_OID_SECG_EC_SECP384R1},
164  { "nistp521", SEC_OID_SECG_EC_SECP521R1},
165  { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
166  { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
167  { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
168  { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
169  { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
170  { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
171  { "secp112r1", SEC_OID_SECG_EC_SECP112R1},
172  { "secp112r2", SEC_OID_SECG_EC_SECP112R2},
173  { "secp128r1", SEC_OID_SECG_EC_SECP128R1},
174  { "secp128r2", SEC_OID_SECG_EC_SECP128R2},
175  { "secp160k1", SEC_OID_SECG_EC_SECP160K1},
176  { "secp160r1", SEC_OID_SECG_EC_SECP160R1},
177  { "secp160r2", SEC_OID_SECG_EC_SECP160R2},
178  { "secp192k1", SEC_OID_SECG_EC_SECP192K1},
179  { "secp192r1", SEC_OID_SECG_EC_SECP192R1},
180  { "secp224k1", SEC_OID_SECG_EC_SECP224K1},
181  { "secp224r1", SEC_OID_SECG_EC_SECP224R1},
182  { "secp256k1", SEC_OID_SECG_EC_SECP256K1},
183  { "secp256r1", SEC_OID_SECG_EC_SECP256R1},
184  { "secp384r1", SEC_OID_SECG_EC_SECP384R1},
185  { "secp521r1", SEC_OID_SECG_EC_SECP521R1},
186  { "sect113r1", SEC_OID_SECG_EC_SECT113R1},
187  { "sect113r2", SEC_OID_SECG_EC_SECT113R2},
188  { "sect131r1", SEC_OID_SECG_EC_SECT131R1},
189  { "sect131r2", SEC_OID_SECG_EC_SECT131R2},
190  { "sect163k1", SEC_OID_SECG_EC_SECT163K1},
191  { "sect163r1", SEC_OID_SECG_EC_SECT163R1},
192  { "sect163r2", SEC_OID_SECG_EC_SECT163R2},
193  { "sect193r1", SEC_OID_SECG_EC_SECT193R1},
194  { "sect193r2", SEC_OID_SECG_EC_SECT193R2},
195  { "sect233k1", SEC_OID_SECG_EC_SECT233K1},
196  { "sect233r1", SEC_OID_SECG_EC_SECT233R1},
197  { "sect239k1", SEC_OID_SECG_EC_SECT239K1},
198  { "sect283k1", SEC_OID_SECG_EC_SECT283K1},
199  { "sect283r1", SEC_OID_SECG_EC_SECT283R1},
200  { "sect409k1", SEC_OID_SECG_EC_SECT409K1},
201  { "sect409r1", SEC_OID_SECG_EC_SECT409R1},
202  { "sect571k1", SEC_OID_SECG_EC_SECT571K1},
203  { "sect571r1", SEC_OID_SECG_EC_SECT571R1},
204 };
205 static size_t nrpmnssOIDS = sizeof(rpmnssOIDS) / sizeof(rpmnssOIDS[0]);
206 
207 #define _ENTRY(_v) { SEC_ERROR_##_v, #_v }
208 /* XXX sorted table */
209 static keyVN_t rpmnssERRS[] = {
210  _ENTRY(IO),
211  _ENTRY(LIBRARY_FAILURE),
212  _ENTRY(BAD_DATA),
213  _ENTRY(OUTPUT_LEN),
214  _ENTRY(INPUT_LEN),
215  _ENTRY(INVALID_ARGS),
216  _ENTRY(INVALID_ALGORITHM),
217  _ENTRY(INVALID_AVA),
218  _ENTRY(INVALID_TIME),
219  _ENTRY(BAD_DER),
220  _ENTRY(BAD_SIGNATURE),
221  _ENTRY(EXPIRED_CERTIFICATE),
222  _ENTRY(REVOKED_CERTIFICATE),
223  _ENTRY(UNKNOWN_ISSUER),
224  _ENTRY(BAD_KEY),
225  _ENTRY(BAD_PASSWORD),
226  _ENTRY(RETRY_PASSWORD),
227  _ENTRY(NO_NODELOCK),
228  _ENTRY(BAD_DATABASE),
229  _ENTRY(NO_MEMORY),
230  _ENTRY(UNTRUSTED_ISSUER),
231  _ENTRY(UNTRUSTED_CERT),
232  _ENTRY(DUPLICATE_CERT),
233  _ENTRY(DUPLICATE_CERT_NAME),
234  _ENTRY(ADDING_CERT),
235  _ENTRY(FILING_KEY),
236  _ENTRY(NO_KEY),
237  _ENTRY(CERT_VALID),
238  _ENTRY(CERT_NOT_VALID),
239  _ENTRY(CERT_NO_RESPONSE),
240  _ENTRY(EXPIRED_ISSUER_CERTIFICATE),
241  _ENTRY(CRL_EXPIRED),
242  _ENTRY(CRL_BAD_SIGNATURE),
243  _ENTRY(CRL_INVALID),
244  _ENTRY(EXTENSION_VALUE_INVALID),
245  _ENTRY(EXTENSION_NOT_FOUND),
246  _ENTRY(CA_CERT_INVALID),
247  _ENTRY(PATH_LEN_CONSTRAINT_INVALID),
248  _ENTRY(CERT_USAGES_INVALID),
249 /* SEC_INTERNAL_ONLY */
250  _ENTRY(INVALID_KEY),
251  _ENTRY(UNKNOWN_CRITICAL_EXTENSION),
252  _ENTRY(OLD_CRL),
253  _ENTRY(NO_EMAIL_CERT),
254  _ENTRY(NO_RECIPIENT_CERTS_QUERY),
255  _ENTRY(NOT_A_RECIPIENT),
256  _ENTRY(PKCS7_KEYALG_MISMATCH),
257  _ENTRY(PKCS7_BAD_SIGNATURE),
258  _ENTRY(UNSUPPORTED_KEYALG),
259  _ENTRY(DECRYPTION_DISALLOWED),
260 /* Fortezza Alerts */
261 /* XP_SEC_FORTEZZA_BAD_CARD */
262 /* XP_SEC_FORTEZZA_NO_CARD */
263 /* XP_SEC_FORTEZZA_NONE_SELECTED */
264 /* XP_SEC_FORTEZZA_MORE_INFO */
265 /* XP_SEC_FORTEZZA_PERSON_NOT_FOUND */
266 /* XP_SEC_FORTEZZA_NO_MORE_INFO */
267 /* XP_SEC_FORTEZZA_BAD_PIN */
268 /* XP_SEC_FORTEZZA_PERSON_ERROR */
269  _ENTRY(NO_KRL),
270  _ENTRY(KRL_EXPIRED),
271  _ENTRY(KRL_BAD_SIGNATURE),
272  _ENTRY(REVOKED_KEY),
273  _ENTRY(KRL_INVALID),
274  _ENTRY(NEED_RANDOM),
275  _ENTRY(NO_MODULE),
276  _ENTRY(NO_TOKEN),
277  _ENTRY(READ_ONLY),
278  _ENTRY(NO_SLOT_SELECTED),
279  _ENTRY(CERT_NICKNAME_COLLISION),
280  _ENTRY(KEY_NICKNAME_COLLISION),
281  _ENTRY(SAFE_NOT_CREATED),
282  _ENTRY(BAGGAGE_NOT_CREATED),
283 /* XP_JAVA_REMOVE_PRINCIPAL_ERROR */
284 /* XP_JAVA_DELETE_PRIVILEGE_ERROR */
285 /* XP_JAVA_CERT_NOT_EXISTS_ERROR */
286  _ENTRY(BAD_EXPORT_ALGORITHM),
287  _ENTRY(EXPORTING_CERTIFICATES),
288  _ENTRY(IMPORTING_CERTIFICATES),
289  _ENTRY(PKCS12_DECODING_PFX),
290  _ENTRY(PKCS12_INVALID_MAC),
291  _ENTRY(PKCS12_UNSUPPORTED_MAC_ALGORITHM),
292  _ENTRY(PKCS12_UNSUPPORTED_TRANSPORT_MODE),
293  _ENTRY(PKCS12_CORRUPT_PFX_STRUCTURE),
294  _ENTRY(PKCS12_UNSUPPORTED_PBE_ALGORITHM),
295  _ENTRY(PKCS12_UNSUPPORTED_VERSION),
296  _ENTRY(PKCS12_PRIVACY_PASSWORD_INCORRECT),
297  _ENTRY(PKCS12_CERT_COLLISION),
298  _ENTRY(USER_CANCELLED),
299  _ENTRY(PKCS12_DUPLICATE_DATA),
300  _ENTRY(MESSAGE_SEND_ABORTED),
301  _ENTRY(INADEQUATE_KEY_USAGE),
302  _ENTRY(INADEQUATE_CERT_TYPE),
303  _ENTRY(CERT_ADDR_MISMATCH),
304  _ENTRY(PKCS12_UNABLE_TO_IMPORT_KEY),
305  _ENTRY(PKCS12_IMPORTING_CERT_CHAIN),
306  _ENTRY(PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME),
307  _ENTRY(PKCS12_UNABLE_TO_EXPORT_KEY),
308  _ENTRY(PKCS12_UNABLE_TO_WRITE),
309  _ENTRY(PKCS12_UNABLE_TO_READ),
310  _ENTRY(PKCS12_KEY_DATABASE_NOT_INITIALIZED),
311  _ENTRY(KEYGEN_FAIL),
312  _ENTRY(INVALID_PASSWORD),
313  _ENTRY(RETRY_OLD_PASSWORD),
314  _ENTRY(BAD_NICKNAME),
315  _ENTRY(NOT_FORTEZZA_ISSUER),
316  _ENTRY(CANNOT_MOVE_SENSITIVE_KEY),
317  _ENTRY(JS_INVALID_MODULE_NAME),
318  _ENTRY(JS_INVALID_DLL),
319  _ENTRY(JS_ADD_MOD_FAILURE),
320  _ENTRY(JS_DEL_MOD_FAILURE),
321  _ENTRY(OLD_KRL),
322  _ENTRY(CKL_CONFLICT),
323  _ENTRY(CERT_NOT_IN_NAME_SPACE),
324  _ENTRY(KRL_NOT_YET_VALID),
325  _ENTRY(CRL_NOT_YET_VALID),
326  _ENTRY(UNKNOWN_CERT),
327  _ENTRY(UNKNOWN_SIGNER),
328  _ENTRY(CERT_BAD_ACCESS_LOCATION),
329  _ENTRY(OCSP_UNKNOWN_RESPONSE_TYPE),
330  _ENTRY(OCSP_BAD_HTTP_RESPONSE),
331  _ENTRY(OCSP_MALFORMED_REQUEST),
332  _ENTRY(OCSP_SERVER_ERROR),
333  _ENTRY(OCSP_TRY_SERVER_LATER),
334  _ENTRY(OCSP_REQUEST_NEEDS_SIG),
335  _ENTRY(OCSP_UNAUTHORIZED_REQUEST),
336  _ENTRY(OCSP_UNKNOWN_RESPONSE_STATUS),
337  _ENTRY(OCSP_UNKNOWN_CERT),
338  _ENTRY(OCSP_NOT_ENABLED),
339  _ENTRY(OCSP_NO_DEFAULT_RESPONDER),
340  _ENTRY(OCSP_MALFORMED_RESPONSE),
341  _ENTRY(OCSP_UNAUTHORIZED_RESPONSE),
342  _ENTRY(OCSP_FUTURE_RESPONSE),
343  _ENTRY(OCSP_OLD_RESPONSE),
344 /* smime stuff */
345  _ENTRY(DIGEST_NOT_FOUND),
346  _ENTRY(UNSUPPORTED_MESSAGE_TYPE),
347  _ENTRY(MODULE_STUCK),
348  _ENTRY(BAD_TEMPLATE),
349  _ENTRY(CRL_NOT_FOUND),
350  _ENTRY(REUSED_ISSUER_AND_SERIAL),
351  _ENTRY(BUSY),
352  _ENTRY(EXTRA_INPUT),
353 /* error codes used by elliptic curve code */
354  _ENTRY(UNSUPPORTED_ELLIPTIC_CURVE),
355  _ENTRY(UNSUPPORTED_EC_POINT_FORM),
356  _ENTRY(UNRECOGNIZED_OID),
357  _ENTRY(OCSP_INVALID_SIGNING_CERT),
358 /* new revocation errors */
359  _ENTRY(REVOKED_CERTIFICATE_CRL),
360  _ENTRY(REVOKED_CERTIFICATE_OCSP),
361  _ENTRY(CRL_INVALID_VERSION),
362  _ENTRY(CRL_V1_CRITICAL_EXTENSION),
363  _ENTRY(CRL_UNKNOWN_CRITICAL_EXTENSION),
364  _ENTRY(UNKNOWN_OBJECT_TYPE),
365  _ENTRY(INCOMPATIBLE_PKCS11),
366  _ENTRY(NO_EVENT),
367  _ENTRY(CRL_ALREADY_EXISTS),
368  _ENTRY(NOT_INITIALIZED),
369  _ENTRY(TOKEN_NOT_LOGGED_IN),
370  _ENTRY(OCSP_RESPONDER_CERT_INVALID),
371  _ENTRY(OCSP_BAD_SIGNATURE),
372  _ENTRY(OUT_OF_SEARCH_LIMITS),
373  _ENTRY(INVALID_POLICY_MAPPING),
374  _ENTRY(POLICY_VALIDATION_FAILED),
375 /* No longer used. Unknown AIA location types are now silently ignored. */
376  _ENTRY(UNKNOWN_AIA_LOCATION_TYPE),
377  _ENTRY(BAD_HTTP_RESPONSE),
378  _ENTRY(BAD_LDAP_RESPONSE),
379  _ENTRY(FAILED_TO_ENCODE_DATA),
380  _ENTRY(BAD_INFO_ACCESS_LOCATION),
381  _ENTRY(LIBPKIX_INTERNAL),
382  _ENTRY(PKCS11_GENERAL_ERROR),
383  _ENTRY(PKCS11_FUNCTION_FAILED),
384  _ENTRY(PKCS11_DEVICE_ERROR),
385 #if defined(SEC_ERROR_BAD_INFO_ACCESS_METHOD)
386  _ENTRY(BAD_INFO_ACCESS_METHOD),
387 #endif
388 #if defined(SEC_ERROR_CRL_IMPORT_FAILED)
389  _ENTRY(CRL_IMPORT_FAILED),
390 #endif
391 #if defined(SEC_ERROR_EXPIRED_PASSWORD)
392  _ENTRY(EXPIRED_PASSWORD),
393 #endif
394 #if defined(SEC_ERROR_LOCKED_PASSWORD)
395  _ENTRY(LOCKED_PASSWORD),
396 #endif
397 #if defined(SEC_ERROR_UNKNOWN_PKCS11_ERROR)
398  _ENTRY(UNKNOWN_PKCS11_ERROR),
399 #endif
400 #if defined(SEC_ERROR_BAD_CRL_DP_URL)
401  _ENTRY(BAD_CRL_DP_URL),
402 #endif
403 #if defined(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED)
404  _ENTRY(CERT_SIGNATURE_ALGORITHM_DISABLED),
405 #endif
406 #if defined(SEC_ERROR_LEGACY_DATABASE)
407  _ENTRY(LEGACY_DATABASE),
408 #endif
409 #if defined(SEC_ERROR_APPLICATION_CALLBACK_ERROR)
410  _ENTRY(APPLICATION_CALLBACK_ERROR),
411 #endif
412 };
413 static size_t nrpmnssERRS = sizeof(rpmnssERRS) / sizeof(rpmnssERRS[0]);
414 #undef _ENTRY
415 
416 static uint32_t curve2oid(const char * name)
417 {
418  uint32_t oid = keyNV(rpmnssOIDS, nrpmnssOIDS, name);
419  if (oid == 0)
420  oid = SEC_OID_UNKNOWN;
421 
422 if (_pgp_debug)
423 fprintf(stderr, "<-- %s(%s) oid %u\n", __FUNCTION__, name, oid);
424 
425  return oid;
426 }
427 
428 static const char * rpmnssStrerror(int err)
429 {
430  static char buf[64];
431  const char * errN = keyVN(rpmnssERRS, nrpmnssERRS, err);
432  if (errN == NULL) {
433  snprintf(buf, sizeof(buf), "SEC_ERROR(%d)", err);
434  errN = buf;
435  }
436  return errN;
437 }
438 
439 static
440 int rpmnssErr(rpmnss nss, const char * msg, int rc)
441  /*@*/
442 {
443 #ifdef REFERENCE
444  /* XXX Don't spew on expected failures ... */
445  if (err && gcry_err_code(err) != gc->badok)
446  fprintf (stderr, "rpmgc: %s(0x%0x): %s/%s\n",
447  msg, (unsigned)err, gcry_strsource(err), gcry_strerror(err));
448 #endif
449  if (rc != SECSuccess) {
450  int err = PORT_GetError();
451  fprintf (stderr, "rpmnss: %s rc(%d) err(%d) %s\n",
452  msg, rc, err, rpmnssStrerror(err));
453  }
454  return rc;
455 }
456 
457 /*==============================================================*/
458 static SECOidTag getEncAlg(unsigned pubkey_algo, unsigned hash_algo)
459 {
460  SECOidTag encAlg = SEC_OID_UNKNOWN;
461 
462  switch (pubkey_algo) {
463  case PGPPUBKEYALGO_RSA:
464  switch (hash_algo) {
465  case PGPHASHALGO_MD2:
466  encAlg = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; break;
467 #ifdef DEAD /* XXX not implemented in modern NSS */
468  case PGPHASHALGO_MD4:
469  encAlg = SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION; break;
470 #endif
471  case PGPHASHALGO_MD5:
472  encAlg = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; break;
473  case PGPHASHALGO_SHA1:
474  encAlg = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; break;
475  case PGPHASHALGO_SHA224:
476  encAlg = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION; break;
477  case PGPHASHALGO_SHA256:
478  encAlg = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; break;
479  case PGPHASHALGO_SHA384:
480  encAlg = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; break;
481  case PGPHASHALGO_SHA512:
482  encAlg = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; break;
483  default:
484  encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION; break;
485  }
486  break;
487  case PGPPUBKEYALGO_DSA:
488  switch(hash_algo) {
489  case PGPHASHALGO_SHA1:
490  encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; break;
491  case PGPHASHALGO_SHA224:
492  encAlg = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST; break;
493  case PGPHASHALGO_SHA256:
494  encAlg = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST; break;
495  default:
496  encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE; break;
497  }
498  break;
499  case PGPPUBKEYALGO_ECDSA:
500  switch(hash_algo) {
501  case PGPHASHALGO_SHA1:
502  encAlg = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; break;
503  case PGPHASHALGO_SHA224:
504  encAlg = SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE; break;
505  case PGPHASHALGO_SHA256:
506  encAlg = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; break;
507  case PGPHASHALGO_SHA384:
508  encAlg = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; break;
509  case PGPHASHALGO_SHA512:
510  encAlg = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE; break;
511 #ifdef NOTYET
512  case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
513  case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
514 #endif
515  default:
516  encAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; break;
517  }
518  break;
519  case PGPPUBKEYALGO_ELGAMAL: /*@fallthrough@*/
520  default:
521  break;
522  }
523  return encAlg;
524 }
525 
526 static SECOidTag getHashAlg(unsigned hash_algo)
527 {
528  SECOidTag hashAlg = SEC_OID_UNKNOWN;
529 
530  switch (hash_algo) {
531  case PGPHASHALGO_MD2: hashAlg = SEC_OID_MD2; break;
532 #ifdef DEAD /* XXX not implemented in modern NSS? */
533  case PGPHASHALGO_MD4: hashAlg = SEC_OID_MD4; break;
534 #endif
535  case PGPHASHALGO_MD5: hashAlg = SEC_OID_MD5; break;
536  case PGPHASHALGO_SHA1: hashAlg = SEC_OID_SHA1; break;
537  case PGPHASHALGO_SHA224: hashAlg = SEC_OID_SHA224; break;
538  case PGPHASHALGO_SHA256: hashAlg = SEC_OID_SHA256; break;
539  case PGPHASHALGO_SHA384: hashAlg = SEC_OID_SHA384; break;
540  case PGPHASHALGO_SHA512: hashAlg = SEC_OID_SHA512; break;
541  case PGPHASHALGO_RIPEMD160: /*@fallthrough@*/
542  case PGPHASHALGO_TIGER192: /*@fallthrough@*/
543  case PGPHASHALGO_HAVAL_5_160: /*@fallthrough@*/
544  default:
545  break;
546  }
547  return hashAlg;
548 }
549 
550 /*==============================================================*/
551 
552 static
553 int rpmnssSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
554  /*@modifies dig @*/
555 {
556  rpmnss nss = (rpmnss) dig->impl;
557  int rc = 1; /* assume error */
558  int xx;
559 pgpDigParams pubp = pgpGetPubkey(dig);
560 assert(pubp->pubkey_algo == PGPPUBKEYALGO_RSA);
561 assert(sigp->pubkey_algo == PGPPUBKEYALGO_RSA);
562 dig->pubkey_algoN = pgpPubkeyAlgo2Name(sigp->pubkey_algo);
563 dig->hash_algoN = pgpHashAlgo2Name(sigp->hash_algo);
564 
565 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
566 
567 nss->digest = _free(nss->digest);
568 nss->digestlen = 0;
569  xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0);
570 
571  nss->encAlg = getEncAlg(sigp->pubkey_algo, 0); /* XXX hash_algo? */
572  nss->hashAlg = getHashAlg(sigp->hash_algo);
573  if (nss->hashAlg == SEC_OID_UNKNOWN)
574  goto exit;
575 
576  /* Compare leading 16 bits of digest for quick check. */
577  rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16));
578 
579  /* XXX FIXME: avoid spurious "BAD" error msg while signing. */
580  if (rc && sigp->signhash16[0] == 0 && sigp->signhash16[1] == 0)
581  rc = 0;
582 
583 exit:
584 SPEW(0, !rc, dig); /* XXX don't spew on mismatch. */
585  return rc;
586 }
587 
588 static int rpmnssGenerateRSA(pgpDig dig)
589 {
590  rpmnss nss = (rpmnss) dig->impl;
591  int rc = 0; /* assume failure */
592 
593 if (nss->nbits == 0) nss->nbits = 1024; /* XXX FIXME */
594 assert(nss->nbits);
595 
596  { void * _cx = NULL;
597  CK_MECHANISM_TYPE _type = CKM_RSA_PKCS_KEY_PAIR_GEN;
598  PK11SlotInfo * _slot = PK11_GetBestSlot(_type, _cx);
599  int _isPerm = PR_FALSE;
600  int _isSensitive = PR_TRUE;
601 
602  if (_slot) {
603  static unsigned _pe = 0x10001; /* XXX FIXME: pass in e */
604  PK11RSAGenParams rsaparams = {};
605  void * params = &rsaparams;
606 
607  rsaparams.keySizeInBits = nss->nbits;
608  rsaparams.pe = _pe;
609 
610  nss->sec_key = PK11_GenerateKeyPair(_slot, _type, params,
611  &nss->pub_key, _isPerm, _isSensitive, _cx);
612 
613  PK11_FreeSlot(_slot);
614  }
615  }
616 
617  rc = (nss->sec_key && nss->pub_key); /* XXX gud enuf? */
618 
619 SPEW(!rc, rc, dig);
620  return rc;
621 }
622 
623 static
624 int rpmnssSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
625  /*@modifies dig @*/
626 {
627  rpmnss nss = (rpmnss) dig->impl;
628  int rc = 1; /* assume error */
629  int xx;
630 pgpDigParams pubp = pgpGetPubkey(dig);
631 assert(pubp->pubkey_algo == PGPPUBKEYALGO_DSA);
632 assert(sigp->pubkey_algo == PGPPUBKEYALGO_DSA);
633 dig->pubkey_algoN = pgpPubkeyAlgo2Name(sigp->pubkey_algo);
634 dig->hash_algoN = pgpHashAlgo2Name(sigp->hash_algo);
635 
636 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
637 
638 nss->digest = _free(nss->digest);
639 nss->digestlen = 0;
640  xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0);
641 
642  nss->encAlg = getEncAlg(sigp->pubkey_algo, 0); /* XXX hash_algo? */
643  nss->hashAlg = getHashAlg(sigp->hash_algo);
644  if (nss->hashAlg == SEC_OID_UNKNOWN)
645  goto exit;
646 
647  /* Compare leading 16 bits of digest for quick check. */
648  rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16));
649 
650  /* XXX FIXME: avoid spurious "BAD" error msg while signing. */
651  if (rc && sigp->signhash16[0] == 0 && sigp->signhash16[1] == 0)
652  rc = 0;
653 
654 exit:
655 SPEW(0, !rc, dig); /* XXX don't spew on mismatch. */
656  return rc;
657 }
658 
659 static int rpmnssGenerateDSA(pgpDig dig)
660 {
661  rpmnss nss = (rpmnss) dig->impl;
662  int rc = 0; /* assume failure */
663  pgpDigParams sigp = pgpGetSignature(dig);
664 unsigned _J = 8; /* XXX DSA1 1024 bits */
665 unsigned _L = 0;
666 unsigned _N = 0;
667 unsigned _seedBytes = 0;
668 int _passed = 0;
669 PK11SlotInfo * _slot = NULL;
670 PQGParams *pqgParams = NULL;
671 PQGVerify *pqgVfy = NULL;
672 int xx;
673 
674  /* XXX Set the no. of qbits based on the digest being used. */
675  if (nss->qbits == 0)
676  switch (sigp->hash_algo) {
677  default: /* XXX default */
678  case PGPHASHALGO_SHA1: nss->qbits = 160; break;
679  case PGPHASHALGO_SHA224: nss->qbits = 224; break;
680  case PGPHASHALGO_SHA256: nss->qbits = 256; break;
681  case PGPHASHALGO_SHA384: nss->qbits = 384; break;
682  case PGPHASHALGO_SHA512: nss->qbits = 512; break;
683  }
684 assert(nss->qbits);
685 
686  /* XXX Set the no. of nbits for non-truncated digest in use. */
687  if (nss->nbits == 0)
688  switch (nss->qbits) {
689  default: /* XXX default */
690  case 160: nss->nbits = 1024; break;
691  case 224: nss->nbits = 2048; break;
692 #ifdef PAINFUL
693  case 256: nss->nbits = 3072; break;
694  case 384: nss->nbits = 7680; break;
695  case 512: nss->nbits = 15360; break;
696 #else
697  case 256: nss->nbits = 2048; break;
698  case 384: nss->nbits = 2048; nss->qbits = 256; break;
699  case 512: nss->nbits = 2048; nss->qbits = 256; break;
700 #endif
701  }
702 assert(nss->nbits);
703 
704 /*
705  * Generate PQGParams and PQGVerify structs.
706  * Length of P specified by L.
707  * if L is greater than 1024 then the resulting verify parameters will be
708  * DSA2.
709  * Length of Q specified by N. If zero, The PKCS #11 module will
710  * pick an appropriately sized Q for P. If N is specified and L = 1024, then
711  * the resulting verify parameters will be DSA2, Otherwise DSA1 parameters
712  * will be returned.
713  * Length of SEED in bytes specified in seedBytes.
714  *
715  * The underlying PKCS #11 module will check the values for L, N,
716  * and seedBytes. The rules for softoken are:
717  *
718  * If L <= 1024, then L must be between 512 and 1024 in increments of 64 bits.
719  * If L <= 1024, then N must be 0 or 160.
720  * If L >= 1024, then L and N must match the following table:
721  * L=1024 N=0 or 160
722  * L=2048 N=0 or 224
723  * L=2048 N=256
724  * L=3072 N=0 or 256
725  * if L <= 1024
726  * seedBytes must be in the range [20..256].
727  * if L >= 1024
728  * seedBytes must be in the range [20..L/16].
729  */
730 /* seedBytes == L/8 for probable primes, N/8 for Shawe-Taylor Primes */
731 
732  switch (nss->nbits) {
733  default: /* XXX sanity */
734  case 1024:
735  _L = 1024;
736  _N = 0; /* XXX 160 uses DSA2 */
737  _seedBytes = 0;
738  break;
739  case 2048:
740  _L = 2048;
741  _N = (nss->qbits == 256) ? 256 : 224; /* 256 or 224 */
742  _seedBytes = _N/8;
743  break;
744  case 3072:
745  _L = 3072;
746  _N = 256;
747  _seedBytes = _N/8;
748  break;
749  }
750 
751  { CK_MECHANISM_TYPE _type = CKM_DSA_KEY_PAIR_GEN;
752  void * _cx = NULL;
753  int _isPerm = PR_FALSE;
754  int _isSensitive = PR_TRUE;
755 
756  _slot = PK11_GetBestSlot(_type, _cx);
757  if (_slot) {
758  void * params = NULL;
759 
760  if (_L > 1024 || _N != 0)
761  xx = rpmnssErr(nss, "PK11_PQG_ParamGenV2",
762  PK11_PQG_ParamGenV2(_L, _N, _seedBytes,
763  &pqgParams, &pqgVfy));
764  else if (_seedBytes)
765  xx = rpmnssErr(nss, "PK11_PQG_ParamGenSeedLen",
766  PK11_PQG_ParamGenSeedLen(_J, _seedBytes,
767  &pqgParams, &pqgVfy));
768  else
769  xx = rpmnssErr(nss, "PK11_PQG_ParamGen",
770  PK11_PQG_ParamGen(_J, &pqgParams, &pqgVfy));
771  if (xx != SECSuccess)
772  goto exit;
773 
774  xx = rpmnssErr(nss, "PK11_PQG_VerifyParams",
775  PK11_PQG_VerifyParams(pqgParams, pqgVfy, &_passed));
776  if (xx != SECSuccess || _passed != SECSuccess)
777  goto exit;
778 
779  params = pqgParams;
780  nss->sec_key = PK11_GenerateKeyPair(_slot, _type, params,
781  &nss->pub_key, _isPerm, _isSensitive, _cx);
782 
783  }
784  }
785 
786  rc = (nss->sec_key && nss->pub_key); /* XXX gud enuf? */
787 
788 exit:
789  if (pqgParams) PK11_PQG_DestroyParams(pqgParams);
790  if (pqgVfy) PK11_PQG_DestroyVerify(pqgVfy);
791  if (_slot) PK11_FreeSlot(_slot);
792 
793 SPEW(!rc, rc, dig);
794  return rc;
795 }
796 
797 static
798 int rpmnssSetELG(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
799  /*@*/
800 {
801  rpmnss nss = (rpmnss) dig->impl;
802  int rc = 1; /* assume failure */
803  int xx;
804 pgpDigParams pubp = pgpGetPubkey(dig);
805 assert(pubp->pubkey_algo == PGPPUBKEYALGO_ELGAMAL);
806 assert(sigp->pubkey_algo == PGPPUBKEYALGO_ELGAMAL);
807 dig->pubkey_algoN = pgpPubkeyAlgo2Name(sigp->pubkey_algo);
808 dig->hash_algoN = pgpHashAlgo2Name(sigp->hash_algo);
809 
810 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
811 nss->digest = _free(nss->digest);
812 nss->digestlen = 0;
813  xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0);
814 
815  /* Compare leading 16 bits of digest for quick check. */
816  rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16));
817 
818  /* XXX FIXME: avoid spurious "BAD" error msg while signing. */
819  if (rc && sigp->signhash16[0] == 0 && sigp->signhash16[1] == 0)
820  rc = 0;
821 
822  rc = 1; /* XXX always fail */
823 
824 SPEW(0, !rc, dig); /* XXX don't spew on mismatch. */
825  return rc;
826 }
827 
828 static
829 int rpmnssSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
830  /*@*/
831 {
832  rpmnss nss = (rpmnss) dig->impl;
833  int rc = 1; /* assume failure */
834  int xx;
835 pgpDigParams pubp = pgpGetPubkey(dig);
836 assert(pubp->pubkey_algo == PGPPUBKEYALGO_ECDSA);
837 assert(sigp->pubkey_algo == PGPPUBKEYALGO_ECDSA);
838 dig->pubkey_algoN = pgpPubkeyAlgo2Name(sigp->pubkey_algo);
839 dig->hash_algoN = pgpHashAlgo2Name(sigp->hash_algo);
840 
841 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
842 
843 nss->digest = _free(nss->digest);
844 nss->digestlen = 0;
845  xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0);
846 
847  nss->encAlg = getEncAlg(sigp->pubkey_algo, 0); /* XXX hash_algo? */
848  nss->hashAlg = getHashAlg(sigp->hash_algo);
849  if (nss->hashAlg == SEC_OID_UNKNOWN)
850  goto exit;
851 
852  /* Compare leading 16 bits of digest for quick check. */
853  rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16));
854 
855  /* XXX FIXME: avoid spurious "BAD" error msg while signing. */
856  if (rc && sigp->signhash16[0] == 0 && sigp->signhash16[1] == 0)
857  rc = 0;
858 
859 exit:
860 SPEW(0, !rc, dig); /* XXX don't spew on mismatch. */
861  return rc;
862 }
863 
864 static int rpmnssLoadParams(pgpDig dig)
865 {
866  rpmnss nss = (rpmnss) dig->impl;
867  const char * name;
868  SECOidTag curveOid = SEC_OID_UNKNOWN;
869  SECOidData * oidData = NULL;
870  int rc = 1; /* assume failure. */
871 
872  name = nss->curveN;
873  if (name == NULL)
874  goto exit;
875  nss->curveOid = curveOid = curve2oid(name);
876  if (curveOid == SEC_OID_UNKNOWN)
877  goto exit;
878  oidData = SECOID_FindOIDByTag(curveOid);
879  if (oidData == NULL)
880  goto exit;
881 
882  if (nss->ecparams != NULL) {
883  SECITEM_FreeItem(nss->ecparams, PR_FALSE);
884  nss->ecparams = NULL;
885  }
886  nss->ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
887  nss->ecparams->data[0] = SEC_ASN1_OBJECT_ID;
888  nss->ecparams->data[1] = oidData->oid.len;
889  memcpy(nss->ecparams->data + 2, oidData->oid.data, oidData->oid.len);
890  rc = 0;
891 
892 exit:
893 if (_pgp_debug)
894 fprintf(stderr, "<-- %s(%p,%s) oid %u params %p\n", __FUNCTION__, dig, name, nss->curveOid, nss->ecparams);
895  return rc;
896 }
897 
898 static
899 int rpmnssGenerateECDSA(/*@unused@*/pgpDig dig)
900  /*@*/
901 {
902  rpmnss nss = (rpmnss) dig->impl;
903  int rc = 0; /* assume failure. */
904 
905  /* XXX Set the no. of bits based on the digest being used. */
906  if (nss->nbits == 0) {
907  if (!strcasecmp(dig->hash_algoN, "SHA224"))
908  nss->nbits = 224;
909  else if (!strcasecmp(dig->hash_algoN, "SHA256"))
910  nss->nbits = 256;
911  else if (!strcasecmp(dig->hash_algoN, "SHA384"))
912  nss->nbits = 384;
913  else if (!strcasecmp(dig->hash_algoN, "SHA512"))
914  nss->nbits = 512;
915  else
916  nss->nbits = 256; /* XXX default */
917  }
918 assert(nss->nbits);
919 
920  /* XXX Choose the curve parameters from the no. of digest bits. */
921  if (nss->curveN == NULL) /* XXX FIXME */
922  switch (nss->nbits) { /* XXX only NIST prime curves for now */
923  default: goto exit; /*@notreached@*/ break;
924  case 192: nss->curveN = xstrdup("nistp192"); break;
925  case 224: nss->curveN = xstrdup("nistp224"); break;
926  case 256: nss->curveN = xstrdup("nistp256"); break;
927  case 384: nss->curveN = xstrdup("nistp384"); break;
928  case 512: /* XXX sanity */
929  case 521: nss->curveN = xstrdup("nistp521"); break;
930  }
931 assert(nss->curveN);
932 
933  /* Load the curve parameters. */
934  rc = rpmnssLoadParams(dig);
935 assert(nss->ecparams);
936 
937  { void * _cx = NULL;
938  CK_MECHANISM_TYPE _type = CKM_EC_KEY_PAIR_GEN;
939  PK11SlotInfo * _slot = PK11_GetBestSlot(_type, _cx);
940 #ifdef NOTYET
941 /* Create an EC key pair in any slot able to do so,
942  * This is a "session" (temporary), not "token" (permanent) key.
943  * Because of the high probability that this key will need to be moved to
944  * another token, and the high cost of moving "sensitive" keys, we attempt
945  * to create this key pair without the "sensitive" attribute, but revert to
946  * creating a "sensitive" key if necessary.
947  */
948 
949  PK11AttrFlags _aFlags = (PK11_ATTR_SESSION
950  | PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC);
951  CK_FLAGS _opFlags = CKF_DERIVE;
952  CK_FLAGS _opFlagsMask = CKF_DERIVE | CKF_SIGN;
953 
954  if (_slot) {
955 
956  nss->sec_key = PK11_GenerateKeyPairWithOpFlags(_slot, _type,
957  nss->ecparams,
958  &nss->pub_key, _aFlags, _opFlags, _opFlagsMask, _cx);
959 
960  if (nss->sec_key == NULL) {
961  _aFlags = (PK11_ATTR_SESSION
962  | PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE);
963  nss->sec_key = PK11_GenerateKeyPairWithOpFlags(_slot, _type,
964  nss->ecparams,
965  &nss->pub_key, _aFlags, _opFlags, _opFlagsMask, _cx);
966 
967  }
968 #else
969  int _isPerm = PR_FALSE;
970  int _isSensitive = PR_TRUE;
971 
972  if (_slot) {
973 
974  nss->sec_key = PK11_GenerateKeyPair(_slot, _type, nss->ecparams,
975  &nss->pub_key, _isPerm, _isSensitive, _cx);
976 #endif
977 
978  PK11_FreeSlot(_slot);
979  }
980  }
981 
982  rc = (nss->sec_key && nss->pub_key); /* XXX gud enuf? */
983 
984 exit:
985 SPEW(!rc, rc, dig);
986 
987  return rc;
988 }
989 
990 static int rpmnssErrChk(pgpDig dig, const char * msg, int rc, unsigned expected)
991 {
992 #ifdef NOTYET
993 rpmgc gc = dig->impl;
994  /* Was the return code the expected result? */
995  rc = (gcry_err_code(gc->err) != expected);
996  if (rc)
997  fail("%s failed: %s\n", msg, gpg_strerror(gc->err));
998 /* XXX FIXME: rpmnssStrerror */
999 #else
1000  rc = (rc == 0); /* XXX impedance match 1 -> 0 on success */
1001 #endif
1002  return rc; /* XXX 0 on success */
1003 }
1004 
1005 static int rpmnssAvailableCipher(pgpDig dig, int algo)
1006 {
1007  int rc = 0; /* assume available */
1008  return rc;
1009 }
1010 
1011 static int rpmnssAvailableDigest(pgpDig dig, int algo)
1012 {
1013  int rc = 0; /* assume available */
1014  SECOidTag hashAlgo = getHashAlg(algo);
1015  rc = (hashAlgo == SEC_OID_UNKNOWN); /* XXX C, not boolean, return */
1016  return rc;
1017 }
1018 
1019 static int rpmnssAvailablePubkey(pgpDig dig, int algo)
1020 {
1021  int rc = 0; /* assume available */
1022  SECOidTag encAlgo = getEncAlg(algo, 0); /* XXX no hash_algo */
1023  rc = (encAlgo == SEC_OID_UNKNOWN); /* XXX C, not boolean, return */
1024  return rc;
1025 }
1026 
1027 static int rpmnssVerify(pgpDig dig)
1028 {
1029  rpmnss nss = (rpmnss) dig->impl;
1030  int rc = 0; /* assume failure */
1031 pgpDigParams pubp = pgpGetPubkey(dig);
1032 
1033 assert(nss->encAlg != SEC_OID_UNKNOWN);
1034 assert(nss->hashAlg != SEC_OID_UNKNOWN);
1035 
1036  nss->item.type = siBuffer;
1037  nss->item.data = (unsigned char *) nss->digest;
1038  nss->item.len = (unsigned) nss->digestlen;
1039 
1040  switch (pubp->pubkey_algo) {
1041  default:
1042 assert(0);
1043  break;
1044  case PGPPUBKEYALGO_RSA:
1045  break;
1046  case PGPPUBKEYALGO_DSA:
1047 assert(nss->encAlg == SEC_OID_ANSIX9_DSA_SIGNATURE);
1048  break;
1049  case PGPPUBKEYALGO_ELGAMAL:
1050  goto exit;
1051  break;
1052  case PGPPUBKEYALGO_ECDSA:
1053 assert(nss->encAlg == SEC_OID_ANSIX962_EC_PUBLIC_KEY);
1054  break;
1055  }
1056 
1057  rc = rpmnssErr(nss, "VFY_VerifyDigestDirect",
1058  VFY_VerifyDigestDirect(&nss->item, nss->pub_key,
1059  nss->sig, nss->encAlg, nss->hashAlg, NULL));
1060  rc = (rc == SECSuccess);
1061 
1062 exit:
1063 SPEW(!rc, rc, dig);
1064  return rc;
1065 }
1066 
1067 static int rpmnssSign(pgpDig dig)
1068 {
1069  rpmnss nss = (rpmnss) dig->impl;
1070  pgpDigParams pubp = pgpGetPubkey(dig);
1071  int rc = 0; /* assume failure */
1072 
1073 assert(nss->hashAlg != SEC_OID_UNKNOWN);
1074 
1075  nss->item.type = siBuffer;
1076  nss->item.data = (unsigned char *) nss->digest;
1077  nss->item.len = (unsigned) nss->digestlen;
1078 
1079  if (nss->sig != NULL) {
1080  SECITEM_ZfreeItem(nss->sig, PR_TRUE);
1081  nss->sig = NULL;
1082  }
1083  nss->sig = SECITEM_AllocItem(NULL, NULL, 0);
1084  nss->sig->type = siBuffer;
1085 
1086  switch (pubp->pubkey_algo) {
1087  default:
1088 assert(0);
1089  break;
1090  case PGPPUBKEYALGO_RSA:
1091  rc = rpmnssErr(nss, "SGN_Digest",
1092  SGN_Digest(nss->sec_key, nss->hashAlg, nss->sig, &nss->item));
1093  break;
1094  case PGPPUBKEYALGO_DSA:
1095  case PGPPUBKEYALGO_ECDSA:
1096  { SECItem sig = { siBuffer, NULL, 0 };
1097  rc = rpmnssErr(nss, "SGN_Digest",
1098  SGN_Digest(nss->sec_key, nss->hashAlg, &sig, &nss->item));
1099 
1100 nss->qbits = 8 * (sig.len/2);
1101  if (rc == SECSuccess)
1102  rc = rpmnssErr(nss, "DSAU_EncodeDerSigWithLen",
1103  DSAU_EncodeDerSigWithLen(nss->sig, &sig, sig.len));
1104  sig.data = _free(sig.data);
1105 
1106  } break;
1107  case PGPPUBKEYALGO_ELGAMAL:
1108  goto exit;
1109  break;
1110  }
1111  rc = (rc == SECSuccess);
1112 
1113 exit:
1114 SPEW(!rc, rc, dig);
1115  return rc;
1116 }
1117 
1118 static int rpmnssGenerate(pgpDig dig)
1119 {
1120  rpmnss nss = (rpmnss) dig->impl;
1121  int rc = 0; /* assume failure */
1122 pgpDigParams pubp = pgpGetPubkey(dig);
1123 
1124 if (nss->sec_key != NULL) {
1125  SECKEY_DestroyPrivateKey(nss->sec_key);
1126  nss->sec_key = NULL;
1127 }
1128 if (nss->pub_key != NULL) {
1129  SECKEY_DestroyPublicKey(nss->pub_key);
1130  nss->pub_key = NULL;
1131 }
1132 
1133  switch (pubp->pubkey_algo) {
1134  default:
1135  break;
1136  case PGPPUBKEYALGO_RSA:
1137  rc = rpmnssGenerateRSA(dig);
1138  break;
1139  case PGPPUBKEYALGO_DSA:
1140  rc = rpmnssGenerateDSA(dig);
1141  break;
1142  case PGPPUBKEYALGO_ELGAMAL:
1143 #ifdef NOTYET
1144  rc = rpmnssGenerateELG(dig);
1145 #endif
1146  break;
1147  case PGPPUBKEYALGO_ECDSA:
1148  rc = rpmnssGenerateECDSA(dig);
1149  break;
1150  }
1151 SPEW(!rc, rc, dig);
1152  return rc;
1153 }
1154 
1159 static
1160 int rpmnssMpiSet(const char * pre, unsigned int lbits,
1161  /*@out@*/ void * dest, const rpmuint8_t * p,
1162  /*@null@*/ const rpmuint8_t * pend)
1163  /*@modifies *dest @*/
1164 {
1165  unsigned int mbits = pgpMpiBits(p);
1166  unsigned int nbits;
1167  unsigned int nb;
1168  char * t = (char *) dest;
1169  unsigned int ix;
1170 
1171  if (pend != NULL && (p + ((mbits+7) >> 3)) > pend)
1172  return 1;
1173 
1174  if (mbits > lbits)
1175  return 1;
1176 
1177  nbits = (lbits > mbits ? lbits : mbits);
1178  nb = ((nbits + 7) >> 3);
1179  ix = ((nbits - mbits) >> 3);
1180 
1181 /*@-modfilesystem @*/
1182 if (_pgp_debug)
1183 fprintf(stderr, "*** mbits %u nbits %u nb %u ix %u\n", mbits, nbits, nb, ix);
1184  if (ix > 0) memset(t, (int)'\0', ix);
1185  memcpy(t+ix, p+2, nb-ix);
1186 if (_pgp_debug && _pgp_print)
1187 fprintf(stderr, "\t %s %s\n", pre, pgpHexStr((rpmuint8_t *)dest, nb));
1188 /*@=modfilesystem @*/
1189  return 0;
1190 }
1191 
1195 static
1196 /*@only@*/ /*@null@*/
1197 SECItem * rpmnssMpiCopy(PRArenaPool * arena, /*@returned@*/ SECItem * item,
1198  const rpmuint8_t * p)
1199  /*@modifies item @*/
1200 {
1201  const rpmuint8_t * b = p + 2;
1202  unsigned int nb = pgpMpiLen(p)-2;
1203 
1204 /*@-moduncon@*/
1205  if (item == NULL) {
1206  if ((item = SECITEM_AllocItem(arena, item, nb)) == NULL)
1207  return item;
1208  } else {
1209  if (arena != NULL)
1210  item->data = (unsigned char *) PORT_ArenaGrow(arena, item->data, item->len, nb);
1211  else
1212  item->data = (unsigned char *) PORT_Realloc(item->data, nb);
1213 
1214  if (item->data == NULL) {
1215  if (arena == NULL)
1216  SECITEM_FreeItem(item, PR_TRUE);
1217  return NULL;
1218  }
1219  }
1220 /*@=moduncon@*/
1221 
1222  memcpy(item->data, b, nb);
1223  item->len = nb;
1224 /*@-temptrans@*/
1225  return item;
1226 /*@=temptrans@*/
1227 }
1228 
1229 static /*@null@*/
1230 SECKEYPublicKey * rpmnssNewPublicKey(KeyType type)
1231  /*@*/
1232 {
1233  PRArenaPool *arena;
1234  SECKEYPublicKey *key;
1235 
1236 /*@-moduncon@*/
1237  arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1238  if (arena == NULL)
1239  return NULL;
1240 
1241  key = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena, sizeof(*key));
1242 
1243  if (key == NULL) {
1244  PORT_FreeArena(arena, PR_FALSE);
1245  return NULL;
1246  }
1247 /*@=moduncon@*/
1248 
1249  key->keyType = type;
1250  key->pkcs11ID = CK_INVALID_HANDLE;
1251  key->pkcs11Slot = NULL;
1252  key->arena = arena;
1253 /*@-nullret@*/ /* key->pkcs11Slot can be NULL */
1254  return key;
1255 /*@=nullret@*/
1256 }
1257 
1258 static
1259 int rpmnssMpiItem(const char * pre, pgpDig dig, int itemno,
1260  const rpmuint8_t * p, /*@null@*/ const rpmuint8_t * pend)
1261  /*@*/
1262 {
1263  rpmnss nss = (rpmnss) dig->impl;
1264  unsigned int nb = (pend >= p ? (pend - p) : 0);
1265  unsigned int mbits = (((8 * (nb - 2)) + 0x1f) & ~0x1f);
1266  unsigned int nz;
1267  int rc = 0;
1268 
1269 /*@-moduncon@*/
1270  switch (itemno) {
1271  default:
1272 assert(0);
1273  break;
1274  case 10: /* RSA m**d */
1275  nss->nbits = mbits;
1276 assert(nss->sig == NULL);
1277  nss->sig = SECITEM_AllocItem(NULL, nss->sig, mbits/8);
1278 assert(nss->sig != NULL);
1279  nz = nss->sig->len - (nb - 2);
1280  if (nz) /* XXX resurrect leading zero bytes. */
1281  memset(nss->sig->data, 0, nz);
1282  memcpy(nss->sig->data+nz, p+2, nb-2);
1283  break;
1284  case 20: /* DSA r */
1285  nss->qbits = mbits;
1286  nss->item.type = (SECItemType) 0;
1287  nss->item.len = 2 * (nss->qbits/8);
1288  nss->item.data = (unsigned char *) xcalloc(1, nss->item.len);
1289  rc = rpmnssMpiSet(pre, nss->qbits, nss->item.data, p, pend);
1290  break;
1291  case 21: /* DSA s */
1292 assert(mbits == nss->qbits);
1293  rc = rpmnssMpiSet(pre, nss->qbits, nss->item.data + (nss->qbits/8), p, pend);
1294 assert(nss->sig == NULL);
1295  if ((nss->sig = SECITEM_AllocItem(NULL, NULL, 0)) == NULL
1296  || DSAU_EncodeDerSigWithLen(nss->sig, &nss->item, nss->item.len) != SECSuccess)
1297  rc = 1;
1298  nss->item.data = _free(nss->item.data);
1299  nss->item.len = 0;
1300  break;
1301  case 30: /* RSA n */
1302  nss->nbits = mbits;
1303 assert(nss->pub_key == NULL);
1304  nss->pub_key = rpmnssNewPublicKey(rsaKey);
1305 assert(nss->pub_key != NULL);
1306  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.rsa.modulus, p);
1307  break;
1308  case 31: /* RSA e */
1309 assert(nss->pub_key != NULL);
1310  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.rsa.publicExponent, p);
1311  break;
1312  case 40: /* DSA p */
1313  nss->nbits = mbits;
1314 assert(nss->pub_key == NULL);
1315  nss->pub_key = rpmnssNewPublicKey(dsaKey);
1316 assert(nss->pub_key != NULL);
1317  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.prime, p);
1318  break;
1319  case 41: /* DSA q */
1320  nss->qbits = mbits;
1321 assert(nss->pub_key != NULL);
1322  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.subPrime, p);
1323  break;
1324  case 42: /* DSA g */
1325 assert(mbits == nss->nbits);
1326 assert(nss->pub_key != NULL);
1327  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.base, p);
1328  break;
1329  case 43: /* DSA y */
1330 assert(mbits == nss->nbits);
1331 assert(nss->pub_key != NULL);
1332  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.publicValue, p);
1333  break;
1334  case 50: /* ECDSA r */
1335  nss->qbits = mbits;
1336  nss->item.type = (SECItemType) 0;
1337  nss->item.len = 2 * (nss->qbits/8);
1338  nss->item.data = (unsigned char *) xcalloc(1, nss->item.len);
1339  rc = rpmnssMpiSet(pre, nss->qbits, nss->item.data, p, pend);
1340  break;
1341  case 51: /* ECDSA s */
1342 assert(mbits == nss->qbits);
1343  rc = rpmnssMpiSet(pre, nss->qbits, nss->item.data + (nss->qbits/8), p, pend);
1344 assert(nss->sig == NULL);
1345  nss->sig = SECITEM_AllocItem(NULL, NULL, 0);
1346 assert(nss->sig != NULL);
1347  if (DSAU_EncodeDerSigWithLen(nss->sig, &nss->item, nss->item.len) != SECSuccess)
1348  rc = 1;
1349  nss->item.data = _free(nss->item.data);
1350  nss->item.len = 0;
1351  break;
1352  case 60: /* ECDSA curve OID */
1353 assert(nss->pub_key == NULL);
1354  nss->pub_key = rpmnssNewPublicKey(ecKey);
1355 assert(nss->pub_key != NULL);
1356 
1357  { const char * s = xstrdup(pgpHexStr(p, nb));
1358  char * t = NULL;
1359 
1360  if (!strcasecmp(s, "2a8648ce3d030008"))
1361  t = " c2onb191v4";
1362  else if (!strcasecmp(s, "2a8648ce3d030009"))
1363  t = "c2onb191v5";
1364  else if (!strcasecmp(s, "2a8648ce3d03000e"))
1365  t = "c2onb239v4";
1366  else if (!strcasecmp(s, "2a8648ce3d03000f"))
1367  t = "c2onb239v5";
1368  else if (!strcasecmp(s, "2a8648ce3d030001"))
1369  t = "c2pnb163v1";
1370  else if (!strcasecmp(s, "2a8648ce3d030002"))
1371  t = "c2pnb163v2";
1372  else if (!strcasecmp(s, "2a8648ce3d030003"))
1373  t = "c2pnb163v3";
1374  else if (!strcasecmp(s, "2a8648ce3d030004"))
1375  t = "c2pnb176v1";
1376  else if (!strcasecmp(s, "2a8648ce3d03000a"))
1377  t = "c2pnb208w1";
1378  else if (!strcasecmp(s, "2a8648ce3d030010"))
1379  t = "c2pnb272w1";
1380  else if (!strcasecmp(s, "2a8648ce3d030011"))
1381  t = "c2pnb304w1";
1382  else if (!strcasecmp(s, "2a8648ce3d030013"))
1383  t = "c2pnb368w1";
1384  else if (!strcasecmp(s, "2a8648ce3d030005"))
1385  t = "c2tnb191v1";
1386  else if (!strcasecmp(s, "2a8648ce3d030006"))
1387  t = "c2tnb191v2";
1388  else if (!strcasecmp(s, "2a8648ce3d030007"))
1389  t = "c2tnb191v3";
1390  else if (!strcasecmp(s, "2a8648ce3d03000b"))
1391  t = "c2tnb239v1";
1392  else if (!strcasecmp(s, "2a8648ce3d03000c"))
1393  t = "c2tnb239v2";
1394  else if (!strcasecmp(s, "2a8648ce3d03000d"))
1395  t = "c2tnb239v3";
1396  else if (!strcasecmp(s, "2a8648ce3d030012"))
1397  t = "c2tnb359v1";
1398  else if (!strcasecmp(s, "2a8648ce3d030014"))
1399  t = "c2tnb431r1";
1400  else if (!strcasecmp(s, "2b8104000f"))
1401  t = "nistb163";
1402  else if (!strcasecmp(s, "2b8104001b"))
1403  t = "nistb233";
1404  else if (!strcasecmp(s, "2b81040011"))
1405  t = "nistb283";
1406  else if (!strcasecmp(s, "2b81040025"))
1407  t = "nistb409";
1408  else if (!strcasecmp(s, "2b81040027"))
1409  t = "nistb571";
1410  else if (!strcasecmp(s, "2b81040001"))
1411  t = "nistk163";
1412  else if (!strcasecmp(s, "2b8104001a"))
1413  t = "nistk233";
1414  else if (!strcasecmp(s, "2b81040010"))
1415  t = "nistk283";
1416  else if (!strcasecmp(s, "2b81040024"))
1417  t = "nistk409";
1418  else if (!strcasecmp(s, "2b81040026"))
1419  t = "nistk571";
1420  else if (!strcasecmp(s, "2a8648ce3d030101"))
1421  t = "nistp192";
1422  else if (!strcasecmp(s, "2b81040021"))
1423  t = "nistp224";
1424  else if (!strcasecmp(s, "2a8648ce3d030107"))
1425  t = "nistp256";
1426  else if (!strcasecmp(s, "2b81040022"))
1427  t = "nistp384";
1428  else if (!strcasecmp(s, "2b81040023"))
1429  t = "nistp521";
1430  else if (!strcasecmp(s, "2a8648ce3d030101"))
1431  t = "prime192v1";
1432  else if (!strcasecmp(s, "2a8648ce3d030102"))
1433  t = "prime192v2";
1434  else if (!strcasecmp(s, "2a8648ce3d030103"))
1435  t = "prime192v3";
1436  else if (!strcasecmp(s, "2a8648ce3d030104"))
1437  t = "prime239v1";
1438  else if (!strcasecmp(s, "2a8648ce3d030105"))
1439  t = "prime239v2";
1440  else if (!strcasecmp(s, "2a8648ce3d030106"))
1441  t = "prime239v3";
1442  else if (!strcasecmp(s, "2b81040006"))
1443  t = "secp112r1";
1444  else if (!strcasecmp(s, "2b81040007"))
1445  t = "secp112r2";
1446  else if (!strcasecmp(s, "2b8104001c"))
1447  t = "secp128r1";
1448  else if (!strcasecmp(s, "2b8104001d"))
1449  t = "secp128r2";
1450  else if (!strcasecmp(s, "2b81040009"))
1451  t = "secp160k1";
1452  else if (!strcasecmp(s, "2b81040008"))
1453  t = "secp160r1";
1454  else if (!strcasecmp(s, "2b8104001e"))
1455  t = "secp160r2";
1456  else if (!strcasecmp(s, "2b8104001f"))
1457  t = "secp192k1";
1458  else if (!strcasecmp(s, "2a8648ce3d030101"))
1459  t = "secp192r1";
1460  else if (!strcasecmp(s, "2b81040020"))
1461  t = "secp224k1";
1462  else if (!strcasecmp(s, "2b81040021"))
1463  t = "secp224r1";
1464  else if (!strcasecmp(s, "2b8104000a"))
1465  t = "secp256k1";
1466  else if (!strcasecmp(s, "2a8648ce3d030107"))
1467  t = "secp256r1";
1468  else if (!strcasecmp(s, "2b81040022"))
1469  t = "secp384r1";
1470  else if (!strcasecmp(s, "2b81040023"))
1471  t = "secp521r1";
1472  else if (!strcasecmp(s, "2b81040004"))
1473  t = "sect113r1";
1474  else if (!strcasecmp(s, "2b81040005"))
1475  t = "sect113r2";
1476  else if (!strcasecmp(s, "2b81040016"))
1477  t = "sect131r1";
1478  else if (!strcasecmp(s, "2b81040017"))
1479  t = "sect131r2";
1480  else if (!strcasecmp(s, "2b81040001"))
1481  t = "sect163k1";
1482  else if (!strcasecmp(s, "2b81040002"))
1483  t = "sect163r1";
1484  else if (!strcasecmp(s, "2b8104000f"))
1485  t = "sect163r2";
1486  else if (!strcasecmp(s, "2b81040018"))
1487  t = "sect193r1";
1488  else if (!strcasecmp(s, "2b81040019"))
1489  t = "sect193r2";
1490  else if (!strcasecmp(s, "2b8104001a"))
1491  t = "sect233k1";
1492  else if (!strcasecmp(s, "2b8104001b"))
1493  t = "sect233r1";
1494  else if (!strcasecmp(s, "2b81040003"))
1495  t = "sect239k1";
1496  else if (!strcasecmp(s, "2b81040010"))
1497  t = "sect283k1";
1498  else if (!strcasecmp(s, "2b81040011"))
1499  t = "sect283r1";
1500  else if (!strcasecmp(s, "2b81040024"))
1501  t = "sect409k1";
1502  else if (!strcasecmp(s, "2b81040025"))
1503  t = "sect409r1";
1504  else if (!strcasecmp(s, "2b81040026"))
1505  t = "sect571k1";
1506  else if (!strcasecmp(s, "2b81040027"))
1507  t = "sect571r1";
1508  else
1509 assert(0);
1510  nss->curveN = xstrdup(t);
1511  s = _free(s);
1512  }
1513 
1514  { SECKEYECParams * ecp = &nss->pub_key->u.ec.DEREncodedParams;
1515  ecp->data = (unsigned char *) PORT_ArenaZAlloc(nss->pub_key->arena, nb + 2);
1516  ecp->data[0] = SEC_ASN1_OBJECT_ID;
1517  ecp->data[1] = nb;
1518  memcpy(ecp->data + 2, p, nb);
1519  ecp->len = nb + 2;
1520  }
1521  break;
1522  case 61: /* ECDSA Q */
1523 assert(nss->pub_key != NULL);
1524  (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.ec.publicValue, p);
1525  nss->pub_key->u.ec.size = mbits;
1526  break;
1527  }
1528 /*@=moduncon@*/
1529  return rc;
1530 }
1531 
1532 /*@-mustmod@*/
1533 static
1534 void rpmnssClean(void * impl)
1535  /*@modifies impl @*/
1536 {
1537  rpmnss nss = (rpmnss) impl;
1538 /*@-moduncon@*/
1539  if (nss != NULL) {
1540  nss->in_fips_mode = 0;
1541  nss->nbits = 0;
1542  nss->qbits = 0;
1543  nss->badok = 0;
1544  nss->err = 0;
1545 
1546  nss->digest = _free(nss->digest);
1547  nss->digestlen = 0;
1548 
1549  if (nss->sec_key != NULL) {
1550  SECKEY_DestroyPrivateKey(nss->sec_key);
1551  nss->sec_key = NULL;
1552  }
1553  if (nss->pub_key != NULL) {
1554  SECKEY_DestroyPublicKey(nss->pub_key);
1555  nss->pub_key = NULL;
1556  }
1557  if (nss->sig != NULL) {
1558  SECITEM_ZfreeItem(nss->sig, PR_TRUE);
1559  nss->sig = NULL;
1560  }
1561 
1562  nss->encAlg = SEC_OID_UNKNOWN;
1563  nss->hashAlg = SEC_OID_UNKNOWN;
1564 
1565  nss->item.type = siBuffer;
1566  nss->item.data = (unsigned char *) NULL;
1567  nss->item.len = (unsigned) 0;
1568 
1569  if (nss->ecparams != NULL) {
1570  SECITEM_FreeItem(nss->ecparams, PR_FALSE);
1571  nss->ecparams = NULL;
1572  }
1573  nss->curveN = _free(nss->curveN);
1574  nss->curveOid = SEC_OID_UNKNOWN;
1575 /*@=moduncon@*/
1576  }
1577 }
1578 /*@=mustmod@*/
1579 
1580 static /*@null@*/
1581 void * rpmnssFree(/*@only@*/ void * impl)
1582  /*@*/
1583 {
1584  rpmnssClean(impl);
1585  impl = _free(impl);
1586  return NULL;
1587 }
1588 
1589 static
1590 void * rpmnssInit(void)
1591  /*@globals _rpmnss_init @*/
1592  /*@modifies _rpmnss_init @*/
1593 {
1594  rpmnss nss = (rpmnss) xcalloc(1, sizeof(*nss));
1595 
1596 #ifdef HAVE_NSS_INITCONTEXT
1597  if (_rpmnss_context == NULL) {
1598  const char * _configdir = rpmExpand("%{?_nssdb_path}", NULL);
1599  const char * _certPrefix = rpmExpand("%{?_nssdb_certprefix}", NULL);
1600  const char * _keyPrefix = rpmExpand("%{?_nssdb_keyprefix}", NULL);
1601  const char * _secmodName = rpmExpand("%{?_nssdb_secmodname}", NULL);
1602  NSSInitParameters _initParams;
1603  uint32_t _flags = rpmExpandNumeric("%{?_nssdb_flags}");
1604  int msglvl = RPMLOG_DEBUG;
1605  unsigned i;
1606 
1607 /* <nss3/nss.h>
1608  * parameters used to initialize softoken. Mostly strings used to
1609  * internationalize softoken. Memory for the strings are owned by the caller,
1610  * who is free to free them once NSS_ContextInit returns. If the string
1611  * parameter is NULL (as opposed to empty, zero length), then the softoken
1612  * default is used. These are equivalent to the parameters for
1613  * PK11_ConfigurePKCS11().
1614  *
1615  * field names match their equivalent parameter names for softoken strings
1616  * documented at https://developer.mozilla.org/en/PKCS11_Module_Specs.
1617  *
1618  * minPWLen
1619  * Minimum password length in bytes.
1620  * manufacturerID
1621  * Override the default manufactureID value for the module returned in
1622  * the CK_INFO, CK_SLOT_INFO, and CK_TOKEN_INFO structures with an
1623  * internationalize string (UTF8). This value will be truncated at 32
1624  * bytes (not including the trailing NULL, partial UTF8 characters will be
1625  * dropped).
1626  * libraryDescription
1627  * Override the default libraryDescription value for the module returned in
1628  * the CK_INFO structure with an internationalize string (UTF8). This value
1629  * will be truncated at 32 bytes(not including the trailing NULL, partial
1630  * UTF8 characters will be dropped).
1631  * cryptoTokenDescription
1632  * Override the default label value for the internal crypto token returned
1633  * in the CK_TOKEN_INFO structure with an internationalize string (UTF8).
1634  * This value will be truncated at 32 bytes (not including the trailing
1635  * NULL, partial UTF8 characters will be dropped).
1636  * dbTokenDescription
1637  * Override the default label value for the internal DB token returned in
1638  * the CK_TOKEN_INFO structure with an internationalize string (UTF8). This
1639  * value will be truncated at 32 bytes (not including the trailing NULL,
1640  * partial UTF8 characters will be dropped).
1641  * FIPSTokenDescription
1642  * Override the default label value for the internal FIPS token returned in
1643  * the CK_TOKEN_INFO structure with an internationalize string (UTF8). This
1644  * value will be truncated at 32 bytes (not including the trailing NULL,
1645  * partial UTF8 characters will be dropped).
1646  * cryptoSlotDescription
1647  * Override the default slotDescription value for the internal crypto token
1648  * returned in the CK_SLOT_INFO structure with an internationalize string
1649  * (UTF8). This value will be truncated at 64 bytes (not including the
1650  * trailing NULL, partial UTF8 characters will be dropped).
1651  * dbSlotDescription
1652  * Override the default slotDescription value for the internal DB token
1653  * returned in the CK_SLOT_INFO structure with an internationalize string
1654  * (UTF8). This value will be truncated at 64 bytes (not including the
1655  * trailing NULL, partial UTF8 characters will be dropped).
1656  * FIPSSlotDescription
1657  * Override the default slotDecription value for the internal FIPS token
1658  * returned in the CK_SLOT_INFO structure with an internationalize string
1659  * (UTF8). This value will be truncated at 64 bytes (not including the
1660  * trailing NULL, partial UTF8 characters will be dropped).
1661  *
1662  */
1663  memset((void *) &_initParams, '\0', sizeof(_initParams));
1664  _initParams.length = sizeof(_initParams);
1665 
1666 /* <nss3/nss.h>
1667  * Open the Cert, Key, and Security Module databases, read/write.
1668  * Initialize the Random Number Generator.
1669  * Does not initialize the cipher policies or enables.
1670  * Default policy settings disallow all ciphers.
1671  *
1672  * This allows using application defined prefixes for the cert and key db's
1673  * and an alternate name for the secmod database. NOTE: In future releases,
1674  * the database prefixes my not necessarily map to database names.
1675  *
1676  * configdir - base directory where all the cert, key, and module datbases live.
1677  * certPrefix - prefix added to the beginning of the cert database example: "
1678  * "https-server1-"
1679  * keyPrefix - prefix added to the beginning of the key database example: "
1680  * "https-server1-"
1681  * secmodName - name of the security module database (usually "secmod.db").
1682  * flags - change the open options of NSS_Initialize as follows:
1683  * NSS_INIT_READONLY - Open the databases read only.
1684  * NSS_INIT_NOCERTDB - Don't open the cert DB and key DB's, just
1685  * initialize the volatile certdb.
1686  * NSS_INIT_NOMODDB - Don't open the security module DB, just
1687  * initialize the PKCS #11 module.
1688  * NSS_INIT_FORCEOPEN - Continue to force initializations even if the
1689  * databases cannot be opened.
1690  * NSS_INIT_NOROOTINIT - Don't try to look for the root certs module
1691  * automatically.
1692  * NSS_INIT_OPTIMIZESPACE - Use smaller tables and caches.
1693  * NSS_INIT_PK11THREADSAFE - only load PKCS#11 modules that are
1694  * thread-safe, ie. that support locking - either OS
1695  * locking or NSS-provided locks . If a PKCS#11
1696  * module isn't thread-safe, don't serialize its
1697  * calls; just don't load it instead. This is necessary
1698  * if another piece of code is using the same PKCS#11
1699  * modules that NSS is accessing without going through
1700  * NSS, for example the Java SunPKCS11 provider.
1701  * NSS_INIT_PK11RELOAD - ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED
1702  * error when loading PKCS#11 modules. This is necessary
1703  * if another piece of code is using the same PKCS#11
1704  * modules that NSS is accessing without going through
1705  * NSS, for example Java SunPKCS11 provider.
1706  * NSS_INIT_NOPK11FINALIZE - never call C_Finalize on any
1707  * PKCS#11 module. This may be necessary in order to
1708  * ensure continuous operation and proper shutdown
1709  * sequence if another piece of code is using the same
1710  * PKCS#11 modules that NSS is accessing without going
1711  * through NSS, for example Java SunPKCS11 provider.
1712  * The following limitation applies when this is set :
1713  * SECMOD_WaitForAnyTokenEvent will not use
1714  * C_WaitForSlotEvent, in order to prevent the need for
1715  * C_Finalize. This call will be emulated instead.
1716  * NSS_INIT_RESERVED - Currently has no effect, but may be used in the
1717  * future to trigger better cooperation between PKCS#11
1718  * modules used by both NSS and the Java SunPKCS11
1719  * provider. This should occur after a new flag is defined
1720  * for C_Initialize by the PKCS#11 working group.
1721  * NSS_INIT_COOPERATE - Sets 4 recommended options for applications that
1722  * use both NSS and the Java SunPKCS11 provider.
1723  *
1724  * Also NOTE: This is not the recommended method for initializing NSS.
1725  * The preferred method is NSS_init().
1726  */
1727  _flags |= NSS_INIT_READONLY;
1728  if (_configdir == NULL || *_configdir != '/') {
1729  _configdir = _free(_configdir);
1730  _flags |= NSS_INIT_NOCERTDB;
1731  _flags |= NSS_INIT_NOMODDB;
1732  _flags |= NSS_INIT_FORCEOPEN;
1733  _flags |= NSS_INIT_NOROOTINIT;
1734  _flags |= NSS_INIT_OPTIMIZESPACE;
1735  }
1736  /* NSS_INIT_PK11THREADSAFE */
1737  /* NSS_INIT_PK11RELOAD */
1738  /* NSS_INIT_NOPK11FINALIZE */
1739  /* NSS_INIT_RESERVED */
1740  /* NSS_INIT_COOPERATE (is all of the above) */
1741 
1742  rpmlog(msglvl, "---------- NSS %s configuration:\n", NSS_VERSION);
1743  rpmlog(msglvl, " version: %s\n", NSS_GetVersion());
1744  rpmlog(msglvl, " configdir: %s\n", _configdir);
1745  rpmlog(msglvl, "certPrefix: %s\n", _certPrefix);
1746  rpmlog(msglvl, " keyPrefix: %s\n", _keyPrefix);
1747  rpmlog(msglvl, "secmodName: %s\n", _secmodName);
1748  rpmlog(msglvl, " flags: 0x%x\n", _flags);
1749 
1750  /* List the ECC curves. */
1751  for (i = 0; i < nrpmnssOIDS; i++) {
1752  const char * N = rpmnssOIDS[i].N;
1753  uint32_t V = rpmnssOIDS[i].V;
1754  SECOidData * o = SECOID_FindOIDByTag(V);
1755 
1756  if (i == 0)
1757  rpmlog(msglvl, " EC curves:\n");
1758  if (o == NULL)
1759  continue;
1760  rpmlog(msglvl, " %s\n", o->desc);
1761  rpmlog(msglvl, " %12s%5d %s\n",
1762  N, V, pgpHexStr(o->oid.data, o->oid.len));
1763  }
1764  rpmlog(msglvl, "----------\n");
1765 
1766  _rpmnss_context = (void *) NSS_InitContext(_configdir,
1767  _certPrefix, _keyPrefix, _secmodName, &_initParams, _flags);
1768 
1769  _configdir = _free(_configdir);
1770  _certPrefix = _free(_certPrefix);
1771  _keyPrefix = _free(_keyPrefix);
1772  _secmodName = _free(_secmodName);
1773 assert(_rpmnss_context != NULL);
1774 #ifdef NOTYET
1775  NSS_ShutdownFunc _sFunc = foo;
1776  void * _appData = bar;
1777  SECStatus rv;
1778  rv = NSS_RegisterShutdown(_sFunc, _appData);
1779  rv = NSS_UnregisterShutdown(_sFunc, _appData);
1780 #endif
1781 
1782  }
1783 #else
1784  if (!NSS_IsInitialized()) {
1785  const char * _configdir = rpmExpand("%{?_nssdb_path}", NULL);
1786  SECStatus rv;
1787  if (_configdir != NULL && *_configdir == '/')
1788  rv = NSS_Init(_configdir);
1789  else
1790  rv NSS_NoDB_Init(NULL);
1791  _configdir = _free(_configdir);
1792 assert(rv == SECSuccess);
1793  }
1794 #endif
1795 
1796  _rpmnss_init = 1;
1797 
1798  return (void *) nss;
1799 }
1800 
1801 struct pgpImplVecs_s rpmnssImplVecs = {
1802  "NSS " NSS_VERSION,
1803  rpmnssSetRSA,
1804  rpmnssSetDSA,
1805  rpmnssSetELG,
1806  rpmnssSetECDSA,
1807 
1808  rpmnssErrChk,
1809  rpmnssAvailableCipher, rpmnssAvailableDigest, rpmnssAvailablePubkey,
1810  rpmnssVerify, rpmnssSign, rpmnssGenerate,
1811 
1812  rpmnssMpiItem, rpmnssClean,
1813  rpmnssFree, rpmnssInit
1814 };
1815 
1816 int rpmnssExportPubkey(pgpDig dig)
1817 {
1818  uint8_t pkt[8192];
1819  uint8_t * be = pkt;
1820  size_t pktlen;
1821  time_t now = time(NULL);
1822  uint32_t bt = now;
1823  uint16_t bn;
1824  pgpDigParams pubp = pgpGetPubkey(dig);
1825  rpmnss nss = (rpmnss) dig->impl;
1826  int rc = 0; /* assume failure */
1827  int xx;
1828 
1829  *be++ = 0x80 | (PGPTAG_PUBLIC_KEY << 2) | 0x01;
1830  be += 2;
1831 
1832  *be++ = 0x04;
1833  *be++ = (bt >> 24);
1834  *be++ = (bt >> 16);
1835  *be++ = (bt >> 8);
1836  *be++ = (bt );
1837  *be++ = pubp->pubkey_algo;
1838 
1839  switch (pubp->pubkey_algo) {
1840  default:
1841 assert(0);
1842  break;
1843  case PGPPUBKEYALGO_RSA:
1844  /* RSA n */
1845  bn = 8 * nss->pub_key->u.rsa.modulus.len;
1846  bn -= __builtin_clz(pgpGrab(nss->pub_key->u.rsa.modulus.data, 4));
1847  *be++ = (bn >> 8); *be++ = (bn );
1848  bn += 7; bn &= ~7;
1849  memcpy(be, nss->pub_key->u.rsa.modulus.data, bn/8);
1850  be += bn/8;
1851 
1852  /* RSA e */
1853  bn = 8 * nss->pub_key->u.rsa.publicExponent.len;
1854  bn -= __builtin_clz(pgpGrab(nss->pub_key->u.rsa.publicExponent.data,4));
1855  *be++ = (bn >> 8); *be++ = (bn );
1856  bn += 7; bn &= ~7;
1857  memcpy(be, nss->pub_key->u.rsa.publicExponent.data, bn/8);
1858  be += bn/8;
1859  break;
1860  case PGPPUBKEYALGO_DSA:
1861  /* DSA p */
1862  bn = 8 * nss->pub_key->u.dsa.params.prime.len;
1863  bn -= __builtin_clz(pgpGrab(nss->pub_key->u.dsa.params.prime.data, 4));
1864  *be++ = (bn >> 8); *be++ = (bn );
1865  bn += 7; bn &= ~7;
1866  memcpy(be, nss->pub_key->u.dsa.params.prime.data, bn/8);
1867  be += bn/8;
1868 
1869  /* DSA q */
1870  bn = 8 * nss->pub_key->u.dsa.params.subPrime.len;
1871  bn -= __builtin_clz(pgpGrab(nss->pub_key->u.dsa.params.subPrime.data, 4));
1872  *be++ = (bn >> 8); *be++ = (bn );
1873  bn += 7; bn &= ~7;
1874  memcpy(be, nss->pub_key->u.dsa.params.subPrime.data, bn/8);
1875  be += bn/8;
1876 
1877  /* DSA g */
1878  bn = 8 * nss->pub_key->u.dsa.params.base.len;
1879  bn -= __builtin_clz(pgpGrab(nss->pub_key->u.dsa.params.base.data, 4));
1880  *be++ = (bn >> 8); *be++ = (bn );
1881  bn += 7; bn &= ~7;
1882  memcpy(be, nss->pub_key->u.dsa.params.base.data, bn/8);
1883  be += bn/8;
1884 
1885  bn = 8 * nss->pub_key->u.dsa.publicValue.len;
1886  bn -= __builtin_clz(pgpGrab(nss->pub_key->u.dsa.publicValue.data, 4));
1887  *be++ = (bn >> 8); *be++ = (bn );
1888  bn += 7; bn &= ~7;
1889  memcpy(be, nss->pub_key->u.dsa.publicValue.data, bn/8);
1890  be += bn/8;
1891  break;
1892  case PGPPUBKEYALGO_ECDSA:
1893  /* ECDSA oid */
1894  { SECKEYECParams * ecp = &nss->pub_key->u.ec.DEREncodedParams;
1895  *be++ = ecp->len - 2;
1896  memcpy(be, ecp->data+2, ecp->len-2);
1897  be += ecp->len - 2;
1898  }
1899 
1900  /* ECDSA Q */
1901  bn = 8 * nss->pub_key->u.ec.publicValue.len;
1902  bn -= __builtin_clz(pgpGrab(nss->pub_key->u.ec.publicValue.data, 4));
1903  *be++ = (bn >> 8); *be++ = (bn );
1904  bn += 7; bn &= ~7;
1905  memcpy(be, nss->pub_key->u.ec.publicValue.data, bn/8);
1906  be += bn/8;
1907  break;
1908  }
1909 
1910  pktlen = (be - pkt);
1911  bn = pktlen - 3;
1912  pkt[1] = (bn >> 8);
1913  pkt[2] = (bn );
1914 
1915  xx = pgpPubkeyFingerprint(pkt, pktlen, pubp->signid);
1916 
1917  dig->pub = memcpy(xmalloc(pktlen), pkt, pktlen);
1918  dig->publen = pktlen;
1919 
1920  rc = 1;
1921 
1922 SPEW(!rc, rc, dig);
1923  return 0;
1924 }
1925 
1926 int rpmnssExportSignature(pgpDig dig, /*@only@*/ DIGEST_CTX ctx)
1927 {
1928  uint8_t pkt[8192];
1929  uint8_t * be = pkt;
1930  uint8_t * h;
1931  size_t pktlen;
1932  time_t now = time(NULL);
1933  uint32_t bt;
1934  uint16_t bn;
1935  pgpDigParams pubp = pgpGetPubkey(dig);
1936  pgpDigParams sigp = pgpGetSignature(dig);
1937  rpmnss nss = (rpmnss) dig->impl;
1938  int rc = 0; /* assume failure */
1939  int xx;
1940 
1941  sigp->tag = PGPTAG_SIGNATURE;
1942  *be++ = 0x80 | (sigp->tag << 2) | 0x01;
1943  be += 2; /* pktlen */
1944 
1945  sigp->hash = be;
1946  *be++ = sigp->version = 0x04; /* version */
1947  *be++ = sigp->sigtype = PGPSIGTYPE_BINARY; /* sigtype */
1948 assert(sigp->pubkey_algo == pubp->pubkey_algo);
1949  *be++ = sigp->pubkey_algo = pubp->pubkey_algo; /* pubkey_algo */
1950  *be++ = sigp->hash_algo; /* hash_algo */
1951 
1952  be += 2; /* skip hashed length */
1953  h = (uint8_t *) be;
1954 
1955  *be++ = 1 + 4; /* signature creation time */
1957  bt = now;
1958  *be++ = sigp->time[0] = (bt >> 24);
1959  *be++ = sigp->time[1] = (bt >> 16);
1960  *be++ = sigp->time[2] = (bt >> 8);
1961  *be++ = sigp->time[3] = (bt );
1962 
1963  *be++ = 1 + 4; /* signature expiration time */
1965  bt = 30 * 24 * 60 * 60; /* XXX 30 days from creation */
1966  *be++ = sigp->expire[0] = (bt >> 24);
1967  *be++ = sigp->expire[1] = (bt >> 16);
1968  *be++ = sigp->expire[2] = (bt >> 8);
1969  *be++ = sigp->expire[3] = (bt );
1970 
1971 /* key expiration time (only on a self-signature) */
1972 
1973  *be++ = 1 + 1; /* exportable certification */
1975  *be++ = 0;
1976 
1977  *be++ = 1 + 1; /* revocable */
1978  *be++ = PGPSUBTYPE_REVOCABLE;
1979  *be++ = 0;
1980 
1981 /* notation data */
1982 
1983  sigp->hashlen = (be - h); /* set hashed length */
1984  h[-2] = (sigp->hashlen >> 8);
1985  h[-1] = (sigp->hashlen );
1986  sigp->hashlen += sizeof(struct pgpPktSigV4_s);
1987 
1988  if (sigp->hash != NULL)
1989  xx = rpmDigestUpdate(ctx, sigp->hash, sigp->hashlen);
1990 
1991  if (sigp->version == (rpmuint8_t) 4) {
1992  uint8_t trailer[6];
1993  trailer[0] = sigp->version;
1994  trailer[1] = (rpmuint8_t)0xff;
1995  trailer[2] = (sigp->hashlen >> 24);
1996  trailer[3] = (sigp->hashlen >> 16);
1997  trailer[4] = (sigp->hashlen >> 8);
1998  trailer[5] = (sigp->hashlen );
1999  xx = rpmDigestUpdate(ctx, trailer, sizeof(trailer));
2000  }
2001 
2002  sigp->signhash16[0] = 0x00;
2003  sigp->signhash16[1] = 0x00;
2004  switch (pubp->pubkey_algo) {
2005  default:
2006 assert(0);
2007  break;
2008  case PGPPUBKEYALGO_RSA:
2009  xx = pgpImplSetRSA(ctx, dig, sigp); /* XXX signhash16 check fails */
2010  break;
2011  case PGPPUBKEYALGO_DSA:
2012  xx = pgpImplSetDSA(ctx, dig, sigp); /* XXX signhash16 check fails */
2013  break;
2014  case PGPPUBKEYALGO_ECDSA:
2015  xx = pgpImplSetECDSA(ctx, dig, sigp); /* XXX signhash16 check fails */
2016  break;
2017  }
2018  h = (uint8_t *) nss->digest;
2019  sigp->signhash16[0] = h[0];
2020  sigp->signhash16[1] = h[1];
2021 
2022  /* XXX pgpImplVec forces "--usecrypto foo" to also be used */
2023  xx = pgpImplSign(dig);
2024 assert(xx == 1);
2025 
2026  be += 2; /* skip unhashed length. */
2027  h = be;
2028 
2029  *be++ = 1 + 8; /* issuer key ID */
2030  *be++ = PGPSUBTYPE_ISSUER_KEYID;
2031  *be++ = pubp->signid[0];
2032  *be++ = pubp->signid[1];
2033  *be++ = pubp->signid[2];
2034  *be++ = pubp->signid[3];
2035  *be++ = pubp->signid[4];
2036  *be++ = pubp->signid[5];
2037  *be++ = pubp->signid[6];
2038  *be++ = pubp->signid[7];
2039 
2040  bt = (be - h); /* set unhashed length */
2041  h[-2] = (bt >> 8);
2042  h[-1] = (bt );
2043 
2044  *be++ = sigp->signhash16[0]; /* signhash16 */
2045  *be++ = sigp->signhash16[1];
2046 
2047  switch (pubp->pubkey_algo) {
2048  default:
2049 assert(0);
2050  break;
2051  case PGPPUBKEYALGO_RSA:
2052  bn = 8 * nss->sig->len - __builtin_clz(pgpGrab(nss->sig->data, 4));
2053  *be++ = (bn >> 8); *be++ = (bn );
2054  bn += 7; bn &= ~7;
2055  memcpy(be, nss->sig->data, bn/8);
2056  be += bn/8;
2057  break;
2058  case PGPPUBKEYALGO_DSA:
2059  { unsigned int nb = nss->qbits/8; /* XXX FIXME */
2060  SECItem * sig = DSAU_DecodeDerSigToLen(nss->sig, 2 * nb);
2061 assert(sig != NULL);
2062  bn = 8 * (sig->len/2) - __builtin_clz(pgpGrab(sig->data , 4));
2063  *be++ = (bn >> 8); *be++ = (bn );
2064  bn += 7; bn &= ~7;
2065  memcpy(be, sig->data, bn/8);
2066  be += bn/8;
2067 
2068  bn = 8 * (sig->len/2) - __builtin_clz(pgpGrab(sig->data+sig->len/2, 4));
2069  *be++ = (bn >> 8); *be++ = (bn );
2070  bn += 7; bn &= ~7;
2071  memcpy(be, sig->data + (bn/8), bn/8);
2072  be += bn/8;
2073  SECITEM_ZfreeItem(sig, PR_TRUE);
2074  } break;
2075  case PGPPUBKEYALGO_ECDSA:
2076  { unsigned int nb = nss->qbits/8; /* XXX FIXME */
2077  SECItem * sig = DSAU_DecodeDerSigToLen(nss->sig, 2 * nb);
2078 assert(sig != NULL);
2079  bn = 8 * (sig->len/2) - __builtin_clz(pgpGrab(sig->data , 4));
2080  *be++ = (bn >> 8); *be++ = (bn );
2081  bn += 7; bn &= ~7;
2082  memcpy(be, sig->data, bn/8);
2083  be += bn/8;
2084 
2085  bn = 8 * (sig->len/2) - __builtin_clz(pgpGrab(sig->data+sig->len/2, 4));
2086  *be++ = (bn >> 8); *be++ = (bn );
2087  bn += 7; bn &= ~7;
2088  memcpy(be, sig->data + (bn/8), bn/8);
2089  be += bn/8;
2090  SECITEM_ZfreeItem(sig, PR_TRUE);
2091  } break;
2092  }
2093 
2094  pktlen = (be - pkt); /* packet length */
2095  bn = pktlen - 3;
2096  pkt[1] = (bn >> 8);
2097  pkt[2] = (bn );
2098 
2099  dig->sig = memcpy(xmalloc(pktlen), pkt, pktlen);
2100  dig->siglen = pktlen;
2101 
2102  rc = 1;
2103 
2104 SPEW(!rc, rc, dig);
2105  return rc;
2106 }
2107 
2108 #endif /* WITH_NSS */
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
struct rpmnss_s * rpmnss
Definition: rpmnss.h:27
char * xstrdup(const char *str)
Definition: rpmmalloc.c:321
struct pgpDigParams_s * pgpDigParams
Definition: rpmiotypes.h:101
static unsigned int pgpGrab(const rpmuint8_t *s, size_t nbytes)
Return (native-endian) integer from big-endian representation.
Definition: rpmpgp.h:1036
const char int time
Definition: bson.h:1005
5.2.3.
Definition: rpmpgp.h:376
static void rpmlog(int code, const char *fmt,...)
Definition: rpmlog.h:299
pgpImplVecs_t rpmnssImplVecs
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
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
mongo_error_t err
Definition: mongo.h:922
const char const bson_oid_t * oid
Definition: bson.h:757
#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
#define fail(_err)
Definition: yarn.c:199
Digest private data.
Definition: digest.c:130
struct pgpDig_s * pgpDig
Definition: rpmiotypes.h:97
static int pgpImplSetECDSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Definition: rpmpgp.h:1803
#define _ENTRY(_v)
Definition: db3.c:236
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
Definition: macro.c:3250
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 int snprintf(char *buf, int nb, const char *fmt,...)
Definition: rpmps.c:220
const char const bson * key
Definition: mongo.h:717
int pgpPubkeyFingerprint(const rpmuint8_t *pkt, size_t pktlen, rpmuint8_t *keyid)
Print/parse an OpenPGP subtype packet.
Definition: rpmpgp.c:1029
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:756
const char char type
Definition: bson.h:908
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
static const char * name
#define xmalloc
Definition: system.h:32
int rpmnssExportSignature(pgpDig dig, DIGEST_CTX ctx)
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 rpmExpandNumeric(const char *arg)
Return macro expansion as a numeric value.
Definition: macro.c:3324
int _pgp_debug
Definition: rpmpgp.c:42
int rpmnssExportPubkey(pgpDig dig)