gnutls psk is working!

FossilOrigin-Name: b62107a4ffcdb33ce511826b20dd85209ed22f56781b43828c1e9b984bb86dd7
This commit is contained in:
7u83@mail.ru 2018-04-04 08:59:07 +00:00
parent debcfd6f3e
commit b21845d3c0
17 changed files with 219 additions and 79 deletions

View File

@ -276,6 +276,8 @@
<File Name="src/cw/cw_ktv_set_byte.c"/>
<File Name="src/cw/conn_q_wait_packet.c"/>
<File Name="src/cw/mavl_get_ext.c"/>
<File Name="src/cw/cw_type_bool.c"/>
<File Name="src/cw/cw_ktv_get_bstr16.c"/>
</VirtualDirectory>
</VirtualDirectory>
<Description/>

View File

@ -27,6 +27,7 @@
#include "cw/log.h"
#include "cw/dbg.h"
#include "cw/cw_util.h"
#include "cw/dtls.h"
#include "conf.h"

View File

@ -1,9 +1,7 @@
capwap/ac-descriptor/hardware/version:Bstr16: "ACTube 1.0"
capwap/ac-descriptor/hardware/vendor:Bastr16: 12346
capwap/ssl-cert:Str: "/usr/local/etc/ssl/tube.ssl"
capwap/ssl-key:Str: "/usr/local/etc/key"
capwap/ssl-dhbits:Word: 2048
#
capwap/ac-descriptor/hardware/version:Bstr16: "ACTube 1.0"
capwap/ac-descriptor/hardware/vendor:Bstr16: 12346
ac-descriptor/stations:Word:05
ac-descriptor/station-limit:Word:6
ac-descriptor/active-wtps:Word:7
@ -23,11 +21,21 @@ capwap-control-ip-address/wtps.0:Word:0
#capwap-control-ip-address/wtps.1:Word:11
capwap/ssl-keyfile:Str:"../../ssl/certs/ac-cisco.key"
capwap/ssl-certfile:Str:"../../ssl/certs/ac-cisco.pem"
capwap/ssl-cipher:Str:+RSA:+AES-256-CBC:+AES-128-CBC:+SHA1
#capwap/ssl-psk:Str:"HalloWelt"
#capwap/ssl-keyfile:Str:"../../ssl/certs/ac-cisco.key"
#capwap/ssl-certfile:Str:"../../ssl/certs/ac-cisco.pem"
capwap/ssl-cipher:Str:+DHE-RSA:+RSA:+AES-256-CBC:+AES-128-CBC:+SHA1:+PSK
capwap/ssl-psk-enable:Bool:true
capwap/ssl-psk:Bstr16:"HalloWelt"
capwap/ssl-dhbits:Word: 64
actube/listen::192.168.0.1
psk:Bstr16:1234
psk/ap1:Bstr16:hallo
#capwap/ssl-psk:Str:HalloWelt1
actube/listen:Bstr16:192.168.0.1

View File

@ -139,7 +139,7 @@ static inline int bstr16_ncpy(uint8_t *dst,uint8_t*src,uint16_t len)
*/
extern uint8_t * bstr16_create(const uint8_t *data, uint16_t len);
bstr16_t bstr16_create(const uint8_t *data, uint16_t len);
uint8_t * bstr16_create_from_str(const char *s);
extern uint8_t * bstr16_create_from_cfgstr(const char * s);

View File

@ -1,6 +1,6 @@
#include "bstr.h"
uint8_t * bstr16_create(const uint8_t *data, uint16_t len)
bstr16_t bstr16_create(const uint8_t *data, uint16_t len)
{
uint8_t * str = malloc(2+len*sizeof(uint8_t));
if (!str)
@ -10,4 +10,3 @@ uint8_t * bstr16_create(const uint8_t *data, uint16_t len)
return str;
}

View File

