pk11_signature_test.h (4233B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include <memory> 6 #include "nss.h" 7 #include "pk11pub.h" 8 #include "sechash.h" 9 10 #include "nss_scoped_ptrs.h" 11 #include "databuffer.h" 12 13 #include "gtest/gtest.h" 14 namespace nss_test { 15 16 // For test vectors. 17 struct Pkcs11SignatureTestParams { 18 const DataBuffer pkcs8_; 19 const DataBuffer spki_; 20 const DataBuffer data_; 21 const DataBuffer signature_; 22 }; 23 24 class Pk11SignatureTest : public ::testing::Test { 25 protected: 26 Pk11SignatureTest(CK_MECHANISM_TYPE mech, SECOidTag hash_oid, 27 CK_MECHANISM_TYPE combo) 28 : mechanism_(mech), hash_oid_(hash_oid), combo_(combo) { 29 skip_raw_ = false; 30 skip_digest_ = false; 31 } 32 33 Pk11SignatureTest(CK_MECHANISM_TYPE mech) : mechanism_(mech) { 34 skip_digest_ = true; 35 } 36 37 virtual const SECItem* parameters() const { return nullptr; } 38 CK_MECHANISM_TYPE mechanism() const { return mechanism_; } 39 void setSkipRaw(bool skip_raw) { skip_raw_ = true; } 40 41 bool ExportPrivateKey(ScopedSECKEYPrivateKey* key, DataBuffer& pkcs8) { 42 SECItem* pkcs8Item = PK11_ExportDERPrivateKeyInfo(key->get(), nullptr); 43 if (!pkcs8Item) { 44 return false; 45 } 46 pkcs8.Assign(pkcs8Item->data, pkcs8Item->len); 47 SECITEM_ZfreeItem(pkcs8Item, PR_TRUE); 48 return true; 49 } 50 51 ScopedSECKEYPrivateKey ImportPrivateKey(const DataBuffer& pkcs8); 52 ScopedSECKEYPublicKey ImportPublicKey(const DataBuffer& spki); 53 54 bool ComputeHash(const DataBuffer& data, DataBuffer* hash) { 55 hash->Allocate(static_cast<size_t>(HASH_ResultLenByOidTag(hash_oid_))); 56 SECStatus rv = 57 PK11_HashBuf(hash_oid_, hash->data(), data.data(), data.len()); 58 return rv == SECSuccess; 59 } 60 61 bool SignRaw(ScopedSECKEYPrivateKey& privKey, const DataBuffer& hash, 62 DataBuffer* sig); 63 bool DigestAndSign(ScopedSECKEYPrivateKey& privKey, const DataBuffer& data, 64 DataBuffer* sig); 65 bool ImportPrivateKeyAndSignHashedData(const DataBuffer& pkcs8, 66 const DataBuffer& data, 67 DataBuffer* sig, DataBuffer* sig2); 68 69 /* most primitive verify implemented in pk11_signature_test.cpp */ 70 void Verify(ScopedSECKEYPublicKey& pubKey, const DataBuffer& data, 71 const DataBuffer& sig, bool valid); 72 73 /* quick helper functions that use the primitive verify */ 74 void Verify(ScopedSECKEYPublicKey& pubKey, const DataBuffer& data, 75 const DataBuffer& sig) { 76 Verify(pubKey, data, sig, true); 77 } 78 79 void Verify(const Pkcs11SignatureTestParams& params, const DataBuffer& sig, 80 bool valid) { 81 ScopedSECKEYPublicKey pubKey(ImportPublicKey(params.spki_)); 82 ASSERT_TRUE(pubKey); 83 Verify(pubKey, params.data_, sig, valid); 84 } 85 86 void Verify(const Pkcs11SignatureTestParams& params, bool valid) { 87 Verify(params, params.signature_, valid); 88 } 89 90 void Verify(const Pkcs11SignatureTestParams& params) { 91 Verify(params, params.signature_, true); 92 } 93 94 void SignAndVerify(const Pkcs11SignatureTestParams& params) { 95 DataBuffer sig; 96 DataBuffer sig2; 97 ASSERT_TRUE(ImportPrivateKeyAndSignHashedData(params.pkcs8_, params.data_, 98 &sig, &sig2)); 99 Verify(params, sig, true); 100 Verify(params, sig2, true); 101 } 102 103 void SignAndVerifyRaw(const Pkcs11SignatureTestParams& params) { 104 ScopedSECKEYPrivateKey privKey(ImportPrivateKey(params.pkcs8_)); 105 ASSERT_NE(privKey, nullptr); 106 DataBuffer sig; 107 SignRaw(privKey, params.data_, &sig); 108 EXPECT_EQ(sig, params.signature_); 109 Verify(params, sig, true); 110 } 111 112 // Importing a private key in PKCS#8 format and reexporting it should 113 // result in the same binary representation. 114 void ImportExport(const DataBuffer& k) { 115 DataBuffer exported; 116 ScopedSECKEYPrivateKey key = ImportPrivateKey(k); 117 ExportPrivateKey(&key, exported); 118 EXPECT_EQ(k, exported); 119 } 120 121 private: 122 CK_MECHANISM_TYPE mechanism_; 123 SECOidTag hash_oid_; 124 CK_MECHANISM_TYPE combo_; 125 bool skip_raw_; 126 bool skip_digest_; 127 }; 128 129 } // namespace nss_test