12 #define TOR_X509_PRIVATE
14 #include "lib/tls/x509_internal.h"
33 #define PRTIME_PER_SEC (1000*1000)
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,
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);
81 request = CERT_CreateCertificateRequest(subject_dn,
88 cert = CERT_CreateCertificate(serial_number,
96 *cert->version.data = 2;
97 cert->version.len = 1;
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,
124 s = SEC_DerSignData(cert->arena,
127 (SECKEYPrivateKey *)signing_key,
128 SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION);
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);
152 SECKEY_DestroySubjectPublicKeyInfo(subject_spki);
154 CERT_DestroyCertificateRequest(request);
156 CERT_DestroyValidity(validity);
162 CERT_DestroyCertificate(cert);
171 const char *cname_sign,
172 unsigned int cert_lifetime))
179 char *cname_rfc_1485 = NULL, *cname_sign_rfc_1485 = NULL;
180 CERTName *subject_dn = NULL, *issuer_dn = NULL;
183 CERTCertificate *result = NULL;
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,
206 CERT_DestroyName(subject_dn);
208 CERT_DestroyName(issuer_dn);
217 const uint8_t **encoded_out,
size_t *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);
248 static tor_x509_cert_impl_t *
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,
270 size_t certificate_len)
273 (
int)certificate_len);
275 crypto_nss_log_errors(
LOG_INFO,
"decoding certificate");
279 tor_x509_cert_t *newcert = tor_x509_cert_new(cert);
288 CERTSubjectPublicKeyInfo *spki = &cert->cert->subjectPublicKeyInfo;
289 SECKEYPublicKey *pub = SECKEY_ExtractPublicKey(spki);
293 if (SECKEY_GetPublicKeyType(pub) != rsaKey) {
294 SECKEY_DestroyPublicKey(pub);
298 return crypto_pk_new_from_nss_pubkey(pub);
303 const tor_x509_cert_t *cert,
304 const tor_x509_cert_t *signing_cert,
313 SECKEYPublicKey *pk = CERT_ExtractPublicKey(signing_cert->cert);
316 "Invalid certificate: could not extract issuer key");
320 SECStatus s = CERT_VerifySignedDataWithPublicKey(&cert->cert->signatureWrap,
322 if (s != SECSuccess) {
324 "Invalid certificate: could not validate signature.");
332 TOR_X509_FUTURE_SLOP) < 0)
335 if (check_rsa_1024) {
337 if (SECKEY_GetPublicKeyType(pk) != rsaKey ||
338 SECKEY_PublicKeyStrengthInBits(pk) != 1024) {
339 log_fn(severity,
LD_CRYPTO,
"Invalid certificate: Key is not RSA1024.");
344 unsigned min_bits = (SECKEY_GetPublicKeyType(pk) == ecKey) ? 128: 1024;
345 if (SECKEY_PublicKeyStrengthInBits(pk) < min_bits) {
356 SECKEY_DestroyPublicKey(pk);
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];
380 "(The certificate is valid from %s until %s. Your time is %s.)",
381 nbbuf, nabuf, nowbuf);
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) {
398 "Couldn't get validity times from certificate");
402 t = ((int64_t)now) + future_tolerance;
406 notBefore, notAfter);
410 t = ((int64_t)now) - past_tolerance;
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,
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) {
438 start_time = new_expiration_time - 10;
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;
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)
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)
tor_x509_cert_t * tor_x509_cert_decode(const uint8_t *certificate, size_t certificate_len)
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)