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 "cw_log.h"
|
||||
#include "conn.h"
|
||||
#include "cw_util.h"
|
||||
|
||||
#include "conn.h"
|
||||
#include "sock.h"
|
||||
|
||||
|
||||
#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)
|
||||
{
|
||||
/* BIO * b = SSL_get_rbio(ssl);
|
||||
struct conn * conn = b->ptr;
|
||||
*/
|
||||
|
||||
|
||||
// printf ("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMaking session id\n");
|
||||
const char * sessid = "123456789";
|
||||
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_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_cookie_generate_cb(d->ctx, dtls_openssl_generate_cookie);
|
||||
SSL_CTX_set_cookie_verify_cb(d->ctx, dtls_openssl_verify_cookie);
|
||||
|
||||
// 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, 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);
|
||||
|
||||
@ -403,195 +417,48 @@ int dtls_openssl_shutdown(struct conn *conn)
|
||||
|
||||
|
||||
|
||||
int cookie_initialized=0;
|
||||
#define COOKIE_SECRET_LENGTH 16
|
||||
unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
|
||||
//int cookie_initialized=0;
|
||||
//#define COOKIE_SECRET_LENGTH 16
|
||||
//unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
|
||||
|
||||
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";
|
||||
memcpy(cookie,coo,strlen(coo));
|
||||
*cookie_len=strlen(coo);
|
||||
/* we "missuse" sockaddr2str to convert our cookie to a hex str */
|
||||
cw_dbg(DBG_DTLS,"DTLS session cookie for %s generated: %s",
|
||||
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;
|
||||
|
||||
|
||||
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");
|
||||
char t[400];
|
||||
strncpy(t,(char*)cookie,cookie_len);
|
||||
t[cookie_len]=0;
|
||||
// printf("TCoo: %s\n",t);
|
||||
cw_dbg(DBG_DTLS,"Verifying DTLS cookie from %s: %s",
|
||||
sock_addr2str(&conn->addr),sock_hwaddr2idstr(conn->dtls_cookie,len));
|
||||
|
||||
if (len != sizeof(conn->dtls_cookie)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (memcmp(cookie,conn->dtls_cookie,len)!=0){
|
||||
return 0;
|
||||
}
|
||||
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)
|
||||
@ -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)
|
||||
{
|
||||
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