Skip to content

Commit

Permalink
first cut at sigalg loading
Browse files Browse the repository at this point in the history
Reviewed-by: Matt Caswell <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl#19312)
  • Loading branch information
baentsch authored and paulidale committed Feb 24, 2023
1 parent 1817dca commit ee58915
Show file tree
Hide file tree
Showing 18 changed files with 3,397 additions and 238 deletions.
9 changes: 9 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ OpenSSL 3.2

*Oliver Mihatsch*

* Added support for pluggable (provider-based) TLS signature algorithms.
This enables TLS 1.3 authentication operations with algorithms embedded
in providers not included by default in OpenSSL. In combination with
the already available pluggable KEM and X.509 support, this enables
for example suitable providers to deliver post-quantum or quantum-safe
cryptography to OpenSSL users.

*Michael Baentsch*

* Added support for Hybrid Public Key Encryption (HPKE) as defined
in RFC9180. HPKE is required for TLS Encrypted ClientHello (ECH),
Message Layer Security (MLS) and other IETF specifications.
Expand Down
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ OpenSSL 3.2
by default.
* TCP Fast Open (RFC7413) support is available on Linux, macOS, and FreeBSD
where enabled and supported.
* Full support for provider-based/pluggable signature algorithms in TLS 1.3
operations as well as X.509 data structure support. With a suitable provider
this fully enables use of post-quantum/quantum-safe cryptography.

OpenSSL 3.1
-----------
Expand Down
3 changes: 2 additions & 1 deletion apps/lib/s_cb.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ static const char *get_sigtype(int nid)
return "gost2012_512";

default:
return NULL;
/* Try to output provider-registered sig alg name */
return OBJ_nid2sn(nid);
}
}

Expand Down
23 changes: 16 additions & 7 deletions crypto/x509/x509_set.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits,

/* Modify *siginf according to alg and sig. Return 1 on success, else 0. */
static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
const ASN1_STRING *sig)
const ASN1_STRING *sig, const EVP_PKEY *pubkey)
{
int pknid, mdnid;
const EVP_MD *md;
Expand All @@ -232,12 +232,20 @@ static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
case NID_undef:
/* If we have one, use a custom handler for this algorithm */
ameth = EVP_PKEY_asn1_find(NULL, pknid);
if (ameth == NULL || ameth->siginf_set == NULL
|| !ameth->siginf_set(siginf, alg, sig)) {
ERR_raise(ERR_LIB_X509, X509_R_ERROR_USING_SIGINF_SET);
return 0;
if (ameth != NULL && ameth->siginf_set != NULL
&& ameth->siginf_set(siginf, alg, sig))
break;
if (pubkey != NULL) {
int secbits;

secbits = EVP_PKEY_get_security_bits(pubkey);
if (secbits != 0) {
siginf->secbits = secbits;
break;
}
}
break;
ERR_raise(ERR_LIB_X509, X509_R_ERROR_USING_SIGINF_SET);
return 0;
/*
* SHA1 and MD5 are known to be broken. Reduce security bits so that
* they're no longer accepted at security level 1.
Expand Down Expand Up @@ -288,5 +296,6 @@ static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
/* Returns 1 on success, 0 on failure */
int ossl_x509_init_sig_info(X509 *x)
{
return x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature);
return x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature,
X509_PUBKEY_get0(x->cert_info.key));
}
123 changes: 123 additions & 0 deletions doc/man7/provider-base.pod
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,129 @@ or maximum. A -1 indicates that the group should not be used in that protocol.

=back

=head3 "TLS-SIGALG" Capability

The "TLS-SIGALG" capability can be queried by libssl to discover the list of
TLS signature algorithms that a provider can support. Each signature supported
can be used for client- or server-authentication in addition to the built-in
signature algorithms.
TLS1.3 clients can advertise the list of TLS signature algorithms they support
in the signature_algorithms extension, and TLS servers can select an algorithm
from the offered list that they also support. In this way a provider can add
to the list of signature algorithms that libssl already supports with
additional ones.

