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 /include | |
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 'include')
-rw-r--r-- | include/internal/dane.h | 147 | ||||
-rw-r--r-- | include/openssl/safestack.h | 23 | ||||
-rw-r--r-- | include/openssl/ssl.h | 40 | ||||
-rw-r--r-- | include/openssl/x509_vfy.h | 8 |
4 files changed, 218 insertions, 0 deletions
diff --git a/include/internal/dane.h b/include/internal/dane.h new file mode 100644 index 0000000000..cbe33f3e48 --- /dev/null +++ b/include/internal/dane.h @@ -0,0 +1,147 @@ +/* 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 */ diff --git a/include/openssl/safestack.h b/include/openssl/safestack.h index cce3afd630..94b8af4cca 100644 --- a/include/openssl/safestack.h +++ b/include/openssl/safestack.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)) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 0d22ab7716..e6342946dd 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -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 diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h index 5e65998b35..e37c2f7f60 100644 --- a/include/openssl/x509_vfy.h +++ b/include/openssl/x509_vfy.h @@ -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, |