summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorTodd Short <tshort@akamai.com>2021-01-27 14:23:33 -0500
committerTodd Short <todd.short@me.com>2023-03-28 13:49:54 -0400
commit3c95ef22df55cb2d9dc64ce1f3be6e5a8ee63206 (patch)
tree0f7fcff4ec4735c778595db4f4a85bce70715d8b /apps
parent5ab3f71a33cb0140fc29ae9244cd4f8331c2f3a5 (diff)
downloadopenssl-new-3c95ef22df55cb2d9dc64ce1f3be6e5a8ee63206.tar.gz
RFC7250 (RPK) support
Add support for the RFC7250 certificate-type extensions. Alows the use of only private keys for connection (i.e. certs not needed). Add APIs Add unit tests Add documentation Add s_client/s_server support Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Viktor Dukhovni <viktor@openssl.org> (Merged from https://github.com/openssl/openssl/pull/18185)
Diffstat (limited to 'apps')
-rw-r--r--apps/lib/s_cb.c34
-rw-r--r--apps/s_client.c45
-rw-r--r--apps/s_server.c43
3 files changed, 105 insertions, 17 deletions
diff --git a/apps/lib/s_cb.c b/apps/lib/s_cb.c
index 04464bec03..dcfea55dc5 100644
--- a/apps/lib/s_cb.c
+++ b/apps/lib/s_cb.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -673,6 +673,8 @@ static STRINT_PAIR tlsext_types[] = {
{"session ticket", TLSEXT_TYPE_session_ticket},
{"renegotiation info", TLSEXT_TYPE_renegotiate},
{"signed certificate timestamps", TLSEXT_TYPE_signed_certificate_timestamp},
+ {"client cert type", TLSEXT_TYPE_client_cert_type},
+ {"server cert type", TLSEXT_TYPE_server_cert_type},
{"TLS padding", TLSEXT_TYPE_padding},
#ifdef TLSEXT_TYPE_next_proto_neg
{"next protocol", TLSEXT_TYPE_next_proto_neg},
@@ -1171,7 +1173,7 @@ static char *hexencode(const unsigned char *data, size_t len)
void print_verify_detail(SSL *s, BIO *bio)
{
int mdpth;
- EVP_PKEY *mspki;
+ EVP_PKEY *mspki = NULL;
long verify_err = SSL_get_verify_result(s);
if (verify_err == X509_V_OK) {
@@ -1206,12 +1208,15 @@ void print_verify_detail(SSL *s, BIO *bio)
hexdata = hexencode(data + dlen - TLSA_TAIL_SIZE, TLSA_TAIL_SIZE);
else
hexdata = hexencode(data, dlen);
- BIO_printf(bio, "DANE TLSA %d %d %d %s%s %s at depth %d\n",
+ BIO_printf(bio, "DANE TLSA %d %d %d %s%s ",
usage, selector, mtype,
- (dlen > TLSA_TAIL_SIZE) ? "..." : "", hexdata,
- (mspki != NULL) ? "signed the certificate" :
- mdpth ? "matched TA certificate" : "matched EE certificate",
- mdpth);
+ (dlen > TLSA_TAIL_SIZE) ? "..." : "", hexdata);
+ if (SSL_get0_peer_rpk(s) == NULL)
+ BIO_printf(bio, "%s certificate at depth %d\n",
+ (mspki != NULL) ? "signed the peer" :
+ mdpth ? "matched the TA" : "matched the EE", mdpth);
+ else
+ BIO_printf(bio, "matched the peer raw public key\n");
OPENSSL_free(hexdata);
}
}
@@ -1219,17 +1224,16 @@ void print_verify_detail(SSL *s, BIO *bio)
void print_ssl_summary(SSL *s)
{
const SSL_CIPHER *c;
- X509 *peer;
+ X509 *peer = SSL_get0_peer_certificate(s);
+ EVP_PKEY *peer_rpk = SSL_get0_peer_rpk(s);
+ int nid;
BIO_printf(bio_err, "Protocol version: %s\n", SSL_get_version(s));
print_raw_cipherlist(s);
c = SSL_get_current_cipher(s);
BIO_printf(bio_err, "Ciphersuite: %s\n", SSL_CIPHER_get_name(c));
do_print_sigalgs(bio_err, s, 0);
- peer = SSL_get0_peer_certificate(s);
if (peer != NULL) {
- int nid;
-
BIO_puts(bio_err, "Peer certificate: ");
X509_NAME_print_ex(bio_err, X509_get_subject_name(peer),
0, get_nameopt());
@@ -1239,8 +1243,13 @@ void print_ssl_summary(SSL *s)
if (SSL_get_peer_signature_type_nid(s, &nid))
BIO_printf(bio_err, "Signature type: %s\n", get_sigtype(nid));
print_verify_detail(s, bio_err);
+ } else if (peer_rpk != NULL) {
+ BIO_printf(bio_err, "Peer used raw public key\n");
+ if (SSL_get_peer_signature_type_nid(s, &nid))
+ BIO_printf(bio_err, "Signature type: %s\n", get_sigtype(nid));
+ print_verify_detail(s, bio_err);
} else {
- BIO_puts(bio_err, "No peer certificate\n");
+ BIO_puts(bio_err, "No peer certificate or raw public key\n");
}
#ifndef OPENSSL_NO_EC
ssl_print_point_formats(bio_err, s);
@@ -1595,4 +1604,3 @@ int progress_cb(EVP_PKEY_CTX *ctx)
(void)BIO_flush(b);
return 1;
}
-
diff --git a/apps/s_client.c b/apps/s_client.c
index 9942893bd3..408be290f3 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2005 Nokia. All rights reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -75,6 +75,9 @@ static int ocsp_resp_cb(SSL *s, void *arg);
static int ldap_ExtendedResponse_parse(const char *buf, long rem);
static int is_dNS_name(const char *host);
+static const unsigned char cert_type_rpk[] = { TLSEXT_cert_type_rpk, TLSEXT_cert_type_x509 };
+static int enable_server_rpk = 0;
+
static int saved_errno;
static void save_errno(void)
@@ -468,6 +471,8 @@ typedef enum OPTION_choice {
#endif
OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME,
OPT_ENABLE_PHA,
+ OPT_ENABLE_SERVER_RPK,
+ OPT_ENABLE_CLIENT_RPK,
OPT_SCTP_LABEL_BUG,
OPT_KTLS,
OPT_R_ENUM, OPT_PROV_ENUM
@@ -658,6 +663,8 @@ const OPTIONS s_client_options[] = {
#endif
{"early_data", OPT_EARLY_DATA, '<', "File to send as early data"},
{"enable_pha", OPT_ENABLE_PHA, '-', "Enable post-handshake-authentication"},
+ {"enable_server_rpk", OPT_ENABLE_SERVER_RPK, '-', "Enable raw public keys (RFC7250) from the server"},
+ {"enable_client_rpk", OPT_ENABLE_CLIENT_RPK, '-', "Enable raw public keys (RFC7250) from the client"},
#ifndef OPENSSL_NO_SRTP
{"use_srtp", OPT_USE_SRTP, 's',
"Offer SRTP key management with a colon-separated profile list"},
@@ -896,6 +903,7 @@ int s_client_main(int argc, char **argv)
#endif
char *psksessf = NULL;
int enable_pha = 0;
+ int enable_client_rpk = 0;
#ifndef OPENSSL_NO_SCTP
int sctp_label_bug = 0;
#endif
@@ -1489,6 +1497,12 @@ int s_client_main(int argc, char **argv)
enable_ktls = 1;
#endif
break;
+ case OPT_ENABLE_SERVER_RPK:
+ enable_server_rpk = 1;
+ break;
+ case OPT_ENABLE_CLIENT_RPK:
+ enable_client_rpk = 1;
+ break;
}
}
@@ -1980,6 +1994,18 @@ int s_client_main(int argc, char **argv)
if (enable_pha)
SSL_set_post_handshake_auth(con, 1);
+ if (enable_client_rpk)
+ if (!SSL_set1_client_cert_type(con, cert_type_rpk, sizeof(cert_type_rpk))) {
+ BIO_printf(bio_err, "Error setting client certificate types\n");
+ goto end;
+ }
+ if (enable_server_rpk) {
+ if (!SSL_set1_server_cert_type(con, cert_type_rpk, sizeof(cert_type_rpk))) {
+ BIO_printf(bio_err, "Error setting server certificate types\n");
+ goto end;
+ }
+ }
+
if (sess_in != NULL) {
SSL_SESSION *sess;
BIO *stmp = BIO_new_file(sess_in, "r");
@@ -3254,6 +3280,23 @@ static void print_stuff(BIO *bio, SSL *s, int full)
} else {
BIO_printf(bio, "no peer certificate available\n");
}
+
+ /* Only display RPK information if configured */
+ if (SSL_get_negotiated_client_cert_type(s) == TLSEXT_cert_type_rpk)
+ BIO_printf(bio, "Client-to-server raw public key negotiated\n");
+ if (SSL_get_negotiated_server_cert_type(s) == TLSEXT_cert_type_rpk)
+ BIO_printf(bio, "Server-to-client raw public key negotiated\n");
+ if (enable_server_rpk) {
+ EVP_PKEY *peer_rpk = SSL_get0_peer_rpk(s);
+
+ if (peer_rpk != NULL) {
+ BIO_printf(bio, "Server raw public key\n");
+ EVP_PKEY_print_public(bio, peer_rpk, 2, NULL);
+ } else {
+ BIO_printf(bio, "no peer rpk available\n");
+ }
+ }
+
print_ca_names(bio, s);
ssl_print_sigalgs(bio, s);
diff --git a/apps/s_server.c b/apps/s_server.c
index e822bcc090..7c18f9ad65 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
@@ -100,6 +100,9 @@ static int use_zc_sendfile = 0;
static const char *session_id_prefix = NULL;
+static const unsigned char cert_type_rpk[] = { TLSEXT_cert_type_rpk, TLSEXT_cert_type_x509 };
+static int enable_client_rpk = 0;
+
#ifndef OPENSSL_NO_DTLS
static int enable_timeouts = 0;
static long socket_mtu;
@@ -720,6 +723,8 @@ typedef enum OPTION_choice {
OPT_HTTP_SERVER_BINMODE, OPT_NOCANAMES, OPT_IGNORE_UNEXPECTED_EOF, OPT_KTLS,
OPT_USE_ZC_SENDFILE,
OPT_TFO, OPT_CERT_COMP,
+ OPT_ENABLE_SERVER_RPK,
+ OPT_ENABLE_CLIENT_RPK,
OPT_R_ENUM,
OPT_S_ENUM,
OPT_V_ENUM,
@@ -971,7 +976,8 @@ const OPTIONS s_server_options[] = {
{"sendfile", OPT_SENDFILE, '-', "Use sendfile to response file with -WWW"},
{"zerocopy_sendfile", OPT_USE_ZC_SENDFILE, '-', "Use zerocopy mode of KTLS sendfile"},
#endif
-
+ {"enable_server_rpk", OPT_ENABLE_SERVER_RPK, '-', "Enable raw public keys (RFC7250) from the server"},
+ {"enable_client_rpk", OPT_ENABLE_CLIENT_RPK, '-', "Enable raw public keys (RFC7250) from the client"},
OPT_R_OPTIONS,
OPT_S_OPTIONS,
OPT_V_OPTIONS,
@@ -1069,6 +1075,7 @@ int s_server_main(int argc, char *argv[])
#endif
int tfo = 0;
int cert_comp = 0;
+ int enable_server_rpk = 0;
/* Init of few remaining global variables */
local_argc = argc;
@@ -1675,6 +1682,12 @@ int s_server_main(int argc, char *argv[])
case OPT_CERT_COMP:
cert_comp = 1;
break;
+ case OPT_ENABLE_SERVER_RPK:
+ enable_server_rpk = 1;
+ break;
+ case OPT_ENABLE_CLIENT_RPK:
+ enable_client_rpk = 1;
+ break;
}
}
@@ -2274,6 +2287,16 @@ int s_server_main(int argc, char *argv[])
if (ctx2 != NULL && !SSL_CTX_compress_certs(ctx2, 0))
BIO_printf(bio_s_out, "Error compressing certs on ctx2\n");
}
+ if (enable_server_rpk)
+ if (!SSL_CTX_set1_server_cert_type(ctx, cert_type_rpk, sizeof(cert_type_rpk))) {
+ BIO_printf(bio_s_out, "Error setting server certificate types\n");
+ goto end;
+ }
+ if (enable_client_rpk)
+ if (!SSL_CTX_set1_client_cert_type(ctx, cert_type_rpk, sizeof(cert_type_rpk))) {
+ BIO_printf(bio_s_out, "Error setting server certificate types\n");
+ goto end;
+ }
if (rev)
server_cb = rev_body;
@@ -3025,6 +3048,19 @@ static void print_connection_info(SSL *con)
dump_cert_text(bio_s_out, peer);
peer = NULL;
}
+ /* Only display RPK information if configured */
+ if (SSL_get_negotiated_server_cert_type(con) == TLSEXT_cert_type_rpk)
+ BIO_printf(bio_s_out, "Server-to-client raw public key negotiated\n");
+ if (SSL_get_negotiated_client_cert_type(con) == TLSEXT_cert_type_rpk)
+ BIO_printf(bio_s_out, "Client-to-server raw public key negotiated\n");
+ if (enable_client_rpk) {
+ EVP_PKEY *client_rpk = SSL_get0_peer_rpk(con);
+
+ if (client_rpk != NULL) {
+ BIO_printf(bio_s_out, "Client raw public key\n");
+ EVP_PKEY_print_public(bio_s_out, client_rpk, 2, NULL);
+ }
+ }
if (SSL_get_shared_ciphers(con, buf, sizeof(buf)) != NULL)
BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf);
@@ -3792,7 +3828,8 @@ static SSL_SESSION *get_session(SSL *ssl, const unsigned char *id, int idlen,
if (idlen == (int)sess->idlen && !memcmp(sess->id, id, idlen)) {
const unsigned char *p = sess->der;
BIO_printf(bio_err, "Lookup session: cache hit\n");
- return d2i_SSL_SESSION(NULL, &p, sess->derlen);
+ return d2i_SSL_SESSION_ex(NULL, &p, sess->derlen, app_get0_libctx(),
+ app_get0_propq());
}
}
BIO_printf(bio_err, "Lookup session: cache miss\n");