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);
46 psk_client_cb (SSL *ssl,
49 unsigned int max_identity_len,
51 unsigned int max_psk_len)
53 struct rs_connection *conn = NULL;
54 struct rs_credentials *cred = NULL;
56 conn = SSL_get_ex_data (ssl, 0);
57 assert (conn != NULL);
58 cred = conn->active_peer->realm->transport_cred;
59 assert (cred != NULL);
60 /* NOTE: Ignoring identity hint from server. */
62 if (strlen (cred->identity) + 1 > max_identity_len)
64 rs_err_conn_push (conn, RSE_CRED, "PSK identity longer than max %d",
65 max_identity_len - 1);
68 strcpy (identity, cred->identity);
70 switch (cred->secret_encoding)
72 case RS_KEY_ENCODING_UTF8:
73 cred->secret_len = strlen (cred->secret);
74 if (cred->secret_len > max_psk_len)
76 rs_err_conn_push (conn, RSE_CRED, "PSK secret longer than max %d",
80 memcpy (psk, cred->secret, cred->secret_len);
82 case RS_KEY_ENCODING_ASCII_HEX:
86 if (BN_hex2bn (&bn, cred->secret) == 0)
88 rs_err_conn_push (conn, RSE_CRED, "Unable to convert pskhexstr");
93 if ((unsigned int) BN_num_bytes (bn) > max_psk_len)
95 rs_err_conn_push (conn, RSE_CRED, "PSK secret longer than max %d",
100 cred->secret_len = BN_bn2bin (bn, psk);
105 assert (!"unknown psk encoding");
108 return cred->secret_len;
112 rs_tls_init (struct rs_connection *conn)
114 struct rs_context *ctx = NULL;
115 struct tls *tlsconf = NULL;
116 SSL_CTX *ssl_ctx = NULL;
118 unsigned long sslerr = 0;
123 tlsconf = _get_tlsconf (conn, conn->active_peer->realm);
126 ssl_ctx = tlsgetctx (RADPROT_TLS, tlsconf);
129 for (sslerr = ERR_get_error (); sslerr; sslerr = ERR_get_error ())
130 rs_err_conn_push_fl (conn, RSE_SSLERR, __FILE__, __LINE__,
131 ERR_error_string (sslerr, NULL));
134 ssl = SSL_new (ssl_ctx);
137 for (sslerr = ERR_get_error (); sslerr; sslerr = ERR_get_error ())
138 rs_err_conn_push_fl (conn, RSE_SSLERR, __FILE__, __LINE__,
139 ERR_error_string (sslerr, NULL));
143 if (conn->active_peer->realm->transport_cred != NULL)
145 SSL_set_psk_client_callback (ssl, psk_client_cb);
146 SSL_set_ex_data (ssl, 0, conn);
148 conn->tls_ctx = ssl_ctx;
150 rs_free (ctx, tlsconf);