tor-browser

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

pkixtestutil.cpp (36628B)


      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 #include "mozpkix/test/pkixtestutil.h"
     26 
     27 #include <cerrno>
     28 #include <cstdio>
     29 #include <limits>
     30 #include <new>
     31 #include <sstream>
     32 #include <cstdlib>
     33 
     34 #include "mozpkix/pkixder.h"
     35 #include "mozpkix/pkixutil.h"
     36 
     37 using namespace std;
     38 
     39 namespace mozilla { namespace pkix { namespace test {
     40 
     41 namespace {
     42 
     43 struct ScopedMaybeDeleteFile {
     44  void operator()(FILE* f) {
     45    if (f) {
     46      (void)fclose(f);
     47    }
     48  }
     49 };
     50 typedef std::unique_ptr<FILE, ScopedMaybeDeleteFile> ScopedFILE;
     51 
     52 FILE*
     53 OpenFile(const string& dir, const string& filename, const string& mode)
     54 {
     55  string path = dir + '/' + filename;
     56 
     57  ScopedFILE file;
     58 #ifdef _MSC_VER
     59  {
     60    FILE* rawFile;
     61    errno_t error = fopen_s(&rawFile, path.c_str(), mode.c_str());
     62    if (error) {
     63      // TODO: map error to NSPR error code
     64      rawFile = nullptr;
     65    }
     66    file.reset(rawFile);
     67  }
     68 #else
     69  file.reset(fopen(path.c_str(), mode.c_str()));
     70 #endif
     71  return file.release();
     72 }
     73 
     74 } // namespace
     75 
     76 bool
     77 InputEqualsByteString(Input input, const ByteString& bs)
     78 {
     79  Input bsInput;
     80  if (bsInput.Init(bs.data(), bs.length()) != Success) {
     81    // Init can only fail if it is given a bad pointer or if the input is too
     82    // long, which won't ever happen. Plus, if it does, it is ok to call abort
     83    // since this is only test code.
     84    abort();
     85  }
     86  return InputsAreEqual(input, bsInput);
     87 }
     88 
     89 ByteString
     90 InputToByteString(Input input)
     91 {
     92  ByteString result;
     93  Reader reader(input);
     94  for (;;) {
     95    uint8_t b;
     96    if (reader.Read(b) != Success) {
     97      return result;
     98    }
     99    result.push_back(b);
    100  }
    101 }
    102 
    103 Result
    104 TamperOnce(/*in/out*/ ByteString& item, const ByteString& from,
    105           const ByteString& to)
    106 {
    107  if (from.length() < 8) {
    108    return Result::FATAL_ERROR_INVALID_ARGS;
    109  }
    110  if (from.length() != to.length()) {
    111    return Result::FATAL_ERROR_INVALID_ARGS;
    112  }
    113  size_t pos = item.find(from);
    114  if (pos == string::npos) {
    115    return Result::FATAL_ERROR_INVALID_ARGS; // No matches.
    116  }
    117  if (item.find(from, pos + from.length()) != string::npos) {
    118    return Result::FATAL_ERROR_INVALID_ARGS; // More than once match.
    119  }
    120  item.replace(pos, from.length(), to);
    121  return Success;
    122 }
    123 
    124 // Given a tag and a value, generates a DER-encoded tag-length-value item.
    125 ByteString
    126 TLV(uint8_t tag, size_t length, const ByteString& value)
    127 {
    128  ByteString result;
    129  result.push_back(tag);
    130 
    131  if (value.length() < 128) {
    132    result.push_back(static_cast<uint8_t>(length));
    133  } else if (value.length() < 256) {
    134    result.push_back(0x81u);
    135    result.push_back(static_cast<uint8_t>(length));
    136  } else if (value.length() < 65536) {
    137    result.push_back(0x82u);
    138    result.push_back(static_cast<uint8_t>(length / 256));
    139    result.push_back(static_cast<uint8_t>(length % 256));
    140  } else {
    141    // It is MUCH more convenient for TLV to be infallible than for it to have
    142    // "proper" error handling.
    143    abort();
    144  }
    145  result.append(value);
    146  return result;
    147 }
    148 
    149 OCSPResponseExtension::OCSPResponseExtension()
    150  : id()
    151  , critical(false)
    152  , value()
    153  , next(nullptr)
    154 {
    155 }
    156 
    157 OCSPResponseContext::OCSPResponseContext(const CertID& aCertID, time_t time)
    158  : certID(aCertID)
    159  , certIDHashAlgorithm(DigestAlgorithm::sha1)
    160  , certIDHashAlgorithmEncoded(ByteString())
    161  , responseStatus(successful)
    162  , skipResponseBytes(false)
    163  , producedAt(time)
    164  , singleExtensions(nullptr)
    165  , responseExtensions(nullptr)
    166  , trailingResponseData(nullptr)
    167  , includeEmptyExtensions(false)
    168  , signatureAlgorithm(sha256WithRSAEncryption())
    169  , badSignature(false)
    170  , certs(nullptr)
    171 
    172  , certStatus(good)
    173  , revocationTime(0)
    174  , thisUpdate(time)
    175  , nextUpdate(time + static_cast<time_t>(Time::ONE_DAY_IN_SECONDS))
    176  , includeNextUpdate(true)
    177 {
    178 }
    179 
    180 static ByteString ResponseBytes(OCSPResponseContext& context);
    181 static ByteString BasicOCSPResponse(OCSPResponseContext& context);
    182 static ByteString ResponseData(OCSPResponseContext& context);
    183 static ByteString ResponderID(OCSPResponseContext& context);
    184 static ByteString KeyHash(const ByteString& subjectPublicKeyInfo);
    185 static ByteString SingleResponse(OCSPResponseContext& context);
    186 static ByteString CertID(OCSPResponseContext& context);
    187 static ByteString CertStatus(OCSPResponseContext& context);
    188 
    189 static ByteString
    190 HASH(const ByteString& toHash, DigestAlgorithm digestAlgorithm)
    191 {
    192  uint8_t digestBuf[MAX_DIGEST_SIZE_IN_BYTES];
    193  Input input;
    194  if (input.Init(toHash.data(), toHash.length()) != Success) {
    195    abort();
    196  }
    197  size_t digestLen = DigestAlgorithmToSizeInBytes(digestAlgorithm);
    198  assert(digestLen <= sizeof(digestBuf));
    199  Result rv = TestDigestBuf(input, digestAlgorithm, digestBuf, digestLen);
    200  if (rv != Success) {
    201    abort();
    202  }
    203  return ByteString(digestBuf, digestLen);
    204 }
    205 
    206 static ByteString
    207 HashedOctetString(const ByteString& bytes, DigestAlgorithm digestAlgorithm)
    208 {
    209  ByteString digest(HASH(bytes, digestAlgorithm));
    210  if (ENCODING_FAILED(digest)) {
    211    return ByteString();
    212  }
    213  return TLV(der::OCTET_STRING, digest);
    214 }
    215 
    216 static ByteString
    217 BitString(const ByteString& rawBytes, bool corrupt)
    218 {
    219  ByteString prefixed;
    220  // We have to add a byte at the beginning indicating no unused bits.
    221  // TODO: add ability to have bit strings of bit length not divisible by 8,
    222  // resulting in unused bits in the bitstring encoding
    223  prefixed.push_back(0);
    224  prefixed.append(rawBytes);
    225  if (corrupt) {
    226    assert(prefixed.length() > 8);
    227    prefixed[8]++;
    228  }
    229  return TLV(der::BIT_STRING, prefixed);
    230 }
    231 
    232 ByteString
    233 Boolean(bool value)
    234 {
    235  ByteString encodedValue;
    236  encodedValue.push_back(value ? 0xffu : 0x00u);
    237  return TLV(der::BOOLEAN, encodedValue);
    238 }
    239 
    240 ByteString
    241 Integer(long value)
    242 {
    243  if (value < 0 || value > 127) {
    244    // TODO: add encoding of larger values
    245    // It is MUCH more convenient for Integer to be infallible than for it to
    246    // have "proper" error handling.
    247    abort();
    248  }
    249 
    250  ByteString encodedValue;
    251  encodedValue.push_back(static_cast<uint8_t>(value));
    252  return TLV(der::INTEGER, encodedValue);
    253 }
    254 
    255 enum TimeEncoding { UTCTime = 0, GeneralizedTime = 1 };
    256 
    257 // Windows doesn't provide gmtime_r, but it provides something very similar.
    258 #if defined(_WINDOWS) && (!defined(_POSIX_C_SOURCE) || !defined(_POSIX_THREAD_SAFE_FUNCTIONS))
    259 static tm*
    260 gmtime_r(const time_t* t, /*out*/ tm* exploded)
    261 {
    262  if (gmtime_s(exploded, t) != 0) {
    263    return nullptr;
    264  }
    265  return exploded;
    266 }
    267 #endif
    268 
    269 // http://tools.ietf.org/html/rfc5280#section-4.1.2.5
    270 // UTCTime:           YYMMDDHHMMSSZ (years 1950-2049 only)
    271 // GeneralizedTime: YYYYMMDDHHMMSSZ
    272 //
    273 // This assumes that time/time_t are POSIX-compliant in that time() returns
    274 // the number of seconds since the Unix epoch.
    275 static ByteString
    276 TimeToEncodedTime(time_t time, TimeEncoding encoding)
    277 {
    278  assert(encoding == UTCTime || encoding == GeneralizedTime);
    279 
    280  tm exploded;
    281  if (!gmtime_r(&time, &exploded)) {
    282    return ByteString();
    283  }
    284 
    285  if (exploded.tm_sec >= 60) {
    286    // round down for leap seconds
    287    exploded.tm_sec = 59;
    288  }
    289 
    290  // exploded.tm_year is the year offset by 1900.
    291  int year = exploded.tm_year + 1900;
    292 
    293  if (encoding == UTCTime && (year < 1950 || year >= 2050)) {
    294    return ByteString();
    295  }
    296 
    297  ByteString value;
    298 
    299  if (encoding == GeneralizedTime) {
    300    value.push_back(static_cast<uint8_t>('0' + (year / 1000)));
    301    value.push_back(static_cast<uint8_t>('0' + ((year % 1000) / 100)));
    302  }
    303 
    304  value.push_back(static_cast<uint8_t>('0' + ((year % 100) / 10)));
    305  value.push_back(static_cast<uint8_t>('0' + (year % 10)));
    306  value.push_back(static_cast<uint8_t>('0' + ((exploded.tm_mon + 1) / 10)));
    307  value.push_back(static_cast<uint8_t>('0' + ((exploded.tm_mon + 1) % 10)));
    308  value.push_back(static_cast<uint8_t>('0' + (exploded.tm_mday / 10)));
    309  value.push_back(static_cast<uint8_t>('0' + (exploded.tm_mday % 10)));
    310  value.push_back(static_cast<uint8_t>('0' + (exploded.tm_hour / 10)));
    311  value.push_back(static_cast<uint8_t>('0' + (exploded.tm_hour % 10)));
    312  value.push_back(static_cast<uint8_t>('0' + (exploded.tm_min / 10)));
    313  value.push_back(static_cast<uint8_t>('0' + (exploded.tm_min % 10)));
    314  value.push_back(static_cast<uint8_t>('0' + (exploded.tm_sec / 10)));
    315  value.push_back(static_cast<uint8_t>('0' + (exploded.tm_sec % 10)));
    316  value.push_back('Z');
    317 
    318  return TLV(encoding == GeneralizedTime ? der::GENERALIZED_TIME : der::UTCTime,
    319             value);
    320 }
    321 
    322 static ByteString
    323 TimeToGeneralizedTime(time_t time)
    324 {
    325  return TimeToEncodedTime(time, GeneralizedTime);
    326 }
    327 
    328 // http://tools.ietf.org/html/rfc5280#section-4.1.2.5: "CAs conforming to this
    329 // profile MUST always encode certificate validity dates through the year 2049
    330 // as UTCTime; certificate validity dates in 2050 or later MUST be encoded as
    331 // GeneralizedTime." (This is a special case of the rule that we must always
    332 // use the shortest possible encoding.)
    333 static ByteString
    334 TimeToTimeChoice(time_t time)
    335 {
    336  tm exploded;
    337  if (!gmtime_r(&time, &exploded)) {
    338    return ByteString();
    339  }
    340  TimeEncoding encoding = (exploded.tm_year + 1900 >= 1950 &&
    341                           exploded.tm_year + 1900 < 2050)
    342                        ? UTCTime
    343                        : GeneralizedTime;
    344 
    345  return TimeToEncodedTime(time, encoding);
    346 }
    347 
    348 Time
    349 YMDHMS(uint16_t year, uint16_t month, uint16_t day,
    350       uint16_t hour, uint16_t minutes, uint16_t seconds)
    351 {
    352  assert(year <= 9999);
    353  assert(month >= 1);
    354  assert(month <= 12);
    355  assert(day >= 1);
    356  assert(hour < 24);
    357  assert(minutes < 60);
    358  assert(seconds < 60);
    359 
    360  uint64_t days = DaysBeforeYear(year);
    361 
    362  {
    363    static const int16_t DAYS_IN_MONTH[] = {
    364      31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    365    };
    366 
    367    int16_t i = 1;
    368    for (;;) {
    369      int16_t daysInMonth = DAYS_IN_MONTH[i - 1];
    370      if (i == 2 &&
    371          ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)))) {
    372        // Add leap day
    373        ++daysInMonth;
    374      }
    375      if (i == month) {
    376        assert(day <= daysInMonth);
    377        break;
    378      }
    379      days += daysInMonth;
    380      ++i;
    381    }
    382  }
    383 
    384  days += (day - 1);
    385 
    386  uint64_t totalSeconds = days * Time::ONE_DAY_IN_SECONDS;
    387  totalSeconds += hour * 60 * 60;
    388  totalSeconds += minutes * 60;
    389  totalSeconds += seconds;
    390  return TimeFromElapsedSecondsAD(totalSeconds);
    391 }
    392 
    393 static ByteString
    394 SignedData(const ByteString& tbsData,
    395           const TestKeyPair& keyPair,
    396           const TestSignatureAlgorithm& signatureAlgorithm,
    397           bool corrupt, /*optional*/ const ByteString* certs)
    398 {
    399  ByteString signature;
    400  if (keyPair.SignData(tbsData, signatureAlgorithm, signature) != Success) {
    401    return ByteString();
    402  }
    403 
    404  // TODO: add ability to have signatures of bit length not divisible by 8,
    405  // resulting in unused bits in the bitstring encoding
    406  ByteString signatureNested(BitString(signature, corrupt));
    407  if (ENCODING_FAILED(signatureNested)) {
    408    return ByteString();
    409  }
    410 
    411  ByteString certsNested;
    412  if (certs) {
    413    ByteString certsSequenceValue;
    414    while (!(*certs).empty()) {
    415      certsSequenceValue.append(*certs);
    416      ++certs;
    417    }
    418    ByteString certsSequence(TLV(der::SEQUENCE, certsSequenceValue));
    419    certsNested = TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
    420                      certsSequence);
    421  }
    422 
    423  ByteString value;
    424  value.append(tbsData);
    425  value.append(signatureAlgorithm.algorithmIdentifier);
    426  value.append(signatureNested);
    427  value.append(certsNested);
    428  return TLV(der::SEQUENCE, value);
    429 }
    430 
    431 // Extension  ::=  SEQUENCE  {
    432 //      extnID      OBJECT IDENTIFIER,
    433 //      critical    BOOLEAN DEFAULT FALSE,
    434 //      extnValue   OCTET STRING
    435 //                  -- contains the DER encoding of an ASN.1 value
    436 //                  -- corresponding to the extension type identified
    437 //                  -- by extnID
    438 //      }
    439 static ByteString
    440 Extension(Input extnID, Critical critical, const ByteString& extnValueBytes)
    441 {
    442  ByteString encoded;
    443 
    444  encoded.append(ByteString(extnID.UnsafeGetData(), extnID.GetLength()));
    445 
    446  if (critical == Critical::Yes) {
    447    encoded.append(Boolean(true));
    448  }
    449 
    450  ByteString extnValueSequence(TLV(der::SEQUENCE, extnValueBytes));
    451  ByteString extnValue(TLV(der::OCTET_STRING, extnValueSequence));
    452  encoded.append(extnValue);
    453  return TLV(der::SEQUENCE, encoded);
    454 }
    455 
    456 static ByteString
    457 EmptyExtension(Input extnID, Critical critical)
    458 {
    459  ByteString encoded(extnID.UnsafeGetData(), extnID.GetLength());
    460 
    461  if (critical == Critical::Yes) {
    462    encoded.append(Boolean(true));
    463  }
    464 
    465  ByteString extnValue(TLV(der::OCTET_STRING, ByteString()));
    466  encoded.append(extnValue);
    467  return TLV(der::SEQUENCE, encoded);
    468 }
    469 
    470 std::string
    471 GetEnv(const char* name)
    472 {
    473  std::string result;
    474 
    475 #ifndef _MSC_VER
    476  // XXX: Not thread safe.
    477  const char* value = getenv(name);
    478  if (value) {
    479    result = value;
    480  }
    481 #else
    482  char* value = nullptr;
    483  size_t valueLength = 0;
    484  if (_dupenv_s(&value, &valueLength, name) != 0) {
    485    abort();
    486  }
    487  if (value) {
    488    result = value;
    489    free(value);
    490  }
    491 #endif
    492  return result;
    493 }
    494 
    495 void
    496 MaybeLogOutput(const ByteString& result, const char* suffix)
    497 {
    498  assert(suffix);
    499 
    500  // This allows us to more easily debug the generated output, by creating a
    501  // file in the directory given by MOZILLA_PKIX_TEST_LOG_DIR for each
    502  // NOT THREAD-SAFE!!!
    503  std::string logPath(GetEnv("MOZILLA_PKIX_TEST_LOG_DIR"));
    504  if (!logPath.empty()) {
    505    static int counter = 0;
    506 
    507    std::ostringstream counterStream;
    508    counterStream << counter;
    509    if (!counterStream) {
    510      assert(false);
    511      return;
    512    }
    513    string filename = counterStream.str() + '-' + suffix + ".der";
    514 
    515    ++counter;
    516    ScopedFILE file(OpenFile(logPath, filename, "wb"));
    517    if (file) {
    518      (void) fwrite(result.data(), result.length(), 1, file.get());
    519    }
    520  }
    521 }
    522 
    523 ///////////////////////////////////////////////////////////////////////////////
    524 // Certificates
    525 
    526 static ByteString TBSCertificate(long version, const ByteString& serialNumber,
    527                                 const ByteString& signature,
    528                                 const ByteString& issuer,
    529                                 time_t notBefore, time_t notAfter,
    530                                 const ByteString& subject,
    531                                 const ByteString& subjectPublicKeyInfo,
    532                                 /*optional*/ const ByteString* extensions);
    533 
    534 // Certificate  ::=  SEQUENCE  {
    535 //         tbsCertificate       TBSCertificate,
    536 //         signatureAlgorithm   AlgorithmIdentifier,
    537 //         signatureValue       BIT STRING  }
    538 ByteString
    539 CreateEncodedCertificate(long version,
    540                         const TestSignatureAlgorithm& signature,
    541                         const ByteString& serialNumber,
    542                         const ByteString& issuerNameDER,
    543                         time_t notBefore, time_t notAfter,
    544                         const ByteString& subjectNameDER,
    545                         const TestKeyPair& subjectKeyPair,
    546                         /*optional*/ const ByteString* extensions,
    547                         const TestKeyPair& issuerKeyPair,
    548                         const TestSignatureAlgorithm& signatureAlgorithm)
    549 {
    550  ByteString tbsCertificate(TBSCertificate(version, serialNumber,
    551                                           signature.algorithmIdentifier,
    552                                           issuerNameDER, notBefore,
    553                                           notAfter, subjectNameDER,
    554                                           subjectKeyPair.subjectPublicKeyInfo,
    555                                           extensions));
    556  if (ENCODING_FAILED(tbsCertificate)) {
    557    return ByteString();
    558  }
    559 
    560  ByteString result(SignedData(tbsCertificate, issuerKeyPair,
    561                               signatureAlgorithm, false, nullptr));
    562  if (ENCODING_FAILED(result)) {
    563    return ByteString();
    564  }
    565 
    566  MaybeLogOutput(result, "cert");
    567 
    568  return result;
    569 }
    570 
    571 // TBSCertificate  ::=  SEQUENCE  {
    572 //      version         [0]  Version DEFAULT v1,
    573 //      serialNumber         CertificateSerialNumber,
    574 //      signature            AlgorithmIdentifier,
    575 //      issuer               Name,
    576 //      validity             Validity,
    577 //      subject              Name,
    578 //      subjectPublicKeyInfo SubjectPublicKeyInfo,
    579 //      issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
    580 //                           -- If present, version MUST be v2 or v3
    581 //      subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
    582 //                           -- If present, version MUST be v2 or v3
    583 //      extensions      [3]  Extensions OPTIONAL
    584 //                           -- If present, version MUST be v3 --  }
    585 static ByteString
    586 TBSCertificate(long versionValue,
    587               const ByteString& serialNumber, const ByteString& signature,
    588               const ByteString& issuer, time_t notBeforeTime,
    589               time_t notAfterTime, const ByteString& subject,
    590               const ByteString& subjectPublicKeyInfo,
    591               /*optional*/ const ByteString* extensions)
    592 {
    593  ByteString value;
    594 
    595  if (versionValue != static_cast<long>(der::Version::v1)) {
    596    ByteString versionInteger(Integer(versionValue));
    597    ByteString version(TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
    598                           versionInteger));
    599    value.append(version);
    600  }
    601 
    602  value.append(serialNumber);
    603  value.append(signature);
    604  value.append(issuer);
    605 
    606  // Validity ::= SEQUENCE {
    607  //       notBefore      Time,
    608  //       notAfter       Time }
    609  ByteString validity;
    610  {
    611    ByteString notBefore(TimeToTimeChoice(notBeforeTime));
    612    if (ENCODING_FAILED(notBefore)) {
    613      return ByteString();
    614    }
    615    ByteString notAfter(TimeToTimeChoice(notAfterTime));
    616    if (ENCODING_FAILED(notAfter)) {
    617      return ByteString();
    618    }
    619    ByteString validityValue;
    620    validityValue.append(notBefore);
    621    validityValue.append(notAfter);
    622    validity = TLV(der::SEQUENCE, validityValue);
    623    if (ENCODING_FAILED(validity)) {
    624      return ByteString();
    625    }
    626  }
    627  value.append(validity);
    628 
    629  value.append(subject);
    630 
    631  value.append(subjectPublicKeyInfo);
    632 
    633  if (extensions) {
    634    ByteString extensionsValue;
    635    while (!(*extensions).empty()) {
    636      extensionsValue.append(*extensions);
    637      ++extensions;
    638    }
    639    ByteString extensionsSequence(TLV(der::SEQUENCE, extensionsValue));
    640    if (ENCODING_FAILED(extensionsSequence)) {
    641      return ByteString();
    642    }
    643    ByteString extensionsWrapped(
    644      TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 3, extensionsSequence));
    645    if (ENCODING_FAILED(extensionsWrapped)) {
    646      return ByteString();
    647    }
    648    value.append(extensionsWrapped);
    649  }
    650 
    651  return TLV(der::SEQUENCE, value);
    652 }
    653 
    654 // AttributeTypeAndValue ::= SEQUENCE {
    655 //   type     AttributeType,
    656 //   value    AttributeValue }
    657 //
    658 // AttributeType ::= OBJECT IDENTIFIER
    659 //
    660 // AttributeValue ::= ANY -- DEFINED BY AttributeType
    661 //
    662 // DirectoryString ::= CHOICE {
    663 //       teletexString           TeletexString (SIZE (1..MAX)),
    664 //       printableString         PrintableString (SIZE (1..MAX)),
    665 //       universalString         UniversalString (SIZE (1..MAX)),
    666 //       utf8String              UTF8String (SIZE (1..MAX)),
    667 //       bmpString               BMPString (SIZE (1..MAX)) }
    668 template <size_t N>
    669 static ByteString
    670 AVA(const uint8_t (&type)[N], uint8_t directoryStringType,
    671    const ByteString& value)
    672 {
    673  ByteString wrappedValue(TLV(directoryStringType, value));
    674  ByteString ava;
    675  ava.append(type, N);
    676  ava.append(wrappedValue);
    677  return TLV(der::SEQUENCE, ava);
    678 }
    679 
    680 ByteString
    681 CN(const ByteString& value, uint8_t encodingTag)
    682 {
    683  // id-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 }
    684  // id-at-commonName        AttributeType ::= { id-at 3 }
    685  // python DottedOIDToCode.py --tlv id-at-commonName 2.5.4.3
    686  static const uint8_t tlv_id_at_commonName[] = {
    687    0x06, 0x03, 0x55, 0x04, 0x03
    688  };
    689  return AVA(tlv_id_at_commonName, encodingTag, value);
    690 }
    691 
    692 ByteString
    693 OU(const ByteString& value, uint8_t encodingTag)
    694 {
    695  // id-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 }
    696  // id-at-organizationalUnitName AttributeType ::= { id-at 11 }
    697  // python DottedOIDToCode.py --tlv id-at-organizationalUnitName 2.5.4.11
    698  static const uint8_t tlv_id_at_organizationalUnitName[] = {
    699    0x06, 0x03, 0x55, 0x04, 0x0b
    700  };
    701 
    702  return AVA(tlv_id_at_organizationalUnitName, encodingTag, value);
    703 }
    704 
    705 ByteString
    706 emailAddress(const ByteString& value)
    707 {
    708  // id-emailAddress AttributeType ::= { pkcs-9 1 }
    709  // python DottedOIDToCode.py --tlv id-emailAddress 1.2.840.113549.1.9.1
    710  static const uint8_t tlv_id_emailAddress[] = {
    711    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01
    712  };
    713 
    714  return AVA(tlv_id_emailAddress, der::IA5String, value);
    715 }
    716 
    717 // RelativeDistinguishedName ::=
    718 //   SET SIZE (1..MAX) OF AttributeTypeAndValue
    719 //
    720 ByteString
    721 RDN(const ByteString& avas)
    722 {
    723  return TLV(der::SET, avas);
    724 }
    725 
    726 // Name ::= CHOICE { -- only one possibility for now --
    727 //   rdnSequence  RDNSequence }
    728 //
    729 // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
    730 //
    731 ByteString
    732 Name(const ByteString& rdns)
    733 {
    734  return TLV(der::SEQUENCE, rdns);
    735 }
    736 
    737 ByteString
    738 CreateEncodedSerialNumber(long serialNumberValue)
    739 {
    740  return Integer(serialNumberValue);
    741 }
    742 
    743 // BasicConstraints ::= SEQUENCE {
    744 //         cA                      BOOLEAN DEFAULT FALSE,
    745 //         pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
    746 ByteString
    747 CreateEncodedBasicConstraints(bool isCA,
    748                              /*optional in*/ const long* pathLenConstraintValue,
    749                              Critical critical)
    750 {
    751  ByteString value;
    752 
    753  if (isCA) {
    754    ByteString cA(Boolean(true));
    755    value.append(cA);
    756  }
    757 
    758  if (pathLenConstraintValue) {
    759    ByteString pathLenConstraint(Integer(*pathLenConstraintValue));
    760    value.append(pathLenConstraint);
    761  }
    762 
    763  // python DottedOIDToCode.py --tlv id-ce-basicConstraints 2.5.29.19
    764  static const uint8_t tlv_id_ce_basicConstraints[] = {
    765    0x06, 0x03, 0x55, 0x1d, 0x13
    766  };
    767  return Extension(Input(tlv_id_ce_basicConstraints), critical, value);
    768 }
    769 
    770 // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
    771 // KeyPurposeId ::= OBJECT IDENTIFIER
    772 ByteString
    773 CreateEncodedEKUExtension(Input ekuOID, Critical critical)
    774 {
    775  ByteString value(ekuOID.UnsafeGetData(), ekuOID.GetLength());
    776 
    777  // python DottedOIDToCode.py --tlv id-ce-extKeyUsage 2.5.29.37
    778  static const uint8_t tlv_id_ce_extKeyUsage[] = {
    779    0x06, 0x03, 0x55, 0x1d, 0x25
    780  };
    781 
    782  return Extension(Input(tlv_id_ce_extKeyUsage), critical, value);
    783 }
    784 
    785 // python DottedOIDToCode.py --tlv id-ce-subjectAltName 2.5.29.17
    786 static const uint8_t tlv_id_ce_subjectAltName[] = {
    787  0x06, 0x03, 0x55, 0x1d, 0x11
    788 };
    789 
    790 ByteString
    791 CreateEncodedSubjectAltName(const ByteString& names)
    792 {
    793  return Extension(Input(tlv_id_ce_subjectAltName), Critical::No, names);
    794 }
    795 
    796 ByteString
    797 CreateEncodedEmptySubjectAltName()
    798 {
    799  return EmptyExtension(Input(tlv_id_ce_subjectAltName), Critical::No);
    800 }
    801 
    802 ///////////////////////////////////////////////////////////////////////////////
    803 // OCSP responses
    804 
    805 ByteString
    806 CreateEncodedOCSPResponse(OCSPResponseContext& context)
    807 {
    808  if (!context.skipResponseBytes) {
    809    if (!context.signerKeyPair) {
    810      return ByteString();
    811    }
    812  }
    813 
    814  // OCSPResponse ::= SEQUENCE {
    815  //    responseStatus          OCSPResponseStatus,
    816  //    responseBytes       [0] EXPLICIT ResponseBytes OPTIONAL }
    817 
    818  // OCSPResponseStatus ::= ENUMERATED {
    819  //    successful          (0),  -- Response has valid confirmations
    820  //    malformedRequest    (1),  -- Illegal confirmation request
    821  //    internalError       (2),  -- Internal error in issuer
    822  //    tryLater            (3),  -- Try again later
    823  //                              -- (4) is not used
    824  //    sigRequired         (5),  -- Must sign the request
    825  //    unauthorized        (6)   -- Request unauthorized
    826  // }
    827  ByteString reponseStatusValue;
    828  reponseStatusValue.push_back(context.responseStatus);
    829  ByteString responseStatus(TLV(der::ENUMERATED, reponseStatusValue));
    830 
    831  ByteString responseBytesNested;
    832  if (!context.skipResponseBytes) {
    833    ByteString responseBytes(ResponseBytes(context));
    834    if (ENCODING_FAILED(responseBytes)) {
    835      return ByteString();
    836    }
    837 
    838    responseBytesNested = TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC,
    839                              responseBytes);
    840  }
    841 
    842  ByteString value;
    843  value.append(responseStatus);
    844  value.append(responseBytesNested);
    845  ByteString result(TLV(der::SEQUENCE, value));
    846 
    847  MaybeLogOutput(result, "ocsp");
    848 
    849  return result;
    850 }
    851 
    852 // ResponseBytes ::= SEQUENCE {
    853 //    responseType            OBJECT IDENTIFIER,
    854 //    response                OCTET STRING }
    855 ByteString
    856 ResponseBytes(OCSPResponseContext& context)
    857 {
    858  // Includes tag and length
    859  static const uint8_t id_pkix_ocsp_basic_encoded[] = {
    860    0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
    861  };
    862  ByteString response(BasicOCSPResponse(context));
    863  if (ENCODING_FAILED(response)) {
    864    return ByteString();
    865  }
    866  ByteString responseNested = TLV(der::OCTET_STRING, response);
    867 
    868  ByteString value;
    869  value.append(id_pkix_ocsp_basic_encoded,
    870               sizeof(id_pkix_ocsp_basic_encoded));
    871  value.append(responseNested);
    872  return TLV(der::SEQUENCE, value);
    873 }
    874 
    875 // BasicOCSPResponse ::= SEQUENCE {
    876 //   tbsResponseData          ResponseData,
    877 //   signatureAlgorithm       AlgorithmIdentifier,
    878 //   signature                BIT STRING,
    879 //   certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
    880 ByteString
    881 BasicOCSPResponse(OCSPResponseContext& context)
    882 {
    883  ByteString tbsResponseData(ResponseData(context));
    884  if (ENCODING_FAILED(tbsResponseData)) {
    885    return ByteString();
    886  }
    887 
    888  return SignedData(tbsResponseData, *context.signerKeyPair,
    889                    context.signatureAlgorithm, context.badSignature,
    890                    context.certs);
    891 }
    892 
    893 // Extension ::= SEQUENCE {
    894 //   id               OBJECT IDENTIFIER,
    895 //   critical         BOOLEAN DEFAULT FALSE
    896 //   value            OCTET STRING
    897 // }
    898 static ByteString
    899 OCSPExtension(OCSPResponseExtension& extension)
    900 {
    901  ByteString encoded;
    902  encoded.append(extension.id);
    903  if (extension.critical) {
    904    encoded.append(Boolean(true));
    905  }
    906  ByteString value(TLV(der::OCTET_STRING, extension.value));
    907  encoded.append(value);
    908  return TLV(der::SEQUENCE, encoded);
    909 }
    910 
    911 // Extensions ::= [1] {
    912 //   SEQUENCE OF Extension
    913 // }
    914 static ByteString
    915 OCSPExtensions(OCSPResponseExtension* extensions)
    916 {
    917  ByteString value;
    918  for (OCSPResponseExtension* extension = extensions;
    919       extension; extension = extension->next) {
    920    ByteString extensionEncoded(OCSPExtension(*extension));
    921    if (ENCODING_FAILED(extensionEncoded)) {
    922      return ByteString();
    923    }
    924    value.append(extensionEncoded);
    925  }
    926  ByteString sequence(TLV(der::SEQUENCE, value));
    927  return TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 1, sequence);
    928 }
    929 
    930 // ResponseData ::= SEQUENCE {
    931 //    version             [0] EXPLICIT Version DEFAULT v1,
    932 //    responderID             ResponderID,
    933 //    producedAt              GeneralizedTime,
    934 //    responses               SEQUENCE OF SingleResponse,
    935 //    responseExtensions  [1] EXPLICIT Extensions OPTIONAL }
    936 ByteString
    937 ResponseData(OCSPResponseContext& context)
    938 {
    939  ByteString responderID(ResponderID(context));
    940  if (ENCODING_FAILED(responderID)) {
    941    return ByteString();
    942  }
    943  ByteString producedAtEncoded(TimeToGeneralizedTime(context.producedAt));
    944  if (ENCODING_FAILED(producedAtEncoded)) {
    945    return ByteString();
    946  }
    947  ByteString response(SingleResponse(context));
    948  if (ENCODING_FAILED(response)) {
    949    return ByteString();
    950  }
    951  ByteString responses(TLV(der::SEQUENCE, response));
    952  ByteString responseExtensions;
    953  if (context.responseExtensions || context.includeEmptyExtensions) {
    954    responseExtensions = OCSPExtensions(context.responseExtensions);
    955  }
    956 
    957  ByteString value;
    958  value.append(responderID);
    959  value.append(producedAtEncoded);
    960  value.append(responses);
    961  value.append(responseExtensions);
    962  if (context.trailingResponseData) {
    963    value.append(*(context.trailingResponseData));
    964  }
    965  return TLV(der::SEQUENCE, value);
    966 }
    967 
    968 // ResponderID ::= CHOICE {
    969 //    byName              [1] Name,
    970 //    byKey               [2] KeyHash }
    971 // }
    972 ByteString
    973 ResponderID(OCSPResponseContext& context)
    974 {
    975  ByteString contents;
    976  uint8_t responderIDType;
    977  if (!context.signerNameDER.empty()) {
    978    contents = context.signerNameDER;
    979    responderIDType = 1; // byName
    980  } else {
    981    contents = KeyHash(context.signerKeyPair->subjectPublicKey);
    982    if (ENCODING_FAILED(contents)) {
    983      return ByteString();
    984    }
    985    responderIDType = 2; // byKey
    986  }
    987 
    988  // XXX: MSVC 2015 wrongly warns about signed/unsigned conversion without the
    989  // static_cast.
    990  uint8_t tag = static_cast<uint8_t>(der::CONSTRUCTED | der::CONTEXT_SPECIFIC |
    991                                     responderIDType);
    992  return TLV(tag, contents);
    993 }
    994 
    995 // KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key
    996 //                          -- (i.e., the SHA-1 hash of the value of the
    997 //                          -- BIT STRING subjectPublicKey [excluding
    998 //                          -- the tag, length, and number of unused
    999 //                          -- bits] in the responder's certificate)
   1000 ByteString
   1001 KeyHash(const ByteString& subjectPublicKey)
   1002 {
   1003  return HashedOctetString(subjectPublicKey, DigestAlgorithm::sha1);
   1004 }
   1005 
   1006 // SingleResponse ::= SEQUENCE {
   1007 //    certID                  CertID,
   1008 //    certStatus              CertStatus,
   1009 //    thisUpdate              GeneralizedTime,
   1010 //    nextUpdate          [0] EXPLICIT GeneralizedTime OPTIONAL,
   1011 //    singleExtensions    [1] EXPLICIT Extensions OPTIONAL }
   1012 ByteString
   1013 SingleResponse(OCSPResponseContext& context)
   1014 {
   1015  ByteString certID(CertID(context));
   1016  if (ENCODING_FAILED(certID)) {
   1017    return ByteString();
   1018  }
   1019  ByteString certStatus(CertStatus(context));
   1020  if (ENCODING_FAILED(certStatus)) {
   1021    return ByteString();
   1022  }
   1023  ByteString thisUpdateEncoded(TimeToGeneralizedTime(context.thisUpdate));
   1024  if (ENCODING_FAILED(thisUpdateEncoded)) {
   1025    return ByteString();
   1026  }
   1027  ByteString nextUpdateEncodedNested;
   1028  if (context.includeNextUpdate) {
   1029    ByteString nextUpdateEncoded(TimeToGeneralizedTime(context.nextUpdate));
   1030    if (ENCODING_FAILED(nextUpdateEncoded)) {
   1031      return ByteString();
   1032    }
   1033    nextUpdateEncodedNested = TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0,
   1034                                  nextUpdateEncoded);
   1035  }
   1036  ByteString singleExtensions;
   1037  if (context.singleExtensions || context.includeEmptyExtensions) {
   1038    singleExtensions = OCSPExtensions(context.singleExtensions);
   1039  }
   1040 
   1041  ByteString value;
   1042  value.append(certID);
   1043  value.append(certStatus);
   1044  value.append(thisUpdateEncoded);
   1045  value.append(nextUpdateEncodedNested);
   1046  value.append(singleExtensions);
   1047  return TLV(der::SEQUENCE, value);
   1048 }
   1049 
   1050 // CertID          ::=     SEQUENCE {
   1051 //        hashAlgorithm       AlgorithmIdentifier,
   1052 //        issuerNameHash      OCTET STRING, -- Hash of issuer's DN
   1053 //        issuerKeyHash       OCTET STRING, -- Hash of issuer's public key
   1054 //        serialNumber        CertificateSerialNumber }
   1055 ByteString
   1056 CertID(OCSPResponseContext& context)
   1057 {
   1058  ByteString issuerName(context.certID.issuer.UnsafeGetData(),
   1059                        context.certID.issuer.GetLength());
   1060  ByteString issuerNameHash(HashedOctetString(issuerName, context.certIDHashAlgorithm));
   1061  if (ENCODING_FAILED(issuerNameHash)) {
   1062    return ByteString();
   1063  }
   1064 
   1065  ByteString issuerKeyHash;
   1066  {
   1067    // context.certID.issuerSubjectPublicKeyInfo is the entire
   1068    // SubjectPublicKeyInfo structure, but we need just the subjectPublicKey
   1069    // part.
   1070    Reader input(context.certID.issuerSubjectPublicKeyInfo);
   1071    Reader contents;
   1072    if (der::ExpectTagAndGetValue(input, der::SEQUENCE, contents) != Success) {
   1073      return ByteString();
   1074    }
   1075    // Skip AlgorithmIdentifier
   1076    if (der::ExpectTagAndSkipValue(contents, der::SEQUENCE) != Success) {
   1077      return ByteString();
   1078    }
   1079    Input subjectPublicKey;
   1080    if (der::BitStringWithNoUnusedBits(contents, subjectPublicKey)
   1081          != Success) {
   1082      return ByteString();
   1083    }
   1084    issuerKeyHash = HashedOctetString(ByteString(subjectPublicKey.UnsafeGetData(),
   1085        subjectPublicKey.GetLength()), context.certIDHashAlgorithm);
   1086    if (ENCODING_FAILED(issuerKeyHash)) {
   1087      return ByteString();
   1088    }
   1089  }
   1090 
   1091  ByteString serialNumberValue(context.certID.serialNumber.UnsafeGetData(),
   1092                               context.certID.serialNumber.GetLength());
   1093  ByteString serialNumber(TLV(der::INTEGER, serialNumberValue));
   1094 
   1095  // python DottedOIDToCode.py --alg id-sha1 1.3.14.3.2.26
   1096  static const uint8_t alg_id_sha1[] = {
   1097    0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a
   1098  };
   1099  // python DottedOIDToCode.py --alg id-sha256 2.16.840.1.101.3.4.2.1
   1100  static const uint8_t alg_id_sha256[] = {
   1101    0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
   1102  };
   1103  // python DottedOIDToCode.py --alg id-sha384 2.16.840.1.101.3.4.2.2
   1104  static const uint8_t alg_id_sha384[] = {
   1105    0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02
   1106  };
   1107  // python DottedOIDToCode.py --alg id-sha512 2.16.840.1.101.3.4.2.3
   1108  static const uint8_t alg_id_sha512[] = {
   1109    0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03
   1110  };
   1111 
   1112  ByteString value;
   1113  if (!context.certIDHashAlgorithmEncoded.empty()) {
   1114    value.append(context.certIDHashAlgorithmEncoded);
   1115  } else {
   1116    switch (context.certIDHashAlgorithm) {
   1117      case DigestAlgorithm::sha1:
   1118        value.append(alg_id_sha1, sizeof(alg_id_sha1));
   1119        break;
   1120      case DigestAlgorithm::sha256:
   1121        value.append(alg_id_sha256, sizeof(alg_id_sha256));
   1122        break;
   1123      case DigestAlgorithm::sha384:
   1124        value.append(alg_id_sha384, sizeof(alg_id_sha384));
   1125        break;
   1126      case DigestAlgorithm::sha512:
   1127        value.append(alg_id_sha512, sizeof(alg_id_sha512));
   1128        break;
   1129      MOZILLA_PKIX_UNREACHABLE_DEFAULT_ENUM
   1130    }
   1131  }
   1132  value.append(issuerNameHash);
   1133  value.append(issuerKeyHash);
   1134  value.append(serialNumber);
   1135  return TLV(der::SEQUENCE, value);
   1136 }
   1137 
   1138 // CertStatus ::= CHOICE {
   1139 //    good                [0] IMPLICIT NULL,
   1140 //    revoked             [1] IMPLICIT RevokedInfo,
   1141 //    unknown             [2] IMPLICIT UnknownInfo }
   1142 //
   1143 // RevokedInfo ::= SEQUENCE {
   1144 //    revocationTime              GeneralizedTime,
   1145 //    revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
   1146 //
   1147 // UnknownInfo ::= NULL
   1148 //
   1149 ByteString
   1150 CertStatus(OCSPResponseContext& context)
   1151 {
   1152  switch (context.certStatus) {
   1153    // Both good and unknown are ultimately represented as NULL - the only
   1154    // difference is in the tag that identifies them.
   1155    case 0:
   1156    case 2:
   1157    {
   1158      // XXX: MSVC 2015 wrongly warns about signed/unsigned conversion without
   1159      // the static cast.
   1160      return TLV(static_cast<uint8_t>(der::CONTEXT_SPECIFIC |
   1161                                      context.certStatus), ByteString());
   1162    }
   1163    case 1:
   1164    {
   1165      ByteString revocationTime(TimeToGeneralizedTime(context.revocationTime));
   1166      if (ENCODING_FAILED(revocationTime)) {
   1167        return ByteString();
   1168      }
   1169      // TODO(bug 980536): add support for revocationReason
   1170      return TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1, revocationTime);
   1171    }
   1172    default:
   1173      assert(false);
   1174      // fall through
   1175  }
   1176  return ByteString();
   1177 }
   1178 
   1179 static const ByteString NO_UNUSED_BITS(1, 0x00);
   1180 
   1181 // The SubjectPublicKeyInfo syntax is specified in RFC 5280 Section 4.1.
   1182 TestKeyPair::TestKeyPair(const TestPublicKeyAlgorithm& aPublicKeyAlg,
   1183                         const ByteString& spk)
   1184  : publicKeyAlg(aPublicKeyAlg)
   1185  , subjectPublicKeyInfo(TLV(der::SEQUENCE,
   1186                             aPublicKeyAlg.algorithmIdentifier +
   1187                             TLV(der::BIT_STRING, NO_UNUSED_BITS + spk)))
   1188  , subjectPublicKey(spk)
   1189 {
   1190 }
   1191 
   1192 } } } // namespace mozilla::pkix::test