Tor  0.4.7.0-alpha-dev
x509_nss.c
Go to the documentation of this file.
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 */
5 
6 /**
7  * \file x509_nss.c
8  * \brief Wrapper functions to present a consistent interface to
9  * X.509 functions from NSS.
10  **/
11 
12 #define TOR_X509_PRIVATE
13 #include "lib/tls/x509.h"
14 #include "lib/tls/x509_internal.h"
15 #include "lib/tls/tortls.h"
19 #include "lib/log/util_bug.h"
20 #include "lib/encoding/time_fmt.h"
21 #include "lib/string/printf.h"
22 
23 #include <pk11pub.h>
24 #include <cryptohi.h>
25 #include <cert.h>
26 #include <keyhi.h>
27 #include <time.h>
28 
29 /* Units of PRTime per second.
30  *
31  * (PRTime is based in microseconds since the Unix
32  * epoch.) */
33 #define PRTIME_PER_SEC (1000*1000)
34 
35 static tor_x509_cert_impl_t *tor_x509_cert_decode_internal(
36  const uint8_t *certificate, int certificate_len);
37 
38 static tor_x509_cert_impl_t *
39 tor_tls_create_certificate_internal(crypto_pk_t *rsa,
40  crypto_pk_t *rsa_sign,
41  CERTName *subject_dn,
42  CERTName *issuer_dn,
43  time_t start_time,
44  time_t end_time)
45 {
46  if (! crypto_pk_key_is_private(rsa_sign)) {
47  return NULL;
48  }
49 
50  const SECKEYPublicKey *subject_key = crypto_pk_get_nss_pubkey(rsa);
51  const SECKEYPrivateKey *signing_key = crypto_pk_get_nss_privkey(rsa_sign);
52  SECStatus s;
53 
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 };
60 
61  CERTCertificate *result_cert = NULL;
62 
63  validity = CERT_CreateValidity(((PRTime)start_time) * PRTIME_PER_SEC,
64  ((PRTime)end_time) * PRTIME_PER_SEC);
65  if (BUG(! validity)) {
66  /* LCOV_EXCL_START */
67  crypto_nss_log_errors(LOG_WARN, "creating a validity object");
68  goto err;
69  /* LCOV_EXCL_STOP */
70  }
71 
72  unsigned long serial_number;
73  crypto_rand((char*)&serial_number, sizeof(serial_number));
74 
75  subject_spki = SECKEY_CreateSubjectPublicKeyInfo(subject_key);
76  if (!subject_spki)
77  goto err;
78 
79  /* Make a CSR ... */
80  // XXX do we need to set any attributes?
81  request = CERT_CreateCertificateRequest(subject_dn,
82  subject_spki,
83  NULL /* attributes */);
84  if (!request)
85  goto err;
86 
87  /* Put it into a certificate ... */
88  cert = CERT_CreateCertificate(serial_number,
89  issuer_dn,
90  validity,
91  request);
92  if (!cert)
93  goto err;
94 
95  /* version 3 cert */
96  *cert->version.data = 2; /* 2 means version 3. */
97  cert->version.len = 1;
98 
99  // XXX do we need to set anything else on the cert?
100 
101  /* Sign it. */
102  KeyType privkey_type = SECKEY_GetPrivateKeyType(signing_key);
103  SECOidTag oid_tag = SEC_GetSignatureAlgorithmOidTag(privkey_type,
104  SEC_OID_SHA256);
105  if (oid_tag == SEC_OID_UNKNOWN)
106  goto err;
107  s = SECOID_SetAlgorithmID(cert->arena, &cert->signature, oid_tag, NULL);
108  if (s != SECSuccess)
109  goto err;
110 
111  void *tmp;
112  tmp = SEC_ASN1EncodeItem(cert->arena, &der, cert,
113  SEC_ASN1_GET(CERT_CertificateTemplate));
114  if (!tmp)
115  goto err;
116 
117 #if 0
118  s = SEC_DerSignDataWithAlgorithmID(cert->arena,
119  &signed_der,
120  der.data, der.len,
121  (SECKEYPrivateKey *)signing_key,//const
122  &cert->signature);
123 #else /* !(0) */
124  s = SEC_DerSignData(cert->arena,
125  &signed_der,
126  der.data, der.len,
127  (SECKEYPrivateKey *)signing_key,//const
128  SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION);
129 #endif /* 0 */
130 
131  if (s != SECSuccess)
132  goto err;
133 
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);
137 
138 #if 1
139  {
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);
147  }
148 #endif /* 1 */
149 
150  err:
151  if (subject_spki)
152  SECKEY_DestroySubjectPublicKeyInfo(subject_spki);
153  if (request)
154  CERT_DestroyCertificateRequest(request);
155  if (validity)
156  CERT_DestroyValidity(validity);
157 
158  // unnecessary, since these are allocated in the cert's arena.
159  //SECITEM_FreeItem(&der, PR_FALSE);
160  //SECITEM_FreeItem(&signed_der, PR_FALSE);
161  if (cert)
162  CERT_DestroyCertificate(cert);
163 
164  return result_cert;
165 }
166 
167 MOCK_IMPL(tor_x509_cert_impl_t *,
169  crypto_pk_t *rsa_sign,
170  const char *cname,
171  const char *cname_sign,
172  unsigned int cert_lifetime))
173 {
174  tor_assert(rsa);
175  tor_assert(rsa_sign);
176  tor_assert(cname);
177  tor_assert(cname_sign);
178 
179  char *cname_rfc_1485 = NULL, *cname_sign_rfc_1485 = NULL;
180  CERTName *subject_dn = NULL, *issuer_dn = NULL;
181  time_t start_time;
182  time_t end_time;
183  CERTCertificate *result = NULL;
184 
185  tor_asprintf(&cname_rfc_1485, "CN=%s", cname);
186  tor_asprintf(&cname_sign_rfc_1485, "CN=%s", cname_sign);
187 
188  subject_dn = CERT_AsciiToName(cname_rfc_1485);
189  issuer_dn = CERT_AsciiToName(cname_sign_rfc_1485);
190  if (!subject_dn || !issuer_dn)
191  goto err;
192 
193  tor_tls_pick_certificate_lifetime(time(NULL), cert_lifetime,
194  &start_time, &end_time);
195 
196  result = tor_tls_create_certificate_internal(rsa,
197  rsa_sign,
198  subject_dn,
199  issuer_dn,
200  start_time,
201  end_time);
202  err:
203  tor_free(cname_rfc_1485);
204  tor_free(cname_sign_rfc_1485);
205  if (subject_dn)
206  CERT_DestroyName(subject_dn);
207  if (issuer_dn)
208  CERT_DestroyName(issuer_dn);
209 
210  return result;
211 }
212 
213 /** Set *<b>encoded_out</b> and *<b>size_out</b> to <b>cert</b>'s encoded DER
214  * representation and length, respectively. */
215 void
216 tor_x509_cert_get_der(const tor_x509_cert_t *cert,
217  const uint8_t **encoded_out, size_t *size_out)
218 {
219  tor_assert(cert);
220  tor_assert(cert->cert);
221  tor_assert(encoded_out);
222  tor_assert(size_out);
223 
224  const SECItem *item = &cert->cert->derCert;
225  *encoded_out = item->data;
226  *size_out = (size_t)item->len;
227 }
228 
229 void
230 tor_x509_cert_impl_free_(tor_x509_cert_impl_t *cert)
231 {
232  if (cert)
233  CERT_DestroyCertificate(cert);
234 }
235 
236 tor_x509_cert_impl_t *
237 tor_x509_cert_impl_dup_(tor_x509_cert_impl_t *cert)
238 {
239  if (cert)
240  return CERT_DupCertificate(cert);
241  else
242  return NULL;
243 }
244 
245 /**
246  * As tor_x509_cert_decode, but return the NSS certificate type
247 */
248 static tor_x509_cert_impl_t *
249 tor_x509_cert_decode_internal(const uint8_t *certificate,
250  int certificate_len)
251 {
252  tor_assert(certificate);
253  if (certificate_len > INT_MAX)
254  return NULL;
255 
256  SECItem der = { .type = siBuffer,
257  .data = (unsigned char *)certificate,
258  .len = certificate_len };
259  CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
260  tor_assert(certdb);
261  return CERT_NewTempCertificate(certdb,
262  &der,
263  NULL /* nickname */,
264  PR_FALSE, /* isPerm */
265  PR_TRUE /* CopyDER */);
266 }
267 
268 tor_x509_cert_t *
269 tor_x509_cert_decode(const uint8_t *certificate,
270  size_t certificate_len)
271 {
272  CERTCertificate *cert = tor_x509_cert_decode_internal(certificate,
273  (int)certificate_len);
274  if (! cert) {
275  crypto_nss_log_errors(LOG_INFO, "decoding certificate");
276  return NULL;
277  }
278 
279  tor_x509_cert_t *newcert = tor_x509_cert_new(cert);
280 
281  return newcert;
282 }
283 
284 crypto_pk_t *
285 tor_tls_cert_get_key(tor_x509_cert_t *cert)
286 {
287  tor_assert(cert);
288  CERTSubjectPublicKeyInfo *spki = &cert->cert->subjectPublicKeyInfo;
289  SECKEYPublicKey *pub = SECKEY_ExtractPublicKey(spki); // we own this pointer
290  if (pub == NULL)
291  return NULL;
292 
293  if (SECKEY_GetPublicKeyType(pub) != rsaKey) {
294  SECKEY_DestroyPublicKey(pub);
295  return NULL;
296  }
297 
298  return crypto_pk_new_from_nss_pubkey(pub);
299 }
300 
301 int
303  const tor_x509_cert_t *cert,
304  const tor_x509_cert_t *signing_cert,
305  time_t now,
306  int check_rsa_1024)
307 {
308  int result = 0;
309 
310  tor_assert(cert);
311  tor_assert(signing_cert);
312 
313  SECKEYPublicKey *pk = CERT_ExtractPublicKey(signing_cert->cert);
314  if (pk == NULL) {
315  log_fn(severity, LD_CRYPTO,
316  "Invalid certificate: could not extract issuer key");
317  goto fail;
318  }
319 
320  SECStatus s = CERT_VerifySignedDataWithPublicKey(&cert->cert->signatureWrap,
321  pk, NULL);
322  if (s != SECSuccess) {
323  log_fn(severity, LD_CRYPTO,
324  "Invalid certificate: could not validate signature.");
325  goto fail;
326  }
327 
329  cert->cert,
330  now,
331  TOR_X509_PAST_SLOP,
332  TOR_X509_FUTURE_SLOP) < 0)
333  goto fail;
334 
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.");
340  goto fail;
341  }
342  } else {
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.");
347  goto fail;
348  }
349  }
350 
351  /* The certificate is valid. */
352  result = 1;
353 
354  fail:
355  if (pk)
356  SECKEY_DestroyPublicKey(pk);
357  return result;
358 }
359 
360 static void
361 log_cert_lifetime(int severity,
362  const char *status,
363  time_t now,
364  PRTime notBefore,
365  PRTime notAfter)
366 {
367  log_fn(severity, LD_GENERAL,
368  "Certificate %s. Either their clock is set wrong, or your clock "
369  "is incorrect.", status);
370 
371  char nowbuf[ISO_TIME_LEN+1];
372  char nbbuf[ISO_TIME_LEN+1];
373  char nabuf[ISO_TIME_LEN+1];
374 
375  format_iso_time(nowbuf, now);
376  format_iso_time(nbbuf, notBefore / PRTIME_PER_SEC);
377  format_iso_time(nabuf, notAfter / PRTIME_PER_SEC);
378 
379  log_fn(severity, LD_GENERAL,
380  "(The certificate is valid from %s until %s. Your time is %s.)",
381  nbbuf, nabuf, nowbuf);
382 }
383 
384 int
386  const tor_x509_cert_impl_t *cert,
387  time_t now,
388  int past_tolerance,
389  int future_tolerance)
390 {
391  tor_assert(cert);
392 
393  PRTime notBefore=0, notAfter=0;
394  int64_t t;
395  SECStatus r = CERT_GetCertTimes(cert, &notBefore, &notAfter);
396  if (r != SECSuccess) {
397  log_fn(severity, LD_CRYPTO,
398  "Couldn't get validity times from certificate");
399  return -1;
400  }
401 
402  t = ((int64_t)now) + future_tolerance;
403  t *= PRTIME_PER_SEC;
404  if (notBefore > t) {
405  log_cert_lifetime(severity, "not yet valid", now,
406  notBefore, notAfter);
407  return -1;
408  }
409 
410  t = ((int64_t)now) - past_tolerance;
411  t *= PRTIME_PER_SEC;
412  if (notAfter < t) {
413  log_cert_lifetime(severity, "already expired", now,
414  notBefore, notAfter);
415  return -1;
416  }
417 
418  return 0;
419 }
420 
421 #ifdef TOR_UNIT_TESTS
422 tor_x509_cert_t *
423 tor_x509_cert_replace_expiration(const tor_x509_cert_t *inp,
424  time_t new_expiration_time,
425  crypto_pk_t *signing_key)
426 {
427  tor_assert(inp);
428  tor_assert(signing_key);
429 
430  PRTime notBefore=0, notAfter=0;
431  SECStatus r = CERT_GetCertTimes(inp->cert, &notBefore, &notAfter);
432  if (r != SECSuccess)
433  return NULL;
434 
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;
439  }
440 
441  crypto_pk_t *subject_key = tor_tls_cert_get_key((tor_x509_cert_t *)inp);
442  if (!subject_key)
443  return NULL;
444 
445  CERTCertificate *newcert;
446 
447  newcert = tor_tls_create_certificate_internal(subject_key,
448  signing_key,
449  &inp->cert->subject,
450  &inp->cert->issuer,
451  start_time,
452  new_expiration_time);
453 
454  crypto_pk_free(subject_key);
455 
456  return newcert ? tor_x509_cert_new(newcert) : NULL;
457 }
458 #endif /* defined(TOR_UNIT_TESTS) */
Headers for crypto_nss_mgt.c.
void crypto_rand(char *to, size_t n)
Definition: crypto_rand.c:477
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,...)
Definition: log.h:283
#define LD_CRYPTO
Definition: log.h:64
#define LD_GENERAL
Definition: log.h:62
#define LOG_WARN
Definition: log.h:53
#define LOG_INFO
Definition: log.h:45
#define tor_free(p)
Definition: malloc.h:52
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
Header for printf.c.
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
Definitions for timing-related constants.
void format_iso_time(char *buf, time_t t)
Definition: time_fmt.c:295
Header for time_fmt.c.
Headers for tortls.c.
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:102
Headers for tortls.c.
crypto_pk_t * tor_tls_cert_get_key(tor_x509_cert_t *cert)
Definition: x509_nss.c:285
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)
Definition: x509_nss.c:302
tor_x509_cert_t * tor_x509_cert_decode(const uint8_t *certificate, size_t certificate_len)
Definition: x509_nss.c:269
static tor_x509_cert_impl_t * tor_x509_cert_decode_internal(const uint8_t *certificate, int certificate_len)
Definition: x509_nss.c:249
void tor_x509_cert_get_der(const tor_x509_cert_t *cert, const uint8_t **encoded_out, size_t *size_out)
Definition: x509_nss.c:216
int tor_x509_check_cert_lifetime_internal(int severity, const X509 *cert, time_t now, int past_tolerance, int future_tolerance)
Definition: x509_openssl.c:428
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)
Definition: x509_openssl.c:105
static void log_cert_lifetime(int severity, const X509 *cert, const char *problem, time_t now)
Definition: x509_openssl.c:367