@ -175,9 +175,11 @@ struct conn {
int (*dtls_start) (struct conn *);
int (*dtls_accept) (struct conn *);
char *dtls_psk;
int dtls_psk_len;
bstr16_t dtls_psk;
int dtls_psk_enable;
int dtls_dhbits;
int (*dtls_get_psk)(struct conn *,const char *user,uint8_t**psk, int *len);
struct cw_Mod *cmod, *bmod;

View File

@ -502,7 +502,7 @@ int cw_put_msg(struct conn *conn, uint8_t * rawout);
char *cw_strdup(const char *s);
int cw_strcicmp(char const *a, char const *b);
int cw_stricmp(char const *a, char const *b);
/**

View File

@ -1,4 +1,30 @@
#include "cw.h"
static int get_psk(struct conn * conn,const char * username, uint8_t **psk, unsigned int *len)
{
char key[CW_KTV_MAX_KEY_LEN];
cw_KTV_t * result;
sprintf(key,"%s/%s","psk",username);
result = cw_ktv_get(conn->local_cfg,key,CW_TYPE_BSTR16);
if (result == NULL){
if (conn->dtls_psk != NULL){
*psk = bstr16_data(conn->dtls_psk);
*len = bstr16_len(conn->dtls_psk);
return 1;
}
return 0;
}
if (result == NULL)
return 0;
*psk = result->type->data(result);
*len = result->type->len(result);
return 1;
}
/**
* @brief Setup DTLS parameters from config
* @param conn
@ -10,7 +36,7 @@
int cw_setup_dtls(struct conn * conn, mavl_t cfg, const char *prefix, char * default_cipher)
{
char key[CW_KTV_MAX_KEY_LEN];
char *ssl_psk,*ssl_cert,*ssl_key;
char *ssl_cert,*ssl_key;
uint8_t security;
security = 0;
@ -18,13 +44,18 @@ int cw_setup_dtls(struct conn * conn, mavl_t cfg, const char *prefix, char * de
sprintf(key,"%s/%s",prefix,"ssl-cipher");
conn->dtls_cipher = cw_ktv_get_str(cfg,key, default_cipher);
sprintf(key,"%s/%s",prefix,"ssl-psk");
ssl_psk = cw_ktv_get_str(cfg,key,NULL);
if (ssl_psk != NULL){
conn->dtls_psk=ssl_psk;
conn->dtls_psk_len=strlen(ssl_psk);
conn->dtls_psk = cw_ktv_get_bstr16(cfg,key,NULL);
sprintf(key,"%s/%s",prefix,"ssl-psk-enable");
conn->dtls_psk_enable = cw_ktv_get_bool(cfg,key,0);
if (conn->dtls_psk_enable ){
security |= CAPWAP_FLAG_AC_SECURITY_S;
}
sprintf(key,"%s/%s",prefix,"ssl-certfile");
ssl_cert = cw_ktv_get_str(conn->local_cfg,key,NULL);
@ -41,6 +72,8 @@ int cw_setup_dtls(struct conn * conn, mavl_t cfg, const char *prefix, char * de
sprintf(key,"%s/%s",prefix,"ssl-dhbits");
conn->dtls_dhbits = cw_ktv_get_word(cfg,key,1024);
conn->dtls_get_psk = get_psk;
return security;
}

View File

@ -2,7 +2,7 @@
#include "cw.h"
int cw_strcicmp(char const *a, char const *b)
int cw_stricmp(char const *a, char const *b)
{
for (;; a++, b++) {
int d = tolower(*a) - tolower(*b);

View File

@ -77,13 +77,13 @@ static struct cw_KTV *from_str ( struct cw_KTV * data, const char *src )
}
static int len ( struct cw_KTV * data ){
static int len (cw_KTV_t * data ){
return bstr16_len(data->val.ptr);
}
static void * data(struct cw_KTV_t * data)
static void * data(cw_KTV_t * data)
{
return bstr16_data(data);
return bstr16_data(data->val.ptr);
}
const struct cw_Type cw_type_bstr16 = {

View File

@ -128,6 +128,7 @@ struct dtls_gnutls_data *dtls_gnutls_data_create(struct conn *conn,int config)
{
const char *errpos;
int rc;
gnutls_datum_t key;
int bits;
struct dtls_gnutls_data *d = malloc(sizeof(struct dtls_gnutls_data));
if (!d)
@ -204,16 +205,18 @@ struct dtls_gnutls_data *dtls_gnutls_data_create(struct conn *conn,int config)
return 0;
}
rc = gnutls_credentials_set(d->session, GNUTLS_CRD_CERTIFICATE, d->x509_cred);
if (rc < 0) {
cw_log(LOG_ERR, "DTLS - Can't set credentials: %s", gnutls_strerror(rc));
cw_log(LOG_ERR, "DTLS - Can't set x.509 credentials: %s", gnutls_strerror(rc));
dtls_gnutls_data_destroy(d);
return 0;
}
gnutls_certificate_set_verify_function(d->x509_cred,verify_cert);
gnutls_session_set_ptr(d->session, conn);
gnutls_transport_set_ptr(d->session, conn);
gnutls_transport_set_pull_function(d->session, dtls_gnutls_bio_read);
gnutls_transport_set_push_function(d->session, dtls_gnutls_bio_write);

View File

@ -35,7 +35,7 @@ const char * dtls_gnutls_get_cipher(struct conn * conn, char * dst);
struct dtls_ssl_cert dtls_gnutls_get_peers_cert(struct conn * conn,unsigned int n);
extern int dtls_gnutls_shutdown(struct conn *conn);
#define CAPWAP_CIPHER "+DHE-RSA:+RSA:+AES-256-CBC:+AES-128-CBC:+SHA1"
#define CAPWAP_CIPHER "+RSA:+AES-128-CBC:+SHA1"
/* functions used only by capwap libray */

View File

@ -35,6 +35,29 @@
#include "timer.h"
int psk_creds(gnutls_session_t session, const char *user, gnutls_datum_t *key)
{
struct conn *conn;
int rc;
uint8_t * psk;
int psk_len;
conn = gnutls_session_get_ptr(session);
rc = conn->dtls_get_psk(conn,user, &psk,&psk_len);
if (!rc)
return -1;
key->size=psk_len;
key->data = gnutls_malloc(key->size);
if (key->data == NULL) {
return -1;
}
memcpy(key->data, psk, psk_len);
return 0;
}
int dtls_gnutls_accept(struct conn *conn)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
@ -47,15 +70,15 @@ int dtls_gnutls_accept(struct conn *conn)
gnutls_datum_t cookie_key;
gnutls_dtls_prestate_st prestate;
gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE);
cw_dbg(DBG_DTLS, "Session cookie for %s generated: %s",
sock_addr2str(&conn->addr,sock_buf),
sock_addr2str(&conn->addr, sock_buf),
sock_hwaddrtostr((uint8_t *) (&cookie_key),
sizeof(cookie_key),cookie_buf,""));
sizeof(cookie_key), cookie_buf, ""));
memset(&prestate, 0, sizeof(prestate));
@ -63,31 +86,34 @@ int dtls_gnutls_accept(struct conn *conn)
tlen = dtls_gnutls_bio_read(conn, buffer, sizeof(buffer));
gnutls_dtls_cookie_send(&cookie_key, &conn->addr, sizeof(conn->addr),
&prestate, (gnutls_transport_ptr_t) conn, dtls_gnutls_bio_write);
&prestate, (gnutls_transport_ptr_t) conn,
dtls_gnutls_bio_write);
rc=-1;
rc = -1;
c_timer = cw_timer_start(10);
while(!cw_timer_timeout(c_timer)){
while (!cw_timer_timeout(c_timer)) {
tlen = conn_q_recv_packet_peek(conn,buffer,sizeof(buffer));
tlen = conn_q_recv_packet_peek(conn, buffer, sizeof(buffer));
if (tlen <0 && errno == EAGAIN)
if (tlen < 0 && errno == EAGAIN)
continue;
if (tlen < 0 ){
if (tlen < 0) {
/* something went wrong, iwe should log a message */
continue;
}
rc = gnutls_dtls_cookie_verify(&cookie_key,
&conn->addr,
sizeof(conn->addr), buffer+4, tlen-4, &prestate);
sizeof(conn->addr), buffer + 4, tlen - 4,
&prestate);
if (rc<0){
cw_dbg(DBG_DTLS, "Cookie couldn't be verified: %s", gnutls_strerror(rc));
if (rc < 0) {
cw_dbg(DBG_DTLS, "Cookie couldn't be verified: %s",
gnutls_strerror(rc));
dtls_gnutls_bio_read(conn, buffer, sizeof(buffer));
continue;
}
@ -96,61 +122,81 @@ int dtls_gnutls_accept(struct conn *conn)
}
if (rc <0 ){
if (rc < 0) {
cw_log(LOG_ERR, "Cookie couldn't be verified: %s", gnutls_strerror(rc));
return 0;
}
cw_dbg(DBG_DTLS, "Cookie verified! Starting handshake with %s ...",sock_addr2str(&conn->addr,sock_buf));
cw_dbg(DBG_DTLS, "Cookie verified! Starting handshake with %s ...",
sock_addr2str(&conn->addr, sock_buf));
d = dtls_gnutls_data_create(conn,GNUTLS_SERVER | GNUTLS_DATAGRAM);
d = dtls_gnutls_data_create(conn, GNUTLS_SERVER | GNUTLS_DATAGRAM);
if (!d)
return 0;
if (conn->dtls_psk_enable) {
gnutls_psk_server_credentials_t cred;
rc = gnutls_psk_allocate_server_credentials(&cred);
if (rc != 0) {
cw_log(LOG_ERR,"gnutls_psk_allocate_server_credentials() failed.");
}
/* GnuTLS will call psk_creds to ask for the key associated with the
client's username.*/
gnutls_psk_set_server_credentials_function(cred, psk_creds);
/* // Pass the "credentials" to the GnuTLS session. GnuTLS does NOT make an
// internal copy of the information, so we have to keep the 'cred' structure
// in memory (and not modify it) until we're done with this session.*/
rc = gnutls_credentials_set(d->session, GNUTLS_CRD_PSK, cred);
if (rc != 0) {
cw_log(LOG_ERR,"gnutls_credentials_set() failed.\n");
}
}
/* Generate Diffie-Hellman parameters - for use with DHE
* kx algorithms. When short bit length is used, it might
* be wise to regenerate parameters often.
*/
/*bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY);*/
* kx algorithms. When short bit length is used, it might
* be wise to regenerate parameters often.
*/
/*bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); */
bits = conn->dtls_dhbits;
gnutls_dh_params_init(&d->dh_params);
cw_dbg(DBG_DTLS,"Generating DH params, %d",bits);
gnutls_dh_params_generate2(d->dh_params, bits);
cw_dbg(DBG_DTLS,"DH params generated, %d",bits);
cw_dbg(DBG_DTLS, "Generating DH params, %d", bits);
gnutls_dh_params_generate2(d->dh_params, bits);
cw_dbg(DBG_DTLS, "DH params generated, %d", bits);
gnutls_certificate_set_dh_params(d->x509_cred, d->dh_params);
gnutls_certificate_set_dh_params(d->x509_cred, d->dh_params);
gnutls_certificate_server_set_request(d->session,GNUTLS_CERT_REQUEST);
gnutls_certificate_server_set_request(d->session, GNUTLS_CERT_REQUEST);
gnutls_dtls_prestate_set(d->session, &prestate);
c_timer = cw_timer_start(10);
do{
do {
rc = gnutls_handshake(d->session);
}while(!cw_timer_timeout(c_timer) && rc==GNUTLS_E_AGAIN);
} while (!cw_timer_timeout(c_timer) && rc == GNUTLS_E_AGAIN);
if ( rc < 0 ) {
cw_log(LOG_ERR, "Error in handshake with %s: %s",sock_addr2str(&conn->addr,sock_buf), gnutls_strerror(rc));
if (rc < 0) {
cw_log(LOG_ERR, "Error in handshake with %s: %s",
sock_addr2str(&conn->addr, sock_buf), gnutls_strerror(rc));
return 0;
}
cw_dbg(DBG_DTLS,"Handshake with %s successful.",sock_addr2str(&conn->addr,sock_buf));
cw_dbg(DBG_DTLS, "Handshake with %s successful.",
sock_addr2str(&conn->addr, sock_buf));
conn->dtls_data=d;
conn->dtls_data = d;
conn->read = dtls_gnutls_read;
conn->write = dtls_gnutls_write;
return 1;
}

View File

@ -34,13 +34,14 @@
#include "sock.h"
/**
* Establish a DTLS connection using gnutls library
* @see #dtls_connect
* @see #dtls_connec
*/
int dtls_gnutls_connect(struct conn *conn)
{
int rc;
char sock_buf[SOCK_ADDR_BUFSIZE];
struct dtls_gnutls_data *d;
gnutls_datum_t key;
d = dtls_gnutls_data_create(conn,
GNUTLS_CLIENT | GNUTLS_DATAGRAM | GNUTLS_NONBLOCK);
@ -56,6 +57,50 @@ int dtls_gnutls_connect(struct conn *conn)
gnutls_dtls_set_mtu(d->session, 1500);
*/
/*
if (conn->dtls_psk != NULL){
key.data=(unsigned char*)conn->dtls_psk;
key.size=strlen(conn->dtls_psk);
rc = gnutls_credentials_set(d->session, GNUTLS_CRD_PSK, &key);
if (rc<0) {
cw_log(LOG_ERR, "DTLS - Can't set x.509 credentials: %s", gnutls_strerror(rc));
dtls_gnutls_data_destroy(d);
return 0;
}
}
*/
if (conn->dtls_psk_enable){
gnutls_psk_client_credentials_t cred;
rc = gnutls_psk_allocate_client_credentials(&cred);
if (rc != 0) {
cw_dbg(DBG_DTLS,"gnutls_psk_allocate_client_credentials() failed.\n");
return 0;
}
key.size = bstr16_len(conn->dtls_psk);
key.data = bstr16_data(conn->dtls_psk);
/* Put the username and key into the structure we use to tell GnuTLs what
// the credentials are. The example server doesn't care about usernames, so
// we use "Alice" here.*/
rc = gnutls_psk_set_client_credentials(cred, "Alice", &key, GNUTLS_PSK_KEY_RAW);
rc = gnutls_credentials_set(d->session, GNUTLS_CRD_PSK, cred);
if (rc != 0) {
cw_log(LOG_ERR,"gnutls_credentials_set() failed.");
}
}
cw_dbg(DBG_DTLS,"Starting handshake");
do {

View File

@ -294,7 +294,8 @@ static unsigned int psk_server_cb(SSL *ssl,const char *identity, unsigned char *
{
BIO * b = SSL_get_rbio(ssl);
struct conn * conn = b->ptr;
int l = conn->dtls_psk_len < max_psk_len ? conn->dtls_psk_len : max_psk_len;
int l = bstr16_len(conn->dtls_psk) < max_psk_len ? bstr16_len(conn->dtls_psk) : max_psk_len;
memcpy(psk,conn->dtls_psk,l);
return l;
}

View File

@ -34,8 +34,8 @@ static BIO_METHOD bio_methods = {
snprintf(identity, max_identity_len, "CLient_identity");
l = conn->dtls_psk_len < max_psk_len ? conn->dtls_psk_len : max_psk_len;
memcpy(psk, conn->dtls_psk, l);
l = bstr16_len(conn->dtls_psk) < max_psk_len ? bstr16_len(conn->dtls_psk) : max_psk_len;
memcpy(psk, bstr16_data(conn->dtls_psk), l);
return l;
}

View File

@ -2,14 +2,15 @@
capwap/ssl-certfile:Str:"../../ssl/certs/wtp.crt"
capwap/ssl-keyfile:Str:"../../ssl/certs/wtp.key"
#capwap/ssl-certfile:Str:"../../ssl/certs/wtp.crt"
#capwap/ssl-keyfile:Str:"../../ssl/certs/wtp.key"
#capwap/ssl-cipher:Str: +RSA:+AES-128-CBC:+SHA1
#capwap/ssl-cipher:Str: +DHE-RSA:+RSA:+AES-256-CBC:+AES-128-CBC:+SHA1
#capwap/ssl-psk:Str:"HalloWelt"
capwap/ssl-cipher:Str: +DHE-RSA:+RSA:+AES-256-CBC:+AES-128-CBC:+SHA1:+PSK
capwap/ssl-psk:Bstr16:"HalloWelt"
capwap/ssl-psk-enable:Bool:true
cisco/ssl-certfile:Str:"../../ssl/certs/wtp.crt"
cisco/ssl-keyfile:Str:"../../ssl/certs/wtp.key"
#cisco/ssl-certfile:Str:"../../ssl/certs/wtp.crt"
#cisco/ssl-keyfile:Str:"../../ssl/certs/wtp.key"
discovery-type:Byte:0
wtp-frame-tunnel-mode:Byte:1
@ -48,7 +49,6 @@ capwap-timers/echo-interval:Byte:3
"discovery-interval":Byte:1
location-data:Bstr16:Entangeled