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

@ -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;
}