1 /* Copyright 2010-2013 NORDUnet A/S. All rights reserved.
2 See LICENSE for licensing information. */
4 #if defined HAVE_CONFIG_H
13 #if defined HAVE_PTHREAD_H
16 #include <openssl/ssl.h>
17 #include <openssl/err.h>
18 #include <openssl/bn.h>
19 #include <openssl/x509v3.h>
20 #include <openssl/rand.h>
21 #include <openssl/crypto.h>
22 #include <radsec/radsec.h>
23 #include <radsec/radsec-impl.h>
26 #include "radsecproxy/list.h"
27 #include "radsecproxy/radsecproxy.h"
32 _get_tlsconf (struct rs_connection *conn, const struct rs_realm *realm)
34 struct tls *c = rs_malloc (conn->ctx, sizeof (struct tls));
38 memset (c, 0, sizeof (struct tls));
39 /* TODO: Make sure old radsecproxy code doesn't free these all
40 of a sudden, or strdup them. */
41 c->name = realm->name;
42 c->cacertfile = realm->cacertfile;
43 c->cacertpath = NULL; /* NYI */
44 c->certfile = realm->certfile;
45 c->certkeyfile = realm->certkeyfile;
46 c->certkeypwd = NULL; /* NYI */
47 c->cacheexpiry = 0; /* NYI */
48 c->crlcheck = 0; /* NYI */
49 c->policyoids = (char **) NULL; /* NYI */
52 rs_err_conn_push_fl (conn, RSE_NOMEM, __FILE__, __LINE__, NULL);
57 #if defined RS_ENABLE_TLS_PSK
59 psk_client_cb (SSL *ssl,
62 unsigned int max_identity_len,
64 unsigned int max_psk_len)
66 struct rs_connection *conn = NULL;
67 struct rs_credentials *cred = NULL;
69 conn = SSL_get_ex_data (ssl, 0);
70 assert (conn != NULL);
71 cred = conn->active_peer->realm->transport_cred;
72 assert (cred != NULL);
73 /* NOTE: Ignoring identity hint from server. */
75 if (strlen (cred->identity) + 1 > max_identity_len)
77 rs_err_conn_push (conn, RSE_CRED, "PSK identity longer than max %d",
78 max_identity_len - 1);
81 strcpy (identity, cred->identity);
83 switch (cred->secret_encoding)
85 case RS_KEY_ENCODING_UTF8:
86 cred->secret_len = strlen (cred->secret);
87 if (cred->secret_len > max_psk_len)
89 rs_err_conn_push (conn, RSE_CRED, "PSK secret longer than max %d",
93 memcpy (psk, cred->secret, cred->secret_len);
95 case RS_KEY_ENCODING_ASCII_HEX:
99 if (BN_hex2bn (&bn, cred->secret) == 0)
101 rs_err_conn_push (conn, RSE_CRED, "Unable to convert pskhexstr");
106 if ((unsigned int) BN_num_bytes (bn) > max_psk_len)
108 rs_err_conn_push (conn, RSE_CRED, "PSK secret longer than max %d",
113 cred->secret_len = BN_bn2bin (bn, psk);
118 assert (!"unknown psk encoding");
121 return cred->secret_len;
123 #endif /* RS_ENABLE_TLS_PSK */
125 /** Read \a buf_len bytes from one of the random devices into \a
126 buf. Return 0 on success and -1 on failure. */
128 load_rand_ (uint8_t *buf, size_t buf_len)
130 static const char *fns[] = {"/dev/urandom", "/dev/random", NULL};
133 if (buf_len > SSIZE_MAX)
136 for (i = 0; fns[i] != NULL; i++)
139 int fd = open (fns[i], O_RDONLY);
142 while (nread != buf_len)
144 ssize_t r = read (fd, buf + nread, buf_len - nread);
152 if (nread != buf_len)
159 /** Initialise OpenSSL's PRNG by possibly invoking RAND_poll() and by
160 feeding RAND_seed() data from one of the random devices. If either
161 succeeds, we're happy and return 0. */
163 init_openssl_rand_ (void)
165 long openssl_version = 0;
166 int openssl_random_init_flag = 0;
167 int our_random_init_flag = 0;
170 /* Older OpenSSL has a crash bug in RAND_poll (when a file it opens
171 gets a file descriptor with a number higher than FD_SETSIZE) so
172 use it only for newer versions. */
173 openssl_version = SSLeay ();
174 if (openssl_version >= OPENSSL_V (0,9,8,'c'))
175 openssl_random_init_flag = RAND_poll ();
177 our_random_init_flag = !load_rand_ (buf, sizeof(buf));
178 if (our_random_init_flag)
179 RAND_seed (buf, sizeof(buf));
180 memset (buf, 0, sizeof(buf)); /* FIXME: What if memset() is optimised out? */
182 if (!openssl_random_init_flag && !our_random_init_flag)
184 if (!RAND_bytes (buf, sizeof(buf)))
189 #if defined HAVE_PTHREADS
190 /** Array of pthread_mutex_t for OpenSSL. Allocated and initialised in
191 \a init_locking_ and never freed. */
192 static pthread_mutex_t *s_openssl_mutexes = NULL;
193 /** Number of pthread_mutex_t's allocated at s_openssl_mutexes. */
194 static int s_openssl_mutexes_count = 0;
196 /** Callback for OpenSSL when a lock is to be held or released. */
198 openssl_locking_cb_ (int mode, int i, const char *file, int line)
200 if (s_openssl_mutexes == NULL || i >= s_openssl_mutexes_count)
202 if (mode & CRYPTO_LOCK)
203 pthread_mutex_lock (&s_openssl_mutexes[i]);
205 pthread_mutex_unlock (&s_openssl_mutexes[i]);
208 /** Initialise any locking needed for being thread safe. Libradsec has
209 all its own state in one or more struct rs_context and doesn't
210 need locks but libraries used by libradsec may need protection. */
215 n = CRYPTO_num_locks ();
217 s_openssl_mutexes = calloc (n, sizeof(pthread_mutex_t));
218 if (s_openssl_mutexes == NULL)
220 for (i = 0; i < n; i++)
221 pthread_mutex_init (&s_openssl_mutexes[i], NULL);
222 s_openssl_mutexes_count = n;
226 #endif /* HAVE_PTHREADS */
228 /** Initialise the TLS library. Return 0 on success, -1 on failure. */
232 SSL_load_error_strings ();
233 #if defined HAVE_PTHREADS
234 if (CRYPTO_get_locking_callback () == NULL)
236 assert (s_openssl_mutexes_count == 0);
237 /* Allocate and initialise mutexes. We will never free
238 these. FIXME: Is there a portable way of having a function
239 invoked when a solib is unloaded? -ln */
240 if (init_locking_ ())
242 CRYPTO_set_locking_callback (openssl_locking_cb_);
244 #endif /* HAVE_PTHREADS */
246 return init_openssl_rand_ ();
250 tls_init_conn (struct rs_connection *conn)
252 struct rs_context *ctx = NULL;
253 struct tls *tlsconf = NULL;
254 SSL_CTX *ssl_ctx = NULL;
256 unsigned long sslerr = 0;
261 tlsconf = _get_tlsconf (conn, conn->active_peer->realm);
264 ssl_ctx = tlsgetctx (RAD_TLS, tlsconf);
267 for (sslerr = ERR_get_error (); sslerr; sslerr = ERR_get_error ())
268 rs_err_conn_push_fl (conn, RSE_SSLERR, __FILE__, __LINE__,
269 ERR_error_string (sslerr, NULL));
272 ssl = SSL_new (ssl_ctx);
275 for (sslerr = ERR_get_error (); sslerr; sslerr = ERR_get_error ())
276 rs_err_conn_push_fl (conn, RSE_SSLERR, __FILE__, __LINE__,
277 ERR_error_string (sslerr, NULL));
281 #if defined RS_ENABLE_TLS_PSK
282 if (conn->active_peer->realm->transport_cred != NULL)
284 SSL_set_psk_client_callback (ssl, psk_client_cb);
285 SSL_set_ex_data (ssl, 0, conn);
287 #endif /* RS_ENABLE_TLS_PSK */
289 conn->tls_ctx = ssl_ctx;
291 rs_free (ctx, tlsconf);
295 /* draft-ietf-radext-radsec-11.txt
297 * Certificate validation MUST include the verification rules as
300 * Implementations SHOULD indicate their acceptable Certification
301 Authorities as per section 7.4.4 (server side) and x.y.z
302 ["Trusted CA Indication"] (client side) of [RFC5246] (see
305 * Implementations SHOULD allow to configure a list of acceptable
306 certificates, identified via certificate fingerprint. When a
307 fingerprint configured, the fingerprint is prepended with an
308 ASCII label identifying the hash function followed by a colon.
309 Implementations MUST support SHA-1 as the hash algorithm and
310 use the ASCII label "sha-1" to identify the SHA-1 algorithm.
311 The length of a SHA-1 hash is 20 bytes and the length of the
312 corresponding fingerprint string is 65 characters. An example
313 certificate fingerprint is: sha-
314 1:E1:2D:53:2B:7C:6B:8A:29:A2:76:C8:64:36:0B:08:4B:7A:F1:9E:9D
316 * Peer validation always includes a check on whether the locally
317 configured expected DNS name or IP address of the server that
318 is contacted matches its presented certificate. DNS names and
319 IP addresses can be contained in the Common Name (CN) or
320 subjectAltName entries. For verification, only one of these
321 entries is to be considered. The following precedence
322 applies: for DNS name validation, subjectAltName:DNS has
323 precedence over CN; for IP address validation, subjectAltName:
324 iPAddr has precedence over CN.
326 * Implementations SHOULD allow to configure a set of acceptable
327 values for subjectAltName:URI.
330 tls_verify_cert (struct rs_connection *conn)
334 X509 *peer_cert = NULL;
335 struct in6_addr addr;
336 const char *hostname = NULL;
338 assert (conn->active_peer->conn == conn);
339 assert (conn->active_peer->hostname != NULL);
340 hostname = conn->active_peer->hostname;
342 /* verifytlscert() performs basic verification as described by
343 OpenSSL VERIFY(1), i.e. verification of the certificate chain. */
344 peer_cert = verifytlscert (conn->tls_ssl);
345 if (peer_cert == NULL)
347 err = rs_err_conn_push (conn, RSE_SSLERR,
348 "basic certificate validation failed");
352 if (inet_pton (AF_INET, hostname, &addr))
353 success = (subjectaltnameaddr (peer_cert, AF_INET, &addr) == 1);
354 else if (inet_pton (AF_INET6, hostname, &addr))
355 success = (subjectaltnameaddr (peer_cert, AF_INET6, &addr) == 1);
357 success = (subjectaltnameregexp (peer_cert, GEN_DNS, hostname, NULL) == 1);
360 success = (cnregexp (peer_cert, hostname, NULL) == 1);
362 if (conn->realm->disable_hostname_check)
365 err = rs_err_conn_push (conn, RSE_CERT, "server certificate doesn't "
366 "match configured hostname \"%s\"", hostname);
369 if (peer_cert != NULL)
370 X509_free (peer_cert);