|
rpm
5.4.4
|
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 = 1; /* assume error */ 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 goto exit; 00378 00379 nss->digest = _free(nss->digest); 00380 nss->digestlen = 0; 00381 xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0); 00382 ctx = NULL; /* XXX avoid double free */ 00383 00384 /* Compare leading 16 bits of digest for quick check. */ 00385 rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16)); 00386 00387 exit: 00388 if (ctx) { /* XXX Free the context on error returns. */ 00389 xx = rpmDigestFinal(ctx, NULL, NULL, 0); 00390 ctx = NULL; 00391 } 00392 SPEW(0, !rc, dig); 00393 return rc; 00394 } 00395 00396 static 00397 int rpmnssVerifyRSA(pgpDig dig) 00398 /*@*/ 00399 { 00400 rpmnss nss = dig->impl; 00401 int rc; 00402 00403 nss->item.type = siBuffer; 00404 nss->item.data = nss->digest; 00405 nss->item.len = (unsigned) nss->digestlen; 00406 00407 rc = rpmnssErr(nss, "VFY_VerifyDigest", 00408 VFY_VerifyDigest(&nss->item, nss->pub_key, 00409 nss->sig, nss->sigalg, NULL)); 00410 rc = (rc == SECSuccess); 00411 00412 SPEW(0, !rc, dig); 00413 return rc; 00414 } 00415 00416 static int rpmnssSignRSA(pgpDig dig) 00417 { 00418 rpmnss nss = dig->impl; 00419 pgpDigParams sigp = pgpGetSignature(dig); 00420 int rc = 0; /* assume failure. */ 00421 00422 SECOidTag sigalg = SEC_OID_UNKNOWN; 00423 switch (sigp->hash_algo) { 00424 case PGPHASHALGO_MD5: 00425 sigalg = SEC_OID_MD5; 00426 break; 00427 case PGPHASHALGO_SHA1: 00428 sigalg = SEC_OID_SHA1; 00429 break; 00430 case PGPHASHALGO_RIPEMD160: 00431 break; 00432 case PGPHASHALGO_MD2: 00433 sigalg = SEC_OID_MD2; 00434 break; 00435 case PGPHASHALGO_MD4: 00436 sigalg = SEC_OID_MD4; 00437 break; 00438 case PGPHASHALGO_TIGER192: 00439 break; 00440 case PGPHASHALGO_HAVAL_5_160: 00441 break; 00442 case PGPHASHALGO_SHA256: 00443 sigalg = SEC_OID_SHA256; 00444 break; 00445 case PGPHASHALGO_SHA384: 00446 sigalg = SEC_OID_SHA384; 00447 break; 00448 case PGPHASHALGO_SHA512: 00449 sigalg = SEC_OID_SHA512; 00450 break; 00451 case PGPHASHALGO_SHA224: 00452 break; 00453 default: 00454 break; 00455 } 00456 if (sigalg == SEC_OID_UNKNOWN) 00457 goto exit; 00458 00459 nss->item.type = siBuffer; 00460 nss->item.data = nss->digest; 00461 nss->item.len = (unsigned) nss->digestlen; 00462 00463 if (nss->sig != NULL) { 00464 SECITEM_ZfreeItem(nss->sig, PR_TRUE); 00465 nss->sig = NULL; 00466 } 00467 nss->sig = SECITEM_AllocItem(NULL, NULL, 0); 00468 nss->sig->type = siBuffer; 00469 00470 rc = rpmnssErr(nss, "SGN_Digest", 00471 SGN_Digest(nss->sec_key, sigalg, nss->sig, &nss->item)); 00472 rc = (rc == SECSuccess); 00473 00474 exit: 00475 SPEW(!rc, rc, dig); 00476 return rc; 00477 } 00478 00479 static int rpmnssGenerateRSA(pgpDig dig) 00480 { 00481 rpmnss nss = dig->impl; 00482 int rc = 0; /* assume failure */ 00483 00484 if (nss->nbits == 0) nss->nbits = 1024; /* XXX FIXME */ 00485 assert(nss->nbits); 00486 00487 { CK_MECHANISM_TYPE _type = CKM_RSA_PKCS_KEY_PAIR_GEN; 00488 PK11SlotInfo * _slot = PK11_GetBestSlot(_type, NULL); 00489 int _isPerm = PR_FALSE; 00490 int _isSensitive = PR_TRUE; 00491 void * _cx = NULL; 00492 00493 if (_slot) { 00494 static unsigned _pe = 0x10001; /* XXX FIXME: pass in e */ 00495 PK11RSAGenParams rsaparams = 00496 { .keySizeInBits = nss->nbits, .pe = _pe }; 00497 void * params = &rsaparams; 00498 00499 nss->sec_key = PK11_GenerateKeyPair(_slot, _type, params, 00500 &nss->pub_key, _isPerm, _isSensitive, _cx); 00501 00502 PK11_FreeSlot(_slot); 00503 } 00504 } 00505 00506 rc = (nss->sec_key && nss->pub_key); 00507 00508 SPEW(!rc, rc, dig); 00509 return rc; 00510 } 00511 00512 static 00513 int rpmnssSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) 00514 /*@modifies dig @*/ 00515 { 00516 rpmnss nss = dig->impl; 00517 int rc; 00518 int xx; 00519 pgpDigParams pubp = pgpGetPubkey(dig); 00520 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00521 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); 00522 00523 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00524 nss->digest = _free(nss->digest); 00525 nss->digestlen = 0; 00526 xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0); 00527 00528 nss->sigalg = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; 00529 00530 /* Compare leading 16 bits of digest for quick check. */ 00531 rc = memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16)); 00532 SPEW(0, !rc, dig); 00533 return rc; 00534 } 00535 00536 static 00537 int rpmnssVerifyDSA(pgpDig dig) 00538 /*@*/ 00539 { 00540 rpmnss nss = dig->impl; 00541 int rc; 00542 00543 nss->item.type = siBuffer; 00544 nss->item.data = nss->digest; 00545 nss->item.len = (unsigned) nss->digestlen; 00546 00547 rc = rpmnssErr(nss, "VFY_VerifyDigest", 00548 VFY_VerifyDigest(&nss->item, nss->pub_key, 00549 nss->sig, nss->sigalg, NULL)); 00550 rc = (rc == SECSuccess); 00551 00552 SPEW(0, rc, dig); 00553 return rc; 00554 } 00555 00556 static int rpmnssSignDSA(pgpDig dig) 00557 { 00558 rpmnss nss = dig->impl; 00559 pgpDigParams sigp = pgpGetSignature(dig); 00560 int rc = 0; /* assume failure. */ 00561 SECItem sig = { .type = siBuffer, .len = 0, .data = NULL }; 00562 00563 SECOidTag sigalg = SEC_OID_UNKNOWN; 00564 switch (sigp->hash_algo) { 00565 case PGPHASHALGO_MD5: 00566 break; 00567 case PGPHASHALGO_SHA1: 00568 sigalg = SEC_OID_SHA1; 00569 break; 00570 case PGPHASHALGO_RIPEMD160: 00571 break; 00572 case PGPHASHALGO_MD2: 00573 break; 00574 case PGPHASHALGO_MD4: 00575 break; 00576 case PGPHASHALGO_TIGER192: 00577 break; 00578 case PGPHASHALGO_HAVAL_5_160: 00579 break; 00580 case PGPHASHALGO_SHA256: 00581 break; 00582 case PGPHASHALGO_SHA384: 00583 break; 00584 case PGPHASHALGO_SHA512: 00585 break; 00586 case PGPHASHALGO_SHA224: 00587 break; 00588 default: 00589 break; 00590 } 00591 if (sigalg == SEC_OID_UNKNOWN) 00592 goto exit; 00593 00594 nss->item.type = siBuffer; 00595 nss->item.data = nss->digest; 00596 nss->item.len = (unsigned) nss->digestlen; 00597 00598 if (nss->sig != NULL) { 00599 SECITEM_ZfreeItem(nss->sig, PR_TRUE); 00600 nss->sig = NULL; 00601 } 00602 00603 nss->sig = SECITEM_AllocItem(NULL, NULL, 0); 00604 nss->sig->type = siBuffer; 00605 00606 rc = rpmnssErr(nss, "SGN_Digest", 00607 SGN_Digest(nss->sec_key, sigalg, &sig, &nss->item)); 00608 00609 if (rc == SECSuccess) 00610 rc = rpmnssErr(nss, "DSAU_EncodeDerSig", 00611 DSAU_EncodeDerSig(nss->sig, &sig)); 00612 00613 sig.data = _free(sig.data); 00614 00615 rc = (rc == SECSuccess); 00616 00617 exit: 00618 SPEW(!rc, rc, dig); 00619 return rc; 00620 } 00621 00622 static int rpmnssGenerateDSA(pgpDig dig) 00623 { 00624 rpmnss nss = dig->impl; 00625 int rc = 0; /* assume failure */ 00626 00627 if (nss->nbits == 0) nss->nbits = 1024; /* XXX FIXME */ 00628 assert(nss->nbits); 00629 00630 { CK_MECHANISM_TYPE _type = CKM_DSA_KEY_PAIR_GEN; 00631 PK11SlotInfo * _slot = PK11_GetBestSlot(_type, NULL); 00632 int _isPerm = PR_FALSE; 00633 int _isSensitive = PR_TRUE; 00634 void * _cx = NULL; 00635 00636 if (_slot) { 00637 PQGParams *pqgParams = NULL; 00638 PQGVerify *pqgVfy = NULL; 00639 void * params = NULL; 00640 int xx; 00641 00642 xx = rpmnssErr(nss, "PK11_PQG_ParamGen", 00643 PK11_PQG_ParamGen(0, &pqgParams, &pqgVfy)); 00644 if (xx != SECSuccess) 00645 goto exit; 00646 params = pqgParams; 00647 00648 nss->sec_key = PK11_GenerateKeyPair(_slot, _type, params, 00649 &nss->pub_key, _isPerm, _isSensitive, _cx); 00650 00651 if (pqgVfy) PK11_PQG_DestroyVerify(pqgVfy); 00652 if (pqgParams) PK11_PQG_DestroyParams(pqgParams); 00653 00654 PK11_FreeSlot(_slot); 00655 } 00656 } 00657 00658 rc = (nss->sec_key && nss->pub_key); 00659 00660 exit: 00661 SPEW(!rc, rc, dig); 00662 return rc; 00663 } 00664 00665 static 00666 int rpmnssSetELG(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp) 00667 /*@*/ 00668 { 00669 rpmnss nss = dig->impl; 00670 int rc = 1; /* XXX always fail. */ 00671 int xx; 00672 00673 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00674 nss->digest = _free(nss->digest); 00675 nss->digestlen = 0; 00676 xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0); 00677 00678 /* Compare leading 16 bits of digest for quick check. */ 00679 00680 return rc; 00681 } 00682 00683 static 00684 int rpmnssSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp) 00685 /*@*/ 00686 { 00687 rpmnss nss = dig->impl; 00688 int xx; 00689 00690 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00691 nss->sigalg = SEC_OID_UNKNOWN; 00692 switch (sigp->hash_algo) { 00693 case PGPHASHALGO_SHA1: 00694 nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; 00695 break; 00696 case PGPHASHALGO_SHA224: 00697 nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE; 00698 break; 00699 case PGPHASHALGO_SHA256: 00700 nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; 00701 break; 00702 case PGPHASHALGO_SHA384: 00703 nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; 00704 break; 00705 case PGPHASHALGO_SHA512: 00706 nss->sigalg = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE; 00707 break; 00708 default: 00709 break; 00710 } 00711 if (nss->sigalg == SEC_OID_UNKNOWN) 00712 return 1; 00713 00714 nss->digest = _free(nss->digest); 00715 nss->digestlen = 0; 00716 xx = rpmDigestFinal(ctx, (void **)&nss->digest, &nss->digestlen, 0); 00717 00718 /* Compare leading 16 bits of digest for quick check. */ 00719 return memcmp(nss->digest, sigp->signhash16, sizeof(sigp->signhash16)); 00720 } 00721 00722 static 00723 int rpmnssVerifyECDSA(/*@unused@*/pgpDig dig) 00724 /*@*/ 00725 { 00726 rpmnss nss = dig->impl; 00727 int rc; 00728 00729 nss->item.type = siBuffer; 00730 nss->item.data = nss->digest; 00731 nss->item.len = (unsigned) nss->digestlen; 00732 00733 rc = VFY_VerifyDigest(&nss->item, nss->pub_key, nss->sig, nss->sigalg, NULL); 00734 rc = (rc == SECSuccess); 00735 00736 SPEW(!rc, rc, dig); 00737 return rc; 00738 } 00739 00740 static 00741 int rpmnssSignECDSA(/*@unused@*/pgpDig dig) 00742 /*@*/ 00743 { 00744 rpmnss nss = dig->impl; 00745 pgpDigParams sigp = pgpGetSignature(dig); 00746 int rc = 0; /* assume failure. */ 00747 00748 SECOidTag sigalg = SEC_OID_UNKNOWN; 00749 switch (sigp->hash_algo) { 00750 case PGPHASHALGO_MD5: 00751 break; 00752 case PGPHASHALGO_SHA1: 00753 sigalg = SEC_OID_SHA1; 00754 break; 00755 case PGPHASHALGO_RIPEMD160: 00756 break; 00757 case PGPHASHALGO_MD2: 00758 break; 00759 case PGPHASHALGO_MD4: 00760 break; 00761 case PGPHASHALGO_TIGER192: 00762 break; 00763 case PGPHASHALGO_HAVAL_5_160: 00764 break; 00765 case PGPHASHALGO_SHA256: 00766 sigalg = SEC_OID_SHA256; 00767 break; 00768 case PGPHASHALGO_SHA384: 00769 sigalg = SEC_OID_SHA384; 00770 break; 00771 case PGPHASHALGO_SHA512: 00772 sigalg = SEC_OID_SHA512; 00773 break; 00774 case PGPHASHALGO_SHA224: 00775 break; 00776 default: 00777 break; 00778 } 00779 if (sigalg == SEC_OID_UNKNOWN) 00780 goto exit; 00781 00782 if (nss->sig != NULL) { 00783 SECITEM_ZfreeItem(nss->sig, PR_TRUE); 00784 nss->sig = NULL; 00785 } 00786 nss->sig = SECITEM_AllocItem(NULL, NULL, 0); 00787 nss->sig->type = siBuffer; 00788 00789 rc = rpmnssErr(nss, "SGN_Digest", 00790 SGN_Digest(nss->sec_key, sigalg, nss->sig, &nss->item)); 00791 00792 rc = (rc == SECSuccess); 00793 00794 exit: 00795 SPEW(!rc, rc, dig); 00796 return rc; 00797 } 00798 00799 static 00800 int rpmnssGenerateECDSA(/*@unused@*/pgpDig dig) 00801 /*@*/ 00802 { 00803 rpmnss nss = dig->impl; 00804 int rc = 0; /* assume failure. */ 00805 00806 { CK_MECHANISM_TYPE _type = CKM_EC_KEY_PAIR_GEN; 00807 PK11SlotInfo * _slot = PK11_GetBestSlot(_type, NULL); 00808 int _isPerm = PR_FALSE; 00809 int _isSensitive = PR_FALSE; 00810 void * _cx = NULL; 00811 00812 if (_slot) { 00813 00814 nss->sec_key = PK11_GenerateKeyPair(_slot, _type, nss->ecparams, 00815 &nss->pub_key, _isPerm, _isSensitive, _cx); 00816 00817 PK11_FreeSlot(_slot); 00818 } 00819 } 00820 00821 rc = (nss->sec_key && nss->pub_key); 00822 00823 SPEW(!rc, rc, dig); 00824 00825 return rc; 00826 } 00827 00828 static int rpmnssErrChk(pgpDig dig, const char * msg, int rc, unsigned expected) 00829 { 00830 #ifdef NOTYET 00831 rpmgc gc = dig->impl; 00832 /* Was the return code the expected result? */ 00833 rc = (gcry_err_code(gc->err) != expected); 00834 if (rc) 00835 fail("%s failed: %s\n", msg, gpg_strerror(gc->err)); 00836 /* XXX FIXME: rpmnssStrerror */ 00837 #else 00838 rc = (rc == 0); /* XXX impedance match 1 -> 0 on success */ 00839 #endif 00840 return rc; /* XXX 0 on success */ 00841 } 00842 00843 static int rpmnssAvailableCipher(pgpDig dig, int algo) 00844 { 00845 int rc = 0; /* assume available */ 00846 #ifdef NOTYET 00847 rc = rpmgnssvailable(dig->impl, algo, 00848 (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5)); 00849 #endif 00850 return rc; 00851 } 00852 00853 static int rpmnssAvailableDigest(pgpDig dig, int algo) 00854 { 00855 int rc = 0; /* assume available */ 00856 #ifdef NOTYET 00857 rc = rpmgnssvailable(dig->impl, algo, 00858 (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5)); 00859 #endif 00860 return rc; 00861 } 00862 00863 static int rpmnssAvailablePubkey(pgpDig dig, int algo) 00864 { 00865 int rc = 0; /* assume available */ 00866 #ifdef NOTYET 00867 rc = rpmnssAvailable(dig->impl, algo, gcry_pk_test_algo(algo)); 00868 #endif 00869 return rc; 00870 } 00871 00872 static int rpmnssVerify(pgpDig dig) 00873 { 00874 rpmnss nss = dig->impl; 00875 int rc = 0; /* assume failure */ 00876 pgpDigParams pubp = pgpGetPubkey(dig); 00877 pgpDigParams sigp = pgpGetSignature(dig); 00878 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00879 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); 00880 00881 switch (pubp->pubkey_algo) { 00882 default: 00883 break; 00884 case PGPPUBKEYALGO_RSA: 00885 rc = rpmnssVerifyRSA(dig); 00886 break; 00887 case PGPPUBKEYALGO_DSA: 00888 rc = rpmnssVerifyDSA(dig); 00889 break; 00890 case PGPPUBKEYALGO_ELGAMAL: 00891 #ifdef NOTYET 00892 rc = rpmnssVerifyELG(dig); 00893 #endif 00894 break; 00895 case PGPPUBKEYALGO_ECDSA: 00896 if (nss->sigalg != SEC_OID_UNKNOWN) 00897 rc = rpmnssVerifyECDSA(dig); 00898 break; 00899 } 00900 SPEW(0, rc, dig); 00901 return rc; 00902 } 00903 00904 static int rpmnssSign(pgpDig dig) 00905 { 00906 rpmnss nss = dig->impl; 00907 int rc = 0; /* assume failure */ 00908 pgpDigParams pubp = pgpGetPubkey(dig); 00909 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00910 switch (pubp->pubkey_algo) { 00911 default: 00912 break; 00913 case PGPPUBKEYALGO_RSA: 00914 rc = rpmnssSignRSA(dig); 00915 break; 00916 case PGPPUBKEYALGO_DSA: 00917 rc = rpmnssSignDSA(dig); 00918 break; 00919 case PGPPUBKEYALGO_ELGAMAL: 00920 #ifdef NOTYET 00921 rc = rpmnssSignELG(dig); 00922 #endif 00923 break; 00924 case PGPPUBKEYALGO_ECDSA: 00925 if (nss->sigalg != SEC_OID_UNKNOWN) 00926 rc = rpmnssSignECDSA(dig); 00927 break; 00928 } 00929 SPEW(!rc, rc, dig); 00930 return rc; 00931 } 00932 00933 static int rpmnssLoadParams(pgpDig dig, const char * name) 00934 { 00935 rpmnss nss = dig->impl; 00936 #ifdef NOTYET 00937 SECOidTag curveOidTag = curve2oid(name); 00938 #else 00939 SECOidTag curveOidTag = !strcmp(name, "nistp256") 00940 ? SEC_OID_SECG_EC_SECP256R1 : SEC_OID_UNKNOWN; 00941 #endif 00942 SECOidData * oidData = SECOID_FindOIDByTag(curveOidTag); 00943 int rc = 1; /* assume failure. */ 00944 00945 if (curveOidTag == SEC_OID_UNKNOWN || oidData == NULL) { 00946 nss->sigalg = curveOidTag; 00947 goto exit; 00948 } 00949 00950 nss->sigalg = curveOidTag; 00951 00952 nss->ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len)); 00953 nss->ecparams->data[0] = SEC_ASN1_OBJECT_ID; 00954 nss->ecparams->data[1] = oidData->oid.len; 00955 memcpy(nss->ecparams->data + 2, oidData->oid.data, oidData->oid.len); 00956 rc = 0; 00957 00958 exit: 00959 if (1 || _pgp_debug) 00960 fprintf(stderr, "<-- %s(%p,%s) oid %u params %p\n", __FUNCTION__, dig, name, nss->sigalg, nss->ecparams); 00961 return rc; 00962 } 00963 00964 static int rpmnssGenerate(pgpDig dig) 00965 { 00966 int rc = 0; /* assume failure */ 00967 pgpDigParams pubp = pgpGetPubkey(dig); 00968 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00969 00970 switch (pubp->pubkey_algo) { 00971 default: 00972 break; 00973 case PGPPUBKEYALGO_RSA: 00974 rc = rpmnssGenerateRSA(dig); 00975 break; 00976 case PGPPUBKEYALGO_DSA: 00977 rc = rpmnssGenerateDSA(dig); 00978 break; 00979 case PGPPUBKEYALGO_ELGAMAL: 00980 #ifdef NOTYET 00981 rc = rpmnssGenerateELG(dig); 00982 #endif 00983 break; 00984 case PGPPUBKEYALGO_ECDSA: 00985 rc = rpmnssLoadParams(dig, "nistp256"); 00986 if (!rc) 00987 rc = rpmnssGenerateECDSA(dig); 00988 break; 00989 } 00990 SPEW(!rc, rc, dig); 00991 return rc; 00992 } 00993 00997 static 00998 int rpmnssMpiSet(const char * pre, unsigned int lbits, 00999 /*@out@*/ void * dest, const rpmuint8_t * p, 01000 /*@null@*/ const rpmuint8_t * pend) 01001 /*@modifies *dest @*/ 01002 { 01003 unsigned int mbits = pgpMpiBits(p); 01004 unsigned int nbits; 01005 unsigned int nbytes; 01006 char * t = dest; 01007 unsigned int ix; 01008 01009 if (pend != NULL && (p + ((mbits+7) >> 3)) > pend) 01010 return 1; 01011 01012 if (mbits > lbits) 01013 return 1; 01014 01015 nbits = (lbits > mbits ? lbits : mbits); 01016 nbytes = ((nbits + 7) >> 3); 01017 ix = ((nbits - mbits) >> 3); 01018 01019 /*@-modfilesystem @*/ 01020 if (_pgp_debug) 01021 fprintf(stderr, "*** mbits %u nbits %u nbytes %u ix %u\n", mbits, nbits, nbytes, ix); 01022 if (ix > 0) memset(t, (int)'\0', ix); 01023 memcpy(t+ix, p+2, nbytes-ix); 01024 if (_pgp_debug && _pgp_print) 01025 fprintf(stderr, "\t %s %s\n", pre, pgpHexStr(dest, nbytes)); 01026 /*@=modfilesystem @*/ 01027 return 0; 01028 } 01029 01033 static 01034 /*@only@*/ /*@null@*/ 01035 SECItem * rpmnssMpiCopy(PRArenaPool * arena, /*@returned@*/ SECItem * item, 01036 const rpmuint8_t * p) 01037 /*@modifies item @*/ 01038 { 01039 unsigned int nbytes = pgpMpiLen(p)-2; 01040 01041 /*@-moduncon@*/ 01042 if (item == NULL) { 01043 if ((item = SECITEM_AllocItem(arena, item, nbytes)) == NULL) 01044 return item; 01045 } else { 01046 if (arena != NULL) 01047 item->data = PORT_ArenaGrow(arena, item->data, item->len, nbytes); 01048 else 01049 item->data = PORT_Realloc(item->data, nbytes); 01050 01051 if (item->data == NULL) { 01052 if (arena == NULL) 01053 SECITEM_FreeItem(item, PR_TRUE); 01054 return NULL; 01055 } 01056 } 01057 /*@=moduncon@*/ 01058 01059 memcpy(item->data, p+2, nbytes); 01060 item->len = nbytes; 01061 /*@-temptrans@*/ 01062 return item; 01063 /*@=temptrans@*/ 01064 } 01065 01066 static /*@null@*/ 01067 SECKEYPublicKey * rpmnssNewPublicKey(KeyType type) 01068 /*@*/ 01069 { 01070 PRArenaPool *arena; 01071 SECKEYPublicKey *key; 01072 01073 /*@-moduncon@*/ 01074 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 01075 if (arena == NULL) 01076 return NULL; 01077 01078 key = PORT_ArenaZAlloc(arena, sizeof(*key)); 01079 01080 if (key == NULL) { 01081 PORT_FreeArena(arena, PR_FALSE); 01082 return NULL; 01083 } 01084 /*@=moduncon@*/ 01085 01086 key->keyType = type; 01087 key->pkcs11ID = CK_INVALID_HANDLE; 01088 key->pkcs11Slot = NULL; 01089 key->arena = arena; 01090 /*@-nullret@*/ /* key->pkcs11Slot can be NULL */ 01091 return key; 01092 /*@=nullret@*/ 01093 } 01094 01095 static 01096 int rpmnssMpiItem(const char * pre, pgpDig dig, int itemno, 01097 const rpmuint8_t * p, /*@null@*/ const rpmuint8_t * pend) 01098 /*@*/ 01099 { 01100 rpmnss nss = dig->impl; 01101 unsigned int hbits; 01102 size_t nb = (pend >= p ? (pend - p) : 0); 01103 int rc = 0; 01104 01105 /*@-moduncon@*/ 01106 switch (itemno) { 01107 default: 01108 assert(0); 01109 break; 01110 case 10: /* RSA m**d */ 01111 nss->sig = rpmnssMpiCopy(NULL, nss->sig, p); 01112 if (nss->sig == NULL) 01113 rc = 1; 01114 break; 01115 case 20: /* DSA r */ 01116 hbits = 160; 01117 nss->item.type = 0; 01118 nss->item.len = 2 * (hbits/8); 01119 nss->item.data = xcalloc(1, nss->item.len); 01120 rc = rpmnssMpiSet(pre, hbits, nss->item.data, p, pend); 01121 break; 01122 case 21: /* DSA s */ 01123 hbits = 160; 01124 rc = rpmnssMpiSet(pre, hbits, nss->item.data + (hbits/8), p, pend); 01125 if (nss->sig != NULL) 01126 SECITEM_FreeItem(nss->sig, PR_FALSE); 01127 if ((nss->sig = SECITEM_AllocItem(NULL, NULL, 0)) == NULL 01128 || DSAU_EncodeDerSig(nss->sig, &nss->item) != SECSuccess) 01129 rc = 1; 01130 nss->item.data = _free(nss->item.data); 01131 break; 01132 case 30: /* RSA n */ 01133 if (nss->pub_key == NULL) 01134 nss->pub_key = rpmnssNewPublicKey(rsaKey); 01135 if (nss->pub_key == NULL) 01136 rc = 1; 01137 else 01138 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.rsa.modulus, p); 01139 break; 01140 case 31: /* RSA e */ 01141 if (nss->pub_key == NULL) 01142 nss->pub_key = rpmnssNewPublicKey(rsaKey); 01143 if (nss->pub_key == NULL) 01144 rc = 1; 01145 else 01146 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.rsa.publicExponent, p); 01147 break; 01148 case 40: /* DSA p */ 01149 if (nss->pub_key == NULL) 01150 nss->pub_key = rpmnssNewPublicKey(dsaKey); 01151 if (nss->pub_key == NULL) 01152 rc = 1; 01153 else 01154 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.prime, p); 01155 break; 01156 case 41: /* DSA q */ 01157 if (nss->pub_key == NULL) 01158 nss->pub_key = rpmnssNewPublicKey(dsaKey); 01159 if (nss->pub_key == NULL) 01160 rc = 1; 01161 else 01162 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.subPrime, p); 01163 break; 01164 case 42: /* DSA g */ 01165 if (nss->pub_key == NULL) 01166 nss->pub_key = rpmnssNewPublicKey(dsaKey); 01167 if (nss->pub_key == NULL) 01168 rc = 1; 01169 else 01170 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.params.base, p); 01171 break; 01172 case 43: /* DSA y */ 01173 if (nss->pub_key == NULL) 01174 nss->pub_key = rpmnssNewPublicKey(dsaKey); 01175 if (nss->pub_key == NULL) 01176 rc = 1; 01177 else 01178 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.dsa.publicValue, p); 01179 break; 01180 case 50: /* ECDSA r */ 01181 hbits = 256; 01182 nss->item.type = 0; 01183 nss->item.len = 2 * (hbits/8); 01184 nss->item.data = xcalloc(1, nss->item.len); 01185 rc = rpmnssMpiSet(pre, hbits, nss->item.data, p, pend); 01186 break; 01187 case 51: /* ECDSA s */ 01188 hbits = 256; 01189 rc = rpmnssMpiSet(pre, hbits, nss->item.data + (hbits/8), p, pend); 01190 if (nss->sig != NULL) 01191 SECITEM_FreeItem(nss->sig, PR_FALSE); 01192 if ((nss->sig = SECITEM_AllocItem(NULL, NULL, 0)) == NULL 01193 || DSAU_EncodeDerSigWithLen(nss->sig, &nss->item, nss->item.len) != SECSuccess) 01194 rc = 1; 01195 nss->item.data = _free(nss->item.data); 01196 break; 01197 case 60: /* ECDSA curve OID */ 01198 assert(pend > p); 01199 if (nss->pub_key == NULL) 01200 nss->pub_key = rpmnssNewPublicKey(ecKey); 01201 if (nss->pub_key == NULL) 01202 rc = 1; 01203 else { 01204 SECKEYECParams * ecp = &nss->pub_key->u.ec.DEREncodedParams; 01205 ecp->data = PORT_ArenaZAlloc(nss->pub_key->arena, nb + 2); 01206 ecp->data[0] = SEC_ASN1_OBJECT_ID; 01207 ecp->data[1] = nb; 01208 memcpy(ecp->data + 2, p, nb); 01209 ecp->len = nb + 2; 01210 } 01211 break; 01212 case 61: /* ECDSA Q */ 01213 assert(nss->pub_key); 01214 /* XXX assumes uncompressed Q as a MPI */ 01215 nss->pub_key->u.ec.size = ((nb - (2 + 1)) * 8)/2; 01216 (void) rpmnssMpiCopy(nss->pub_key->arena, &nss->pub_key->u.ec.publicValue, p); 01217 break; 01218 } 01219 /*@=moduncon@*/ 01220 return rc; 01221 } 01222 01223 /*@-mustmod@*/ 01224 static 01225 void rpmnssClean(void * impl) 01226 /*@modifies impl @*/ 01227 { 01228 rpmnss nss = impl; 01229 /*@-moduncon@*/ 01230 if (nss != NULL) { 01231 nss->nbits = 0; 01232 nss->err = 0; 01233 nss->badok = 0; 01234 nss->digest = _free(nss->digest); 01235 nss->digestlen = 0; 01236 01237 if (nss->sec_key != NULL) { 01238 SECKEY_DestroyPrivateKey(nss->sec_key); 01239 nss->sec_key = NULL; 01240 } 01241 if (nss->pub_key != NULL) { 01242 SECKEY_DestroyPublicKey(nss->pub_key); 01243 nss->pub_key = NULL; 01244 } 01245 if (nss->sig != NULL) { 01246 SECITEM_ZfreeItem(nss->sig, PR_TRUE); 01247 nss->sig = NULL; 01248 } 01249 01250 if (nss->ecparams != NULL) { 01251 SECITEM_FreeItem(nss->ecparams, PR_FALSE); 01252 nss->ecparams = NULL; 01253 } 01254 /*@=moduncon@*/ 01255 } 01256 } 01257 /*@=mustmod@*/ 01258 01259 static /*@null@*/ 01260 void * rpmnssFree(/*@only@*/ void * impl) 01261 /*@*/ 01262 { 01263 rpmnssClean(impl); 01264 impl = _free(impl); 01265 return NULL; 01266 } 01267 01268 static 01269 void * rpmnssInit(void) 01270 /*@globals _rpmnss_init @*/ 01271 /*@modifies _rpmnss_init @*/ 01272 { 01273 rpmnss nss = xcalloc(1, sizeof(*nss)); 01274 const char * _nssdb_path = rpmExpand("%{?_nssdb_path}", NULL); 01275 01276 /*@-moduncon@*/ 01277 if (_nssdb_path != NULL && *_nssdb_path == '/') 01278 (void) NSS_Init(_nssdb_path); 01279 else 01280 (void) NSS_NoDB_Init(NULL); 01281 /*@=moduncon@*/ 01282 _nssdb_path = _free(_nssdb_path); 01283 01284 _rpmnss_init = 1; 01285 01286 return (void *) nss; 01287 } 01288 01289 struct pgpImplVecs_s rpmnssImplVecs = { 01290 rpmnssSetRSA, 01291 rpmnssSetDSA, 01292 rpmnssSetELG, 01293 rpmnssSetECDSA, 01294 01295 rpmnssErrChk, 01296 rpmnssAvailableCipher, rpmnssAvailableDigest, rpmnssAvailablePubkey, 01297 rpmnssVerify, rpmnssSign, rpmnssGenerate, 01298 01299 rpmnssMpiItem, rpmnssClean, 01300 rpmnssFree, rpmnssInit 01301 }; 01302 01303 #endif 01304
1.7.5.1