summaryrefslogtreecommitdiff
path: root/security/pkix/test
diff options
context:
space:
mode:
Diffstat (limited to 'security/pkix/test')
-rw-r--r--security/pkix/test/lib/pkixtestalg.cpp38
-rw-r--r--security/pkix/test/lib/pkixtestnss.cpp167
-rw-r--r--security/pkix/test/lib/pkixtestutil.cpp51
-rw-r--r--security/pkix/test/lib/pkixtestutil.h447
4 files changed, 132 insertions, 571 deletions
diff --git a/security/pkix/test/lib/pkixtestalg.cpp b/security/pkix/test/lib/pkixtestalg.cpp
index 9a2fcd69ae..d698154d04 100644
--- a/security/pkix/test/lib/pkixtestalg.cpp
+++ b/security/pkix/test/lib/pkixtestalg.cpp
@@ -1,29 +1,13 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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 2015 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 "pkixtestutil.h"
+#include "pkix/test/pkixtestutil.h"
-#include "pkixder.h"
+#include "pkix/pkixder.h"
+#include "nss_scoped_ptrs.h"
// python DottedOIDToCode.py --prefixdefine PREFIX_1_2_840_10040 1.2.840.10040
#define PREFIX_1_2_840_10040 0x2a, 0x86, 0x48, 0xce, 0x38
@@ -136,14 +120,14 @@ static const uint8_t DSS_G_RAW[] =
} // namespace
TestSignatureAlgorithm::TestSignatureAlgorithm(
- const TestPublicKeyAlgorithm& publicKeyAlg,
- TestDigestAlgorithmID digestAlg,
- const ByteString& algorithmIdentifier,
- bool accepted)
- : publicKeyAlg(publicKeyAlg)
- , digestAlg(digestAlg)
- , algorithmIdentifier(algorithmIdentifier)
- , accepted(accepted)
+ const TestPublicKeyAlgorithm& aPublicKeyAlg,
+ TestDigestAlgorithmID aDigestAlg,
+ const ByteString& aAlgorithmIdentifier,
+ bool aAccepted)
+ : publicKeyAlg(aPublicKeyAlg)
+ , digestAlg(aDigestAlg)
+ , algorithmIdentifier(aAlgorithmIdentifier)
+ , accepted(aAccepted)
{
}
diff --git a/security/pkix/test/lib/pkixtestnss.cpp b/security/pkix/test/lib/pkixtestnss.cpp
index ce9dfbb12e..001fdfbc46 100644
--- a/security/pkix/test/lib/pkixtestnss.cpp
+++ b/security/pkix/test/lib/pkixtestnss.cpp
@@ -1,27 +1,11 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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 "pkixtestutil.h"
+#include "pkix/test/pkixtestutil.h"
+#include "pkix/test/pkixtestnss.h"
#include <limits>
@@ -30,9 +14,10 @@
#include "nss.h"
#include "pk11pqg.h"
#include "pk11pub.h"
+#include "nss_scoped_ptrs.h"
#include "pkix/pkixnss.h"
-#include "pkixder.h"
-#include "pkixutil.h"
+#include "pkix/pkixder.h"
+#include "pkix/pkixutil.h"
#include "prinit.h"
#include "secerr.h"
#include "secitem.h"
@@ -41,19 +26,6 @@ namespace mozilla { namespace pkix { namespace test {
namespace {
-typedef ScopedPtr<SECKEYPublicKey, SECKEY_DestroyPublicKey>
- ScopedSECKEYPublicKey;
-typedef ScopedPtr<SECKEYPrivateKey, SECKEY_DestroyPrivateKey>
- ScopedSECKEYPrivateKey;
-
-inline void
-SECITEM_FreeItem_true(SECItem* item)
-{
- SECITEM_FreeItem(item, true);
-}
-
-typedef mozilla::pkix::ScopedPtr<SECItem, SECITEM_FreeItem_true> ScopedSECItem;
-
TestKeyPair* GenerateKeyPairInner();
void
@@ -77,12 +49,15 @@ InitReusedKeyPair()
class NSSTestKeyPair final : public TestKeyPair
{
public:
- // NSSTestKeyPair takes ownership of privateKey.
- NSSTestKeyPair(const TestPublicKeyAlgorithm& publicKeyAlg,
+ NSSTestKeyPair(const TestPublicKeyAlgorithm& aPublicKeyAlg,
const ByteString& spk,
- SECKEYPrivateKey* privateKey)
- : TestKeyPair(publicKeyAlg, spk)
- , privateKey(privateKey)
+ const ByteString& aEncryptedPrivateKey,
+ const ByteString& aEncryptionAlgorithm,
+ const ByteString& aEncryptionParams)
+ : TestKeyPair(aPublicKeyAlg, spk)
+ , encryptedPrivateKey(aEncryptedPrivateKey)
+ , encryptionAlgorithm(aEncryptionAlgorithm)
+ , encryptionParams(aEncryptionParams)
{
}
@@ -120,10 +95,50 @@ public:
abort();
}
+ ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ if (!slot) {
+ return MapPRErrorCodeToResult(PR_GetError());
+ }
+ SECItem encryptedPrivateKeyInfoItem = {
+ siBuffer,
+ const_cast<uint8_t*>(encryptedPrivateKey.data()),
+ static_cast<unsigned int>(encryptedPrivateKey.length())
+ };
+ SECItem encryptionAlgorithmItem = {
+ siBuffer,
+ const_cast<uint8_t*>(encryptionAlgorithm.data()),
+ static_cast<unsigned int>(encryptionAlgorithm.length())
+ };
+ SECItem encryptionParamsItem = {
+ siBuffer,
+ const_cast<uint8_t*>(encryptionParams.data()),
+ static_cast<unsigned int>(encryptionParams.length())
+ };
+ SECKEYEncryptedPrivateKeyInfo encryptedPrivateKeyInfo = {
+ nullptr,
+ { encryptionAlgorithmItem, encryptionParamsItem },
+ encryptedPrivateKeyInfoItem
+ };
+ SECItem passwordItem = { siBuffer, nullptr, 0 };
+ SECItem publicValueItem = {
+ siBuffer,
+ const_cast<uint8_t*>(subjectPublicKey.data()),
+ static_cast<unsigned int>(subjectPublicKey.length())
+ };
+ SECKEYPrivateKey* privateKey;
+ // This should always be an RSA key (we'll have aborted above if we're not
+ // doing an RSA signature).
+ if (PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(
+ slot.get(), &encryptedPrivateKeyInfo, &passwordItem, nullptr,
+ &publicValueItem, false, false, rsaKey, KU_ALL, &privateKey,
+ nullptr) != SECSuccess) {
+ return MapPRErrorCodeToResult(PR_GetError());
+ }
+ ScopedSECKEYPrivateKey scopedPrivateKey(privateKey);
SECItem signatureItem;
if (SEC_SignData(&signatureItem, tbs.data(),
static_cast<int>(tbs.length()),
- privateKey.get(), oidTag) != SECSuccess) {
+ scopedPrivateKey.get(), oidTag) != SECSuccess) {
return MapPRErrorCodeToResult(PR_GetError());
}
signature.assign(signatureItem.data, signatureItem.len);
@@ -133,40 +148,63 @@ public:
TestKeyPair* Clone() const override
{
- ScopedSECKEYPrivateKey
- privateKeyCopy(SECKEY_CopyPrivateKey(privateKey.get()));
- if (!privateKeyCopy) {
- return nullptr;
- }
return new (std::nothrow) NSSTestKeyPair(publicKeyAlg,
subjectPublicKey,
- privateKeyCopy.release());
+ encryptedPrivateKey,
+ encryptionAlgorithm,
+ encryptionParams);
}
private:
- ScopedSECKEYPrivateKey privateKey;
+ const ByteString encryptedPrivateKey;
+ const ByteString encryptionAlgorithm;
+ const ByteString encryptionParams;
};
} // namespace
// This private function is also used by Gecko's PSM test framework
// (OCSPCommon.cpp).
-//
-// Ownership of privateKey is transfered.
TestKeyPair* CreateTestKeyPair(const TestPublicKeyAlgorithm publicKeyAlg,
- const SECKEYPublicKey& publicKey,
- SECKEYPrivateKey* privateKey)
+ const ScopedSECKEYPublicKey& publicKey,
+ const ScopedSECKEYPrivateKey& privateKey)
{
- ScopedPtr<CERTSubjectPublicKeyInfo, SECKEY_DestroySubjectPublicKeyInfo>
- spki(SECKEY_CreateSubjectPublicKeyInfo(&publicKey));
+ ScopedCERTSubjectPublicKeyInfo
+ spki(SECKEY_CreateSubjectPublicKeyInfo(publicKey.get()));
if (!spki) {
return nullptr;
}
SECItem spkDER = spki->subjectPublicKey;
DER_ConvertBitString(&spkDER); // bits to bytes
- return new (std::nothrow) NSSTestKeyPair(publicKeyAlg,
- ByteString(spkDER.data, spkDER.len),
- privateKey);
+ ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+ if (!slot) {
+ return nullptr;
+ }
+ // Because NSSTestKeyPair isn't tracked by XPCOM and won't otherwise be aware
+ // of shutdown, we don't have a way to release NSS resources at the
+ // appropriate time. To work around this, NSSTestKeyPair doesn't hold on to
+ // NSS resources. Instead, we export the generated private key part as an
+ // encrypted blob (with an empty password and fairly lame encryption). When we
+ // need to use it (e.g. to sign something), we decrypt it and create a
+ // temporary key object.
+ SECItem passwordItem = { siBuffer, nullptr, 0 };
+ ScopedSECKEYEncryptedPrivateKeyInfo encryptedPrivateKey(
+ PK11_ExportEncryptedPrivKeyInfo(
+ slot.get(), SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC,
+ &passwordItem, privateKey.get(), 1, nullptr));
+ if (!encryptedPrivateKey) {
+ return nullptr;
+ }
+
+ return new (std::nothrow) NSSTestKeyPair(
+ publicKeyAlg,
+ ByteString(spkDER.data, spkDER.len),
+ ByteString(encryptedPrivateKey->encryptedData.data,
+ encryptedPrivateKey->encryptedData.len),
+ ByteString(encryptedPrivateKey->algorithm.algorithm.data,
+ encryptedPrivateKey->algorithm.algorithm.len),
+ ByteString(encryptedPrivateKey->algorithm.parameters.data,
+ encryptedPrivateKey->algorithm.parameters.len));
}
namespace {
@@ -174,18 +212,18 @@ namespace {
TestKeyPair*
GenerateKeyPairInner()
{
- ScopedPtr<PK11SlotInfo, PK11_FreeSlot> slot(PK11_GetInternalSlot());
+ ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot) {
abort();
}
+ PK11RSAGenParams params;
+ params.keySizeInBits = 2048;
+ params.pe = 65537;
// Bug 1012786: PK11_GenerateKeyPair can fail if there is insufficient
// entropy to generate a random key. Attempting to add some entropy and
// retrying appears to solve this issue.
for (uint32_t retries = 0; retries < 10; retries++) {
- PK11RSAGenParams params;
- params.keySizeInBits = 2048;
- params.pe = 3;
SECKEYPublicKey* publicKeyTemp = nullptr;
ScopedSECKEYPrivateKey
privateKey(PK11_GenerateKeyPair(slot.get(), CKM_RSA_PKCS_KEY_PAIR_GEN,
@@ -193,7 +231,7 @@ GenerateKeyPairInner()
nullptr));
ScopedSECKEYPublicKey publicKey(publicKeyTemp);
if (privateKey) {
- return CreateTestKeyPair(RSA_PKCS1(), *publicKey, privateKey.release());
+ return CreateTestKeyPair(RSA_PKCS1(), publicKey, privateKey);
}
assert(!publicKeyTemp);
@@ -206,8 +244,9 @@ GenerateKeyPairInner()
// random keys.
// https://xkcd.com/221/
static const uint8_t RANDOM_NUMBER[] = { 4, 4, 4, 4, 4, 4, 4, 4 };
- if (PK11_RandomUpdate((void*) &RANDOM_NUMBER,
- sizeof(RANDOM_NUMBER)) != SECSuccess) {
+ if (PK11_RandomUpdate(
+ const_cast<void*>(reinterpret_cast<const void*>(RANDOM_NUMBER)),
+ sizeof(RANDOM_NUMBER)) != SECSuccess) {
break;
}
}
@@ -240,7 +279,7 @@ GenerateDSSKeyPair()
{
InitNSSIfNeeded();
- ScopedPtr<PK11SlotInfo, PK11_FreeSlot> slot(PK11_GetInternalSlot());
+ ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot) {
return nullptr;
}
@@ -274,7 +313,7 @@ GenerateDSSKeyPair()
return nullptr;
}
ScopedSECKEYPublicKey publicKey(publicKeyTemp);
- return CreateTestKeyPair(DSS(), *publicKey, privateKey.release());
+ return CreateTestKeyPair(DSS(), publicKey, privateKey);
}
Result
diff --git a/security/pkix/test/lib/pkixtestutil.cpp b/security/pkix/test/lib/pkixtestutil.cpp
index fa4d7eeee0..32401af81b 100644
--- a/security/pkix/test/lib/pkixtestutil.cpp
+++ b/security/pkix/test/lib/pkixtestutil.cpp
@@ -1,27 +1,10 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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 "pkixtestutil.h"
+#include "pkix/test/pkixtestutil.h"
#include <cerrno>
#include <cstdio>
@@ -30,8 +13,8 @@
#include <sstream>
#include <cstdlib>
-#include "pkixder.h"
-#include "pkixutil.h"
+#include "pkix/pkixder.h"
+#include "pkix/pkixutil.h"
using namespace std;
@@ -39,12 +22,14 @@ namespace mozilla { namespace pkix { namespace test {
namespace {
-inline void
-fclose_void(FILE* file) {
- (void) fclose(file);
-}
-
-typedef mozilla::pkix::ScopedPtr<FILE, fclose_void> ScopedFILE;
+struct ScopedMaybeDeleteFile {
+ void operator()(FILE* f) {
+ if (f) {
+ (void)fclose(f);
+ }
+ }
+};
+typedef std::unique_ptr<FILE, ScopedMaybeDeleteFile> ScopedFILE;
FILE*
OpenFile(const string& dir, const string& filename, const string& mode)
@@ -151,8 +136,8 @@ OCSPResponseExtension::OCSPResponseExtension()
{
}
-OCSPResponseContext::OCSPResponseContext(const CertID& certID, time_t time)
- : certID(certID)
+OCSPResponseContext::OCSPResponseContext(const CertID& aCertID, time_t time)
+ : certID(aCertID)
, responseStatus(successful)
, skipResponseBytes(false)
, producedAt(time)
@@ -248,7 +233,7 @@ Integer(long value)
enum TimeEncoding { UTCTime = 0, GeneralizedTime = 1 };
// Windows doesn't provide gmtime_r, but it provides something very similar.
-#if defined(WIN32) && !defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+#if defined(_WINDOWS) && (!defined(_POSIX_C_SOURCE) || !defined(_POSIX_THREAD_SAFE_FUNCTIONS))
static tm*
gmtime_r(const time_t* t, /*out*/ tm* exploded)
{
@@ -738,7 +723,7 @@ CreateEncodedSerialNumber(long serialNumberValue)
// pathLenConstraint INTEGER (0..MAX) OPTIONAL }
ByteString
CreateEncodedBasicConstraints(bool isCA,
- /*optional*/ long* pathLenConstraintValue,
+ /*optional in*/ const long* pathLenConstraintValue,
Critical critical)
{
ByteString value;
@@ -1139,11 +1124,11 @@ CertStatus(OCSPResponseContext& context)
static const ByteString NO_UNUSED_BITS(1, 0x00);
// The SubjectPublicKeyInfo syntax is specified in RFC 5280 Section 4.1.
-TestKeyPair::TestKeyPair(const TestPublicKeyAlgorithm& publicKeyAlg,
+TestKeyPair::TestKeyPair(const TestPublicKeyAlgorithm& aPublicKeyAlg,
const ByteString& spk)
- : publicKeyAlg(publicKeyAlg)
+ : publicKeyAlg(aPublicKeyAlg)
, subjectPublicKeyInfo(TLV(der::SEQUENCE,
- publicKeyAlg.algorithmIdentifier +
+ aPublicKeyAlg.algorithmIdentifier +
TLV(der::BIT_STRING, NO_UNUSED_BITS + spk)))
, subjectPublicKey(spk)
{
diff --git a/security/pkix/test/lib/pkixtestutil.h b/security/pkix/test/lib/pkixtestutil.h
deleted file mode 100644
index 7e00ed4f3b..0000000000
--- a/security/pkix/test/lib/pkixtestutil.h
+++ /dev/null
@@ -1,447 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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.
- */
-
-#ifndef mozilla_pkix_test_pkixtestutils_h
-#define mozilla_pkix_test_pkixtestutils_h
-
-#include <ctime>
-#include <stdint.h> // Some Mozilla-supported compilers lack <cstdint>
-#include <string>
-#include <cstring>
-
-#include "pkix/pkixtypes.h"
-#include "../../lib/ScopedPtr.h"
-
-namespace mozilla { namespace pkix { namespace test {
-
-typedef std::basic_string<uint8_t> ByteString;
-
-inline bool ENCODING_FAILED(const ByteString& bs) { return bs.empty(); }
-
-template <size_t L>
-inline ByteString
-BytesToByteString(const uint8_t (&bytes)[L])
-{
- return ByteString(bytes, L);
-}
-
-// XXX: Ideally, we should define this instead:
-//
-// template <typename T, std::size_t N>
-// constexpr inline std::size_t
-// ArrayLength(T (&)[N])
-// {
-// return N;
-// }
-//
-// However, we don't because not all supported compilers support constexpr,
-// and we need to calculate array lengths in static_assert sometimes.
-//
-// XXX: Evaluates its argument twice
-#define MOZILLA_PKIX_ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
-
-bool InputEqualsByteString(Input input, const ByteString& bs);
-ByteString InputToByteString(Input input);
-
-// python DottedOIDToCode.py --tlv id-kp-OCSPSigning 1.3.6.1.5.5.7.3.9
-static const uint8_t tlv_id_kp_OCSPSigning[] = {
- 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
-};
-
-enum class TestDigestAlgorithmID
-{
- MD2,
- MD5,
- SHA1,
- SHA224,
- SHA256,
- SHA384,
- SHA512,
-};
-
-struct TestPublicKeyAlgorithm
-{
- explicit TestPublicKeyAlgorithm(const ByteString& algorithmIdentifier)
- : algorithmIdentifier(algorithmIdentifier) { }
- bool operator==(const TestPublicKeyAlgorithm& other) const
- {
- return algorithmIdentifier == other.algorithmIdentifier;
- }
- ByteString algorithmIdentifier;
-};
-
-ByteString DSS_P();
-ByteString DSS_Q();
-ByteString DSS_G();
-
-TestPublicKeyAlgorithm DSS();
-TestPublicKeyAlgorithm RSA_PKCS1();
-
-struct TestSignatureAlgorithm
-{
- TestSignatureAlgorithm(const TestPublicKeyAlgorithm& publicKeyAlg,
- TestDigestAlgorithmID digestAlg,
- const ByteString& algorithmIdentifier,
- bool accepted);
-
- TestPublicKeyAlgorithm publicKeyAlg;
- TestDigestAlgorithmID digestAlg;
- ByteString algorithmIdentifier;
- bool accepted;
-};
-
-TestSignatureAlgorithm md2WithRSAEncryption();
-TestSignatureAlgorithm md5WithRSAEncryption();
-TestSignatureAlgorithm sha1WithRSAEncryption();
-TestSignatureAlgorithm sha256WithRSAEncryption();
-
-// e.g. YMDHMS(2016, 12, 31, 1, 23, 45) => 2016-12-31:01:23:45 (GMT)
-mozilla::pkix::Time YMDHMS(uint16_t year, uint16_t month, uint16_t day,
- uint16_t hour, uint16_t minutes, uint16_t seconds);
-
-ByteString TLV(uint8_t tag, size_t length, const ByteString& value);
-
-inline ByteString
-TLV(uint8_t tag, const ByteString& value)
-{
- return TLV(tag, value.length(), value);
-}
-
-// Although we can't enforce it without relying on Cuser-defined literals,
-// which aren't supported by all of our compilers yet, you should only pass
-// string literals as the last parameter to the following two functions.
-
-template <size_t N>
-inline ByteString
-TLV(uint8_t tag, const char(&value)[N])
-{
- static_assert(N > 0, "cannot have string literal of size 0");
- assert(value[N - 1] == 0);
- return TLV(tag, ByteString(reinterpret_cast<const uint8_t*>(&value), N - 1));
-}
-
-template <size_t N>
-inline ByteString
-TLV(uint8_t tag, size_t length, const char(&value)[N])
-{
- static_assert(N > 0, "cannot have string literal of size 0");
- assert(value[N - 1] == 0);
- return TLV(tag, length,
- ByteString(reinterpret_cast<const uint8_t*>(&value), N - 1));
-}
-
-ByteString Boolean(bool value);
-ByteString Integer(long value);
-
-ByteString CN(const ByteString&, uint8_t encodingTag = 0x0c /*UTF8String*/);
-
-inline ByteString
-CN(const char* value, uint8_t encodingTag = 0x0c /*UTF8String*/)
-{
- return CN(ByteString(reinterpret_cast<const uint8_t*>(value),
- std::strlen(value)), encodingTag);
-}
-
-ByteString OU(const ByteString&, uint8_t encodingTag = 0x0c /*UTF8String*/);
-
-inline ByteString
-OU(const char* value, uint8_t encodingTag = 0x0c /*UTF8String*/)
-{
- return OU(ByteString(reinterpret_cast<const uint8_t*>(value),
- std::strlen(value)), encodingTag);
-}
-
-ByteString emailAddress(const ByteString&);
-
-inline ByteString
-emailAddress(const char* value)
-{
- return emailAddress(ByteString(reinterpret_cast<const uint8_t*>(value),
- std::strlen(value)));
-}
-
-// RelativeDistinguishedName ::=
-// SET SIZE (1..MAX) OF AttributeTypeAndValue
-//
-ByteString RDN(const ByteString& avas);
-
-// Name ::= CHOICE { -- only one possibility for now --
-// rdnSequence RDNSequence }
-//
-// RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
-//
-ByteString Name(const ByteString& rdns);
-
-inline ByteString
-CNToDERName(const ByteString& cn)
-{
- return Name(RDN(CN(cn)));
-}
-
-inline ByteString
-CNToDERName(const char* cn)
-{
- return Name(RDN(CN(cn)));
-}
-
-// GeneralName ::= CHOICE {
-// otherName [0] OtherName,
-// rfc822Name [1] IA5String,
-// dNSName [2] IA5String,
-// x400Address [3] ORAddress,
-// directoryName [4] Name,
-// ediPartyName [5] EDIPartyName,
-// uniformResourceIdentifier [6] IA5String,
-// iPAddress [7] OCTET STRING,
-// registeredID [8] OBJECT IDENTIFIER }
-
-inline ByteString
-RFC822Name(const ByteString& name)
-{
- // (2 << 6) means "context-specific", 1 is the GeneralName tag.
- return TLV((2 << 6) | 1, name);
-}
-
-template <size_t L>
-inline ByteString
-RFC822Name(const char (&bytes)[L])
-{
- return RFC822Name(ByteString(reinterpret_cast<const uint8_t*>(&bytes),
- L - 1));
-}
-
-inline ByteString
-DNSName(const ByteString& name)
-{
- // (2 << 6) means "context-specific", 2 is the GeneralName tag.
- return TLV((2 << 6) | 2, name);
-}
-
-template <size_t L>
-inline ByteString
-DNSName(const char (&bytes)[L])
-{
- return DNSName(ByteString(reinterpret_cast<const uint8_t*>(&bytes),
- L - 1));
-}
-
-inline ByteString
-DirectoryName(const ByteString& name)
-{
- // (2 << 6) means "context-specific", (1 << 5) means "constructed", and 4 is
- // the DirectoryName tag.
- return TLV((2 << 6) | (1 << 5) | 4, name);
-}
-
-inline ByteString
-IPAddress()
-{
- // (2 << 6) means "context-specific", 7 is the GeneralName tag.
- return TLV((2 << 6) | 7, ByteString());
-}
-
-template <size_t L>
-inline ByteString
-IPAddress(const uint8_t (&bytes)[L])
-{
- // (2 << 6) means "context-specific", 7 is the GeneralName tag.
- return TLV((2 << 6) | 7, ByteString(bytes, L));
-}
-
-// Names should be zero or more GeneralNames, like DNSName and IPAddress return,
-// concatenated together.
-//
-// CreatedEncodedSubjectAltName(ByteString()) results in a SAN with an empty
-// sequence. CreateEmptyEncodedSubjectName() results in a SAN without any
-// sequence.
-ByteString CreateEncodedSubjectAltName(const ByteString& names);
-ByteString CreateEncodedEmptySubjectAltName();
-
-class TestKeyPair
-{
-public:
- virtual ~TestKeyPair() { }
-
- const TestPublicKeyAlgorithm publicKeyAlg;
-
- // The DER encoding of the entire SubjectPublicKeyInfo structure. This is
- // 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,
- const TestSignatureAlgorithm& signatureAlgorithm,
- /*out*/ ByteString& signature) const = 0;
-
- virtual TestKeyPair* Clone() const = 0;
-protected:
- TestKeyPair(const TestPublicKeyAlgorithm& publicKeyAlg, const ByteString& spk);
- TestKeyPair(const TestKeyPair&) = delete;
- void operator=(const TestKeyPair&) = delete;
-};
-
-TestKeyPair* CloneReusedKeyPair();
-TestKeyPair* GenerateKeyPair();
-TestKeyPair* GenerateDSSKeyPair();
-inline void DeleteTestKeyPair(TestKeyPair* keyPair) { delete keyPair; }
-typedef ScopedPtr<TestKeyPair, DeleteTestKeyPair> ScopedTestKeyPair;
-
-Result TestVerifyECDSASignedDigest(const SignedDigest& signedDigest,
- Input subjectPublicKeyInfo);
-Result TestVerifyRSAPKCS1SignedDigest(const SignedDigest& signedDigest,
- Input subjectPublicKeyInfo);
-Result TestDigestBuf(Input item, DigestAlgorithm digestAlg,
- /*out*/ uint8_t* digestBuf, size_t digestBufLen);
-
-// Replace one substring in item with another of the same length, but only if
-// the substring was found exactly once. The "same length" restriction is
-// useful for avoiding invalidating lengths encoded within the item. The
-// "only once" restriction is helpful for avoiding making accidental changes.
-//
-// The string to search for must be 8 or more bytes long so that it is
-// extremely unlikely that there will ever be any false positive matches
-// in digital signatures, keys, hashes, etc.
-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. 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.)
-ByteString CreateEncodedCertificate(long version,
- const TestSignatureAlgorithm& signature,
- const ByteString& serialNumber,
- const ByteString& issuerNameDER,
- time_t notBefore, time_t notAfter,
- const ByteString& subjectNameDER,
- const TestKeyPair& subjectKeyPair,
- /*optional*/ const ByteString* extensions,
- const TestKeyPair& issuerKeyPair,
- const TestSignatureAlgorithm& signatureAlgorithm);
-
-ByteString CreateEncodedSerialNumber(long value);
-
-enum class Critical { No = 0, Yes = 1 };
-
-ByteString CreateEncodedBasicConstraints(bool isCA,
- /*optional*/ long* pathLenConstraint,
- Critical critical);
-
-// Creates a DER-encoded extKeyUsage extension with one EKU OID.
-ByteString CreateEncodedEKUExtension(Input eku, Critical critical);
-
-///////////////////////////////////////////////////////////////////////////////
-// Encode OCSP responses
-
-class OCSPResponseExtension final
-{
-public:
- OCSPResponseExtension();
-
- ByteString id;
- bool critical;
- ByteString value;
- OCSPResponseExtension* next;
-};
-
-class OCSPResponseContext final
-{
-public:
- OCSPResponseContext(const CertID& certID, std::time_t time);
-
- const CertID& certID;
- // TODO(bug 980538): add a way to specify what certificates are included.
-
- // The fields below are in the order that they appear in an OCSP response.
-
- enum OCSPResponseStatus
- {
- successful = 0,
- malformedRequest = 1,
- internalError = 2,
- tryLater = 3,
- // 4 is not used
- sigRequired = 5,
- unauthorized = 6,
- };
- uint8_t responseStatus; // an OCSPResponseStatus or an invalid value
- bool skipResponseBytes; // If true, don't include responseBytes
-
- // responderID
- ByteString signerNameDER; // If set, responderID will use the byName
- // form; otherwise responderID will use the
- // byKeyHash form.
-
- std::time_t producedAt;
-
- // SingleResponse extensions (for the certID given in the constructor).
- OCSPResponseExtension* singleExtensions;
- // ResponseData extensions.
- OCSPResponseExtension* responseExtensions;
- bool includeEmptyExtensions; // If true, include the extension wrapper
- // regardless of if there are any actual
- // extensions.
- ScopedTestKeyPair signerKeyPair;
- TestSignatureAlgorithm signatureAlgorithm;
- bool badSignature; // If true, alter the signature to fail verification
- const ByteString* certs; // optional; array terminated by an empty string
-
- // The following fields are on a per-SingleResponse basis. In the future we
- // may support including multiple SingleResponses per response.
- enum CertStatus
- {
- good = 0,
- revoked = 1,
- unknown = 2,
- };
- uint8_t certStatus; // CertStatus or an invalid value
- std::time_t revocationTime; // For certStatus == revoked
- std::time_t thisUpdate;
- std::time_t nextUpdate;
- bool includeNextUpdate;
-};
-
-ByteString CreateEncodedOCSPResponse(OCSPResponseContext& context);
-
-} } } // namespace mozilla::pkix::test
-
-#endif // mozilla_pkix_test_pkixtestutils_h