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