Iplemented clean DTLS cookie handling.
Also certificate check is available, still with a hard-coded pem file. FossilOrigin-Name: 2fb98eb2bf9e07bd7f21223dea499a992a7c38c963cfbeabbba2f7aa8ccd82af
This commit is contained in:
parent
14e08f96b5
commit
396c3ea5e0
@ -25,8 +25,10 @@
|
|||||||
#include "dtls_openssl.h"
|
#include "dtls_openssl.h"
|
||||||
|
|
||||||
#include "cw_log.h"
|
#include "cw_log.h"
|
||||||
#include "conn.h"
|
#include "cw_util.h"
|
||||||
|
|
||||||
|
#include "conn.h"
|
||||||
|
#include "sock.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef WITH_CW_LOG_DEBUG
|
#ifdef WITH_CW_LOG_DEBUG
|
||||||
@ -199,6 +201,11 @@ int dtls_openssl_set_certs(struct conn * conn, struct dtls_openssl_data *d)
|
|||||||
|
|
||||||
int generate_session_id(const SSL *ssl, unsigned char * id, unsigned int *id_len)
|
int generate_session_id(const SSL *ssl, unsigned char * id, unsigned int *id_len)
|
||||||
{
|
{
|
||||||
|
/* BIO * b = SSL_get_rbio(ssl);
|
||||||
|
struct conn * conn = b->ptr;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
// printf ("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMaking session id\n");
|
// printf ("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMaking session id\n");
|
||||||
const char * sessid = "123456789";
|
const char * sessid = "123456789";
|
||||||
memcpy(id,sessid,strlen(sessid));
|
memcpy(id,sessid,strlen(sessid));
|
||||||
@ -244,12 +251,18 @@ struct dtls_openssl_data * dtls_openssl_data_create(struct conn * conn, const SS
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SSL_CTX_set_session_cache_mode(d->ctx, SSL_SESS_CACHE_BOTH);
|
// SSL_CTX_set_session_cache_mode(d->ctx, SSL_SESS_CACHE_BOTH);
|
||||||
SSL_CTX_set_options(d->ctx, SSL_OP_COOKIE_EXCHANGE|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TICKET);
|
SSL_CTX_set_options(d->ctx, SSL_OP_COOKIE_EXCHANGE); //|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TICKET);
|
||||||
|
|
||||||
|
|
||||||
|
rc = SSL_CTX_load_verify_locations(d->ctx,"/home/tube/v/actube/ssl/root-ca.pem",NULL);
|
||||||
|
|
||||||
|
printf("Locations RC = %d\n",rc);
|
||||||
|
|
||||||
// SSL_CTX_set_options(d->ctx, SSL_OP_ALL);
|
// SSL_CTX_set_options(d->ctx, SSL_OP_ALL);
|
||||||
|
|
||||||
SSL_CTX_set_cookie_generate_cb(d->ctx, dtls_openssl_generate_cookie);
|
SSL_CTX_set_cookie_generate_cb(d->ctx, dtls_openssl_generate_cookie);
|
||||||
SSL_CTX_set_cookie_verify_cb(d->ctx, dtls_openssl_verify_cookie);
|
SSL_CTX_set_cookie_verify_cb(d->ctx, dtls_openssl_verify_cookie);
|
||||||
|
|
||||||
// SSL_CTX_set_generate_session_id(d->ctx,generate_session_id);
|
// SSL_CTX_set_generate_session_id(d->ctx,generate_session_id);
|
||||||
|
|
||||||
|
|
||||||
@ -257,7 +270,8 @@ struct dtls_openssl_data * dtls_openssl_data_create(struct conn * conn, const SS
|
|||||||
|
|
||||||
|
|
||||||
// SSL_CTX_set_verify(d->ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback);
|
// SSL_CTX_set_verify(d->ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback);
|
||||||
SSL_CTX_set_verify(d->ctx, SSL_VERIFY_PEER, dtls_verify_callback);
|
// SSL_CTX_set_verify(d->ctx, SSL_VERIFY_PEER, dtls_verify_callback);
|
||||||
|
SSL_CTX_set_verify(d->ctx, SSL_VERIFY_PEER, NULL);
|
||||||
|
|
||||||
// SSL_CTX_set_tmp_rsa_callback(d->ctx,tmp_rsa_callback);
|
// SSL_CTX_set_tmp_rsa_callback(d->ctx,tmp_rsa_callback);
|
||||||
|
|
||||||
@ -403,195 +417,48 @@ int dtls_openssl_shutdown(struct conn *conn)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cookie_initialized=0;
|
//int cookie_initialized=0;
|
||||||
#define COOKIE_SECRET_LENGTH 16
|
//#define COOKIE_SECRET_LENGTH 16
|
||||||
unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
|
//unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
|
||||||
|
|
||||||
int dtls_openssl_generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
|
int dtls_openssl_generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
BIO * b = SSL_get_rbio(ssl);
|
||||||
|
struct conn * conn = b->ptr;
|
||||||
|
|
||||||
//printf(" Gen cookie!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
|
cw_rand(conn->dtls_cookie,sizeof(conn->dtls_cookie));
|
||||||
|
|
||||||
const char * coo = "1234567890123456";
|
/* we "missuse" sockaddr2str to convert our cookie to a hex str */
|
||||||
memcpy(cookie,coo,strlen(coo));
|
cw_dbg(DBG_DTLS,"DTLS session cookie for %s generated: %s",
|
||||||
*cookie_len=strlen(coo);
|
sock_addr2str(&conn->addr), sock_hwaddr2idstr(conn->dtls_cookie,sizeof(conn->dtls_cookie)));
|
||||||
|
|
||||||
|
memcpy(cookie,conn->dtls_cookie,sizeof(conn->dtls_cookie));
|
||||||
|
*cookie_len=sizeof(conn->dtls_cookie);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
||||||
unsigned char *buffer, result[EVP_MAX_MD_SIZE];
|
|
||||||
unsigned int length = 0, resultlength;
|
|
||||||
union {
|
|
||||||
struct sockaddr_storage ss;
|
|
||||||
struct sockaddr_in6 s6;
|
|
||||||
struct sockaddr_in s4;
|
|
||||||
} peer;
|
|
||||||
|
|
||||||
/* Initialize a random secret */
|
|
||||||
if (!cookie_initialized)
|
|
||||||
{
|
|
||||||
if (!RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH))
|
|
||||||
{
|
|
||||||
printf("error setting random cookie secret\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
cookie_initialized = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Read peer information */
|
|
||||||
(void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
|
|
||||||
|
|
||||||
/* Create buffer with peer's address and port */
|
|
||||||
length = 0;
|
|
||||||
switch (peer.ss.ss_family) {
|
|
||||||
case AF_INET:
|
|
||||||
length += sizeof(struct in_addr);
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
length += sizeof(struct in6_addr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
OPENSSL_assert(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
length += sizeof(in_port_t);
|
|
||||||
buffer = (unsigned char*) OPENSSL_malloc(length);
|
|
||||||
|
|
||||||
if (buffer == NULL) {
|
|
||||||
printf("out of memory\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (peer.ss.ss_family) {
|
|
||||||
case AF_INET:
|
|
||||||
memcpy(buffer,
|
|
||||||
&peer.s4.sin_port,
|
|
||||||
sizeof(in_port_t));
|
|
||||||
memcpy(buffer + sizeof(peer.s4.sin_port),
|
|
||||||
&peer.s4.sin_addr,
|
|
||||||
sizeof(struct in_addr));
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
memcpy(buffer,
|
|
||||||
&peer.s6.sin6_port,
|
|
||||||
sizeof(in_port_t));
|
|
||||||
memcpy(buffer + sizeof(in_port_t),
|
|
||||||
&peer.s6.sin6_addr,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
OPENSSL_assert(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate HMAC of buffer using the secret */
|
|
||||||
HMAC(EVP_sha1(), (const void*) cookie_secret, COOKIE_SECRET_LENGTH,
|
|
||||||
(const unsigned char*) buffer, length, result, &resultlength);
|
|
||||||
OPENSSL_free(buffer);
|
|
||||||
|
|
||||||
memcpy(cookie, result, resultlength);
|
|
||||||
*cookie_len = resultlength;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int dtls_openssl_verify_cookie(SSL *ssl, unsigned char *cookie, unsigned int cookie_len)
|
int dtls_openssl_verify_cookie(SSL *ssl, unsigned char *cookie, unsigned int len)
|
||||||
{
|
{
|
||||||
|
BIO * b = SSL_get_rbio(ssl);
|
||||||
|
struct conn * conn = b->ptr;
|
||||||
|
|
||||||
//printf(" Verify cookie!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
|
cw_dbg(DBG_DTLS,"Verifying DTLS cookie from %s: %s",
|
||||||
char t[400];
|
sock_addr2str(&conn->addr),sock_hwaddr2idstr(conn->dtls_cookie,len));
|
||||||
strncpy(t,(char*)cookie,cookie_len);
|
|
||||||
t[cookie_len]=0;
|
|
||||||
// printf("TCoo: %s\n",t);
|
|
||||||
|
|
||||||
|
if (len != sizeof(conn->dtls_cookie)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(cookie,conn->dtls_cookie,len)!=0){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
unsigned char *buffer, result[EVP_MAX_MD_SIZE];
|
|
||||||
unsigned int length = 0, resultlength;
|
|
||||||
union {
|
|
||||||
struct sockaddr_storage ss;
|
|
||||||
struct sockaddr_in6 s6;
|
|
||||||
struct sockaddr_in s4;
|
|
||||||
} peer;
|
|
||||||
|
|
||||||
/* If secret isn't initialized yet, the cookie can't be valid */
|
|
||||||
if (!cookie_initialized)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Read peer information */
|
|
||||||
(void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
|
|
||||||
|
|
||||||
/* Create buffer with peer's address and port */
|
|
||||||
length = 0;
|
|
||||||
switch (peer.ss.ss_family) {
|
|
||||||
case AF_INET:
|
|
||||||
length += sizeof(struct in_addr);
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
length += sizeof(struct in6_addr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
OPENSSL_assert(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
length += sizeof(in_port_t);
|
|
||||||
buffer = (unsigned char*) OPENSSL_malloc(length);
|
|
||||||
|
|
||||||
if (buffer == NULL){
|
|
||||||
printf("out of memory\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (peer.ss.ss_family) {
|
|
||||||
case AF_INET:
|
|
||||||
memcpy(buffer,
|
|
||||||
&peer.s4.sin_port,
|
|
||||||
sizeof(in_port_t));
|
|
||||||
memcpy(buffer + sizeof(in_port_t),
|
|
||||||
&peer.s4.sin_addr,
|
|
||||||
sizeof(struct in_addr));
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
memcpy(buffer,
|
|
||||||
&peer.s6.sin6_port,
|
|
||||||
sizeof(in_port_t));
|
|
||||||
memcpy(buffer + sizeof(in_port_t),
|
|
||||||
&peer.s6.sin6_addr,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
OPENSSL_assert(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate HMAC of buffer using the secret */
|
|
||||||
HMAC(EVP_sha1(), (const void*) cookie_secret, COOKIE_SECRET_LENGTH,
|
|
||||||
(const unsigned char*) buffer, length, result, &resultlength);
|
|
||||||
OPENSSL_free(buffer);
|
|
||||||
|
|
||||||
if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct pass_info {
|
|
||||||
union {
|
|
||||||
struct sockaddr_storage ss;
|
|
||||||
struct sockaddr_in6 s6;
|
|
||||||
struct sockaddr_in s4;
|
|
||||||
} server_addr, client_addr;
|
|
||||||
SSL *ssl;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
int dtls_openssl_read(struct conn * conn, uint8_t *buffer, int len)
|
int dtls_openssl_read(struct conn * conn, uint8_t *buffer, int len)
|
||||||
@ -608,6 +475,11 @@ int dtls_openssl_read(struct conn * conn, uint8_t *buffer, int len)
|
|||||||
int dtls_openssl_write(struct conn * conn, const uint8_t *buffer, int len)
|
int dtls_openssl_write(struct conn * conn, const uint8_t *buffer, int len)
|
||||||
{
|
{
|
||||||
struct dtls_openssl_data * d = conn->dtls_data;
|
struct dtls_openssl_data * d = conn->dtls_data;
|
||||||
return SSL_write(d->ssl,buffer,len);
|
int rc = SSL_write(d->ssl,buffer,len);
|
||||||
|
if (dtls_openssl_log_error_queue("DTLS write error:")){
|
||||||
|
conn->dtls_error=1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user