AC works with GnuTLS 3 now.

No certifacte verification and no psk supprt for now.

FossilOrigin-Name: 3809cff8b383f71541f4324949d9f89dc1db56aacada12bd45ba9a28b2b39cca
This commit is contained in:
7u83@mail.ru
2015-02-08 10:42:01 +00:00
parent 843d10055e
commit 36d5368316
15 changed files with 244 additions and 100 deletions

View File

@ -186,7 +186,8 @@ OBJS:=$(patsubst %.o,$(ARCH)/%.o,$(OBJS))
#CFLAGS = -Wall -g -O3 -D_REENTRANT -DWITH_IPV6
CFLAGS = -Wall -g -O0 -D_REENTRANT -DWITH_IPV6 -DWITH_RMAC_SUPPORT
CFLAGS += -DWITH_CW_LOG \
CFLAGS += $(GNUTLS_CFLAGS) \
-DWITH_CW_LOG \
-DWITH_CW_LOG_DEBUG \
-DWITH_DTLS \
$(XINCLUDE)\
@ -205,10 +206,7 @@ $(ARCH)/%.o:%.c
$(ARCH)/$(NAME) : $(OBJS)
@echo " AR $(ARCH)/$(NAME)"
@$(AR) rcs $(ARCH)/$(NAME) $(OBJS)
#$(OBJS)
#.c.o:
# $(CC) -c $(CFLAGS) $<
SRCS = $(OBJS:.o=.c)
DEPS := $(OBJS:.o=.d)

View File

@ -121,6 +121,7 @@ int cw_dbg_opt_level = 0;
void cw_log_dbg_(int level, const char *file, int line, const char *format,
...)
{
if (!(level & cw_dbg_opt_level))
return;

View File

@ -46,10 +46,10 @@ void cwmsg_addelem_wtp_descriptor(struct cwmsg * cwmsg, struct wtpinfo * wtpinfo
len+=3;
*/
uint8_t hww[2];
/* uint8_t hww[2];
hww[0]=0x1c;
hww[1]=0;
*/
/* software subelem*/
len+=wtpdesc_addsubelem(d+len,CWMSGSUBELEM_WTP_DESCRIPTOR_SOFTWARE_VERSION,
wtpinfo->software_vendor_id,wtpinfo->software_version,-1);

View File

@ -37,33 +37,37 @@ int dtls_bio_read(struct conn *conn, char *out, int maxlen)
memcpy(out, conn->dtls_buffer + conn->dtls_buffer_pos, maxlen);
conn->dtls_buffer_len -= maxlen;
conn->dtls_buffer_pos += maxlen;
cw_dbg(DBG_DTLS_BIO, "SSL BIO read: (maxlen = %d), remain %d", maxlen,conn->dtls_buffer_len);
cw_dbg_dmp(DBG_DTLS_BIO_DMP,(uint8_t*)out,maxlen,"Dump...");
cw_dbg(DBG_DTLS_BIO, "SSL BIO read: (maxlen = %d), read %d, remain %d", maxlen,
maxlen, conn->dtls_buffer_len);
cw_dbg_dmp(DBG_DTLS_BIO_DMP, (uint8_t *) out, maxlen, "Dump...");
return maxlen;
}
memcpy(out, conn->dtls_buffer + conn->dtls_buffer_pos, conn->dtls_buffer_len);
int ret = conn->dtls_buffer_len;
conn->dtls_buffer_len = 0;
cw_dbg(DBG_DTLS_BIO, "SSL BIO read: (maxlen = %d), remain %d", ret,conn->dtls_buffer_len);
cw_dbg_dmp(DBG_DTLS_BIO_DMP,(uint8_t*)out,ret,"Dump...");
cw_dbg(DBG_DTLS_BIO, "SSL BIO read: (maxlen = %d), read %d, remain %d", maxlen, ret,
conn->dtls_buffer_len);
cw_dbg_dmp(DBG_DTLS_BIO_DMP, (uint8_t *) out, ret, "Dump...");
return ret;
}
int dtls_bio_write(struct conn * conn, const char *data, int len)
int dtls_bio_write(struct conn *conn, const char *data, int len)
{
uint8_t buffer[2048];
*((uint32_t *) buffer) = htonl(1 << 24);
memcpy(buffer + 4, data, len);
int rc = conn->send_packet(conn, buffer, len + 4);
if (rc>=0)
rc-=4;
cw_dbg(DBG_DTLS_BIO, "SSL BIO write: %d bytes, rc=%d, ptr: %p", len, rc, data);
cw_dbg_dmp(DBG_DTLS_BIO_DMP,(uint8_t*)data,len,"Dump ...");
cw_dbg(DBG_DTLS_BIO, "SSL BIO write: %d bytes, wrote=%d, ptr: %p", len, rc, data);
cw_dbg_dmp(DBG_DTLS_BIO_DMP, (uint8_t *) data, len, "Dump ...");
if (rc < 0)
return rc;
return rc - 4;
return rc ;
}

View File

