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 
ExpectTagAndGetValue(Reader & input,uint8_t tag,Input & value)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 
ExpectTagAndGetValue(Reader & input,uint8_t tag,Reader & value)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 
ExpectTagAndEmptyValue(Reader & input,uint8_t tag)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 
ExpectTagAndSkipValue(Reader & input,uint8_t tag)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`).
SkipOptionalImplicitPrimitiveTag(Reader & input,uint8_t numberInClass)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.
ExpectTagAndGetTLV(Reader & input,uint8_t tag,Input & tlv)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 
End(Reader & input)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>
Nested(Reader & input,uint8_t tag,Decoder 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>
Nested(Reader & input,uint8_t outerTag,uint8_t innerTag,Decoder 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>
NestedOf(Reader & input,uint8_t outerTag,uint8_t innerTag,EmptyAllowed mayBeEmpty,Decoder 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.
ExpectTagAndGetValueAtEnd(Reader & outer,uint8_t expectedTag,Reader & inner)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&.
ExpectTagAndGetValueAtEnd(Input outer,uint8_t expectedTag,Reader & inner)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 
Boolean(Reader & input,bool & value)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.
OptionalBoolean(Reader & input,bool & value)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.
Enumerated(Reader & input,uint8_t & value)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.
GeneralizedTime(Reader & input,Time & time)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.
TimeChoice(Reader & input,Time & time)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.
Integer(Reader & input,uint8_t & value)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.
OptionalInteger(Reader & input,long defaultValue,long & value)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 
Null(Reader & input)395 inline Result Null(Reader& input) {
396   return ExpectTagAndEmptyValue(input, NULLTag);
397 }
398 
399 template <uint8_t Len>
OID(Reader & input,const uint8_t (& expectedOid)[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 
CertificateSerialNumber(Reader & input,Input & value)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>
OptionalExtensions(Reader & input,uint8_t tag,ExtensionHandler 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, ECDSA, Uninitialized };
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 }
529 }  // namespace mozilla::pkix::der
530 
531 #endif  // mozilla_pkix_pkixder_h
532