Skip to content

Commit 920a331

Browse files
committed
Add interface required to implement QUIC draft-17
1 parent cf1698c commit 920a331

File tree

7 files changed

+226
-3
lines changed

7 files changed

+226
-3
lines changed

include/openssl/ssl.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,8 @@ typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx);
498498
*/
499499
# define SSL_MODE_NO_KTLS_TX 0x00000200U
500500

501+
# define SSL_MODE_QUIC_HACK 0x00000800U
502+
501503
/* Cert related flags */
502504
/*
503505
* Many implementations ignore some aspects of the TLS standards such as
@@ -625,6 +627,20 @@ void SSL_set_msg_callback(SSL *ssl,
625627
# define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
626628
# define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
627629

630+
typedef enum {
631+
SSL_KEY_CLIENT_EARLY_TRAFFIC,
632+
SSL_KEY_CLIENT_HANDSHAKE_TRAFFIC,
633+
SSL_KEY_CLIENT_APPLICATION_TRAFFIC,
634+
SSL_KEY_SERVER_HANDSHAKE_TRAFFIC,
635+
SSL_KEY_SERVER_APPLICATION_TRAFFIC
636+
} OSSL_KEY_TYPE;
637+
638+
void SSL_set_key_callback(SSL *ssl,
639+
int (*cb)(SSL *ssl, int name,
640+
const unsigned char *secret,
641+
size_t secretlen, void *arg),
642+
void *arg);
643+
628644
# define SSL_get_extms_support(s) \
629645
SSL_ctrl((s),SSL_CTRL_GET_EXTMS_SUPPORT,0,NULL)
630646

ssl/record/rec_layer_s3.c

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <stdio.h>
1111
#include <limits.h>
1212
#include <errno.h>
13+
#include <assert.h>
1314
#include "../ssl_locl.h"
1415
#include <openssl/evp.h>
1516
#include <openssl/buffer.h>
@@ -347,6 +348,22 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len,
347348
int i;
348349
size_t tmpwrit;
349350

351+
if (s->mode & SSL_MODE_QUIC_HACK) {
352+
/* If we have an alert to send, lets send it */
353+
if (s->s3->alert_dispatch) {
354+
i = s->method->ssl_dispatch_alert(s);
355+
if (i <= 0) {
356+
/* SSLfatal() already called if appropriate */
357+
return i;
358+
}
359+
}
360+
361+
s->rwstate = SSL_WRITING;
362+
*written = len;
363+
364+
return 1;
365+
}
366+
350367
s->rwstate = SSL_NOTHING;
351368
tot = s->rlayer.wnum;
352369
/*
@@ -659,6 +676,10 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
659676
size_t totlen = 0, len, wpinited = 0;
660677
size_t j;
661678

679+
if (s->mode & SSL_MODE_QUIC_HACK) {
680+
assert(0);
681+
}
682+
662683
for (j = 0; j < numpipes; j++)
663684
totlen += pipelens[j];
664685
/*
@@ -1156,6 +1177,10 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len,
11561177
size_t currbuf = 0;
11571178
size_t tmpwrit = 0;
11581179

1180+
if (s->mode & SSL_MODE_QUIC_HACK) {
1181+
assert(0);
1182+
}
1183+
11591184
if ((s->rlayer.wpend_tot > len)
11601185
|| (!(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)
11611186
&& (s->rlayer.wpend_buf != buf))
@@ -1274,6 +1299,117 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
12741299
}
12751300
}
12761301

1302+
if (s->mode & SSL_MODE_QUIC_HACK) {
1303+
/* In QUIC, we only expect handshake protocol. Alerts are
1304+
notified by decicated API function. */
1305+
if (!ossl_statem_get_in_handshake(s)) {
1306+
/* We found handshake data, so we're going back into init */
1307+
ossl_statem_set_in_init(s, 1);
1308+
1309+
i = s->handshake_func(s);
1310+
/* SSLfatal() already called if appropriate */
1311+
if (i < 0)
1312+
return i;
1313+
if (i == 0) {
1314+
return -1;
1315+
}
1316+
*readbytes = 0;
1317+
return 1;
1318+
}
1319+
1320+
if (s->rlayer.packet_length == 0) {
1321+
if (rbuf->left < 4) {
1322+
if (rbuf->len - rbuf->offset < 4 - rbuf->left) {
1323+
memmove(rbuf->buf, rbuf->buf + rbuf->offset - rbuf->left,
1324+
rbuf->left);
1325+
rbuf->offset = rbuf->left;
1326+
}
1327+
s->rwstate = SSL_READING;
1328+
/* TODO(size_t): Convert this function */
1329+
ret = BIO_read(s->rbio, rbuf->buf + rbuf->offset,
1330+
rbuf->len - rbuf->offset);
1331+
if (ret < 0) {
1332+
return -1;
1333+
}
1334+
/* TODO Check this is really ok */
1335+
if (ret == 0) {
1336+
*readbytes = 0;
1337+
return 1;
1338+
}
1339+
1340+
rbuf->left += ret;
1341+
rbuf->offset += ret;
1342+
1343+
if (rbuf->left < 4) {
1344+
*readbytes = 0;
1345+
return 1;
1346+
}
1347+
rbuf->offset -= rbuf->left;
1348+
}
1349+
1350+
switch (rbuf->buf[rbuf->offset]) {
1351+
case SSL3_MT_CLIENT_HELLO:
1352+
case SSL3_MT_SERVER_HELLO:
1353+
case SSL3_MT_NEWSESSION_TICKET:
1354+
case SSL3_MT_END_OF_EARLY_DATA:
1355+
case SSL3_MT_ENCRYPTED_EXTENSIONS:
1356+
case SSL3_MT_CERTIFICATE:
1357+
case SSL3_MT_CERTIFICATE_REQUEST:
1358+
case SSL3_MT_CERTIFICATE_VERIFY:
1359+
case SSL3_MT_FINISHED:
1360+
case SSL3_MT_KEY_UPDATE:
1361+
case SSL3_MT_MESSAGE_HASH:
1362+
break;
1363+
default:
1364+
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_READ_BYTES,
1365+
ERR_R_INTERNAL_ERROR);
1366+
return -1;
1367+
}
1368+
1369+
s->rlayer.packet_length = (rbuf->buf[rbuf->offset + 1] << 16)
1370+
+ (rbuf->buf[rbuf->offset + 2] << 8)
1371+
+ rbuf->buf[rbuf->offset + 3] + 4;
1372+
}
1373+
1374+
if (s->rlayer.packet_length) {
1375+
size_t n;
1376+
1377+
n = len < s->rlayer.packet_length ? len : s->rlayer.packet_length;
1378+
if (rbuf->left == 0) {
1379+
s->rwstate = SSL_READING;
1380+
ret = BIO_read(s->rbio, buf, n);
1381+
if (ret >= 0) {
1382+
s->rlayer.packet_length -= ret;
1383+
*readbytes = ret;
1384+
if (recvd_type) {
1385+
*recvd_type = SSL3_RT_HANDSHAKE;
1386+
}
1387+
return 1;
1388+
}
1389+
return -1;
1390+
}
1391+
1392+
n = n < rbuf->left ? n : rbuf->left;
1393+
1394+
memcpy(buf, rbuf->buf + rbuf->offset, n);
1395+
rbuf->offset += n;
1396+
rbuf->left -= n;
1397+
s->rlayer.packet_length -= n;
1398+
if (rbuf->left == 0) {
1399+
rbuf->offset = 0;
1400+
}
1401+
*readbytes = n;
1402+
if (recvd_type) {
1403+
*recvd_type = SSL3_RT_HANDSHAKE;
1404+
}
1405+
return 1;
1406+
}
1407+
1408+
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_READ_BYTES,
1409+
ERR_R_INTERNAL_ERROR);
1410+
return -1;
1411+
}
1412+
12771413
if ((type && (type != SSL3_RT_APPLICATION_DATA)
12781414
&& (type != SSL3_RT_HANDSHAKE)) || (peek
12791415
&& (type !=

ssl/s3_msg.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,16 @@ int ssl3_dispatch_alert(SSL *s)
7878
size_t written;
7979

8080
s->s3->alert_dispatch = 0;
81-
alertlen = 2;
82-
i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], &alertlen, 1, 0,
83-
&written);
81+
82+
if (!(s->mode & SSL_MODE_QUIC_HACK)) {
83+
alertlen = 2;
84+
i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], &alertlen, 1,
85+
0, &written);
86+
} else {
87+
s->rwstate = SSL_WRITING;
88+
i = 1;
89+
}
90+
8491
if (i <= 0) {
8592
s->s3->alert_dispatch = 1;
8693
} else {

ssl/ssl_lib.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4322,6 +4322,16 @@ void SSL_set_msg_callback(SSL *ssl,
43224322
SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
43234323
}
43244324

4325+
void SSL_set_key_callback(SSL *ssl,
4326+
int (*cb)(SSL *ssl, int name,
4327+
const unsigned char *secret,
4328+
size_t secretlen, void *arg),
4329+
void *arg)
4330+
{
4331+
ssl->key_callback = cb;
4332+
ssl->key_callback_arg = arg;
4333+
}
4334+
43254335
void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx,
43264336
int (*cb) (SSL *ssl,
43274337
int

ssl/ssl_locl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,9 @@ struct ssl_st {
11371137
void (*msg_callback) (int write_p, int version, int content_type,
11381138
const void *buf, size_t len, SSL *ssl, void *arg);
11391139
void *msg_callback_arg;
1140+
int (*key_callback)(SSL *ssl, int name, const unsigned char *secret,
1141+
size_t secretlen, void *arg);
1142+
void *key_callback_arg;
11401143
int hit; /* reusing a previous session */
11411144
X509_VERIFY_PARAM *param;
11421145
/* Per connection DANE state */

ssl/tls13_enc.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,56 @@ int tls13_change_cipher_state(SSL *s, int which)
642642
goto err;
643643
}
644644

645+
if (s->key_callback) {
646+
int type;
647+
if (label == client_early_traffic) {
648+
type = SSL_KEY_CLIENT_EARLY_TRAFFIC;
649+
} else if (label == client_handshake_traffic) {
650+
type = SSL_KEY_CLIENT_HANDSHAKE_TRAFFIC;
651+
} else if (label == client_application_traffic) {
652+
type = SSL_KEY_CLIENT_APPLICATION_TRAFFIC;
653+
} else if (label == server_handshake_traffic) {
654+
type = SSL_KEY_SERVER_HANDSHAKE_TRAFFIC;
655+
} else if (label == server_application_traffic) {
656+
type = SSL_KEY_SERVER_APPLICATION_TRAFFIC;
657+
} else {
658+
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_CHANGE_CIPHER_STATE,
659+
ERR_R_INTERNAL_ERROR);
660+
goto err;
661+
}
662+
if (!s->key_callback(s, type, secret, hashlen, s->key_callback_arg)) {
663+
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_CHANGE_CIPHER_STATE,
664+
ERR_R_INTERNAL_ERROR);
665+
goto err;
666+
}
667+
668+
if (s->server) {
669+
switch (type) {
670+
case SSL_KEY_CLIENT_HANDSHAKE_TRAFFIC:
671+
case SSL_KEY_CLIENT_APPLICATION_TRAFFIC:
672+
if (s->rlayer.rbuf.left) {
673+
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
674+
SSL_F_TLS13_CHANGE_CIPHER_STATE,
675+
ERR_R_INTERNAL_ERROR);
676+
goto err;
677+
}
678+
break;
679+
}
680+
} else {
681+
switch (type) {
682+
case SSL_KEY_SERVER_HANDSHAKE_TRAFFIC:
683+
case SSL_KEY_SERVER_APPLICATION_TRAFFIC:
684+
if (s->rlayer.rbuf.left) {
685+
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
686+
SSL_F_TLS13_CHANGE_CIPHER_STATE,
687+
ERR_R_INTERNAL_ERROR);
688+
goto err;
689+
}
690+
break;
691+
}
692+
}
693+
}
694+
645695
if (label == server_application_traffic) {
646696
memcpy(s->server_app_traffic_secret, secret, hashlen);
647697
/* Now we create the exporter master secret */

util/libssl.num

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,3 +498,4 @@ SSL_CTX_get_recv_max_early_data 498 3_0_0 EXIST::FUNCTION:
498498
SSL_CTX_set_recv_max_early_data 499 3_0_0 EXIST::FUNCTION:
499499
SSL_CTX_set_post_handshake_auth 500 3_0_0 EXIST::FUNCTION:
500500
SSL_get_signature_type_nid 501 3_0_0 EXIST::FUNCTION:
501+
SSL_set_key_callback 502 3_0_0 EXIST::FUNCTION:

0 commit comments

Comments
 (0)