err_t RSA_signature_verify_nss(const struct RSA_public_key *k , const u_char *hash_val, size_t hash_len ,const u_char *sig_val, size_t sig_len) { SECKEYPublicKey *publicKey; PRArenaPool *arena; SECStatus retVal = SECSuccess; SECItem nss_n, nss_e; SECItem signature, data; chunk_t n,e; /*Converting n and e to form public key in SECKEYPublicKey data structure*/ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { PORT_SetError (SEC_ERROR_NO_MEMORY); return "10" "NSS error: Not enough memory to create arena"; } publicKey = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey)); if (!publicKey) { PORT_FreeArena (arena, PR_FALSE); PORT_SetError (SEC_ERROR_NO_MEMORY); return "11" "NSS error: Not enough memory to create publicKey"; } publicKey->arena = arena; publicKey->keyType = rsaKey; publicKey->pkcs11Slot = NULL; publicKey->pkcs11ID = CK_INVALID_HANDLE; /* Converting n(modulus) and e(exponent) from mpz_t form to chunk_t */ n = mpz_to_n_autosize(&k->n); e = mpz_to_n_autosize(&k->e); /*Converting n and e to nss_n and nss_e*/ nss_n.data = n.ptr; nss_n.len = (unsigned int)n.len; nss_n.type = siBuffer; nss_e.data = e.ptr; nss_e.len = (unsigned int)e.len; nss_e.type = siBuffer; retVal = SECITEM_CopyItem(arena, &publicKey->u.rsa.modulus, &nss_n); if (retVal == SECSuccess) { retVal = SECITEM_CopyItem (arena, &publicKey->u.rsa.publicExponent, &nss_e); } if(retVal != SECSuccess) { pfree(n.ptr); pfree(e.ptr); SECKEY_DestroyPublicKey (publicKey); return "12" "NSS error: Not able to copy modulus or exponent or both while forming SECKEYPublicKey structure"; } signature.type = siBuffer; signature.data = DISCARD_CONST(unsigned char *, sig_val); signature.len = (unsigned int)sig_len; data.len = (unsigned int)sig_len; data.data = alloc_bytes(data.len, "NSS decrypted signature"); data.type = siBuffer; if(PK11_VerifyRecover(publicKey, &signature, &data, osw_return_nss_password_file_info()) == SECSuccess ) { DBG(DBG_CRYPT,DBG_dump("NSS RSA verify: decrypted sig: ", data.data, data.len)); } else { DBG(DBG_CRYPT,DBG_log("NSS RSA verify: decrypting signature is failed")); return "13" "NSS error: Not able to decrypt"; } if(memcmp(data.data+data.len-hash_len, hash_val, hash_len)!=0) { pfree(data.data); loglog(RC_LOG_SERIOUS, "RSA Signature NOT verified"); return "14" "NSS error: Not able to verify"; } DBG(DBG_CRYPT,DBG_dump("NSS RSA verify: hash value: ", hash_val, hash_len)); pfree(data.data); pfree(n.ptr); pfree(e.ptr); SECKEY_DestroyPublicKey (publicKey); DBG(DBG_CRYPT, DBG_log("RSA Signature verified")); return NULL; }
/* MUST BE THREAD-SAFE */ void calc_ke(struct pluto_crypto_req *r) { SECKEYDHParams dhp; PK11SlotInfo *slot = NULL; SECKEYPrivateKey *privk; SECKEYPublicKey *pubk; struct pcr_kenonce *kn = &r->pcr_d.kn; const struct oakley_group_desc *group = lookup_group(kn->oakley_group); chunk_t base = mpz_to_n_autosize(group->generator); chunk_t prime = mpz_to_n_autosize(group->modulus); DBG(DBG_CRYPT, DBG_dump_chunk("NSS: Value of Prime:", prime)); DBG(DBG_CRYPT, DBG_dump_chunk("NSS: Value of base:", base)); dhp.prime.data = prime.ptr; dhp.prime.len = prime.len; dhp.base.data = base.ptr; dhp.base.len = base.len; slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN, lsw_return_nss_password_file_info()); if (slot == NULL) loglog(RC_LOG_SERIOUS, "NSS: slot for DH key gen is NULL"); passert(slot != NULL); for (;;) { pubk = NULL; /* ??? is this needed? Output-only from next call? */ privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, &dhp, &pubk, PR_FALSE, PR_TRUE, lsw_return_nss_password_file_info()); if (privk == NULL) { loglog(RC_LOG_SERIOUS, "NSS: DH private key creation failed (err %d)", PR_GetError()); } passert(privk != NULL && pubk != NULL); if (group->bytes == pubk->u.dh.publicValue.len) { DBG(DBG_CRYPT, DBG_log("NSS: generated dh priv and pub keys: %d", pubk->u.dh.publicValue.len)); break; } else { DBG(DBG_CRYPT, DBG_log("NSS: generating dh priv and pub keys again")); SECKEY_DestroyPrivateKey(privk); SECKEY_DestroyPublicKey(pubk); } } kn->secret = privk; kn->pubk = pubk; ALLOC_WIRE_CHUNK(*kn, gi, pubk->u.dh.publicValue.len); { unsigned char *gip = WIRE_CHUNK_PTR(*kn, gi); memcpy(gip, pubk->u.dh.publicValue.data, pubk->u.dh.publicValue.len); } DBG(DBG_CRYPT, { DBG_log("NSS: Local DH secret (pointer): %p", kn->secret); DBG_dump("NSS: Public DH value sent(computed in NSS):", WIRE_CHUNK_PTR(*kn, gi), pubk->u.dh.publicValue.len); });