tls_psk.c

00001 /*
00002  * Copyright (c) 2005-2012 by KoanLogic s.r.l. <http://www.koanlogic.com>
00003  * All rights reserved.
00004  *
00005  * This file is part of KLone, and as such it is subject to the license stated
00006  * in the LICENSE file which you have received as part of this distribution.
00007  *
00008  * $Id: tls_psk.c,v 1.6 2008/03/26 09:02:24 tho Exp $
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 /* SSL_OPENSSL_PSK */
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     /* create pwd instance */
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     /* stick the pwd handler into the SSL context */
00041     SSL_CTX_set_ex_data(c, __pwd_exdata_idx(), pwd);
00042 
00043     /* set psk callback */
00044     SSL_CTX_set_psk_server_callback(c, psk_cb);
00045 
00046     /* set global hint if provided */
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     /* retrieve pwd handler that we previously cached in SSL_CTX's ex_data */
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     /* get a pwd record for the supplied id */
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     /* .opaque field is used to store the optional per-user hint string */
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     /* do the requested psk conversion */
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     /* dispose temp stuff */
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     /* if we've (pwd_rec != NULL) we also have (pwd != NULL) */
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  /* SSL_OPENSSL_PSK */

←Products
Copyright © 2005-2012 - KoanLogic S.r.l. - All rights reserved