1 /* Copyright 2010, 2011 NORDUnet A/S. All rights reserved.
2 See the file COPYING 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 <radsec/radsec.h>
13 #include <radsec/radsec-impl.h>
17 #include "../radsecproxy.h"
20 _get_tlsconf (struct rs_connection *conn, const struct rs_realm *realm)
22 struct tls *c = rs_malloc (conn->ctx, sizeof (struct tls));
26 memset (c, 0, sizeof (struct tls));
27 /* TODO: Make sure old radsecproxy code doesn't free these all
28 of a sudden, or strdup them. */
29 c->name = realm->name;
30 c->cacertfile = realm->cacertfile;
31 c->cacertpath = NULL; /* NYI */
32 c->certfile = realm->certfile;
33 c->certkeyfile = realm->certkeyfile;
34 c->certkeypwd = NULL; /* NYI */
35 c->cacheexpiry = 0; /* NYI */
36 c->crlcheck = 0; /* NYI */
37 c->policyoids = (char **) NULL; /* NYI */
40 rs_err_conn_push_fl (conn, RSE_NOMEM, __FILE__, __LINE__, NULL);
45 #if defined RS_ENABLE_TLS_PSK
47 psk_client_cb (SSL *ssl,
50 unsigned int max_identity_len,
52 unsigned int max_psk_len)
54 struct rs_connection *conn = NULL;
55 struct rs_credentials *cred = NULL;
57 conn = SSL_get_ex_data (ssl, 0);
58 assert (conn != NULL);
59 cred = conn->active_peer->realm->transport_cred;
60 assert (cred != NULL);
61 /* NOTE: Ignoring identity hint from server. */
63 if (strlen (cred->identity) + 1 > max_identity_len)
65 rs_err_conn_push (conn, RSE_CRED, "PSK identity longer than max %d",
66 max_identity_len - 1);
69 strcpy (identity, cred->identity);
71 switch (cred->secret_encoding)
73 case RS_KEY_ENCODING_UTF8:
74 cred->secret_len = strlen (cred->secret);
75 if (cred->secret_len > max_psk_len)
77 rs_err_conn_push (conn, RSE_CRED, "PSK secret longer than max %d",
81 memcpy (psk, cred->secret, cred->secret_len);
83 case RS_KEY_ENCODING_ASCII_HEX:
87 if (BN_hex2bn (&bn, cred->secret) == 0)
89 rs_err_conn_push (conn, RSE_CRED, "Unable to convert pskhexstr");
94 if ((unsigned int) BN_num_bytes (bn) > max_psk_len)
96 rs_err_conn_push (conn, RSE_CRED, "PSK secret longer than max %d",
101 cred->secret_len = BN_bn2bin (bn, psk);
106 assert (!"unknown psk encoding");
109 return cred->secret_len;
111 #endif /* RS_ENABLE_TLS_PSK */
114 rs_tls_init (struct rs_connection *conn)
116 struct rs_context *ctx = NULL;
117 struct tls *tlsconf = NULL;
118 SSL_CTX *ssl_ctx = NULL;
120 unsigned long sslerr = 0;
125 tlsconf = _get_tlsconf (conn, conn->active_peer->realm);
128 ssl_ctx = tlsgetctx (RAD_TLS, tlsconf);
131 for (sslerr = ERR_get_error (); sslerr; sslerr = ERR_get_error ())
132 rs_err_conn_push_fl (conn, RSE_SSLERR, __FILE__, __LINE__,
133 ERR_error_string (sslerr, NULL));
136 ssl = SSL_new (ssl_ctx);
139 for (sslerr = ERR_get_error (); sslerr; sslerr = ERR_get_error ())
140 rs_err_conn_push_fl (conn, RSE_SSLERR, __FILE__, __LINE__,
141 ERR_error_string (sslerr, NULL));
145 #if defined RS_ENABLE_TLS_PSK
146 if (conn->active_peer->realm->transport_cred != NULL)
148 SSL_set_psk_client_callback (ssl, psk_client_cb);
149 SSL_set_ex_data (ssl, 0, conn);
151 #endif /* RS_ENABLE_TLS_PSK */
153 conn->tls_ctx = ssl_ctx;
155 rs_free (ctx, tlsconf);