tor-browser

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

pkixder.h (17244B)


      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_pkixder_h
     26 #define mozilla_pkix_pkixder_h
     27 
     28 // Expect* functions advance the input mark and return Success if the input
     29 // matches the given criteria; they fail with the input mark in an undefined
     30 // state if the input does not match the criteria.
     31 //
     32 // Match* functions advance the input mark and return true if the input matches
     33 // the given criteria; they return false without changing the input mark if the
     34 // input does not match the criteria.
     35 //
     36 // Skip* functions unconditionally advance the input mark and return Success if
     37 // they are able to do so; otherwise they fail with the input mark in an
     38 // undefined state.
     39 
     40 #include "mozpkix/Input.h"
     41 #include "mozpkix/pkixtypes.h"
     42 
     43 namespace mozilla {
     44 namespace pkix {
     45 namespace der {
     46 
     47 enum Class : uint8_t {
     48  UNIVERSAL = 0 << 6,
     49  // APPLICATION = 1 << 6, // unused
     50  CONTEXT_SPECIFIC = 2 << 6,
     51  // PRIVATE = 3 << 6 // unused
     52 };
     53 
     54 enum Constructed { CONSTRUCTED = 1 << 5 };
     55 
     56 enum Tag : uint8_t {
     57  BOOLEAN = UNIVERSAL | 0x01,
     58  INTEGER = UNIVERSAL | 0x02,
     59  BIT_STRING = UNIVERSAL | 0x03,
     60  OCTET_STRING = UNIVERSAL | 0x04,
     61  NULLTag = UNIVERSAL | 0x05,
     62  OIDTag = UNIVERSAL | 0x06,
     63  ENUMERATED = UNIVERSAL | 0x0a,
     64  UTF8String = UNIVERSAL | 0x0c,
     65  SEQUENCE = UNIVERSAL | CONSTRUCTED | 0x10,  // 0x30
     66  SET = UNIVERSAL | CONSTRUCTED | 0x11,       // 0x31
     67  PrintableString = UNIVERSAL | 0x13,
     68  TeletexString = UNIVERSAL | 0x14,
     69  IA5String = UNIVERSAL | 0x16,
     70  UTCTime = UNIVERSAL | 0x17,
     71  GENERALIZED_TIME = UNIVERSAL | 0x18,
     72 };
     73 
     74 enum class EmptyAllowed { No = 0, Yes = 1 };
     75 
     76 Result ReadTagAndGetValue(Reader& input, /*out*/ uint8_t& tag,
     77                          /*out*/ Input& value);
     78 Result End(Reader& input);
     79 
     80 inline Result ExpectTagAndGetValue(Reader& input, uint8_t tag,
     81                                   /*out*/ Input& value) {
     82  uint8_t actualTag;
     83  Result rv = ReadTagAndGetValue(input, actualTag, value);
     84  if (rv != Success) {
     85    return rv;
     86  }
     87  if (tag != actualTag) {
     88    return Result::ERROR_BAD_DER;
     89  }
     90  return Success;
     91 }
     92 
     93 inline Result ExpectTagAndGetValue(Reader& input, uint8_t tag,
     94                                   /*out*/ Reader& value) {
     95  Input valueInput;
     96  Result rv = ExpectTagAndGetValue(input, tag, valueInput);
     97  if (rv != Success) {
     98    return rv;
     99  }
    100  return value.Init(valueInput);
    101 }
    102 
    103 inline Result ExpectTagAndEmptyValue(Reader& input, uint8_t tag) {
    104  Reader value;
    105  Result rv = ExpectTagAndGetValue(input, tag, value);
    106  if (rv != Success) {
    107    return rv;
    108  }
    109  return End(value);
    110 }
    111 
    112 inline Result ExpectTagAndSkipValue(Reader& input, uint8_t tag) {
    113  Input ignoredValue;
    114  return ExpectTagAndGetValue(input, tag, ignoredValue);
    115 }
    116 
    117 // This skips IMPLICIT OPTIONAL tags that are "primitive" (not constructed),
    118 // given the number in the class of the tag (i.e. the number in the brackets in
    119 // `issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL`).
    120 inline Result SkipOptionalImplicitPrimitiveTag(Reader& input,
    121                                               uint8_t numberInClass) {
    122  if (input.Peek(CONTEXT_SPECIFIC | numberInClass)) {
    123    return ExpectTagAndSkipValue(input, CONTEXT_SPECIFIC | numberInClass);
    124  }
    125  return Success;
    126 }
    127 
    128 // Like ExpectTagAndGetValue, except the output Input will contain the
    129 // encoded tag and length along with the value.
    130 inline Result ExpectTagAndGetTLV(Reader& input, uint8_t tag,
    131                                 /*out*/ Input& tlv) {
    132  Reader::Mark mark(input.GetMark());
    133  Result rv = ExpectTagAndSkipValue(input, tag);
    134  if (rv != Success) {
    135    return rv;
    136  }
    137  return input.GetInput(mark, tlv);
    138 }
    139 
    140 inline Result End(Reader& input) {
    141  if (!input.AtEnd()) {
    142    return Result::ERROR_BAD_DER;
    143  }
    144 
    145  return Success;
    146 }
    147 
    148 template <typename Decoder>
    149 inline Result Nested(Reader& input, uint8_t tag, Decoder decoder) {
    150  Reader nested;
    151  Result rv = ExpectTagAndGetValue(input, tag, nested);
    152  if (rv != Success) {
    153    return rv;
    154  }
    155  rv = decoder(nested);
    156  if (rv != Success) {
    157    return rv;
    158  }
    159  return End(nested);
    160 }
    161 
    162 template <typename Decoder>
    163 inline Result Nested(Reader& input, uint8_t outerTag, uint8_t innerTag,
    164                     Decoder decoder) {
    165  Reader nestedInput;
    166  Result rv = ExpectTagAndGetValue(input, outerTag, nestedInput);
    167  if (rv != Success) {
    168    return rv;
    169  }
    170  rv = Nested(nestedInput, innerTag, decoder);
    171  if (rv != Success) {
    172    return rv;
    173  }
    174  return End(nestedInput);
    175 }
    176 
    177 // This can be used to decode constructs like this:
    178 //
    179 //     ...
    180 //     foos SEQUENCE OF Foo,
    181 //     ...
    182 //     Foo ::= SEQUENCE {
    183 //     }
    184 //
    185 // using code like this:
    186 //
    187 //    Result Foo(Reader& r) { /*...*/ }
    188 //
    189 //    rv = der::NestedOf(input, der::SEQEUENCE, der::SEQUENCE, Foo);
    190 //
    191 // or:
    192 //
    193 //    Result Bar(Reader& r, int value) { /*...*/ }
    194 //
    195 //    int value = /*...*/;
    196 //
    197 //    rv = der::NestedOf(input, der::SEQUENCE, [value](Reader& r) {
    198 //      return Bar(r, value);
    199 //    });
    200 //
    201 // In these examples the function will get called once for each element of
    202 // foos.
    203 //
    204 template <typename Decoder>
    205 inline Result NestedOf(Reader& input, uint8_t outerTag, uint8_t innerTag,
    206                       EmptyAllowed mayBeEmpty, Decoder decoder) {
    207  Reader inner;
    208  Result rv = ExpectTagAndGetValue(input, outerTag, inner);
    209  if (rv != Success) {
    210    return rv;
    211  }
    212 
    213  if (inner.AtEnd()) {
    214    if (mayBeEmpty != EmptyAllowed::Yes) {
    215      return Result::ERROR_BAD_DER;
    216    }
    217    return Success;
    218  }
    219 
    220  do {
    221    rv = Nested(inner, innerTag, decoder);
    222    if (rv != Success) {
    223      return rv;
    224    }
    225  } while (!inner.AtEnd());
    226 
    227  return Success;
    228 }
    229 
    230 // Often, a function will need to decode an Input or Reader that contains
    231 // DER-encoded data wrapped in a SEQUENCE (or similar) with nothing after it.
    232 // This function reduces the boilerplate necessary for stripping the outermost
    233 // SEQUENCE (or similar) and ensuring that nothing follows it.
    234 inline Result ExpectTagAndGetValueAtEnd(Reader& outer, uint8_t expectedTag,
    235                                        /*out*/ Reader& inner) {
    236  Result rv = der::ExpectTagAndGetValue(outer, expectedTag, inner);
    237  if (rv != Success) {
    238    return rv;
    239  }
    240  return der::End(outer);
    241 }
    242 
    243 // Similar to the above, but takes an Input instead of a Reader&.
    244 inline Result ExpectTagAndGetValueAtEnd(Input outer, uint8_t expectedTag,
    245                                        /*out*/ Reader& inner) {
    246  Reader outerReader(outer);
    247  return ExpectTagAndGetValueAtEnd(outerReader, expectedTag, inner);
    248 }
    249 
    250 // Universal types
    251 
    252 namespace internal {
    253 
    254 enum class IntegralValueRestriction {
    255  NoRestriction,
    256  MustBePositive,
    257  MustBe0To127,
    258 };
    259 
    260 Result IntegralBytes(
    261    Reader& input, uint8_t tag, IntegralValueRestriction valueRestriction,
    262    /*out*/ Input& value,
    263    /*optional out*/ Input::size_type* significantBytes = nullptr);
    264 
    265 // This parser will only parse values between 0..127. If this range is
    266 // increased then callers will need to be changed.
    267 Result IntegralValue(Reader& input, uint8_t tag, /*out*/ uint8_t& value);
    268 
    269 }  // namespace internal
    270 
    271 Result BitStringWithNoUnusedBits(Reader& input, /*out*/ Input& value);
    272 
    273 inline Result Boolean(Reader& input, /*out*/ bool& value) {
    274  Reader valueReader;
    275  Result rv = ExpectTagAndGetValue(input, BOOLEAN, valueReader);
    276  if (rv != Success) {
    277    return rv;
    278  }
    279 
    280  uint8_t intValue;
    281  rv = valueReader.Read(intValue);
    282  if (rv != Success) {
    283    return rv;
    284  }
    285  rv = End(valueReader);
    286  if (rv != Success) {
    287    return rv;
    288  }
    289  switch (intValue) {
    290    case 0:
    291      value = false;
    292      return Success;
    293    case 0xFF:
    294      value = true;
    295      return Success;
    296    default:
    297      return Result::ERROR_BAD_DER;
    298  }
    299 }
    300 
    301 // This is for BOOLEAN DEFAULT FALSE.
    302 // The standard stipulates that "The encoding of a set value or sequence value
    303 // shall not include an encoding for any component value which is equal to its
    304 // default value." However, it appears to be common that other libraries
    305 // incorrectly include the value of a BOOLEAN even when it's equal to the
    306 // default value, so we allow invalid explicit encodings here.
    307 inline Result OptionalBoolean(Reader& input, /*out*/ bool& value) {
    308  value = false;
    309  if (input.Peek(BOOLEAN)) {
    310    Result rv = Boolean(input, value);
    311    if (rv != Success) {
    312      return rv;
    313    }
    314  }
    315  return Success;
    316 }
    317 
    318 // This parser will only parse values between 0..127. If this range is
    319 // increased then callers will need to be changed.
    320 inline Result Enumerated(Reader& input, uint8_t& value) {
    321  return internal::IntegralValue(input, ENUMERATED | 0, value);
    322 }
    323 
    324 namespace internal {
    325 
    326 // internal::TimeChoice implements the shared functionality of GeneralizedTime
    327 // and TimeChoice. tag must be either UTCTime or GENERALIZED_TIME.
    328 //
    329 // Only times from 1970-01-01-00:00:00 onward are accepted, in order to
    330 // eliminate the chance for complications in converting times to traditional
    331 // time formats that start at 1970.
    332 Result TimeChoice(Reader& input, uint8_t tag, /*out*/ Time& time);
    333 
    334 }  // namespace internal
    335 
    336 // Only times from 1970-01-01-00:00:00 onward are accepted, in order to
    337 // eliminate the chance for complications in converting times to traditional
    338 // time formats that start at 1970.
    339 inline Result GeneralizedTime(Reader& input, /*out*/ Time& time) {
    340  return internal::TimeChoice(input, GENERALIZED_TIME, time);
    341 }
    342 
    343 // Only times from 1970-01-01-00:00:00 onward are accepted, in order to
    344 // eliminate the chance for complications in converting times to traditional
    345 // time formats that start at 1970.
    346 inline Result TimeChoice(Reader& input, /*out*/ Time& time) {
    347  uint8_t expectedTag = input.Peek(UTCTime) ? UTCTime : GENERALIZED_TIME;
    348  return internal::TimeChoice(input, expectedTag, time);
    349 }
    350 
    351 // Parse a DER integer value into value. Empty values, negative values, and
    352 // zero are rejected. If significantBytes is not null, then it will be set to
    353 // the number of significant bytes in the value (the length of the value, less
    354 // the length of any leading padding), which is useful for key size checks.
    355 inline Result PositiveInteger(
    356    Reader& input, /*out*/ Input& value,
    357    /*optional out*/ Input::size_type* significantBytes = nullptr) {
    358  return internal::IntegralBytes(
    359      input, INTEGER, internal::IntegralValueRestriction::MustBePositive, value,
    360      significantBytes);
    361 }
    362 
    363 // This parser will only parse values between 0..127. If this range is
    364 // increased then callers will need to be changed.
    365 inline Result Integer(Reader& input, /*out*/ uint8_t& value) {
    366  return internal::IntegralValue(input, INTEGER, value);
    367 }
    368 
    369 // This parser will only parse values between 0..127. If this range is
    370 // increased then callers will need to be changed. The default value must be
    371 // -1; defaultValue is only a parameter to make it clear in the calling code
    372 // what the default value is.
    373 inline Result OptionalInteger(Reader& input, long defaultValue,
    374                              /*out*/ long& value) {
    375  // If we need to support a different default value in the future, we need to
    376  // test that parsedValue != defaultValue.
    377  if (defaultValue != -1) {
    378    return Result::FATAL_ERROR_INVALID_ARGS;
    379  }
    380 
    381  if (!input.Peek(INTEGER)) {
    382    value = defaultValue;
    383    return Success;
    384  }
    385 
    386  uint8_t parsedValue;
    387  Result rv = Integer(input, parsedValue);
    388  if (rv != Success) {
    389    return rv;
    390  }
    391  value = parsedValue;
    392  return Success;
    393 }
    394 
    395 inline Result Null(Reader& input) {
    396  return ExpectTagAndEmptyValue(input, NULLTag);
    397 }
    398 
    399 template <uint8_t Len>
    400 Result OID(Reader& input, const uint8_t (&expectedOid)[Len]) {
    401  Reader value;
    402  Result rv = ExpectTagAndGetValue(input, OIDTag, value);
    403  if (rv != Success) {
    404    return rv;
    405  }
    406  if (!value.MatchRest(expectedOid)) {
    407    return Result::ERROR_BAD_DER;
    408  }
    409  return Success;
    410 }
    411 
    412 // PKI-specific types
    413 
    414 inline Result CertificateSerialNumber(Reader& input, /*out*/ Input& value) {
    415  // http://tools.ietf.org/html/rfc5280#section-4.1.2.2:
    416  //
    417  // * "The serial number MUST be a positive integer assigned by the CA to
    418  //   each certificate."
    419  // * "Certificate users MUST be able to handle serialNumber values up to 20
    420  //   octets. Conforming CAs MUST NOT use serialNumber values longer than 20
    421  //   octets."
    422  // * "Note: Non-conforming CAs may issue certificates with serial numbers
    423  //   that are negative or zero.  Certificate users SHOULD be prepared to
    424  //   gracefully handle such certificates."
    425  return internal::IntegralBytes(
    426      input, INTEGER, internal::IntegralValueRestriction::NoRestriction, value);
    427 }
    428 
    429 // x.509 and OCSP both use this same version numbering scheme, though OCSP
    430 // only supports v1.
    431 enum class Version { v1 = 0, v2 = 1, v3 = 2, v4 = 3, Uninitialized = 255 };
    432 
    433 // X.509 Certificate and OCSP ResponseData both use
    434 // "[0] EXPLICIT Version DEFAULT v1". Although an explicit encoding of v1 is
    435 // illegal, we support it because some real-world OCSP responses explicitly
    436 // encode it.
    437 Result OptionalVersion(Reader& input, /*out*/ Version& version);
    438 
    439 template <typename ExtensionHandler>
    440 inline Result OptionalExtensions(Reader& input, uint8_t tag,
    441                                 ExtensionHandler extensionHandler) {
    442  if (!input.Peek(tag)) {
    443    return Success;
    444  }
    445 
    446  return Nested(input, tag, [extensionHandler](Reader& tagged) {
    447    // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
    448    //
    449    // TODO(bug 997994): According to the specification, there should never be
    450    // an empty sequence of extensions but we've found OCSP responses that have
    451    // that (see bug 991898).
    452    return NestedOf(
    453        tagged, SEQUENCE, SEQUENCE, EmptyAllowed::Yes,
    454        [extensionHandler](Reader& extension) -> Result {
    455          // Extension  ::=  SEQUENCE  {
    456          //      extnID      OBJECT IDENTIFIER,
    457          //      critical    BOOLEAN DEFAULT FALSE,
    458          //      extnValue   OCTET STRING
    459          //      }
    460          Reader extnID;
    461          Result rv = ExpectTagAndGetValue(extension, OIDTag, extnID);
    462          if (rv != Success) {
    463            return rv;
    464          }
    465          bool critical;
    466          rv = OptionalBoolean(extension, critical);
    467          if (rv != Success) {
    468            return rv;
    469          }
    470          Input extnValue;
    471          rv = ExpectTagAndGetValue(extension, OCTET_STRING, extnValue);
    472          if (rv != Success) {
    473            return rv;
    474          }
    475          bool understood = false;
    476          rv = extensionHandler(extnID, extnValue, critical, understood);
    477          if (rv != Success) {
    478            return rv;
    479          }
    480          if (critical && !understood) {
    481            return Result::ERROR_UNKNOWN_CRITICAL_EXTENSION;
    482          }
    483          return Success;
    484        });
    485  });
    486 }
    487 
    488 Result DigestAlgorithmIdentifier(Reader& input,
    489                                 /*out*/ DigestAlgorithm& algorithm);
    490 
    491 enum class PublicKeyAlgorithm { RSA_PKCS1, RSA_PSS, ECDSA };
    492 
    493 Result SignatureAlgorithmIdentifierValue(
    494    Reader& input,
    495    /*out*/ PublicKeyAlgorithm& publicKeyAlgorithm,
    496    /*out*/ DigestAlgorithm& digestAlgorithm);
    497 
    498 struct SignedDataWithSignature final {
    499 public:
    500  Input data;
    501  Input algorithm;
    502  Input signature;
    503 
    504  void operator=(const SignedDataWithSignature&) = delete;
    505 };
    506 
    507 // Parses a SEQUENCE into tbs and then parses an AlgorithmIdentifier followed
    508 // by a BIT STRING into signedData. This handles the commonality between
    509 // parsing the signed/signature fields of certificates and OCSP responses. In
    510 // the case of an OCSP response, the caller needs to parse the certs
    511 // separately.
    512 //
    513 // Note that signatureAlgorithm is NOT parsed or validated.
    514 //
    515 // Certificate  ::=  SEQUENCE  {
    516 //        tbsCertificate       TBSCertificate,
    517 //        signatureAlgorithm   AlgorithmIdentifier,
    518 //        signatureValue       BIT STRING  }
    519 //
    520 // BasicOCSPResponse       ::= SEQUENCE {
    521 //    tbsResponseData      ResponseData,
    522 //    signatureAlgorithm   AlgorithmIdentifier,
    523 //    signature            BIT STRING,
    524 //    certs            [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
    525 Result SignedData(Reader& input, /*out*/ Reader& tbs,
    526                  /*out*/ SignedDataWithSignature& signedDataWithSignature);
    527 
    528 // Parses an ECDSASigValue (RFC 5480) into its components r and s.
    529 Result ECDSASigValue(Input ecdsaSignature, /*out*/ Input& r, /*out*/ Input& s);
    530 }  // namespace der
    531 }  // namespace pkix
    532 }  // namespace mozilla
    533 
    534 #endif  // mozilla_pkix_pkixder_h