Update copyrights to 2021, using "make update-copyright"
[tor.git] / src / lib / tls / x509_nss.c
blobf29f9461148e52b8e4c9acd4b6e3624f60adc8d9
1 /* Copyright (c) 2003, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 /**
7 * \file x509_nss.c
8 * \brief Wrapper functions to present a consistent interface to
9 * X.509 functions from NSS.
10 **/
12 #define TOR_X509_PRIVATE
13 #include "lib/tls/x509.h"
14 #include "lib/tls/x509_internal.h"
15 #include "lib/tls/tortls.h"
16 #include "lib/crypt_ops/crypto_rand.h"
17 #include "lib/crypt_ops/crypto_util.h"
18 #include "lib/crypt_ops/crypto_nss_mgt.h"
19 #include "lib/log/util_bug.h"
20 #include "lib/encoding/time_fmt.h"
21 #include "lib/string/printf.h"
23 #include <pk11pub.h>
24 #include <cryptohi.h>
25 #include <cert.h>
26 #include <keyhi.h>
27 #include <time.h>
29 /* Units of PRTime per second.
31 * (PRTime is based in microseconds since the Unix
32 * epoch.) */
33 #define PRTIME_PER_SEC (1000*1000)
35 static tor_x509_cert_impl_t *tor_x509_cert_decode_internal(
36 const uint8_t *certificate, int certificate_len);
38 static tor_x509_cert_impl_t *
39 tor_tls_create_certificate_internal(crypto_pk_t *rsa,
40 crypto_pk_t *rsa_sign,
41 CERTName *subject_dn,
42 CERTName *issuer_dn,
43 time_t start_time,
44 time_t end_time)
46 if (! crypto_pk_key_is_private(rsa_sign)) {
47 return NULL;
50 const SECKEYPublicKey *subject_key = crypto_pk_get_nss_pubkey(rsa);
51 const SECKEYPrivateKey *signing_key = crypto_pk_get_nss_privkey(rsa_sign);
52 SECStatus s;
54 CERTSubjectPublicKeyInfo *subject_spki = NULL;
55 CERTCertificateRequest *request = NULL;
56 CERTValidity *validity = NULL;
57 CERTCertificate *cert = NULL;
58 SECItem der = { .data = NULL, .len = 0 };
59 SECItem signed_der = { .data = NULL, .len = 0 };
61 CERTCertificate *result_cert = NULL;
63 validity = CERT_CreateValidity(((PRTime)start_time) * PRTIME_PER_SEC,
64 ((PRTime)end_time) * PRTIME_PER_SEC);
65 if (BUG(! validity)) {
66 /* LCOV_EXCL_START */
67 crypto_nss_log_errors(LOG_WARN, "creating a validity object");
68 goto err;
69 /* LCOV_EXCL_STOP */
72 unsigned long serial_number;
73 crypto_rand((char*)&serial_number, sizeof(serial_number));
75 subject_spki = SECKEY_CreateSubjectPublicKeyInfo(subject_key);
76 if (!subject_spki)
77 goto err;
79 /* Make a CSR ... */
80 // XXX do we need to set any attributes?
81 request = CERT_CreateCertificateRequest(subject_dn,
82 subject_spki,
83 NULL /* attributes */);
84 if (!request)
85 goto err;
87 /* Put it into a certificate ... */
88 cert = CERT_CreateCertificate(serial_number,
89 issuer_dn,
90 validity,
91 request);
92 if (!cert)
93 goto err;
95 /* version 3 cert */
96 *cert->version.data = 2; /* 2 means version 3. */
97 cert->version.len = 1;
99 // XXX do we need to set anything else on the cert?
101 /* Sign it. */
102 KeyType privkey_type = SECKEY_GetPrivateKeyType(signing_key);
103 SECOidTag oid_tag = SEC_GetSignatureAlgorithmOidTag(privkey_type,
104 SEC_OID_SHA256);
105 if (oid_tag == SEC_OID_UNKNOWN)
106 goto err;
107 s = SECOID_SetAlgorithmID(cert->arena, &cert->signature, oid_tag, NULL);
108 if (s != SECSuccess)
109 goto err;
111 void *tmp;
112 tmp = SEC_ASN1EncodeItem(cert->arena, &der, cert,
113 SEC_ASN1_GET(CERT_CertificateTemplate));
114 if (!tmp)
115 goto err;
117 #if 0
118 s = SEC_DerSignDataWithAlgorithmID(cert->arena,
119 &signed_der,
120 der.data, der.len,
121 (SECKEYPrivateKey *)signing_key,//const
122 &cert->signature);
123 #else /* !(0) */
124 s = SEC_DerSignData(cert->arena,
125 &signed_der,
126 der.data, der.len,
127 (SECKEYPrivateKey *)signing_key,//const
128 SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION);
129 #endif /* 0 */
131 if (s != SECSuccess)
132 goto err;
134 /* Re-parse it, to make sure all the certificates we actually use
135 * appear via being decoded. */
136 result_cert = tor_x509_cert_decode_internal(signed_der.data, signed_der.len);
138 #if 1
140 // Can we check the cert we just signed?
141 tor_assert(result_cert);
142 SECKEYPublicKey *issuer_pk = (SECKEYPublicKey *)
143 crypto_pk_get_nss_pubkey(rsa_sign);
144 SECStatus cert_ok = CERT_VerifySignedDataWithPublicKey(
145 &result_cert->signatureWrap, issuer_pk, NULL);
146 tor_assert(cert_ok == SECSuccess);
148 #endif /* 1 */
150 err:
151 if (subject_spki)
152 SECKEY_DestroySubjectPublicKeyInfo(subject_spki);
153 if (request)
154 CERT_DestroyCertificateRequest(request);
155 if (validity)
156 CERT_DestroyValidity(validity);
158 // unnecessary, since these are allocated in the cert's arena.
159 //SECITEM_FreeItem(&der, PR_FALSE);
160 //SECITEM_FreeItem(&signed_der, PR_FALSE);
161 if (cert)
162 CERT_DestroyCertificate(cert);
164 return result_cert;
167 MOCK_IMPL(tor_x509_cert_impl_t *,
168 tor_tls_create_certificate,(crypto_pk_t *rsa,
169 crypto_pk_t *rsa_sign,
170 const char *cname,
171 const char *cname_sign,
172 unsigned int cert_lifetime))
174 tor_assert(rsa);
175 tor_assert(rsa_sign);
176 tor_assert(cname);
177 tor_assert(cname_sign);
179 char *cname_rfc_1485 = NULL, *cname_sign_rfc_1485 = NULL;
180 CERTName *subject_dn = NULL, *issuer_dn = NULL;
181 time_t start_time;
182 time_t end_time;
183 CERTCertificate *result = NULL;
185 tor_asprintf(&cname_rfc_1485, "CN=%s", cname);
186 tor_asprintf(&cname_sign_rfc_1485, "CN=%s", cname_sign);
188 subject_dn = CERT_AsciiToName(cname_rfc_1485);
189 issuer_dn = CERT_AsciiToName(cname_sign_rfc_1485);
190 if (!subject_dn || !issuer_dn)
191 goto err;
193 tor_tls_pick_certificate_lifetime(time(NULL), cert_lifetime,
194 &start_time, &end_time);
196 result = tor_tls_create_certificate_internal(rsa,
197 rsa_sign,
198 subject_dn,
199 issuer_dn,
200 start_time,
201 end_time);
202 err:
203 tor_free(cname_rfc_1485);
204 tor_free(cname_sign_rfc_1485);
205 if (subject_dn)
206 CERT_DestroyName(subject_dn);
207 if (issuer_dn)
208 CERT_DestroyName(issuer_dn);
210 return result;
213 /** Set *<b>encoded_out</b> and *<b>size_out</b> to <b>cert</b>'s encoded DER
214 * representation and length, respectively. */
215 void
216 tor_x509_cert_get_der(const tor_x509_cert_t *cert,
217 const uint8_t **encoded_out, size_t *size_out)
219 tor_assert(cert);
220 tor_assert(cert->cert);
221 tor_assert(encoded_out);
222 tor_assert(size_out);
224 const SECItem *item = &cert->cert->derCert;
225 *encoded_out = item->data;
226 *size_out = (size_t)item->len;
229 void
230 tor_x509_cert_impl_free_(tor_x509_cert_impl_t *cert)
232 if (cert)
233 CERT_DestroyCertificate(cert);
236 tor_x509_cert_impl_t *
237 tor_x509_cert_impl_dup_(tor_x509_cert_impl_t *cert)
239 if (cert)
240 return CERT_DupCertificate(cert);
241 else
242 return NULL;
246 * As tor_x509_cert_decode, but return the NSS certificate type
248 static tor_x509_cert_impl_t *
249 tor_x509_cert_decode_internal(const uint8_t *certificate,
250 int certificate_len)
252 tor_assert(certificate);
253 if (certificate_len > INT_MAX)
254 return NULL;
256 SECItem der = { .type = siBuffer,
257 .data = (unsigned char *)certificate,
258 .len = certificate_len };
259 CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
260 tor_assert(certdb);
261 return CERT_NewTempCertificate(certdb,
262 &der,
263 NULL /* nickname */,
264 PR_FALSE, /* isPerm */
265 PR_TRUE /* CopyDER */);
268 tor_x509_cert_t *
269 tor_x509_cert_decode(const uint8_t *certificate,
270 size_t certificate_len)
272 CERTCertificate *cert = tor_x509_cert_decode_internal(certificate,
273 (int)certificate_len);
274 if (! cert) {
275 crypto_nss_log_errors(LOG_INFO, "decoding certificate");
276 return NULL;
279 tor_x509_cert_t *newcert = tor_x509_cert_new(cert);
281 return newcert;
284 crypto_pk_t *
285 tor_tls_cert_get_key(tor_x509_cert_t *cert)
287 tor_assert(cert);
288 CERTSubjectPublicKeyInfo *spki = &cert->cert->subjectPublicKeyInfo;
289 SECKEYPublicKey *pub = SECKEY_ExtractPublicKey(spki); // we own this pointer
290 if (pub == NULL)
291 return NULL;
293 if (SECKEY_GetPublicKeyType(pub) != rsaKey) {
294 SECKEY_DestroyPublicKey(pub);
295 return NULL;
298 return crypto_pk_new_from_nss_pubkey(pub);
302 tor_tls_cert_is_valid(int severity,
303 const tor_x509_cert_t *cert,
304 const tor_x509_cert_t *signing_cert,
305 time_t now,
306 int check_rsa_1024)
308 int result = 0;
310 tor_assert(cert);
311 tor_assert(signing_cert);
313 SECKEYPublicKey *pk = CERT_ExtractPublicKey(signing_cert->cert);
314 if (pk == NULL) {
315 log_fn(severity, LD_CRYPTO,
316 "Invalid certificate: could not extract issuer key");
317 goto fail;
320 SECStatus s = CERT_VerifySignedDataWithPublicKey(&cert->cert->signatureWrap,
321 pk, NULL);
322 if (s != SECSuccess) {
323 log_fn(severity, LD_CRYPTO,
324 "Invalid certificate: could not validate signature.");
325 goto fail;
328 if (tor_x509_check_cert_lifetime_internal(severity,
329 cert->cert,
330 now,
331 TOR_X509_PAST_SLOP,
332 TOR_X509_FUTURE_SLOP) < 0)
333 goto fail;
335 if (check_rsa_1024) {
336 /* We require that this is a 1024-bit RSA key, for legacy reasons .:p */
337 if (SECKEY_GetPublicKeyType(pk) != rsaKey ||
338 SECKEY_PublicKeyStrengthInBits(pk) != 1024) {
339 log_fn(severity, LD_CRYPTO, "Invalid certificate: Key is not RSA1024.");
340 goto fail;
342 } else {
343 /* We require that this key is at least minimally strong. */
344 unsigned min_bits = (SECKEY_GetPublicKeyType(pk) == ecKey) ? 128: 1024;
345 if (SECKEY_PublicKeyStrengthInBits(pk) < min_bits) {
346 log_fn(severity, LD_CRYPTO, "Invalid certificate: Key is too weak.");
347 goto fail;
351 /* The certificate is valid. */
352 result = 1;
354 fail:
355 if (pk)
356 SECKEY_DestroyPublicKey(pk);
357 return result;
360 static void
361 log_cert_lifetime(int severity,
362 const char *status,
363 time_t now,
364 PRTime notBefore,
365 PRTime notAfter)
367 log_fn(severity, LD_GENERAL,
368 "Certificate %s. Either their clock is set wrong, or your clock "
369 "is incorrect.", status);
371 char nowbuf[ISO_TIME_LEN+1];
372 char nbbuf[ISO_TIME_LEN+1];
373 char nabuf[ISO_TIME_LEN+1];
375 format_iso_time(nowbuf, now);
376 format_iso_time(nbbuf, notBefore / PRTIME_PER_SEC);
377 format_iso_time(nabuf, notAfter / PRTIME_PER_SEC);
379 log_fn(severity, LD_GENERAL,
380 "(The certificate is valid from %s until %s. Your time is %s.)",
381 nbbuf, nabuf, nowbuf);
385 tor_x509_check_cert_lifetime_internal(int severity,
386 const tor_x509_cert_impl_t *cert,
387 time_t now,
388 int past_tolerance,
389 int future_tolerance)
391 tor_assert(cert);
393 PRTime notBefore=0, notAfter=0;
394 int64_t t;
395 SECStatus r = CERT_GetCertTimes(cert, &notBefore, &notAfter);
396 if (r != SECSuccess) {
397 log_fn(severity, LD_CRYPTO,
398 "Couldn't get validity times from certificate");
399 return -1;
402 t = ((int64_t)now) + future_tolerance;
403 t *= PRTIME_PER_SEC;
404 if (notBefore > t) {
405 log_cert_lifetime(severity, "not yet valid", now,
406 notBefore, notAfter);
407 return -1;
410 t = ((int64_t)now) - past_tolerance;
411 t *= PRTIME_PER_SEC;
412 if (notAfter < t) {
413 log_cert_lifetime(severity, "already expired", now,
414 notBefore, notAfter);
415 return -1;
418 return 0;
421 #ifdef TOR_UNIT_TESTS
422 tor_x509_cert_t *
423 tor_x509_cert_replace_expiration(const tor_x509_cert_t *inp,
424 time_t new_expiration_time,
425 crypto_pk_t *signing_key)
427 tor_assert(inp);
428 tor_assert(signing_key);
430 PRTime notBefore=0, notAfter=0;
431 SECStatus r = CERT_GetCertTimes(inp->cert, &notBefore, &notAfter);
432 if (r != SECSuccess)
433 return NULL;
435 time_t start_time = notBefore / PRTIME_PER_SEC;
436 if (new_expiration_time < start_time) {
437 /* This prevents an NSS error. */
438 start_time = new_expiration_time - 10;
441 crypto_pk_t *subject_key = tor_tls_cert_get_key((tor_x509_cert_t *)inp);
442 if (!subject_key)
443 return NULL;
445 CERTCertificate *newcert;
447 newcert = tor_tls_create_certificate_internal(subject_key,
448 signing_key,
449 &inp->cert->subject,
450 &inp->cert->issuer,
451 start_time,
452 new_expiration_time);
454 crypto_pk_free(subject_key);
456 return newcert ? tor_x509_cert_new(newcert) : NULL;
458 #endif /* defined(TOR_UNIT_TESTS) */