summaryrefslogtreecommitdiffstats
path: root/ssl/ssl_local.h
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 /ssl/ssl_local.h
parent5ab3f71a33cb0140fc29ae9244cd4f8331c2f3a5 (diff)
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 'ssl/ssl_local.h')
-rw-r--r--ssl/ssl_local.h65
1 files changed, 64 insertions, 1 deletions
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index 87fb1fd7cf..89b29cb9a9 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -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.
*
@@ -371,6 +371,11 @@
#define CERT_PRIVATE_KEY 2
*/
+/* Certificate Type State */
+# define OSSL_CERT_TYPE_CTOS_NONE 0
+# define OSSL_CERT_TYPE_CTOS_GOOD 1
+# define OSSL_CERT_TYPE_CTOS_ERROR 2
+
/* Post-Handshake Authentication state */
typedef enum {
SSL_PHA_NONE = 0,
@@ -510,6 +515,8 @@ struct ssl_session_st {
* to disable session caching and tickets.
*/
int not_resumable;
+ /* Peer raw public key, if available */
+ EVP_PKEY *peer_rpk;
/* This is the cert and type for the other end. */
X509 *peer;
/* Certificate chain peer sent. */
@@ -684,6 +691,8 @@ typedef enum tlsext_index_en {
TLSEXT_IDX_extended_master_secret,
TLSEXT_IDX_signature_algorithms_cert,
TLSEXT_IDX_post_handshake_auth,
+ TLSEXT_IDX_client_cert_type,
+ TLSEXT_IDX_server_cert_type,
TLSEXT_IDX_signature_algorithms,
TLSEXT_IDX_supported_versions,
TLSEXT_IDX_psk_kex_modes,
@@ -1170,6 +1179,12 @@ struct ssl_ctx_st {
/* certificate compression preferences */
int cert_comp_prefs[TLSEXT_comp_cert_limit];
#endif
+
+ /* Certificate Type stuff - for RPK vs X.509 */
+ unsigned char *client_cert_type;
+ size_t client_cert_type_len;
+ unsigned char *server_cert_type;
+ size_t server_cert_type_len;
};
typedef struct cert_pkey_st CERT_PKEY;
@@ -1651,6 +1666,11 @@ struct ssl_connection_st {
int compress_certificate_from_peer[TLSEXT_comp_cert_limit];
/* indicate that we sent the extension, so we'll accept it */
int compress_certificate_sent;
+
+ uint8_t client_cert_type;
+ uint8_t client_cert_type_ctos;
+ uint8_t server_cert_type;
+ uint8_t server_cert_type_ctos;
} ext;
/*
@@ -1771,6 +1791,12 @@ struct ssl_connection_st {
/* certificate compression preferences */
int cert_comp_prefs[TLSEXT_comp_cert_limit];
#endif
+
+ /* Certificate Type stuff - for RPK vs X.509 */
+ unsigned char *client_cert_type;
+ size_t client_cert_type_len;
+ unsigned char *server_cert_type;
+ size_t server_cert_type_len;
};
# define SSL_CONNECTION_FROM_SSL_ONLY_int(ssl, c) \
@@ -2380,11 +2406,47 @@ struct openssl_ssl_test_functions {
const char *ssl_protocol_to_string(int version);
+static ossl_inline int tls12_rpk_and_privkey(const SSL_CONNECTION *sc, int idx)
+{
+ /*
+ * This is to check for special cases when using RPK with just
+ * a private key, and NO CERTIFICATE
+ */
+ return ((sc->server && sc->ext.server_cert_type == TLSEXT_cert_type_rpk)
+ || (!sc->server && sc->ext.client_cert_type == TLSEXT_cert_type_rpk))
+ && sc->cert->pkeys[idx].privatekey != NULL
+ && sc->cert->pkeys[idx].x509 == NULL;
+}
+
+static ossl_inline int ssl_has_cert_type(const SSL_CONNECTION *sc, unsigned char ct)
+{
+ unsigned char *ptr;
+ size_t len;
+
+ if (sc->server) {
+ ptr = sc->server_cert_type;
+ len = sc->server_cert_type_len;
+ } else {
+ ptr = sc->client_cert_type;
+ len = sc->client_cert_type_len;
+ }
+
+ if (ptr == NULL)
+ return 0;
+
+ return memchr(ptr, ct, len) != NULL;
+}
+
/* Returns true if certificate and private key for 'idx' are present */
static ossl_inline int ssl_has_cert(const SSL_CONNECTION *s, int idx)
{
if (idx < 0 || idx >= (int)s->ssl_pkey_num)
return 0;
+
+ /* If RPK is enabled for this SSL... only require private key */
+ if (ssl_has_cert_type(s, TLSEXT_cert_type_rpk))
+ return s->cert->pkeys[idx].privatekey != NULL;
+
return s->cert->pkeys[idx].x509 != NULL
&& s->cert->pkeys[idx].privatekey != NULL;
}
@@ -2461,6 +2523,7 @@ __owur int ssl_cert_set_current(CERT *c, long arg);
void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg);
__owur int ssl_verify_cert_chain(SSL_CONNECTION *s, STACK_OF(X509) *sk);
+__owur int ssl_verify_rpk(SSL_CONNECTION *s, EVP_PKEY *rpk);
__owur int ssl_build_cert_chain(SSL_CONNECTION *s, SSL_CTX *ctx, int flags);
__owur int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain,
int ref);