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"
29 /* Units of PRTime per second.
31 * (PRTime is based in microseconds since the Unix
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
,
46 if (! crypto_pk_key_is_private(rsa_sign
)) {
50 const SECKEYPublicKey
*subject_key
= crypto_pk_get_nss_pubkey(rsa
);
51 const SECKEYPrivateKey
*signing_key
= crypto_pk_get_nss_privkey(rsa_sign
);
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
)) {
67 crypto_nss_log_errors(LOG_WARN
, "creating a validity object");
72 unsigned long serial_number
;
73 crypto_rand((char*)&serial_number
, sizeof(serial_number
));
75 subject_spki
= SECKEY_CreateSubjectPublicKeyInfo(subject_key
);
80 // XXX do we need to set any attributes?
81 request
= CERT_CreateCertificateRequest(subject_dn
,
83 NULL
/* attributes */);
87 /* Put it into a certificate ... */
88 cert
= CERT_CreateCertificate(serial_number
,
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?
102 KeyType privkey_type
= SECKEY_GetPrivateKeyType(signing_key
);
103 SECOidTag oid_tag
= SEC_GetSignatureAlgorithmOidTag(privkey_type
,
105 if (oid_tag
== SEC_OID_UNKNOWN
)
107 s
= SECOID_SetAlgorithmID(cert
->arena
, &cert
->signature
, oid_tag
, NULL
);
112 tmp
= SEC_ASN1EncodeItem(cert
->arena
, &der
, cert
,
113 SEC_ASN1_GET(CERT_CertificateTemplate
));
118 s
= SEC_DerSignDataWithAlgorithmID(cert
->arena
,
121 (SECKEYPrivateKey
*)signing_key
,//const
124 s
= SEC_DerSignData(cert
->arena
,
127 (SECKEYPrivateKey
*)signing_key
,//const
128 SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION
);
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
);
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
);
152 SECKEY_DestroySubjectPublicKeyInfo(subject_spki
);
154 CERT_DestroyCertificateRequest(request
);
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);
162 CERT_DestroyCertificate(cert
);
167 MOCK_IMPL(tor_x509_cert_impl_t
*,
168 tor_tls_create_certificate
,(crypto_pk_t
*rsa
,
169 crypto_pk_t
*rsa_sign
,
171 const char *cname_sign
,
172 unsigned int cert_lifetime
))
175 tor_assert(rsa_sign
);
177 tor_assert(cname_sign
);
179 char *cname_rfc_1485
= NULL
, *cname_sign_rfc_1485
= NULL
;
180 CERTName
*subject_dn
= NULL
, *issuer_dn
= NULL
;
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
)
193 tor_tls_pick_certificate_lifetime(time(NULL
), cert_lifetime
,
194 &start_time
, &end_time
);
196 result
= tor_tls_create_certificate_internal(rsa
,
203 tor_free(cname_rfc_1485
);
204 tor_free(cname_sign_rfc_1485
);
206 CERT_DestroyName(subject_dn
);
208 CERT_DestroyName(issuer_dn
);
213 /** Set *<b>encoded_out</b> and *<b>size_out</b> to <b>cert</b>'s encoded DER
214 * representation and length, respectively. */
216 tor_x509_cert_get_der(const tor_x509_cert_t
*cert
,
217 const uint8_t **encoded_out
, size_t *size_out
)
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
;
230 tor_x509_cert_impl_free_(tor_x509_cert_impl_t
*cert
)
233 CERT_DestroyCertificate(cert
);
236 tor_x509_cert_impl_t
*
237 tor_x509_cert_impl_dup_(tor_x509_cert_impl_t
*cert
)
240 return CERT_DupCertificate(cert
);
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
,
252 tor_assert(certificate
);
253 if (certificate_len
> INT_MAX
)
256 SECItem der
= { .type
= siBuffer
,
257 .data
= (unsigned char *)certificate
,
258 .len
= certificate_len
};
259 CERTCertDBHandle
*certdb
= CERT_GetDefaultCertDB();
261 return CERT_NewTempCertificate(certdb
,
264 PR_FALSE
, /* isPerm */
265 PR_TRUE
/* CopyDER */);
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
);
275 crypto_nss_log_errors(LOG_INFO
, "decoding certificate");
279 tor_x509_cert_t
*newcert
= tor_x509_cert_new(cert
);
285 tor_tls_cert_get_key(tor_x509_cert_t
*cert
)
288 CERTSubjectPublicKeyInfo
*spki
= &cert
->cert
->subjectPublicKeyInfo
;
289 SECKEYPublicKey
*pub
= SECKEY_ExtractPublicKey(spki
); // we own this pointer
293 if (SECKEY_GetPublicKeyType(pub
) != rsaKey
) {
294 SECKEY_DestroyPublicKey(pub
);
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
,
311 tor_assert(signing_cert
);
313 SECKEYPublicKey
*pk
= CERT_ExtractPublicKey(signing_cert
->cert
);
315 log_fn(severity
, LD_CRYPTO
,
316 "Invalid certificate: could not extract issuer key");
320 SECStatus s
= CERT_VerifySignedDataWithPublicKey(&cert
->cert
->signatureWrap
,
322 if (s
!= SECSuccess
) {
323 log_fn(severity
, LD_CRYPTO
,
324 "Invalid certificate: could not validate signature.");
328 if (tor_x509_check_cert_lifetime_internal(severity
,
332 TOR_X509_FUTURE_SLOP
) < 0)
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.");
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.");
351 /* The certificate is valid. */
356 SECKEY_DestroyPublicKey(pk
);
361 log_cert_lifetime(int severity
,
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
,
389 int future_tolerance
)
393 PRTime notBefore
=0, notAfter
=0;
395 SECStatus r
= CERT_GetCertTimes(cert
, ¬Before
, ¬After
);
396 if (r
!= SECSuccess
) {
397 log_fn(severity
, LD_CRYPTO
,
398 "Couldn't get validity times from certificate");
402 t
= ((int64_t)now
) + future_tolerance
;
405 log_cert_lifetime(severity
, "not yet valid", now
,
406 notBefore
, notAfter
);
410 t
= ((int64_t)now
) - past_tolerance
;
413 log_cert_lifetime(severity
, "already expired", now
,
414 notBefore
, notAfter
);
421 #ifdef TOR_UNIT_TESTS
423 tor_x509_cert_replace_expiration(const tor_x509_cert_t
*inp
,
424 time_t new_expiration_time
,
425 crypto_pk_t
*signing_key
)
428 tor_assert(signing_key
);
430 PRTime notBefore
=0, notAfter
=0;
431 SECStatus r
= CERT_GetCertTimes(inp
->cert
, ¬Before
, ¬After
);
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
);
445 CERTCertificate
*newcert
;
447 newcert
= tor_tls_create_certificate_internal(subject_key
,
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) */