1 /* Copyright 2010,2011,2013 NORDUnet A/S. All rights reserved.
2 See LICENSE for licensing information. */
4 #if defined HAVE_CONFIG_H
9 #include <openssl/ssl.h>
10 #include <openssl/err.h>
11 #include <openssl/bn.h>
12 #include <openssl/x509v3.h>
13 #include <radsec/radsec.h>
14 #include <radsec/radsec-impl.h>
17 #include "radsecproxy/list.h"
18 #include "radsecproxy/radsecproxy.h"
21 _get_tlsconf (struct rs_connection *conn, const struct rs_realm *realm)
23 struct tls *c = rs_malloc (conn->base_.ctx, sizeof (struct tls));
27 memset (c, 0, sizeof (struct tls));
28 /* _conn_open() should've picked a peer by now. */
29 assert (conn->active_peer);
30 /* TODO: Make sure old radsecproxy code doesn't free these all
31 of a sudden, or strdup them. */
32 c->name = realm->name;
33 c->cacertfile = conn->active_peer->cacertfile;
34 c->cacertpath = NULL; /* NYI */
35 c->certfile = conn->active_peer->certfile;
36 c->certkeyfile = conn->active_peer->certkeyfile;
37 c->certkeypwd = NULL; /* NYI */
38 c->cacheexpiry = 0; /* NYI */
39 c->crlcheck = 0; /* NYI */
40 c->policyoids = (char **) NULL; /* NYI */
43 rs_err_conn_push_fl (conn, RSE_NOMEM, __FILE__, __LINE__, NULL);
48 #if defined RS_ENABLE_TLS_PSK
50 psk_client_cb (SSL *ssl,
53 unsigned int max_identity_len,
55 unsigned int max_psk_len)
57 struct rs_connection *conn = NULL;
58 struct rs_credentials *cred = NULL;
59 unsigned int secret_len;
61 conn = SSL_get_ex_data (ssl, 0);
62 assert (conn != NULL);
63 cred = conn->active_peer->transport_cred;
64 assert (cred != NULL);
65 /* NOTE: Ignoring identity hint from server. */
67 if (strlen (cred->identity) + 1 > max_identity_len)
69 rs_err_conn_push (conn, RSE_CRED, "PSK identity longer than max %d",
70 max_identity_len - 1);
73 strcpy (identity, cred->identity);
75 switch (cred->secret_encoding)
77 case RS_KEY_ENCODING_UTF8:
78 secret_len = strlen (cred->secret);
79 if (secret_len > max_psk_len)
81 rs_err_conn_push (conn, RSE_CRED, "PSK secret longer than max %d",
85 memcpy (psk, cred->secret, secret_len);
87 case RS_KEY_ENCODING_ASCII_HEX:
91 if (BN_hex2bn (&bn, cred->secret) == 0)
93 rs_err_conn_push (conn, RSE_CRED, "Unable to convert pskhexstr");
98 if ((unsigned int) BN_num_bytes (bn) > max_psk_len)
100 rs_err_conn_push (conn, RSE_CRED, "PSK secret longer than max %d",
105 secret_len = BN_bn2bin (bn, psk);
110 assert (!"unknown psk encoding");
115 #endif /* RS_ENABLE_TLS_PSK */
118 rs_tls_init (struct rs_connection *conn)
120 struct rs_context *ctx = NULL;
121 struct tls *tlsconf = NULL;
122 SSL_CTX *ssl_ctx = NULL;
124 unsigned long sslerr = 0;
126 assert (conn->base_.ctx);
127 ctx = conn->base_.ctx;
129 tlsconf = _get_tlsconf (conn, conn->active_peer->realm);
132 ssl_ctx = tlsgetctx (RAD_TLS, tlsconf);
135 for (sslerr = ERR_get_error (); sslerr; sslerr = ERR_get_error ())
136 rs_err_conn_push_fl (conn, RSE_SSLERR, __FILE__, __LINE__,
137 ERR_error_string (sslerr, NULL));
140 ssl = SSL_new (ssl_ctx);
143 for (sslerr = ERR_get_error (); sslerr; sslerr = ERR_get_error ())
144 rs_err_conn_push_fl (conn, RSE_SSLERR, __FILE__, __LINE__,
145 ERR_error_string (sslerr, NULL));
149 #if defined RS_ENABLE_TLS_PSK
150 if (conn->active_peer->transport_cred != NULL)
152 SSL_set_psk_client_callback (ssl, psk_client_cb);
153 SSL_set_ex_data (ssl, 0, conn);
155 #endif /* RS_ENABLE_TLS_PSK */
157 conn->tls_ctx = ssl_ctx;
159 rs_free (ctx, tlsconf);
163 /* draft-ietf-radext-radsec-11.txt
165 * Certificate validation MUST include the verification rules as
168 * Implementations SHOULD indicate their acceptable Certification
169 Authorities as per section 7.4.4 (server side) and x.y.z
170 ["Trusted CA Indication"] (client side) of [RFC5246] (see
173 * Implementations SHOULD allow to configure a list of acceptable
174 certificates, identified via certificate fingerprint. When a
175 fingerprint configured, the fingerprint is prepended with an
176 ASCII label identifying the hash function followed by a colon.
177 Implementations MUST support SHA-1 as the hash algorithm and
178 use the ASCII label "sha-1" to identify the SHA-1 algorithm.
179 The length of a SHA-1 hash is 20 bytes and the length of the
180 corresponding fingerprint string is 65 characters. An example
181 certificate fingerprint is: sha-
182 1:E1:2D:53:2B:7C:6B:8A:29:A2:76:C8:64:36:0B:08:4B:7A:F1:9E:9D
184 * Peer validation always includes a check on whether the locally
185 configured expected DNS name or IP address of the server that
186 is contacted matches its presented certificate. DNS names and
187 IP addresses can be contained in the Common Name (CN) or
188 subjectAltName entries. For verification, only one of these
189 entries is to be considered. The following precedence
190 applies: for DNS name validation, subjectAltName:DNS has
191 precedence over CN; for IP address validation, subjectAltName:
192 iPAddr has precedence over CN.
194 * Implementations SHOULD allow to configure a set of acceptable
195 values for subjectAltName:URI.
198 tls_verify_cert (struct rs_connection *conn)
202 X509 *peer_cert = NULL;
203 struct in6_addr addr;
204 const char *hostname = NULL;
206 assert (conn->active_peer->conn == conn);
207 assert (conn->active_peer->hostname != NULL);
208 hostname = conn->active_peer->hostname;
210 /* verifytlscert() performs basic verification as described by
211 OpenSSL VERIFY(1), i.e. verification of the certificate chain. */
212 peer_cert = verifytlscert (conn->tls_ssl);
213 if (peer_cert == NULL)
215 err = rs_err_conn_push (conn, RSE_SSLERR,
216 "basic certificate validation failed");
220 if (inet_pton (AF_INET, hostname, &addr))
221 success = (subjectaltnameaddr (peer_cert, AF_INET, &addr) == 1);
222 else if (inet_pton (AF_INET6, hostname, &addr))
223 success = (subjectaltnameaddr (peer_cert, AF_INET6, &addr) == 1);
225 success = (subjectaltnameregexp (peer_cert, GEN_DNS, hostname, NULL) == 1);
228 success = (cnregexp (peer_cert, hostname, NULL) == 1);
231 err = rs_err_conn_push (conn, RSE_CERT, "server certificate doesn't "
232 "match configured hostname \"%s\"", hostname);
235 if (peer_cert != NULL)
236 X509_free (peer_cert);