tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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