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