Merge branch 'tor-gitlab/mr/583' into maint-0.4.7
[tor.git] / src / lib / tls / x509_nss.c
blob1034d1c39da69246f183c2a0296171eb90817e60
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 DISABLE_GCC_WARNING("-Wstrict-prototypes")
24 #include <pk11pub.h>
25 #include <cryptohi.h>
26 #include <cert.h>
27 #include <keyhi.h>
28 #include <time.h>
29 ENABLE_GCC_WARNING("-Wstrict-prototypes")
31 /* Units of PRTime per second.
33 * (PRTime is based in microseconds since the Unix
34 * epoch.) */
35 #define PRTIME_PER_SEC (1000*1000)
37 static tor_x509_cert_impl_t *tor_x509_cert_decode_internal(
38 const uint8_t *certificate, int certificate_len);
40 static tor_x509_cert_impl_t *
41 tor_tls_create_certificate_internal(crypto_pk_t *rsa,
42 crypto_pk_t *rsa_sign,
43 CERTName *subject_dn,
44 CERTName *issuer_dn,
45 time_t start_time,
46 time_t end_time)
48 if (! crypto_pk_key_is_private(rsa_sign)) {
49 return NULL;
52 const SECKEYPublicKey *subject_key = crypto_pk_get_nss_pubkey(rsa);
53 const SECKEYPrivateKey *signing_key = crypto_pk_get_nss_privkey(rsa_sign);
54 SECStatus s;
56 CERTSubjectPublicKeyInfo *subject_spki = NULL;
57 CERTCertificateRequest *request = NULL;
58 CERTValidity *validity = NULL;
59 CERTCertificate *cert = NULL;
60 SECItem der = { .data = NULL, .len = 0 };
61 SECItem signed_der = { .data = NULL, .len = 0 };
63 CERTCertificate *result_cert = NULL;
65 validity = CERT_CreateValidity(((PRTime)start_time) * PRTIME_PER_SEC,
66 ((PRTime)end_time) * PRTIME_PER_SEC);
67 if (BUG(! validity)) {
68 /* LCOV_EXCL_START */
69 crypto_nss_log_errors(LOG_WARN, "creating a validity object");
70 goto err;
71 /* LCOV_EXCL_STOP */
74 unsigned long serial_number;
75 crypto_rand((char*)&serial_number, sizeof(serial_number));
77 subject_spki = SECKEY_CreateSubjectPublicKeyInfo(subject_key);
78 if (!subject_spki)
79 goto err;
81 /* Make a CSR ... */
82 // XXX do we need to set any attributes?
83 request = CERT_CreateCertificateRequest(subject_dn,
84 subject_spki,
85 NULL /* attributes */);
86 if (!request)
87 goto err;
89 /* Put it into a certificate ... */
90 cert = CERT_CreateCertificate(serial_number,
91 issuer_dn,
92 validity,
93 request);
94 if (!cert)
95 goto err;
97 /* version 3 cert */
98 *cert->version.data = 2; /* 2 means version 3. */
99 cert->version.len = 1;
101 // XXX do we need to set anything else on the cert?
103 /* Sign it. */
104 KeyType privkey_type = SECKEY_GetPrivateKeyType(signing_key);
105 SECOidTag oid_tag = SEC_GetSignatureAlgorithmOidTag(privkey_type,
106 SEC_OID_SHA256);
107 if (oid_tag == SEC_OID_UNKNOWN)
108 goto err;
109 s = SECOID_SetAlgorithmID(cert->arena, &cert->signature, oid_tag, NULL);
110 if (s != SECSuccess)
111 goto err;
113 void *tmp;
114 tmp = SEC_ASN1EncodeItem(cert->arena, &der, cert,
115 SEC_ASN1_GET(CERT_CertificateTemplate));
116 if (!tmp)
117 goto err;
119 #if 0
120 s = SEC_DerSignDataWithAlgorithmID(cert->arena,
121 &signed_der,
122 der.data, der.len,
123 (SECKEYPrivateKey *)signing_key,//const
124 &cert->signature);
125 #else /* !(0) */
126 s = SEC_DerSignData(cert->arena,
127 &signed_der,
128 der.data, der.len,
129 (SECKEYPrivateKey *)signing_key,//const
130 SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION);
131 #endif /* 0 */
133 if (s != SECSuccess)
134 goto err;
136 /* Re-parse it, to make sure all the certificates we actually use
137 * appear via being decoded. */
138 result_cert = tor_x509_cert_decode_internal(signed_der.data, signed_der.len);
140 #if 1
142 // Can we check the cert we just signed?
143 tor_assert(result_cert);
144 SECKEYPublicKey *issuer_pk = (SECKEYPublicKey *)
145 crypto_pk_get_nss_pubkey(rsa_sign);
146 SECStatus cert_ok = CERT_VerifySignedDataWithPublicKey(
147 &result_cert->signatureWrap, issuer_pk, NULL);
148 tor_assert(cert_ok == SECSuccess);
150 #endif /* 1 */
152 err:
153 if (subject_spki)
154 SECKEY_DestroySubjectPublicKeyInfo(subject_spki);
155 if (request)
156 CERT_DestroyCertificateRequest(request);
157 if (validity)
158 CERT_DestroyValidity(validity);
160 // unnecessary, since these are allocated in the cert's arena.
161 //SECITEM_FreeItem(&der, PR_FALSE);
162 //SECITEM_FreeItem(&signed_der, PR_FALSE);
163 if (cert)
164 CERT_DestroyCertificate(cert);
166 return result_cert;
169 MOCK_IMPL(tor_x509_cert_impl_t *,
170 tor_tls_create_certificate,(crypto_pk_t *rsa,
171 crypto_pk_t *rsa_sign,
172 const char *cname,
173 const char *cname_sign,
174 unsigned int cert_lifetime))
176 tor_assert(rsa);
177 tor_assert(rsa_sign);
178 tor_assert(cname);
179 tor_assert(cname_sign);
181 char *cname_rfc_1485 = NULL, *cname_sign_rfc_1485 = NULL;
182 CERTName *subject_dn = NULL, *issuer_dn = NULL;
183 time_t start_time;
184 time_t end_time;
185 CERTCertificate *result = NULL;
187 tor_asprintf(&cname_rfc_1485, "CN=%s", cname);
188 tor_asprintf(&cname_sign_rfc_1485, "CN=%s", cname_sign);
190 subject_dn = CERT_AsciiToName(cname_rfc_1485);
191 issuer_dn = CERT_AsciiToName(cname_sign_rfc_1485);
192 if (!subject_dn || !issuer_dn)
193 goto err;
195 tor_tls_pick_certificate_lifetime(time(NULL), cert_lifetime,
196 &start_time, &end_time);
198 result = tor_tls_create_certificate_internal(rsa,
199 rsa_sign,
200 subject_dn,
201 issuer_dn,
202 start_time,
203 end_time);
204 err:
205 tor_free(cname_rfc_1485);
206 tor_free(cname_sign_rfc_1485);
207 if (subject_dn)
208 CERT_DestroyName(subject_dn);
209 if (issuer_dn)
210 CERT_DestroyName(issuer_dn);
212 return result;
215 /** Set *<b>encoded_out</b> and *<b>size_out</b> to <b>cert</b>'s encoded DER
216 * representation and length, respectively. */
217 void
218 tor_x509_cert_get_der(const tor_x509_cert_t *cert,
219 const uint8_t **encoded_out, size_t *size_out)
221 tor_assert(cert);
222 tor_assert(cert->cert);
223 tor_assert(encoded_out);
224 tor_assert(size_out);
226 const SECItem *item = &cert->cert->derCert;
227 *encoded_out = item->data;
228 *size_out = (size_t)item->len;
231 void
232 tor_x509_cert_impl_free_(tor_x509_cert_impl_t *cert)
234 if (cert)
235 CERT_DestroyCertificate(cert);
238 tor_x509_cert_impl_t *
239 tor_x509_cert_impl_dup_(tor_x509_cert_impl_t *cert)
241 if (cert)
242 return CERT_DupCertificate(cert);
243 else
244 return NULL;
248 * As tor_x509_cert_decode, but return the NSS certificate type
250 static tor_x509_cert_impl_t *
251 tor_x509_cert_decode_internal(const uint8_t *certificate,
252 int certificate_len)
254 tor_assert(certificate);
255 if (certificate_len > INT_MAX)
256 return NULL;
258 SECItem der = { .type = siBuffer,
259 .data = (unsigned char *)certificate,
260 .len = certificate_len };
261 CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
262 tor_assert(certdb);
263 return CERT_NewTempCertificate(certdb,
264 &der,
265 NULL /* nickname */,
266 PR_FALSE, /* isPerm */
267 PR_TRUE /* CopyDER */);
270 tor_x509_cert_t *
271 tor_x509_cert_decode(const uint8_t *certificate,
272 size_t certificate_len)
274 CERTCertificate *cert = tor_x509_cert_decode_internal(certificate,
275 (int)certificate_len);
276 if (! cert) {
277 crypto_nss_log_errors(LOG_INFO, "decoding certificate");
278 return NULL;
281 tor_x509_cert_t *newcert = tor_x509_cert_new(cert);
283 return newcert;
286 crypto_pk_t *
287 tor_tls_cert_get_key(tor_x509_cert_t *cert)
289 tor_assert(cert);
290 CERTSubjectPublicKeyInfo *spki = &cert->cert->subjectPublicKeyInfo;
291 SECKEYPublicKey *pub = SECKEY_ExtractPublicKey(spki); // we own this pointer
292 if (pub == NULL)
293 return NULL;
295 if (SECKEY_GetPublicKeyType(pub) != rsaKey) {
296 SECKEY_DestroyPublicKey(pub);
297 return NULL;
300 return crypto_pk_new_from_nss_pubkey(pub);
304 tor_tls_cert_is_valid(int severity,
305 const tor_x509_cert_t *cert,
306 const tor_x509_cert_t *signing_cert,
307 time_t now,
308 int check_rsa_1024)
310 int result = 0;
312 tor_assert(cert);
313 tor_assert(signing_cert);
315 SECKEYPublicKey *pk = CERT_ExtractPublicKey(signing_cert->cert);
316 if (pk == NULL) {
317 log_fn(severity, LD_CRYPTO,
318 "Invalid certificate: could not extract issuer key");
319 goto fail;
322 SECStatus s = CERT_VerifySignedDataWithPublicKey(&cert->cert->signatureWrap,
323 pk, NULL);
324 if (s != SECSuccess) {
325 log_fn(severity, LD_CRYPTO,
326 "Invalid certificate: could not validate signature.");
327 goto fail;
330 if (tor_x509_check_cert_lifetime_internal(severity,
331 cert->cert,
332 now,
333 TOR_X509_PAST_SLOP,
334 TOR_X509_FUTURE_SLOP) < 0)
335 goto fail;
337 if (check_rsa_1024) {
338 /* We require that this is a 1024-bit RSA key, for legacy reasons .:p */
339 if (SECKEY_GetPublicKeyType(pk) != rsaKey ||
340 SECKEY_PublicKeyStrengthInBits(pk) != 1024) {
341 log_fn(severity, LD_CRYPTO, "Invalid certificate: Key is not RSA1024.");
342 goto fail;
344 } else {
345 /* We require that this key is at least minimally strong. */
346 unsigned min_bits = (SECKEY_GetPublicKeyType(pk) == ecKey) ? 128: 1024;
347 if (SECKEY_PublicKeyStrengthInBits(pk) < min_bits) {
348 log_fn(severity, LD_CRYPTO, "Invalid certificate: Key is too weak.");
349 goto fail;
353 /* The certificate is valid. */
354 result = 1;
356 fail:
357 if (pk)
358 SECKEY_DestroyPublicKey(pk);
359 return result;
362 static void
363 log_cert_lifetime(int severity,
364 const char *status,
365 time_t now,
366 PRTime notBefore,
367 PRTime notAfter)
369 log_fn(severity, LD_GENERAL,
370 "Certificate %s. Either their clock is set wrong, or your clock "
371 "is incorrect.", status);
373 char nowbuf[ISO_TIME_LEN+1];
374 char nbbuf[ISO_TIME_LEN+1];
375 char nabuf[ISO_TIME_LEN+1];
377 format_iso_time(nowbuf, now);
378 format_iso_time(nbbuf, notBefore / PRTIME_PER_SEC);
379 format_iso_time(nabuf, notAfter / PRTIME_PER_SEC);
381 log_fn(severity, LD_GENERAL,
382 "(The certificate is valid from %s until %s. Your time is %s.)",
383 nbbuf, nabuf, nowbuf);
387 tor_x509_check_cert_lifetime_internal(int severity,
388 const tor_x509_cert_impl_t *cert,
389 time_t now,
390 int past_tolerance,
391 int future_tolerance)
393 tor_assert(cert);
395 PRTime notBefore=0, notAfter=0;
396 int64_t t;
397 SECStatus r = CERT_GetCertTimes(cert, &notBefore, &notAfter);
398 if (r != SECSuccess) {
399 log_fn(severity, LD_CRYPTO,
400 "Couldn't get validity times from certificate");
401 return -1;
404 t = ((int64_t)now) + future_tolerance;
405 t *= PRTIME_PER_SEC;
406 if (notBefore > t) {
407 log_cert_lifetime(severity, "not yet valid", now,
408 notBefore, notAfter);
409 return -1;
412 t = ((int64_t)now) - past_tolerance;
413 t *= PRTIME_PER_SEC;
414 if (notAfter < t) {
415 log_cert_lifetime(severity, "already expired", now,
416 notBefore, notAfter);
417 return -1;
420 return 0;
423 #ifdef TOR_UNIT_TESTS
424 tor_x509_cert_t *
425 tor_x509_cert_replace_expiration(const tor_x509_cert_t *inp,
426 time_t new_expiration_time,
427 crypto_pk_t *signing_key)
429 tor_assert(inp);
430 tor_assert(signing_key);
432 PRTime notBefore=0, notAfter=0;
433 SECStatus r = CERT_GetCertTimes(inp->cert, &notBefore, &notAfter);
434 if (r != SECSuccess)
435 return NULL;
437 time_t start_time = notBefore / PRTIME_PER_SEC;
438 if (new_expiration_time < start_time) {
439 /* This prevents an NSS error. */
440 start_time = new_expiration_time - 10;
443 crypto_pk_t *subject_key = tor_tls_cert_get_key((tor_x509_cert_t *)inp);
444 if (!subject_key)
445 return NULL;
447 CERTCertificate *newcert;
449 newcert = tor_tls_create_certificate_internal(subject_key,
450 signing_key,
451 &inp->cert->subject,
452 &inp->cert->issuer,
453 start_time,
454 new_expiration_time);
456 crypto_pk_free(subject_key);
458 return newcert ? tor_x509_cert_new(newcert) : NULL;
460 #endif /* defined(TOR_UNIT_TESTS) */