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_test_pkixtestutil_h
26 #define mozilla_pkix_test_pkixtestutil_h
27 
28 #include <cstdint>
29 #include <cstring>
30 #include <ctime>
31 #include <string>
32 
33 #include "mozpkix/pkixtypes.h"
34 
35 namespace mozilla {
36 namespace pkix {
37 namespace test {
38 
39 typedef std::basic_string<uint8_t> ByteString;
40 
ENCODING_FAILED(const ByteString & bs)41 inline bool ENCODING_FAILED(const ByteString& bs) { return bs.empty(); }
42 
43 template <size_t L>
BytesToByteString(const uint8_t (& bytes)[L])44 inline ByteString BytesToByteString(const uint8_t (&bytes)[L]) {
45   return ByteString(bytes, L);
46 }
47 
48 // XXX: Ideally, we should define this instead:
49 //
50 //   template <typename T, std::size_t N>
51 //   constexpr inline std::size_t
52 //   ArrayLength(T (&)[N])
53 //   {
54 //     return N;
55 //   }
56 //
57 // However, we don't because not all supported compilers support constexpr,
58 // and we need to calculate array lengths in static_assert sometimes.
59 //
60 // XXX: Evaluates its argument twice
61 #define MOZILLA_PKIX_ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
62 
63 bool InputEqualsByteString(Input input, const ByteString& bs);
64 ByteString InputToByteString(Input input);
65 
66 // python DottedOIDToCode.py --tlv id-kp-OCSPSigning 1.3.6.1.5.5.7.3.9
67 static const uint8_t tlv_id_kp_OCSPSigning[] = {0x06, 0x08, 0x2b, 0x06, 0x01,
68                                                 0x05, 0x05, 0x07, 0x03, 0x09};
69 
70 // python DottedOIDToCode.py --tlv id-kp-serverAuth 1.3.6.1.5.5.7.3.1
71 static const uint8_t tlv_id_kp_serverAuth[] = {0x06, 0x08, 0x2b, 0x06, 0x01,
72                                                0x05, 0x05, 0x07, 0x03, 0x01};
73 
74 enum class TestDigestAlgorithmID {
75   MD2,
76   MD5,
77   SHA1,
78   SHA224,
79   SHA256,
80   SHA384,
81   SHA512,
82 };
83 
84 struct TestPublicKeyAlgorithm {
TestPublicKeyAlgorithmTestPublicKeyAlgorithm85   explicit TestPublicKeyAlgorithm(const ByteString& aAlgorithmIdentifier)
86       : algorithmIdentifier(aAlgorithmIdentifier) {}
87   bool operator==(const TestPublicKeyAlgorithm& other) const {
88     return algorithmIdentifier == other.algorithmIdentifier;
89   }
90   ByteString algorithmIdentifier;
91 };
92 
93 ByteString DSS_P();
94 ByteString DSS_Q();
95 ByteString DSS_G();
96 
97 TestPublicKeyAlgorithm DSS();
98 TestPublicKeyAlgorithm RSA_PKCS1();
99 
100 struct TestSignatureAlgorithm {
101   TestSignatureAlgorithm(const TestPublicKeyAlgorithm& publicKeyAlg,
102                          TestDigestAlgorithmID digestAlg,
103                          const ByteString& algorithmIdentifier, bool accepted);
104 
105   TestPublicKeyAlgorithm publicKeyAlg;
106   TestDigestAlgorithmID digestAlg;
107   ByteString algorithmIdentifier;
108   bool accepted;
109 };
110 
111 TestSignatureAlgorithm md2WithRSAEncryption();
112 TestSignatureAlgorithm md5WithRSAEncryption();
113 TestSignatureAlgorithm sha1WithRSAEncryption();
114 TestSignatureAlgorithm sha256WithRSAEncryption();
115 
116 // e.g. YMDHMS(2016, 12, 31, 1, 23, 45) => 2016-12-31:01:23:45 (GMT)
117 mozilla::pkix::Time YMDHMS(uint16_t year, uint16_t month, uint16_t day,
118                            uint16_t hour, uint16_t minutes, uint16_t seconds);
119 
120 ByteString TLV(uint8_t tag, size_t length, const ByteString& value);
121 
TLV(uint8_t tag,const ByteString & value)122 inline ByteString TLV(uint8_t tag, const ByteString& value) {
123   return TLV(tag, value.length(), value);
124 }
125 
126 // Although we can't enforce it without relying on Cuser-defined literals,
127 // which aren't supported by all of our compilers yet, you should only pass
128 // string literals as the last parameter to the following two functions.
129 
130 template <size_t N>
TLV(uint8_t tag,const char (& value)[N])131 inline ByteString TLV(uint8_t tag, const char (&value)[N]) {
132   static_assert(N > 0, "cannot have string literal of size 0");
133   assert(value[N - 1] == 0);
134   return TLV(tag, ByteString(reinterpret_cast<const uint8_t*>(&value), N - 1));
135 }
136 
137 template <size_t N>
TLV(uint8_t tag,size_t length,const char (& value)[N])138 inline ByteString TLV(uint8_t tag, size_t length, const char (&value)[N]) {
139   static_assert(N > 0, "cannot have string literal of size 0");
140   assert(value[N - 1] == 0);
141   return TLV(tag, length,
142              ByteString(reinterpret_cast<const uint8_t*>(&value), N - 1));
143 }
144 
145 ByteString Boolean(bool value);
146 ByteString Integer(long value);
147 
148 ByteString CN(const ByteString&, uint8_t encodingTag = 0x0c /*UTF8String*/);
149 
150 inline ByteString CN(const char* value,
151                      uint8_t encodingTag = 0x0c /*UTF8String*/) {
152   return CN(
153       ByteString(reinterpret_cast<const uint8_t*>(value), std::strlen(value)),
154       encodingTag);
155 }
156 
157 ByteString OU(const ByteString&, uint8_t encodingTag = 0x0c /*UTF8String*/);
158 
159 inline ByteString OU(const char* value,
160                      uint8_t encodingTag = 0x0c /*UTF8String*/) {
161   return OU(
162       ByteString(reinterpret_cast<const uint8_t*>(value), std::strlen(value)),
163       encodingTag);
164 }
165 
166 ByteString emailAddress(const ByteString&);
167 
emailAddress(const char * value)168 inline ByteString emailAddress(const char* value) {
169   return emailAddress(
170       ByteString(reinterpret_cast<const uint8_t*>(value), std::strlen(value)));
171 }
172 
173 // RelativeDistinguishedName ::=
174 //   SET SIZE (1..MAX) OF AttributeTypeAndValue
175 //
176 ByteString RDN(const ByteString& avas);
177 
178 // Name ::= CHOICE { -- only one possibility for now --
179 //   rdnSequence  RDNSequence }
180 //
181 // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
182 //
183 ByteString Name(const ByteString& rdns);
184 
CNToDERName(const ByteString & cn)185 inline ByteString CNToDERName(const ByteString& cn) {
186   return Name(RDN(CN(cn)));
187 }
188 
CNToDERName(const char * cn)189 inline ByteString CNToDERName(const char* cn) { return Name(RDN(CN(cn))); }
190 
191 // GeneralName ::= CHOICE {
192 //      otherName                       [0]     OtherName,
193 //      rfc822Name                      [1]     IA5String,
194 //      dNSName                         [2]     IA5String,
195 //      x400Address                     [3]     ORAddress,
196 //      directoryName                   [4]     Name,
197 //      ediPartyName                    [5]     EDIPartyName,
198 //      uniformResourceIdentifier       [6]     IA5String,
199 //      iPAddress                       [7]     OCTET STRING,
200 //      registeredID                    [8]     OBJECT IDENTIFIER }
201 
RFC822Name(const ByteString & name)202 inline ByteString RFC822Name(const ByteString& name) {
203   // (2 << 6) means "context-specific", 1 is the GeneralName tag.
204   return TLV((2 << 6) | 1, name);
205 }
206 
207 template <size_t L>
RFC822Name(const char (& bytes)[L])208 inline ByteString RFC822Name(const char (&bytes)[L]) {
209   return RFC822Name(
210       ByteString(reinterpret_cast<const uint8_t*>(&bytes), L - 1));
211 }
212 
DNSName(const ByteString & name)213 inline ByteString DNSName(const ByteString& name) {
214   // (2 << 6) means "context-specific", 2 is the GeneralName tag.
215   return TLV((2 << 6) | 2, name);
216 }
217 
218 template <size_t L>
DNSName(const char (& bytes)[L])219 inline ByteString DNSName(const char (&bytes)[L]) {
220   return DNSName(ByteString(reinterpret_cast<const uint8_t*>(&bytes), L - 1));
221 }
222 
DirectoryName(const ByteString & name)223 inline ByteString DirectoryName(const ByteString& name) {
224   // (2 << 6) means "context-specific", (1 << 5) means "constructed", and 4 is
225   // the DirectoryName tag.
226   return TLV((2 << 6) | (1 << 5) | 4, name);
227 }
228 
IPAddress()229 inline ByteString IPAddress() {
230   // (2 << 6) means "context-specific", 7 is the GeneralName tag.
231   return TLV((2 << 6) | 7, ByteString());
232 }
233 
234 template <size_t L>
IPAddress(const uint8_t (& bytes)[L])235 inline ByteString IPAddress(const uint8_t (&bytes)[L]) {
236   // (2 << 6) means "context-specific", 7 is the GeneralName tag.
237   return TLV((2 << 6) | 7, ByteString(bytes, L));
238 }
239 
240 // Names should be zero or more GeneralNames, like DNSName and IPAddress return,
241 // concatenated together.
242 //
243 // CreatedEncodedSubjectAltName(ByteString()) results in a SAN with an empty
244 // sequence. CreateEmptyEncodedSubjectName() results in a SAN without any
245 // sequence.
246 ByteString CreateEncodedSubjectAltName(const ByteString& names);
247 ByteString CreateEncodedEmptySubjectAltName();
248 
249 class TestKeyPair {
250  public:
~TestKeyPair()251   virtual ~TestKeyPair() {}
252 
253   const TestPublicKeyAlgorithm publicKeyAlg;
254 
255   // The DER encoding of the entire SubjectPublicKeyInfo structure. This is
256   // what is encoded in certificates.
257   const ByteString subjectPublicKeyInfo;
258 
259   // The DER encoding of subjectPublicKeyInfo.subjectPublicKey. This is what is
260   // hashed to create CertIDs for OCSP.
261   const ByteString subjectPublicKey;
262 
263   virtual Result SignData(const ByteString& tbs,
264                           const TestSignatureAlgorithm& signatureAlgorithm,
265                           /*out*/ ByteString& signature) const = 0;
266 
267   virtual TestKeyPair* Clone() const = 0;
268 
269  protected:
270   TestKeyPair(const TestPublicKeyAlgorithm& publicKeyAlg,
271               const ByteString& spk);
272   TestKeyPair(const TestKeyPair&) = delete;
273   void operator=(const TestKeyPair&) = delete;
274 };
275 
276 TestKeyPair* CloneReusedKeyPair();
277 TestKeyPair* GenerateKeyPair();
278 TestKeyPair* GenerateDSSKeyPair();
DeleteTestKeyPair(TestKeyPair * keyPair)279 inline void DeleteTestKeyPair(TestKeyPair* keyPair) { delete keyPair; }
280 typedef std::unique_ptr<TestKeyPair> ScopedTestKeyPair;
281 
282 Result TestVerifyECDSASignedDigest(const SignedDigest& signedDigest,
283                                    Input subjectPublicKeyInfo);
284 Result TestVerifyRSAPKCS1SignedDigest(const SignedDigest& signedDigest,
285                                       Input subjectPublicKeyInfo);
286 Result TestDigestBuf(Input item, DigestAlgorithm digestAlg,
287                      /*out*/ uint8_t* digestBuf, size_t digestBufLen);
288 
289 // Replace one substring in item with another of the same length, but only if
290 // the substring was found exactly once. The "same length" restriction is
291 // useful for avoiding invalidating lengths encoded within the item. The
292 // "only once" restriction is helpful for avoiding making accidental changes.
293 //
294 // The string to search for must be 8 or more bytes long so that it is
295 // extremely unlikely that there will ever be any false positive matches
296 // in digital signatures, keys, hashes, etc.
297 Result TamperOnce(/*in/out*/ ByteString& item, const ByteString& from,
298                   const ByteString& to);
299 
300 ///////////////////////////////////////////////////////////////////////////////
301 // Encode Certificates
302 
303 enum Version { v1 = 0, v2 = 1, v3 = 2 };
304 
305 // signature is assumed to be the DER encoding of an AlgorithmIdentifer. It is
306 // put into the signature field of the TBSCertificate. In most cases, it will
307 // be the same as signatureAlgorithm, which is the algorithm actually used
308 // to sign the certificate.
309 // serialNumber is assumed to be the DER encoding of an INTEGER.
310 //
311 // If extensions is null, then no extensions will be encoded. Otherwise,
312 // extensions must point to an array of ByteStrings, terminated with an empty
313 // ByteString. (If the first item of the array is empty then an empty
314 // Extensions sequence will be encoded.)
315 ByteString CreateEncodedCertificate(
316     long version, const TestSignatureAlgorithm& signature,
317     const ByteString& serialNumber, const ByteString& issuerNameDER,
318     time_t notBefore, time_t notAfter, const ByteString& subjectNameDER,
319     const TestKeyPair& subjectKeyPair,
320     /*optional*/ const ByteString* extensions, const TestKeyPair& issuerKeyPair,
321     const TestSignatureAlgorithm& signatureAlgorithm);
322 
323 ByteString CreateEncodedSerialNumber(long value);
324 
325 enum class Critical { No = 0, Yes = 1 };
326 
327 ByteString CreateEncodedBasicConstraints(
328     bool isCA,
329     /*optional in*/ const long* pathLenConstraint, Critical critical);
330 
331 // Creates a DER-encoded extKeyUsage extension with one EKU OID.
332 ByteString CreateEncodedEKUExtension(Input eku, Critical critical);
333 
334 ///////////////////////////////////////////////////////////////////////////////
335 // Encode OCSP responses
336 
337 class OCSPResponseExtension final {
338  public:
339   OCSPResponseExtension();
340 
341   ByteString id;
342   bool critical;
343   ByteString value;
344   OCSPResponseExtension* next;
345 };
346 
347 class OCSPResponseContext final {
348  public:
349   OCSPResponseContext(const CertID& certID, std::time_t time);
350 
351   const CertID& certID;
352   // What digest algorithm to use to produce issuerNameHash and issuerKeyHash.
353   // Defaults to sha1.
354   DigestAlgorithm certIDHashAlgorithm;
355   // If non-empty, the sequence of bytes to use for hashAlgorithm when encoding
356   // this response. If empty, the sequence of bytes corresponding to
357   // certIDHashAlgorithm will be used. Defaults to empty.
358   ByteString certIDHashAlgorithmEncoded;
359 
360   // TODO(bug 980538): add a way to specify what certificates are included.
361 
362   // The fields below are in the order that they appear in an OCSP response.
363 
364   enum OCSPResponseStatus {
365     successful = 0,
366     malformedRequest = 1,
367     internalError = 2,
368     tryLater = 3,
369     // 4 is not used
370     sigRequired = 5,
371     unauthorized = 6,
372   };
373   uint8_t responseStatus;  // an OCSPResponseStatus or an invalid value
374   bool skipResponseBytes;  // If true, don't include responseBytes
375 
376   // responderID
377   ByteString signerNameDER;  // If set, responderID will use the byName
378                              // form; otherwise responderID will use the
379                              // byKeyHash form.
380 
381   std::time_t producedAt;
382 
383   // SingleResponse extensions (for the certID given in the constructor).
384   OCSPResponseExtension* singleExtensions;
385   // ResponseData extensions.
386   OCSPResponseExtension* responseExtensions;
387   bool includeEmptyExtensions;  // If true, include the extension wrapper
388                                 // regardless of if there are any actual
389                                 // extensions.
390   ScopedTestKeyPair signerKeyPair;
391   TestSignatureAlgorithm signatureAlgorithm;
392   bool badSignature;        // If true, alter the signature to fail verification
393   const ByteString* certs;  // optional; array terminated by an empty string
394 
395   // The following fields are on a per-SingleResponse basis. In the future we
396   // may support including multiple SingleResponses per response.
397   enum CertStatus {
398     good = 0,
399     revoked = 1,
400     unknown = 2,
401   };
402   uint8_t certStatus;          // CertStatus or an invalid value
403   std::time_t revocationTime;  // For certStatus == revoked
404   std::time_t thisUpdate;
405   std::time_t nextUpdate;
406   bool includeNextUpdate;
407 };
408 
409 ByteString CreateEncodedOCSPResponse(OCSPResponseContext& context);
410 }
411 }
412 }  // namespace mozilla::pkix::test
413 
414 #endif  // mozilla_pkix_test_pkixtestutil_h
415