9 #define _RPMPGP_INTERNAL
11 #define _RPMNSS_INTERNAL
32 extern int _rpmnss_init;
35 static int _rpmnss_debug;
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); \
45 typedef struct keyNV_s {
52 keyNVCmp(
const void * a,
const void *
b)
54 return strcmp(((keyNV_t *)a)->
N, ((keyNV_t *)b)->
N);
58 keyNV(keyNV_t *
keys,
size_t nkeys,
const char *
N)
63 keyNV_t needle = { .N =
N, .V = 0 };
64 keyNV_t *
k = (keyNV_t *)
65 bsearch(&needle, keys, nkeys,
sizeof(*keys), keyNVCmp);
72 typedef struct keyVN_s {
79 keyVNCmp(
const void * a,
const void * b)
81 return (((keyVN_t *)a)->V - ((keyVN_t *)b)->V);
85 keyVN(keyVN_t * keys,
size_t nkeys,
int V)
87 const char * N =
NULL;
97 bsearch(&needle, keys, nkeys,
sizeof(*keys), keyVNCmp);
117 EC_DecodeParams(
const SECItem *encodedParams, ECParams **ecparams);
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},
195 static size_t nrpmnssOIDS =
sizeof(rpmnssOIDS) /
sizeof(rpmnssOIDS[0]);
197 #define _ENTRY(_v) { SEC_ERROR_##_v, #_v }
199 static keyVN_t rpmnssERRS[] = {
206 _ENTRY(INVALID_ALGORITHM),
211 _ENTRY(EXPIRED_CERTIFICATE),
212 _ENTRY(REVOKED_CERTIFICATE),
223 _ENTRY(DUPLICATE_CERT_NAME),
230 _ENTRY(EXPIRED_ISSUER_CERTIFICATE),
232 _ENTRY(CRL_BAD_SIGNATURE),
234 _ENTRY(EXTENSION_VALUE_INVALID),
235 _ENTRY(EXTENSION_NOT_FOUND),
237 _ENTRY(PATH_LEN_CONSTRAINT_INVALID),
238 _ENTRY(CERT_USAGES_INVALID),
241 _ENTRY(UNKNOWN_CRITICAL_EXTENSION),
244 _ENTRY(NO_RECIPIENT_CERTS_QUERY),
246 _ENTRY(PKCS7_KEYALG_MISMATCH),
247 _ENTRY(PKCS7_BAD_SIGNATURE),
248 _ENTRY(UNSUPPORTED_KEYALG),
249 _ENTRY(DECRYPTION_DISALLOWED),
261 _ENTRY(KRL_BAD_SIGNATURE),
269 _ENTRY(CERT_NICKNAME_COLLISION),
270 _ENTRY(KEY_NICKNAME_COLLISION),
272 _ENTRY(BAGGAGE_NOT_CREATED),
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),
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),
303 _ENTRY(RETRY_OLD_PASSWORD),
305 _ENTRY(NOT_FORTEZZA_ISSUER),
306 _ENTRY(CANNOT_MOVE_SENSITIVE_KEY),
307 _ENTRY(JS_INVALID_MODULE_NAME),
309 _ENTRY(JS_ADD_MOD_FAILURE),
310 _ENTRY(JS_DEL_MOD_FAILURE),
313 _ENTRY(CERT_NOT_IN_NAME_SPACE),
314 _ENTRY(KRL_NOT_YET_VALID),
315 _ENTRY(CRL_NOT_YET_VALID),
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),
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),
336 _ENTRY(UNSUPPORTED_MESSAGE_TYPE),
340 _ENTRY(REUSED_ISSUER_AND_SERIAL),
344 _ENTRY(UNSUPPORTED_ELLIPTIC_CURVE),
345 _ENTRY(UNSUPPORTED_EC_POINT_FORM),
347 _ENTRY(OCSP_INVALID_SIGNING_CERT),
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),
357 _ENTRY(CRL_ALREADY_EXISTS),
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),
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),
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),
378 #if defined(SEC_ERROR_CRL_IMPORT_FAILED)
379 _ENTRY(CRL_IMPORT_FAILED),
381 #if defined(SEC_ERROR_EXPIRED_PASSWORD)
384 #if defined(SEC_ERROR_LOCKED_PASSWORD)
387 #if defined(SEC_ERROR_UNKNOWN_PKCS11_ERROR)
388 _ENTRY(UNKNOWN_PKCS11_ERROR),
390 #if defined(SEC_ERROR_BAD_CRL_DP_URL)
393 #if defined(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED)
394 _ENTRY(CERT_SIGNATURE_ALGORITHM_DISABLED),
396 #if defined(SEC_ERROR_LEGACY_DATABASE)
399 #if defined(SEC_ERROR_APPLICATION_CALLBACK_ERROR)
400 _ENTRY(APPLICATION_CALLBACK_ERROR),
403 static size_t nrpmnssERRS =
sizeof(rpmnssERRS) /
sizeof(rpmnssERRS[0]);
406 static uint32_t curve2oid(
const char *
name)
408 uint32_t oid = keyNV(rpmnssOIDS, nrpmnssOIDS, name);
410 oid = SEC_OID_UNKNOWN;
413 fprintf(stderr,
"<-- %s(%s) oid %u\n", __FUNCTION__, name, oid);
418 static const char * rpmnssStrerror(
int err)
421 const char * errN = keyVN(rpmnssERRS, nrpmnssERRS, err);
423 snprintf(buf,
sizeof(buf),
"SEC_ERROR(%d)", err);
430 int rpmnssErr(
rpmnss nss,
const char *
msg,
int rc)
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));
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));
448 static SECOidTag getEncAlg(
unsigned pubkey_algo)
450 SECOidTag encAlg = SEC_OID_UNKNOWN;
452 switch (pubkey_algo) {
463 static SECOidTag getHashAlg(
unsigned hash_algo)
465 SECOidTag hashAlg = SEC_OID_UNKNOWN;
500 nss->digest =
_free(nss->digest);
504 nss->encAlg = getEncAlg(pubp->pubkey_algo);
505 nss->hashAlg = getHashAlg(sigp->hash_algo);
506 if (nss->hashAlg == SEC_OID_UNKNOWN)
510 rc = memcmp(nss->digest, sigp->signhash16,
sizeof(sigp->signhash16));
518 int rpmnssVerifyRSA(
pgpDig dig)
524 nss->encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
525 assert(nss->encAlg == SEC_OID_PKCS1_RSA_ENCRYPTION);
526 assert(nss->hashAlg != SEC_OID_UNKNOWN);
528 nss->item.type = siBuffer;
529 nss->item.data = (
unsigned char *) nss->digest;
530 nss->item.len = (
unsigned) nss->digestlen;
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);
541 static int rpmnssSignRSA(
pgpDig dig)
546 assert(nss->hashAlg != SEC_OID_UNKNOWN);
548 nss->item.type = siBuffer;
549 nss->item.data = (
unsigned char *) nss->digest;
550 nss->item.len = (
unsigned) nss->digestlen;
552 if (nss->sig !=
NULL) {
553 SECITEM_ZfreeItem(nss->sig, PR_TRUE);
556 nss->sig = SECITEM_AllocItem(
NULL,
NULL, 0);
557 nss->sig->type = siBuffer;
559 rc = rpmnssErr(nss,
"SGN_Digest",
560 SGN_Digest(nss->sec_key, nss->hashAlg, nss->sig, &nss->item));
561 rc = (rc == SECSuccess);
567 static int rpmnssGenerateRSA(
pgpDig dig)
572 if (nss->nbits == 0) nss->nbits = 1024;
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;
582 static unsigned _pe = 0x10001;
583 PK11RSAGenParams rsaparams = {};
584 void * params = &rsaparams;
586 rsaparams.keySizeInBits = nss->nbits;
589 nss->sec_key = PK11_GenerateKeyPair(_slot, _type, params,
590 &nss->pub_key, _isPerm, _isSensitive, _cx);
592 PK11_FreeSlot(_slot);
596 rc = (nss->sec_key && nss->pub_key);
615 nss->digest =
_free(nss->digest);
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);
627 rc = memcmp(nss->digest, sigp->signhash16,
sizeof(sigp->signhash16));
635 int rpmnssVerifyDSA(
pgpDig dig)
641 nss->encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
642 assert(nss->encAlg == SEC_OID_ANSIX9_DSA_SIGNATURE);
643 assert(nss->hashAlg != SEC_OID_UNKNOWN);
645 nss->item.type = siBuffer;
646 nss->item.data = (
unsigned char *) nss->digest;
647 nss->item.len = (
unsigned) nss->digestlen;
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);
658 static int rpmnssSignDSA(
pgpDig dig)
662 SECItem sig = { siBuffer,
NULL, 0 };
664 assert(nss->hashAlg != SEC_OID_UNKNOWN);
666 nss->item.type = siBuffer;
667 nss->item.data = (
unsigned char *) nss->digest;
668 nss->item.len = (
unsigned) nss->digestlen;
670 if (nss->sig !=
NULL) {
671 SECITEM_ZfreeItem(nss->sig, PR_TRUE);
675 nss->sig = SECITEM_AllocItem(
NULL,
NULL, 0);
676 nss->sig->type = siBuffer;
678 rc = rpmnssErr(nss,
"SGN_Digest",
679 SGN_Digest(nss->sec_key, nss->hashAlg, &sig, &nss->item));
681 if (rc == SECSuccess)
682 rc = rpmnssErr(nss,
"DSAU_EncodeDerSigWithLen",
683 DSAU_EncodeDerSigWithLen(nss->sig, &sig, sig.len));
684 sig.data =
_free(sig.data);
686 rc = (rc == SECSuccess);
692 static int rpmnssGenerateDSA(
pgpDig dig)
698 unsigned _seedBytes = 0;
701 if (nss->nbits == 0) nss->nbits = 1024;
703 if (nss->qbits == 0) nss->qbits = 160;
733 xx = PQG_PBITS_TO_INDEX(nss->nbits);
734 if (
xx >= 0 &&
xx <= 8) {
739 switch (nss->nbits) {
748 _N = (nss->qbits == 256) ? 256 : 0;
753 _N = (nss->qbits == 256) ? 256 : 0;
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;
766 PQGParams *pqgParams =
NULL;
767 PQGVerify *pqgVfy =
NULL;
768 void * params =
NULL;
771 xx = rpmnssErr(nss,
"PK11_PQG_ParamGenV2",
772 PK11_PQG_ParamGenV2(_L, _N, _seedBytes,
773 &pqgParams, &pqgVfy));
775 xx = rpmnssErr(nss,
"PK11_PQG_ParamGen",
776 PK11_PQG_ParamGen(0, &pqgParams, &pqgVfy));
778 if (
xx != SECSuccess)
782 nss->sec_key = PK11_GenerateKeyPair(_slot, _type, params,
783 &nss->pub_key, _isPerm, _isSensitive, _cx);
785 if (pqgVfy) PK11_PQG_DestroyVerify(pqgVfy);
786 if (pqgParams) PK11_PQG_DestroyParams(pqgParams);
788 PK11_FreeSlot(_slot);
792 rc = (nss->sec_key && nss->pub_key);
808 nss->digest =
_free(nss->digest);
813 rc = memcmp(nss->digest, sigp->signhash16,
sizeof(sigp->signhash16));
833 nss->digest =
_free(nss->digest);
837 nss->encAlg = getEncAlg(pubp->pubkey_algo);
838 nss->hashAlg = getHashAlg(sigp->hash_algo);
839 if (nss->hashAlg == SEC_OID_UNKNOWN)
843 rc = memcmp(nss->digest, sigp->signhash16,
sizeof(sigp->signhash16));
851 int rpmnssVerifyECDSA(
pgpDig dig)
857 nss->encAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
858 assert(nss->encAlg == SEC_OID_ANSIX962_EC_PUBLIC_KEY);
859 assert(nss->hashAlg != SEC_OID_UNKNOWN);
861 nss->item.type = siBuffer;
862 nss->item.data = (
unsigned char *) nss->digest;
863 nss->item.len = (
unsigned) nss->digestlen;
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);
875 int rpmnssSignECDSA(
pgpDig dig)
880 SECItem sig = { siBuffer,
NULL, 0 };
882 assert(nss->hashAlg != SEC_OID_UNKNOWN);
884 nss->item.type = siBuffer;
885 nss->item.data = nss->digest;
886 nss->item.len = (
unsigned) nss->digestlen;
889 SECITEM_ZfreeItem(nss->sig, PR_TRUE);
892 nss->sig = SECITEM_AllocItem(
NULL,
NULL, 0);
893 nss->sig->type = siBuffer;
895 rc = rpmnssErr(nss,
"SGN_Digest",
896 SGN_Digest(nss->sec_key, nss->hashAlg, &sig, &nss->item));
898 if (rc == SECSuccess)
899 rc = rpmnssErr(nss,
"DSAU_EncodeDerSigWithLen",
900 DSAU_EncodeDerSigWithLen(nss->sig, &sig, sig.len));
901 sig.data =
_free(sig.data);
903 rc = (rc == SECSuccess);
909 static int rpmnssLoadParams(
pgpDig dig)
913 SECOidTag curveOid = SEC_OID_UNKNOWN;
914 SECOidData * oidData =
NULL;
920 nss->curveOid = curveOid = curve2oid(name);
921 if (curveOid == SEC_OID_UNKNOWN)
923 oidData = SECOID_FindOIDByTag(curveOid);
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);
935 fprintf(stderr,
"<-- %s(%p,%s) oid %u params %p\n", __FUNCTION__, dig, name, nss->curveOid, nss->ecparams);
940 int rpmnssGenerateECDSA(
pgpDig dig)
946 if (nss->sec_key !=
NULL) {
947 SECKEY_DestroyPrivateKey(nss->sec_key);
950 if (nss->pub_key !=
NULL) {
951 SECKEY_DestroyPublicKey(nss->pub_key);
959 if (nss->curveN ==
NULL)
960 switch (nss->nbits) {
961 default:
goto exit;
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;
970 rc = rpmnssLoadParams(dig);
974 CK_MECHANISM_TYPE _type = CKM_EC_KEY_PAIR_GEN;
975 PK11SlotInfo * _slot = PK11_GetBestSlot(_type, _cx);
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;
992 nss->sec_key = PK11_GenerateKeyPairWithOpFlags(_slot, _type,
994 &nss->pub_key, _aFlags, _opFlags, _opFlagsMask, _cx);
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,
1001 &nss->pub_key, _aFlags, _opFlags, _opFlagsMask, _cx);
1005 int _isPerm = PR_FALSE;
1006 int _isSensitive = PR_TRUE;
1010 nss->sec_key = PK11_GenerateKeyPair(_slot, _type, nss->ecparams,
1011 &nss->pub_key, _isPerm, _isSensitive, _cx);
1014 PK11_FreeSlot(_slot);
1018 rc = (nss->sec_key && nss->pub_key);
1026 static int rpmnssErrChk(
pgpDig dig,
const char * msg,
int rc,
unsigned expected)
1029 rpmgc gc = dig->impl;
1031 rc = (gcry_err_code(gc->err) != expected);
1033 fail(
"%s failed: %s\n", msg, gpg_strerror(gc->err));
1041 static int rpmnssAvailableCipher(
pgpDig dig,
int algo)
1047 static int rpmnssAvailableDigest(
pgpDig dig,
int algo)
1050 SECOidTag hashAlgo = getHashAlg(algo);
1051 rc = (hashAlgo == SEC_OID_UNKNOWN);
1055 static int rpmnssAvailablePubkey(
pgpDig dig,
int algo)
1058 SECOidTag encAlgo = getEncAlg(algo);
1059 rc = (encAlgo == SEC_OID_UNKNOWN);
1063 static int rpmnssVerify(
pgpDig dig)
1071 switch (pubp->pubkey_algo) {
1075 rc = rpmnssVerifyRSA(dig);
1078 rc = rpmnssVerifyDSA(dig);
1082 rc = rpmnssVerifyELG(dig);
1086 rc = rpmnssVerifyECDSA(dig);
1093 static int rpmnssSign(
pgpDig dig)
1099 switch (pubp->pubkey_algo) {
1103 rc = rpmnssSignRSA(dig);
1106 rc = rpmnssSignDSA(dig);
1110 rc = rpmnssSignELG(dig);
1114 rc = rpmnssSignECDSA(dig);
1121 static int rpmnssGenerate(
pgpDig dig)
1127 switch (pubp->pubkey_algo) {
1131 rc = rpmnssGenerateRSA(dig);
1134 rc = rpmnssGenerateDSA(dig);
1138 rc = rpmnssGenerateELG(dig);
1142 rc = rpmnssGenerateECDSA(dig);
1153 int rpmnssMpiSet(
const char * pre,
unsigned int lbits,
1160 unsigned int nbytes;
1161 char *
t = (
char *) dest;
1164 if (pend !=
NULL && (p + ((mbits+7) >> 3)) > pend)
1170 nbits = (lbits > mbits ? lbits : mbits);
1171 nbytes = ((nbits + 7) >> 3);
1172 ix = ((nbits - mbits) >> 3);
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);
1190 SECItem * rpmnssMpiCopy(PRArenaPool * arena, SECItem * item,
1198 if ((item = SECITEM_AllocItem(arena, item, nbytes)) ==
NULL)
1202 item->data = (
unsigned char *) PORT_ArenaGrow(arena, item->data, item->len, nbytes);
1204 item->data = (
unsigned char *) PORT_Realloc(item->data, nbytes);
1206 if (item->data ==
NULL) {
1208 SECITEM_FreeItem(item, PR_TRUE);
1214 memcpy(item->data, p+2, nbytes);
1222 SECKEYPublicKey * rpmnssNewPublicKey(KeyType
type)
1226 SECKEYPublicKey *
key;
1229 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1233 key = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena,
sizeof(*key));
1236 PORT_FreeArena(arena, PR_FALSE);
1241 key->keyType =
type;
1242 key->pkcs11ID = CK_INVALID_HANDLE;
1243 key->pkcs11Slot =
NULL;
1251 int rpmnssMpiItem(
const char * pre,
pgpDig dig,
int itemno,
1257 size_t nb = (pend >= p ? (pend - p) : 0);
1266 nss->sig = rpmnssMpiCopy(
NULL, nss->sig, p);
1267 if (nss->sig ==
NULL)
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);
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)
1285 nss->item.data =
_free(nss->item.data);
1288 if (nss->pub_key ==
NULL)
1289 nss->pub_key = rpmnssNewPublicKey(rsaKey);
1290 if (nss->pub_key ==
NULL)
1293 (
void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.rsa.modulus, p);
1296 if (nss->pub_key ==
NULL)
1297 nss->pub_key = rpmnssNewPublicKey(rsaKey);
1298 if (nss->pub_key ==
NULL)
1301 (
void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.rsa.publicExponent, p);
1304 if (nss->pub_key ==
NULL)
1305 nss->pub_key = rpmnssNewPublicKey(dsaKey);
1306 if (nss->pub_key ==
NULL)
1309 (
void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.prime, p);
1312 if (nss->pub_key ==
NULL)
1313 nss->pub_key = rpmnssNewPublicKey(dsaKey);
1314 if (nss->pub_key ==
NULL)
1317 (
void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.subPrime, p);
1320 if (nss->pub_key ==
NULL)
1321 nss->pub_key = rpmnssNewPublicKey(dsaKey);
1322 if (nss->pub_key ==
NULL)
1325 (
void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.base, p);
1328 if (nss->pub_key ==
NULL)
1329 nss->pub_key = rpmnssNewPublicKey(dsaKey);
1330 if (nss->pub_key ==
NULL)
1333 (
void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.publicValue, p);
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);
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)
1350 nss->item.data =
_free(nss->item.data);
1354 if (nss->pub_key ==
NULL)
1355 nss->pub_key = rpmnssNewPublicKey(ecKey);
1356 if (nss->pub_key ==
NULL)
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;
1363 memcpy(ecp->data + 2, p,
nb);
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);
1380 void rpmnssClean(
void * impl)
1391 nss->digest =
_free(nss->digest);
1394 if (nss->sec_key !=
NULL) {
1395 SECKEY_DestroyPrivateKey(nss->sec_key);
1396 nss->sec_key =
NULL;
1398 if (nss->pub_key !=
NULL) {
1399 SECKEY_DestroyPublicKey(nss->pub_key);
1400 nss->pub_key =
NULL;
1402 if (nss->sig !=
NULL) {
1403 SECITEM_ZfreeItem(nss->sig, PR_TRUE);
1407 nss->encAlg = SEC_OID_UNKNOWN;
1408 nss->hashAlg = SEC_OID_UNKNOWN;
1410 nss->item.type = siBuffer;
1411 nss->item.data = (
unsigned char *)
NULL;
1414 if (nss->ecparams !=
NULL) {
1415 SECITEM_FreeItem(nss->ecparams, PR_FALSE);
1416 nss->ecparams =
NULL;
1418 nss->curveN =
_free(nss->curveN);
1419 nss->curveOid = SEC_OID_UNKNOWN;
1426 void * rpmnssFree(
void * impl)
1435 void * rpmnssInit(
void)
1440 const char * _nssdb_path =
rpmExpand(
"%{?_nssdb_path}",
NULL);
1443 if (_nssdb_path !=
NULL && *_nssdb_path ==
'/')
1444 (
void) NSS_Init(_nssdb_path);
1446 (
void) NSS_NoDB_Init(
NULL);
1448 _nssdb_path =
_free(_nssdb_path);
1452 return (
void *) nss;
1462 rpmnssAvailableCipher, rpmnssAvailableDigest, rpmnssAvailablePubkey,
1463 rpmnssVerify, rpmnssSign, rpmnssGenerate,
1465 rpmnssMpiItem, rpmnssClean,
1466 rpmnssFree, rpmnssInit
static unsigned int pgpMpiBits(const rpmuint8_t *p)
Return no.
static const char * _pgpHashAlgo2Name(uint32_t algo)
pgpImplVecs_t rpmnssImplVecs
static PyObject *int type
char * xstrdup(const char *str)
static char *size_t nb
fgets(3) analogue that reads \ continuations.
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
memset(_r, 0, sizeof(*_r))
void * xcalloc(size_t nmemb, size_t size)
assert(key->size==sizeof(hdrNum))
struct pgpValTbl_s pgpHashTbl[]
Hash (string, value) pairs.
static char * pgpHexStr(const rpmuint8_t *p, size_t plen)
Return hex formatted representation of bytes.
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.
pgpHashAlgo rpmDigestAlgo(DIGEST_CTX ctx)
Return digest algorithm identifier.
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
return strcmp(ame->name, bme->name)
static int snprintf(char *buf, int nb, const char *fmt,...)
static unsigned int pgpMpiLen(const rpmuint8_t *p)
Return no.
#define SPEW(_t, _rc, _dig)
struct pgpDigParams_s * pgpDigParams
static const char * pgpValStr(pgpValTbl vs, rpmuint8_t val)
Return string representation of am OpenPGP value.
static void
Print copy of spec file, filling in Group/Description/Summary from specspo.
char * buf
Parse (and execute) macro undefinition.
void rpmDigestFinal(rpmDigestDup(md5ctx),&md5sum,&md5len, 0)
static const char * _pgpPubkeyAlgo2Name(uint32_t algo)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
pgpDigParams pgpGetPubkey(pgpDig dig)
Return OpenPGP pubkey parameters.
struct pgpValTbl_s pgpPubkeyTbl[]