pkixtestutil.h (15841B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This code is made available to you under your choice of the following sets 4 * of licensing terms: 5 */ 6 /* This Source Code Form is subject to the terms of the Mozilla Public 7 * License, v. 2.0. If a copy of the MPL was not distributed with this 8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 */ 10 /* Copyright 2013 Mozilla Contributors 11 * 12 * Licensed under the Apache License, Version 2.0 (the "License"); 13 * you may not use this file except in compliance with the License. 14 * You may obtain a copy of the License at 15 * 16 * http://www.apache.org/licenses/LICENSE-2.0 17 * 18 * Unless required by applicable law or agreed to in writing, software 19 * distributed under the License is distributed on an "AS IS" BASIS, 20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 * See the License for the specific language governing permissions and 22 * limitations under the License. 23 */ 24 25 #ifndef mozilla_pkix_test_pkixtestutil_h 26 #define mozilla_pkix_test_pkixtestutil_h 27 28 #include <cstdint> 29 #include <cstring> 30 #include <ctime> 31 #include <string> 32 33 #include "mozpkix/pkixtypes.h" 34 35 namespace mozilla { 36 namespace pkix { 37 namespace test { 38 39 class ByteString : public std::string { 40 public: 41 ByteString() {} 42 ByteString(size_t count, uint8_t value) : std::string(count, char(value)) {} 43 explicit ByteString(const uint8_t* data) 44 : std::string(reinterpret_cast<const char*>(data)) {} 45 ByteString(const uint8_t* data, size_t length) 46 : std::string(reinterpret_cast<const char*>(data), length) {} 47 ByteString operator+(const ByteString& rhs) const { 48 ByteString result = *this; 49 result.std::string::append(rhs); 50 return result; 51 } 52 const uint8_t* data() const { 53 return reinterpret_cast<const uint8_t*>(std::string::data()); 54 } 55 void assign(const uint8_t* data, size_t length) { 56 std::string::assign(reinterpret_cast<const char*>(data), length); 57 } 58 void append(const ByteString& other) { std::string::append(other); } 59 void append(const uint8_t* data, size_t length) { 60 std::string::append(reinterpret_cast<const char*>(data), length); 61 } 62 void push_back(uint8_t c) { std::string::push_back(char(c)); } 63 }; 64 65 inline bool ENCODING_FAILED(const ByteString& bs) { return bs.empty(); } 66 67 template <size_t L> 68 inline ByteString BytesToByteString(const uint8_t (&bytes)[L]) { 69 return ByteString(bytes, L); 70 } 71 72 // XXX: Ideally, we should define this instead: 73 // 74 // template <typename T, std::size_t N> 75 // constexpr inline std::size_t 76 // ArrayLength(T (&)[N]) 77 // { 78 // return N; 79 // } 80 // 81 // However, we don't because not all supported compilers support constexpr, 82 // and we need to calculate array lengths in static_assert sometimes. 83 // 84 // XXX: Evaluates its argument twice 85 #define MOZILLA_PKIX_ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) 86 87 bool InputEqualsByteString(Input input, const ByteString& bs); 88 ByteString InputToByteString(Input input); 89 90 // python DottedOIDToCode.py --tlv id-kp-OCSPSigning 1.3.6.1.5.5.7.3.9 91 static const uint8_t tlv_id_kp_OCSPSigning[] = {0x06, 0x08, 0x2b, 0x06, 0x01, 92 0x05, 0x05, 0x07, 0x03, 0x09}; 93 94 // python DottedOIDToCode.py --tlv id-kp-serverAuth 1.3.6.1.5.5.7.3.1 95 static const uint8_t tlv_id_kp_serverAuth[] = {0x06, 0x08, 0x2b, 0x06, 0x01, 96 0x05, 0x05, 0x07, 0x03, 0x01}; 97 98 enum class TestDigestAlgorithmID { 99 MD2, 100 MD5, 101 SHA1, 102 SHA224, 103 SHA256, 104 SHA384, 105 SHA512, 106 }; 107 108 struct TestPublicKeyAlgorithm { 109 explicit TestPublicKeyAlgorithm(const ByteString& aAlgorithmIdentifier) 110 : algorithmIdentifier(aAlgorithmIdentifier) {} 111 bool operator==(const TestPublicKeyAlgorithm& other) const { 112 return algorithmIdentifier == other.algorithmIdentifier; 113 } 114 ByteString algorithmIdentifier; 115 }; 116 117 ByteString DSS_P(); 118 ByteString DSS_Q(); 119 ByteString DSS_G(); 120 121 TestPublicKeyAlgorithm DSS(); 122 TestPublicKeyAlgorithm RSA_PKCS1(); 123 124 struct TestSignatureAlgorithm { 125 TestSignatureAlgorithm(const TestPublicKeyAlgorithm& publicKeyAlg, 126 TestDigestAlgorithmID digestAlg, 127 const ByteString& algorithmIdentifier, bool accepted); 128 129 TestPublicKeyAlgorithm publicKeyAlg; 130 TestDigestAlgorithmID digestAlg; 131 ByteString algorithmIdentifier; 132 bool accepted; 133 }; 134 135 TestSignatureAlgorithm md2WithRSAEncryption(); 136 TestSignatureAlgorithm md5WithRSAEncryption(); 137 TestSignatureAlgorithm sha1WithRSAEncryption(); 138 TestSignatureAlgorithm sha256WithRSAEncryption(); 139 140 // e.g. YMDHMS(2016, 12, 31, 1, 23, 45) => 2016-12-31:01:23:45 (GMT) 141 mozilla::pkix::Time YMDHMS(uint16_t year, uint16_t month, uint16_t day, 142 uint16_t hour, uint16_t minutes, uint16_t seconds); 143 144 ByteString TLV(uint8_t tag, size_t length, const ByteString& value); 145 146 inline ByteString TLV(uint8_t tag, const ByteString& value) { 147 return TLV(tag, value.length(), value); 148 } 149 150 // Although we can't enforce it without relying on Cuser-defined literals, 151 // which aren't supported by all of our compilers yet, you should only pass 152 // string literals as the last parameter to the following two functions. 153 154 template <size_t N> 155 inline ByteString TLV(uint8_t tag, const char (&value)[N]) { 156 static_assert(N > 0, "cannot have string literal of size 0"); 157 assert(value[N - 1] == 0); 158 return TLV(tag, ByteString(reinterpret_cast<const uint8_t*>(&value), N - 1)); 159 } 160 161 template <size_t N> 162 inline ByteString TLV(uint8_t tag, size_t length, const char (&value)[N]) { 163 static_assert(N > 0, "cannot have string literal of size 0"); 164 assert(value[N - 1] == 0); 165 return TLV(tag, length, 166 ByteString(reinterpret_cast<const uint8_t*>(&value), N - 1)); 167 } 168 169 ByteString Boolean(bool value); 170 ByteString Integer(long value); 171 172 ByteString CN(const ByteString&, uint8_t encodingTag = 0x0c /*UTF8String*/); 173 174 inline ByteString CN(const char* value, 175 uint8_t encodingTag = 0x0c /*UTF8String*/) { 176 return CN( 177 ByteString(reinterpret_cast<const uint8_t*>(value), std::strlen(value)), 178 encodingTag); 179 } 180 181 ByteString OU(const ByteString&, uint8_t encodingTag = 0x0c /*UTF8String*/); 182 183 inline ByteString OU(const char* value, 184 uint8_t encodingTag = 0x0c /*UTF8String*/) { 185 return OU( 186 ByteString(reinterpret_cast<const uint8_t*>(value), std::strlen(value)), 187 encodingTag); 188 } 189 190 ByteString emailAddress(const ByteString&); 191 192 inline ByteString emailAddress(const char* value) { 193 return emailAddress( 194 ByteString(reinterpret_cast<const uint8_t*>(value), std::strlen(value))); 195 } 196 197 // RelativeDistinguishedName ::= 198 // SET SIZE (1..MAX) OF AttributeTypeAndValue 199 // 200 ByteString RDN(const ByteString& avas); 201 202 // Name ::= CHOICE { -- only one possibility for now -- 203 // rdnSequence RDNSequence } 204 // 205 // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName 206 // 207 ByteString Name(const ByteString& rdns); 208 209 inline ByteString CNToDERName(const ByteString& cn) { 210 return Name(RDN(CN(cn))); 211 } 212 213 inline ByteString CNToDERName(const char* cn) { return Name(RDN(CN(cn))); } 214 215 // GeneralName ::= CHOICE { 216 // otherName [0] OtherName, 217 // rfc822Name [1] IA5String, 218 // dNSName [2] IA5String, 219 // x400Address [3] ORAddress, 220 // directoryName [4] Name, 221 // ediPartyName [5] EDIPartyName, 222 // uniformResourceIdentifier [6] IA5String, 223 // iPAddress [7] OCTET STRING, 224 // registeredID [8] OBJECT IDENTIFIER } 225 226 inline ByteString RFC822Name(const ByteString& name) { 227 // (2 << 6) means "context-specific", 1 is the GeneralName tag. 228 return TLV((2 << 6) | 1, name); 229 } 230 231 template <size_t L> 232 inline ByteString RFC822Name(const char (&bytes)[L]) { 233 return RFC822Name( 234 ByteString(reinterpret_cast<const uint8_t*>(&bytes), L - 1)); 235 } 236 237 inline ByteString DNSName(const ByteString& name) { 238 // (2 << 6) means "context-specific", 2 is the GeneralName tag. 239 return TLV((2 << 6) | 2, name); 240 } 241 242 template <size_t L> 243 inline ByteString DNSName(const char (&bytes)[L]) { 244 return DNSName(ByteString(reinterpret_cast<const uint8_t*>(&bytes), L - 1)); 245 } 246 247 inline ByteString DirectoryName(const ByteString& name) { 248 // (2 << 6) means "context-specific", (1 << 5) means "constructed", and 4 is 249 // the DirectoryName tag. 250 return TLV((2 << 6) | (1 << 5) | 4, name); 251 } 252 253 inline ByteString IPAddress() { 254 // (2 << 6) means "context-specific", 7 is the GeneralName tag. 255 return TLV((2 << 6) | 7, ByteString()); 256 } 257 258 template <size_t L> 259 inline ByteString IPAddress(const uint8_t (&bytes)[L]) { 260 // (2 << 6) means "context-specific", 7 is the GeneralName tag. 261 return TLV((2 << 6) | 7, ByteString(bytes, L)); 262 } 263 264 // Names should be zero or more GeneralNames, like DNSName and IPAddress return, 265 // concatenated together. 266 // 267 // CreatedEncodedSubjectAltName(ByteString()) results in a SAN with an empty 268 // sequence. CreateEmptyEncodedSubjectName() results in a SAN without any 269 // sequence. 270 ByteString CreateEncodedSubjectAltName(const ByteString& names); 271 ByteString CreateEncodedEmptySubjectAltName(); 272 273 class TestKeyPair { 274 public: 275 virtual ~TestKeyPair() {} 276 277 const TestPublicKeyAlgorithm publicKeyAlg; 278 279 // The DER encoding of the entire SubjectPublicKeyInfo structure. This is 280 // what is encoded in certificates. 281 const ByteString subjectPublicKeyInfo; 282 283 // The DER encoding of subjectPublicKeyInfo.subjectPublicKey. This is what is 284 // hashed to create CertIDs for OCSP. 285 const ByteString subjectPublicKey; 286 287 virtual Result SignData(const ByteString& tbs, 288 const TestSignatureAlgorithm& signatureAlgorithm, 289 /*out*/ ByteString& signature) const = 0; 290 291 virtual TestKeyPair* Clone() const = 0; 292 293 protected: 294 TestKeyPair(const TestPublicKeyAlgorithm& publicKeyAlg, 295 const ByteString& spk); 296 TestKeyPair(const TestKeyPair&) = delete; 297 void operator=(const TestKeyPair&) = delete; 298 }; 299 300 TestKeyPair* CloneReusedKeyPair(); 301 TestKeyPair* GenerateKeyPair(); 302 TestKeyPair* GenerateDSSKeyPair(); 303 inline void DeleteTestKeyPair(TestKeyPair* keyPair) { delete keyPair; } 304 typedef std::unique_ptr<TestKeyPair> ScopedTestKeyPair; 305 306 Result TestVerifyECDSASignedData(Input data, DigestAlgorithm digestAlgorithm, 307 Input signature, Input subjectPublicKeyInfo); 308 Result TestVerifyRSAPKCS1SignedData(Input data, DigestAlgorithm digestAlgorithm, 309 Input signature, 310 Input subjectPublicKeyInfo); 311 Result TestDigestBuf(Input item, DigestAlgorithm digestAlg, 312 /*out*/ uint8_t* digestBuf, size_t digestBufLen); 313 314 // Replace one substring in item with another of the same length, but only if 315 // the substring was found exactly once. The "same length" restriction is 316 // useful for avoiding invalidating lengths encoded within the item. The 317 // "only once" restriction is helpful for avoiding making accidental changes. 318 // 319 // The string to search for must be 8 or more bytes long so that it is 320 // extremely unlikely that there will ever be any false positive matches 321 // in digital signatures, keys, hashes, etc. 322 Result TamperOnce(/*in/out*/ ByteString& item, const ByteString& from, 323 const ByteString& to); 324 325 /////////////////////////////////////////////////////////////////////////////// 326 // Encode Certificates 327 328 enum Version { v1 = 0, v2 = 1, v3 = 2 }; 329 330 // signature is assumed to be the DER encoding of an AlgorithmIdentifer. It is 331 // put into the signature field of the TBSCertificate. In most cases, it will 332 // be the same as signatureAlgorithm, which is the algorithm actually used 333 // to sign the certificate. 334 // serialNumber is assumed to be the DER encoding of an INTEGER. 335 // 336 // If extensions is null, then no extensions will be encoded. Otherwise, 337 // extensions must point to an array of ByteStrings, terminated with an empty 338 // ByteString. (If the first item of the array is empty then an empty 339 // Extensions sequence will be encoded.) 340 ByteString CreateEncodedCertificate( 341 long version, const TestSignatureAlgorithm& signature, 342 const ByteString& serialNumber, const ByteString& issuerNameDER, 343 time_t notBefore, time_t notAfter, const ByteString& subjectNameDER, 344 const TestKeyPair& subjectKeyPair, 345 /*optional*/ const ByteString* extensions, const TestKeyPair& issuerKeyPair, 346 const TestSignatureAlgorithm& signatureAlgorithm); 347 348 ByteString CreateEncodedSerialNumber(long value); 349 350 enum class Critical { No = 0, Yes = 1 }; 351 352 ByteString CreateEncodedBasicConstraints( 353 bool isCA, 354 /*optional in*/ const long* pathLenConstraint, Critical critical); 355 356 // Creates a DER-encoded extKeyUsage extension with one EKU OID. 357 ByteString CreateEncodedEKUExtension(Input eku, Critical critical); 358 359 /////////////////////////////////////////////////////////////////////////////// 360 // Encode OCSP responses 361 362 class OCSPResponseExtension final { 363 public: 364 OCSPResponseExtension(); 365 366 ByteString id; 367 bool critical; 368 ByteString value; 369 OCSPResponseExtension* next; 370 }; 371 372 class OCSPResponseContext final { 373 public: 374 OCSPResponseContext(const CertID& certID, std::time_t time); 375 376 const CertID& certID; 377 // What digest algorithm to use to produce issuerNameHash and issuerKeyHash. 378 // Defaults to sha1. 379 DigestAlgorithm certIDHashAlgorithm; 380 // If non-empty, the sequence of bytes to use for hashAlgorithm when encoding 381 // this response. If empty, the sequence of bytes corresponding to 382 // certIDHashAlgorithm will be used. Defaults to empty. 383 ByteString certIDHashAlgorithmEncoded; 384 385 // TODO(bug 980538): add a way to specify what certificates are included. 386 387 // The fields below are in the order that they appear in an OCSP response. 388 389 enum OCSPResponseStatus { 390 successful = 0, 391 malformedRequest = 1, 392 internalError = 2, 393 tryLater = 3, 394 // 4 is not used 395 sigRequired = 5, 396 unauthorized = 6, 397 }; 398 uint8_t responseStatus; // an OCSPResponseStatus or an invalid value 399 bool skipResponseBytes; // If true, don't include responseBytes 400 401 // responderID 402 ByteString signerNameDER; // If set, responderID will use the byName 403 // form; otherwise responderID will use the 404 // byKeyHash form. 405 406 std::time_t producedAt; 407 408 // SingleResponse extensions (for the certID given in the constructor). 409 OCSPResponseExtension* singleExtensions; 410 // ResponseData extensions. 411 OCSPResponseExtension* responseExtensions; 412 const ByteString* trailingResponseData; // optional; trailing data to include 413 // at the end of the ResponseData. 414 bool includeEmptyExtensions; // If true, include the extension wrapper 415 // regardless of if there are any actual 416 // extensions. 417 ScopedTestKeyPair signerKeyPair; 418 TestSignatureAlgorithm signatureAlgorithm; 419 bool badSignature; // If true, alter the signature to fail verification 420 const ByteString* certs; // optional; array terminated by an empty string 421 422 // The following fields are on a per-SingleResponse basis. In the future we 423 // may support including multiple SingleResponses per response. 424 enum CertStatus { 425 good = 0, 426 revoked = 1, 427 unknown = 2, 428 }; 429 uint8_t certStatus; // CertStatus or an invalid value 430 std::time_t revocationTime; // For certStatus == revoked 431 std::time_t thisUpdate; 432 std::time_t nextUpdate; 433 bool includeNextUpdate; 434 }; 435 436 ByteString CreateEncodedOCSPResponse(OCSPResponseContext& context); 437 } // namespace test 438 } // namespace pkix 439 } // namespace mozilla 440 441 #endif // mozilla_pkix_test_pkixtestutil_h