919ba00942
Also tweak some of the code in demos/bio, to enable interactive testing of BIO_s_accept's use of SSL_dup. Changed the sconnect client to authenticate the server, which now exercises the new SSL_set1_host() function. Reviewed-by: Richard Levitte <levitte@openssl.org>
278 lines
11 KiB
Text
278 lines
11 KiB
Text
=pod
|
|
|
|
=head1 NAME
|
|
|
|
SSL_CTX_dane_enable, SSL_CTX_dane_mtype_set, SSL_dane_enable,
|
|
SSL_dane_tlsa_add, SSL_get0_dane_authority, SSL_get0_dane_tlsa -
|
|
enable DANE TLS authentication of the remote TLS server in the local
|
|
TLS client
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
#include <openssl/ssl.h>
|
|
|
|
int SSL_CTX_dane_enable(SSL_CTX *ctx);
|
|
int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md,
|
|
uint8_t mtype, uint8_t ord);
|
|
int SSL_dane_enable(SSL *s, const char *basedomain);
|
|
int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector,
|
|
uint8_t mtype, unsigned char *data, size_t dlen);
|
|
int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki);
|
|
int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector,
|
|
uint8_t *mtype, unsigned const char **data,
|
|
size_t *dlen);
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
These functions implement support for DANE TLSA (RFC6698 and RFC7671)
|
|
peer authentication.
|
|
|
|
SSL_CTX_dane_enable() must be called first to initialize the
|
|
shared state required for DANE support. Individual connections
|
|
associated with the context can then enable per-connection DANE
|
|
support as appropriate. DANE authentication is implemented in the
|
|
L<X509_verify_cert(3)> function, and applications that override
|
|
L<X509_verify_cert(3)> via L<SSL_CTX_set_cert_verify_callback(3)>
|
|
are responsible to authenticate the peer chain in whatever manner
|
|
they see fit.
|
|
|
|
SSL_CTX_dane_mtype_set() may then be called zero or more times to
|
|
to adjust the supported digest algorithms. This must be done before
|
|
any SSL handles are created for the context.
|
|
|
|
The B<mtype> argument specifies a DANE TLSA matching type and the
|
|
the B<md> argument specifies the associated digest algorithm handle.
|
|
The B<ord> argument specifies a strength ordinal. Algorithms with
|
|
a larger strength ordinal are considered more secure. Strength
|
|
ordinals are used to implement RFC7671 digest algorithm agility.
|
|
Specifying a B<NULL> digest algorithm for a matching type disables
|
|
support for that matching type. Matching type Full(0) cannot be
|
|
modified or disabled.
|
|
|
|
By default, matching type C<SHA2-256(1)> (see RFC7218 for definitions
|
|
of the DANE TLSA parameter acronyms) is mapped to C<EVP_sha256()>
|
|
with a strength ordinal of C<1> and matching type C<SHA2-512(2)>
|
|
is mapped to C<EVP_sha512()> with a strength ordinal of C<2>.
|
|
|
|
SSL_dane_enable() may be called before the SSL handshake is
|
|
initiated with L<SSL_connect(3)> to enable DANE for that connection.
|
|
(The connection must be associated with a DANE-enabled SSL context).
|
|
The B<basedomain> argument specifies the RFC7671 TLSA base domain,
|
|
which will be the primary peer reference identifier for certificate
|
|
name checks. Additional server names can be specified via
|
|
L<SSL_add1_host(3)>. The B<basedomain> is used as the default SNI
|
|
hint if none has yet been specified via L<SSL_set_tlsext_host_name(3)>.
|
|
|
|
SSL_dane_tlsa_add() may then be called one or more times, to
|
|
load each of the TLSA records that apply to the remote TLS peer.
|
|
(This too must be done prior to the beginning of the SSL handshake).
|
|
The arguments specify the fields of the TLSA record. The B<data>
|
|
field is provided in binary (wire RDATA) form, not the hexadecimal ASCII
|
|
presentation form, with an explicit length passed via B<dlen>.
|
|
A return value of 0 indicates that "unusable" TLSA records
|
|
(with invalid or unsupported parameters) were provided, a negative
|
|
return value indicates an internal error in processing the records.
|
|
If DANE authentication is enabled, but no TLSA records are added
|
|
successfully, authentication will fail, and the handshake may not
|
|
complete, depending on the B<mode> argument of L<SSL_set_verify(3)>
|
|
and any verification callback.
|
|
|
|
SSL_get0_dane_authority() can be used to get more detailed information
|
|
about the matched DANE trust-anchor after successful connection
|
|
completion. The return value is negative if DANE verification
|
|
failed (or was not enabled), 0 if an EE TLSA record directly matched
|
|
the leaf certificate, or a positive number indicating the depth at
|
|
which a TA record matched an issuer certificate.
|
|
|
|
If the B<mcert> argument is not B<NULL> and a TLSA record matched
|
|
a chain certificate, a pointer to the matching certificate is
|
|
returned via B<mcert>. The returned address is a short-term internal
|
|
reference to the certificate and must not be freed by the application.
|
|
Applications that want to retain access to the certificate can call
|
|
L<X509_up_ref(3)> to obtain a long-term reference which must then
|
|
be freed via L<X509_free(3)> once no longer needed.
|
|
|
|
If no TLSA records directly matched any elements of the certificate
|
|
chain, but a DANE-TA(2) SPKI(1) Full(0) record provided the public
|
|
key that signed an element of the chain, then that key is returned
|
|
via B<mspki> argument (if not NULL). In this case the return value
|
|
is the depth of the top-most element of the validated certificate
|
|
chain. As with B<mcert> this is a short-term internal reference,
|
|
and L<EVP_PKEY_up_ref(3)> and L<EVP_PKEY_free(3)> can be used to
|
|
acquire and release long-term references respectively.
|
|
|
|
SSL_get0_dane_tlsa() can be used to retrieve the fields of the
|
|
TLSA record that matched the peer certificate chain. The return
|
|
value indicates the match depth or failure to match just as with
|
|
SSL_get0_dane_authority(). When the return value is non-negative,
|
|
the storage pointed to by the B<usage>, B<selector>, B<mtype> and
|
|
B<data> parameters is updated to the corresponding TLSA record
|
|
fields. The B<data> field is in binary wire form, and is therefore
|
|
not NUL-terminated, its length is returned via the B<dlen> parameter.
|
|
If any of these parameters is NULL, the corresponding field
|
|
is not returned. The B<data> parameter is set to a short-term
|
|
internal-copy of the associated data field and must not be freed
|
|
by the application. Applications that need long-term access to
|
|
this field need to copy the content.
|
|
|
|
=head1 RETURN VALUES
|
|
|
|
The functions SSL_CTX_dane_enable(), SSL_CTX_dane_mtype_set(),
|
|
SSL_dane_enable() and SSL_dane_tlsa_add() return a positive value
|
|
on success. Negative return values indicate resource problems (out
|
|
of memory, etc.) in the SSL library, while a return value of B<0>
|
|
indicates incorrect usage or invalid input, such as an unsupported
|
|
TLSA record certificate usage, selector or matching type. Invalid
|
|
input also includes malformed data, either a digest length that
|
|
does not match the digest algorithm, or a C<Full(0)> (binary ASN.1
|
|
DER form) certificate or a public key that fails to parse.
|
|
|
|
The functions SSL_get0_dane_authority() and SSL_get0_dane_tlsa()
|
|
return a negative value when DANE authentication failed or was not
|
|
enabled, a non-negative value indicates the chain depth at which
|
|
the TLSA record matched a chain certificate, or the depth of the
|
|
top-most certificate, when the TLSA record is a full public key
|
|
that is its signer.
|
|
|
|
=head1 EXAMPLE
|
|
|
|
Suppose "smtp.example.com" is the MX host of the domain "example.com",
|
|
and has DNSSEC-validated TLSA records. The calls below will perform
|
|
DANE authentication and arrange to match either the MX hostname or
|
|
the destination domain name in the SMTP server certificate. Wildcards
|
|
are supported, but must match the entire label. The actual name
|
|
matched in the certificate (which might be a wildcard) is retrieved,
|
|
and must be copied by the application if it is to be retained beyond
|
|
the lifetime of the SSL connection.
|
|
|
|
SSL_CTX *ctx;
|
|
SSL *ssl;
|
|
int num_usable = 0;
|
|
const char *nexthop_domain = "example.com";
|
|
const char *dane_tlsa_domain = "smtp.example.com";
|
|
uint8_t usage, selector, mtype;
|
|
|
|
if ((ctx = SSL_CTX_new(TLS_client_method())) == NULL)
|
|
/* handle error */
|
|
if (SSL_CTX_dane_enable(ctx) <= 0)
|
|
/* handle error */
|
|
|
|
if ((ssl = SSL_new(ctx)) == NULL)
|
|
/* handle error */
|
|
|
|
if (SSL_dane_enable(ssl, dane_tlsa_domain) <= 0)
|
|
/* handle error */
|
|
if (!SSL_add1_host(ssl, nexthop_domain))
|
|
/* handle error */
|
|
SSL_set_hostflags(ssl, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
|
|
|
|
for (... each TLSA record ...) {
|
|
unsigned char *data;
|
|
size_t len;
|
|
int ret;
|
|
|
|
/* set usage, selector, mtype, data, len */
|
|
|
|
/* Opportunistic DANE TLS clients treat usages 0, 1 as unusable. */
|
|
switch (usage) {
|
|
case 0: /* PKIX-TA(0) */
|
|
case 1: /* PKIX-EE(1) */
|
|
continue;
|
|
}
|
|
|
|
ret = SSL_dane_tlsa_add(ssl, usage, selector, mtype, data, len);
|
|
/* free data as approriate */
|
|
|
|
if (ret < 0)
|
|
/* handle SSL library internal error */
|
|
else if (ret == 0)
|
|
/* handle unusable TLSA record */
|
|
else
|
|
++num_usable;
|
|
}
|
|
|
|
/*
|
|
* Opportunistic DANE clients use unauthenticated TLS when all TLSA records
|
|
* are unusable, so continue the handshake even if authentication fails.
|
|
*/
|
|
if (num_usable == 0) {
|
|
int (*cb)(int ok, X509_STORE_CTX *sctx) = NULL;
|
|
|
|
/* Log all records unusable? */
|
|
/* Set cb to a non-NULL callback of your choice? */
|
|
|
|
SSL_set_verify(ssl, SSL_VERIFY_NONE, cb);
|
|
}
|
|
|
|
/* Perform SSL_connect() handshake and handle errors here */
|
|
|
|
if (SSL_get_verify_result(ssl) == X509_V_OK) {
|
|
const char *peername = SSL_get0_peername(ssl);
|
|
EVP_PKEY *mspki = NULL;
|
|
|
|
int depth = SSL_get0_dane_authority(s, NULL, &mspki);
|
|
if (depth >= 0) {
|
|
(void) SSL_get0_dane_tlsa(s, &usage, &selector, &mtype, NULL, NULL);
|
|
printf("DANE TLSA %d %d %d %s at depth %d\n", usage, selector, mtype,
|
|
(mspki != NULL) ? "TA public key verified certificate" :
|
|
depth ? "matched TA certificate" : "matched EE certificate",
|
|
depth);
|
|
}
|
|
if (peername != NULL) {
|
|
/* Name checks were in scope and matched the peername */
|
|
printf(bio, "Verified peername: %s\n", peername);
|
|
}
|
|
} else {
|
|
/*
|
|
* Not authenticated, presumably all TLSA rrs unusable, but possibly a
|
|
* callback suppressed connection termination despite presence of TLSA
|
|
* usable RRs none of which matched. Do whatever is appropriate for
|
|
* unauthenticated connections.
|
|
*/
|
|
}
|
|
|
|
=head1 NOTES
|
|
|
|
It is expected that the majority of clients employing DANE TLS will
|
|
be doing "opportunistic DANE TLS" in the sense of RFC7672 and
|
|
RFC7435. That is, they will use DANE authentication when
|
|
DNSSEC-validated TLSA records are published for a given peer, and
|
|
otherwise will use unauthenticated TLS or even cleartext.
|
|
|
|
Such applications should generally treat any TLSA records published
|
|
by the peer with usages PKIX-TA(0) and PKIX-EE(1) as "unusable",
|
|
and should not include them among the TLSA records used to authenticate
|
|
peer connections. In addition, some TLSA records with supported
|
|
usages may be "unusable" as a result of invalid or unsupported
|
|
parameters.
|
|
|
|
When a peer has TLSA records, but none are "usable", an opportunistic
|
|
application must avoid cleartext, but cannot authenticate the peer,
|
|
and so should generally proceed with an unauthenticated connection.
|
|
Opportunistic applications need to note the return value of each
|
|
call to SSL_dane_tlsa_add(), and if all return 0 (due to invalid
|
|
or unsupported parameters) disable peer authentication by calling
|
|
L<SSL_set_verify(3)> with B<mode> equal to B<SSL_VERIFY_NONE>.
|
|
|
|
=head1 SEE ALSO
|
|
|
|
L<SSL_new(3)>,
|
|
L<SSL_add1_host(3)>,
|
|
L<SSL_set_hostflags(3)>,
|
|
L<SSL_set_tlsext_host_name(3)>,
|
|
L<SSL_set_verify(3)>,
|
|
L<SSL_CTX_set_cert_verify_callback(3)>,
|
|
L<X509_verify_cert(3)>,
|
|
L<SSL_connect(3)>,
|
|
L<SSL_get0_peername(3)>,
|
|
L<EVP_get_digestbyname(3)>,
|
|
L<X509_up_ref(3)>,
|
|
L<X509_free(3)>,
|
|
L<EVP_PKEY_up_ref(3)>,
|
|
L<EVP_PKEY_free(3)>
|
|
|
|
=head1 HISTORY
|
|
|
|
These functions were first added to OpenSSL 1.1.0.
|
|
|
|
=cut
|