bug 1058812 - (2/3) mozilla::pkix: use ByteStrings to identify signature algorithm parameters in tests r=briansmith
authorDavid Keeler <dkeeler@mozilla.com>
Wed, 08 Oct 2014 09:33:59 -0700
changeset 209463 a4356f6fb7e79422f862bd6066dcc938cc588164
parent 209462 18d10c64257d137c33282b7aaed5932c17692843
child 209464 3ae75c8b8f640c99186f04e7ffbacd4450b57e4b
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbriansmith
bugs1058812
milestone35.0a1
bug 1058812 - (2/3) mozilla::pkix: use ByteStrings to identify signature algorithm parameters in tests r=briansmith
security/pkix/test/gtest/pkixbuild_tests.cpp
security/pkix/test/gtest/pkixcert_extension_tests.cpp
security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp
security/pkix/test/lib/pkixtestnss.cpp
security/pkix/test/lib/pkixtestutil.cpp
security/pkix/test/lib/pkixtestutil.h
--- a/security/pkix/test/gtest/pkixbuild_tests.cpp
+++ b/security/pkix/test/gtest/pkixbuild_tests.cpp
@@ -60,17 +60,17 @@ CreateCert(const char* issuerCN,
     EXPECT_FALSE(ENCODING_FAILED(extensions[0]));
   }
 
   ByteString certDER(CreateEncodedCertificate(
                        v3, sha256WithRSAEncryption,
                        serialNumber, issuerDER,
                        oneDayBeforeNow, oneDayAfterNow,
                        subjectDER, extensions, issuerKey,
-                       SignatureAlgorithm::rsa_pkcs1_with_sha256,
+                       sha256WithRSAEncryption,
                        subjectKey));
   EXPECT_FALSE(ENCODING_FAILED(certDER));
   if (subjectCert) {
     SECItem certDERItem = {
       siBuffer,
       const_cast<uint8_t*>(certDER.data()),
       static_cast<unsigned int>(certDER.length())
     };
@@ -395,17 +395,17 @@ TEST_F(pkixbuild, NoRevocationCheckingFo
   ByteString subjectDER(CNToDERName("Expired End-Entity Cert"));
   ScopedTestKeyPair unusedSubjectKey;
   ByteString certDER(CreateEncodedCertificate(
                        v3, sha256WithRSAEncryption,
                        serialNumber, issuerDER,
                        oneDayBeforeNow - Time::ONE_DAY_IN_SECONDS,
                        oneDayBeforeNow,
                        subjectDER, nullptr, rootKey.get(),
-                       SignatureAlgorithm::rsa_pkcs1_with_sha256,
+                       sha256WithRSAEncryption,
                        unusedSubjectKey));
   EXPECT_FALSE(ENCODING_FAILED(certDER));
 
   Input cert;
   ASSERT_EQ(Success, cert.Init(certDER.data(), certDER.length()));
   ASSERT_EQ(Result::ERROR_EXPIRED_CERTIFICATE,
             BuildCertChain(expiredCertTrustDomain, cert, Now(),
                            EndEntityOrCA::MustBeEndEntity,
--- a/security/pkix/test/gtest/pkixcert_extension_tests.cpp
+++ b/security/pkix/test/gtest/pkixcert_extension_tests.cpp
@@ -43,17 +43,17 @@ CreateCert(const char* subjectCN,
   EXPECT_FALSE(ENCODING_FAILED(issuerDER));
   ByteString subjectDER(CNToDERName(subjectCN));
   EXPECT_FALSE(ENCODING_FAILED(subjectDER));
   return CreateEncodedCertificate(v3, sha256WithRSAEncryption,
                                   serialNumber, issuerDER,
                                   oneDayBeforeNow, oneDayAfterNow,
                                   subjectDER, extensions,
                                   nullptr,
-                                  SignatureAlgorithm::rsa_pkcs1_with_sha256,
+                                  sha256WithRSAEncryption,
                                   subjectKey);
 }
 
 // Creates a self-signed certificate with the given extension.
 static ByteString
 CreateCert(const char* subjectStr,
            const ByteString& extension,
            /*out*/ ScopedTestKeyPair& subjectKey)
--- a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp
+++ b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp
@@ -438,17 +438,17 @@ protected:
       return ByteString();
     }
     return ::mozilla::pkix::test::CreateEncodedCertificate(
                                     v3,
                                     sha256WithRSAEncryption,
                                     serialNumberDER, issuerDER, notBefore,
                                     notAfter, subjectDER, extensions,
                                     signerKeyPair,
-                                    SignatureAlgorithm::rsa_pkcs1_with_sha256,
+                                    sha256WithRSAEncryption,
                                     keyPair);
   }
 
   static const Input OCSPSigningEKUDER;
 };
 
 /*static*/ const Input pkixocsp_VerifyEncodedResponse_DelegatedResponder::
   OCSPSigningEKUDER(tlv_id_kp_OCSPSigning);
--- a/security/pkix/test/lib/pkixtestnss.cpp
+++ b/security/pkix/test/lib/pkixtestnss.cpp
@@ -68,26 +68,24 @@ public:
                  const ByteString& spk,
                  SECKEYPrivateKey* privateKey)
     : TestKeyPair(spki, spk)
     , privateKey(privateKey)
   {
   }
 
   virtual Result SignData(const ByteString& tbs,
-                          SignatureAlgorithm signatureAlgorithm,
+                          const ByteString& signatureAlgorithm,
                           /*out*/ ByteString& signature) const
   {
     SECOidTag signatureAlgorithmOidTag;
-    switch (signatureAlgorithm) {
-      case SignatureAlgorithm::rsa_pkcs1_with_sha256:
-        signatureAlgorithmOidTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
-        break;
-      default:
-        return Result::FATAL_ERROR_INVALID_ARGS;
+    if (signatureAlgorithm == sha256WithRSAEncryption) {
+      signatureAlgorithmOidTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
+    } else {
+      return Result::FATAL_ERROR_INVALID_ARGS;
     }
 
     SECItem signatureItem;
     if (SEC_SignData(&signatureItem, tbs.data(), tbs.length(),
                      privateKey.get(), signatureAlgorithmOidTag)
           != SECSuccess) {
       return MapPRErrorCodeToResult(PR_GetError());
     }
--- a/security/pkix/test/lib/pkixtestutil.cpp
+++ b/security/pkix/test/lib/pkixtestutil.cpp
@@ -36,17 +36,18 @@
 using namespace std;
 
 namespace mozilla { namespace pkix { namespace test {
 
 // python DottedOIDToCode.py --alg sha256WithRSAEncryption 1.2.840.113549.1.1.11
 static const uint8_t alg_sha256WithRSAEncryption[] = {
   0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b
 };
-const Input sha256WithRSAEncryption(alg_sha256WithRSAEncryption);
+const ByteString sha256WithRSAEncryption(alg_sha256WithRSAEncryption,
+  MOZILLA_PKIX_ARRAY_LENGTH(alg_sha256WithRSAEncryption));
 
 namespace {
 
 inline void
 fclose_void(FILE* file) {
   (void) fclose(file);
 }
 
@@ -337,37 +338,27 @@ YMDHMS(int16_t year, int16_t month, int1
   totalSeconds += minutes * 60;
   totalSeconds += seconds;
   return TimeFromElapsedSecondsAD(totalSeconds);
 }
 
 static ByteString
 SignedData(const ByteString& tbsData,
            /*optional*/ TestKeyPair* keyPair,
-           SignatureAlgorithm signatureAlgorithm,
+           const ByteString& signatureAlgorithm,
            bool corrupt, /*optional*/ const ByteString* certs)
 {
   ByteString signature;
   if (keyPair) {
     if (keyPair->SignData(tbsData, signatureAlgorithm, signature)
           != Success) {
        return ByteString();
      }
   }
 
-  ByteString signatureAlgorithmDER;
-  switch (signatureAlgorithm) {
-    case SignatureAlgorithm::rsa_pkcs1_with_sha256:
-      signatureAlgorithmDER.assign(alg_sha256WithRSAEncryption,
-                                   sizeof(alg_sha256WithRSAEncryption));
-      break;
-    default:
-      return ByteString();
-  }
-
   // TODO: add ability to have signatures of bit length not divisible by 8,
   // resulting in unused bits in the bitstring encoding
   ByteString signatureNested(BitString(signature, corrupt));
   if (ENCODING_FAILED(signatureNested)) {
     return ByteString();
   }
 
   ByteString certsNested;
@@ -379,17 +370,17 @@ SignedData(const ByteString& tbsData,
     }
     ByteString certsSequence(TLV(der::SEQUENCE, certsSequenceValue));
     certsNested = TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
                       certsSequence);
   }
 
   ByteString value;
   value.append(tbsData);
-  value.append(signatureAlgorithmDER);
+  value.append(signatureAlgorithm);
   value.append(signatureNested);
   value.append(certsNested);
   return TLV(der::SEQUENCE, value);
 }
 
 // Extension  ::=  SEQUENCE  {
 //      extnID      OBJECT IDENTIFIER,
 //      critical    BOOLEAN DEFAULT FALSE,
@@ -444,35 +435,36 @@ MaybeLogOutput(const ByteString& result,
     }
   }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // Certificates
 
 static ByteString TBSCertificate(long version, const ByteString& serialNumber,
-                                 Input signature, const ByteString& issuer,
+                                 const ByteString& signature,
+                                 const ByteString& issuer,
                                  time_t notBefore, time_t notAfter,
                                  const ByteString& subject,
                                  const ByteString& subjectPublicKeyInfo,
                                  /*optional*/ const ByteString* extensions);
 
 // Certificate  ::=  SEQUENCE  {
 //         tbsCertificate       TBSCertificate,
 //         signatureAlgorithm   AlgorithmIdentifier,
 //         signatureValue       BIT STRING  }
 ByteString
-CreateEncodedCertificate(long version, Input signature,
+CreateEncodedCertificate(long version, const ByteString& signature,
                          const ByteString& serialNumber,
                          const ByteString& issuerNameDER,
                          time_t notBefore, time_t notAfter,
                          const ByteString& subjectNameDER,
                          /*optional*/ const ByteString* extensions,
                          /*optional*/ TestKeyPair* issuerKeyPair,
-                         SignatureAlgorithm signatureAlgorithm,
+                         const ByteString& signatureAlgorithm,
                          /*out*/ ScopedTestKeyPair& keyPairResult)
 {
   // It may be the case that privateKeyResult references the same TestKeyPair
   // as issuerKeyPair. Thus, we can't set keyPairResult until after we're done
   // with issuerKeyPair.
   ScopedTestKeyPair subjectKeyPair(GenerateKeyPair());
   if (!subjectKeyPair) {
     return ByteString();
@@ -513,33 +505,33 @@ CreateEncodedCertificate(long version, I
 //      issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
 //                           -- If present, version MUST be v2 or v3
 //      subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
 //                           -- If present, version MUST be v2 or v3
 //      extensions      [3]  Extensions OPTIONAL
 //                           -- If present, version MUST be v3 --  }
 static ByteString
 TBSCertificate(long versionValue,
-               const ByteString& serialNumber, Input signature,
+               const ByteString& serialNumber, const ByteString& signature,
                const ByteString& issuer, time_t notBeforeTime,
                time_t notAfterTime, const ByteString& subject,
                const ByteString& subjectPublicKeyInfo,
                /*optional*/ const ByteString* extensions)
 {
   ByteString value;
 
   if (versionValue != static_cast<long>(der::Version::v1)) {
     ByteString versionInteger(Integer(versionValue));
     ByteString version(TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
                            versionInteger));
     value.append(version);
   }
 
   value.append(serialNumber);
-  value.append(signature.UnsafeGetData(), signature.GetLength());
+  value.append(signature);
   value.append(issuer);
 
   // Validity ::= SEQUENCE {
   //       notBefore      Time,
   //       notAfter       Time }
   ByteString validity;
   {
     ByteString notBefore(TimeToTimeChoice(notBeforeTime));
@@ -761,17 +753,17 @@ BasicOCSPResponse(OCSPResponseContext& c
 {
   ByteString tbsResponseData(ResponseData(context));
   if (ENCODING_FAILED(tbsResponseData)) {
     return ByteString();
   }
 
   // TODO(bug 980538): certs
   return SignedData(tbsResponseData, context.signerKeyPair.get(),
-                    SignatureAlgorithm::rsa_pkcs1_with_sha256,
+                    sha256WithRSAEncryption,
                     context.badSignature, context.certs);
 }
 
 // Extension ::= SEQUENCE {
 //   id               OBJECT IDENTIFIER,
 //   critical         BOOLEAN DEFAULT FALSE
 //   value            OCTET STRING
 // }
--- a/security/pkix/test/lib/pkixtestutil.h
+++ b/security/pkix/test/lib/pkixtestutil.h
@@ -69,17 +69,17 @@ static const uint8_t tlv_id_kp_OCSPSigni
   0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09
 };
 
 // python DottedOIDToCode.py --tlv id-kp-serverAuth 1.3.6.1.5.5.7.3.1
 static const uint8_t tlv_id_kp_serverAuth[] = {
   0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01
 };
 
-extern const Input sha256WithRSAEncryption;
+extern const ByteString sha256WithRSAEncryption;
 
 // e.g. YMDHMS(2016, 12, 31, 1, 23, 45) => 2016-12-31:01:23:45 (GMT)
 mozilla::pkix::Time YMDHMS(int16_t year, int16_t month, int16_t day,
                            int16_t hour, int16_t minutes, int16_t seconds);
 
 ByteString CNToDERName(const char* cn);
 
 class TestKeyPair
@@ -91,17 +91,17 @@ public:
   // what is encoded in certificates.
   const ByteString subjectPublicKeyInfo;
 
   // The DER encoding of subjectPublicKeyInfo.subjectPublicKey. This is what is
   // hashed to create CertIDs for OCSP.
   const ByteString subjectPublicKey;
 
   virtual Result SignData(const ByteString& tbs,
-                          SignatureAlgorithm signatureAlgorithm,
+                          const ByteString& signatureAlgorithm,
                           /*out*/ ByteString& signature) const = 0;
 
   virtual TestKeyPair* Clone() const = 0;
 protected:
   TestKeyPair(const ByteString& spki, const ByteString& spk)
     : subjectPublicKeyInfo(spki)
     , subjectPublicKey(spk)
   {
@@ -134,35 +134,38 @@ Result TestDigestBuf(Input item, /*out*/
 Result TamperOnce(/*in/out*/ ByteString& item, const ByteString& from,
                   const ByteString& to);
 
 ///////////////////////////////////////////////////////////////////////////////
 // Encode Certificates
 
 enum Version { v1 = 0, v2 = 1, v3 = 2 };
 
-// signature is assumed to be the DER encoding of an AlgorithmIdentifer.
+// signature is assumed to be the DER encoding of an AlgorithmIdentifer. It is
+// put into the signature field of the TBSCertificate. In most cases, it will
+// be the same as signatureAlgorithm, which is the algorithm actually used
+// to sign the certificate.
 // serialNumber is assumed to be the DER encoding of an INTEGER.
 //
 // If extensions is null, then no extensions will be encoded. Otherwise,
 // extensions must point to an array of ByteStrings, terminated with an empty
 // ByteString. (If the first item of the array is empty then an empty
 // Extensions sequence will be encoded.)
 //
 // If issuerPrivateKey is null, then the certificate will be self-signed.
 // Parameter order is based on the order of the attributes of the certificate
 // in RFC 5280.
-ByteString CreateEncodedCertificate(long version, Input signature,
+ByteString CreateEncodedCertificate(long version, const ByteString& signature,
                                     const ByteString& serialNumber,
                                     const ByteString& issuerNameDER,
                                     time_t notBefore, time_t notAfter,
                                     const ByteString& subjectNameDER,
                                     /*optional*/ const ByteString* extensions,
                                     /*optional*/ TestKeyPair* issuerKeyPair,
-                                    SignatureAlgorithm signatureAlgorithm,
+                                    const ByteString& signatureAlgorithm,
                                     /*out*/ ScopedTestKeyPair& keyPairResult);
 
 ByteString CreateEncodedSerialNumber(long value);
 
 MOZILLA_PKIX_ENUM_CLASS ExtensionCriticality { NotCritical = 0, Critical = 1 };
 
 ByteString CreateEncodedBasicConstraints(bool isCA,
                                          /*optional*/ long* pathLenConstraint,