diff options
author | Viktor Dukhovni <openssl-users@dukhovni.org> | 2015-12-29 13:28:28 -0500 |
---|---|---|
committer | Viktor Dukhovni <openssl-users@dukhovni.org> | 2016-01-05 19:31:49 -0500 |
commit | 919ba009429b3617e975933f37a23be996a33b8d (patch) | |
tree | ffe91f4f27fd4d8b3d3401f1e860212f15c8b993 /doc | |
parent | e29c73c93b88a4b7f492c7c8c7343223e7548612 (diff) |
DANE support structures, constructructors and accessors
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>
Diffstat (limited to 'doc')
-rw-r--r-- | doc/crypto/X509_VERIFY_PARAM_set_flags.pod | 2 | ||||
-rw-r--r-- | doc/ssl/SSL_CTX_dane_enable.pod | 278 | ||||
-rw-r--r-- | doc/ssl/SSL_set1_host.pod | 115 | ||||
-rw-r--r-- | doc/ssl/ssl.pod | 19 |
4 files changed, 413 insertions, 1 deletions
diff --git a/doc/crypto/X509_VERIFY_PARAM_set_flags.pod b/doc/crypto/X509_VERIFY_PARAM_set_flags.pod index df5766cdef..a2219d2aae 100644 --- a/doc/crypto/X509_VERIFY_PARAM_set_flags.pod +++ b/doc/crypto/X509_VERIFY_PARAM_set_flags.pod @@ -127,7 +127,7 @@ IPv6. The condensed "::" notation is supported for IPv6 addresses. X509_VERIFY_PARAM_set_flags(), X509_VERIFY_PARAM_clear_flags(), X509_VERIFY_PARAM_set_purpose(), X509_VERIFY_PARAM_set_trust(), X509_VERIFY_PARAM_add0_policy() X509_VERIFY_PARAM_set1_policies(), -X509_VERIFY_PARAM_set1_host(), X509_VERIFY_PARAM_set_hostflags(), +X509_VERIFY_PARAM_set1_host(), X509_VERIFY_PARAM_add1_host(), X509_VERIFY_PARAM_set1_email(), X509_VERIFY_PARAM_set1_ip() and X509_VERIFY_PARAM_set1_ip_asc() return 1 for success and 0 for failure. diff --git a/doc/ssl/SSL_CTX_dane_enable.pod b/doc/ssl/SSL_CTX_dane_enable.pod new file mode 100644 index 0000000000..66eb1b3d8d --- /dev/null +++ b/doc/ssl/SSL_CTX_dane_enable.pod @@ -0,0 +1,278 @@ +=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 diff --git a/doc/ssl/SSL_set1_host.pod b/doc/ssl/SSL_set1_host.pod new file mode 100644 index 0000000000..b008a5ff6e --- /dev/null +++ b/doc/ssl/SSL_set1_host.pod @@ -0,0 +1,115 @@ +=pod + +=head1 NAME + + SSL_set1_host, SSL_add1_host, SSL_set_hostflags, SSL_get0_peername - + SSL server verification parameters + +=head1 SYNOPSIS + + #include <openssl/ssl.h> + #include <openssl/x509_vfy.h> + + int SSL_set1_host(SSL *s, const char *hostname); + int SSL_add1_host(SSL *s, const char *hostname); + void SSL_set_hostflags(SSL *s, unsigned int flags); + const char *SSL_get0_peername(SSL *s); + +=head1 DESCRIPTION + +These functions configure server hostname checks in the SSL client. + +SSL_set1_host() sets the expected DNS hostname to B<name> clearing +any previously specified host name or names. If B<name> is NULL, +or the empty string the list of hostnames is cleared, and name +checks are not performed on the peer certificate. When a non-empty +B<name> is specified, certificate verification automatically checks +the peer hostname via L<X509_check_host(3)> with B<flags> as specified +via SSL_set_hostflags(). Clients that enable DANE TLSA authentication +via L<SSL_dane_enable(3)> should leave it to that function to set +the primary reference identifier of the peer, and should not call +SSL_set1_host(). + +SSL_add1_host() adds B<name> as an additional reference identifier +that can match the peer's certificate. Any previous names set via +SSL_set1_host() or SSL_add1_host() are retained, no change is made +if B<name> is NULL or empty. When multiple names are configured, +the peer is considered verified when any name matches. This function +is required for DANE TLA in the presence of service name indirection +via CNAME, MX or SRV records as specified in RFC7671, RFC7672 or +RFC7673. + +SSL_set_hostflags() sets the B<flags> that will be passed to +L<X509_check_host(3)> when name checks are applicable, by default +the B<flags> value is 0. See L<X509_check_host(3)> for the list +of available flags and their meaning. + +SSL_get0_peername() returns the DNS hostname or subject CommonName +from the peer certificate that matched one of the reference +identifiers. When wildcard matching is not disabled, the name +matched in the peer certificate may be a wildcard name. When one +of the reference identifiers configured via SSL_set1_host() or +SSL_add1_host() starts with ".", which indicates a parent domain prefix +rather than a fixed name, the matched peer name may be a sub-domain +of the reference identifier. The returned string is allocated by +the library and is no longer valid once the associated B<ssl> handle +is cleared or freed, or a renegotiation takes place. Applications +must not free the return value. + +SSL clients are advised to use these functions in preference to +explicitly calling L<X509_check_host(3)>. Hostname checks are out +of scope with the RFC7671 DANE-EE(3) certificate usage, and the +internal check will be suppressed as appropriate when DANE is +enabled. + +=head1 RETURN VALUES + +SSL_set1_host() and SSL_add1_host() return 1 for success and 0 for +failure. + +SSL_get0_peername() returns NULL if peername verification is not +applicable (as with RFC7671 DANE-EE(3)), or no trusted peername was +matched. Otherwise, it returns the matched peername. To determine +whether verification succeeded call L<SSL_get_verify_result(3)>. + +=head1 NOTES + +=head1 EXAMPLE + +Suppose "smtp.example.com" is the MX host of the domain "example.com". +The calls below will 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_set_hostflags(ssl, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); + if (!SSL_set1_host(ssl, "smtp.example.com")) { + /* handle error */ + } + if (!SSL_add1_host(ssl, "example.com")) { + /* handle error */ + } + + /* XXX: Perform SSL_connect() handshake and handle errors here */ + + if (SSL_get_verify_result(ssl) == X509_V_OK) { + const char *peername = SSL_get0_peername(ssl); + + if (peername != NULL) { + /* Name checks were in scope and matched the peername */ + } + } + +=head1 SEE ALSO + +L<X509_check_host(3)>, +L<SSL_get_verify_result(3)>. +L<SSL_dane_enable(3)>. + +=head1 HISTORY + +These functions were first added to OpenSSL 1.1.0. + +=cut diff --git a/doc/ssl/ssl.pod b/doc/ssl/ssl.pod index adcec5ffa9..bb3bc94809 100644 --- a/doc/ssl/ssl.pod +++ b/doc/ssl/ssl.pod @@ -447,6 +447,25 @@ success or 0 on failure. =item SSL *B<SSL_dup>(SSL *ssl); +SSL_dup() allows applications to configure an SSL handle for use +in multiple SSL connections, and then duplicate it prior to initiating +each connection with the duplicated handle. +Use of SSL_dup() avoids the need to repeat the configuration of the +handles for each connection. +This is used internally by L<BIO_s_accept(3)> to construct +per-connection SSL handles after L<accept(2)>. + +For SSL_dup() to work, the connection MUST be in its initial state +and MUST NOT have not yet have started the SSL handshake. +For connections that are not in their initial state SSL_dup() just +increments an internal reference count and returns the I<same> +handle. +It may be possible to use L<SSL_clear(3)> to recycle an SSL handle +that is not in its initial state for re-use, but this is best +avoided. +Instead, save and restore the session, if desired, and construct a +fresh handle for each connection. + =item STACK *B<SSL_dup_CA_list>(STACK *sk); =item void B<SSL_free>(SSL *ssl); |