tor-browser

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

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