提交 919ba009 编写于 作者: V Viktor Dukhovni

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: NRichard Levitte <levitte@openssl.org>
上级 e29c73c9
......@@ -70,6 +70,7 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/objects.h>
#include <internal/dane.h>
#include <internal/x509_int.h>
#include "x509_lcl.h"
......@@ -2072,6 +2073,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
ctx->current_reasons = 0;
ctx->tree = NULL;
ctx->parent = NULL;
ctx->dane = NULL;
/* Zero ex_data to make sure we're cleanup-safe */
memset(&ctx->ex_data, 0, sizeof(ctx->ex_data));
......@@ -2263,6 +2265,11 @@ void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
ctx->param = param;
}
void X509_STORE_CTX_set0_dane(X509_STORE_CTX *ctx, struct dane_st *dane)
{
ctx->dane = dane;
}
static int build_chain(X509_STORE_CTX *ctx)
{
int (*cb) (int, X509_STORE_CTX *) = ctx->verify_cb;
......
......@@ -444,6 +444,24 @@ char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
return param->peername;
}
/*
* Move peername from one param structure to another, freeing any name present
* at the target. If the source is a NULL parameter structure, free and zero
* the target peername.
*/
void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *to,
X509_VERIFY_PARAM *from)
{
char *peername = (from != NULL) ? from->peername : NULL;
if (to->peername != peername) {
OPENSSL_free(to->peername);
to->peername = peername;
}
if (from)
from->peername = NULL;
}
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
const char *email, size_t emaillen)
{
......
#include <string.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
......@@ -56,7 +57,7 @@ int main(int argc, char **argv)
if (!SSL_CONF_CTX_finish(cctx)) {
fprintf(stderr, "Finish error\n");
ERR_print_errors_fp(stderr);
goto err;
goto end;
}
/*
......
#include <string.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/conf.h>
......@@ -64,7 +65,7 @@ int main(int argc, char **argv)
if (!SSL_CONF_CTX_finish(cctx)) {
fprintf(stderr, "Finish error\n");
ERR_print_errors_fp(stderr);
goto err;
goto end;
}
/*
......
......@@ -18,16 +18,30 @@
#define CERT_FILE "server.pem"
BIO *in = NULL;
static int done = 0;
void close_up()
void interrupt()
{
BIO_free(in);
done = 1;
}
void sigsetup(void)
{
struct sigaction sa;
/*
* Catch at most once, and don't restart the accept system call.
*/
sa.sa_flags = SA_RESETHAND;
sa.sa_handler = interrupt;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);
}
int main(int argc, char *argv[])
{
char *port = NULL;
BIO *in = NULL;
BIO *ssl_bio, *tmp;
SSL_CTX *ctx;
char buf[512];
......@@ -38,15 +52,13 @@ int main(int argc, char *argv[])
else
port = argv[1];
signal(SIGINT, close_up);
SSL_load_error_strings();
/* Add ciphers and message digests */
OpenSSL_add_ssl_algorithms();
ctx = SSL_CTX_new(TLS_server_method());
if (!SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
if (!SSL_CTX_use_certificate_chain_file(ctx, CERT_FILE))
goto err;
if (!SSL_CTX_use_PrivateKey_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
goto err;
......@@ -66,6 +78,9 @@ int main(int argc, char *argv[])
*/
BIO_set_accept_bios(in, ssl_bio);
/* Arrange to leave server loop on interrupt */
sigsetup();
again:
/*
* The first call will setup the accept socket, and the second will get a
......@@ -76,7 +91,7 @@ int main(int argc, char *argv[])
if (BIO_do_accept(in) <= 0)
goto err;
for (;;) {
while (!done) {
i = BIO_read(in, buf, 512);
if (i == 0) {
/*
......
......@@ -11,27 +11,38 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#define HOSTPORT "localhost:4433"
#define CAFILE "root.pem"
extern int errno;
int main(argc, argv)
int argc;
char *argv[];
{
char *host;
BIO *out;
const char *hostport = HOSTPORT;
const char *CAfile = CAFILE;
char *hostname;
char *cp;
BIO *out = NULL;
char buf[1024 * 10], *p;
SSL_CTX *ssl_ctx = NULL;
SSL *ssl;
BIO *ssl_bio;
int i, len, off, ret = 1;
if (argc <= 1)
host = "localhost:4433";
else
host = argv[1];
if (argc > 1)
hostport = argv[1];
if (argc > 2)
CAfile = argv[2];
hostname = OPENSSL_strdup(hostport);
if ((cp = strchr(hostname, ':')) != NULL)
*cp = 0;
#ifdef WATT32
dbug_init();
......@@ -45,17 +56,25 @@ char *argv[];
OpenSSL_add_ssl_algorithms();
ssl_ctx = SSL_CTX_new(TLS_client_method());
/* Enable trust chain verification */
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_load_verify_locations(ssl_ctx, CAfile, NULL);
/* Lets make a SSL structure */
ssl = SSL_new(ssl_ctx);
SSL_set_connect_state(ssl);
/* Enable peername verification */
if (SSL_set1_host(ssl, hostname) <= 0)
goto err;
/* Use it inside an SSL BIO */
ssl_bio = BIO_new(BIO_f_ssl());
BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);
/* Lets use a connect BIO under the SSL BIO */
out = BIO_new(BIO_s_connect());
BIO_set_conn_hostname(out, host);
BIO_set_conn_hostname(out, hostport);
BIO_set_nbio(out, 1);
out = BIO_push(ssl_bio, out);
......
subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Server Cert
issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA
-----BEGIN CERTIFICATE-----
MIIDpTCCAo2gAwIBAgIJAK8ArbvjIOQlMA0GCSqGSIb3DQEBCwUAMHAxCzAJBgNV
MIIDyTCCArGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJVSzEW
MBQGA1UECgwNT3BlblNTTCBHcm91cDEiMCAGA1UECwwZRk9SIFRFU1RJTkcgUFVS
UE9TRVMgT05MWTElMCMGA1UEAwwcT3BlblNTTCBUZXN0IEludGVybWVkaWF0ZSBD
QTAgFw0xNjAxMDQwODU0NDZaGA8yMTE2MDEwNTA4NTQ0NlowZDELMAkGA1UEBhMC
VUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBURVNUSU5H
IFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgU2VydmVyIENlcnQwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDzhPOSNtyyRspmeuUpxfNJKCLTuf7g
3uQ4zu4iHOmRO5TQci+HhVlLZrHF9XqFXcIP0y4pWDbMSGuiorUmzmfiR7bfSdI/
+qIQt8KXRH6HNG1t8ou0VSvWId5TS5Dq/er5ODUr9OaaDva7EquHIcMvvPQGuI+O
EAcnleVCy9HVEIySrO4P3CNIicnGkwwiAud05yUAq/gPXBC1hTtmlPD7TVcGVSEi
Jdvzqqlgv02qedGrkki6GY4S7GjZxrrf7Foc2EP+51LJzwLQx3/JfrCU41NEWAsu
/Sl0tQabXESN+zJ1pDqoZ3uHMgpQjeGiE0olr+YcsSW/tJmiU9OiAr8RAgMBAAGj
eDB2MB0GA1UdDgQWBBSCvM8AABPR9zklmifnr9LvIBturDAfBgNVHSMEGDAWgBQ2
w2yI55X+sL3szj49hqshgYfa2jAJBgNVHRMEAjAAMBMGA1UdJQQMMAoGCCsGAQUF
BwMBMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAC78R
sAr4uvkYOu/pSwQ3MYOFqZ0BnPuP0/AZW2zF7TLNy8g36GyH9rKxz2ffQEHRmPQN
Z11Ohg3z03jw/sVzkgt2U5Ipv923sSeCZcu0nuNex3v9/x72ldYikZNhQOsw+2kr
hx3OvE9R7xl9eyjz7BknsbY7PC3kiUY8SDdc5Fr/XMkHm3ge65oWYOHBjC5tAr5K
FGCEjM3syxS+Li5X6yfDGiVSjOU4gJuZDCYbl7cEQexU2deds8EmpJJrrI7s4JcQ
rraHI8+Hu8X9VLpZE1jl/fKJw3D0i53PoN2WhukIOg1Zv+ajMKQ4ubVfISH2ebox
+ybAZO8hxL6/I08/GQ==
-----END CERTIFICATE-----
subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA
issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Root CA
-----BEGIN CERTIFICATE-----
MIIDvjCCAqagAwIBAgIJAPzCy4CUW9/qMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV
BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT
VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt
ZWRpYXRlIENBMB4XDTE1MDcxNDEzMjIwNVoXDTI1MDUyMjEzMjIwNVowZDELMAkG
A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU
RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgU2VydmVyIENlcnQw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDzhPOSNtyyRspmeuUpxfNJ
KCLTuf7g3uQ4zu4iHOmRO5TQci+HhVlLZrHF9XqFXcIP0y4pWDbMSGuiorUmzmfi
R7bfSdI/+qIQt8KXRH6HNG1t8ou0VSvWId5TS5Dq/er5ODUr9OaaDva7EquHIcMv
vPQGuI+OEAcnleVCy9HVEIySrO4P3CNIicnGkwwiAud05yUAq/gPXBC1hTtmlPD7
TVcGVSEiJdvzqqlgv02qedGrkki6GY4S7GjZxrrf7Foc2EP+51LJzwLQx3/JfrCU
41NEWAsu/Sl0tQabXESN+zJ1pDqoZ3uHMgpQjeGiE0olr+YcsSW/tJmiU9OiAr8R
AgMBAAGjTjBMMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCwGCWCGSAGG
+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0B
AQsFAAOCAQEAq8v8dvU3Xskb7q5LKbLXxTIF6owFs5uLk2k2msEAQzX7SrYFZwdE
5e33S71rpDbXiJjyD4Yj0Av5yeRlW0YVFlBZAwgPn29CDCD6+DeQ7AwtXvJhcq9e
llTLpB1EuXC5UCerQmq99wmfTrK0q4hgK7/5c7mcoD7V1iOEvxI2kmG6ukIupbKi
P1TNVVET1kPhRG1dFP9rge7j2ssY3/H+j3jlAJnwQQoYg+YCZ6g0atjOrqvywAy3
5E2d9LPF3TKw2mf4mAxjU6hPDOk0tiMS6g1xdHyeTftPXfN8Gli0T0LpNpy5a24B
dLPqZEpj0kXT8gTYEROX7tq9gYwpe6FVKw==
VElORyBQVVJQT1NFUyBPTkxZMR0wGwYDVQQDDBRPcGVuU1NMIFRlc3QgUm9vdCBD
QTAeFw0xNTA3MTQxMzIyMDVaFw0yNTA2MjExMzIyMDVaMHAxCzAJBgNVBAYTAlVL
MRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVTVElORyBQ
VVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJtZWRpYXRl
IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsErw75CmLYD6pkrG
W/YhAl/K8L5wJYxDjqu2FghxjD8K308W3EHq4uBxEwR1OHXaM1+6ZZw7/r2I37VL
IdurBEAIEUdbzx0so74FPawgz5EW2CTqoJnK8F71/vo5Kj1VPwW46CxwxUR3cfvJ
GNXND2ip0TcyTSPLROXOyQakcVfIGJmdSa1wHKi+c2gMA4emADudZUOYLrg80gr2
ldePm07ynbVsKKzCcStw8MdmoW9Qt3fLnPJn2TFUUBNWj+4kvL+88edWCVQXKNds
ysD/CDrH4W/hjyPDStVsM6XpiNU0+L2ZY6fcj3OP8d0goOx45xotMn9m8hNkCGsr
VXx9IwIDAQABo2MwYTAdBgNVHQ4EFgQUNsNsiOeV/rC97M4+PYarIYGH2towHwYD
VR0jBBgwFoAUjBkP10IxdwUG4dOxn+s5+3hxOkUwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAANQT0pDWBQoT/RY76xz
audadGz/dfYnwvSwT0RMFcXLcMVVRNqP0HeR8OP8qLaP7onRbNnEXNfos9pxXYlg
j+/WjWTBLVcr3pX2Xtmcaqw3CGN9qbQI8B3JkYeijZmc5+3r5MzK/9R0w8Y/T9Xt
CXEiQhtWHpPrFEfrExeVy2kjJNRctEfq3OTd1bjgX64zvTU7eR+MHFYKPoyMqwIR
gjoVKinvovEwWoZe5kfMQwJNA3IgoJexX9BXbS8efAYF/ku3tS0laoZS/q6V/o5I
RvG0OqnNgxhul+96PE5ujSaprsyvBswIUKt+e/BCxGaS6f2AJ8RmtoPOSfT4b9qN
thI=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA84TzkjbcskbKZnrlKcXzSSgi07n+4N7kOM7uIhzpkTuU0HIv
......
......@@ -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.
......
=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
=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
......@@ -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);
......
/* dane.h */
/*
* Written by Viktor Dukhovni (viktor@openssl.org) for the OpenSSL project
* 2015.
*/
/* ====================================================================
* Copyright (c) 2015 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#ifndef HEADER_INTERNAL_DANE_H
#define HEADER_INTERNAL_DANE_H
#include <openssl/safestack.h>
/*-
* Certificate usages:
* https://tools.ietf.org/html/rfc6698#section-2.1.1
*/
#define DANETLS_USAGE_PKIX_TA 0
#define DANETLS_USAGE_PKIX_EE 1
#define DANETLS_USAGE_DANE_TA 2
#define DANETLS_USAGE_DANE_EE 3
#define DANETLS_USAGE_LAST DANETLS_USAGE_DANE_EE
/*-
* Selectors:
* https://tools.ietf.org/html/rfc6698#section-2.1.2
*/
#define DANETLS_SELECTOR_CERT 0
#define DANETLS_SELECTOR_SPKI 1
#define DANETLS_SELECTOR_LAST DANETLS_SELECTOR_SPKI
/*-
* Matching types:
* https://tools.ietf.org/html/rfc6698#section-2.1.3
*/
#define DANETLS_MATCHING_FULL 0
#define DANETLS_MATCHING_2256 1
#define DANETLS_MATCHING_2512 2
#define DANETLS_MATCHING_LAST DANETLS_MATCHING_2512
typedef struct danetls_record_st {
uint8_t usage;
uint8_t selector;
uint8_t mtype;
unsigned char *data;
size_t dlen;
EVP_PKEY *spki;
} danetls_record;
/*
* Shared DANE context
*/
struct dane_ctx_st {
const EVP_MD **mdevp; /* mtype -> digest */
uint8_t *mdord; /* mtype -> preference */
uint8_t mdmax; /* highest supported mtype */
};
/*
* Per connection DANE state
*/
struct dane_st {
struct dane_ctx_st *dctx;
STACK_OF(danetls_record) *trecs;
STACK_OF(X509) *certs; /* DANE-TA(2) Cert(0) Full(0) certs */
danetls_record *mtlsa; /* Matching TLSA record */
X509 *mcert; /* DANE matched cert */
uint32_t umask; /* Usages present */
int mdpth; /* Depth of matched cert */
int pdpth; /* Depth of PKIX trust */
};
#define DANETLS_ENABLED(dane) ((dane) && ((dane)->trecs != NULL))
#define DANETLS_USAGE_BIT(u) (((uint32_t)1) << u)
#define DANETLS_PKIX_TA_MASK (DANETLS_USAGE_BIT(DANETLS_USAGE_PKIX_TA))
#define DANETLS_PKIX_EE_MASK (DANETLS_USAGE_BIT(DANETLS_USAGE_PKIX_EE))
#define DANETLS_DANE_TA_MASK (DANETLS_USAGE_BIT(DANETLS_USAGE_DANE_TA))
#define DANETLS_DANE_EE_MASK (DANETLS_USAGE_BIT(DANETLS_USAGE_DANE_EE))
#define DANETLS_PKIX_MASK (DANETLS_PKIX_TA_MASK | DANETLS_PKIX_EE_MASK)
#define DANETLS_DANE_MASK (DANETLS_DANE_TA_MASK | DANETLS_DANE_EE_MASK)
#define DANETLS_TA_MASK (DANETLS_PKIX_TA_MASK | DANETLS_DANE_TA_MASK)
#define DANETLS_EE_MASK (DANETLS_PKIX_EE_MASK | DANETLS_DANE_EE_MASK)
#define DANETLS_HAS_PKIX(dane) ((dane) && ((dane)->umask & DANETLS_PKIX_MASK))
#define DANETLS_HAS_DANE(dane) ((dane) && ((dane)->umask & DANETLS_DANE_MASK))
#define DANETLS_HAS_TA(dane) ((dane) && ((dane)->umask & DANETLS_TA_MASK))
#define DANETLS_HAS_EE(dane) ((dane) && ((dane)->umask & DANETLS_EE_MASK))
#define DANETLS_HAS_PKIX_TA(dane) ((dane)&&((dane)->umask & DANETLS_PKIX_TA_MASK))
#define DANETLS_HAS_PKIX_EE(dane) ((dane)&&((dane)->umask & DANETLS_PKIX_EE_MASK))
#define DANETLS_HAS_DANE_TA(dane) ((dane)&&((dane)->umask & DANETLS_DANE_TA_MASK))
#define DANETLS_HAS_DANE_EE(dane) ((dane)&&((dane)->umask & DANETLS_DANE_EE_MASK))
#endif /* HEADER_INTERNAL_DANE_H */
......@@ -2045,6 +2045,29 @@ DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
# define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
# define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
# define sk_danetls_record_new(cmp) SKM_sk_new(danetls_record, (cmp))
# define sk_danetls_record_new_null() SKM_sk_new_null(danetls_record)
# define sk_danetls_record_free(st) SKM_sk_free(danetls_record, (st))
# define sk_danetls_record_num(st) SKM_sk_num(danetls_record, (st))
# define sk_danetls_record_value(st, i) SKM_sk_value(danetls_record, (st), (i))
# define sk_danetls_record_set(st, i, val) SKM_sk_set(danetls_record, (st), (i), (val))
# define sk_danetls_record_zero(st) SKM_sk_zero(danetls_record, (st))
# define sk_danetls_record_push(st, val) SKM_sk_push(danetls_record, (st), (val))
# define sk_danetls_record_unshift(st, val) SKM_sk_unshift(danetls_record, (st), (val))
# define sk_danetls_record_find(st, val) SKM_sk_find(danetls_record, (st), (val))
# define sk_danetls_record_find_ex(st, val) SKM_sk_find_ex(danetls_record, (st), (val))
# define sk_danetls_record_delete(st, i) SKM_sk_delete(danetls_record, (st), (i))
# define sk_danetls_record_delete_ptr(st, ptr) SKM_sk_delete_ptr(danetls_record, (st), (ptr))
# define sk_danetls_record_insert(st, val, i) SKM_sk_insert(danetls_record, (st), (val), (i))
# define sk_danetls_record_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(danetls_record, (st), (cmp))
# define sk_danetls_record_dup(st) SKM_sk_dup(danetls_record, st)
# define sk_danetls_record_pop_free(st, free_func) SKM_sk_pop_free(danetls_record, (st), (free_func))
# define sk_danetls_record_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(danetls_record, (st), (copy_func), (free_func))
# define sk_danetls_record_shift(st) SKM_sk_shift(danetls_record, (st))
# define sk_danetls_record_pop(st) SKM_sk_pop(danetls_record, (st))
# define sk_danetls_record_sort(st) SKM_sk_sort(danetls_record, (st))
# define sk_danetls_record_is_sorted(st) SKM_sk_is_sorted(danetls_record, (st))
# define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp))
# define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple)
# define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st))
......
......@@ -327,6 +327,8 @@ typedef struct ssl_conf_ctx_st SSL_CONF_CTX;
DECLARE_STACK_OF(SSL_CIPHER)
DECLARE_STACK_OF(danetls_record)
/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/
typedef struct srtp_protection_profile_st {
const char *name;
......@@ -1533,6 +1535,27 @@ __owur int SSL_set_purpose(SSL *s, int purpose);
__owur int SSL_CTX_set_trust(SSL_CTX *s, int trust);
__owur int SSL_set_trust(SSL *s, int trust);
__owur int SSL_set1_host(SSL *s, const char *hostname);
__owur int SSL_add1_host(SSL *s, const char *hostname);
__owur const char *SSL_get0_peername(SSL *s);
void SSL_set_hostflags(SSL *s, unsigned int flags);
__owur int SSL_CTX_dane_enable(SSL_CTX *ctx);
__owur int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md,
uint8_t mtype, uint8_t ord);
__owur int SSL_dane_enable(SSL *s, const char *basedomain);
__owur int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector,
uint8_t mtype, unsigned char *data, size_t dlen);
__owur int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki);
__owur int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector,
uint8_t *mtype, unsigned const char **data,
size_t *dlen);
/*
* Bridge opacity barrier between libcrypt and libssl, also needed to support
* offline testing in test/danetest.c
*/
struct dane_st *SSL_get0_dane(SSL *ssl);
__owur int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
__owur int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
......@@ -1919,6 +1942,9 @@ void ERR_load_SSL_strings(void);
/* Function codes. */
# define SSL_F_CHECK_SUITEB_CIPHER_LIST 331
# define SSL_F_D2I_SSL_SESSION 103
# define SSL_F_DANE_CTX_ENABLE 347
# define SSL_F_DANE_MTYPE_SET 393
# define SSL_F_DANE_TLSA_ADD 394
# define SSL_F_DO_DTLS1_WRITE 245
# define SSL_F_DO_SSL3_WRITE 104
# define SSL_F_DTLS1_ACCEPT 246
......@@ -2059,6 +2085,7 @@ void ERR_load_SSL_strings(void);
# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE 179
# define SSL_F_SSL_CTX_USE_SERVERINFO 336
# define SSL_F_SSL_CTX_USE_SERVERINFO_FILE 337
# define SSL_F_SSL_DANE_ENABLE 395
# define SSL_F_SSL_DO_CONFIG 391
# define SSL_F_SSL_DO_HANDSHAKE 180
# define SSL_F_SSL_GET_NEW_SESSION 181
......@@ -2232,8 +2259,20 @@ void ERR_load_SSL_strings(void);
# define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307
# define SSL_R_COMPRESSION_LIBRARY_ERROR 142
# define SSL_R_CONNECTION_TYPE_NOT_SET 144
# define SSL_R_CONTEXT_NOT_DANE_ENABLED 167
# define SSL_R_COOKIE_GEN_CALLBACK_FAILURE 400
# define SSL_R_COOKIE_MISMATCH 308
# define SSL_R_DANE_ALREADY_ENABLED 172
# define SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL 173
# define SSL_R_DANE_NOT_ENABLED 175
# define SSL_R_DANE_TLSA_BAD_CERTIFICATE 180
# define SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE 184
# define SSL_R_DANE_TLSA_BAD_DATA_LENGTH 189
# define SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH 192
# define SSL_R_DANE_TLSA_BAD_MATCHING_TYPE 200
# define SSL_R_DANE_TLSA_BAD_PUBLIC_KEY 201
# define SSL_R_DANE_TLSA_BAD_SELECTOR 202
# define SSL_R_DANE_TLSA_NULL_DATA 203
# define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145
# define SSL_R_DATA_LENGTH_TOO_LONG 146
# define SSL_R_DECRYPTION_FAILED 147
......@@ -2253,6 +2292,7 @@ void ERR_load_SSL_strings(void);
# define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354
# define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150
# define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151
# define SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN 204
# define SSL_R_EXCESSIVE_MESSAGE_SIZE 152
# define SSL_R_EXTRA_DATA_IN_MESSAGE 153
# define SSL_R_FAILED_TO_INIT_ASYNC 405
......
......@@ -263,6 +263,7 @@ struct x509_store_ctx_st { /* X509_STORE_CTX */
/* For CRL path validation: parent context */
X509_STORE_CTX *parent;
CRYPTO_EX_DATA ex_data;
struct dane_st *dane;
} /* X509_STORE_CTX */ ;
void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
......@@ -528,6 +529,12 @@ X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
/*
* Bridge opacity barrier between libcrypt and libssl, also needed to support
* offline testing in test/danetest.c
*/
void X509_STORE_CTX_set0_dane(X509_STORE_CTX *ctx, struct dane_st *dane);
/* X509_VERIFY_PARAM functions */
X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
......@@ -558,6 +565,7 @@ int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
unsigned int flags);
char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *);
void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *, X509_VERIFY_PARAM *);
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
const char *email, size_t emaillen);
int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
......
......@@ -208,15 +208,6 @@ int RECORD_LAYER_set_data(RECORD_LAYER *rl, const unsigned char *buf, int len)
return 1;
}
void RECORD_LAYER_dup(RECORD_LAYER *dst, RECORD_LAYER *src)
{
/*
* Currently only called from SSL_dup...which only seems to expect the
* rstate to be duplicated and nothing else from the RECORD_LAYER???
*/
dst->rstate = src->rstate;
}
void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl)
{
memset(rl->read_sequence, 0, sizeof(rl->read_sequence));
......
......@@ -321,7 +321,6 @@ void RECORD_LAYER_release(RECORD_LAYER *rl);
int RECORD_LAYER_read_pending(RECORD_LAYER *rl);
int RECORD_LAYER_write_pending(RECORD_LAYER *rl);
int RECORD_LAYER_set_data(RECORD_LAYER *rl, const unsigned char *buf, int len);
void RECORD_LAYER_dup(RECORD_LAYER *dst, RECORD_LAYER *src);
void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl);
void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl);
int RECORD_LAYER_setup_comp_buffer(RECORD_LAYER *rl);
......
......@@ -486,6 +486,7 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
int i;
X509_STORE *verify_store;
X509_STORE_CTX ctx;
X509_VERIFY_PARAM *param;
if (s->cert->verify_store)
verify_store = s->cert->verify_store;
......@@ -500,10 +501,16 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB);
return (0);
}
param = X509_STORE_CTX_get0_param(&ctx);
/* Set suite B flags if needed */
X509_STORE_CTX_set_flags(&ctx, tls1_suiteb(s));
X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s);
/* Verify via DANE if enabled */
if (DANETLS_ENABLED(&s->dane))
X509_STORE_CTX_set0_dane(&ctx, &s->dane);
/*
* We need to inherit the verify parameters. These can be determined by
* the context: if its a server it will verify SSL client certificates or
......@@ -512,9 +519,9 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server");
/*
* Anything non-default in "param" should overwrite anything in the ctx.
* Anything non-default in "s->param" should overwrite anything in the ctx.
*/
X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
X509_VERIFY_PARAM_set1(param, s->param);
if (s->verify_callback)
X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
......@@ -534,6 +541,10 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
}
s->verify_result = ctx.error;
/* Move peername from the store context params to the SSL handle's */
X509_VERIFY_PARAM_move_peername(s->param, param);
X509_STORE_CTX_cleanup(&ctx);
return (i);
......
......@@ -72,6 +72,9 @@
static ERR_STRING_DATA SSL_str_functs[] = {
{ERR_FUNC(SSL_F_CHECK_SUITEB_CIPHER_LIST), "check_suiteb_cipher_list"},
{ERR_FUNC(SSL_F_D2I_SSL_SESSION), "d2i_SSL_SESSION"},
{ERR_FUNC(SSL_F_DANE_CTX_ENABLE), "dane_ctx_enable"},
{ERR_FUNC(SSL_F_DANE_MTYPE_SET), "dane_mtype_set"},
{ERR_FUNC(SSL_F_DANE_TLSA_ADD), "dane_tlsa_add"},
{ERR_FUNC(SSL_F_DO_DTLS1_WRITE), "do_dtls1_write"},
{ERR_FUNC(SSL_F_DO_SSL3_WRITE), "DO_SSL3_WRITE"},
{ERR_FUNC(SSL_F_DTLS1_ACCEPT), "dtls1_accept"},
......@@ -262,6 +265,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
{ERR_FUNC(SSL_F_SSL_CTX_USE_SERVERINFO), "SSL_CTX_use_serverinfo"},
{ERR_FUNC(SSL_F_SSL_CTX_USE_SERVERINFO_FILE),
"SSL_CTX_use_serverinfo_file"},
{ERR_FUNC(SSL_F_SSL_DANE_ENABLE), "SSL_dane_enable"},
{ERR_FUNC(SSL_F_SSL_DO_CONFIG), "ssl_do_config"},
{ERR_FUNC(SSL_F_SSL_DO_HANDSHAKE), "SSL_do_handshake"},
{ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION), "ssl_get_new_session"},
......@@ -491,9 +495,25 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
{ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR),
"compression library error"},
{ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET), "connection type not set"},
{ERR_REASON(SSL_R_CONTEXT_NOT_DANE_ENABLED), "context not dane enabled"},
{ERR_REASON(SSL_R_COOKIE_GEN_CALLBACK_FAILURE),
"cookie gen callback failure"},
{ERR_REASON(SSL_R_COOKIE_MISMATCH), "cookie mismatch"},
{ERR_REASON(SSL_R_DANE_ALREADY_ENABLED), "dane already enabled"},
{ERR_REASON(SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL),
"dane cannot override mtype full"},
{ERR_REASON(SSL_R_DANE_NOT_ENABLED), "dane not enabled"},
{ERR_REASON(SSL_R_DANE_TLSA_BAD_CERTIFICATE), "dane tlsa bad certificate"},
{ERR_REASON(SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE),
"dane tlsa bad certificate usage"},
{ERR_REASON(SSL_R_DANE_TLSA_BAD_DATA_LENGTH), "dane tlsa bad data length"},
{ERR_REASON(SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH),
"dane tlsa bad digest length"},
{ERR_REASON(SSL_R_DANE_TLSA_BAD_MATCHING_TYPE),
"dane tlsa bad matching type"},
{ERR_REASON(SSL_R_DANE_TLSA_BAD_PUBLIC_KEY), "dane tlsa bad public key"},
{ERR_REASON(SSL_R_DANE_TLSA_BAD_SELECTOR), "dane tlsa bad selector"},
{ERR_REASON(SSL_R_DANE_TLSA_NULL_DATA), "dane tlsa null data"},
{ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED),
"data between ccs and finished"},
{ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG), "data length too long"},
......@@ -524,6 +544,8 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
"encrypted length too long"},
{ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST),
"error in received cipher list"},
{ERR_REASON(SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN),
"error setting tlsa base domain"},
{ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE), "excessive message size"},
{ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE), "extra data in message"},
{ERR_REASON(SSL_R_FAILED_TO_INIT_ASYNC), "failed to init async"},
......
......@@ -197,6 +197,333 @@ struct ssl_async_args {
} f;
};
static const struct {
uint8_t mtype;
uint8_t ord;
int nid;
} dane_mds[] = {
{ DANETLS_MATCHING_FULL, 0, NID_undef },
{ DANETLS_MATCHING_2256, 1, NID_sha256 },
{ DANETLS_MATCHING_2512, 2, NID_sha512 },
};
static int dane_ctx_enable(struct dane_ctx_st *dctx)
{
const EVP_MD **mdevp;
uint8_t *mdord;
uint8_t mdmax = DANETLS_MATCHING_LAST;
int n = ((int) mdmax) + 1; /* int to handle PrivMatch(255) */
size_t i;
mdevp = OPENSSL_zalloc(n * sizeof(*mdevp));
mdord = OPENSSL_zalloc(n * sizeof(*mdord));
if (mdord == NULL || mdevp == NULL) {
OPENSSL_free(mdevp);
SSLerr(SSL_F_DANE_CTX_ENABLE, ERR_R_MALLOC_FAILURE);
return 0;
}
/* Install default entries */
for (i = 0; i < OSSL_NELEM(dane_mds); ++i) {
const EVP_MD *md;
if (dane_mds[i].nid == NID_undef ||
(md = EVP_get_digestbynid(dane_mds[i].nid)) == NULL)
continue;
mdevp[dane_mds[i].mtype] = md;
mdord[dane_mds[i].mtype] = dane_mds[i].ord;
}
dctx->mdevp = mdevp;
dctx->mdord = mdord;
dctx->mdmax = mdmax;
return 1;
}
static void dane_ctx_final(struct dane_ctx_st *dctx)
{
OPENSSL_free(dctx->mdevp);
dctx->mdevp = NULL;
OPENSSL_free(dctx->mdord);
dctx->mdord = NULL;
dctx->mdmax = 0;
}
static void tlsa_free(danetls_record *t)
{
if (t == NULL)
return;
OPENSSL_free(t->data);
EVP_PKEY_free(t->spki);
OPENSSL_free(t);
}
static void dane_final(struct dane_st *dane)
{
sk_danetls_record_pop_free(dane->trecs, tlsa_free);
dane->trecs = NULL;
sk_X509_pop_free(dane->certs, X509_free);
dane->certs = NULL;
X509_free(dane->mcert);
dane->mcert = NULL;
dane->mtlsa = NULL;
dane->mdpth = -1;
dane->pdpth = -1;
}
/*
* dane_copy - Copy dane configuration, sans verification state.
*/
static int ssl_dane_dup(SSL *to, SSL *from)
{
int num;
int i;
if (!DANETLS_ENABLED(&from->dane))
return 1;
dane_final(&to->dane);
num = sk_danetls_record_num(from->dane.trecs);
for (i = 0; i < num; ++i) {
danetls_record *t = sk_danetls_record_value(from->dane.trecs, i);
if (SSL_dane_tlsa_add(to, t->usage, t->selector, t->mtype,
t->data, t->dlen) <= 0)
return 0;
}
return 1;
}
static int dane_mtype_set(
struct dane_ctx_st *dctx,
const EVP_MD *md,
uint8_t mtype,
uint8_t ord)
{
int i;
if (mtype == DANETLS_MATCHING_FULL && md != NULL) {
SSLerr(SSL_F_DANE_MTYPE_SET,
SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL);
return 0;
}
if (mtype > dctx->mdmax) {
const EVP_MD **mdevp;
uint8_t *mdord;
int n = ((int) mtype) + 1;
mdevp = OPENSSL_realloc(dctx->mdevp, n * sizeof(*mdevp));
if (mdevp == NULL) {
SSLerr(SSL_F_DANE_MTYPE_SET, ERR_R_MALLOC_FAILURE);
return -1;
}
dctx->mdevp = mdevp;
mdord = OPENSSL_realloc(dctx->mdord, n * sizeof(*mdord));
if (mdord == NULL) {
SSLerr(SSL_F_DANE_MTYPE_SET, ERR_R_MALLOC_FAILURE);
return -1;
}
dctx->mdord = mdord;
/* Zero-fill any gaps */
for (i = dctx->mdmax+1; i < mtype; ++i) {
mdevp[i] = NULL;
mdord[i] = 0;
}
dctx->mdmax = mtype;
}
dctx->mdevp[mtype] = md;
/* Coerce ordinal of disabled matching types to 0 */
dctx->mdord[mtype] = (md == NULL) ? 0 : ord;
return 1;
}
static const EVP_MD *tlsa_md_get(struct dane_st *dane, uint8_t mtype)
{
if (mtype > dane->dctx->mdmax)
return NULL;
return dane->dctx->mdevp[mtype];
}
static int dane_tlsa_add(
struct dane_st *dane,
uint8_t usage,
uint8_t selector,
uint8_t mtype,
unsigned char *data,
size_t dlen)
{
danetls_record *t;
const EVP_MD *md = NULL;
int ilen = (int)dlen;
int i;
if (dane->trecs == NULL) {
SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_NOT_ENABLED);
return -1;
}
if (ilen < 0 || dlen != (size_t)ilen) {
SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_DATA_LENGTH);
return 0;
}
if (usage > DANETLS_USAGE_LAST) {
SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE);
return 0;
}
if (selector > DANETLS_SELECTOR_LAST) {
SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_SELECTOR);
return 0;
}
if (mtype != DANETLS_MATCHING_FULL) {
md = tlsa_md_get(dane, mtype);
if (md == NULL) {
SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_MATCHING_TYPE);
return 0;
}
}
if (md != NULL && dlen != (size_t)EVP_MD_size(md)) {
SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH);
return 0;
}
if (!data) {
SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_NULL_DATA);
return 0;
}
if ((t = OPENSSL_zalloc(sizeof(*t))) == NULL) {
SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
return -1;
}
t->usage = usage;
t->selector = selector;
t->mtype = mtype;
t->data = OPENSSL_malloc(ilen);
if (t->data == NULL) {
tlsa_free(t);
SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
return -1;
}
memcpy(t->data, data, ilen);
t->dlen = ilen;
/* Validate and cache full certificate or public key */
if (mtype == DANETLS_MATCHING_FULL) {
const unsigned char *p = data;
X509 *cert = NULL;
EVP_PKEY *pkey = NULL;
switch (selector) {
case DANETLS_SELECTOR_CERT:
if (!d2i_X509(&cert, &p, dlen) || p < data ||
dlen != (size_t)(p - data)) {
tlsa_free(t);
SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE);
return 0;
}
if (X509_get0_pubkey(cert) == NULL) {
tlsa_free(t);
SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE);
return 0;
}
if ((DANETLS_USAGE_BIT(usage) & DANETLS_TA_MASK) == 0) {
X509_free(cert);
break;
}
/*
* For usage DANE-TA(2), we support authentication via "2 0 0" TLSA
* records that contain full certificates of trust-anchors that are
* not present in the wire chain. For usage PKIX-TA(0), we augment
* the chain with untrusted Full(0) certificates from DNS, in case
* they are missing from the chain.
*/
if ((dane->certs == NULL &&
(dane->certs = sk_X509_new_null()) == NULL) ||
!sk_X509_push(dane->certs, cert)) {
SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
X509_free(cert);
tlsa_free(t);
return -1;
}
break;
case DANETLS_SELECTOR_SPKI:
if (!d2i_PUBKEY(&pkey, &p, dlen) || p < data ||
dlen != (size_t)(p - data)) {
tlsa_free(t);
SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY);
return 0;
}
/*
* For usage DANE-TA(2), we support authentication via "2 1 0" TLSA
* records that contain full bare keys of trust-anchors that are
* not present in the wire chain.
*/
if (usage == DANETLS_USAGE_DANE_TA)
t->spki = pkey;
else
EVP_PKEY_free(pkey);
break;
}
}
/*-
* Find the right insertion point for the new record.
*
* See crypto/x509/x509_vfy.c. We sort DANE-EE(3) records first, so that
* they can be processed first, as they require no chain building, and no
* expiration or hostname checks. Because DANE-EE(3) is numerically
* largest, this is accomplished via descending sort by "usage".
*
* We also sort in descending order by matching ordinal to simplify
* the implementation of digest agility in the verification code.
*
* The choice of order for the selector is not significant, so we
* use the same descending order for consistency.
*/
for (i = 0; i < sk_danetls_record_num(dane->trecs); ++i) {
danetls_record *rec = sk_danetls_record_value(dane->trecs, i);
if (rec->usage > usage)
continue;
if (rec->usage < usage)
break;
if (rec->selector > selector)
continue;
if (rec->selector < selector)
break;
if (dane->dctx->mdord[rec->mtype] > dane->dctx->mdord[mtype])
continue;
break;
}
if (!sk_danetls_record_insert(dane->trecs, t, i)) {
tlsa_free(t);
SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
return -1;
}
dane->umask |= DANETLS_USAGE_BIT(usage);
return 1;
}
static void clear_ciphers(SSL *s)
{
/* clear the current cipher */
......@@ -237,6 +564,16 @@ int SSL_clear(SSL *s)
clear_ciphers(s);
s->first_packet = 0;
/* Reset DANE verification result state */
s->dane.mdpth = -1;
s->dane.pdpth = -1;
X509_free(s->dane.mcert);
s->dane.mcert = NULL;
s->dane.mtlsa = NULL;
/* Clear the verification result peername */
X509_VERIFY_PARAM_move_peername(s->param, NULL);
/*
* Check to see if we were changed into a different method, if so, revert
* back if we are not doing session-id reuse.
......@@ -497,6 +834,121 @@ int SSL_set_trust(SSL *s, int trust)
return X509_VERIFY_PARAM_set_trust(s->param, trust);
}
int SSL_set1_host(SSL *s, const char *hostname)
{
return X509_VERIFY_PARAM_set1_host(s->param, hostname, 0);
}
int SSL_add1_host(SSL *s, const char *hostname)
{
return X509_VERIFY_PARAM_add1_host(s->param, hostname, 0);
}
void SSL_set_hostflags(SSL *s, unsigned int flags)
{
X509_VERIFY_PARAM_set_hostflags(s->param, flags);
}
const char *SSL_get0_peername(SSL *s)
{
return X509_VERIFY_PARAM_get0_peername(s->param);
}
int SSL_CTX_dane_enable(SSL_CTX *ctx)
{
return dane_ctx_enable(&ctx->dane);
}
int SSL_dane_enable(SSL *s, const char *basedomain)
{
struct dane_st *dane = &s->dane;
if (s->ctx->dane.mdmax == 0) {
SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_CONTEXT_NOT_DANE_ENABLED);
return 0;
}
if (dane->trecs != NULL) {
SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_DANE_ALREADY_ENABLED);
return 0;
}
/* Primary RFC6125 reference identifier */
if (!X509_VERIFY_PARAM_set1_host(s->param, basedomain, 0)) {
SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN);
return -1;
}
/* Default SNI name */
if (s->tlsext_hostname == NULL) {
if (!SSL_set_tlsext_host_name(s, basedomain))
return -1;
}
dane->mdpth = -1;
dane->pdpth = -1;
dane->dctx = &s->ctx->dane;
dane->trecs = sk_danetls_record_new_null();
if (dane->trecs == NULL) {
SSLerr(SSL_F_SSL_DANE_ENABLE, ERR_R_MALLOC_FAILURE);
return -1;
}
return 1;
}
int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki)
{
struct dane_st *dane = &s->dane;
if (!DANETLS_ENABLED(dane))
return -1;
if (dane->mtlsa) {
if (mcert)
*mcert = dane->mcert;
if (mspki)
*mspki = (dane->mcert == NULL) ? dane->mtlsa->spki : NULL;
}
return dane->mdpth;
}
int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector,
uint8_t *mtype, unsigned const char **data, size_t *dlen)
{
struct dane_st *dane = &s->dane;
if (!DANETLS_ENABLED(dane))
return -1;
if (dane->mtlsa) {
if (usage)
*usage = dane->mtlsa->usage;
if (selector)
*selector = dane->mtlsa->selector;
if (mtype)
*mtype = dane->mtlsa->mtype;
if (data)
*data = dane->mtlsa->data;
if (dlen)
*dlen = dane->mtlsa->dlen;
}
return dane->mdpth;
}
struct dane_st *SSL_get0_dane(SSL *s)
{
return &s->dane;
}
int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector,
uint8_t mtype, unsigned char *data, size_t dlen)
{
return dane_tlsa_add(&s->dane, usage, selector, mtype, data, dlen);
}
int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md, uint8_t mtype, uint8_t ord)
{
return dane_mtype_set(&ctx->dane, md, mtype, ord);
}
int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm)
{
return X509_VERIFY_PARAM_set1(ctx->param, vpm);
......@@ -543,6 +995,7 @@ void SSL_free(SSL *s)
#endif
X509_VERIFY_PARAM_free(s->param);
dane_final(&s->dane);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
if (s->bbio != NULL) {
......@@ -877,9 +1330,10 @@ int SSL_copy_session_id(SSL *t, const SSL *f)
* what if we are setup for one protocol version but want to talk another
*/
if (t->method != f->method) {
t->method->ssl_free(t); /* cleanup current */
t->method = f->method; /* change method */
t->method->ssl_new(t); /* setup new */
t->method->ssl_free(t);
t->method = f->method;
if (t->method->ssl_new(t) == 0)
return 0;
}
CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT);
......@@ -1922,6 +2376,7 @@ void SSL_CTX_free(SSL_CTX *a)
#endif
X509_VERIFY_PARAM_free(a->param);
dane_ctx_final(&a->dane);
/*
* Free internal session cache. However: the remove_cb() may reference
......@@ -2346,24 +2801,23 @@ const SSL_METHOD *SSL_get_ssl_method(SSL *s)
int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth)
{
int conn = -1;
int ret = 1;
if (s->method != meth) {
if (s->handshake_func != NULL)
conn = (s->handshake_func == s->method->ssl_connect);
const SSL_METHOD *sm = s->method;
int (*hf)(SSL *) = s->handshake_func;
if (s->method->version == meth->version)
if (sm->version == meth->version)
s->method = meth;
else {
s->method->ssl_free(s);
sm->ssl_free(s);
s->method = meth;
ret = s->method->ssl_new(s);
}
if (conn == 1)
if (hf == sm->ssl_connect)
s->handshake_func = meth->ssl_connect;
else if (conn == 0)
else if (hf == sm->ssl_accept)
s->handshake_func = meth->ssl_accept;
}
return (ret);
......@@ -2554,14 +3008,23 @@ SSL *SSL_dup(SSL *s)
SSL *ret;
int i;
/* If we're not quiescent, just up_ref! */
if (!SSL_in_init(s) || !SSL_in_before(s)) {
CRYPTO_add(&s->references, 1, CRYPTO_LOCK_SSL);
return s;
}
/*
* Otherwise, copy configuration state, and session if set.
*/
if ((ret = SSL_new(SSL_get_SSL_CTX(s))) == NULL)
return (NULL);
ret->version = s->version;
ret->method = s->method;
if (s->session != NULL) {
/* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */
/*
* Arranges to share the same session via up_ref. This "copies"
* session-id, SSL_METHOD, sid_ctx, and 'cert'
*/
if (!SSL_copy_session_id(ret, s))
goto err;
} else {
......@@ -2571,10 +3034,8 @@ SSL *SSL_dup(SSL *s)
* point to the same object, and thus we can't use
* SSL_copy_session_id.
*/
ret->method->ssl_free(ret);
ret->method = s->method;
ret->method->ssl_new(ret);
if (!SSL_set_ssl_method(ret, s->method))
goto err;
if (s->cert != NULL) {
ssl_cert_free(ret->cert);
......@@ -2587,6 +3048,8 @@ SSL *SSL_dup(SSL *s)
goto err;
}
ssl_dane_dup(ret, s);
ret->version = s->version;
ret->options = s->options;
ret->mode = s->mode;
SSL_set_max_cert_list(ret, SSL_get_max_cert_list(s));
......@@ -2617,19 +3080,15 @@ SSL *SSL_dup(SSL *s)
} else
ret->wbio = ret->rbio;
}
ret->rwstate = s->rwstate;
ret->handshake_func = s->handshake_func;
ret->server = s->server;
ret->renegotiate = s->renegotiate;
ret->new_session = s->new_session;
ret->quiet_shutdown = s->quiet_shutdown;
if (s->handshake_func) {
if (s->server)
SSL_set_accept_state(ret);
else
SSL_set_connect_state(ret);
}
ret->shutdown = s->shutdown;
ret->statem = s->statem; /* SSL_dup does not really work at any state,
* though */
RECORD_LAYER_dup(&ret->rlayer, &s->rlayer);
ret->init_num = 0; /* would have to copy ret->init_buf,
* ret->init_msg, ret->init_num,
* ret->init_off */
ret->hit = s->hit;
ret->default_passwd_callback = s->default_passwd_callback;
......
......@@ -169,6 +169,7 @@
#include "record/record.h"
#include "statem/statem.h"
#include "packet_locl.h"
#include "internal/dane.h"
# ifdef OPENSSL_BUILD_SHLIBSSL
# undef OPENSSL_EXTERN
......@@ -925,6 +926,9 @@ struct ssl_ctx_st {
unsigned char *alpn_client_proto_list;
unsigned alpn_client_proto_list_len;
/* Shared DANE context */
struct dane_ctx_st dane;
/* SRTP profiles we are willing to do from RFC 5764 */
STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
/*
......@@ -1007,6 +1011,10 @@ struct ssl_st {
void *msg_callback_arg;
int hit; /* reusing a previous session */
X509_VERIFY_PARAM *param;
/* Per connection DANE state */
struct dane_st dane;
/* crypto */
STACK_OF(SSL_CIPHER) *cipher_list;
STACK_OF(SSL_CIPHER) *cipher_list_by_id;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册