@ -23,7 +23,8 @@
int dtls_gnutls_init()
{
cw_dbg(DBG_CW_INFO,"Init SSL library - using GnuTLS");
cw_dbg(DBG_CW_INFO,"Init SSL library - using GnuTLS %s",gnutls_check_version(NULL));
gnutls_global_init();
return 1;
}

View File

@ -17,17 +17,22 @@
*/
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <gnutls/gnutls.h>
#include <gnutls/dtls.h>
#include "dtls_gnutls.h"
#include "conn.h"
#include "cw_log.h"
#include "sock.h"
#include "cw_util.h"
struct dtls_gnutls_data{
struct dtls_gnutls_data {
gnutls_session_t session;
gnutls_certificate_credentials_t x509_cred;
gnutls_priority_t priority_cache;
@ -38,106 +43,224 @@ void dtls_gnutls_data_destroy(struct dtls_gnutls_data *d)
free(d);
}
struct dtls_gnutls_data * dtls_gnutls_data_create(struct conn * conn)
int dtls_gnutls_read(struct conn * conn, uint8_t *buffer, int len)
{
struct dtls_gnutls_data * d = malloc(sizeof(struct dtls_gnutls_data));
struct dtls_gnutls_data * d = conn->dtls_data;
int rc = gnutls_record_recv(d->session,buffer,len);
if ( rc == GNUTLS_E_AGAIN )
return 0;
if ( rc < 0 ){
cw_log(LOG_ERR, "DTLS - read error: %s", gnutls_strerror(rc));
conn->dtls_error=1;
return -1;
}
return rc;
}
int dtls_gnutls_write(struct conn * conn, const uint8_t *buffer, int len)
{
struct dtls_gnutls_data * d = conn->dtls_data;
int rc = gnutls_record_send(d->session,buffer,len);
if ( rc < 0 ){
cw_log(LOG_ERR, "DTLS - write error: %s", gnutls_strerror(rc));
conn->dtls_error=1;
return -1;
}
return rc;
}
static int pull_timeout_func(gnutls_transport_ptr_t ptr, unsigned int ms)
{
struct conn * conn = (struct conn*)ptr;
time_t timer = cw_timer_start(ms/1000);
int rc;
uint8_t buffer[5];
do {
rc = conn_q_recv_packet_peek(conn,buffer,sizeof(buffer));
}while(!cw_timer_timeout(timer) && rc==GNUTLS_E_AGAIN);
return rc;
}
struct dtls_gnutls_data *dtls_gnutls_data_create(struct conn *conn)
{
struct dtls_gnutls_data *d = malloc(sizeof(struct dtls_gnutls_data));
if (!d)
return 0;
gnutls_certificate_allocate_credentials(&d->x509_cred);
int rc;
int rc;
/* Set credentials */
rc = gnutls_certificate_set_x509_key_file(d->x509_cred, conn->dtls_cert_file,
conn->dtls_key_file,
GNUTLS_X509_FMT_PEM);
rc = gnutls_certificate_set_x509_key_file(d->x509_cred, conn->dtls_cert_file,
conn->dtls_key_file, GNUTLS_X509_FMT_PEM);
if (rc<0){
cw_log(LOG_ERR,"DTLS - Can't set cert/key: %s",gnutls_strerror(rc));
if (rc < 0) {
cw_log(LOG_ERR, "DTLS - Can't set cert/key: %s", gnutls_strerror(rc));
dtls_gnutls_data_destroy(d);
return 0;
}
/* Set ciphers */
const char * errpos;
rc = gnutls_priority_init(&d->priority_cache,
conn->dtls_cipher,
&errpos);
if (rc<0){
cw_log(LOG_ERR,"DTLS - Can't init ciphers '%s' at '%s' : %s",conn->dtls_cipher,errpos,gnutls_strerror(rc));
const char *errpos;
rc = gnutls_priority_init(&d->priority_cache, conn->dtls_cipher, &errpos);
if (rc < 0) {
cw_log(LOG_ERR, "DTLS - Can't init ciphers '%s' at '%s' : %s", conn->dtls_cipher,
errpos, gnutls_strerror(rc));
dtls_gnutls_data_destroy(d);
return 0;
}
rc = gnutls_init(&d->session, GNUTLS_SERVER );
if (rc<0){
cw_log(LOG_ERR,"DTLS - Can't init session: %s",gnutls_strerror(rc));
rc = gnutls_init(&d->session, GNUTLS_SERVER | GNUTLS_DATAGRAM);
if (rc < 0) {
cw_log(LOG_ERR, "DTLS - Can't init session: %s", gnutls_strerror(rc));
dtls_gnutls_data_destroy(d);
return 0;
}
gnutls_transport_set_ptr(d->session,conn);
gnutls_transport_set_ptr(d->session, conn);
rc = gnutls_priority_set(d->session, d->priority_cache);
if (rc<0){
cw_log(LOG_ERR,"DTLS - Can't set priority: %s",gnutls_strerror(rc));
if (rc < 0) {
cw_log(LOG_ERR, "DTLS - Can't set priority: %s", gnutls_strerror(rc));
dtls_gnutls_data_destroy(d);
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));
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));
dtls_gnutls_data_destroy(d);
return 0;
}
gnutls_transport_set_pull_function(d->session,dtls_gnutls_bio_read);
gnutls_transport_set_push_function(d->session,dtls_gnutls_bio_write);
gnutls_certificate_server_set_request(d->session,GNUTLS_CERT_REQUEST);
gnutls_transport_set_pull_function(d->session, dtls_gnutls_bio_read);
gnutls_transport_set_push_function(d->session, dtls_gnutls_bio_write);
return d;
return d;
}
int dtls_gnutls_accept(struct conn * conn)
int dtls_gnutls_accept(struct conn *conn)
{
struct dtls_gnutls_data *d;
gnutls_datum_t cookie_key;
gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE);
cw_dbg(DBG_DTLS, "DTLS session cookie for %s generated: %s",
sock_addr2str(&conn->addr), sock_hwaddr2idstr((uint8_t *) (&cookie_key),
sizeof(cookie_key)));
gnutls_dtls_prestate_st prestate;
memset(&prestate, 0, sizeof(prestate));
uint8_t buffer[2048];
int tlen;
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);
int rc=-1;
time_t c_timer = cw_timer_start(10);
while(!cw_timer_timeout(c_timer)){
tlen = conn_q_recv_packet_peek(conn,buffer,sizeof(buffer));
if (tlen <0 && errno == EAGAIN)
continue;
if (tlen < 0 ){
/* something went wrong, log a message */
continue;
}
rc = gnutls_dtls_cookie_verify(&cookie_key,
&conn->addr,
sizeof(conn->addr), buffer+4, tlen-4, &prestate);
if (rc<0){
cw_dbg(DBG_DTLS, "DTLS - Cookie couldn't be verified: %s", gnutls_strerror(rc));
dtls_gnutls_bio_read(conn, buffer, sizeof(buffer));
continue;
}
dtls_gnutls_bio_read(conn, buffer, sizeof(buffer));
break;
}
if (rc <0 ){
cw_log(LOG_ERR, "DTLS - Cookie couldn't be verified: %s", gnutls_strerror(rc));
return 0;
}
cw_dbg(DBG_DTLS, "DTLS - Cookie verified! Starting handshake ...");
d = dtls_gnutls_data_create(conn);
if (!d)
return 0;
gnutls_transport_set_pull_timeout_function(d->session, pull_timeout_func);
gnutls_dtls_prestate_set(d->session, &prestate);
int rc;
do {
c_timer = cw_timer_start(10);
do{
rc = gnutls_handshake(d->session);
}while(rc == GNUTLS_E_AGAIN);
cw_log(LOG_ERR,"DTLS - Can't set credentials: %s",gnutls_strerror(rc));
// gnutls_certificate_allocate_credentials(&x509_cred);
}while(!cw_timer_timeout(c_timer) && rc==GNUTLS_E_AGAIN);
return 0;
if ( rc < 0 ) {
cw_log(LOG_ERR, "DTLS - Error in handshake: %s", gnutls_strerror(rc));
return 0;
}
return 1;
// gnutls_certificate_allocate_credentials(&x509_cred);
cw_dbg(DBG_DTLS,"DTLS - Handshake successful");
conn->dtls_data=d;
conn->read = dtls_gnutls_read;
conn->write = dtls_gnutls_write;
return 1;
}
const char * dtls_gnutls_get_cipher(struct conn * conn)
const char *dtls_gnutls_get_cipher(struct conn *conn)
{
return "Unknown";
}

