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 */
8 * \brief Wrapper functions to present a consistent interface to
9 * X.509 functions from NSS.
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")
29 ENABLE_GCC_WARNING("-Wstrict-prototypes")
31 /* Units of PRTime per second.
33 * (PRTime is based in microseconds since the Unix
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
,
48 if (! crypto_pk_key_is_private(rsa_sign
)) {
52 const SECKEYPublicKey
*subject_key
= crypto_pk_get_nss_pubkey(rsa
);
53 const SECKEYPrivateKey
*signing_key
= crypto_pk_get_nss_privkey(rsa_sign
);
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
)) {
69 crypto_nss_log_errors(LOG_WARN
, "creating a validity object");
74 unsigned long serial_number
;
75 crypto_rand((char*)&serial_number
, sizeof(serial_number
));
77 subject_spki
= SECKEY_CreateSubjectPublicKeyInfo(subject_key
);
82 // XXX do we need to set any attributes?
83 request
= CERT_CreateCertificateRequest(subject_dn
,
85 NULL
/* attributes */);
89 /* Put it into a certificate ... */
90 cert
= CERT_CreateCertificate(serial_number
,
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?
104 KeyType privkey_type
= SECKEY_GetPrivateKeyType(signing_key
);
105 SECOidTag oid_tag
= SEC_GetSignatureAlgorithmOidTag(privkey_type
,
107 if (oid_tag
== SEC_OID_UNKNOWN
)
109 s
= SECOID_SetAlgorithmID(cert
->arena
, &cert
->signature
, oid_tag
, NULL
);
114 tmp
= SEC_ASN1EncodeItem(cert
->arena
, &der
, cert
,
115 SEC_ASN1_GET(CERT_CertificateTemplate
));
120 s
= SEC_DerSignDataWithAlgorithmID(cert
->arena
,
123 (SECKEYPrivateKey
*)signing_key
,//const
126 s
= SEC_DerSignData(cert
->arena
,
129 (SECKEYPrivateKey
*)signing_key
,//const
130 SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION
);
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
);
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
);
154 SECKEY_DestroySubjectPublicKeyInfo(subject_spki
);
156 CERT_DestroyCertificateRequest(request
);
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);
164 CERT_DestroyCertificate(cert
);
169 MOCK_IMPL(tor_x509_cert_impl_t
*,
170 tor_tls_create_certificate
,(crypto_pk_t
*rsa
,
171 crypto_pk_t
*rsa_sign
,
173 const char *cname_sign
,
174 unsigned int cert_lifetime
))
177 tor_assert(rsa_sign
);
179 tor_assert(cname_sign
);
181 char *cname_rfc_1485
= NULL
, *cname_sign_rfc_1485
= NULL
;
182 CERTName
*subject_dn
= NULL
, *issuer_dn
= NULL
;
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
)
195 tor_tls_pick_certificate_lifetime(time(NULL
), cert_lifetime
,
196 &start_time
, &end_time
);
198 result
= tor_tls_create_certificate_internal(rsa
,
205 tor_free(cname_rfc_1485
);
206 tor_free(cname_sign_rfc_1485
);
208 CERT_DestroyName(subject_dn
);
210 CERT_DestroyName(issuer_dn
);
215 /** Set *<b>encoded_out</b> and *<b>size_out</b> to <b>cert</b>'s encoded DER
216 * representation and length, respectively. */
218 tor_x509_cert_get_der(const tor_x509_cert_t
*cert
,
219 const uint8_t **encoded_out
, size_t *size_out
)
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
;
232 tor_x509_cert_impl_free_(tor_x509_cert_impl_t
*cert
)
235 CERT_DestroyCertificate(cert
);
238 tor_x509_cert_impl_t
*
239 tor_x509_cert_impl_dup_(tor_x509_cert_impl_t
*cert
)
242 return CERT_DupCertificate(cert
);
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
,
254 tor_assert(certificate
);
255 if (certificate_len
> INT_MAX
)
258 SECItem der
= { .type
= siBuffer
,
259 .data
= (unsigned char *)certificate
,
260 .len
= certificate_len
};
261 CERTCertDBHandle
*certdb
= CERT_GetDefaultCertDB();
263 return CERT_NewTempCertificate(certdb
,
266 PR_FALSE
, /* isPerm */
267 PR_TRUE
/* CopyDER */);
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
);
277 crypto_nss_log_errors(LOG_INFO
, "decoding certificate");
281 tor_x509_cert_t
*newcert
= tor_x509_cert_new(cert
);
287 tor_tls_cert_get_key(tor_x509_cert_t
*cert
)
290 CERTSubjectPublicKeyInfo
*spki
= &cert
->cert
->subjectPublicKeyInfo
;
291 SECKEYPublicKey
*pub
= SECKEY_ExtractPublicKey(spki
); // we own this pointer
295 if (SECKEY_GetPublicKeyType(pub
) != rsaKey
) {
296 SECKEY_DestroyPublicKey(pub
);
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
,
313 tor_assert(signing_cert
);
315 SECKEYPublicKey
*pk
= CERT_ExtractPublicKey(signing_cert
->cert
);
317 log_fn(severity
, LD_CRYPTO
,
318 "Invalid certificate: could not extract issuer key");
322 SECStatus s
= CERT_VerifySignedDataWithPublicKey(&cert
->cert
->signatureWrap
,
324 if (s
!= SECSuccess
) {
325 log_fn(severity
, LD_CRYPTO
,
326 "Invalid certificate: could not validate signature.");
330 if (tor_x509_check_cert_lifetime_internal(severity
,
334 TOR_X509_FUTURE_SLOP
) < 0)
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.");
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.");
353 /* The certificate is valid. */
358 SECKEY_DestroyPublicKey(pk
);
363 log_cert_lifetime(int severity
,
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
,
391 int future_tolerance
)
395 PRTime notBefore
=0, notAfter
=0;
397 SECStatus r
= CERT_GetCertTimes(cert
, ¬Before
, ¬After
);
398 if (r
!= SECSuccess
) {
399 log_fn(severity
, LD_CRYPTO
,
400 "Couldn't get validity times from certificate");
404 t
= ((int64_t)now
) + future_tolerance
;
407 log_cert_lifetime(severity
, "not yet valid", now
,
408 notBefore
, notAfter
);
412 t
= ((int64_t)now
) - past_tolerance
;
415 log_cert_lifetime(severity
, "already expired", now
,
416 notBefore
, notAfter
);
423 #ifdef TOR_UNIT_TESTS
425 tor_x509_cert_replace_expiration(const tor_x509_cert_t
*inp
,
426 time_t new_expiration_time
,
427 crypto_pk_t
*signing_key
)
430 tor_assert(signing_key
);
432 PRTime notBefore
=0, notAfter
=0;
433 SECStatus r
= CERT_GetCertTimes(inp
->cert
, ¬Before
, ¬After
);
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
);
447 CERTCertificate
*newcert
;
449 newcert
= tor_tls_create_certificate_internal(subject_key
,
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) */