12#define TOR_X509_PRIVATE
14#include "lib/tls/x509_internal.h"
23DISABLE_GCC_WARNING(
"-Wstrict-prototypes")
29ENABLE_GCC_WARNING(
"-Wstrict-prototypes")
35#define PRTIME_PER_SEC (1000*1000)
38 const uint8_t *certificate,
int certificate_len);
40static tor_x509_cert_impl_t *
41tor_tls_create_certificate_internal(
crypto_pk_t *rsa,
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);
83 request = CERT_CreateCertificateRequest(subject_dn,
90 cert = CERT_CreateCertificate(serial_number,
98 *cert->version.data = 2;
99 cert->version.len = 1;
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,
126 s = SEC_DerSignData(cert->arena,
129 (SECKEYPrivateKey *)signing_key,
130 SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION);
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);
154 SECKEY_DestroySubjectPublicKeyInfo(subject_spki);
156 CERT_DestroyCertificateRequest(request);
158 CERT_DestroyValidity(validity);
164 CERT_DestroyCertificate(cert);
173 const char *cname_sign,
174 unsigned int cert_lifetime))
181 char *cname_rfc_1485 = NULL, *cname_sign_rfc_1485 = NULL;
182 CERTName *subject_dn = NULL, *issuer_dn = NULL;
185 CERTCertificate *result = NULL;
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,
208 CERT_DestroyName(subject_dn);
210 CERT_DestroyName(issuer_dn);
219 const uint8_t **encoded_out,
size_t *size_out)
226 const SECItem *item = &cert->cert->derCert;
227 *encoded_out = item->data;
228 *size_out = (size_t)item->len;
232tor_x509_cert_impl_free_(tor_x509_cert_impl_t *cert)
235 CERT_DestroyCertificate(cert);
238tor_x509_cert_impl_t *
239tor_x509_cert_impl_dup_(tor_x509_cert_impl_t *cert)
242 return CERT_DupCertificate(cert);
250static tor_x509_cert_impl_t *
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,
272 size_t certificate_len)
275 (
int)certificate_len);
277 crypto_nss_log_errors(
LOG_INFO,
"decoding certificate");
281 tor_x509_cert_t *newcert = tor_x509_cert_new(cert);
290 CERTSubjectPublicKeyInfo *spki = &cert->cert->subjectPublicKeyInfo;
291 SECKEYPublicKey *pub = SECKEY_ExtractPublicKey(spki);
295 if (SECKEY_GetPublicKeyType(pub) != rsaKey) {
296 SECKEY_DestroyPublicKey(pub);
300 return crypto_pk_new_from_nss_pubkey(pub);
305 const tor_x509_cert_t *cert,
306 const tor_x509_cert_t *signing_cert,
315 SECKEYPublicKey *pk = CERT_ExtractPublicKey(signing_cert->cert);
318 "Invalid certificate: could not extract issuer key");
322 SECStatus s = CERT_VerifySignedDataWithPublicKey(&cert->cert->signatureWrap,
324 if (s != SECSuccess) {
326 "Invalid certificate: could not validate signature.");
334 TOR_X509_FUTURE_SLOP) < 0)
337 if (check_rsa_1024) {
339 if (SECKEY_GetPublicKeyType(pk) != rsaKey ||
340 SECKEY_PublicKeyStrengthInBits(pk) != 1024) {
341 log_fn(severity,
LD_CRYPTO,
"Invalid certificate: Key is not RSA1024.");
346 unsigned min_bits = (SECKEY_GetPublicKeyType(pk) == ecKey) ? 128: 1024;
347 if (SECKEY_PublicKeyStrengthInBits(pk) < min_bits) {
358 SECKEY_DestroyPublicKey(pk);
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];
382 "(The certificate is valid from %s until %s. Your time is %s.)",
383 nbbuf, nabuf, nowbuf);
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) {
400 "Couldn't get validity times from certificate");
404 t = ((int64_t)now) + future_tolerance;
408 notBefore, notAfter);
412 t = ((int64_t)now) - past_tolerance;
416 notBefore, notAfter);
425tor_x509_cert_replace_expiration(
const tor_x509_cert_t *inp,
426 time_t new_expiration_time,
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) {
440 start_time = new_expiration_time - 10;
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;
Headers for crypto_nss_mgt.c.
void crypto_rand(char *to, size_t n)
Common functions for using (pseudo-)random number generators.
int crypto_pk_key_is_private(const crypto_pk_t *key)
Common functions for cryptographic routines.
#define log_fn(severity, domain, args,...)
int tor_asprintf(char **strp, const char *fmt,...)
#define MOCK_IMPL(rv, funcname, arglist)
Definitions for timing-related constants.
void format_iso_time(char *buf, time_t t)
Macros to manage assertions, fatal and non-fatal.
crypto_pk_t * tor_tls_cert_get_key(tor_x509_cert_t *cert)
tor_x509_cert_t * tor_x509_cert_decode(const uint8_t *certificate, size_t certificate_len)
int tor_tls_cert_is_valid(int severity, const tor_x509_cert_t *cert, const tor_x509_cert_t *signing_cert, time_t now, int check_rsa_1024)
static tor_x509_cert_impl_t * tor_x509_cert_decode_internal(const uint8_t *certificate, int certificate_len)
void tor_x509_cert_get_der(const tor_x509_cert_t *cert, const uint8_t **encoded_out, size_t *size_out)
int tor_x509_check_cert_lifetime_internal(int severity, const X509 *cert, time_t now, int past_tolerance, int future_tolerance)
X509 * tor_tls_create_certificate(crypto_pk_t *rsa, crypto_pk_t *rsa_sign, const char *cname, const char *cname_sign, unsigned int cert_lifetime)
static void log_cert_lifetime(int severity, const X509 *cert, const char *problem, time_t now)