summaryrefslogtreecommitdiffstats
path: root/security/nss/gtests/mozpkix_gtest/pkixder_pki_types_tests.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /security/nss/gtests/mozpkix_gtest/pkixder_pki_types_tests.cpp
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'security/nss/gtests/mozpkix_gtest/pkixder_pki_types_tests.cpp')
-rw-r--r--security/nss/gtests/mozpkix_gtest/pkixder_pki_types_tests.cpp727
1 files changed, 727 insertions, 0 deletions
diff --git a/security/nss/gtests/mozpkix_gtest/pkixder_pki_types_tests.cpp b/security/nss/gtests/mozpkix_gtest/pkixder_pki_types_tests.cpp
new file mode 100644
index 0000000000..fa5c551237
--- /dev/null
+++ b/security/nss/gtests/mozpkix_gtest/pkixder_pki_types_tests.cpp
@@ -0,0 +1,727 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This code is made available to you under your choice of the following sets
+ * of licensing terms:
+ */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+/* Copyright 2013 Mozilla Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <functional>
+#include <vector>
+
+#include "pkixgtest.h"
+
+#include "mozpkix/pkixtypes.h"
+#include "mozpkix/pkixder.h"
+
+using namespace mozilla::pkix;
+using namespace mozilla::pkix::der;
+using namespace mozilla::pkix::test;
+
+class pkixder_pki_types_tests : public ::testing::Test { };
+
+TEST_F(pkixder_pki_types_tests, CertificateSerialNumber)
+{
+ const uint8_t DER_CERT_SERIAL[] = {
+ 0x02, // INTEGER
+ 8, // length
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
+ };
+ Input input(DER_CERT_SERIAL);
+ Reader reader(input);
+
+ Input item;
+ ASSERT_EQ(Success, CertificateSerialNumber(reader, item));
+
+ Input expected;
+ ASSERT_EQ(Success,
+ expected.Init(DER_CERT_SERIAL + 2, sizeof DER_CERT_SERIAL - 2));
+ ASSERT_TRUE(InputsAreEqual(expected, item));
+}
+
+TEST_F(pkixder_pki_types_tests, CertificateSerialNumberLongest)
+{
+ const uint8_t DER_CERT_SERIAL_LONGEST[] = {
+ 0x02, // INTEGER
+ 20, // length
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
+ };
+ Input input(DER_CERT_SERIAL_LONGEST);
+ Reader reader(input);
+
+ Input item;
+ ASSERT_EQ(Success, CertificateSerialNumber(reader, item));
+
+ Input expected;
+ ASSERT_EQ(Success,
+ expected.Init(DER_CERT_SERIAL_LONGEST + 2,
+ sizeof DER_CERT_SERIAL_LONGEST - 2));
+ ASSERT_TRUE(InputsAreEqual(expected, item));
+}
+
+TEST_F(pkixder_pki_types_tests, CertificateSerialNumberCrazyLong)
+{
+ const uint8_t DER_CERT_SERIAL_CRAZY_LONG[] = {
+ 0x02, // INTEGER
+ 32, // length
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
+ };
+ Input input(DER_CERT_SERIAL_CRAZY_LONG);
+ Reader reader(input);
+
+ Input item;
+ ASSERT_EQ(Success, CertificateSerialNumber(reader, item));
+}
+
+TEST_F(pkixder_pki_types_tests, CertificateSerialNumberZeroLength)
+{
+ const uint8_t DER_CERT_SERIAL_ZERO_LENGTH[] = {
+ 0x02, // INTEGER
+ 0x00 // length
+ };
+ Input input(DER_CERT_SERIAL_ZERO_LENGTH);
+ Reader reader(input);
+
+ Input item;
+ ASSERT_EQ(Result::ERROR_INVALID_INTEGER_ENCODING,
+ CertificateSerialNumber(reader, item));
+}
+
+TEST_F(pkixder_pki_types_tests, OptionalVersionV1ExplicitEncodingAllowed)
+{
+ const uint8_t DER_OPTIONAL_VERSION_V1[] = {
+ 0xa0, 0x03, // context specific 0
+ 0x02, 0x01, 0x00 // INTEGER(0)
+ };
+ Input input(DER_OPTIONAL_VERSION_V1);
+ Reader reader(input);
+
+ // XXX(bug 1031093): We shouldn't accept an explicit encoding of v1, but we
+ // do here for compatibility reasons.
+ // Version version;
+ // ASSERT_EQ(Result::ERROR_BAD_DER, OptionalVersion(reader, version));
+ der::Version version = der::Version::v3;
+ ASSERT_EQ(Success, OptionalVersion(reader, version));
+ ASSERT_EQ(der::Version::v1, version);
+}
+
+TEST_F(pkixder_pki_types_tests, OptionalVersionV2)
+{
+ const uint8_t DER_OPTIONAL_VERSION_V2[] = {
+ 0xa0, 0x03, // context specific 0
+ 0x02, 0x01, 0x01 // INTEGER(1)
+ };
+ Input input(DER_OPTIONAL_VERSION_V2);
+ Reader reader(input);
+
+ der::Version version = der::Version::v1;
+ ASSERT_EQ(Success, OptionalVersion(reader, version));
+ ASSERT_EQ(der::Version::v2, version);
+}
+
+TEST_F(pkixder_pki_types_tests, OptionalVersionV3)
+{
+ const uint8_t DER_OPTIONAL_VERSION_V3[] = {
+ 0xa0, 0x03, // context specific 0
+ 0x02, 0x01, 0x02 // INTEGER(2)
+ };
+ Input input(DER_OPTIONAL_VERSION_V3);
+ Reader reader(input);
+
+ der::Version version = der::Version::v1;
+ ASSERT_EQ(Success, OptionalVersion(reader, version));
+ ASSERT_EQ(der::Version::v3, version);
+}
+
+TEST_F(pkixder_pki_types_tests, OptionalVersionUnknown)
+{
+ const uint8_t DER_OPTIONAL_VERSION_INVALID[] = {
+ 0xa0, 0x03, // context specific 0
+ 0x02, 0x01, 0x42 // INTEGER(0x42)
+ };
+ Input input(DER_OPTIONAL_VERSION_INVALID);
+ Reader reader(input);
+
+ der::Version version = der::Version::v1;
+ ASSERT_EQ(Result::ERROR_BAD_DER, OptionalVersion(reader, version));
+}
+
+TEST_F(pkixder_pki_types_tests, OptionalVersionInvalidTooLong)
+{
+ const uint8_t DER_OPTIONAL_VERSION_INVALID_TOO_LONG[] = {
+ 0xa0, 0x03, // context specific 0
+ 0x02, 0x02, 0x12, 0x34 // INTEGER(0x1234)
+ };
+ Input input(DER_OPTIONAL_VERSION_INVALID_TOO_LONG);
+ Reader reader(input);
+
+ der::Version version;
+ ASSERT_EQ(Result::ERROR_BAD_DER, OptionalVersion(reader, version));
+}
+
+TEST_F(pkixder_pki_types_tests, OptionalVersionMissing)
+{
+ const uint8_t DER_OPTIONAL_VERSION_MISSING[] = {
+ 0x02, 0x11, 0x22 // INTEGER
+ };
+ Input input(DER_OPTIONAL_VERSION_MISSING);
+ Reader reader(input);
+
+ der::Version version = der::Version::v3;
+ ASSERT_EQ(Success, OptionalVersion(reader, version));
+ ASSERT_EQ(der::Version::v1, version);
+}
+
+static const size_t MAX_ALGORITHM_OID_DER_LENGTH = 65;
+
+struct InvalidAlgorithmIdentifierTestInfo
+{
+ uint8_t der[MAX_ALGORITHM_OID_DER_LENGTH];
+ size_t derLength;
+};
+
+struct ValidDigestAlgorithmIdentifierTestInfo
+{
+ DigestAlgorithm algorithm;
+ uint8_t der[MAX_ALGORITHM_OID_DER_LENGTH];
+ size_t derLength;
+};
+
+class pkixder_DigestAlgorithmIdentifier_Valid
+ : public ::testing::Test
+ , public ::testing::WithParamInterface<ValidDigestAlgorithmIdentifierTestInfo>
+{
+};
+
+static const ValidDigestAlgorithmIdentifierTestInfo
+ VALID_DIGEST_ALGORITHM_TEST_INFO[] =
+{
+ { DigestAlgorithm::sha512,
+ { 0x30, 0x0b, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 },
+ 13
+ },
+ { DigestAlgorithm::sha384,
+ { 0x30, 0x0b, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 },
+ 13
+ },
+ { DigestAlgorithm::sha256,
+ { 0x30, 0x0b, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 },
+ 13
+ },
+ { DigestAlgorithm::sha1,
+ { 0x30, 0x07, 0x06, 0x05,
+ 0x2b, 0x0e, 0x03, 0x02, 0x1a },
+ 9
+ },
+};
+
+TEST_P(pkixder_DigestAlgorithmIdentifier_Valid, Valid)
+{
+ const ValidDigestAlgorithmIdentifierTestInfo& param(GetParam());
+
+ {
+ Input input;
+ ASSERT_EQ(Success, input.Init(param.der, param.derLength));
+ Reader reader(input);
+ DigestAlgorithm alg;
+ ASSERT_EQ(Success, DigestAlgorithmIdentifier(reader, alg));
+ ASSERT_EQ(param.algorithm, alg);
+ ASSERT_EQ(Success, End(reader));
+ }
+
+ {
+ uint8_t derWithNullParam[MAX_ALGORITHM_OID_DER_LENGTH + 2];
+ memcpy(derWithNullParam, param.der, param.derLength);
+ derWithNullParam[1] += 2; // we're going to expand the value by 2 bytes
+ derWithNullParam[param.derLength] = 0x05; // NULL tag
+ derWithNullParam[param.derLength + 1] = 0x00; // length zero
+
+ Input input;
+ ASSERT_EQ(Success, input.Init(derWithNullParam, param.derLength + 2));
+ Reader reader(input);
+ DigestAlgorithm alg;
+ ASSERT_EQ(Success, DigestAlgorithmIdentifier(reader, alg));
+ ASSERT_EQ(param.algorithm, alg);
+ ASSERT_EQ(Success, End(reader));
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(pkixder_DigestAlgorithmIdentifier_Valid,
+ pkixder_DigestAlgorithmIdentifier_Valid,
+ testing::ValuesIn(VALID_DIGEST_ALGORITHM_TEST_INFO));
+
+class pkixder_DigestAlgorithmIdentifier_Invalid
+ : public ::testing::Test
+ , public ::testing::WithParamInterface<InvalidAlgorithmIdentifierTestInfo>
+{
+};
+
+static const InvalidAlgorithmIdentifierTestInfo
+ INVALID_DIGEST_ALGORITHM_TEST_INFO[] =
+{
+ { // MD5
+ { 0x30, 0x0a, 0x06, 0x08,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05 },
+ 12,
+ },
+ { // ecdsa-with-SHA256 (1.2.840.10045.4.3.2) (not a hash algorithm)
+ { 0x30, 0x0a, 0x06, 0x08,
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02 },
+ 12,
+ },
+};
+
+TEST_P(pkixder_DigestAlgorithmIdentifier_Invalid, Invalid)
+{
+ const InvalidAlgorithmIdentifierTestInfo& param(GetParam());
+ Input input;
+ ASSERT_EQ(Success, input.Init(param.der, param.derLength));
+ Reader reader(input);
+ DigestAlgorithm alg;
+ ASSERT_EQ(Result::ERROR_INVALID_ALGORITHM,
+ DigestAlgorithmIdentifier(reader, alg));
+}
+
+INSTANTIATE_TEST_SUITE_P(pkixder_DigestAlgorithmIdentifier_Invalid,
+ pkixder_DigestAlgorithmIdentifier_Invalid,
+ testing::ValuesIn(INVALID_DIGEST_ALGORITHM_TEST_INFO));
+
+struct ValidSignatureAlgorithmIdentifierValueTestInfo
+{
+ PublicKeyAlgorithm publicKeyAlg;
+ DigestAlgorithm digestAlg;
+ uint8_t der[MAX_ALGORITHM_OID_DER_LENGTH];
+ size_t derLength;
+ bool explicitNullAllowed;
+};
+
+static const ValidSignatureAlgorithmIdentifierValueTestInfo
+ VALID_SIGNATURE_ALGORITHM_VALUE_TEST_INFO[] =
+{
+ // ECDSA
+ { PublicKeyAlgorithm::ECDSA,
+ DigestAlgorithm::sha512,
+ { 0x06, 0x08,
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04 },
+ 10,
+ true,
+ },
+ { PublicKeyAlgorithm::ECDSA,
+ DigestAlgorithm::sha384,
+ { 0x06, 0x08,
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03 },
+ 10,
+ true,
+ },
+ { PublicKeyAlgorithm::ECDSA,
+ DigestAlgorithm::sha256,
+ { 0x06, 0x08,
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02 },
+ 10,
+ true,
+ },
+ { PublicKeyAlgorithm::ECDSA,
+ DigestAlgorithm::sha1,
+ { 0x06, 0x07,
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01 },
+ 9,
+ true,
+ },
+
+ // RSA PKCS#1 1.5
+ { PublicKeyAlgorithm::RSA_PKCS1,
+ DigestAlgorithm::sha512,
+ { 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d },
+ 11,
+ true,
+ },
+ { PublicKeyAlgorithm::RSA_PKCS1,
+ DigestAlgorithm::sha384,
+ { 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c },
+ 11,
+ true,
+ },
+ { PublicKeyAlgorithm::RSA_PKCS1,
+ DigestAlgorithm::sha256,
+ { 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b },
+ 11,
+ true,
+ },
+ { PublicKeyAlgorithm::RSA_PKCS1,
+ DigestAlgorithm::sha1,
+ // IETF Standard OID
+ { 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05 },
+ 11,
+ true,
+ },
+ { PublicKeyAlgorithm::RSA_PKCS1,
+ DigestAlgorithm::sha1,
+ // Legacy OIW OID (bug 1042479)
+ { 0x06, 0x05,
+ 0x2b, 0x0e, 0x03, 0x02, 0x1d },
+ 7,
+ true,
+ },
+
+ // RSA-PSS
+ { PublicKeyAlgorithm::RSA_PSS,
+ DigestAlgorithm::sha256,
+ { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30,
+ 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06,
+ 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
+ 0xa2, 0x03, 0x02, 0x01, 0x20 },
+ 65,
+ false,
+ },
+
+ { PublicKeyAlgorithm::RSA_PSS,
+ DigestAlgorithm::sha384,
+ { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30,
+ 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06,
+ 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00,
+ 0xa2, 0x03, 0x02, 0x01, 0x30 },
+ 65,
+ false,
+ },
+
+ { PublicKeyAlgorithm::RSA_PSS,
+ DigestAlgorithm::sha512,
+ { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30,
+ 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06,
+ 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00,
+ 0xa2, 0x03, 0x02, 0x01, 0x40 },
+ 65,
+ false,
+ },
+};
+
+class pkixder_SignatureAlgorithmIdentifierValue_Valid
+ : public ::testing::Test
+ , public ::testing::WithParamInterface<
+ ValidSignatureAlgorithmIdentifierValueTestInfo>
+{
+};
+
+TEST_P(pkixder_SignatureAlgorithmIdentifierValue_Valid, Valid)
+{
+ const ValidSignatureAlgorithmIdentifierValueTestInfo& param(GetParam());
+
+ {
+ Input input;
+ ASSERT_EQ(Success, input.Init(param.der, param.derLength));
+ Reader reader(input);
+ PublicKeyAlgorithm publicKeyAlg;
+ DigestAlgorithm digestAlg;
+ ASSERT_EQ(Success,
+ SignatureAlgorithmIdentifierValue(reader, publicKeyAlg,
+ digestAlg));
+ ASSERT_EQ(param.publicKeyAlg, publicKeyAlg);
+ ASSERT_EQ(param.digestAlg, digestAlg);
+ ASSERT_EQ(Success, End(reader));
+ }
+
+ uint8_t derWithNullParam[MAX_ALGORITHM_OID_DER_LENGTH + 2];
+ memcpy(derWithNullParam, param.der, param.derLength);
+ derWithNullParam[param.derLength] = 0x05; // NULL tag
+ derWithNullParam[param.derLength + 1] = 0x00; // length zero
+
+ Input input;
+ ASSERT_EQ(Success, input.Init(derWithNullParam, param.derLength + 2));
+ Reader reader(input);
+ PublicKeyAlgorithm publicKeyAlg;
+ DigestAlgorithm digestAlg;
+ ASSERT_EQ(param.explicitNullAllowed
+ ? Success
+ : Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED,
+ SignatureAlgorithmIdentifierValue(reader, publicKeyAlg,
+ digestAlg));
+ if (param.explicitNullAllowed) {
+ ASSERT_EQ(param.publicKeyAlg, publicKeyAlg);
+ ASSERT_EQ(param.digestAlg, digestAlg);
+ ASSERT_EQ(Success, End(reader));
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ pkixder_SignatureAlgorithmIdentifierValue_Valid,
+ pkixder_SignatureAlgorithmIdentifierValue_Valid,
+ testing::ValuesIn(VALID_SIGNATURE_ALGORITHM_VALUE_TEST_INFO));
+
+static const InvalidAlgorithmIdentifierTestInfo
+ INVALID_SIGNATURE_ALGORITHM_VALUE_TEST_INFO[] =
+{
+ // id-dsa-with-sha256 (2.16.840.1.101.3.4.3.2)
+ { { 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x02 },
+ 11,
+ },
+
+ // id-dsa-with-sha1 (1.2.840.10040.4.3)
+ { { 0x06, 0x07,
+ 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x03 },
+ 9,
+ },
+
+ // RSA-with-MD5 (1.2.840.113549.1.1.4)
+ { { 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04 },
+ 11,
+ },
+
+ // id-sha256 (2.16.840.1.101.3.4.2.1). It is invalid because SHA-256 is not
+ // a signature algorithm.
+ { { 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 },
+ 11,
+ },
+
+ // RSA-PSS with SHA-256, MGF-1 with SHA-256, and a salt length of 48 bytes
+ { { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30,
+ 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06,
+ 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
+ 0xa2, 0x03, 0x02, 0x01, 0x30 },
+ 65,
+ },
+
+ // RSA-PSS with SHA-512, MGF-1 with SHA-256, and a salt length of 32 bytes
+ { { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30,
+ 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06,
+ 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
+ 0xa2, 0x03, 0x02, 0x01, 0x20 },
+ 65,
+ },
+
+ // RSA-PSS with omitted parameters
+ { { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a },
+ 11,
+ },
+
+ // RSA-PSS with NULL parameters
+ { { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a,
+ 0x05, 0x00 },
+ 13,
+ },
+};
+
+class pkixder_SignatureAlgorithmIdentifier_Invalid
+ : public ::testing::Test
+ , public ::testing::WithParamInterface<InvalidAlgorithmIdentifierTestInfo>
+{
+};
+
+TEST_P(pkixder_SignatureAlgorithmIdentifier_Invalid, Invalid)
+{
+ const InvalidAlgorithmIdentifierTestInfo& param(GetParam());
+ Input input;
+ ASSERT_EQ(Success, input.Init(param.der, param.derLength));
+ Reader reader(input);
+ der::PublicKeyAlgorithm publicKeyAlg;
+ DigestAlgorithm digestAlg;
+ ASSERT_EQ(Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED,
+ SignatureAlgorithmIdentifierValue(reader, publicKeyAlg, digestAlg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ pkixder_SignatureAlgorithmIdentifier_Invalid,
+ pkixder_SignatureAlgorithmIdentifier_Invalid,
+ testing::ValuesIn(INVALID_SIGNATURE_ALGORITHM_VALUE_TEST_INFO));
+
+struct EncodedECDSASignatureValidParams {
+ std::vector<uint8_t> signature;
+ std::vector<uint8_t> rExpected;
+ std::vector<uint8_t> sExpected;
+};
+
+::std::ostream& operator<<(::std::ostream& os, const EncodedECDSASignatureValidParams&)
+{
+ return os << "TODO (bug 1318770)";
+}
+
+static const EncodedECDSASignatureValidParams
+ ENCODEDECDSASIGNATURE_VALID_PARAMS[] =
+{
+ {
+ { 0x30, 0x07, // SEQUENCE
+ 0x02, 0x01, 0x01, // INTEGER (0x01)
+ 0x02, 0x02, 0x05, 0x06 }, // INTEGER ([0x05, 0x06])
+ { 0x01 },
+ { 0x05, 0x06 },
+ },
+ {
+ { 0x30, 0x08, // SEQUENCE
+ 0x02, 0x03, 0x00, 0xb7, 0x0a, // INTEGER ([0xb7, 0x0a]) highest bit set
+ 0x02, 0x01, 0x02 }, // INTEGER (0x02)
+ { 0xb7, 0x0a },
+ { 0x02 },
+ },
+ {
+ { 0x30, 0x09, // SEQUENCE
+ 0x02, 0x03, 0x23, 0x00, 0x55, // INTEGER ([0x23, 0x00, 0x55])
+ 0x02, 0x02, 0x00, 0xf0 }, // INTEGER (0xf0) highest bit set
+ { 0x23, 0x00, 0x55 },
+ { 0xf0 },
+ },
+ {
+ { 0x30, 0x09, // SEQUENCE
+ 0x02, 0x03, 0x00, 0x93, 0x10, // INTEGER ([0x93, 0xl0]) highest bit set
+ 0x02, 0x02, 0x00, 0xcf }, // INTEGER (0xcf) highest bit set
+ { 0x93, 0x10, },
+ { 0xcf },
+ },
+};
+
+class pkixder_ECDSASigValue_valid
+ : public ::testing::Test
+ , public ::testing::WithParamInterface<EncodedECDSASignatureValidParams>
+{
+};
+
+
+TEST_P(pkixder_ECDSASigValue_valid, pkixder_ECDSASigValue_valid)
+{
+ const EncodedECDSASignatureValidParams& params(GetParam());
+
+ Input signature;
+ ASSERT_EQ(Success,
+ signature.Init(params.signature.data(), params.signature.size()));
+ Input r;
+ Input s;
+ ASSERT_EQ(Success, ECDSASigValue(signature, r, s));
+
+ Input rExpected;
+ ASSERT_EQ(Success,
+ rExpected.Init(params.rExpected.data(), params.rExpected.size()));
+ ASSERT_TRUE(InputsAreEqual(r, rExpected));
+
+ Input sExpected;
+ ASSERT_EQ(Success,
+ sExpected.Init(params.sExpected.data(), params.sExpected.size()));
+ ASSERT_TRUE(InputsAreEqual(s, sExpected));
+}
+
+INSTANTIATE_TEST_SUITE_P(pkixder_ECDSASigValue_valid,
+ pkixder_ECDSASigValue_valid,
+ testing::ValuesIn(ENCODEDECDSASIGNATURE_VALID_PARAMS));
+
+struct EncodedECDSASignatureInvalidParams {
+ std::vector<uint8_t> signature;
+ Result expectedResult;
+};
+
+::std::ostream& operator<<(::std::ostream& os, const EncodedECDSASignatureInvalidParams&)
+{
+ return os << "TODO (bug 1318770)";
+}
+
+static const EncodedECDSASignatureInvalidParams
+ ENCODEDECDSASIGNATURE_INVALID_PARAMS[] =
+{
+ {
+ { 0x05, 0x00 }, // not a SEQUENCE
+ Result::ERROR_BAD_DER
+ },
+ {
+ { 0x30, 0x00 }, // empty SEQUENCE
+ Result::ERROR_BAD_DER
+ },
+ {
+ { 0x30, 0x06,
+ 0x05, 0x01, 0x01, // NULL, not INTEGER
+ 0x02, 0x01, 0x01 },
+ Result::ERROR_BAD_DER
+ },
+ {
+ { 0x30, 0x08,
+ 0x02, 0x01, 0x01,
+ 0x02, 0x01, 0x01,
+ 0x05, 0x00 }, // trailing data in SEQUENCE
+ Result::ERROR_BAD_DER
+ },
+ { { 0x30, 0x06,
+ 0x02, 0x01, 0x01,
+ 0x02, 0x01, 0x01,
+ 0x05, 0x00 }, // trailing data after SEQUENCE
+ Result::ERROR_BAD_DER
+ },
+ {
+ { 0x30, 0x07,
+ 0x02, 0x01, 0x00, // not a positive INTEGER
+ 0x02, 0x02, 0x0f, 0x02 },
+ Result::ERROR_INVALID_INTEGER_ENCODING
+ },
+ {
+ { 0x30, 0x08,
+ 0x02, 0x02, 0x00, 0x01, // unnecessary zero padding
+ 0x02, 0x02, 0x0f, 0x02 },
+ Result::ERROR_INVALID_INTEGER_ENCODING
+ },
+ {
+ { 0x30, 0x07,
+ 0x02, 0x01, 0x01,
+ 0x02, 0x02, 0xff, 0x02 }, // negative INTEGER
+ Result::ERROR_INVALID_INTEGER_ENCODING
+ },
+ {
+ { 0x30, 0x06,
+ 0x02, 0x01, 0x01,
+ 0x02, 0x01, 0xf0 }, // negative INTEGER
+ Result::ERROR_INVALID_INTEGER_ENCODING
+ },
+};
+
+class pkixder_ECDSASigValue_invalid
+ : public ::testing::Test
+ , public ::testing::WithParamInterface<EncodedECDSASignatureInvalidParams>
+{
+};
+
+
+TEST_P(pkixder_ECDSASigValue_invalid, pkixder_ECDSASigValue_invalid)
+{
+ const EncodedECDSASignatureInvalidParams& params(GetParam());
+
+ Input signature;
+ ASSERT_EQ(Success,
+ signature.Init(params.signature.data(), params.signature.size()));
+ Input r;
+ Input s;
+ ASSERT_EQ(params.expectedResult, ECDSASigValue(signature, r, s));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ pkixder_ECDSASigValue_invalid, pkixder_ECDSASigValue_invalid,
+ testing::ValuesIn(ENCODEDECDSASIGNATURE_INVALID_PARAMS));