View File

@ -22,11 +22,20 @@
#include "dtls.h"
#include "dtls_gnutls.h"
#include <stdio.h>
#include <errno.h>
ssize_t dtls_gnutls_bio_read(gnutls_transport_ptr_t b, void *out, size_t maxlen)
{
struct conn *conn = (struct conn *)b;
return dtls_bio_read(conn,out,maxlen);
int rc = dtls_bio_read(conn,out,maxlen);
if (rc<=0){
errno = EAGAIN;
return -1;
}
errno=0;
return rc;
}
ssize_t dtls_gnutls_bio_write(gnutls_transport_ptr_t b, const void *data, size_t len)

View File

@ -246,8 +246,8 @@ static int dtls_verify_peer_callback (int ok, X509_STORE_CTX *ctx)
{
printf ("Verify callback called with ok = %d\n",ok);
SSL *ssl;
ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
// SSL *ssl;
// ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
char buf[1024];
X509 *err_cert;
@ -292,7 +292,7 @@ struct dtls_openssl_data * dtls_openssl_data_create(struct conn * conn, const SS
int rc = SSL_CTX_set_cipher_list(d->ctx, conn->dtls_cipher);
if (!rc){
dtls_openssl_log_error(0,rc,"DTLS setup error:");
dtls_openssl_log_error(0,rc,"DTLS setup cipher error:");
dtls_openssl_data_destroy(d);
return 0;
}

View File

@ -3,7 +3,7 @@
#include <stdint.h>
#include <ssl.h>
#include <openssl/ssl.h>
#include "conn.h"