tls_psk.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "klone_conf.h"
00012 #include <sys/types.h>
00013 #include <sys/time.h>
00014 #include <unistd.h>
00015 #include <strings.h>
00016
00017 #ifndef SSL_OPENSSL_PSK
00018 int tls_psk_dummy_decl_stub = 0;
00019 #else
00020 #include <openssl/ssl.h>
00021 #include <u/libu.h>
00022 #include <klone/tls.h>
00023 #include <klone/utils.h>
00024 #include <klone/tlsprv.h>
00025
00026 static unsigned int psk_cb (SSL *ssl, const char *id, unsigned char *psk,
00027 unsigned int max_psk_len);
00028
00029 static int __pwd_exdata_idx (void);
00030
00031 int tls_psk_init (SSL_CTX *c, tls_ctx_args_t *cargs)
00032 {
00033 int rc;
00034 u_pwd_t *pwd = NULL;
00035
00036
00037 rc = u_pwd_init_agnostic(cargs->pskdb, cargs->psk_is_hashed, 0, &pwd);
00038 dbg_err_ifm (rc, "psk pwd creation failed (%s)", cargs->pskdb);
00039
00040
00041 SSL_CTX_set_ex_data(c, __pwd_exdata_idx(), pwd);
00042
00043
00044 SSL_CTX_set_psk_server_callback(c, psk_cb);
00045
00046
00047 if (cargs->psk_hint)
00048 dbg_err_if (!SSL_CTX_use_psk_identity_hint(c, cargs->psk_hint));
00049
00050 return 0;
00051 err:
00052 if (pwd)
00053 u_pwd_term(pwd);
00054
00055 return ~0;
00056 }
00057
00058 static unsigned int psk_cb (SSL *ssl, const char *id, unsigned char *psk,
00059 unsigned int max_psk_len)
00060 {
00061 SSL_CTX *ctx;
00062 u_pwd_t *pwd = NULL;
00063 u_pwd_rec_t *pwd_rec = NULL;
00064 int psk_len = 0;
00065 const char *__psk, *psk_hint;
00066 BIGNUM *bn = NULL;
00067
00068
00069 ctx = SSL_get_SSL_CTX(ssl);
00070 pwd = (u_pwd_t *) SSL_CTX_get_ex_data(ctx, __pwd_exdata_idx());
00071 dbg_err_if (pwd == NULL);
00072
00073
00074 dbg_err_if (u_pwd_retr(pwd, id, &pwd_rec));
00075 dbg_err_if ((__psk = u_pwd_rec_get_password(pwd_rec)) == NULL);
00076
00077 if ((psk_hint = u_pwd_rec_get_opaque(pwd_rec)))
00078 dbg_err_if (!SSL_use_psk_identity_hint(ssl, psk_hint));
00079
00080
00081 dbg_err_if (!BN_hex2bn(&bn, __psk));
00082 dbg_err_if ((unsigned int) BN_num_bytes(bn) > max_psk_len);
00083 dbg_err_if ((psk_len = BN_bn2bin(bn, psk)) < 0);
00084
00085
00086 BN_free(bn);
00087 u_pwd_rec_free(pwd, pwd_rec);
00088
00089 return psk_len;
00090 err:
00091 if (bn)
00092 BN_free(bn);
00093
00094
00095 if (pwd_rec)
00096 u_pwd_rec_free(pwd, pwd_rec);
00097
00098 return 0;
00099 }
00100
00101 static int __pwd_exdata_idx (void)
00102 {
00103 char tag[32];
00104 static int idx = -1;
00105
00106 if (idx < 0)
00107 {
00108 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
00109 (void) u_strlcpy(tag, "PSK pwd instance", sizeof tag);
00110 idx = SSL_CTX_get_ex_new_index(0, tag, NULL, NULL, NULL);
00111 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
00112 }
00113
00114 return idx;
00115 }
00116
00117 #endif