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