rpm 5.3.12
|
00001 00005 #include "system.h" 00006 #include <rpmio.h> 00007 00008 #include <rpmiotypes.h> 00009 #define _RPMPGP_INTERNAL 00010 #if defined(WITH_NSS) 00011 #define _RPMNSS_INTERNAL 00012 #include <rpmnss.h> 00013 #endif 00014 #include <rpmmacro.h> 00015 00016 #include "debug.h" 00017 00018 #if defined(WITH_NSS) 00019 00020 /*@access pgpDig @*/ 00021 /*@access pgpDigParams @*/ 00022 00023 /*@-redecl@*/ 00024 /*@unchecked@*/ 00025 extern int _pgp_debug; 00026 00027 /*@unchecked@*/ 00028 extern int _pgp_print; 00029 /*@=redecl@*/ 00030 00031 /*@unchecked@*/ 00032 extern int _rpmnss_init; 00033 00034 /*@unchecked@*/ 00035 static int _rpmnss_debug; 00036 00037 #define SPEW(_t, _rc, _dig) \ 00038 { if ((_t) || _rpmnss_debug || _pgp_debug < 0) \ 00039 fprintf(stderr, "<-- %s(%p) %s\t%s\n", __FUNCTION__, (_dig), \ 00040 ((_rc) ? "OK" : "BAD"), (_dig)->pubkey_algoN); \ 00041 } 00042 00043 /*==============================================================*/ 00044 00045 #ifdef NOTYET 00046 typedef struct key_s { 00047 /*@observer@*/ 00048 const char * name; /* key name */ 00049 uint32_t value; 00050 } KEY; 00051 00052 static int 00053 keyCmp(const void * a, const void * b) 00054 { 00055 return strcmp(((KEY *)a)->name, ((KEY *)b)->name); 00056 } 00057 00058 static uint32_t 00059 keyValue(KEY * keys, size_t nkeys, /*@null@*/ const char *name) 00060 { 00061 uint32_t keyval = 0; 00062 00063 if (name && *name) { 00064 /* XXX bsearch is overkill */ 00065 KEY needle = { .name = name, .value = 0 }; 00066 KEY *k = (KEY *)bsearch(&needle, keys, nkeys, sizeof(*keys), keyCmp); 00067 if (k) 00068 keyval = k->value; 00069 } 00070 return keyval; 00071 } 00072 #endif 00073 00074 typedef struct keyVN_s { 00075 int V; 00076 /*@observer@*/ 00077 const char * N; /* key name */ 00078 } keyVN_t; 00079 00080 static int 00081 keyVNCmp(const void * a, const void * b) 00082 { 00083 return (((keyVN_t *)a)->V - ((keyVN_t *)b)->V); 00084 } 00085 00086 static const char * 00087 keyVN(keyVN_t * keys, size_t nkeys, /*@null@*/ int V) 00088 { 00089 const char * N = NULL; 00090 00091 if (V) { 00092 /* XXX bsearch is overkill */ 00093 keyVN_t needle = { .V = V, .N = NULL }; 00094 keyVN_t *k = (keyVN_t *) 00095 bsearch(&needle, keys, nkeys, sizeof(*keys), keyVNCmp); 00096 if (k) 00097 N = k->N; 00098 } 00099 return N; 00100 } 00101 00102 static const char * _pgpHashAlgo2Name(uint32_t algo) 00103 { 00104 return pgpValStr(pgpHashTbl, (rpmuint8_t)algo); 00105 } 00106 00107 static const char * _pgpPubkeyAlgo2Name(uint32_t algo) 00108 { 00109 return pgpValStr(pgpPubkeyTbl, (rpmuint8_t)algo); 00110 } 00111 00112 /*==============================================================*/ 00113 00114 #define _ENTRY(_v) { SEC_ERROR_##_v, #_v } 00115 /* XXX sorted table */ 00116 static keyVN_t rpmnssERRS[] = { 00117 _ENTRY(IO), 00118 _ENTRY(LIBRARY_FAILURE), 00119 _ENTRY(BAD_DATA), 00120 _ENTRY(OUTPUT_LEN), 00121 _ENTRY(INPUT_LEN), 00122 _ENTRY(INVALID_ARGS), 00123 _ENTRY(INVALID_ALGORITHM), 00124 _ENTRY(INVALID_AVA), 00125 _ENTRY(INVALID_TIME), 00126 _ENTRY(BAD_DER), 00127 _ENTRY(BAD_SIGNATURE), 00128 _ENTRY(EXPIRED_CERTIFICATE), 00129 _ENTRY(REVOKED_CERTIFICATE), 00130 _ENTRY(UNKNOWN_ISSUER), 00131 _ENTRY(BAD_KEY), 00132 _ENTRY(BAD_PASSWORD), 00133 _ENTRY(RETRY_PASSWORD), 00134 _ENTRY(NO_NODELOCK), 00135 _ENTRY(BAD_DATABASE), 00136 _ENTRY(NO_MEMORY), 00137 _ENTRY(UNTRUSTED_ISSUER), 00138 _ENTRY(UNTRUSTED_CERT), 00139 _ENTRY(DUPLICATE_CERT), 00140 _ENTRY(DUPLICATE_CERT_NAME), 00141 _ENTRY(ADDING_CERT), 00142 _ENTRY(FILING_KEY), 00143 _ENTRY(NO_KEY), 00144 _ENTRY(CERT_VALID), 00145 _ENTRY(CERT_NOT_VALID), 00146 _ENTRY(CERT_NO_RESPONSE), 00147 _ENTRY(EXPIRED_ISSUER_CERTIFICATE), 00148 _ENTRY(CRL_EXPIRED), 00149 _ENTRY(CRL_BAD_SIGNATURE), 00150 _ENTRY(CRL_INVALID), 00151 _ENTRY(EXTENSION_VALUE_INVALID), 00152 _ENTRY(EXTENSION_NOT_FOUND), 00153 _ENTRY(CA_CERT_INVALID), 00154 _ENTRY(PATH_LEN_CONSTRAINT_INVALID), 00155 _ENTRY(CERT_USAGES_INVALID), 00156 /* SEC_INTERNAL_ONLY */ 00157 _ENTRY(INVALID_KEY), 00158 _ENTRY(UNKNOWN_CRITICAL_EXTENSION), 00159 _ENTRY(OLD_CRL), 00160 _ENTRY(NO_EMAIL_CERT), 00161 _ENTRY(NO_RECIPIENT_CERTS_QUERY), 00162 _ENTRY(NOT_A_RECIPIENT), 00163 _ENTRY(PKCS7_KEYALG_MISMATCH), 00164 _ENTRY(PKCS7_BAD_SIGNATURE), 00165 _ENTRY(UNSUPPORTED_KEYALG), 00166 _ENTRY(DECRYPTION_DISALLOWED), 00167 /* Fortezza Alerts */ 00168 /* XP_SEC_FORTEZZA_BAD_CARD */ 00169 /* XP_SEC_FORTEZZA_NO_CARD */ 00170 /* XP_SEC_FORTEZZA_NONE_SELECTED */ 00171 /* XP_SEC_FORTEZZA_MORE_INFO */ 00172 /* XP_SEC_FORTEZZA_PERSON_NOT_FOUND */ 00173 /* XP_SEC_FORTEZZA_NO_MORE_INFO */ 00174 /* XP_SEC_FORTEZZA_BAD_PIN */ 00175 /* XP_SEC_FORTEZZA_PERSON_ERROR */ 00176 _ENTRY(NO_KRL), 00177 _ENTRY(KRL_EXPIRED), 00178 _ENTRY(KRL_BAD_SIGNATURE), 00179 _ENTRY(REVOKED_KEY), 00180 _ENTRY(KRL_INVALID), 00181 _ENTRY(NEED_RANDOM), 00182 _ENTRY(NO_MODULE), 00183 _ENTRY(NO_TOKEN), 00184 _ENTRY(READ_ONLY), 00185 _ENTRY(NO_SLOT_SELECTED), 00186 _ENTRY(CERT_NICKNAME_COLLISION), 00187 _ENTRY(KEY_NICKNAME_COLLISION), 00188 _ENTRY(SAFE_NOT_CREATED), 00189 _ENTRY(BAGGAGE_NOT_CREATED), 00190 /* XP_JAVA_REMOVE_PRINCIPAL_ERROR */ 00191 /* XP_JAVA_DELETE_PRIVILEGE_ERROR */ 00192 /* XP_JAVA_CERT_NOT_EXISTS_ERROR */ 00193 _ENTRY(BAD_EXPORT_ALGORITHM), 00194 _ENTRY(EXPORTING_CERTIFICATES), 00195 _ENTRY(IMPORTING_CERTIFICATES), 00196 _ENTRY(PKCS12_DECODING_PFX), 00197 _ENTRY(PKCS12_INVALID_MAC), 00198 _ENTRY(PKCS12_UNSUPPORTED_MAC_ALGORITHM), 00199 _ENTRY(PKCS12_UNSUPPORTED_TRANSPORT_MODE), 00200 _ENTRY(PKCS12_CORRUPT_PFX_STRUCTURE), 00201 _ENTRY(PKCS12_UNSUPPORTED_PBE_ALGORITHM), 00202 _ENTRY(PKCS12_UNSUPPORTED_VERSION), 00203 _ENTRY(PKCS12_PRIVACY_PASSWORD_INCORRECT), 00204 _ENTRY(PKCS12_CERT_COLLISION), 00205 _ENTRY(USER_CANCELLED), 00206 _ENTRY(PKCS12_DUPLICATE_DATA), 00207 _ENTRY(MESSAGE_SEND_ABORTED), 00208 _ENTRY(INADEQUATE_KEY_USAGE), 00209 _ENTRY(INADEQUATE_CERT_TYPE), 00210 _ENTRY(CERT_ADDR_MISMATCH), 00211 _ENTRY(PKCS12_UNABLE_TO_IMPORT_KEY), 00212 _ENTRY(PKCS12_IMPORTING_CERT_CHAIN), 00213 _ENTRY(PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME), 00214 _ENTRY(PKCS12_UNABLE_TO_EXPORT_KEY), 00215 _ENTRY(PKCS12_UNABLE_TO_WRITE), 00216 _ENTRY(PKCS12_UNABLE_TO_READ), 00217 _ENTRY(PKCS12_KEY_DATABASE_NOT_INITIALIZED), 00218 _ENTRY(KEYGEN_FAIL), 00219 _ENTRY(INVALID_PASSWORD), 00220 _ENTRY(RETRY_OLD_PASSWORD), 00221 _ENTRY(BAD_NICKNAME), 00222 _ENTRY(NOT_FORTEZZA_ISSUER), 00223 _ENTRY(CANNOT_MOVE_SENSITIVE_KEY), 00224 _ENTRY(JS_INVALID_MODULE_NAME), 00225 _ENTRY(JS_INVALID_DLL), 00226 _ENTRY(JS_ADD_MOD_FAILURE), 00227 _ENTRY(JS_DEL_MOD_FAILURE), 00228 _ENTRY(OLD_KRL), 00229 _ENTRY(CKL_CONFLICT), 00230 _ENTRY(CERT_NOT_IN_NAME_SPACE), 00231 _ENTRY(KRL_NOT_YET_VALID), 00232 _ENTRY(CRL_NOT_YET_VALID), 00233 _ENTRY(UNKNOWN_CERT), 00234 _ENTRY(UNKNOWN_SIGNER), 00235 _ENTRY(CERT_BAD_ACCESS_LOCATION), 00236 _ENTRY(OCSP_UNKNOWN_RESPONSE_TYPE), 00237 _ENTRY(OCSP_BAD_HTTP_RESPONSE), 00238 _ENTRY(OCSP_MALFORMED_REQUEST), 00239 _ENTRY(OCSP_SERVER_ERROR), 00240 _ENTRY(OCSP_TRY_SERVER_LATER), 00241 _ENTRY(OCSP_REQUEST_NEEDS_SIG), 00242 _ENTRY(OCSP_UNAUTHORIZED_REQUEST), 00243 _ENTRY(OCSP_UNKNOWN_RESPONSE_STATUS), 00244 _ENTRY(OCSP_UNKNOWN_CERT), 00245 _ENTRY(OCSP_NOT_ENABLED), 00246 _ENTRY(OCSP_NO_DEFAULT_RESPONDER), 00247 _ENTRY(OCSP_MALFORMED_RESPONSE), 00248 _ENTRY(OCSP_UNAUTHORIZED_RESPONSE), 00249 _ENTRY(OCSP_FUTURE_RESPONSE), 00250 _ENTRY(OCSP_OLD_RESPONSE), 00251 /* smime stuff */ 00252 _ENTRY(DIGEST_NOT_FOUND), 00253 _ENTRY(UNSUPPORTED_MESSAGE_TYPE), 00254 _ENTRY(MODULE_STUCK), 00255 _ENTRY(BAD_TEMPLATE), 00256 _ENTRY(CRL_NOT_FOUND), 00257 _ENTRY(REUSED_ISSUER_AND_SERIAL), 00258 _ENTRY(BUSY), 00259 _ENTRY(EXTRA_INPUT), 00260 /* error codes used by elliptic curve code */ 00261 _ENTRY(UNSUPPORTED_ELLIPTIC_CURVE), 00262 _ENTRY(UNSUPPORTED_EC_POINT_FORM), 00263 _ENTRY(UNRECOGNIZED_OID), 00264 _ENTRY(OCSP_INVALID_SIGNING_CERT), 00265 /* new revocation errors */ 00266 _ENTRY(REVOKED_CERTIFICATE_CRL), 00267 _ENTRY(REVOKED_CERTIFICATE_OCSP), 00268 _ENTRY(CRL_INVALID_VERSION), 00269 _ENTRY(CRL_V1_CRITICAL_EXTENSION), 00270 _ENTRY(CRL_UNKNOWN_CRITICAL_EXTENSION), 00271 _ENTRY(UNKNOWN_OBJECT_TYPE), 00272 _ENTRY(INCOMPATIBLE_PKCS11), 00273 _ENTRY(NO_EVENT), 00274 _ENTRY(CRL_ALREADY_EXISTS), 00275 _ENTRY(NOT_INITIALIZED), 00276 _ENTRY(TOKEN_NOT_LOGGED_IN), 00277 _ENTRY(OCSP_RESPONDER_CERT_INVALID), 00278 _ENTRY(OCSP_BAD_SIGNATURE), 00279 _ENTRY(OUT_OF_SEARCH_LIMITS), 00280 _ENTRY(INVALID_POLICY_MAPPING), 00281 _ENTRY(POLICY_VALIDATION_FAILED), 00282 _ENTRY(UNKNOWN_AIA_LOCATION_TYPE), 00283 _ENTRY(BAD_HTTP_RESPONSE), 00284 _ENTRY(BAD_LDAP_RESPONSE), 00285 _ENTRY(FAILED_TO_ENCODE_DATA), 00286 _ENTRY(BAD_INFO_ACCESS_LOCATION), 00287 _ENTRY(LIBPKIX_INTERNAL), 00288 _ENTRY(PKCS11_GENERAL_ERROR), 00289 _ENTRY(PKCS11_FUNCTION_FAILED), 00290 _ENTRY(PKCS11_DEVICE_ERROR), 00291 #if defined(SEC_ERROR_BAD_INFO_ACCESS_METHOD) 00292 _ENTRY(BAD_INFO_ACCESS_METHOD), 00293 #endif 00294 #if defined(SEC_ERROR_CRL_IMPORT_FAILED) 00295 _ENTRY(CRL_IMPORT_FAILED), 00296 #endif 00297 }; 00298 static size_t nrpmnssERRS = sizeof(rpmnssERRS) / sizeof(rpmnssERRS[0]); 00299 #undef _ENTRY 00300 00301 static const char * rpmnssStrerror(int err) 00302 { 00303 static char buf[64]; 00304 const char * errN = keyVN(rpmnssERRS, nrpmnssERRS, err); 00305 if (errN == NULL) { 00306 snprintf(buf, sizeof(buf), "SEC_ERROR(%d)", err); 00307 errN = buf; 00308 } 00309 return errN; 00310 } 00311 00312 static 00313 int rpmnssErr(rpmnss nss, const char * msg, int rc) 00314 /*@*/ 00315 { 00316 #ifdef REFERENCE 00317 /* XXX Don't spew on expected failures ... */ 00318 if (err && gcry_err_code(err) != gc->badok) 00319 fprintf (stderr, "rpmgc: %s(0x%0x): %s/%s\n", 00320 msg, (unsigned)err, gcry_strsource(err), gcry_strerror(err)); 00321 #endif 00322 if (rc != SECSuccess) { 00323 int err = PORT_GetError(); 00324 fprintf (stderr, "rpmnss: %s rc(%d) err(%d) %s\n", 00325 msg, rc, err, rpmnssStrerror(err)); 00326 } 00327 return rc; 00328 } 00329 00330 static 00331 int rpmnssSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) 00332 /*@modifies dig @*/ 00333 { 00334 rpmnss nss = dig->impl; 00335 int rc; 00336 int xx; 00337 pgpDigParams pubp = pgpGetPubkey(dig); 00338 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00339 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); 00340 00341 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00342 nss->sigalg = SEC_OID_UNKNOWN; 00343 switch (sigp->hash_algo) { 00344 case PGPHASHALGO_MD5: 00345 nss->sigalg = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; 00346 break; 00347 case PGPHASHALGO_SHA1: 00348 nss->sigalg = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 00349 break; 00350 case PGPHASHALGO_RIPEMD160: 00351 break; 00352 case PGPHASHALGO_MD2: 00353 nss->sigalg = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; 00354 break; 00355 case PGPHASHALGO_MD4: 00356 nss->sigalg = SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION; 00357 break; 00358 case PGPHASHALGO_TIGER192: 00359 break; 00360 case PGPHASHALGO_HAVAL_5_160: 00361 break; 00362 case PGPHASHALGO_SHA256: 00363 nss->sigalg = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; 00364 break; 00365 case PGPHASHALGO_SHA384: 00366 nss->sigalg = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; 00367 break; 00368 case PGPHASHALGO_SHA512: 00369 nss->sigalg = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; 00370 break; 00371 case PGPHASHALGO_SHA224: 00372 break; 00373 default: 00374 break; 00375 } 00376 if (nss->sigalg == SEC_OID_UNKNOWN) 00377 return 1; 00378 00379 nss->digest = _free(nss->digest); 00380 nss->digestlen = 0; 00381 xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0); 00382 00383 /* Compare leading 16 bits of digest for quick check. */ 00384 rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16)); 00385 SPEW(0, !rc, dig); 00386 return rc; 00387 } 00388 00389 static 00390 int rpmnssVerifyRSA(pgpDig dig) 00391 /*@*/ 00392 { 00393 rpmnss nss = dig->impl; 00394 int rc; 00395 00396 nss->item.type = siBuffer; 00397 nss->item.data = nss->digest; 00398 nss->item.len = (unsigned) nss->digestlen; 00399 00400 rc = rpmnssErr(nss, "VFY_VerifyDigest", 00401 VFY_VerifyDigest(&nss->item, nss->pub_key, 00402 nss->sig, nss->sigalg, NULL)); 00403 rc = (rc == SECSuccess); 00404 00405 SPEW(0, !rc, dig); 00406 return rc; 00407 } 00408 00409 static int rpmnssSignRSA(pgpDig dig) 00410 { 00411 rpmnss nss = dig->impl; 00412 pgpDigParams sigp = pgpGetSignature(dig); 00413 int rc = 0; /* assume failure. */ 00414 00415 SECOidTag sigalg = SEC_OID_UNKNOWN; 00416 switch (sigp->hash_algo) { 00417 case PGPHASHALGO_MD5: 00418 sigalg = SEC_OID_MD5; 00419 break; 00420 case PGPHASHALGO_SHA1: 00421 sigalg = SEC_OID_SHA1; 00422 break; 00423 case PGPHASHALGO_RIPEMD160: 00424 break; 00425 case PGPHASHALGO_MD2: 00426 sigalg = SEC_OID_MD2; 00427 break; 00428 case PGPHASHALGO_MD4: 00429 sigalg = SEC_OID_MD4; 00430 break; 00431 case PGPHASHALGO_TIGER192: 00432 break; 00433 case PGPHASHALGO_HAVAL_5_160: 00434 break; 00435 case PGPHASHALGO_SHA256: 00436 sigalg = SEC_OID_SHA256; 00437 break; 00438 case PGPHASHALGO_SHA384: 00439 sigalg = SEC_OID_SHA384; 00440 break; 00441 case PGPHASHALGO_SHA512: 00442 sigalg = SEC_OID_SHA512; 00443 break; 00444 case PGPHASHALGO_SHA224: 00445 break; 00446 default: 00447 break; 00448 } 00449 if (sigalg == SEC_OID_UNKNOWN) 00450 goto exit; 00451 00452 nss->item.type = siBuffer; 00453 nss->item.data = nss->digest; 00454 nss->item.len = (unsigned) nss->digestlen; 00455 00456 if (nss->sig != NULL) { 00457 SECITEM_ZfreeItem(nss->sig, PR_TRUE); 00458 nss->sig = NULL; 00459 } 00460 nss->sig = SECITEM_AllocItem(NULL, NULL, 0); 00461 nss->sig->type = siBuffer; 00462 00463 rc = rpmnssErr(nss, "SGN_Digest", 00464 SGN_Digest(nss->sec_key, sigalg, nss->sig, &nss->item)); 00465 rc = (rc == SECSuccess); 00466 00467 exit: 00468 SPEW(!rc, rc, dig); 00469 return rc; 00470 } 00471 00472 static int rpmnssGenerateRSA(pgpDig dig) 00473 { 00474 rpmnss nss = dig->impl; 00475 int rc = 0; /* assume failure */ 00476 00477 if (nss->nbits == 0) nss->nbits = 1024; /* XXX FIXME */ 00478 assert(nss->nbits); 00479 00480 { CK_MECHANISM_TYPE _type = CKM_RSA_PKCS_KEY_PAIR_GEN; 00481 PK11SlotInfo * _slot = PK11_GetBestSlot(_type, NULL); 00482 int _isPerm = PR_FALSE; 00483 int _isSensitive = PR_TRUE; 00484 void * _cx = NULL; 00485 00486 if (_slot) { 00487 static unsigned _pe = 0x10001; /* XXX FIXME: pass in e */ 00488 PK11RSAGenParams rsaparams = 00489 { .keySizeInBits = nss->nbits, .pe = _pe }; 00490 void * params = &rsaparams; 00491 00492 nss->sec_key = PK11_GenerateKeyPair(_slot, _type, params, 00493 &nss->pub_key, _isPerm, _isSensitive, _cx); 00494 00495 PK11_FreeSlot(_slot); 00496 } 00497 } 00498 00499 rc = (nss->sec_key && nss->pub_key); 00500 00501 SPEW(!rc, rc, dig); 00502 return rc; 00503 } 00504 00505 static 00506 int rpmnssSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) 00507 /*@modifies dig @*/ 00508 { 00509 rpmnss nss = dig->impl; 00510 int rc; 00511 int xx; 00512 pgpDigParams pubp = pgpGetPubkey(dig); 00513 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00514 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); 00515 00516 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00517 nss->digest = _free(nss->digest); 00518 nss->digestlen = 0; 00519 xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0); 00520 00521 nss->sigalg = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; 00522 00523 /* Compare leading 16 bits of digest for quick check. */ 00524 rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16)); 00525 SPEW(0, !rc, dig); 00526 return rc; 00527 } 00528 00529 static 00530 int rpmnssVerifyDSA(pgpDig dig) 00531 /*@*/ 00532 { 00533 rpmnss nss = dig->impl; 00534 int rc; 00535 00536 nss->item.type = siBuffer; 00537 nss->item.data = nss->digest; 00538 nss->item.len = (unsigned) nss->digestlen; 00539 00540 rc = rpmnssErr(nss, "VFY_VerifyDigest", 00541 VFY_VerifyDigest(&nss->item, nss->pub_key, 00542 nss->sig, nss->sigalg, NULL)); 00543 rc = (rc == SECSuccess); 00544 00545 SPEW(0, rc, dig); 00546 return rc; 00547 } 00548 00549 static int rpmnssSignDSA(pgpDig dig) 00550 { 00551 rpmnss nss = dig->impl; 00552 pgpDigParams sigp = pgpGetSignature(dig); 00553 int rc = 0; /* assume failure. */ 00554 SECItem sig = { .type = siBuffer, .len = 0, .data = NULL }; 00555 00556 SECOidTag sigalg = SEC_OID_UNKNOWN; 00557 switch (sigp->hash_algo) { 00558 case PGPHASHALGO_MD5: 00559 break; 00560 case PGPHASHALGO_SHA1: 00561 sigalg = SEC_OID_SHA1; 00562 break; 00563 case PGPHASHALGO_RIPEMD160: 00564 break; 00565 case PGPHASHALGO_MD2: 00566 break; 00567 case PGPHASHALGO_MD4: 00568 break; 00569 case PGPHASHALGO_TIGER192: 00570 break; 00571 case PGPHASHALGO_HAVAL_5_160: 00572 break; 00573 case PGPHASHALGO_SHA256: 00574 break; 00575 case PGPHASHALGO_SHA384: 00576 break; 00577 case PGPHASHALGO_SHA512: 00578 break; 00579 case PGPHASHALGO_SHA224: 00580 break; 00581 default: 00582 break; 00583 } 00584 if (sigalg == SEC_OID_UNKNOWN) 00585 goto exit; 00586 00587 nss->item.type = siBuffer; 00588 nss->item.data = nss->digest; 00589 nss->item.len = (unsigned) nss->digestlen; 00590 00591 if (nss->sig != NULL) { 00592 SECITEM_ZfreeItem(nss->sig, PR_TRUE); 00593 nss->sig = NULL; 00594 } 00595 00596 nss->sig = SECITEM_AllocItem(NULL, NULL, 0); 00597 nss->sig->type = siBuffer; 00598 00599 rc = rpmnssErr(nss, "SGN_Digest", 00600 SGN_Digest(nss->sec_key, sigalg, &sig, &nss->item)); 00601 00602 if (rc == SECSuccess) 00603 rc = rpmnssErr(nss, "DSAU_EncodeDerSig", 00604 DSAU_EncodeDerSig(nss->sig, &sig)); 00605 00606 sig.data = _free(sig.data); 00607 00608 rc = (rc == SECSuccess); 00609 00610 exit: 00611 SPEW(!rc, rc, dig); 00612 return rc; 00613 } 00614 00615 static int rpmnssGenerateDSA(pgpDig dig) 00616 { 00617 rpmnss nss = dig->impl; 00618 int rc = 0; /* assume failure */ 00619 00620 if (nss->nbits == 0) nss->nbits = 1024; /* XXX FIXME */ 00621 assert(nss->nbits); 00622 00623 { CK_MECHANISM_TYPE _type = CKM_DSA_KEY_PAIR_GEN; 00624 PK11SlotInfo * _slot = PK11_GetBestSlot(_type, NULL); 00625 int _isPerm = PR_FALSE; 00626 int _isSensitive = PR_TRUE; 00627 void * _cx = NULL; 00628 00629 if (_slot) { 00630 PQGParams *pqgParams = NULL; 00631 PQGVerify *pqgVfy = NULL; 00632 void * params = NULL; 00633 int xx; 00634 00635 xx = rpmnssErr(nss, "PK11_PQG_ParamGen", 00636 PK11_PQG_ParamGen(0, &pqgParams, &pqgVfy)); 00637 if (xx != SECSuccess) 00638 goto exit; 00639 params = pqgParams; 00640 00641 nss->sec_key = PK11_GenerateKeyPair(_slot, _type, params, 00642 &nss->pub_key, _isPerm, _isSensitive, _cx); 00643 00644 if (pqgVfy) PK11_PQG_DestroyVerify(pqgVfy); 00645 if (pqgParams) PK11_PQG_DestroyParams(pqgParams); 00646 00647 PK11_FreeSlot(_slot); 00648 } 00649 } 00650 00651 rc = (nss->sec_key && nss->pub_key); 00652 00653 exit: 00654 SPEW(!rc, rc, dig); 00655 return rc; 00656 } 00657 00658 static 00659 int rpmnssSetELG(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp) 00660 /*@*/ 00661 { 00662 rpmnss nss = dig->impl; 00663 int rc = 1; /* XXX always fail. */ 00664 int xx; 00665 00666 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00667 nss->digest = _free(nss->digest); 00668 nss->digestlen = 0; 00669 xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0); 00670 00671 /* Compare leading 16 bits of digest for quick check. */ 00672 00673 return rc; 00674 } 00675 00676 static 00677 int rpmnssSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp) 00678 /*@*/ 00679 { 00680 rpmnss nss = dig->impl; 00681 int xx; 00682 00683 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00684 nss->sigalg = SEC_OID_UNKNOWN; 00685 switch (sigp->hash_algo) { 00686 case PGPHASHALGO_SHA1: 00687 nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; 00688 break; 00689 case PGPHASHALGO_SHA224: 00690 nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE; 00691 break; 00692 case PGPHASHALGO_SHA256: 00693 nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; 00694 break; 00695 case PGPHASHALGO_SHA384: 00696 nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; 00697 break; 00698 case PGPHASHALGO_SHA512: 00699 nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE; 00700 break; 00701 default: 00702 break; 00703 } 00704 if (nss->sigalg == SEC_OID_UNKNOWN) 00705 return 1; 00706 00707 nss->digest = _free(nss->digest); 00708 nss->digestlen = 0; 00709 xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0); 00710 00711 /* Compare leading 16 bits of digest for quick check. */ 00712 return memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16)); 00713 } 00714 00715 static 00716 int rpmnssVerifyECDSA(/*@unused@*/pgpDig dig) 00717 /*@*/ 00718 { 00719 rpmnss nss = dig->impl; 00720 int rc; 00721 00722 nss->item.type = siBuffer; 00723 nss->item.data = nss->digest; 00724 nss->item.len = (unsigned) nss->digestlen; 00725 00726 rc = VFY_VerifyDigest(&nss->item, nss->pub_key, nss->sig, nss->sigalg, NULL); 00727 rc = (rc == SECSuccess); 00728 00729 SPEW(!rc, rc, dig); 00730 return rc; 00731 } 00732 00733 static 00734 int rpmnssSignECDSA(/*@unused@*/pgpDig dig) 00735 /*@*/ 00736 { 00737 rpmnss nss = dig->impl; 00738 pgpDigParams sigp = pgpGetSignature(dig); 00739 int rc = 0; /* assume failure. */ 00740 00741 SECOidTag sigalg = SEC_OID_UNKNOWN; 00742 switch (sigp->hash_algo) { 00743 case PGPHASHALGO_MD5: 00744 break; 00745 case PGPHASHALGO_SHA1: 00746 sigalg = SEC_OID_SHA1; 00747 break; 00748 case PGPHASHALGO_RIPEMD160: 00749 break; 00750 case PGPHASHALGO_MD2: 00751 break; 00752 case PGPHASHALGO_MD4: 00753 break; 00754 case PGPHASHALGO_TIGER192: 00755 break; 00756 case PGPHASHALGO_HAVAL_5_160: 00757 break; 00758 case PGPHASHALGO_SHA256: 00759 sigalg = SEC_OID_SHA256; 00760 break; 00761 case PGPHASHALGO_SHA384: 00762 sigalg = SEC_OID_SHA384; 00763 break; 00764 case PGPHASHALGO_SHA512: 00765 sigalg = SEC_OID_SHA512; 00766 break; 00767 case PGPHASHALGO_SHA224: 00768 break; 00769 default: 00770 break; 00771 } 00772 if (sigalg == SEC_OID_UNKNOWN) 00773 goto exit; 00774 00775 if (nss->sig != NULL) { 00776 SECITEM_ZfreeItem(nss->sig, PR_TRUE); 00777 nss->sig = NULL; 00778 } 00779 nss->sig = SECITEM_AllocItem(NULL, NULL, 0); 00780 nss->sig->type = siBuffer; 00781 00782 rc = rpmnssErr(nss, "SGN_Digest", 00783 SGN_Digest(nss->sec_key, sigalg, nss->sig, &nss->item)); 00784 00785 rc = (rc == SECSuccess); 00786 00787 exit: 00788 SPEW(!rc, rc, dig); 00789 return rc; 00790 } 00791 00792 static 00793 int rpmnssGenerateECDSA(/*@unused@*/pgpDig dig) 00794 /*@*/ 00795 { 00796 rpmnss nss = dig->impl; 00797 int rc = 0; /* assume failure. */ 00798 00799 { CK_MECHANISM_TYPE _type = CKM_EC_KEY_PAIR_GEN; 00800 PK11SlotInfo * _slot = PK11_GetBestSlot(_type, NULL); 00801 int _isPerm = PR_FALSE; 00802 int _isSensitive = PR_FALSE; 00803 void * _cx = NULL; 00804 00805 if (_slot) { 00806 00807 nss->sec_key = PK11_GenerateKeyPair(_slot, _type, nss->ecparams, 00808 &nss->pub_key, _isPerm, _isSensitive, _cx); 00809 00810 PK11_FreeSlot(_slot); 00811 } 00812 } 00813 00814 rc = (nss->sec_key && nss->pub_key); 00815 00816 SPEW(!rc, rc, dig); 00817 00818 return rc; 00819 } 00820 00821 static int rpmnssErrChk(pgpDig dig, const char * msg, int rc, unsigned expected) 00822 { 00823 #ifdef NOTYET 00824 rpmgc gc = dig->impl; 00825 /* Was the return code the expected result? */ 00826 rc = (gcry_err_code(gc->err) != expected); 00827 if (rc) 00828 fail("%s failed: %s\n", msg, gpg_strerror(gc->err)); 00829 /* XXX FIXME: rpmnssStrerror */ 00830 #else 00831 rc = (rc == 0); /* XXX impedance match 1 -> 0 on success */ 00832 #endif 00833 return rc; /* XXX 0 on success */ 00834 } 00835 00836 static int rpmnssAvailableCipher(pgpDig dig, int algo) 00837 { 00838 int rc = 0; /* assume available */ 00839 #ifdef NOTYET 00840 rc = rpmgnssvailable(dig->impl, algo, 00841 (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5)); 00842 #endif 00843 return rc; 00844 } 00845 00846 static int rpmnssAvailableDigest(pgpDig dig, int algo) 00847 { 00848 int rc = 0; /* assume available */ 00849 #ifdef NOTYET 00850 rc = rpmgnssvailable(dig->impl, algo, 00851 (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5)); 00852 #endif 00853 return rc; 00854 } 00855 00856 static int rpmnssAvailablePubkey(pgpDig dig, int algo) 00857 { 00858 int rc = 0; /* assume available */ 00859 #ifdef NOTYET 00860 rc = rpmnssAvailable(dig->impl, algo, gcry_pk_test_algo(algo)); 00861 #endif 00862 return rc; 00863 } 00864 00865 static int rpmnssVerify(pgpDig dig) 00866 { 00867 rpmnss nss = dig->impl; 00868 int rc = 0; /* assume failure */ 00869 pgpDigParams pubp = pgpGetPubkey(dig); 00870 pgpDigParams sigp = pgpGetSignature(dig); 00871 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00872 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); 00873 00874 switch (pubp->pubkey_algo) { 00875 default: 00876 break; 00877 case PGPPUBKEYALGO_RSA: 00878 rc = rpmnssVerifyRSA(dig); 00879 break; 00880 case PGPPUBKEYALGO_DSA: 00881 rc = rpmnssVerifyDSA(dig); 00882 break; 00883 case PGPPUBKEYALGO_ELGAMAL: 00884 #ifdef NOTYET 00885 rc = rpmnssVerifyELG(dig); 00886 #endif 00887 break; 00888 case PGPPUBKEYALGO_ECDSA: 00889 if (nss->sigalg != SEC_OID_UNKNOWN) 00890 rc = rpmnssVerifyECDSA(dig); 00891 break; 00892 } 00893 SPEW(0, rc, dig); 00894 return rc; 00895 } 00896 00897 static int rpmnssSign(pgpDig dig) 00898 { 00899 rpmnss nss = dig->impl; 00900 int rc = 0; /* assume failure */ 00901 pgpDigParams pubp = pgpGetPubkey(dig); 00902 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00903 switch (pubp->pubkey_algo) { 00904 default: 00905 break; 00906 case PGPPUBKEYALGO_RSA: 00907 rc = rpmnssSignRSA(dig); 00908 break; 00909 case PGPPUBKEYALGO_DSA: 00910 rc = rpmnssSignDSA(dig); 00911 break; 00912 case PGPPUBKEYALGO_ELGAMAL: 00913 #ifdef NOTYET 00914 rc = rpmnssSignELG(dig); 00915 #endif 00916 break; 00917 case PGPPUBKEYALGO_ECDSA: 00918 if (nss->sigalg != SEC_OID_UNKNOWN) 00919 rc = rpmnssSignECDSA(dig); 00920 break; 00921 } 00922 SPEW(!rc, rc, dig); 00923 return rc; 00924 } 00925 00926 static int rpmnssLoadParams(pgpDig dig, const char * name) 00927 { 00928 rpmnss nss = dig->impl; 00929 #ifdef NOTYET 00930 SECOidTag curveOidTag = curve2oid(name); 00931 #else 00932 SECOidTag curveOidTag = !strcmp(name, "nistp256") 00933 ? SEC_OID_SECG_EC_SECP256R1 : SEC_OID_UNKNOWN; 00934 #endif 00935 SECOidData * oidData = SECOID_FindOIDByTag(curveOidTag); 00936 int rc = 1; /* assume failure. */ 00937 00938 if (curveOidTag == SEC_OID_UNKNOWN || oidData == NULL) { 00939 nss->sigalg = curveOidTag; 00940 goto exit; 00941 } 00942 00943 nss->sigalg = curveOidTag; 00944 00945 nss->ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len)); 00946 nss->ecparams->data[0] = SEC_ASN1_OBJECT_ID; 00947 nss->ecparams->data[1] = oidData->oid.len; 00948 memcpy(nss->ecparams->data + 2, oidData->oid.data, oidData->oid.len); 00949 rc = 0; 00950 00951 exit: 00952 if (1 || _pgp_debug) 00953 fprintf(stderr, "<-- %s(%p,%s) oid %u params %p\n", __FUNCTION__, dig, name, nss->sigalg, nss->ecparams); 00954 return rc; 00955 } 00956 00957 static int rpmnssGenerate(pgpDig dig) 00958 { 00959 int rc = 0; /* assume failure */ 00960 pgpDigParams pubp = pgpGetPubkey(dig); 00961 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00962 00963 switch (pubp->pubkey_algo) { 00964 default: 00965 break; 00966 case PGPPUBKEYALGO_RSA: 00967 rc = rpmnssGenerateRSA(dig); 00968 break; 00969 case PGPPUBKEYALGO_DSA: 00970 rc = rpmnssGenerateDSA(dig); 00971 break; 00972 case PGPPUBKEYALGO_ELGAMAL: 00973 #ifdef NOTYET 00974 rc = rpmnssGenerateELG(dig); 00975 #endif 00976 break; 00977 case PGPPUBKEYALGO_ECDSA: 00978 rc = rpmnssLoadParams(dig, "nistp256"); 00979 if (!rc) 00980 rc = rpmnssGenerateECDSA(dig); 00981 break; 00982 } 00983 SPEW(!rc, rc, dig); 00984 return rc; 00985 } 00986 00990 static 00991 int rpmnssMpiSet(const char * pre, unsigned int lbits, 00992 /*@out@*/ void * dest, const rpmuint8_t * p, 00993 /*@null@*/ const rpmuint8_t * pend) 00994 /*@modifies *dest @*/ 00995 { 00996 unsigned int mbits = pgpMpiBits(p); 00997 unsigned int nbits; 00998 unsigned int nbytes; 00999 char * t = dest; 01000 unsigned int ix; 01001 01002 if (pend != NULL && (p + ((mbits+7) >> 3)) > pend) 01003 return 1; 01004 01005 if (mbits > lbits) 01006 return 1; 01007 01008 nbits = (lbits > mbits ? lbits : mbits); 01009 nbytes = ((nbits + 7) >> 3); 01010 ix = ((nbits - mbits) >> 3); 01011 01012 /*@-modfilesystem @*/ 01013 if (_pgp_debug) 01014 fprintf(stderr, "*** mbits %u nbits %u nbytes %u ix %u\n", mbits, nbits, nbytes, ix); 01015 if (ix > 0) memset(t, (int)'\0', ix); 01016 memcpy(t+ix, p+2, nbytes-ix); 01017 if (_pgp_debug && _pgp_print) 01018 fprintf(stderr, "\t %s %s\n", pre, pgpHexStr(dest, nbytes)); 01019 /*@=modfilesystem @*/ 01020 return 0; 01021 } 01022 01026 static 01027 /*@only@*/ /*@null@*/ 01028 SECItem * rpmnssMpiCopy(PRArenaPool * arena, /*@returned@*/ SECItem * item, 01029 const rpmuint8_t * p) 01030 /*@modifies item @*/ 01031 { 01032 unsigned int nbytes = pgpMpiLen(p)-2; 01033 01034 /*@-moduncon@*/ 01035 if (item == NULL) { 01036 if ((item = SECITEM_AllocItem(arena, item, nbytes)) == NULL) 01037 return item; 01038 } else { 01039 if (arena != NULL) 01040 item->data = PORT_ArenaGrow(arena, item->data, item->len, nbytes); 01041 else 01042 item->data = PORT_Realloc(item->data, nbytes); 01043 01044 if (item->data == NULL) { 01045 if (arena == NULL) 01046 SECITEM_FreeItem(item, PR_TRUE); 01047 return NULL; 01048 } 01049 } 01050 /*@=moduncon@*/ 01051 01052 memcpy(item->data, p+2, nbytes); 01053 item->len = nbytes; 01054 /*@-temptrans@*/ 01055 return item; 01056 /*@=temptrans@*/ 01057 } 01058 01059 static /*@null@*/ 01060 SECKEYPublicKey * rpmnssNewPublicKey(KeyType type) 01061 /*@*/ 01062 { 01063 PRArenaPool *arena; 01064 SECKEYPublicKey *key; 01065 01066 /*@-moduncon@*/ 01067 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 01068 if (arena == NULL) 01069 return NULL; 01070 01071 key = PORT_ArenaZAlloc(arena, sizeof(*key)); 01072 01073 if (key == NULL) { 01074 PORT_FreeArena(arena, PR_FALSE); 01075 return NULL; 01076 } 01077 /*@=moduncon@*/ 01078 01079 key->keyType = type; 01080 key->pkcs11ID = CK_INVALID_HANDLE; 01081 key->pkcs11Slot = NULL; 01082 key->arena = arena; 01083 /*@-nullret@*/ /* key->pkcs11Slot can be NULL */ 01084 return key; 01085 /*@=nullret@*/ 01086 } 01087 01088 static 01089 int rpmnssMpiItem(const char * pre, pgpDig dig, int itemno, 01090 const rpmuint8_t * p, /*@null@*/ const rpmuint8_t * pend) 01091 /*@*/ 01092 { 01093 rpmnss nss = dig->impl; 01094 unsigned int hbits; 01095 size_t nb = (pend >= p ? (pend - p) : 0); 01096 int rc = 0; 01097 01098 /*@-moduncon@*/ 01099 switch (itemno) { 01100 default: 01101 assert(0); 01102 break; 01103 case 10: /* RSA m**d */ 01104 nss->sig = rpmnssMpiCopy(NULL, nss->sig, p); 01105 if (nss->sig == NULL) 01106 rc = 1; 01107 break; 01108 case 20: /* DSA r */ 01109 hbits = 160; 01110 nss->item.type = 0; 01111 nss->item.len = 2 * (hbits/8); 01112 nss->item.data = xcalloc(1, nss->item.len); 01113 rc = rpmnssMpiSet(pre, hbits, nss->item.data, p, pend); 01114 break; 01115 case 21: /* DSA s */ 01116 hbits = 160; 01117 rc = rpmnssMpiSet(pre, hbits, nss->item.data + (hbits/8), p, pend); 01118 if (nss->sig != NULL) 01119 SECITEM_FreeItem(nss->sig, PR_FALSE); 01120 if ((nss->sig = SECITEM_AllocItem(NULL, NULL, 0)) == NULL 01121 || DSAU_EncodeDerSig(nss->sig, &nss->item) != SECSuccess) 01122 rc = 1; 01123 nss->item.data = _free(nss->item.data); 01124 break; 01125 case 30: /* RSA n */ 01126 if (nss->pub_key == NULL) 01127 nss->pub_key = rpmnssNewPublicKey(rsaKey); 01128 if (nss->pub_key == NULL) 01129 rc = 1; 01130 else 01131 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.rsa.modulus, p); 01132 break; 01133 case 31: /* RSA e */ 01134 if (nss->pub_key == NULL) 01135 nss->pub_key = rpmnssNewPublicKey(rsaKey); 01136 if (nss->pub_key == NULL) 01137 rc = 1; 01138 else 01139 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.rsa.publicExponent, p); 01140 break; 01141 case 40: /* DSA p */ 01142 if (nss->pub_key == NULL) 01143 nss->pub_key = rpmnssNewPublicKey(dsaKey); 01144 if (nss->pub_key == NULL) 01145 rc = 1; 01146 else 01147 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.prime, p); 01148 break; 01149 case 41: /* DSA q */ 01150 if (nss->pub_key == NULL) 01151 nss->pub_key = rpmnssNewPublicKey(dsaKey); 01152 if (nss->pub_key == NULL) 01153 rc = 1; 01154 else 01155 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.subPrime, p); 01156 break; 01157 case 42: /* DSA g */ 01158 if (nss->pub_key == NULL) 01159 nss->pub_key = rpmnssNewPublicKey(dsaKey); 01160 if (nss->pub_key == NULL) 01161 rc = 1; 01162 else 01163 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.base, p); 01164 break; 01165 case 43: /* DSA y */ 01166 if (nss->pub_key == NULL) 01167 nss->pub_key = rpmnssNewPublicKey(dsaKey); 01168 if (nss->pub_key == NULL) 01169 rc = 1; 01170 else 01171 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.publicValue, p); 01172 break; 01173 case 50: /* ECDSA r */ 01174 hbits = 256; 01175 nss->item.type = 0; 01176 nss->item.len = 2 * (hbits/8); 01177 nss->item.data = xcalloc(1, nss->item.len); 01178 rc = rpmnssMpiSet(pre, hbits, nss->item.data, p, pend); 01179 break; 01180 case 51: /* ECDSA s */ 01181 hbits = 256; 01182 rc = rpmnssMpiSet(pre, hbits, nss->item.data + (hbits/8), p, pend); 01183 if (nss->sig != NULL) 01184 SECITEM_FreeItem(nss->sig, PR_FALSE); 01185 if ((nss->sig = SECITEM_AllocItem(NULL, NULL, 0)) == NULL 01186 || DSAU_EncodeDerSigWithLen(nss->sig, &nss->item, nss->item.len) != SECSuccess) 01187 rc = 1; 01188 nss->item.data = _free(nss->item.data); 01189 break; 01190 case 60: /* ECDSA curve OID */ 01191 assert(pend > p); 01192 if (nss->pub_key == NULL) 01193 nss->pub_key = rpmnssNewPublicKey(ecKey); 01194 if (nss->pub_key == NULL) 01195 rc = 1; 01196 else { 01197 SECKEYECParams * ecp = &nss->pub_key->u.ec.DEREncodedParams; 01198 ecp->data = PORT_ArenaZAlloc(nss->pub_key->arena, nb + 2); 01199 ecp->data[0] = SEC_ASN1_OBJECT_ID; 01200 ecp->data[1] = nb; 01201 memcpy(ecp->data + 2, p, nb); 01202 ecp->len = nb + 2; 01203 } 01204 break; 01205 case 61: /* ECDSA Q */ 01206 assert(nss->pub_key); 01207 /* XXX assumes uncompressed Q as a MPI */ 01208 nss->pub_key->u.ec.size = ((nb - (2 + 1)) * 8)/2; 01209 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.ec.publicValue, p); 01210 break; 01211 } 01212 /*@=moduncon@*/ 01213 return rc; 01214 } 01215 01216 /*@-mustmod@*/ 01217 static 01218 void rpmnssClean(void * impl) 01219 /*@modifies impl @*/ 01220 { 01221 rpmnss nss = impl; 01222 /*@-moduncon@*/ 01223 if (nss != NULL) { 01224 nss->nbits = 0; 01225 nss->err = 0; 01226 nss->badok = 0; 01227 nss->digest = _free(nss->digest); 01228 nss->digestlen = 0; 01229 01230 if (nss->sec_key != NULL) { 01231 SECKEY_DestroyPrivateKey(nss->sec_key); 01232 nss->sec_key = NULL; 01233 } 01234 if (nss->pub_key != NULL) { 01235 SECKEY_DestroyPublicKey(nss->pub_key); 01236 nss->pub_key = NULL; 01237 } 01238 if (nss->sig != NULL) { 01239 SECITEM_ZfreeItem(nss->sig, PR_TRUE); 01240 nss->sig = NULL; 01241 } 01242 01243 if (nss->ecparams != NULL) { 01244 SECITEM_FreeItem(nss->ecparams, PR_FALSE); 01245 nss->ecparams = NULL; 01246 } 01247 /*@=moduncon@*/ 01248 } 01249 } 01250 /*@=mustmod@*/ 01251 01252 static /*@null@*/ 01253 void * rpmnssFree(/*@only@*/ void * impl) 01254 /*@*/ 01255 { 01256 rpmnssClean(impl); 01257 impl = _free(impl); 01258 return NULL; 01259 } 01260 01261 static 01262 void * rpmnssInit(void) 01263 /*@globals _rpmnss_init @*/ 01264 /*@modifies _rpmnss_init @*/ 01265 { 01266 rpmnss nss = xcalloc(1, sizeof(*nss)); 01267 const char * _nssdb_path = rpmExpand("%{?_nssdb_path}", NULL); 01268 01269 /*@-moduncon@*/ 01270 if (_nssdb_path != NULL && *_nssdb_path == '/') 01271 (void) NSS_Init(_nssdb_path); 01272 else 01273 (void) NSS_NoDB_Init(NULL); 01274 /*@=moduncon@*/ 01275 _nssdb_path = _free(_nssdb_path); 01276 01277 _rpmnss_init = 1; 01278 01279 return (void *) nss; 01280 } 01281 01282 struct pgpImplVecs_s rpmnssImplVecs = { 01283 rpmnssSetRSA, 01284 rpmnssSetDSA, 01285 rpmnssSetELG, 01286 rpmnssSetECDSA, 01287 01288 rpmnssErrChk, 01289 rpmnssAvailableCipher, rpmnssAvailableDigest, rpmnssAvailablePubkey, 01290 rpmnssVerify, rpmnssSign, rpmnssGenerate, 01291 01292 rpmnssMpiItem, rpmnssClean, 01293 rpmnssFree, rpmnssInit 01294 }; 01295 01296 #endif 01297