/* * check the consistancy and initialize a Private Key Object */ static CK_RV lg_createPrivateKeyObject(SDB *sdb, CK_KEY_TYPE key_type, CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count) { NSSLOWKEYPrivateKey *privKey; char *label; SECStatus rv = SECSuccess; CK_RV crv = CKR_DEVICE_ERROR; SECItem pubKey; NSSLOWKEYDBHandle *keyHandle = lg_getKeyDB(sdb); if (keyHandle == NULL) { return CKR_TOKEN_WRITE_PROTECTED; } privKey = lg_mkPrivKey(sdb, templ, count, key_type, &crv); if (privKey == NULL) return crv; label = lg_getString(CKA_LABEL, templ, count); crv = lg_Attribute2SSecItem(NULL, CKA_NETSCAPE_DB, templ, count, &pubKey); if (crv != CKR_OK) { crv = CKR_TEMPLATE_INCOMPLETE; rv = SECFailure; goto fail; } #ifdef notdef if (keyHandle->version != 3) { unsigned char buf[SHA1_LENGTH]; SHA1_HashBuf(buf, pubKey.data, pubKey.len); PORT_Memcpy(pubKey.data, buf, sizeof(buf)); pubKey.len = sizeof(buf); } #endif /* get the key type */ if (key_type == CKK_RSA) { rv = RSA_PrivateKeyCheck(&privKey->u.rsa); if (rv == SECFailure) { goto fail; } } rv = nsslowkey_StoreKeyByPublicKey(keyHandle, privKey, &pubKey, label, sdb /*->password*/); fail: if (label) PORT_Free(label); *handle = lg_mkHandle(sdb, &pubKey, LG_TOKEN_TYPE_PRIV); if (pubKey.data) PORT_Free(pubKey.data); lg_nsslowkey_DestroyPrivateKey(privKey); if (rv != SECSuccess) return crv; return CKR_OK; }
/* Hash a null-terminated character string. */ SECStatus SHA1_Hash(unsigned char *dest, const char *src) { return SHA1_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); }
/* * Test the softoken RSA_HashSign and RSH_HashCheckSign. */ static SECStatus sftk_fips_RSA_PowerUpSigSelfTest(HASH_HashType shaAlg, NSSLOWKEYPublicKey *rsa_public_key, NSSLOWKEYPrivateKey *rsa_private_key, const unsigned char *rsa_known_msg, const unsigned int rsa_kmsg_length, const unsigned char *rsa_known_signature) { SECOidTag shaOid; /* SHA OID */ unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */ unsigned int shaLength = 0; /* length of SHA */ unsigned int rsa_bytes_signed; unsigned char rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH]; SECStatus rv; if (shaAlg == HASH_AlgSHA1) { if (SHA1_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) != SECSuccess) { goto loser; } shaLength = SHA1_LENGTH; shaOid = SEC_OID_SHA1; } else if (shaAlg == HASH_AlgSHA256) { if (SHA256_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) != SECSuccess) { goto loser; } shaLength = SHA256_LENGTH; shaOid = SEC_OID_SHA256; } else if (shaAlg == HASH_AlgSHA384) { if (SHA384_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) != SECSuccess) { goto loser; } shaLength = SHA384_LENGTH; shaOid = SEC_OID_SHA384; } else if (shaAlg == HASH_AlgSHA512) { if (SHA512_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) != SECSuccess) { goto loser; } shaLength = SHA512_LENGTH; shaOid = SEC_OID_SHA512; } else { goto loser; } /*************************************************/ /* RSA Single-Round Known Answer Signature Test. */ /*************************************************/ /* Perform RSA signature with the RSA private key. */ rv = RSA_HashSign(shaOid, rsa_private_key, rsa_computed_signature, &rsa_bytes_signed, FIPS_RSA_SIGNATURE_LENGTH, sha, shaLength); if ((rv != SECSuccess) || (rsa_bytes_signed != FIPS_RSA_SIGNATURE_LENGTH) || (PORT_Memcmp(rsa_computed_signature, rsa_known_signature, FIPS_RSA_SIGNATURE_LENGTH) != 0)) { goto loser; } /****************************************************/ /* RSA Single-Round Known Answer Verification Test. */ /****************************************************/ /* Perform RSA verification with the RSA public key. */ rv = RSA_HashCheckSign(shaOid, rsa_public_key, rsa_computed_signature, rsa_bytes_signed, sha, shaLength); if (rv != SECSuccess) { goto loser; } return (SECSuccess); loser: return (SECFailure); }
/* * check the consistancy and initialize a Public Key Object */ static CK_RV lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type, CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count) { CK_ATTRIBUTE_TYPE pubKeyAttr = CKA_VALUE; CK_RV crv = CKR_OK; NSSLOWKEYPrivateKey *priv; SECItem pubKeySpace = { siBuffer, NULL, 0 }; SECItem *pubKey; #ifndef NSS_DISABLE_ECC SECItem pubKey2Space = { siBuffer, NULL, 0 }; PLArenaPool *arena = NULL; #endif /* NSS_DISABLE_ECC */ NSSLOWKEYDBHandle *keyHandle = NULL; switch (key_type) { case CKK_RSA: pubKeyAttr = CKA_MODULUS; break; #ifndef NSS_DISABLE_ECC case CKK_EC: pubKeyAttr = CKA_EC_POINT; break; #endif /* NSS_DISABLE_ECC */ case CKK_DSA: case CKK_DH: break; default: return CKR_ATTRIBUTE_VALUE_INVALID; } pubKey = &pubKeySpace; crv = lg_Attribute2SSecItem(NULL, pubKeyAttr, templ, count, pubKey); if (crv != CKR_OK) return crv; #ifndef NSS_DISABLE_ECC if (key_type == CKK_EC) { SECStatus rv; /* * for ECC, use the decoded key first. */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { crv = CKR_HOST_MEMORY; goto done; } rv = SEC_QuickDERDecodeItem(arena, &pubKey2Space, SEC_ASN1_GET(SEC_OctetStringTemplate), pubKey); if (rv != SECSuccess) { /* decode didn't work, just try the pubKey */ PORT_FreeArena(arena, PR_FALSE); arena = NULL; } else { /* try the decoded pub key first */ pubKey = &pubKey2Space; } } #endif /* NSS_DISABLE_ECC */ PORT_Assert(pubKey->data); if (pubKey->data == NULL) { crv = CKR_ATTRIBUTE_VALUE_INVALID; goto done; } keyHandle = lg_getKeyDB(sdb); if (keyHandle == NULL) { crv = CKR_TOKEN_WRITE_PROTECTED; goto done; } if (keyHandle->version != 3) { unsigned char buf[SHA1_LENGTH]; SHA1_HashBuf(buf, pubKey->data, pubKey->len); PORT_Memcpy(pubKey->data, buf, sizeof(buf)); pubKey->len = sizeof(buf); } /* make sure the associated private key already exists */ /* only works if we are logged in */ priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, sdb /*password*/); #ifndef NSS_DISABLE_ECC if (priv == NULL && pubKey == &pubKey2Space) { /* no match on the decoded key, match the original pubkey */ pubKey = &pubKeySpace; priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, sdb /*password*/); } #endif if (priv == NULL) { /* the legacy database can only 'store' public keys which already * have their corresponding private keys in the database */ crv = CKR_ATTRIBUTE_VALUE_INVALID; goto done; } lg_nsslowkey_DestroyPrivateKey(priv); crv = CKR_OK; *handle = lg_mkHandle(sdb, pubKey, LG_TOKEN_TYPE_PUB); done: PORT_Free(pubKeySpace.data); #ifndef NSS_DISABLE_ECC if (arena) PORT_FreeArena(arena, PR_FALSE); #endif return crv; }