Each TLS signature algorithm that a provider supports should be described via
the callback passed in through the provider_get_capabilities function. Each
algorithm can have the following details supplied:

=over 4

=item "iana-name" (B<OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME>) <UTF8 string>

The name of the signature algorithm as given in the IANA TLS Signature Scheme
registry as "Description":
L<https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-signaturescheme>.
This value must be supplied.

=item "iana-code-point" (B<OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT>) <unsigned integer>

The TLS algorithm ID value as given in the IANA TLS SignatureScheme registry.
This value must be supplied.

=item "sigalg-name" (B<OSSL_CAPABILITY_TLS_SIGALG_NAME>) <UTF8 string>

A name for the full (possibly composite hash-and-signature) signature
algorithm.
The provider may, but is not obligated to, provide a signature implementation
with this name; if it doesn't, this is assumed to be a composite of a pure
signature algorithm and a hash algorithm, which must be given with the
parameters "sig-name" and "hash-name".
This value must be supplied.

=item "sigalg-oid" (B<OSSL_CAPABILITY_TLS_SIGALG_OID>) <UTF8 string>

The OID of the "sigalg-name" algorithm in canonical numeric text form. If
this parameter is given, OBJ_create() will be used to create an OBJ and
a NID for this OID, using the "sigalg-name" parameter for its (short) name.
Otherwise, it's assumed to already exist in the object database, possibly
done by the provider with the core_obj_create() upcall.
This value is optional.

=item "sig-name" (B<OSSL_CAPABILITY_TLS_SIGALG_SIG_NAME>) <UTF8 string>

The name of the pure signature algorithm that is part of a composite
"sigalg-name". If "sigalg-name" is implemented by the provider, this
parameter is redundant and must not be given.
This value is optional.

=item "sig-oid" (B<OSSL_CAPABILITY_TLS_SIGALG_SIG_OID>) <UTF8 string>

The OID of the "sig-name" algorithm in canonical numeric text form. If
this parameter is given, OBJ_create() will be used to create an OBJ and
a NID for this OID, using the "sig-name" parameter for its (short) name.
Otherwise, it is assumed to already exist in the object database. This
can be done by the provider using the core_obj_create() upcall.
This value is optional.

=item "hash-name" (B<OSSL_CAPABILITY_TLS_SIGALG_HASH_NAME>) <UTF8 string>

The name of the hash algorithm that is part of a composite "sigalg-name".
If "sigalg-name" is implemented by the provider, this parameter is redundant
and must not be given.
This value is optional.

=item "hash-oid" (B<OSSL_CAPABILITY_TLS_SIGALG_HASH_OID>) <UTF8 string>

The OID of the "hash-name" algorithm in canonical numeric text form. If
this parameter is given, OBJ_create() will be used to create an OBJ and
a NID for this OID, using the "hash-name" parameter for its (short) name.
Otherwise, it's assumed to already exist in the object database, possibly
done by the provider with the core_obj_create() upcall.
This value is optional.

=item "key-type" (B<OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE>) <UTF8 string>

The key type of the public key of applicable certificates. If this parameter
isn't present, it's assumed to be the same as "sig-name" if that's present,
otherwise "sigalg-name".
This value is optional.

=item "key-type-oid" (B<OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE_OID>) <UTF8 string>

The OID of the "key-type" in canonical numeric text form. If
this parameter is given, OBJ_create() will be used to create an OBJ and
a NID for this OID, using the "key-type" parameter for its (short) name.
Otherwise, it's assumed to already exist in the object database, possibly
done by the provider with the core_obj_create() upcall.
This value is optional.

=item "sec-bits" (B<OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS>) <unsigned integer>

The number of bits of security offered by keys of this algorithm. The number
of bits should be comparable with the ones given in table 2 and 3 of the NIST
SP800-57 document. This number is used to determine the security strength of
the algorithm if no digest algorithm has been registered that otherwise
defines the security strength. If the signature algorithm implements its own
digest internally, this value needs to be set to properly reflect the overall
security strength.
This value must be supplied.

