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 15 namespace nss_test { 16 17 // For test vectors. 18 struct Pkcs11SignatureTestParams { 19 const DataBuffer pkcs8_; 20 const DataBuffer spki_; 21 const DataBuffer data_; 22 const DataBuffer signature_; 23 }; 24 25 class Pk11SignatureTest : public ::testing::Test { 26 protected: Pk11SignatureTest(CK_MECHANISM_TYPE mech,SECOidTag hash_oid,CK_MECHANISM_TYPE combo)27 Pk11SignatureTest(CK_MECHANISM_TYPE mech, SECOidTag hash_oid, 28 CK_MECHANISM_TYPE combo) 29 : mechanism_(mech), hash_oid_(hash_oid), combo_(combo) { 30 skip_raw_ = false; 31 } 32 parameters()33 virtual const SECItem* parameters() const { return nullptr; } mechanism()34 CK_MECHANISM_TYPE mechanism() const { return mechanism_; } setSkipRaw(bool skip_raw)35 void setSkipRaw(bool skip_raw) { skip_raw_ = true; } 36 ExportPrivateKey(ScopedSECKEYPrivateKey * key,DataBuffer & pkcs8)37 bool ExportPrivateKey(ScopedSECKEYPrivateKey* key, DataBuffer& pkcs8) { 38 SECItem* pkcs8Item = PK11_ExportDERPrivateKeyInfo(key->get(), nullptr); 39 if (!pkcs8Item) { 40 return false; 41 } 42 pkcs8.Assign(pkcs8Item->data, pkcs8Item->len); 43 SECITEM_ZfreeItem(pkcs8Item, PR_TRUE); 44 return true; 45 } 46 47 ScopedSECKEYPrivateKey ImportPrivateKey(const DataBuffer& pkcs8); 48 ScopedSECKEYPublicKey ImportPublicKey(const DataBuffer& spki); 49 ComputeHash(const DataBuffer & data,DataBuffer * hash)50 bool ComputeHash(const DataBuffer& data, DataBuffer* hash) { 51 hash->Allocate(static_cast<size_t>(HASH_ResultLenByOidTag(hash_oid_))); 52 SECStatus rv = 53 PK11_HashBuf(hash_oid_, hash->data(), data.data(), data.len()); 54 return rv == SECSuccess; 55 } 56 57 bool SignHashedData(ScopedSECKEYPrivateKey& privKey, const DataBuffer& hash, 58 DataBuffer* sig); 59 bool SignData(ScopedSECKEYPrivateKey& privKey, const DataBuffer& data, 60 DataBuffer* sig); 61 bool ImportPrivateKeyAndSignHashedData(const DataBuffer& pkcs8, 62 const DataBuffer& data, 63 DataBuffer* sig, DataBuffer* sig2); 64 65 /* most primitive verify implemented in pk11_signature_test.cpp */ 66 void Verify(ScopedSECKEYPublicKey& pubKey, const DataBuffer& data, 67 const DataBuffer& sig, bool valid); 68 69 /* quick helper functions that use the primitive verify */ Verify(ScopedSECKEYPublicKey & pubKey,const DataBuffer & data,const DataBuffer & sig)70 void Verify(ScopedSECKEYPublicKey& pubKey, const DataBuffer& data, 71 const DataBuffer& sig) { 72 Verify(pubKey, data, sig, true); 73 } 74 Verify(const Pkcs11SignatureTestParams & params,const DataBuffer & sig,bool valid)75 void Verify(const Pkcs11SignatureTestParams& params, const DataBuffer& sig, 76 bool valid) { 77 ScopedSECKEYPublicKey pubKey(ImportPublicKey(params.spki_)); 78 ASSERT_TRUE(pubKey); 79 Verify(pubKey, params.data_, sig, valid); 80 } 81 Verify(const Pkcs11SignatureTestParams & params,bool valid)82 void Verify(const Pkcs11SignatureTestParams& params, bool valid) { 83 Verify(params, params.signature_, valid); 84 } 85 Verify(const Pkcs11SignatureTestParams & params)86 void Verify(const Pkcs11SignatureTestParams& params) { 87 Verify(params, params.signature_, true); 88 } 89 SignAndVerify(const Pkcs11SignatureTestParams & params)90 void SignAndVerify(const Pkcs11SignatureTestParams& params) { 91 DataBuffer sig; 92 DataBuffer sig2; 93 ASSERT_TRUE(ImportPrivateKeyAndSignHashedData(params.pkcs8_, params.data_, 94 &sig, &sig2)); 95 Verify(params, sig, true); 96 Verify(params, sig2, true); 97 } 98 99 // Importing a private key in PKCS#8 format and reexporting it should 100 // result in the same binary representation. ImportExport(const DataBuffer & k)101 void ImportExport(const DataBuffer& k) { 102 DataBuffer exported; 103 ScopedSECKEYPrivateKey key = ImportPrivateKey(k); 104 ExportPrivateKey(&key, exported); 105 EXPECT_EQ(k, exported); 106 } 107 108 private: 109 CK_MECHANISM_TYPE mechanism_; 110 SECOidTag hash_oid_; 111 CK_MECHANISM_TYPE combo_; 112 bool skip_raw_; 113 }; 114 115 } // namespace nss_test 116