The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
cert.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: 315d76d2a35ff8ed5a33cf1ec64b76d1fae38e01 $
19  *
20  * @file tls/cert.c
21  * @brief Functions to work with certificates.
22  *
23  * @copyright 2021 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24  */
25 RCSID("$Id: 315d76d2a35ff8ed5a33cf1ec64b76d1fae38e01 $")
26 USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */
27 
28 #ifdef WITH_TLS
29 #define LOG_PREFIX "tls"
30 #include <freeradius-devel/util/strerror.h>
31 
32 #include "cert.h"
33 #include "utils.h"
34 
35 #include <openssl/ssl.h>
36 
37 /** Check if a certificate is currently valid
38  *
39  * @param[out] not_before_p Where to write the not before time. May be NULL.
40  * @param[out] not_after_p Where to write the not after time. May be NULL.
41  * @param[in] cert The Certificate to validate.
42  * @return
43  * - -1 if we can't parse the notBefore or notAfter values in the cert.
44  * - -2 if the cert has expired (not_before_p, not_after_p still populated).
45  * - -3 if the cert is not yet valid (not_before_p, not_after_t still populated).
46  */
47 int fr_tls_cert_is_valid(fr_unix_time_t *not_before_p, fr_unix_time_t *not_after_p, X509 *cert)
48 {
49  fr_time_t now = fr_time();
50  time_t not_before, not_after;
51 
52  /*
53  * If the cert has a mangled notAfter or
54  * notBefore timestamps then always fail,
55  * no matter what the verify mode.
56  */
57  if (fr_tls_utils_asn1time_to_epoch(&not_after, X509_get0_notAfter(cert)) < 0) {
58  fr_strerror_const_push("Failed parsing notAfter time in certificate");
59  return -1;
60  }
61  if (fr_tls_utils_asn1time_to_epoch(&not_before, X509_get0_notBefore(cert)) < 0) {
62  fr_strerror_const_push("Failed parsing notBefore time in certificate");
63  return -1;
64  }
65 
66  if (not_before_p) *not_before_p = fr_unix_time_from_time(not_before);
67  if (not_after_p) *not_after_p = fr_unix_time_from_time(not_after);
68 
69  /*
70  * Check the cert hasn't expired
71  */
72  if (fr_time_lt(fr_time_from_sec(not_after), now)) {
73  fr_strerror_printf("Certificate has expired. "
74  "Validity period (notAfter) ends %pV, current time is %pV",
76  return -2;
77  }
78 
79  /*
80  * Check the cert's validity period
81  * has started.
82  */
83  if (fr_time_gt(fr_time_from_sec(not_before), now)) {
84  fr_strerror_printf("Certificate is not yet valid. "
85  "Validity period (notBefore) starts %pV, current time is %pV",
87  return -3;
88  }
89 
90  return 0;
91 }
92 #endif
#define USES_APPLE_DEPRECATED_API
Definition: build.h:431
#define RCSID(id)
Definition: build.h:444
#define fr_time()
Allow us to arbitrarily manipulate time.
Definition: state_test.c:8
static fr_time_t fr_time_from_sec(time_t when)
Convert a time_t (wallclock time) to a fr_time_t (internal time)
Definition: time.h:856
#define fr_time_gt(_a, _b)
Definition: time.h:237
static fr_unix_time_t fr_unix_time_from_time(time_t time)
Convert a time_t into out internal fr_unix_time_t.
Definition: time.h:534
static fr_unix_time_t fr_time_to_unix_time(fr_time_t when)
Convert an fr_time_t (internal time) to our version of unix time (wallclock time)
Definition: time.h:686
#define fr_time_lt(_a, _b)
Definition: time.h:239
"server local" time.
Definition: time.h:69
"Unix" time.
Definition: time.h:95
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
#define fr_strerror_const_push(_msg)
Definition: strerror.h:227
int fr_tls_utils_asn1time_to_epoch(time_t *out, ASN1_TIME const *asn1)
Convert OpenSSL's ASN1_TIME to an epoch time.
Definition: utils.c:115
#define fr_box_date(_val)
Definition: value.h:317