=item "tls-min-tls" (B<OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS>) <integer>

=item "tls-max-tls" (B<OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS>) <integer>

These parameters can be used to describe the minimum and maximum TLS
versions supported by the signature algorithm. The values equate to the
on-the-wire encoding of the various TLS versions. For example TLSv1.3 is
0x0304 (772 decimal), and TLSv1.2 is 0x0303 (771 decimal). A 0 indicates that
there is no defined minimum or maximum. A -1 indicates that the signature
algorithm should not be used in that protocol.
Presently values representing anything other than TLS1.3 mean that the
complete algorithm is ignored.

=back

=head1 NOTES

The core_obj_create() and core_obj_add_sigid() functions were not thread safe
Expand Down
15 changes: 15 additions & 0 deletions include/openssl/core_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,21 @@ extern "C" {
#define OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS "tls-min-dtls"
#define OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS "tls-max-dtls"

/* TLS-SIGALG Capability */
#define OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME "tls-sigalg-iana-name"
#define OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT "tls-sigalg-code-point"
#define OSSL_CAPABILITY_TLS_SIGALG_NAME "tls-sigalg-name"
#define OSSL_CAPABILITY_TLS_SIGALG_OID "tls-sigalg-oid"
#define OSSL_CAPABILITY_TLS_SIGALG_SIG_NAME "tls-sigalg-sig-name"
#define OSSL_CAPABILITY_TLS_SIGALG_SIG_OID "tls-sigalg-sig-oid"
#define OSSL_CAPABILITY_TLS_SIGALG_HASH_NAME "tls-sigalg-hash-name"
#define OSSL_CAPABILITY_TLS_SIGALG_HASH_OID "tls-sigalg-hash-oid"
#define OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE "tls-sigalg-keytype"
#define OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE_OID "tls-sigalg-keytype-oid"
#define OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS "tls-sigalg-sec-bits"
#define OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS "tls-min-tls"
#define OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS "tls-max-tls"

/*-
* storemgmt parameters
*/
Expand Down
8 changes: 5 additions & 3 deletions ssl/s3_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -3366,6 +3366,7 @@ void ssl3_free(SSL *s)
OPENSSL_clear_free(sc->s3.tmp.pms, sc->s3.tmp.pmslen);
OPENSSL_free(sc->s3.tmp.peer_sigalgs);
OPENSSL_free(sc->s3.tmp.peer_cert_sigalgs);
OPENSSL_free(sc->s3.tmp.valid_flags);
ssl3_free_digest_list(sc);
OPENSSL_free(sc->s3.alpn_selected);
OPENSSL_free(sc->s3.alpn_proposed);
Expand All @@ -3390,6 +3391,7 @@ int ssl3_clear(SSL *s)
OPENSSL_clear_free(sc->s3.tmp.pms, sc->s3.tmp.pmslen);
OPENSSL_free(sc->s3.tmp.peer_sigalgs);
OPENSSL_free(sc->s3.tmp.peer_cert_sigalgs);
OPENSSL_free(sc->s3.tmp.valid_flags);

EVP_PKEY_free(sc->s3.tmp.pkey);
EVP_PKEY_free(sc->s3.peer_tmp);
Expand Down Expand Up @@ -4244,7 +4246,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl

if (SSL_CONNECTION_IS_TLS13(s)) {
#ifndef OPENSSL_NO_PSK
int j;
size_t j;

/*
* If we allow "old" style PSK callbacks, and we have no certificate (so
Expand All @@ -4254,8 +4256,8 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl
* that.
*/
if (s->psk_server_callback != NULL) {
for (j = 0; j < SSL_PKEY_NUM && !ssl_has_cert(s, j); j++);
if (j == SSL_PKEY_NUM) {
for (j = 0; j < s->ssl_pkey_num && !ssl_has_cert(s, j); j++);
if (j == s->ssl_pkey_num) {
/* There are no certificates */
prefer_sha256 = 1;
}
Expand Down
Loading

0 comments on commit ee58915

Please sign in to comment.