From: Jan Klemkow Subject: tcpbench: key/cert generator To: tech@openbsd.org Cc: tb@openbsd.org Date: Tue, 5 Nov 2024 23:47:19 +0100 Hi, This diff add an on the fly key and self signed certificate generator for the server mode of tcpbench using the new crypto option -c. Thus, using tcpbench is much more convenient with crypto traffic. The user still can provide his own key and certificate. # tcpbench -sc # tcpbench -c localhost ok? Bye, Jan Index: Makefile =================================================================== RCS file: /cvs/src/usr.bin/tcpbench/Makefile,v diff -u -p -r1.11 Makefile --- Makefile 5 Nov 2024 18:12:55 -0000 1.11 +++ Makefile 5 Nov 2024 22:31:13 -0000 @@ -1,7 +1,7 @@ # $OpenBSD: Makefile,v 1.11 2024/11/05 18:12:55 jan Exp $ PROG= tcpbench -LDADD= -lm -levent -ltls -lcrypto -DPADD= ${LIBM} ${LIBEVENT} ${LIBTLS} ${LIBCRYPTO} +LDADD= -lm -levent -ltls -lssl -lcrypto +DPADD= ${LIBM} ${LIBEVENT} ${LIBTLS} ${LIBSSL} ${LIBCRYPTO} .include Index: tcpbench.c =================================================================== RCS file: /cvs/src/usr.bin/tcpbench/tcpbench.c,v diff -u -p -r1.71 tcpbench.c --- tcpbench.c 5 Nov 2024 18:12:55 -0000 1.71 +++ tcpbench.c 5 Nov 2024 22:31:13 -0000 @@ -1098,6 +1098,92 @@ process_tls_opt(char *s) return 0; } +void +generate_cert(uint8_t **key, size_t *key_size, uint8_t **crt, size_t *crt_size) +{ + EVP_PKEY *pkey; + EVP_PKEY_CTX *ctx; + X509 *x509; + X509_NAME *name; + BIO *bio; + BUF_MEM mem; + + /* + * Generate RSA key. + */ + if ((pkey = EVP_PKEY_new()) == NULL) + err(1, "EVP_PKEY_new"); + if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) + errx(1, "EVP_PKEY_CTX_new_id"); + if (EVP_PKEY_keygen_init(ctx) <= 0) + errx(1, "EVP_PKEY_keygen_init"); + if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0) + errx(1, "EVP_PKEY_CTX_set_rsa_keygen_bits"); + if (EVP_PKEY_keygen(ctx, &pkey) <= 0) + errx(1, "EVP_PKEY_keygen"); + + /* Get memory pointer of RSA key. */ + memset(&mem, 0, sizeof mem); + if ((bio = BIO_new(BIO_s_mem())) == NULL) + errx(1, "BIO_new"); + if (BIO_set_mem_buf(bio, &mem, BIO_NOCLOSE) <= 0) + errx(1, "BIO_set_mem_buf"); + if (PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL) == 0) + errx(1, "PEM_write_bio_PrivateKey"); + if (BIO_free(bio) == 0) + errx(1, "BIO_free"); + *key = mem.data; + *key_size = mem.length; + + /* + * Generate self sign certificate. + */ + if ((x509 = X509_new()) == NULL) + err(1, "X509_new"); + + /* Set subject and issuer. */ + name = X509_get_subject_name(x509); + if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, "localhost", + -1, -1, 0) == 0) + err(1, "X509_NAME_add_entry_by_txt"); + X509_set_subject_name(x509, name); + X509_set_issuer_name(x509, name); + + /* Set serial number. */ + if (ASN1_INTEGER_set(X509_get_serialNumber(x509), 1) == 0) + err(1, "ASN1_INTEGER_set"); + /* Use certificate version 3. */ + if (X509_set_version(x509, 2) == 0) + err(1, "X509_set_version"); + + /* Expiration date: 30 days (60s * 60m * 24h * 30d) */ + X509_gmtime_adj(X509_get_notBefore(x509), 0); + X509_gmtime_adj(X509_get_notAfter(x509), 2592000); + + /* Sign the certificate with the key. */ + if (X509_set_pubkey(x509, pkey) == 0) + err(1, "X509_set_pubkey"); + if (X509_sign(x509, pkey, EVP_sha256()) == 0) + err(1, "X509_sign"); + + /* Get memory pointer of certificate. */ + memset(&mem, 0, sizeof mem); + if ((bio = BIO_new(BIO_s_mem())) == NULL) + errx(1, "BIO_new"); + if (BIO_set_mem_buf(bio, &mem, BIO_NOCLOSE) <= 0) + errx(1, "BIO_set_mem_buf"); + if (PEM_write_bio_X509(bio, x509) == 0) + err(1, "PEM_write_bio_X509"); + if (BIO_free(bio) == 0) + errx(1, "BIO_free"); + *crt = mem.data; + *crt_size = mem.length; + + X509_free(x509); + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); +} + int main(int argc, char **argv) { @@ -1253,7 +1339,8 @@ main(int argc, char **argv) (UDP_MODE && (ptb->kvars || nconn != 1 || usetls))) usage(); - if (ptb->sflag && usetls && (crtfile == NULL || keyfile == NULL)) + if ((crtfile != NULL && (!ptb->sflag || !usetls || keyfile == NULL)) || + (keyfile != NULL && (!ptb->sflag || !usetls || crtfile == NULL))) usage(); if (crtfile != NULL && keyfile != NULL) { @@ -1350,6 +1437,10 @@ main(int argc, char **argv) errx(1, "unable to allocate TLS config"); if (ptb->sflag) { + /* Generate key with selfsigned certificate. */ + if (crt == NULL && key == NULL) + generate_cert(&key, &key_size, &crt, &crt_size); + if (tls_config_set_key_mem(ptb->tls_cfg, key, key_size) == -1) errx(1, "%s", tls_config_error(ptb->tls_cfg));