diff options
author | Matt Caswell <matt@openssl.org> | 2022-02-04 17:24:20 +0300 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2022-02-04 17:26:08 +0300 |
commit | 591f97b6732c80b07edd37d69faa95c11c1b263f (patch) | |
tree | 923cf7d145e249288cd72f382db00d680d408652 | |
parent | 74723171cc164766f42e1392a6b79e126cc31dad (diff) |
Add Toy protocol server support to sslechossl-compat-toy
Also adds the necessary SSL compat layer for server support
-rw-r--r-- | apps/toyclient.c | 4 | ||||
-rw-r--r-- | apps/toysrvr.c | 4 | ||||
-rw-r--r-- | crypto/toy/toy.c | 9 | ||||
-rw-r--r-- | demos/sslecho/main.c | 50 | ||||
-rw-r--r-- | include/openssl/ssl.h.in | 1 | ||||
-rw-r--r-- | include/openssl/toy.h | 3 | ||||
-rw-r--r-- | ssl/methods.c | 38 | ||||
-rw-r--r-- | ssl/ssl_local.h | 1 | ||||
-rw-r--r-- | ssl/toyprot.c | 39 | ||||
-rw-r--r-- | util/libcrypto.num | 1 | ||||
-rw-r--r-- | util/libssl.num | 1 |
11 files changed, 123 insertions, 28 deletions
diff --git a/apps/toyclient.c b/apps/toyclient.c index 20433013e5..ebfb83ac7d 100644 --- a/apps/toyclient.c +++ b/apps/toyclient.c @@ -53,7 +53,7 @@ int toyclient_main(int argc, char **argv) struct timeval timeout, *timeoutp = NULL; int width; fd_set readfds; - int i, havenewtimeout; + int i, havenewtimeout, isnew; prog = opt_init(argc, argv, toyclient_options); while ((o = opt_next()) != OPT_EOF) { @@ -215,7 +215,7 @@ opthelp: } if (FD_ISSET(sock, &readfds)) { - if (OSSL_TOY_CTX_process_packet(ctx, &conn, &stream) <= 0) { + if (OSSL_TOY_CTX_process_packet(ctx, &conn, &stream, &isnew) <= 0) { BIO_printf(bio_err, "Failed processing a packet\n"); goto err; } diff --git a/apps/toysrvr.c b/apps/toysrvr.c index 1c1410a822..7d671cc91d 100644 --- a/apps/toysrvr.c +++ b/apps/toysrvr.c @@ -45,7 +45,7 @@ static int toy_server_cb(int sock, int type, int protocol, OSSL_TOY_STREAM *stream; unsigned char buf[4097]; size_t bytesread, byteswritten; - int ret = -1; + int ret = -1, isnew; BIO *rbio = NULL, *wbio = NULL; rbio = BIO_new_dgram(sock, BIO_NOCLOSE); @@ -69,7 +69,7 @@ static int toy_server_cb(int sock, int type, int protocol, rbio = wbio = NULL; for (;;) { - if (OSSL_TOY_CTX_process_packet(ctx, &conn, &stream) <= 0) { + if (OSSL_TOY_CTX_process_packet(ctx, &conn, &stream, &isnew) <= 0) { BIO_printf(bio_err, "Failed processing a packet\n"); goto err; } diff --git a/crypto/toy/toy.c b/crypto/toy/toy.c index 3d2ba97b6f..dc53d3ac84 100644 --- a/crypto/toy/toy.c +++ b/crypto/toy/toy.c @@ -163,7 +163,7 @@ OSSL_TOY_CONN *OSSL_TOY_CTX_get0_connection(OSSL_TOY_CTX *ctx, uint32_t id) } int OSSL_TOY_CTX_process_packet(OSSL_TOY_CTX *ctx, OSSL_TOY_CONN **conn, - OSSL_TOY_STREAM **stream) + OSSL_TOY_STREAM **stream, int *isnew) { int ret; OSSL_TOY_PACKET *packet = ossl_toy_packet_new(); @@ -189,6 +189,7 @@ int OSSL_TOY_CTX_process_packet(OSSL_TOY_CTX *ctx, OSSL_TOY_CONN **conn, packet->appdata = packet->data + OSSL_TOY_PACKET_HEADER_SIZE; packet->length = ret - OSSL_TOY_PACKET_HEADER_SIZE; + *isnew = 0; *conn = NULL; /* Find the connection */ for (i = 0; i < OSSL_TOY_MAX_TOY_CONNECTIONS; i++) { @@ -209,6 +210,7 @@ int OSSL_TOY_CTX_process_packet(OSSL_TOY_CTX *ctx, OSSL_TOY_CONN **conn, ret = -1; goto err; } + *isnew = 1; } if (ctx->isserver && (*conn)->peer == NULL) { @@ -256,6 +258,11 @@ int OSSL_TOY_CTX_handle_timeout(struct timeval *nxttimeout, int *havenewtimeout) return 1; } +int OSSL_TOY_CTX_is_server(OSSL_TOY_CTX *ctx) +{ + return ctx->isserver; +} + void ossl_toy_conn_free(OSSL_TOY_CONN *conn) { size_t i; diff --git a/demos/sslecho/main.c b/demos/sslecho/main.c index 7892a77b2d..7467cee99e 100644 --- a/demos/sslecho/main.c +++ b/demos/sslecho/main.c @@ -51,13 +51,12 @@ int create_socket(bool isServer, bool isTls) { perror("setsockopt(SO_REUSEADDR) failed"); exit(EXIT_FAILURE); } - if (bind(s, (struct sockaddr*) &addr, sizeof(addr)) < 0) { perror("Unable to bind"); exit(EXIT_FAILURE); } - if (listen(s, 1) < 0) { + if (isTls && listen(s, 1) < 0) { perror("Unable to listen"); exit(EXIT_FAILURE); } @@ -70,12 +69,16 @@ SSL_CTX* create_context(bool isServer, bool isTls) { const SSL_METHOD *method; SSL_CTX *ctx; - if (isServer) - method = TLS_server_method(); - else if (isTls) + if (isServer) { + if (isTls) + method = TLS_server_method(); + else + method = TOY_server_method(); + } else if (isTls) { method = TLS_client_method(); - else + } else { method = TOY_client_method(); + } ctx = SSL_CTX_new(method); if (ctx == NULL) { @@ -167,15 +170,12 @@ int main(int argc, char **argv) { rem_server_ip = argv[3]; } - /* We don't support TOY protocol on the server yet */ - if (isServer && !isTls) - usage(); - /* Create context used by both client and server */ ssl_ctx = create_context(isServer, isTls); /* If server */ if (isServer) { + BIO *srvrbio; printf("We are the server on port: %d\n\n", server_port); @@ -184,6 +184,8 @@ int main(int argc, char **argv) { /* Create server socket; will bind with server port and listen */ server_skt = create_socket(true, isTls); + if (!isTls) + srvrbio = BIO_new_dgram(server_skt, BIO_NOCLOSE); /* * Loop to accept clients. @@ -191,26 +193,34 @@ int main(int argc, char **argv) { * before we can catch a CTRL-C and kill the server. */ while (server_running) { - /* Wait for TCP connection from client */ - client_skt = accept(server_skt, (struct sockaddr*) &addr, - &addr_len); - if (client_skt < 0) { - perror("Unable to accept"); - exit(EXIT_FAILURE); + if (isTls) { + /* Wait for TCP connection from client */ + client_skt = accept(server_skt, (struct sockaddr*) &addr, + &addr_len); + if (client_skt < 0) { + perror("Unable to accept"); + exit(EXIT_FAILURE); + } + printf("Client TCP connection accepted\n"); } - - printf("Client TCP connection accepted\n"); + /* + * else do nothing. For the TOY protocol we just call SSL_accept() + * to accept a connection using the main socket + */ /* Create server SSL structure using newly accepted client socket */ ssl = SSL_new(ssl_ctx); - SSL_set_fd(ssl, client_skt); + if (isTls) + SSL_set_fd(ssl, client_skt); + else + SSL_set_bio(ssl, srvrbio, srvrbio); /* Wait for SSL connection from the client */ if (SSL_accept(ssl) <= 0) { ERR_print_errors_fp(stderr); } else { - printf("Client SSL connection accepted\n\n"); + printf("Client connection accepted\n\n"); /* Echo loop */ while (true) { diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in index ea30c273da..49a0a62754 100644 --- a/include/openssl/ssl.h.in +++ b/include/openssl/ssl.h.in @@ -1972,6 +1972,7 @@ __owur const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */ __owur const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */ __owur const SSL_METHOD *TOY_client_method(void); +__owur const SSL_METHOD *TOY_server_method(void); __owur size_t DTLS_get_data_mtu(const SSL *s); diff --git a/include/openssl/toy.h b/include/openssl/toy.h index d0bdbc558b..463f7d19ff 100644 --- a/include/openssl/toy.h +++ b/include/openssl/toy.h @@ -31,8 +31,9 @@ BIO *OSSL_TOY_CTX_get0_rbio(OSSL_TOY_CTX *ctx); BIO *OSSL_TOY_CTX_get0_wbio(OSSL_TOY_CTX *ctx); OSSL_TOY_CONN *OSSL_TOY_CTX_get0_connection(OSSL_TOY_CTX *ctx, uint32_t id); int OSSL_TOY_CTX_process_packet(OSSL_TOY_CTX *ctx, OSSL_TOY_CONN **conn, - OSSL_TOY_STREAM **stream); + OSSL_TOY_STREAM **stream, int *isnew); int OSSL_TOY_CTX_handle_timeout(struct timeval *nxttimeout, int *havenewtimeout); +int OSSL_TOY_CTX_is_server(OSSL_TOY_CTX *ctx); OSSL_TOY_STREAM *OSSL_TOY_CONN_get0_stream(OSSL_TOY_CONN *conn, uint32_t streamid); uint32_t OSSL_TOY_CONN_get_id(OSSL_TOY_CONN *conn); diff --git a/ssl/methods.c b/ssl/methods.c index 0628277604..2c809ad154 100644 --- a/ssl/methods.c +++ b/ssl/methods.c @@ -315,3 +315,41 @@ const SSL_METHOD *TOY_client_method(void) return &toy_client_method_data; } + +const SSL_METHOD *TOY_server_method(void) +{ + static const SSL_METHOD toy_server_method_data= { + TOY_PROTOCOL_VERSION_1, + 0, /* flags */ + 0, /* mask */ + ossl_toy_new, + ossl_toy_clear, + ossl_toy_free, + ossl_toy_accept, + NULL, /* connect */ + ossl_toy_read, + NULL, /* peek */ + ossl_toy_write, + NULL, /* shutdown*/ + NULL, /* renegotiate */ + ossl_toy_renegotiate_check, + NULL, /* read_bytes */ + NULL, /* write_bytes */ + NULL, /* dispatch_alert */ + ossl_toy_ctrl, + NULL, /* ctx_ctrl */ + NULL, + NULL, + NULL, + ossl_toy_num_ciphers, + NULL, + tls1_default_timeout, + NULL, + NULL, + NULL, + NULL, + ossl_toy_server_ctx_new + }; + + return &toy_server_method_data; +} diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 8c4d5afa22..83adb1f451 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -2902,6 +2902,7 @@ int ossl_toy_write(SSL *s, const void *buf, size_t len, size_t *written); int ossl_toy_num_ciphers(void); long ossl_toy_ctrl(SSL *s, int cmd, long larg, void *parg); int ossl_toy_connect(SSL *s); +int ossl_toy_accept(SSL *s); int ossl_toy_renegotiate_check(SSL *s, int initok); #endif diff --git a/ssl/toyprot.c b/ssl/toyprot.c index 9e4888a72f..b4b1617cc5 100644 --- a/ssl/toyprot.c +++ b/ssl/toyprot.c @@ -23,6 +23,12 @@ static ossl_inline OSSL_TOY_CONN *ossl_toy_get_conn(SSL *s) int ossl_toy_new(SSL *s) { + OSSL_TOY_CTX *ctx = ossl_toy_get_ctx(s); + + /* Nothing to be done if we are a server */ + if (OSSL_TOY_CTX_is_server(ctx)) + return 1; + s->meth_data = OSSL_TOY_CTX_get0_connection(ossl_toy_get_ctx(s), OSSL_TOY_NULL_CONNECTION_ID); return s->meth_data != NULL; @@ -58,14 +64,14 @@ int ossl_toy_read(SSL *s, void *buf, size_t len, size_t *readbytes) OSSL_TOY_STREAM *stream = OSSL_TOY_CONN_get0_stream(ossl_toy_get_conn(s), 0); if (!OSSL_TOY_STREAM_read(stream, buf, len, readbytes)) { - int ret; + int ret, isnew; OSSL_TOY_STREAM *tmpstream; OSSL_TOY_CONN *conn; /* See if we can get more data */ do { ret = OSSL_TOY_CTX_process_packet(ossl_toy_get_ctx(s), &conn, - &tmpstream); + &tmpstream, &isnew); } while (ret > 0 && stream != tmpstream); return ret > 0 && OSSL_TOY_STREAM_read(stream, buf, len, readbytes); } @@ -109,6 +115,35 @@ int ossl_toy_connect(SSL *s) return 1; } +int ossl_toy_accept(SSL *s) +{ + OSSL_TOY_CTX *ctx = ossl_toy_get_ctx(s); + OSSL_TOY_CONN *conn = NULL; + OSSL_TOY_STREAM *stream = NULL; + int isnew, ret; + + if (s->rbio != OSSL_TOY_CTX_get0_rbio(ctx)) { + if (!BIO_up_ref(s->rbio)) + return -1; + OSSL_TOY_CTX_set0_rbio(ctx, s->rbio); + } + + if (s->wbio != OSSL_TOY_CTX_get0_wbio(ctx)) { + if (!BIO_up_ref(s->wbio)) + return -1; + OSSL_TOY_CTX_set0_wbio(ctx, s->wbio); + } + + do { + ret = OSSL_TOY_CTX_process_packet(ctx, &conn, &stream, &isnew); + } while(ret > 0 && !isnew); + + if (ret > 0) + s->meth_data = conn; + + return ret; +} + int ossl_toy_renegotiate_check(SSL *s, int initok) { return 1; diff --git a/util/libcrypto.num b/util/libcrypto.num index 087b510a98..420cf52a20 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5449,3 +5449,4 @@ OSSL_TOY_CTX_set0_rbio ? 3_1_0 EXIST::FUNCTION: OSSL_TOY_CTX_set0_wbio ? 3_1_0 EXIST::FUNCTION: OSSL_TOY_CTX_get0_rbio ? 3_1_0 EXIST::FUNCTION: OSSL_TOY_CTX_get0_wbio ? 3_1_0 EXIST::FUNCTION: +OSSL_TOY_CTX_is_server ? 3_1_0 EXIST::FUNCTION: diff --git a/util/libssl.num b/util/libssl.num index 9449d7b707..8075e662b5 100644 --- a/util/libssl.num +++ b/util/libssl.num @@ -521,3 +521,4 @@ SSL_set0_tmp_dh_pkey 521 3_0_0 EXIST::FUNCTION: SSL_CTX_set0_tmp_dh_pkey 522 3_0_0 EXIST::FUNCTION: SSL_group_to_name 523 3_0_0 EXIST::FUNCTION: TOY_client_method ? 3_1_0 EXIST::FUNCTION: +TOY_server_method ? 3_1_0 EXIST::FUNCTION: |