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