diff options
Diffstat (limited to 'thirdparty/openssl/ssl')
53 files changed, 0 insertions, 55257 deletions
diff --git a/thirdparty/openssl/ssl/bio_ssl.c b/thirdparty/openssl/ssl/bio_ssl.c deleted file mode 100644 index d2d4d2ea2d..0000000000 --- a/thirdparty/openssl/ssl/bio_ssl.c +++ /dev/null @@ -1,591 +0,0 @@ -/* ssl/bio_ssl.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <openssl/crypto.h> -#include <openssl/bio.h> -#include <openssl/err.h> -#include <openssl/ssl.h> - -static int ssl_write(BIO *h, const char *buf, int num); -static int ssl_read(BIO *h, char *buf, int size); -static int ssl_puts(BIO *h, const char *str); -static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int ssl_new(BIO *h); -static int ssl_free(BIO *data); -static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); -typedef struct bio_ssl_st { - SSL *ssl; /* The ssl handle :-) */ - /* re-negotiate every time the total number of bytes is this size */ - int num_renegotiates; - unsigned long renegotiate_count; - unsigned long byte_count; - unsigned long renegotiate_timeout; - unsigned long last_time; -} BIO_SSL; - -static BIO_METHOD methods_sslp = { - BIO_TYPE_SSL, "ssl", - ssl_write, - ssl_read, - ssl_puts, - NULL, /* ssl_gets, */ - ssl_ctrl, - ssl_new, - ssl_free, - ssl_callback_ctrl, -}; - -BIO_METHOD *BIO_f_ssl(void) -{ - return (&methods_sslp); -} - -static int ssl_new(BIO *bi) -{ - BIO_SSL *bs; - - bs = (BIO_SSL *)OPENSSL_malloc(sizeof(BIO_SSL)); - if (bs == NULL) { - BIOerr(BIO_F_SSL_NEW, ERR_R_MALLOC_FAILURE); - return (0); - } - memset(bs, 0, sizeof(BIO_SSL)); - bi->init = 0; - bi->ptr = (char *)bs; - bi->flags = 0; - return (1); -} - -static int ssl_free(BIO *a) -{ - BIO_SSL *bs; - - if (a == NULL) - return (0); - bs = (BIO_SSL *)a->ptr; - if (bs->ssl != NULL) - SSL_shutdown(bs->ssl); - if (a->shutdown) { - if (a->init && (bs->ssl != NULL)) - SSL_free(bs->ssl); - a->init = 0; - a->flags = 0; - } - if (a->ptr != NULL) - OPENSSL_free(a->ptr); - return (1); -} - -static int ssl_read(BIO *b, char *out, int outl) -{ - int ret = 1; - BIO_SSL *sb; - SSL *ssl; - int retry_reason = 0; - int r = 0; - - if (out == NULL) - return (0); - sb = (BIO_SSL *)b->ptr; - ssl = sb->ssl; - - BIO_clear_retry_flags(b); - -#if 0 - if (!SSL_is_init_finished(ssl)) { -/* ret=SSL_do_handshake(ssl); */ - if (ret > 0) { - - outflags = (BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY); - ret = -1; - goto end; - } - } -#endif -/* if (ret > 0) */ - ret = SSL_read(ssl, out, outl); - - switch (SSL_get_error(ssl, ret)) { - case SSL_ERROR_NONE: - if (ret <= 0) - break; - if (sb->renegotiate_count > 0) { - sb->byte_count += ret; - if (sb->byte_count > sb->renegotiate_count) { - sb->byte_count = 0; - sb->num_renegotiates++; - SSL_renegotiate(ssl); - r = 1; - } - } - if ((sb->renegotiate_timeout > 0) && (!r)) { - unsigned long tm; - - tm = (unsigned long)time(NULL); - if (tm > sb->last_time + sb->renegotiate_timeout) { - sb->last_time = tm; - sb->num_renegotiates++; - SSL_renegotiate(ssl); - } - } - - break; - case SSL_ERROR_WANT_READ: - BIO_set_retry_read(b); - break; - case SSL_ERROR_WANT_WRITE: - BIO_set_retry_write(b); - break; - case SSL_ERROR_WANT_X509_LOOKUP: - BIO_set_retry_special(b); - retry_reason = BIO_RR_SSL_X509_LOOKUP; - break; - case SSL_ERROR_WANT_ACCEPT: - BIO_set_retry_special(b); - retry_reason = BIO_RR_ACCEPT; - break; - case SSL_ERROR_WANT_CONNECT: - BIO_set_retry_special(b); - retry_reason = BIO_RR_CONNECT; - break; - case SSL_ERROR_SYSCALL: - case SSL_ERROR_SSL: - case SSL_ERROR_ZERO_RETURN: - default: - break; - } - - b->retry_reason = retry_reason; - return (ret); -} - -static int ssl_write(BIO *b, const char *out, int outl) -{ - int ret, r = 0; - int retry_reason = 0; - SSL *ssl; - BIO_SSL *bs; - - if (out == NULL) - return (0); - bs = (BIO_SSL *)b->ptr; - ssl = bs->ssl; - - BIO_clear_retry_flags(b); - - /* - * ret=SSL_do_handshake(ssl); if (ret > 0) - */ - ret = SSL_write(ssl, out, outl); - - switch (SSL_get_error(ssl, ret)) { - case SSL_ERROR_NONE: - if (ret <= 0) - break; - if (bs->renegotiate_count > 0) { - bs->byte_count += ret; - if (bs->byte_count > bs->renegotiate_count) { - bs->byte_count = 0; - bs->num_renegotiates++; - SSL_renegotiate(ssl); - r = 1; - } - } - if ((bs->renegotiate_timeout > 0) && (!r)) { - unsigned long tm; - - tm = (unsigned long)time(NULL); - if (tm > bs->last_time + bs->renegotiate_timeout) { - bs->last_time = tm; - bs->num_renegotiates++; - SSL_renegotiate(ssl); - } - } - break; - case SSL_ERROR_WANT_WRITE: - BIO_set_retry_write(b); - break; - case SSL_ERROR_WANT_READ: - BIO_set_retry_read(b); - break; - case SSL_ERROR_WANT_X509_LOOKUP: - BIO_set_retry_special(b); - retry_reason = BIO_RR_SSL_X509_LOOKUP; - break; - case SSL_ERROR_WANT_CONNECT: - BIO_set_retry_special(b); - retry_reason = BIO_RR_CONNECT; - case SSL_ERROR_SYSCALL: - case SSL_ERROR_SSL: - default: - break; - } - - b->retry_reason = retry_reason; - return (ret); -} - -static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - SSL **sslp, *ssl; - BIO_SSL *bs; - BIO *dbio, *bio; - long ret = 1; - - bs = (BIO_SSL *)b->ptr; - ssl = bs->ssl; - if ((ssl == NULL) && (cmd != BIO_C_SET_SSL)) - return (0); - switch (cmd) { - case BIO_CTRL_RESET: - SSL_shutdown(ssl); - - if (ssl->handshake_func == ssl->method->ssl_connect) - SSL_set_connect_state(ssl); - else if (ssl->handshake_func == ssl->method->ssl_accept) - SSL_set_accept_state(ssl); - - SSL_clear(ssl); - - if (b->next_bio != NULL) - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - else if (ssl->rbio != NULL) - ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); - else - ret = 1; - break; - case BIO_CTRL_INFO: - ret = 0; - break; - case BIO_C_SSL_MODE: - if (num) /* client mode */ - SSL_set_connect_state(ssl); - else - SSL_set_accept_state(ssl); - break; - case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT: - ret = bs->renegotiate_timeout; - if (num < 60) - num = 5; - bs->renegotiate_timeout = (unsigned long)num; - bs->last_time = (unsigned long)time(NULL); - break; - case BIO_C_SET_SSL_RENEGOTIATE_BYTES: - ret = bs->renegotiate_count; - if ((long)num >= 512) - bs->renegotiate_count = (unsigned long)num; - break; - case BIO_C_GET_SSL_NUM_RENEGOTIATES: - ret = bs->num_renegotiates; - break; - case BIO_C_SET_SSL: - if (ssl != NULL) { - ssl_free(b); - if (!ssl_new(b)) - return 0; - } - b->shutdown = (int)num; - ssl = (SSL *)ptr; - ((BIO_SSL *)b->ptr)->ssl = ssl; - bio = SSL_get_rbio(ssl); - if (bio != NULL) { - if (b->next_bio != NULL) - BIO_push(bio, b->next_bio); - b->next_bio = bio; - CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO); - } - b->init = 1; - break; - case BIO_C_GET_SSL: - if (ptr != NULL) { - sslp = (SSL **)ptr; - *sslp = ssl; - } else - ret = 0; - break; - case BIO_CTRL_GET_CLOSE: - ret = b->shutdown; - break; - case BIO_CTRL_SET_CLOSE: - b->shutdown = (int)num; - break; - case BIO_CTRL_WPENDING: - ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); - break; - case BIO_CTRL_PENDING: - ret = SSL_pending(ssl); - if (ret == 0) - ret = BIO_pending(ssl->rbio); - break; - case BIO_CTRL_FLUSH: - BIO_clear_retry_flags(b); - ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); - BIO_copy_next_retry(b); - break; - case BIO_CTRL_PUSH: - if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) { - SSL_set_bio(ssl, b->next_bio, b->next_bio); - CRYPTO_add(&b->next_bio->references, 1, CRYPTO_LOCK_BIO); - } - break; - case BIO_CTRL_POP: - /* Only detach if we are the BIO explicitly being popped */ - if (b == ptr) { - /* - * Shouldn't happen in practice because the rbio and wbio are the - * same when pushed. - */ - if (ssl->rbio != ssl->wbio) - BIO_free_all(ssl->wbio); - if (b->next_bio != NULL) - CRYPTO_add(&b->next_bio->references, -1, CRYPTO_LOCK_BIO); - ssl->wbio = NULL; - ssl->rbio = NULL; - } - break; - case BIO_C_DO_STATE_MACHINE: - BIO_clear_retry_flags(b); - - b->retry_reason = 0; - ret = (int)SSL_do_handshake(ssl); - - switch (SSL_get_error(ssl, (int)ret)) { - case SSL_ERROR_WANT_READ: - BIO_set_flags(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY); - break; - case SSL_ERROR_WANT_WRITE: - BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY); - break; - case SSL_ERROR_WANT_CONNECT: - BIO_set_flags(b, BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY); - b->retry_reason = b->next_bio->retry_reason; - break; - case SSL_ERROR_WANT_X509_LOOKUP: - BIO_set_retry_special(b); - b->retry_reason = BIO_RR_SSL_X509_LOOKUP; - break; - default: - break; - } - break; - case BIO_CTRL_DUP: - dbio = (BIO *)ptr; - if (((BIO_SSL *)dbio->ptr)->ssl != NULL) - SSL_free(((BIO_SSL *)dbio->ptr)->ssl); - ((BIO_SSL *)dbio->ptr)->ssl = SSL_dup(ssl); - ((BIO_SSL *)dbio->ptr)->renegotiate_count = - ((BIO_SSL *)b->ptr)->renegotiate_count; - ((BIO_SSL *)dbio->ptr)->byte_count = ((BIO_SSL *)b->ptr)->byte_count; - ((BIO_SSL *)dbio->ptr)->renegotiate_timeout = - ((BIO_SSL *)b->ptr)->renegotiate_timeout; - ((BIO_SSL *)dbio->ptr)->last_time = ((BIO_SSL *)b->ptr)->last_time; - ret = (((BIO_SSL *)dbio->ptr)->ssl != NULL); - break; - case BIO_C_GET_FD: - ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); - break; - case BIO_CTRL_SET_CALLBACK: - { -#if 0 /* FIXME: Should this be used? -- Richard - * Levitte */ - SSLerr(SSL_F_SSL_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - ret = -1; -#else - ret = 0; -#endif - } - break; - case BIO_CTRL_GET_CALLBACK: - { - void (**fptr) (const SSL *xssl, int type, int val); - - fptr = (void (**)(const SSL *xssl, int type, int val))ptr; - *fptr = SSL_get_info_callback(ssl); - } - break; - default: - ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); - break; - } - return (ret); -} - -static long ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - SSL *ssl; - BIO_SSL *bs; - long ret = 1; - - bs = (BIO_SSL *)b->ptr; - ssl = bs->ssl; - switch (cmd) { - case BIO_CTRL_SET_CALLBACK: - { - /* - * FIXME: setting this via a completely different prototype seems - * like a crap idea - */ - SSL_set_info_callback(ssl, (void (*)(const SSL *, int, int))fp); - } - break; - default: - ret = BIO_callback_ctrl(ssl->rbio, cmd, fp); - break; - } - return (ret); -} - -static int ssl_puts(BIO *bp, const char *str) -{ - int n, ret; - - n = strlen(str); - ret = BIO_write(bp, str, n); - return (ret); -} - -BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx) -{ -#ifndef OPENSSL_NO_SOCK - BIO *ret = NULL, *buf = NULL, *ssl = NULL; - - if ((buf = BIO_new(BIO_f_buffer())) == NULL) - return (NULL); - if ((ssl = BIO_new_ssl_connect(ctx)) == NULL) - goto err; - if ((ret = BIO_push(buf, ssl)) == NULL) - goto err; - return (ret); - err: - if (buf != NULL) - BIO_free(buf); - if (ssl != NULL) - BIO_free(ssl); -#endif - return (NULL); -} - -BIO *BIO_new_ssl_connect(SSL_CTX *ctx) -{ -#ifndef OPENSSL_NO_SOCK - BIO *ret = NULL, *con = NULL, *ssl = NULL; - - if ((con = BIO_new(BIO_s_connect())) == NULL) - return (NULL); - if ((ssl = BIO_new_ssl(ctx, 1)) == NULL) - goto err; - if ((ret = BIO_push(ssl, con)) == NULL) - goto err; - return (ret); - err: - if (con != NULL) - BIO_free(con); -#endif - return (NULL); -} - -BIO *BIO_new_ssl(SSL_CTX *ctx, int client) -{ - BIO *ret; - SSL *ssl; - - if ((ret = BIO_new(BIO_f_ssl())) == NULL) - return (NULL); - if ((ssl = SSL_new(ctx)) == NULL) { - BIO_free(ret); - return (NULL); - } - if (client) - SSL_set_connect_state(ssl); - else - SSL_set_accept_state(ssl); - - BIO_set_ssl(ret, ssl, BIO_CLOSE); - return (ret); -} - -int BIO_ssl_copy_session_id(BIO *t, BIO *f) -{ - t = BIO_find_type(t, BIO_TYPE_SSL); - f = BIO_find_type(f, BIO_TYPE_SSL); - if ((t == NULL) || (f == NULL)) - return (0); - if ((((BIO_SSL *)t->ptr)->ssl == NULL) || - (((BIO_SSL *)f->ptr)->ssl == NULL)) - return (0); - SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl, ((BIO_SSL *)f->ptr)->ssl); - return (1); -} - -void BIO_ssl_shutdown(BIO *b) -{ - SSL *s; - - while (b != NULL) { - if (b->method->type == BIO_TYPE_SSL) { - s = ((BIO_SSL *)b->ptr)->ssl; - SSL_shutdown(s); - break; - } - b = b->next_bio; - } -} diff --git a/thirdparty/openssl/ssl/d1_both.c b/thirdparty/openssl/ssl/d1_both.c deleted file mode 100644 index e6bc761e8b..0000000000 --- a/thirdparty/openssl/ssl/d1_both.c +++ /dev/null @@ -1,1598 +0,0 @@ -/* ssl/d1_both.c */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1998-2005 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 - * openssl-core@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). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <limits.h> -#include <string.h> -#include <stdio.h> -#include "ssl_locl.h" -#include <openssl/buffer.h> -#include <openssl/rand.h> -#include <openssl/objects.h> -#include <openssl/evp.h> -#include <openssl/x509.h> - -#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) - -#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ - if ((end) - (start) <= 8) { \ - long ii; \ - for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \ - } else { \ - long ii; \ - bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \ - for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \ - bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \ - } } - -#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ - long ii; \ - OPENSSL_assert((msg_len) > 0); \ - is_complete = 1; \ - if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \ - if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \ - if (bitmask[ii] != 0xff) { is_complete = 0; break; } } - -#if 0 -# define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \ - long ii; \ - printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \ - printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \ - printf("\n"); } -#endif - -static unsigned char bitmask_start_values[] = - { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 }; -static unsigned char bitmask_end_values[] = - { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f }; - -/* XDTLS: figure out the right values */ -static const unsigned int g_probable_mtu[] = { 1500, 512, 256 }; - -static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, - unsigned long frag_len); -static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p); -static void dtls1_set_message_header_int(SSL *s, unsigned char mt, - unsigned long len, - unsigned short seq_num, - unsigned long frag_off, - unsigned long frag_len); -static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, - int *ok); - -static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len, - int reassembly) -{ - hm_fragment *frag = NULL; - unsigned char *buf = NULL; - unsigned char *bitmask = NULL; - - frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); - if (frag == NULL) - return NULL; - - if (frag_len) { - buf = (unsigned char *)OPENSSL_malloc(frag_len); - if (buf == NULL) { - OPENSSL_free(frag); - return NULL; - } - } - - /* zero length fragment gets zero frag->fragment */ - frag->fragment = buf; - - /* Initialize reassembly bitmask if necessary */ - if (reassembly) { - bitmask = - (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len)); - if (bitmask == NULL) { - if (buf != NULL) - OPENSSL_free(buf); - OPENSSL_free(frag); - return NULL; - } - memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len)); - } - - frag->reassembly = bitmask; - - return frag; -} - -void dtls1_hm_fragment_free(hm_fragment *frag) -{ - - if (frag->msg_header.is_ccs) { - EVP_CIPHER_CTX_free(frag->msg_header. - saved_retransmit_state.enc_write_ctx); - EVP_MD_CTX_destroy(frag->msg_header. - saved_retransmit_state.write_hash); - } - if (frag->fragment) - OPENSSL_free(frag->fragment); - if (frag->reassembly) - OPENSSL_free(frag->reassembly); - OPENSSL_free(frag); -} - -static int dtls1_query_mtu(SSL *s) -{ - if (s->d1->link_mtu) { - s->d1->mtu = - s->d1->link_mtu - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); - s->d1->link_mtu = 0; - } - - /* AHA! Figure out the MTU, and stick to the right size */ - if (s->d1->mtu < dtls1_min_mtu(s)) { - if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { - s->d1->mtu = - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); - - /* - * I've seen the kernel return bogus numbers when it doesn't know - * (initial write), so just make sure we have a reasonable number - */ - if (s->d1->mtu < dtls1_min_mtu(s)) { - /* Set to min mtu */ - s->d1->mtu = dtls1_min_mtu(s); - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, - s->d1->mtu, NULL); - } - } else - return 0; - } - return 1; -} - -/* - * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or - * SSL3_RT_CHANGE_CIPHER_SPEC) - */ -int dtls1_do_write(SSL *s, int type) -{ - int ret; - unsigned int curr_mtu; - int retry = 1; - unsigned int len, frag_off, mac_size, blocksize, used_len; - - if (!dtls1_query_mtu(s)) - return -1; - - OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu(s)); /* should have something - * reasonable now */ - - if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) - OPENSSL_assert(s->init_num == - (int)s->d1->w_msg_hdr.msg_len + - DTLS1_HM_HEADER_LENGTH); - - if (s->write_hash) { - if (s->enc_write_ctx - && EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_GCM_MODE) - mac_size = 0; - else - mac_size = EVP_MD_CTX_size(s->write_hash); - } else - mac_size = 0; - - if (s->enc_write_ctx && - (EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE)) - blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher); - else - blocksize = 0; - - frag_off = 0; - s->rwstate = SSL_NOTHING; - - /* s->init_num shouldn't ever be < 0...but just in case */ - while (s->init_num > 0) { - if (type == SSL3_RT_HANDSHAKE && s->init_off != 0) { - /* We must be writing a fragment other than the first one */ - - if (frag_off > 0) { - /* This is the first attempt at writing out this fragment */ - - if (s->init_off <= DTLS1_HM_HEADER_LENGTH) { - /* - * Each fragment that was already sent must at least have - * contained the message header plus one other byte. - * Therefore |init_off| must have progressed by at least - * |DTLS1_HM_HEADER_LENGTH + 1| bytes. If not something went - * wrong. - */ - return -1; - } - - /* - * Adjust |init_off| and |init_num| to allow room for a new - * message header for this fragment. - */ - s->init_off -= DTLS1_HM_HEADER_LENGTH; - s->init_num += DTLS1_HM_HEADER_LENGTH; - } else { - /* - * We must have been called again after a retry so use the - * fragment offset from our last attempt. We do not need - * to adjust |init_off| and |init_num| as above, because - * that should already have been done before the retry. - */ - frag_off = s->d1->w_msg_hdr.frag_off; - } - } - - used_len = BIO_wpending(SSL_get_wbio(s)) + DTLS1_RT_HEADER_LENGTH - + mac_size + blocksize; - if (s->d1->mtu > used_len) - curr_mtu = s->d1->mtu - used_len; - else - curr_mtu = 0; - - if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) { - /* - * grr.. we could get an error if MTU picked was wrong - */ - ret = BIO_flush(SSL_get_wbio(s)); - if (ret <= 0) { - s->rwstate = SSL_WRITING; - return ret; - } - used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize; - if (s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH) { - curr_mtu = s->d1->mtu - used_len; - } else { - /* Shouldn't happen */ - return -1; - } - } - - /* - * We just checked that s->init_num > 0 so this cast should be safe - */ - if (((unsigned int)s->init_num) > curr_mtu) - len = curr_mtu; - else - len = s->init_num; - - /* Shouldn't ever happen */ - if (len > INT_MAX) - len = INT_MAX; - - /* - * XDTLS: this function is too long. split out the CCS part - */ - if (type == SSL3_RT_HANDSHAKE) { - if (len < DTLS1_HM_HEADER_LENGTH) { - /* - * len is so small that we really can't do anything sensible - * so fail - */ - return -1; - } - dtls1_fix_message_header(s, frag_off, - len - DTLS1_HM_HEADER_LENGTH); - - dtls1_write_message_header(s, - (unsigned char *)&s->init_buf-> - data[s->init_off]); - } - - ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], - len); - if (ret < 0) { - /* - * might need to update MTU here, but we don't know which - * previous packet caused the failure -- so can't really - * retransmit anything. continue as if everything is fine and - * wait for an alert to handle the retransmit - */ - if (retry && BIO_ctrl(SSL_get_wbio(s), - BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) { - if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { - if (!dtls1_query_mtu(s)) - return -1; - /* Have one more go */ - retry = 0; - } else - return -1; - } else { - return (-1); - } - } else { - - /* - * bad if this assert fails, only part of the handshake message - * got sent. but why would this happen? - */ - OPENSSL_assert(len == (unsigned int)ret); - - if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting) { - /* - * should not be done for 'Hello Request's, but in that case - * we'll ignore the result anyway - */ - unsigned char *p = - (unsigned char *)&s->init_buf->data[s->init_off]; - const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - int xlen; - - if (frag_off == 0 && s->version != DTLS1_BAD_VER) { - /* - * reconstruct message header is if it is being sent in - * single fragment - */ - *p++ = msg_hdr->type; - l2n3(msg_hdr->msg_len, p); - s2n(msg_hdr->seq, p); - l2n3(0, p); - l2n3(msg_hdr->msg_len, p); - p -= DTLS1_HM_HEADER_LENGTH; - xlen = ret; - } else { - p += DTLS1_HM_HEADER_LENGTH; - xlen = ret - DTLS1_HM_HEADER_LENGTH; - } - - ssl3_finish_mac(s, p, xlen); - } - - if (ret == s->init_num) { - if (s->msg_callback) - s->msg_callback(1, s->version, type, s->init_buf->data, - (size_t)(s->init_off + s->init_num), s, - s->msg_callback_arg); - - s->init_off = 0; /* done writing this message */ - s->init_num = 0; - - return (1); - } - s->init_off += ret; - s->init_num -= ret; - ret -= DTLS1_HM_HEADER_LENGTH; - frag_off += ret; - - /* - * We save the fragment offset for the next fragment so we have it - * available in case of an IO retry. We don't know the length of the - * next fragment yet so just set that to 0 for now. It will be - * updated again later. - */ - dtls1_fix_message_header(s, frag_off, 0); - } - } - return (0); -} - -/* - * Obtain handshake message of message type 'mt' (any if mt == -1), maximum - * acceptable body length 'max'. Read an entire handshake message. Handshake - * messages arrive in fragments. - */ -long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) -{ - int i, al; - struct hm_header_st *msg_hdr; - unsigned char *p; - unsigned long msg_len; - - /* - * s3->tmp is used to store messages that are unexpected, caused by the - * absence of an optional handshake message - */ - if (s->s3->tmp.reuse_message) { - s->s3->tmp.reuse_message = 0; - if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - *ok = 1; - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - s->init_num = (int)s->s3->tmp.message_size; - return s->init_num; - } - - msg_hdr = &s->d1->r_msg_hdr; - memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - - again: - i = dtls1_get_message_fragment(s, st1, stn, max, ok); - if (i == DTLS1_HM_BAD_FRAGMENT || i == DTLS1_HM_FRAGMENT_RETRY) { - /* bad fragment received */ - goto again; - } else if (i <= 0 && !*ok) { - return i; - } - - /* - * Don't change the *message* read sequence number while listening. For - * the *record* write sequence we reflect the ClientHello sequence number - * when listening. - */ - if (s->d1->listen) - memcpy(s->s3->write_sequence, s->s3->read_sequence, - sizeof(s->s3->write_sequence)); - else - s->d1->handshake_read_seq++; - - if (mt >= 0 && s->s3->tmp.message_type != mt) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - - p = (unsigned char *)s->init_buf->data; - msg_len = msg_hdr->msg_len; - - /* reconstruct message header */ - *(p++) = msg_hdr->type; - l2n3(msg_len, p); - s2n(msg_hdr->seq, p); - l2n3(0, p); - l2n3(msg_len, p); - if (s->version != DTLS1_BAD_VER) { - p -= DTLS1_HM_HEADER_LENGTH; - msg_len += DTLS1_HM_HEADER_LENGTH; - } - - ssl3_finish_mac(s, p, msg_len); - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, msg_len, s, s->msg_callback_arg); - - memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - return s->init_num; - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - *ok = 0; - return -1; -} - -static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, - int max) -{ - size_t frag_off, frag_len, msg_len; - - msg_len = msg_hdr->msg_len; - frag_off = msg_hdr->frag_off; - frag_len = msg_hdr->frag_len; - - /* sanity checking */ - if ((frag_off + frag_len) > msg_len) { - SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE); - return SSL_AD_ILLEGAL_PARAMETER; - } - - if ((frag_off + frag_len) > (unsigned long)max) { - SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE); - return SSL_AD_ILLEGAL_PARAMETER; - } - - if (s->d1->r_msg_hdr.frag_off == 0) { /* first fragment */ - /* - * msg_len is limited to 2^24, but is effectively checked against max - * above - * - * Make buffer slightly larger than message length as a precaution - * against small OOB reads e.g. CVE-2016-6306 - */ - if (!BUF_MEM_grow_clean - (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH + 16)) { - SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB); - return SSL_AD_INTERNAL_ERROR; - } - - s->s3->tmp.message_size = msg_len; - s->d1->r_msg_hdr.msg_len = msg_len; - s->s3->tmp.message_type = msg_hdr->type; - s->d1->r_msg_hdr.type = msg_hdr->type; - s->d1->r_msg_hdr.seq = msg_hdr->seq; - } else if (msg_len != s->d1->r_msg_hdr.msg_len) { - /* - * They must be playing with us! BTW, failure to enforce upper limit - * would open possibility for buffer overrun. - */ - SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE); - return SSL_AD_ILLEGAL_PARAMETER; - } - - return 0; /* no error */ -} - -static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) -{ - /*- - * (0) check whether the desired fragment is available - * if so: - * (1) copy over the fragment to s->init_buf->data[] - * (2) update s->init_num - */ - pitem *item; - hm_fragment *frag; - int al; - - *ok = 0; - do { - item = pqueue_peek(s->d1->buffered_messages); - if (item == NULL) - return 0; - - frag = (hm_fragment *)item->data; - - if (frag->msg_header.seq < s->d1->handshake_read_seq) { - /* This is a stale message that has been buffered so clear it */ - pqueue_pop(s->d1->buffered_messages); - dtls1_hm_fragment_free(frag); - pitem_free(item); - item = NULL; - frag = NULL; - } - } while (item == NULL); - - - /* Don't return if reassembly still in progress */ - if (frag->reassembly != NULL) - return 0; - - if (s->d1->handshake_read_seq == frag->msg_header.seq) { - unsigned long frag_len = frag->msg_header.frag_len; - pqueue_pop(s->d1->buffered_messages); - - al = dtls1_preprocess_fragment(s, &frag->msg_header, max); - - if (al == 0) { /* no alert */ - unsigned char *p = - (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - memcpy(&p[frag->msg_header.frag_off], frag->fragment, - frag->msg_header.frag_len); - } - - dtls1_hm_fragment_free(frag); - pitem_free(item); - - if (al == 0) { - *ok = 1; - return frag_len; - } - - ssl3_send_alert(s, SSL3_AL_FATAL, al); - s->init_num = 0; - *ok = 0; - return -1; - } else - return 0; -} - -/* - * dtls1_max_handshake_message_len returns the maximum number of bytes - * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but - * may be greater if the maximum certificate list size requires it. - */ -static unsigned long dtls1_max_handshake_message_len(const SSL *s) -{ - unsigned long max_len = - DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; - if (max_len < (unsigned long)s->max_cert_list) - return s->max_cert_list; - return max_len; -} - -static int -dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr, int *ok) -{ - hm_fragment *frag = NULL; - pitem *item = NULL; - int i = -1, is_complete; - unsigned char seq64be[8]; - unsigned long frag_len = msg_hdr->frag_len; - - if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len || - msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) - goto err; - - if (frag_len == 0) - return DTLS1_HM_FRAGMENT_RETRY; - - /* Try to find item in queue */ - memset(seq64be, 0, sizeof(seq64be)); - seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); - seq64be[7] = (unsigned char)msg_hdr->seq; - item = pqueue_find(s->d1->buffered_messages, seq64be); - - if (item == NULL) { - frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); - if (frag == NULL) - goto err; - memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); - frag->msg_header.frag_len = frag->msg_header.msg_len; - frag->msg_header.frag_off = 0; - } else { - frag = (hm_fragment *)item->data; - if (frag->msg_header.msg_len != msg_hdr->msg_len) { - item = NULL; - frag = NULL; - goto err; - } - } - - /* - * If message is already reassembled, this must be a retransmit and can - * be dropped. In this case item != NULL and so frag does not need to be - * freed. - */ - if (frag->reassembly == NULL) { - unsigned char devnull[256]; - - while (frag_len) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, - devnull, - frag_len > - sizeof(devnull) ? sizeof(devnull) : - frag_len, 0); - if (i <= 0) - goto err; - frag_len -= i; - } - return DTLS1_HM_FRAGMENT_RETRY; - } - - /* read the body of the fragment (header has already been read */ - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, - frag->fragment + msg_hdr->frag_off, - frag_len, 0); - if ((unsigned long)i != frag_len) - i = -1; - if (i <= 0) - goto err; - - RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, - (long)(msg_hdr->frag_off + frag_len)); - - RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len, - is_complete); - - if (is_complete) { - OPENSSL_free(frag->reassembly); - frag->reassembly = NULL; - } - - if (item == NULL) { - item = pitem_new(seq64be, frag); - if (item == NULL) { - i = -1; - goto err; - } - - item = pqueue_insert(s->d1->buffered_messages, item); - /* - * pqueue_insert fails iff a duplicate item is inserted. However, - * |item| cannot be a duplicate. If it were, |pqueue_find|, above, - * would have returned it and control would never have reached this - * branch. - */ - OPENSSL_assert(item != NULL); - } - - return DTLS1_HM_FRAGMENT_RETRY; - - err: - if (frag != NULL && item == NULL) - dtls1_hm_fragment_free(frag); - *ok = 0; - return i; -} - -static int -dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr, - int *ok) -{ - int i = -1; - hm_fragment *frag = NULL; - pitem *item = NULL; - unsigned char seq64be[8]; - unsigned long frag_len = msg_hdr->frag_len; - - if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len) - goto err; - - /* Try to find item in queue, to prevent duplicate entries */ - memset(seq64be, 0, sizeof(seq64be)); - seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); - seq64be[7] = (unsigned char)msg_hdr->seq; - item = pqueue_find(s->d1->buffered_messages, seq64be); - - /* - * If we already have an entry and this one is a fragment, don't discard - * it and rather try to reassemble it. - */ - if (item != NULL && frag_len != msg_hdr->msg_len) - item = NULL; - - /* - * Discard the message if sequence number was already there, is too far - * in the future, already in the queue or if we received a FINISHED - * before the SERVER_HELLO, which then must be a stale retransmit. - */ - if (msg_hdr->seq <= s->d1->handshake_read_seq || - msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL || - (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED)) - { - unsigned char devnull[256]; - - while (frag_len) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, - devnull, - frag_len > - sizeof(devnull) ? sizeof(devnull) : - frag_len, 0); - if (i <= 0) - goto err; - frag_len -= i; - } - } else { - if (frag_len != msg_hdr->msg_len) - return dtls1_reassemble_fragment(s, msg_hdr, ok); - - if (frag_len > dtls1_max_handshake_message_len(s)) - goto err; - - frag = dtls1_hm_fragment_new(frag_len, 0); - if (frag == NULL) - goto err; - - memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); - - if (frag_len) { - /* - * read the body of the fragment (header has already been read - */ - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, - frag->fragment, frag_len, 0); - if ((unsigned long)i != frag_len) - i = -1; - if (i <= 0) - goto err; - } - - item = pitem_new(seq64be, frag); - if (item == NULL) - goto err; - - item = pqueue_insert(s->d1->buffered_messages, item); - /* - * pqueue_insert fails iff a duplicate item is inserted. However, - * |item| cannot be a duplicate. If it were, |pqueue_find|, above, - * would have returned it. Then, either |frag_len| != - * |msg_hdr->msg_len| in which case |item| is set to NULL and it will - * have been processed with |dtls1_reassemble_fragment|, above, or - * the record will have been discarded. - */ - OPENSSL_assert(item != NULL); - } - - return DTLS1_HM_FRAGMENT_RETRY; - - err: - if (frag != NULL && item == NULL) - dtls1_hm_fragment_free(frag); - *ok = 0; - return i; -} - -static long -dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) -{ - unsigned char wire[DTLS1_HM_HEADER_LENGTH]; - unsigned long len, frag_off, frag_len; - int i, al; - struct hm_header_st msg_hdr; - - redo: - /* see if we have the required fragment already */ - if ((frag_len = dtls1_retrieve_buffered_fragment(s, max, ok)) || *ok) { - if (*ok) - s->init_num = frag_len; - return frag_len; - } - - /* read handshake message header */ - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, wire, - DTLS1_HM_HEADER_LENGTH, 0); - if (i <= 0) { /* nbio, or an error */ - s->rwstate = SSL_READING; - *ok = 0; - return i; - } - /* Handshake fails if message header is incomplete */ - if (i != DTLS1_HM_HEADER_LENGTH) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - - /* parse the message fragment header */ - dtls1_get_message_header(wire, &msg_hdr); - - len = msg_hdr.msg_len; - frag_off = msg_hdr.frag_off; - frag_len = msg_hdr.frag_len; - - /* - * We must have at least frag_len bytes left in the record to be read. - * Fragments must not span records. - */ - if (frag_len > s->s3->rrec.length) { - al = SSL3_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_BAD_LENGTH); - goto f_err; - } - - /* - * if this is a future (or stale) message it gets buffered - * (or dropped)--no further processing at this time - * While listening, we accept seq 1 (ClientHello with cookie) - * although we're still expecting seq 0 (ClientHello) - */ - if (msg_hdr.seq != s->d1->handshake_read_seq - && !(s->d1->listen && msg_hdr.seq == 1)) - return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); - - if (frag_len && frag_len < len) - return dtls1_reassemble_fragment(s, &msg_hdr, ok); - - if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && - wire[0] == SSL3_MT_HELLO_REQUEST) { - /* - * The server may always send 'Hello Request' messages -- we are - * doing a handshake anyway now, so ignore them if their format is - * correct. Does not count for 'Finished' MAC. - */ - if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - wire, DTLS1_HM_HEADER_LENGTH, s, - s->msg_callback_arg); - - s->init_num = 0; - goto redo; - } else { /* Incorrectly formated Hello request */ - - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, - SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - } - - if ((al = dtls1_preprocess_fragment(s, &msg_hdr, max))) - goto f_err; - - if (frag_len > 0) { - unsigned char *p = - (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, - &p[frag_off], frag_len, 0); - - /* - * This shouldn't ever fail due to NBIO because we already checked - * that we have enough data in the record - */ - if (i <= 0) { - s->rwstate = SSL_READING; - *ok = 0; - return i; - } - } else - i = 0; - - /* - * XDTLS: an incorrectly formatted fragment should cause the handshake - * to fail - */ - if (i != (int)frag_len) { - al = SSL3_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL3_AD_ILLEGAL_PARAMETER); - goto f_err; - } - - *ok = 1; - s->state = stn; - - /* - * Note that s->init_num is *not* used as current offset in - * s->init_buf->data, but as a counter summing up fragments' lengths: as - * soon as they sum up to handshake packet length, we assume we have got - * all the fragments. - */ - s->init_num = frag_len; - return frag_len; - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - s->init_num = 0; - - *ok = 0; - return (-1); -} - -/*- - * for these 2 messages, we need to - * ssl->enc_read_ctx re-init - * ssl->s3->read_sequence zero - * ssl->s3->read_mac_secret re-init - * ssl->session->read_sym_enc assign - * ssl->session->read_compression assign - * ssl->session->read_hash assign - */ -int dtls1_send_change_cipher_spec(SSL *s, int a, int b) -{ - unsigned char *p; - - if (s->state == a) { - p = (unsigned char *)s->init_buf->data; - *p++ = SSL3_MT_CCS; - s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; - s->init_num = DTLS1_CCS_HEADER_LENGTH; - - if (s->version == DTLS1_BAD_VER) { - s->d1->next_handshake_write_seq++; - s2n(s->d1->handshake_write_seq, p); - s->init_num += 2; - } - - s->init_off = 0; - - dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, - s->d1->handshake_write_seq, 0, 0); - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 1); - - s->state = b; - } - - /* SSL3_ST_CW_CHANGE_B */ - return (dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC)); -} - -int dtls1_read_failed(SSL *s, int code) -{ - if (code > 0) { -#ifdef TLS_DEBUG - fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__); -#endif - return 1; - } - - if (!dtls1_is_timer_expired(s)) { - /* - * not a timeout, none of our business, let higher layers handle - * this. in fact it's probably an error - */ - return code; - } -#ifndef OPENSSL_NO_HEARTBEATS - /* done, no need to send a retransmit */ - if (!SSL_in_init(s) && !s->tlsext_hb_pending) -#else - /* done, no need to send a retransmit */ - if (!SSL_in_init(s)) -#endif - { - BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); - return code; - } -#if 0 /* for now, each alert contains only one - * record number */ - item = pqueue_peek(state->rcvd_records); - if (item) { - /* send an alert immediately for all the missing records */ - } else -#endif - -#if 0 /* no more alert sending, just retransmit the - * last set of messages */ - if (state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT) - ssl3_send_alert(s, SSL3_AL_WARNING, - DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); -#endif - - return dtls1_handle_timeout(s); -} - -int dtls1_get_queue_priority(unsigned short seq, int is_ccs) -{ - /* - * The index of the retransmission queue actually is the message sequence - * number, since the queue only contains messages of a single handshake. - * However, the ChangeCipherSpec has no message sequence number and so - * using only the sequence will result in the CCS and Finished having the - * same index. To prevent this, the sequence number is multiplied by 2. - * In case of a CCS 1 is subtracted. This does not only differ CSS and - * Finished, it also maintains the order of the index (important for - * priority queues) and fits in the unsigned short variable. - */ - return seq * 2 - is_ccs; -} - -int dtls1_retransmit_buffered_messages(SSL *s) -{ - pqueue sent = s->d1->sent_messages; - piterator iter; - pitem *item; - hm_fragment *frag; - int found = 0; - - iter = pqueue_iterator(sent); - - for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) { - frag = (hm_fragment *)item->data; - if (dtls1_retransmit_message(s, (unsigned short) - dtls1_get_queue_priority - (frag->msg_header.seq, - frag->msg_header.is_ccs), 0, - &found) <= 0 && found) { -#ifdef TLS_DEBUG - fprintf(stderr, "dtls1_retransmit_message() failed\n"); -#endif - return -1; - } - } - - return 1; -} - -int dtls1_buffer_message(SSL *s, int is_ccs) -{ - pitem *item; - hm_fragment *frag; - unsigned char seq64be[8]; - - /* - * this function is called immediately after a message has been - * serialized - */ - OPENSSL_assert(s->init_off == 0); - - frag = dtls1_hm_fragment_new(s->init_num, 0); - if (!frag) - return 0; - - memcpy(frag->fragment, s->init_buf->data, s->init_num); - - if (is_ccs) { - /* For DTLS1_BAD_VER the header length is non-standard */ - OPENSSL_assert(s->d1->w_msg_hdr.msg_len + - ((s->version==DTLS1_BAD_VER)?3:DTLS1_CCS_HEADER_LENGTH) - == (unsigned int)s->init_num); - } else { - OPENSSL_assert(s->d1->w_msg_hdr.msg_len + - DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num); - } - - frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; - frag->msg_header.seq = s->d1->w_msg_hdr.seq; - frag->msg_header.type = s->d1->w_msg_hdr.type; - frag->msg_header.frag_off = 0; - frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; - frag->msg_header.is_ccs = is_ccs; - - /* save current state */ - frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx; - frag->msg_header.saved_retransmit_state.write_hash = s->write_hash; - frag->msg_header.saved_retransmit_state.compress = s->compress; - frag->msg_header.saved_retransmit_state.session = s->session; - frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch; - - memset(seq64be, 0, sizeof(seq64be)); - seq64be[6] = - (unsigned - char)(dtls1_get_queue_priority(frag->msg_header.seq, - frag->msg_header.is_ccs) >> 8); - seq64be[7] = - (unsigned - char)(dtls1_get_queue_priority(frag->msg_header.seq, - frag->msg_header.is_ccs)); - - item = pitem_new(seq64be, frag); - if (item == NULL) { - dtls1_hm_fragment_free(frag); - return 0; - } -#if 0 - fprintf(stderr, "buffered messge: \ttype = %xx\n", msg_buf->type); - fprintf(stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len); - fprintf(stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num); -#endif - - pqueue_insert(s->d1->sent_messages, item); - return 1; -} - -int -dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, - int *found) -{ - int ret; - /* XDTLS: for now assuming that read/writes are blocking */ - pitem *item; - hm_fragment *frag; - unsigned long header_length; - unsigned char seq64be[8]; - struct dtls1_retransmit_state saved_state; - unsigned char save_write_sequence[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - /*- - OPENSSL_assert(s->init_num == 0); - OPENSSL_assert(s->init_off == 0); - */ - - /* XDTLS: the requested message ought to be found, otherwise error */ - memset(seq64be, 0, sizeof(seq64be)); - seq64be[6] = (unsigned char)(seq >> 8); - seq64be[7] = (unsigned char)seq; - - item = pqueue_find(s->d1->sent_messages, seq64be); - if (item == NULL) { -#ifdef TLS_DEBUG - fprintf(stderr, "retransmit: message %d non-existant\n", seq); -#endif - *found = 0; - return 0; - } - - *found = 1; - frag = (hm_fragment *)item->data; - - if (frag->msg_header.is_ccs) - header_length = DTLS1_CCS_HEADER_LENGTH; - else - header_length = DTLS1_HM_HEADER_LENGTH; - - memcpy(s->init_buf->data, frag->fragment, - frag->msg_header.msg_len + header_length); - s->init_num = frag->msg_header.msg_len + header_length; - - dtls1_set_message_header_int(s, frag->msg_header.type, - frag->msg_header.msg_len, - frag->msg_header.seq, 0, - frag->msg_header.frag_len); - - /* save current state */ - saved_state.enc_write_ctx = s->enc_write_ctx; - saved_state.write_hash = s->write_hash; - saved_state.compress = s->compress; - saved_state.session = s->session; - saved_state.epoch = s->d1->w_epoch; - saved_state.epoch = s->d1->w_epoch; - - s->d1->retransmitting = 1; - - /* restore state in which the message was originally sent */ - s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx; - s->write_hash = frag->msg_header.saved_retransmit_state.write_hash; - s->compress = frag->msg_header.saved_retransmit_state.compress; - s->session = frag->msg_header.saved_retransmit_state.session; - s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch; - - if (frag->msg_header.saved_retransmit_state.epoch == - saved_state.epoch - 1) { - memcpy(save_write_sequence, s->s3->write_sequence, - sizeof(s->s3->write_sequence)); - memcpy(s->s3->write_sequence, s->d1->last_write_sequence, - sizeof(s->s3->write_sequence)); - } - - ret = dtls1_do_write(s, frag->msg_header.is_ccs ? - SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); - - /* restore current state */ - s->enc_write_ctx = saved_state.enc_write_ctx; - s->write_hash = saved_state.write_hash; - s->compress = saved_state.compress; - s->session = saved_state.session; - s->d1->w_epoch = saved_state.epoch; - - if (frag->msg_header.saved_retransmit_state.epoch == - saved_state.epoch - 1) { - memcpy(s->d1->last_write_sequence, s->s3->write_sequence, - sizeof(s->s3->write_sequence)); - memcpy(s->s3->write_sequence, save_write_sequence, - sizeof(s->s3->write_sequence)); - } - - s->d1->retransmitting = 0; - - (void)BIO_flush(SSL_get_wbio(s)); - return ret; -} - -unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p, - unsigned char mt, unsigned long len, - unsigned long frag_off, - unsigned long frag_len) -{ - /* Don't change sequence numbers while listening */ - if (frag_off == 0 && !s->d1->listen) { - s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; - s->d1->next_handshake_write_seq++; - } - - dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, - frag_off, frag_len); - - return p += DTLS1_HM_HEADER_LENGTH; -} - -/* don't actually do the writing, wait till the MTU has been retrieved */ -static void -dtls1_set_message_header_int(SSL *s, unsigned char mt, - unsigned long len, unsigned short seq_num, - unsigned long frag_off, unsigned long frag_len) -{ - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - - msg_hdr->type = mt; - msg_hdr->msg_len = len; - msg_hdr->seq = seq_num; - msg_hdr->frag_off = frag_off; - msg_hdr->frag_len = frag_len; -} - -static void -dtls1_fix_message_header(SSL *s, unsigned long frag_off, - unsigned long frag_len) -{ - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - - msg_hdr->frag_off = frag_off; - msg_hdr->frag_len = frag_len; -} - -static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p) -{ - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - - *p++ = msg_hdr->type; - l2n3(msg_hdr->msg_len, p); - - s2n(msg_hdr->seq, p); - l2n3(msg_hdr->frag_off, p); - l2n3(msg_hdr->frag_len, p); - - return p; -} - -unsigned int dtls1_link_min_mtu(void) -{ - return (g_probable_mtu[(sizeof(g_probable_mtu) / - sizeof(g_probable_mtu[0])) - 1]); -} - -unsigned int dtls1_min_mtu(SSL *s) -{ - return dtls1_link_min_mtu() - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); -} - -void -dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) -{ - memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - msg_hdr->type = *(data++); - n2l3(data, msg_hdr->msg_len); - - n2s(data, msg_hdr->seq); - n2l3(data, msg_hdr->frag_off); - n2l3(data, msg_hdr->frag_len); -} - -void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr) -{ - memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st)); - - ccs_hdr->type = *(data++); -} - -int dtls1_shutdown(SSL *s) -{ - int ret; -#ifndef OPENSSL_NO_SCTP - BIO *wbio; - - wbio = SSL_get_wbio(s); - if (wbio != NULL && BIO_dgram_is_sctp(wbio) && - !(s->shutdown & SSL_SENT_SHUTDOWN)) { - ret = BIO_dgram_sctp_wait_for_dry(wbio); - if (ret < 0) - return -1; - - if (ret == 0) - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1, - NULL); - } -#endif - ret = ssl3_shutdown(s); -#ifndef OPENSSL_NO_SCTP - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL); -#endif - return ret; -} - -#ifndef OPENSSL_NO_HEARTBEATS -int dtls1_process_heartbeat(SSL *s) -{ - unsigned char *p = &s->s3->rrec.data[0], *pl; - unsigned short hbtype; - unsigned int payload; - unsigned int padding = 16; /* Use minimum padding */ - - if (s->msg_callback) - s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, - &s->s3->rrec.data[0], s->s3->rrec.length, - s, s->msg_callback_arg); - - /* Read type and payload length first */ - if (1 + 2 + 16 > s->s3->rrec.length) - return 0; /* silently discard */ - if (s->s3->rrec.length > SSL3_RT_MAX_PLAIN_LENGTH) - return 0; /* silently discard per RFC 6520 sec. 4 */ - - hbtype = *p++; - n2s(p, payload); - if (1 + 2 + payload + 16 > s->s3->rrec.length) - return 0; /* silently discard per RFC 6520 sec. 4 */ - pl = p; - - if (hbtype == TLS1_HB_REQUEST) { - unsigned char *buffer, *bp; - unsigned int write_length = 1 /* heartbeat type */ + - 2 /* heartbeat length */ + - payload + padding; - int r; - - if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) - return 0; - - /* - * Allocate memory for the response, size is 1 byte message type, - * plus 2 bytes payload length, plus payload, plus padding - */ - buffer = OPENSSL_malloc(write_length); - if (buffer == NULL) - return -1; - bp = buffer; - - /* Enter response type, length and copy payload */ - *bp++ = TLS1_HB_RESPONSE; - s2n(payload, bp); - memcpy(bp, pl, payload); - bp += payload; - /* Random padding */ - if (RAND_bytes(bp, padding) <= 0) { - OPENSSL_free(buffer); - return -1; - } - - r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length); - - if (r >= 0 && s->msg_callback) - s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, - buffer, write_length, s, s->msg_callback_arg); - - OPENSSL_free(buffer); - - if (r < 0) - return r; - } else if (hbtype == TLS1_HB_RESPONSE) { - unsigned int seq; - - /* - * We only send sequence numbers (2 bytes unsigned int), and 16 - * random bytes, so we just try to read the sequence number - */ - n2s(pl, seq); - - if (payload == 18 && seq == s->tlsext_hb_seq) { - dtls1_stop_timer(s); - s->tlsext_hb_seq++; - s->tlsext_hb_pending = 0; - } - } - - return 0; -} - -int dtls1_heartbeat(SSL *s) -{ - unsigned char *buf, *p; - int ret = -1; - unsigned int payload = 18; /* Sequence number + random bytes */ - unsigned int padding = 16; /* Use minimum padding */ - - /* Only send if peer supports and accepts HB requests... */ - if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || - s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) { - SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); - return -1; - } - - /* ...and there is none in flight yet... */ - if (s->tlsext_hb_pending) { - SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING); - return -1; - } - - /* ...and no handshake in progress. */ - if (SSL_in_init(s) || s->in_handshake) { - SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE); - return -1; - } - - /* - * Check if padding is too long, payload and padding must not exceed 2^14 - * - 3 = 16381 bytes in total. - */ - OPENSSL_assert(payload + padding <= 16381); - - /*- - * Create HeartBeat message, we just use a sequence number - * as payload to distuingish different messages and add - * some random stuff. - * - Message Type, 1 byte - * - Payload Length, 2 bytes (unsigned int) - * - Payload, the sequence number (2 bytes uint) - * - Payload, random bytes (16 bytes uint) - * - Padding - */ - buf = OPENSSL_malloc(1 + 2 + payload + padding); - if (buf == NULL) - goto err; - p = buf; - /* Message Type */ - *p++ = TLS1_HB_REQUEST; - /* Payload length (18 bytes here) */ - s2n(payload, p); - /* Sequence number */ - s2n(s->tlsext_hb_seq, p); - /* 16 random bytes */ - if (RAND_bytes(p, 16) <= 0) - goto err; - p += 16; - /* Random padding */ - if (RAND_bytes(p, padding) <= 0) - goto err; - - ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); - if (ret >= 0) { - if (s->msg_callback) - s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, - buf, 3 + payload + padding, - s, s->msg_callback_arg); - - dtls1_start_timer(s); - s->tlsext_hb_pending = 1; - } - -err: - OPENSSL_free(buf); - - return ret; -} -#endif diff --git a/thirdparty/openssl/ssl/d1_clnt.c b/thirdparty/openssl/ssl/d1_clnt.c deleted file mode 100644 index 76451a346d..0000000000 --- a/thirdparty/openssl/ssl/d1_clnt.c +++ /dev/null @@ -1,875 +0,0 @@ -/* ssl/d1_clnt.c */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-2007 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 - * openssl-core@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). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include "ssl_locl.h" -#ifndef OPENSSL_NO_KRB5 -# include "kssl_lcl.h" -#endif -#include <openssl/buffer.h> -#include <openssl/rand.h> -#include <openssl/objects.h> -#include <openssl/evp.h> -#include <openssl/md5.h> -#include <openssl/bn.h> -#ifndef OPENSSL_NO_DH -# include <openssl/dh.h> -#endif - -static const SSL_METHOD *dtls1_get_client_method(int ver); -static int dtls1_get_hello_verify(SSL *s); - -static const SSL_METHOD *dtls1_get_client_method(int ver) -{ - if (ver == DTLS_ANY_VERSION) - return DTLS_client_method(); - else if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER) - return DTLSv1_client_method(); - else if (ver == DTLS1_2_VERSION) - return DTLSv1_2_client_method(); - else - return NULL; -} - -IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, - DTLSv1_client_method, - ssl_undefined_function, - dtls1_connect, - dtls1_get_client_method, DTLSv1_enc_data) - -IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, - DTLSv1_2_client_method, - ssl_undefined_function, - dtls1_connect, - dtls1_get_client_method, DTLSv1_2_enc_data) - -IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, - DTLS_client_method, - ssl_undefined_function, - dtls1_connect, - dtls1_get_client_method, DTLSv1_2_enc_data) - -int dtls1_connect(SSL *s) -{ - BUF_MEM *buf = NULL; - unsigned long Time = (unsigned long)time(NULL); - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int ret = -1; - int new_state, state, skip = 0; -#ifndef OPENSSL_NO_SCTP - unsigned char sctpauthkey[64]; - char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; -#endif - - RAND_add(&Time, sizeof(Time), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - -#ifndef OPENSSL_NO_SCTP - /* - * Notify SCTP BIO socket to enter handshake mode and prevent stream - * identifier other than 0. Will be ignored if no SCTP is used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, - s->in_handshake, NULL); -#endif - -#ifndef OPENSSL_NO_HEARTBEATS - /* - * If we're awaiting a HeartbeatResponse, pretend we already got and - * don't await it anymore, because Heartbeats don't make sense during - * handshakes anyway. - */ - if (s->tlsext_hb_pending) { - dtls1_stop_timer(s); - s->tlsext_hb_pending = 0; - s->tlsext_hb_seq++; - } -#endif - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_RENEGOTIATE: - s->renegotiate = 1; - s->state = SSL_ST_CONNECT; - s->ctx->stats.sess_connect_renegotiate++; - /* break */ - case SSL_ST_BEFORE: - case SSL_ST_CONNECT: - case SSL_ST_BEFORE | SSL_ST_CONNECT: - case SSL_ST_OK | SSL_ST_CONNECT: - - s->server = 0; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00) && - (s->version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) { - SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR); - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - /* s->version=SSL3_VERSION; */ - s->type = SSL_ST_CONNECT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - s->init_buf = buf; - buf = NULL; - } - - if (!ssl3_setup_buffers(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - /* setup buffing BIO */ - if (!ssl_init_wbio_buffer(s, 0)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - /* don't push the buffering BIO quite yet */ - - s->state = SSL3_ST_CW_CLNT_HELLO_A; - s->ctx->stats.sess_connect++; - s->init_num = 0; - /* mark client_random uninitialized */ - memset(s->s3->client_random, 0, sizeof(s->s3->client_random)); - s->d1->send_cookie = 0; - s->hit = 0; - s->d1->change_cipher_spec_ok = 0; - /* - * Should have been reset by ssl3_get_finished, too. - */ - s->s3->change_cipher_spec = 0; - break; - -#ifndef OPENSSL_NO_SCTP - case DTLS1_SCTP_ST_CR_READ_SOCK: - - if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { - s->s3->in_read_app_data = 2; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - ret = -1; - goto end; - } - - s->state = s->s3->tmp.next_state; - break; - - case DTLS1_SCTP_ST_CW_WRITE_SOCK: - /* read app data until dry event */ - - ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); - if (ret < 0) - goto end; - - if (ret == 0) { - s->s3->in_read_app_data = 2; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - ret = -1; - goto end; - } - - s->state = s->d1->next_state; - break; -#endif - - case SSL3_ST_CW_CLNT_HELLO_A: - s->shutdown = 0; - - /* every DTLS ClientHello resets Finished MAC */ - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - /* fall thru */ - case SSL3_ST_CW_CLNT_HELLO_B: - dtls1_start_timer(s); - ret = ssl3_client_hello(s); - if (ret <= 0) - goto end; - - if (s->d1->send_cookie) { - s->state = SSL3_ST_CW_FLUSH; - s->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A; - } else - s->state = SSL3_ST_CR_SRVR_HELLO_A; - - s->init_num = 0; - -#ifndef OPENSSL_NO_SCTP - /* Disable buffering for SCTP */ - if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) { -#endif - /* - * turn on buffering for the next lot of output - */ - if (s->bbio != s->wbio) - s->wbio = BIO_push(s->bbio, s->wbio); -#ifndef OPENSSL_NO_SCTP - } -#endif - - break; - - case SSL3_ST_CR_SRVR_HELLO_A: - case SSL3_ST_CR_SRVR_HELLO_B: - ret = ssl3_get_server_hello(s); - if (ret <= 0) - goto end; - else { - if (s->hit) { -#ifndef OPENSSL_NO_SCTP - /* - * Add new shared key for SCTP-Auth, will be ignored if - * no SCTP used. - */ - snprintf((char *)labelbuffer, - sizeof(DTLS1_SCTP_AUTH_LABEL), - DTLS1_SCTP_AUTH_LABEL); - - if (SSL_export_keying_material(s, sctpauthkey, - sizeof(sctpauthkey), - labelbuffer, - sizeof(labelbuffer), NULL, 0, - 0) <= 0) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - BIO_ctrl(SSL_get_wbio(s), - BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, - sizeof(sctpauthkey), sctpauthkey); -#endif - - s->state = SSL3_ST_CR_FINISHED_A; - if (s->tlsext_ticket_expected) { - /* receive renewed session ticket */ - s->state = SSL3_ST_CR_SESSION_TICKET_A; - } - } else - s->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; - } - s->init_num = 0; - break; - - case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: - case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: - - ret = dtls1_get_hello_verify(s); - if (ret <= 0) - goto end; - dtls1_stop_timer(s); - if (s->d1->send_cookie) /* start again, with a cookie */ - s->state = SSL3_ST_CW_CLNT_HELLO_A; - else - s->state = SSL3_ST_CR_CERT_A; - s->init_num = 0; - break; - - case SSL3_ST_CR_CERT_A: - case SSL3_ST_CR_CERT_B: - /* Check if it is anon DH or PSK */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && - !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - ret = ssl3_get_server_certificate(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_status_expected) - s->state = SSL3_ST_CR_CERT_STATUS_A; - else - s->state = SSL3_ST_CR_KEY_EXCH_A; - } else { - skip = 1; - s->state = SSL3_ST_CR_KEY_EXCH_A; - } -#else - } else - skip = 1; - - s->state = SSL3_ST_CR_KEY_EXCH_A; -#endif - s->init_num = 0; - break; - - case SSL3_ST_CR_KEY_EXCH_A: - case SSL3_ST_CR_KEY_EXCH_B: - ret = ssl3_get_key_exchange(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_CERT_REQ_A; - s->init_num = 0; - - /* - * at this point we check that we have the required stuff from - * the server - */ - if (!ssl3_check_cert_and_algorithm(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - break; - - case SSL3_ST_CR_CERT_REQ_A: - case SSL3_ST_CR_CERT_REQ_B: - ret = ssl3_get_certificate_request(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_SRVR_DONE_A; - s->init_num = 0; - break; - - case SSL3_ST_CR_SRVR_DONE_A: - case SSL3_ST_CR_SRVR_DONE_B: - ret = ssl3_get_server_done(s); - if (ret <= 0) - goto end; - dtls1_stop_timer(s); - if (s->s3->tmp.cert_req) - s->s3->tmp.next_state = SSL3_ST_CW_CERT_A; - else - s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; - s->init_num = 0; - -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && - state == SSL_ST_RENEGOTIATE) - s->state = DTLS1_SCTP_ST_CR_READ_SOCK; - else -#endif - s->state = s->s3->tmp.next_state; - break; - - case SSL3_ST_CW_CERT_A: - case SSL3_ST_CW_CERT_B: - case SSL3_ST_CW_CERT_C: - case SSL3_ST_CW_CERT_D: - dtls1_start_timer(s); - ret = ssl3_send_client_certificate(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CW_KEY_EXCH_A; - s->init_num = 0; - break; - - case SSL3_ST_CW_KEY_EXCH_A: - case SSL3_ST_CW_KEY_EXCH_B: - dtls1_start_timer(s); - ret = ssl3_send_client_key_exchange(s); - if (ret <= 0) - goto end; - -#ifndef OPENSSL_NO_SCTP - /* - * Add new shared key for SCTP-Auth, will be ignored if no SCTP - * used. - */ - snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), - DTLS1_SCTP_AUTH_LABEL); - - if (SSL_export_keying_material(s, sctpauthkey, - sizeof(sctpauthkey), labelbuffer, - sizeof(labelbuffer), NULL, 0, 0) <= 0) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, - sizeof(sctpauthkey), sctpauthkey); -#endif - - /* - * EAY EAY EAY need to check for DH fix cert sent back - */ - /* - * For TLS, cert_req is set to 2, so a cert chain of nothing is - * sent, but no verify packet is sent - */ - if (s->s3->tmp.cert_req == 1) { - s->state = SSL3_ST_CW_CERT_VRFY_A; - } else { -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = SSL3_ST_CW_CHANGE_A; - s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; - } else -#endif - s->state = SSL3_ST_CW_CHANGE_A; - } - - s->init_num = 0; - break; - - case SSL3_ST_CW_CERT_VRFY_A: - case SSL3_ST_CW_CERT_VRFY_B: - dtls1_start_timer(s); - ret = ssl3_send_client_verify(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = SSL3_ST_CW_CHANGE_A; - s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; - } else -#endif - s->state = SSL3_ST_CW_CHANGE_A; - s->init_num = 0; - break; - - case SSL3_ST_CW_CHANGE_A: - case SSL3_ST_CW_CHANGE_B: - if (!s->hit) - dtls1_start_timer(s); - ret = dtls1_send_change_cipher_spec(s, - SSL3_ST_CW_CHANGE_A, - SSL3_ST_CW_CHANGE_B); - if (ret <= 0) - goto end; - - s->state = SSL3_ST_CW_FINISHED_A; - s->init_num = 0; - - s->session->cipher = s->s3->tmp.new_cipher; -#ifdef OPENSSL_NO_COMP - s->session->compress_meth = 0; -#else - if (s->s3->tmp.new_compression == NULL) - s->session->compress_meth = 0; - else - s->session->compress_meth = s->s3->tmp.new_compression->id; -#endif - if (!s->method->ssl3_enc->setup_key_block(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - if (!s->method->ssl3_enc->change_cipher_state(s, - SSL3_CHANGE_CIPHER_CLIENT_WRITE)) - { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } -#ifndef OPENSSL_NO_SCTP - if (s->hit) { - /* - * Change to new shared key of SCTP-Auth, will be ignored if - * no SCTP used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, - 0, NULL); - } -#endif - - dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); - break; - - case SSL3_ST_CW_FINISHED_A: - case SSL3_ST_CW_FINISHED_B: - if (!s->hit) - dtls1_start_timer(s); - ret = ssl3_send_finished(s, - SSL3_ST_CW_FINISHED_A, - SSL3_ST_CW_FINISHED_B, - s->method-> - ssl3_enc->client_finished_label, - s->method-> - ssl3_enc->client_finished_label_len); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CW_FLUSH; - - /* clear flags */ - s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; - if (s->hit) { - s->s3->tmp.next_state = SSL_ST_OK; -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = s->s3->tmp.next_state; - s->s3->tmp.next_state = DTLS1_SCTP_ST_CW_WRITE_SOCK; - } -#endif - if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) { - s->state = SSL_ST_OK; -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = SSL_ST_OK; - s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; - } -#endif - s->s3->flags |= SSL3_FLAGS_POP_BUFFER; - s->s3->delay_buf_pop_ret = 0; - } - } else { -#ifndef OPENSSL_NO_SCTP - /* - * Change to new shared key of SCTP-Auth, will be ignored if - * no SCTP used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, - 0, NULL); -#endif - -#ifndef OPENSSL_NO_TLSEXT - /* - * Allow NewSessionTicket if ticket expected - */ - if (s->tlsext_ticket_expected) - s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; - else -#endif - - s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A; - } - s->init_num = 0; - break; - -#ifndef OPENSSL_NO_TLSEXT - case SSL3_ST_CR_SESSION_TICKET_A: - case SSL3_ST_CR_SESSION_TICKET_B: - ret = ssl3_get_new_session_ticket(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_FINISHED_A; - s->init_num = 0; - break; - - case SSL3_ST_CR_CERT_STATUS_A: - case SSL3_ST_CR_CERT_STATUS_B: - ret = ssl3_get_cert_status(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_KEY_EXCH_A; - s->init_num = 0; - break; -#endif - - case SSL3_ST_CR_FINISHED_A: - case SSL3_ST_CR_FINISHED_B: - s->d1->change_cipher_spec_ok = 1; - ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, - SSL3_ST_CR_FINISHED_B); - if (ret <= 0) - goto end; - dtls1_stop_timer(s); - - if (s->hit) - s->state = SSL3_ST_CW_CHANGE_A; - else - s->state = SSL_ST_OK; - -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && - state == SSL_ST_RENEGOTIATE) { - s->d1->next_state = s->state; - s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; - } -#endif - - s->init_num = 0; - break; - - case SSL3_ST_CW_FLUSH: - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { - /* - * If the write error was fatal, stop trying - */ - if (!BIO_should_retry(s->wbio)) { - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; - } - - ret = -1; - goto end; - } - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; - break; - - case SSL_ST_OK: - /* clean a few things up */ - ssl3_cleanup_key_block(s); - -#if 0 - if (s->init_buf != NULL) { - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - } -#endif - - /* - * If we are not 'joining' the last two packets, remove the - * buffering now - */ - if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) - ssl_free_wbio_buffer(s); - /* else do it later in ssl3_write */ - - s->init_num = 0; - s->renegotiate = 0; - s->new_session = 0; - - ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); - if (s->hit) - s->ctx->stats.sess_hit++; - - ret = 1; - /* s->server=0; */ - s->handshake_func = dtls1_connect; - s->ctx->stats.sess_connect_good++; - - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - - /* done with handshaking */ - s->d1->handshake_read_seq = 0; - s->d1->next_handshake_write_seq = 0; - dtls1_clear_received_buffer(s); - goto end; - /* break; */ - - case SSL_ST_ERR: - default: - SSLerr(SSL_F_DTLS1_CONNECT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* break; */ - } - - /* did we do anything */ - if (!s->s3->tmp.reuse_message && !skip) { - if (s->debug) { - if ((ret = BIO_flush(s->wbio)) <= 0) - goto end; - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_CONNECT_LOOP, 1); - s->state = new_state; - } - } - skip = 0; - } - end: - s->in_handshake--; - -#ifndef OPENSSL_NO_SCTP - /* - * Notify SCTP BIO socket to leave handshake mode and allow stream - * identifier other than 0. Will be ignored if no SCTP is used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, - s->in_handshake, NULL); -#endif - - if (buf != NULL) - BUF_MEM_free(buf); - if (cb != NULL) - cb(s, SSL_CB_CONNECT_EXIT, ret); - return (ret); -} - -static int dtls1_get_hello_verify(SSL *s) -{ - int n, al, ok = 0; - unsigned char *data; - unsigned int cookie_len; - - s->first_packet = 1; - n = s->method->ssl_get_message(s, - DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, - DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, - -1, s->max_cert_list, &ok); - s->first_packet = 0; - - if (!ok) - return ((int)n); - - if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) { - s->d1->send_cookie = 0; - s->s3->tmp.reuse_message = 1; - return (1); - } - - data = (unsigned char *)s->init_msg; -#if 0 - if (s->method->version != DTLS_ANY_VERSION && - ((data[0] != (s->version >> 8)) || (data[1] != (s->version & 0xff)))) - { - SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY, SSL_R_WRONG_SSL_VERSION); - s->version = (s->version & 0xff00) | data[1]; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } -#endif - data += 2; - - cookie_len = *(data++); - if (cookie_len > sizeof(s->d1->cookie)) { - al = SSL_AD_ILLEGAL_PARAMETER; - goto f_err; - } - - memcpy(s->d1->cookie, data, cookie_len); - s->d1->cookie_len = cookie_len; - - s->d1->send_cookie = 1; - return 1; - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - s->state = SSL_ST_ERR; - return -1; -} diff --git a/thirdparty/openssl/ssl/d1_lib.c b/thirdparty/openssl/ssl/d1_lib.c deleted file mode 100644 index debd4fd5dc..0000000000 --- a/thirdparty/openssl/ssl/d1_lib.c +++ /dev/null @@ -1,588 +0,0 @@ -/* ssl/d1_lib.c */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-2005 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 - * openssl-core@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). - * - */ - -#include <stdio.h> -#define USE_SOCKETS -#include <openssl/objects.h> -#include "ssl_locl.h" - -#if defined(OPENSSL_SYS_VMS) -# include <sys/timeb.h> -#endif - -static void get_current_time(struct timeval *t); -static void dtls1_set_handshake_header(SSL *s, int type, unsigned long len); -static int dtls1_handshake_write(SSL *s); -const char dtls1_version_str[] = "DTLSv1" OPENSSL_VERSION_PTEXT; -int dtls1_listen(SSL *s, struct sockaddr *client); - -SSL3_ENC_METHOD DTLSv1_enc_data = { - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV, - DTLS1_HM_HEADER_LENGTH, - dtls1_set_handshake_header, - dtls1_handshake_write -}; - -SSL3_ENC_METHOD DTLSv1_2_enc_data = { - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS - | SSL_ENC_FLAG_SHA256_PRF | SSL_ENC_FLAG_TLS1_2_CIPHERS, - DTLS1_HM_HEADER_LENGTH, - dtls1_set_handshake_header, - dtls1_handshake_write -}; - -long dtls1_default_timeout(void) -{ - /* - * 2 hours, the 24 hours mentioned in the DTLSv1 spec is way too long for - * http, the cache would over fill - */ - return (60 * 60 * 2); -} - -int dtls1_new(SSL *s) -{ - DTLS1_STATE *d1; - - if (!ssl3_new(s)) - return (0); - if ((d1 = OPENSSL_malloc(sizeof *d1)) == NULL) - return (0); - memset(d1, 0, sizeof *d1); - - /* d1->handshake_epoch=0; */ - - d1->unprocessed_rcds.q = pqueue_new(); - d1->processed_rcds.q = pqueue_new(); - d1->buffered_messages = pqueue_new(); - d1->sent_messages = pqueue_new(); - d1->buffered_app_data.q = pqueue_new(); - - if (s->server) { - d1->cookie_len = sizeof(s->d1->cookie); - } - - d1->link_mtu = 0; - d1->mtu = 0; - - if (!d1->unprocessed_rcds.q || !d1->processed_rcds.q - || !d1->buffered_messages || !d1->sent_messages - || !d1->buffered_app_data.q) { - if (d1->unprocessed_rcds.q) - pqueue_free(d1->unprocessed_rcds.q); - if (d1->processed_rcds.q) - pqueue_free(d1->processed_rcds.q); - if (d1->buffered_messages) - pqueue_free(d1->buffered_messages); - if (d1->sent_messages) - pqueue_free(d1->sent_messages); - if (d1->buffered_app_data.q) - pqueue_free(d1->buffered_app_data.q); - OPENSSL_free(d1); - return (0); - } - - s->d1 = d1; - s->method->ssl_clear(s); - return (1); -} - -static void dtls1_clear_queues(SSL *s) -{ - pitem *item = NULL; - DTLS1_RECORD_DATA *rdata; - - while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { - rdata = (DTLS1_RECORD_DATA *)item->data; - if (rdata->rbuf.buf) { - OPENSSL_free(rdata->rbuf.buf); - } - OPENSSL_free(item->data); - pitem_free(item); - } - - while ((item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) { - rdata = (DTLS1_RECORD_DATA *)item->data; - if (rdata->rbuf.buf) { - OPENSSL_free(rdata->rbuf.buf); - } - OPENSSL_free(item->data); - pitem_free(item); - } - - while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { - rdata = (DTLS1_RECORD_DATA *)item->data; - if (rdata->rbuf.buf) { - OPENSSL_free(rdata->rbuf.buf); - } - OPENSSL_free(item->data); - pitem_free(item); - } - - dtls1_clear_received_buffer(s); - dtls1_clear_sent_buffer(s); -} - -void dtls1_clear_received_buffer(SSL *s) -{ - pitem *item = NULL; - hm_fragment *frag = NULL; - - while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { - frag = (hm_fragment *)item->data; - dtls1_hm_fragment_free(frag); - pitem_free(item); - } -} - -void dtls1_clear_sent_buffer(SSL *s) -{ - pitem *item = NULL; - hm_fragment *frag = NULL; - - while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { - frag = (hm_fragment *)item->data; - dtls1_hm_fragment_free(frag); - pitem_free(item); - } -} - - -void dtls1_free(SSL *s) -{ - ssl3_free(s); - - dtls1_clear_queues(s); - - pqueue_free(s->d1->unprocessed_rcds.q); - pqueue_free(s->d1->processed_rcds.q); - pqueue_free(s->d1->buffered_messages); - pqueue_free(s->d1->sent_messages); - pqueue_free(s->d1->buffered_app_data.q); - - OPENSSL_free(s->d1); - s->d1 = NULL; -} - -void dtls1_clear(SSL *s) -{ - pqueue unprocessed_rcds; - pqueue processed_rcds; - pqueue buffered_messages; - pqueue sent_messages; - pqueue buffered_app_data; - unsigned int mtu; - unsigned int link_mtu; - - if (s->d1) { - unprocessed_rcds = s->d1->unprocessed_rcds.q; - processed_rcds = s->d1->processed_rcds.q; - buffered_messages = s->d1->buffered_messages; - sent_messages = s->d1->sent_messages; - buffered_app_data = s->d1->buffered_app_data.q; - mtu = s->d1->mtu; - link_mtu = s->d1->link_mtu; - - dtls1_clear_queues(s); - - memset(s->d1, 0, sizeof(*(s->d1))); - - if (s->server) { - s->d1->cookie_len = sizeof(s->d1->cookie); - } - - if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) { - s->d1->mtu = mtu; - s->d1->link_mtu = link_mtu; - } - - s->d1->unprocessed_rcds.q = unprocessed_rcds; - s->d1->processed_rcds.q = processed_rcds; - s->d1->buffered_messages = buffered_messages; - s->d1->sent_messages = sent_messages; - s->d1->buffered_app_data.q = buffered_app_data; - } - - ssl3_clear(s); - if (s->options & SSL_OP_CISCO_ANYCONNECT) - s->client_version = s->version = DTLS1_BAD_VER; - else if (s->method->version == DTLS_ANY_VERSION) - s->version = DTLS1_2_VERSION; - else - s->version = s->method->version; -} - -long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) -{ - int ret = 0; - - switch (cmd) { - case DTLS_CTRL_GET_TIMEOUT: - if (dtls1_get_timeout(s, (struct timeval *)parg) != NULL) { - ret = 1; - } - break; - case DTLS_CTRL_HANDLE_TIMEOUT: - ret = dtls1_handle_timeout(s); - break; - case DTLS_CTRL_LISTEN: - ret = dtls1_listen(s, parg); - break; - case SSL_CTRL_CHECK_PROTO_VERSION: - /* - * For library-internal use; checks that the current protocol is the - * highest enabled version (according to s->ctx->method, as version - * negotiation may have changed s->method). - */ - if (s->version == s->ctx->method->version) - return 1; - /* - * Apparently we're using a version-flexible SSL_METHOD (not at its - * highest protocol version). - */ - if (s->ctx->method->version == DTLS_method()->version) { -#if DTLS_MAX_VERSION != DTLS1_2_VERSION -# error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION. -#endif - if (!(s->options & SSL_OP_NO_DTLSv1_2)) - return s->version == DTLS1_2_VERSION; - if (!(s->options & SSL_OP_NO_DTLSv1)) - return s->version == DTLS1_VERSION; - } - return 0; /* Unexpected state; fail closed. */ - case DTLS_CTRL_SET_LINK_MTU: - if (larg < (long)dtls1_link_min_mtu()) - return 0; - s->d1->link_mtu = larg; - return 1; - case DTLS_CTRL_GET_LINK_MIN_MTU: - return (long)dtls1_link_min_mtu(); - case SSL_CTRL_SET_MTU: - /* - * We may not have a BIO set yet so can't call dtls1_min_mtu() - * We'll have to make do with dtls1_link_min_mtu() and max overhead - */ - if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD) - return 0; - s->d1->mtu = larg; - return larg; - default: - ret = ssl3_ctrl(s, cmd, larg, parg); - break; - } - return (ret); -} - -/* - * As it's impossible to use stream ciphers in "datagram" mode, this - * simple filter is designed to disengage them in DTLS. Unfortunately - * there is no universal way to identify stream SSL_CIPHER, so we have - * to explicitly list their SSL_* codes. Currently RC4 is the only one - * available, but if new ones emerge, they will have to be added... - */ -const SSL_CIPHER *dtls1_get_cipher(unsigned int u) -{ - const SSL_CIPHER *ciph = ssl3_get_cipher(u); - - if (ciph != NULL) { - if (ciph->algorithm_enc == SSL_RC4) - return NULL; - } - - return ciph; -} - -void dtls1_start_timer(SSL *s) -{ -#ifndef OPENSSL_NO_SCTP - /* Disable timer for SCTP */ - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); - return; - } -#endif - - /* If timer is not set, initialize duration with 1 second */ - if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { - s->d1->timeout_duration = 1; - } - - /* Set timeout to current time */ - get_current_time(&(s->d1->next_timeout)); - - /* Add duration to current time */ - s->d1->next_timeout.tv_sec += s->d1->timeout_duration; - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, - &(s->d1->next_timeout)); -} - -struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft) -{ - struct timeval timenow; - - /* If no timeout is set, just return NULL */ - if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { - return NULL; - } - - /* Get current time */ - get_current_time(&timenow); - - /* If timer already expired, set remaining time to 0 */ - if (s->d1->next_timeout.tv_sec < timenow.tv_sec || - (s->d1->next_timeout.tv_sec == timenow.tv_sec && - s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { - memset(timeleft, 0, sizeof(struct timeval)); - return timeleft; - } - - /* Calculate time left until timer expires */ - memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); - timeleft->tv_sec -= timenow.tv_sec; - timeleft->tv_usec -= timenow.tv_usec; - if (timeleft->tv_usec < 0) { - timeleft->tv_sec--; - timeleft->tv_usec += 1000000; - } - - /* - * If remaining time is less than 15 ms, set it to 0 to prevent issues - * because of small devergences with socket timeouts. - */ - if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) { - memset(timeleft, 0, sizeof(struct timeval)); - } - - return timeleft; -} - -int dtls1_is_timer_expired(SSL *s) -{ - struct timeval timeleft; - - /* Get time left until timeout, return false if no timer running */ - if (dtls1_get_timeout(s, &timeleft) == NULL) { - return 0; - } - - /* Return false if timer is not expired yet */ - if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { - return 0; - } - - /* Timer expired, so return true */ - return 1; -} - -void dtls1_double_timeout(SSL *s) -{ - s->d1->timeout_duration *= 2; - if (s->d1->timeout_duration > 60) - s->d1->timeout_duration = 60; - dtls1_start_timer(s); -} - -void dtls1_stop_timer(SSL *s) -{ - /* Reset everything */ - memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st)); - memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); - s->d1->timeout_duration = 1; - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, - &(s->d1->next_timeout)); - /* Clear retransmission buffer */ - dtls1_clear_sent_buffer(s); -} - -int dtls1_check_timeout_num(SSL *s) -{ - unsigned int mtu; - - s->d1->timeout.num_alerts++; - - /* Reduce MTU after 2 unsuccessful retransmissions */ - if (s->d1->timeout.num_alerts > 2 - && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { - mtu = - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, - NULL); - if (mtu < s->d1->mtu) - s->d1->mtu = mtu; - } - - if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) { - /* fail the connection, enough alerts have been sent */ - SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM, SSL_R_READ_TIMEOUT_EXPIRED); - return -1; - } - - return 0; -} - -int dtls1_handle_timeout(SSL *s) -{ - /* if no timer is expired, don't do anything */ - if (!dtls1_is_timer_expired(s)) { - return 0; - } - - dtls1_double_timeout(s); - - if (dtls1_check_timeout_num(s) < 0) - return -1; - - s->d1->timeout.read_timeouts++; - if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) { - s->d1->timeout.read_timeouts = 1; - } -#ifndef OPENSSL_NO_HEARTBEATS - if (s->tlsext_hb_pending) { - s->tlsext_hb_pending = 0; - return dtls1_heartbeat(s); - } -#endif - - dtls1_start_timer(s); - return dtls1_retransmit_buffered_messages(s); -} - -static void get_current_time(struct timeval *t) -{ -#if defined(_WIN32) - SYSTEMTIME st; - union { - unsigned __int64 ul; - FILETIME ft; - } now; - - GetSystemTime(&st); - SystemTimeToFileTime(&st, &now.ft); -# ifdef __MINGW32__ - now.ul -= 116444736000000000ULL; -# else - now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */ -# endif - t->tv_sec = (long)(now.ul / 10000000); - t->tv_usec = ((int)(now.ul % 10000000)) / 10; -#elif defined(OPENSSL_SYS_VMS) - struct timeb tb; - ftime(&tb); - t->tv_sec = (long)tb.time; - t->tv_usec = (long)tb.millitm * 1000; -#else - gettimeofday(t, NULL); -#endif -} - -int dtls1_listen(SSL *s, struct sockaddr *client) -{ - int ret; - - /* Ensure there is no state left over from a previous invocation */ - SSL_clear(s); - - SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); - s->d1->listen = 1; - - ret = SSL_accept(s); - if (ret <= 0) - return ret; - - (void)BIO_dgram_get_peer(SSL_get_rbio(s), client); - return 1; -} - -static void dtls1_set_handshake_header(SSL *s, int htype, unsigned long len) -{ - unsigned char *p = (unsigned char *)s->init_buf->data; - dtls1_set_message_header(s, p, htype, len, 0, len); - s->init_num = (int)len + DTLS1_HM_HEADER_LENGTH; - s->init_off = 0; - /* Buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); -} - -static int dtls1_handshake_write(SSL *s) -{ - return dtls1_do_write(s, SSL3_RT_HANDSHAKE); -} diff --git a/thirdparty/openssl/ssl/d1_meth.c b/thirdparty/openssl/ssl/d1_meth.c deleted file mode 100644 index 899010e985..0000000000 --- a/thirdparty/openssl/ssl/d1_meth.c +++ /dev/null @@ -1,90 +0,0 @@ -/* ssl/d1_meth.h */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-2005 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 - * openssl-core@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). - * - */ - -#include <stdio.h> -#include <openssl/objects.h> -#include "ssl_locl.h" - -static const SSL_METHOD *dtls1_get_method(int ver); -static const SSL_METHOD *dtls1_get_method(int ver) -{ - if (ver == DTLS_ANY_VERSION) - return DTLS_method(); - else if (ver == DTLS1_VERSION) - return DTLSv1_method(); - else if (ver == DTLS1_2_VERSION) - return DTLSv1_2_method(); - else - return NULL; -} - -IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, - DTLSv1_method, - dtls1_accept, - dtls1_connect, dtls1_get_method, DTLSv1_enc_data) - -IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, - DTLSv1_2_method, - dtls1_accept, - dtls1_connect, dtls1_get_method, DTLSv1_2_enc_data) - -IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, - DTLS_method, - dtls1_accept, - dtls1_connect, dtls1_get_method, DTLSv1_2_enc_data) diff --git a/thirdparty/openssl/ssl/d1_pkt.c b/thirdparty/openssl/ssl/d1_pkt.c deleted file mode 100644 index 10586fee54..0000000000 --- a/thirdparty/openssl/ssl/d1_pkt.c +++ /dev/null @@ -1,2020 +0,0 @@ -/* ssl/d1_pkt.c */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1998-2005 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 - * openssl-core@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). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include <errno.h> -#define USE_SOCKETS -#include "ssl_locl.h" -#include <openssl/evp.h> -#include <openssl/buffer.h> -#include <openssl/pqueue.h> -#include <openssl/rand.h> - -/* mod 128 saturating subtract of two 64-bit values in big-endian order */ -static int satsub64be(const unsigned char *v1, const unsigned char *v2) -{ - int ret, i; - - if (sizeof(long) == 8) - do { - const union { - long one; - char little; - } is_endian = { - 1 - }; - long l; - - if (is_endian.little) - break; - /* not reached on little-endians */ - /* - * following test is redundant, because input is always aligned, - * but I take no chances... - */ - if (((size_t)v1 | (size_t)v2) & 0x7) - break; - - l = *((long *)v1); - l -= *((long *)v2); - if (l > 128) - return 128; - else if (l < -128) - return -128; - else - return (int)l; - } while (0); - - ret = 0; - for (i=0; i<7; i++) { - if (v1[i] > v2[i]) { - /* v1 is larger... but by how much? */ - if (v1[i] != v2[i] + 1) - return 128; - while (++i <= 6) { - if (v1[i] != 0x00 || v2[i] != 0xff) - return 128; /* too much */ - } - /* We checked all the way to the penultimate byte, - * so despite higher bytes changing we actually - * know that it only changed from (e.g.) - * ... (xx) ff ff ff ?? - * to ... (xx+1) 00 00 00 ?? - * so we add a 'bias' of 256 for the carry that - * happened, and will eventually return - * 256 + v1[7] - v2[7]. */ - ret = 256; - break; - } else if (v2[i] > v1[i]) { - /* v2 is larger... but by how much? */ - if (v2[i] != v1[i] + 1) - return -128; - while (++i <= 6) { - if (v2[i] != 0x00 || v1[i] != 0xff) - return -128; /* too much */ - } - /* Similar to the case above, we know it changed - * from ... (xx) 00 00 00 ?? - * to ... (xx-1) ff ff ff ?? - * so we add a 'bias' of -256 for the borrow, - * to return -256 + v1[7] - v2[7]. */ - ret = -256; - } - } - - ret += (int)v1[7] - (int)v2[7]; - - if (ret > 128) - return 128; - else if (ret < -128) - return -128; - else - return ret; -} - -static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, - int len, int peek); -static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap); -static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap); -static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, - unsigned int *is_next_epoch); -#if 0 -static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, - unsigned short *priority, - unsigned long *offset); -#endif -static int dtls1_buffer_record(SSL *s, record_pqueue *q, - unsigned char *priority); -static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); - -/* copy buffered record into SSL structure */ -static int dtls1_copy_record(SSL *s, pitem *item) -{ - DTLS1_RECORD_DATA *rdata; - - rdata = (DTLS1_RECORD_DATA *)item->data; - - if (s->s3->rbuf.buf != NULL) - OPENSSL_free(s->s3->rbuf.buf); - - s->packet = rdata->packet; - s->packet_length = rdata->packet_length; - memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); - memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); - - /* Set proper sequence number for mac calculation */ - memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6); - - return (1); -} - -static int -dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) -{ - DTLS1_RECORD_DATA *rdata; - pitem *item; - - /* Limit the size of the queue to prevent DOS attacks */ - if (pqueue_size(queue->q) >= 100) - return 0; - - rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); - item = pitem_new(priority, rdata); - if (rdata == NULL || item == NULL) { - if (rdata != NULL) - OPENSSL_free(rdata); - if (item != NULL) - pitem_free(item); - - SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); - return -1; - } - - rdata->packet = s->packet; - rdata->packet_length = s->packet_length; - memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER)); - memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD)); - - item->data = rdata; - -#ifndef OPENSSL_NO_SCTP - /* Store bio_dgram_sctp_rcvinfo struct */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - (s->state == SSL3_ST_SR_FINISHED_A - || s->state == SSL3_ST_CR_FINISHED_A)) { - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO, - sizeof(rdata->recordinfo), &rdata->recordinfo); - } -#endif - - s->packet = NULL; - s->packet_length = 0; - memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER)); - memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD)); - - if (!ssl3_setup_buffers(s)) { - SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); - if (rdata->rbuf.buf != NULL) - OPENSSL_free(rdata->rbuf.buf); - OPENSSL_free(rdata); - pitem_free(item); - return (-1); - } - - /* insert should not fail, since duplicates are dropped */ - if (pqueue_insert(queue->q, item) == NULL) { - SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); - if (rdata->rbuf.buf != NULL) - OPENSSL_free(rdata->rbuf.buf); - OPENSSL_free(rdata); - pitem_free(item); - return (-1); - } - - return (1); -} - -static int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) -{ - pitem *item; - - item = pqueue_pop(queue->q); - if (item) { - dtls1_copy_record(s, item); - - OPENSSL_free(item->data); - pitem_free(item); - - return (1); - } - - return (0); -} - -/* - * retrieve a buffered record that belongs to the new epoch, i.e., not - * processed yet - */ -#define dtls1_get_unprocessed_record(s) \ - dtls1_retrieve_buffered_record((s), \ - &((s)->d1->unprocessed_rcds)) - -/* - * retrieve a buffered record that belongs to the current epoch, ie, - * processed - */ -#define dtls1_get_processed_record(s) \ - dtls1_retrieve_buffered_record((s), \ - &((s)->d1->processed_rcds)) - -static int dtls1_process_buffered_records(SSL *s) -{ - pitem *item; - SSL3_BUFFER *rb; - SSL3_RECORD *rr; - DTLS1_BITMAP *bitmap; - unsigned int is_next_epoch; - int replayok = 1; - - item = pqueue_peek(s->d1->unprocessed_rcds.q); - if (item) { - /* Check if epoch is current. */ - if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) - return 1; /* Nothing to do. */ - - rr = &s->s3->rrec; - rb = &s->s3->rbuf; - - if (rb->left > 0) { - /* - * We've still got data from the current packet to read. There could - * be a record from the new epoch in it - so don't overwrite it - * with the unprocessed records yet (we'll do it when we've - * finished reading the current packet). - */ - return 1; - } - - - /* Process all the records. */ - while (pqueue_peek(s->d1->unprocessed_rcds.q)) { - dtls1_get_unprocessed_record(s); - bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); - if (bitmap == NULL) { - /* - * Should not happen. This will only ever be NULL when the - * current record is from a different epoch. But that cannot - * be the case because we already checked the epoch above - */ - SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, - ERR_R_INTERNAL_ERROR); - return 0; - } -#ifndef OPENSSL_NO_SCTP - /* Only do replay check if no SCTP bio */ - if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) -#endif - { - /* - * Check whether this is a repeat, or aged record. We did this - * check once already when we first received the record - but - * we might have updated the window since then due to - * records we subsequently processed. - */ - replayok = dtls1_record_replay_check(s, bitmap); - } - - if (!replayok || !dtls1_process_record(s, bitmap)) { - /* dump this record */ - rr->length = 0; - s->packet_length = 0; - continue; - } - - if (dtls1_buffer_record(s, &(s->d1->processed_rcds), - s->s3->rrec.seq_num) < 0) - return 0; - } - } - - /* - * sync epoch numbers once all the unprocessed records have been - * processed - */ - s->d1->processed_rcds.epoch = s->d1->r_epoch; - s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; - - return 1; -} - -#if 0 - -static int dtls1_get_buffered_record(SSL *s) -{ - pitem *item; - PQ_64BIT priority = - (((PQ_64BIT) s->d1->handshake_read_seq) << 32) | - ((PQ_64BIT) s->d1->r_msg_hdr.frag_off); - - /* if we're not (re)negotiating, nothing buffered */ - if (!SSL_in_init(s)) - return 0; - - item = pqueue_peek(s->d1->rcvd_records); - if (item && item->priority == priority) { - /* - * Check if we've received the record of interest. It must be a - * handshake record, since data records as passed up without - * buffering - */ - DTLS1_RECORD_DATA *rdata; - item = pqueue_pop(s->d1->rcvd_records); - rdata = (DTLS1_RECORD_DATA *)item->data; - - if (s->s3->rbuf.buf != NULL) - OPENSSL_free(s->s3->rbuf.buf); - - s->packet = rdata->packet; - s->packet_length = rdata->packet_length; - memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); - memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); - - OPENSSL_free(item->data); - pitem_free(item); - - /* s->d1->next_expected_seq_num++; */ - return (1); - } - - return 0; -} - -#endif - -static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) -{ - int i, al; - int enc_err; - SSL_SESSION *sess; - SSL3_RECORD *rr; - unsigned int mac_size, orig_len; - unsigned char md[EVP_MAX_MD_SIZE]; - - rr = &(s->s3->rrec); - sess = s->session; - - /* - * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, - * and we have that many bytes in s->packet - */ - rr->input = &(s->packet[DTLS1_RT_HEADER_LENGTH]); - - /* - * ok, we can now read from 's->packet' data into 'rr' rr->input points - * at rr->length bytes, which need to be copied into rr->data by either - * the decryption or by the decompression When the data is 'copied' into - * the rr->data buffer, rr->input will be pointed at the new buffer - */ - - /* - * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length - * bytes of encrypted compressed stuff. - */ - - /* check is not needed I believe */ - if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); - goto f_err; - } - - /* decrypt in place in 'rr->input' */ - rr->data = rr->input; - - enc_err = s->method->ssl3_enc->enc(s, 0); - /*- - * enc_err is: - * 0: (in non-constant time) if the record is publically invalid. - * 1: if the padding is valid - * -1: if the padding is invalid - */ - if (enc_err == 0) { - /* For DTLS we simply ignore bad packets. */ - rr->length = 0; - s->packet_length = 0; - goto err; - } -#ifdef TLS_DEBUG - printf("dec %d\n", rr->length); - { - unsigned int z; - for (z = 0; z < rr->length; z++) - printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n'); - } - printf("\n"); -#endif - - /* r->length is now the compressed data plus mac */ - if ((sess != NULL) && - (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) { - /* s->read_hash != NULL => mac_size != -1 */ - unsigned char *mac = NULL; - unsigned char mac_tmp[EVP_MAX_MD_SIZE]; - mac_size = EVP_MD_CTX_size(s->read_hash); - OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); - - /* - * kludge: *_cbc_remove_padding passes padding length in rr->type - */ - orig_len = rr->length + ((unsigned int)rr->type >> 8); - - /* - * orig_len is the length of the record before any padding was - * removed. This is public information, as is the MAC in use, - * therefore we can safely process the record in a different amount - * of time if it's too short to possibly contain a MAC. - */ - if (orig_len < mac_size || - /* CBC records must have a padding length byte too. */ - (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && - orig_len < mac_size + 1)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { - /* - * We update the length so that the TLS header bytes can be - * constructed correctly but we need to extract the MAC in - * constant time from within the record, without leaking the - * contents of the padding bytes. - */ - mac = mac_tmp; - ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); - rr->length -= mac_size; - } else { - /* - * In this case there's no padding, so |orig_len| equals - * |rec->length| and we checked that there's enough bytes for - * |mac_size| above. - */ - rr->length -= mac_size; - mac = &rr->data[rr->length]; - } - - i = s->method->ssl3_enc->mac(s, md, 0 /* not send */ ); - if (i < 0 || mac == NULL - || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) - enc_err = -1; - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) - enc_err = -1; - } - - if (enc_err < 0) { - /* decryption failed, silently discard message */ - rr->length = 0; - s->packet_length = 0; - goto err; - } - - /* r->length is now just compressed */ - if (s->expand != NULL) { - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, - SSL_R_COMPRESSED_LENGTH_TOO_LONG); - goto f_err; - } - if (!ssl3_do_uncompress(s)) { - al = SSL_AD_DECOMPRESSION_FAILURE; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_BAD_DECOMPRESSION); - goto f_err; - } - } - - if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_DATA_LENGTH_TOO_LONG); - goto f_err; - } - - rr->off = 0; - /*- - * So at this point the following is true - * ssl->s3->rrec.type is the type of record - * ssl->s3->rrec.length == number of bytes in record - * ssl->s3->rrec.off == offset to first valid byte - * ssl->s3->rrec.data == where to take bytes from, increment - * after use :-). - */ - - /* we have pulled in a full packet so zero things */ - s->packet_length = 0; - - /* Mark receipt of record. */ - dtls1_record_bitmap_update(s, bitmap); - - return (1); - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - return (0); -} - -/*- - * Call this to get a new input record. - * It will return <= 0 if more data is needed, normally due to an error - * or non-blocking IO. - * When it finishes, one packet has been decoded and can be found in - * ssl->s3->rrec.type - is the type of record - * ssl->s3->rrec.data, - data - * ssl->s3->rrec.length, - number of bytes - */ -/* used only by dtls1_read_bytes */ -int dtls1_get_record(SSL *s) -{ - int ssl_major, ssl_minor; - int i, n; - SSL3_RECORD *rr; - unsigned char *p = NULL; - unsigned short version; - DTLS1_BITMAP *bitmap; - unsigned int is_next_epoch; - - rr = &(s->s3->rrec); - - again: - /* - * The epoch may have changed. If so, process all the pending records. - * This is a non-blocking operation. - */ - if (!dtls1_process_buffered_records(s)) - return -1; - - /* if we're renegotiating, then there may be buffered records */ - if (dtls1_get_processed_record(s)) - return 1; - - /* get something from the wire */ - /* check if we have the header */ - if ((s->rstate != SSL_ST_READ_BODY) || - (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { - n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); - /* read timeout is handled by dtls1_read_bytes */ - if (n <= 0) - return (n); /* error or non-blocking */ - - /* this packet contained a partial record, dump it */ - if (s->packet_length != DTLS1_RT_HEADER_LENGTH) { - s->packet_length = 0; - goto again; - } - - s->rstate = SSL_ST_READ_BODY; - - p = s->packet; - - if (s->msg_callback) - s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH, - s, s->msg_callback_arg); - - /* Pull apart the header into the DTLS1_RECORD */ - rr->type = *(p++); - ssl_major = *(p++); - ssl_minor = *(p++); - version = (ssl_major << 8) | ssl_minor; - - /* sequence number is 64 bits, with top 2 bytes = epoch */ - n2s(p, rr->epoch); - - memcpy(&(s->s3->read_sequence[2]), p, 6); - p += 6; - - n2s(p, rr->length); - - /* Lets check version */ - if (!s->first_packet) { - if (version != s->version) { - /* unexpected version, silently discard */ - rr->length = 0; - s->packet_length = 0; - goto again; - } - } - - if ((version & 0xff00) != (s->version & 0xff00)) { - /* wrong version, silently discard record */ - rr->length = 0; - s->packet_length = 0; - goto again; - } - - if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { - /* record too long, silently discard it */ - rr->length = 0; - s->packet_length = 0; - goto again; - } - - /* now s->rstate == SSL_ST_READ_BODY */ - } - - /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ - - if (rr->length > s->packet_length - DTLS1_RT_HEADER_LENGTH) { - /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */ - i = rr->length; - n = ssl3_read_n(s, i, i, 1); - /* this packet contained a partial record, dump it */ - if (n != i) { - rr->length = 0; - s->packet_length = 0; - goto again; - } - - /* - * now n == rr->length, and s->packet_length == - * DTLS1_RT_HEADER_LENGTH + rr->length - */ - } - s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ - - /* match epochs. NULL means the packet is dropped on the floor */ - bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); - if (bitmap == NULL) { - rr->length = 0; - s->packet_length = 0; /* dump this record */ - goto again; /* get another record */ - } -#ifndef OPENSSL_NO_SCTP - /* Only do replay check if no SCTP bio */ - if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) { -#endif - /* - * Check whether this is a repeat, or aged record. Don't check if - * we're listening and this message is a ClientHello. They can look - * as if they're replayed, since they arrive from different - * connections and would be dropped unnecessarily. - */ - if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && - s->packet_length > DTLS1_RT_HEADER_LENGTH && - s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) && - !dtls1_record_replay_check(s, bitmap)) { - rr->length = 0; - s->packet_length = 0; /* dump this record */ - goto again; /* get another record */ - } -#ifndef OPENSSL_NO_SCTP - } -#endif - - /* just read a 0 length packet */ - if (rr->length == 0) - goto again; - - /* - * If this record is from the next epoch (either HM or ALERT), and a - * handshake is currently in progress, buffer it since it cannot be - * processed at this time. However, do not buffer anything while - * listening. - */ - if (is_next_epoch) { - if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) { - if (dtls1_buffer_record - (s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0) - return -1; - } - rr->length = 0; - s->packet_length = 0; - goto again; - } - - if (!dtls1_process_record(s, bitmap)) { - rr->length = 0; - s->packet_length = 0; /* dump this record */ - goto again; /* get another record */ - } - - return (1); - -} - -/*- - * Return up to 'len' payload bytes received in 'type' records. - * 'type' is one of the following: - * - * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) - * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) - * - 0 (during a shutdown, no data has to be returned) - * - * If we don't have stored data to work from, read a SSL/TLS record first - * (possibly multiple records if we still don't have anything to return). - * - * This function must handle any surprises the peer may have for us, such as - * Alert records (e.g. close_notify), ChangeCipherSpec records (not really - * a surprise, but handled as if it were), or renegotiation requests. - * Also if record payloads contain fragments too small to process, we store - * them until there is enough for the respective protocol (the record protocol - * may use arbitrary fragmentation and even interleaving): - * Change cipher spec protocol - * just 1 byte needed, no need for keeping anything stored - * Alert protocol - * 2 bytes needed (AlertLevel, AlertDescription) - * Handshake protocol - * 4 bytes needed (HandshakeType, uint24 length) -- we just have - * to detect unexpected Client Hello and Hello Request messages - * here, anything else is handled by higher layers - * Application data protocol - * none of our business - */ -int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) -{ - int al, i, j, ret; - unsigned int n; - SSL3_RECORD *rr; - void (*cb) (const SSL *ssl, int type2, int val) = NULL; - - if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ - if (!ssl3_setup_buffers(s)) - return (-1); - - /* XXX: check what the second '&& type' is about */ - if ((type && (type != SSL3_RT_APPLICATION_DATA) && - (type != SSL3_RT_HANDSHAKE) && type) || - (peek && (type != SSL3_RT_APPLICATION_DATA))) { - SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); - return -1; - } - - /* - * check whether there's a handshake message (client hello?) waiting - */ - if ((ret = have_handshake_fragment(s, type, buf, len, peek))) - return ret; - - /* - * Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. - */ - -#ifndef OPENSSL_NO_SCTP - /* - * Continue handshake if it had to be interrupted to read app data with - * SCTP. - */ - if ((!s->in_handshake && SSL_in_init(s)) || - (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - (s->state == DTLS1_SCTP_ST_SR_READ_SOCK - || s->state == DTLS1_SCTP_ST_CR_READ_SOCK) - && s->s3->in_read_app_data != 2)) -#else - if (!s->in_handshake && SSL_in_init(s)) -#endif - { - /* type == SSL3_RT_APPLICATION_DATA */ - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - } - - start: - s->rwstate = SSL_NOTHING; - - /*- - * s->s3->rrec.type - is the type of record - * s->s3->rrec.data, - data - * s->s3->rrec.off, - offset into 'data' for next read - * s->s3->rrec.length, - number of bytes. - */ - rr = &(s->s3->rrec); - - /* - * We are not handshaking and have no data yet, so process data buffered - * during the last handshake in advance, if any. - */ - if (s->state == SSL_ST_OK && rr->length == 0) { - pitem *item; - item = pqueue_pop(s->d1->buffered_app_data.q); - if (item) { -#ifndef OPENSSL_NO_SCTP - /* Restore bio_dgram_sctp_rcvinfo struct */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s))) { - DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *)item->data; - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO, - sizeof(rdata->recordinfo), &rdata->recordinfo); - } -#endif - - dtls1_copy_record(s, item); - - OPENSSL_free(item->data); - pitem_free(item); - } - } - - /* Check for timeout */ - if (dtls1_handle_timeout(s) > 0) - goto start; - - /* get new packet if necessary */ - if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) { - ret = dtls1_get_record(s); - if (ret <= 0) { - ret = dtls1_read_failed(s, ret); - /* anything other than a timeout is an error */ - if (ret <= 0) - return (ret); - else - goto start; - } - } - - if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE) { - rr->length = 0; - goto start; - } - - /* - * Reset the count of consecutive warning alerts if we've got a non-empty - * record that isn't an alert. - */ - if (rr->type != SSL3_RT_ALERT && rr->length != 0) - s->cert->alert_count = 0; - - /* we now have a packet which can be read and processed */ - - if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, - * reset by ssl3_get_finished */ - && (rr->type != SSL3_RT_HANDSHAKE)) { - /* - * We now have application data between CCS and Finished. Most likely - * the packets were reordered on their way, so buffer the application - * data for later processing rather than dropping the connection. - */ - if (dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num) < - 0) { - SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); - return -1; - } - rr->length = 0; - goto start; - } - - /* - * If the other end has shut down, throw anything we read away (even in - * 'peek' mode) - */ - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - rr->length = 0; - s->rwstate = SSL_NOTHING; - return (0); - } - - if (type == rr->type) { /* SSL3_RT_APPLICATION_DATA or - * SSL3_RT_HANDSHAKE */ - /* - * make sure that we are not getting application data when we are - * doing a handshake for the first time - */ - if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && - (s->enc_read_ctx == NULL)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE); - goto f_err; - } - - if (len <= 0) - return (len); - - if ((unsigned int)len > rr->length) - n = rr->length; - else - n = (unsigned int)len; - - memcpy(buf, &(rr->data[rr->off]), n); - if (!peek) { - rr->length -= n; - rr->off += n; - if (rr->length == 0) { - s->rstate = SSL_ST_READ_HEADER; - rr->off = 0; - } - } -#ifndef OPENSSL_NO_SCTP - /* - * We were about to renegotiate but had to read belated application - * data first, so retry. - */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - rr->type == SSL3_RT_APPLICATION_DATA && - (s->state == DTLS1_SCTP_ST_SR_READ_SOCK - || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)) { - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - } - - /* - * We might had to delay a close_notify alert because of reordered - * app data. If there was an alert and there is no message to read - * anymore, finally set shutdown. - */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - s->d1->shutdown_received - && !BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - return (0); - } -#endif - return (n); - } - - /* - * If we get here, then type != rr->type; if we have a handshake message, - * then it was unexpected (Hello Request or Client Hello). - */ - - /* - * In case of record types for which we have 'fragment' storage, fill - * that so that we can process the data at a fixed place. - */ - { - unsigned int k, dest_maxlen = 0; - unsigned char *dest = NULL; - unsigned int *dest_len = NULL; - - if (rr->type == SSL3_RT_HANDSHAKE) { - dest_maxlen = sizeof s->d1->handshake_fragment; - dest = s->d1->handshake_fragment; - dest_len = &s->d1->handshake_fragment_len; - } else if (rr->type == SSL3_RT_ALERT) { - dest_maxlen = sizeof(s->d1->alert_fragment); - dest = s->d1->alert_fragment; - dest_len = &s->d1->alert_fragment_len; - } -#ifndef OPENSSL_NO_HEARTBEATS - else if (rr->type == TLS1_RT_HEARTBEAT) { - dtls1_process_heartbeat(s); - - /* Exit and notify application to read again */ - rr->length = 0; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - return (-1); - } -#endif - /* else it's a CCS message, or application data or wrong */ - else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC) { - /* - * Application data while renegotiating is allowed. Try again - * reading. - */ - if (rr->type == SSL3_RT_APPLICATION_DATA) { - BIO *bio; - s->s3->in_read_app_data = 2; - bio = SSL_get_rbio(s); - s->rwstate = SSL_READING; - BIO_clear_retry_flags(bio); - BIO_set_retry_read(bio); - return (-1); - } - - /* Not certain if this is the right error handling */ - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); - goto f_err; - } - - if (dest_maxlen > 0) { - /* - * XDTLS: In a pathalogical case, the Client Hello may be - * fragmented--don't always expect dest_maxlen bytes - */ - if (rr->length < dest_maxlen) { -#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE - /* - * for normal alerts rr->length is 2, while - * dest_maxlen is 7 if we were to handle this - * non-existing alert... - */ - FIX ME -#endif - s->rstate = SSL_ST_READ_HEADER; - rr->length = 0; - goto start; - } - - /* now move 'n' bytes: */ - for (k = 0; k < dest_maxlen; k++) { - dest[k] = rr->data[rr->off++]; - rr->length--; - } - *dest_len = dest_maxlen; - } - } - - /*- - * s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE; - * s->d1->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT. - * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) - */ - - /* If we are a client, check for an incoming 'Hello Request': */ - if ((!s->server) && - (s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && - (s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && - (s->session != NULL) && (s->session->cipher != NULL)) { - s->d1->handshake_fragment_len = 0; - - if ((s->d1->handshake_fragment[1] != 0) || - (s->d1->handshake_fragment[2] != 0) || - (s->d1->handshake_fragment[3] != 0)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_HELLO_REQUEST); - goto f_err; - } - - /* - * no need to check sequence number on HELLO REQUEST messages - */ - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - s->d1->handshake_fragment, 4, s, - s->msg_callback_arg); - - if (SSL_is_init_finished(s) && - !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && - !s->s3->renegotiate) { - s->d1->handshake_read_seq++; - s->new_session = 1; - ssl3_renegotiate(s); - if (ssl3_renegotiate_check(s)) { - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_DTLS1_READ_BYTES, - SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - - if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ - BIO *bio; - /* - * In the case where we try to read application data, - * but we trigger an SSL handshake, we return -1 with - * the retry option set. Otherwise renegotiation may - * cause nasty problems in the blocking world - */ - s->rwstate = SSL_READING; - bio = SSL_get_rbio(s); - BIO_clear_retry_flags(bio); - BIO_set_retry_read(bio); - return (-1); - } - } - } - } - /* - * we either finished a handshake or ignored the request, now try - * again to obtain the (application) data we were asked for - */ - goto start; - } - - if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) { - int alert_level = s->d1->alert_fragment[0]; - int alert_descr = s->d1->alert_fragment[1]; - - s->d1->alert_fragment_len = 0; - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_ALERT, - s->d1->alert_fragment, 2, s, s->msg_callback_arg); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - if (cb != NULL) { - j = (alert_level << 8) | alert_descr; - cb(s, SSL_CB_READ_ALERT, j); - } - - if (alert_level == SSL3_AL_WARNING) { - s->s3->warn_alert = alert_descr; - - s->cert->alert_count++; - if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS); - goto f_err; - } - - if (alert_descr == SSL_AD_CLOSE_NOTIFY) { -#ifndef OPENSSL_NO_SCTP - /* - * With SCTP and streams the socket may deliver app data - * after a close_notify alert. We have to check this first so - * that nothing gets discarded. - */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { - s->d1->shutdown_received = 1; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - return -1; - } -#endif - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - return (0); - } -#if 0 - /* XXX: this is a possible improvement in the future */ - /* now check if it's a missing record */ - if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { - unsigned short seq; - unsigned int frag_off; - unsigned char *p = &(s->d1->alert_fragment[2]); - - n2s(p, seq); - n2l3(p, frag_off); - - dtls1_retransmit_message(s, - dtls1_get_queue_priority - (frag->msg_header.seq, 0), frag_off, - &found); - if (!found && SSL_in_init(s)) { - /* - * fprintf( stderr,"in init = %d\n", SSL_in_init(s)); - */ - /* - * requested a message not yet sent, send an alert - * ourselves - */ - ssl3_send_alert(s, SSL3_AL_WARNING, - DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); - } - } -#endif - } else if (alert_level == SSL3_AL_FATAL) { - char tmp[16]; - - s->rwstate = SSL_NOTHING; - s->s3->fatal_alert = alert_descr; - SSLerr(SSL_F_DTLS1_READ_BYTES, - SSL_AD_REASON_OFFSET + alert_descr); - BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); - ERR_add_error_data(2, "SSL alert number ", tmp); - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL_CTX_remove_session(s->session_ctx, s->session); - return (0); - } else { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE); - goto f_err; - } - - goto start; - } - - if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a - * shutdown */ - s->rwstate = SSL_NOTHING; - rr->length = 0; - return (0); - } - - if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { - struct ccs_header_st ccs_hdr; - unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH; - - dtls1_get_ccs_header(rr->data, &ccs_hdr); - - if (s->version == DTLS1_BAD_VER) - ccs_hdr_len = 3; - - /* - * 'Change Cipher Spec' is just a single byte, so we know exactly - * what the record payload has to look like - */ - /* XDTLS: check that epoch is consistent */ - if ((rr->length != ccs_hdr_len) || - (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto f_err; - } - - rr->length = 0; - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, - rr->data, 1, s, s->msg_callback_arg); - - /* - * We can't process a CCS now, because previous handshake messages - * are still missing, so just drop it. - */ - if (!s->d1->change_cipher_spec_ok) { - goto start; - } - - s->d1->change_cipher_spec_ok = 0; - - s->s3->change_cipher_spec = 1; - if (!ssl3_do_change_cipher_spec(s)) - goto err; - - /* do this whenever CCS is processed */ - dtls1_reset_seq_numbers(s, SSL3_CC_READ); - - if (s->version == DTLS1_BAD_VER) - s->d1->handshake_read_seq++; - -#ifndef OPENSSL_NO_SCTP - /* - * Remember that a CCS has been received, so that an old key of - * SCTP-Auth can be deleted when a CCS is sent. Will be ignored if no - * SCTP is used - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL); -#endif - - goto start; - } - - /* - * Unexpected handshake message (Client Hello, or protocol violation) - */ - if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && - !s->in_handshake) { - struct hm_header_st msg_hdr; - - /* this may just be a stale retransmit */ - dtls1_get_message_header(rr->data, &msg_hdr); - if (rr->epoch != s->d1->r_epoch) { - rr->length = 0; - goto start; - } - - /* - * If we are server, we may have a repeated FINISHED of the client - * here, then retransmit our CCS and FINISHED. - */ - if (msg_hdr.type == SSL3_MT_FINISHED) { - if (dtls1_check_timeout_num(s) < 0) - return -1; - - dtls1_retransmit_buffered_messages(s); - rr->length = 0; - goto start; - } - - if (((s->state & SSL_ST_MASK) == SSL_ST_OK) && - !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { -#if 0 /* worked only because C operator preferences - * are not as expected (and because this is - * not really needed for clients except for - * detecting protocol violations): */ - s->state = SSL_ST_BEFORE | (s->server) - ? SSL_ST_ACCEPT : SSL_ST_CONNECT; -#else - s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; -#endif - s->renegotiate = 1; - s->new_session = 1; - } - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - - if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ - BIO *bio; - /* - * In the case where we try to read application data, but we - * trigger an SSL handshake, we return -1 with the retry - * option set. Otherwise renegotiation may cause nasty - * problems in the blocking world - */ - s->rwstate = SSL_READING; - bio = SSL_get_rbio(s); - BIO_clear_retry_flags(bio); - BIO_set_retry_read(bio); - return (-1); - } - } - goto start; - } - - switch (rr->type) { - default: -#ifndef OPENSSL_NO_TLS - /* TLS just ignores unknown message types */ - if (s->version == TLS1_VERSION) { - rr->length = 0; - goto start; - } -#endif - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); - goto f_err; - case SSL3_RT_CHANGE_CIPHER_SPEC: - case SSL3_RT_ALERT: - case SSL3_RT_HANDSHAKE: - /* - * we already handled all of these, with the possible exception of - * SSL3_RT_HANDSHAKE when s->in_handshake is set, but that should not - * happen when type != rr->type - */ - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); - goto f_err; - case SSL3_RT_APPLICATION_DATA: - /* - * At this point, we were expecting handshake data, but have - * application data. If the library was running inside ssl3_read() - * (i.e. in_read_app_data is set) and it makes sense to read - * application data at this point (session renegotiation not yet - * started), we will indulge it. - */ - if (s->s3->in_read_app_data && - (s->s3->total_renegotiations != 0) && - (((s->state & SSL_ST_CONNECT) && - (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && - (s->state <= SSL3_ST_CR_SRVR_HELLO_A) - ) || ((s->state & SSL_ST_ACCEPT) && - (s->state <= SSL3_ST_SW_HELLO_REQ_A) && - (s->state >= SSL3_ST_SR_CLNT_HELLO_A) - ) - )) { - s->s3->in_read_app_data = 2; - return (-1); - } else { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); - goto f_err; - } - } - /* not reached */ - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - return (-1); -} - -int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) -{ - int i; - -#ifndef OPENSSL_NO_SCTP - /* - * Check if we have to continue an interrupted handshake for reading - * belated app data with SCTP. - */ - if ((SSL_in_init(s) && !s->in_handshake) || - (BIO_dgram_is_sctp(SSL_get_wbio(s)) && - (s->state == DTLS1_SCTP_ST_SR_READ_SOCK - || s->state == DTLS1_SCTP_ST_CR_READ_SOCK))) -#else - if (SSL_in_init(s) && !s->in_handshake) -#endif - { - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, - SSL_R_SSL_HANDSHAKE_FAILURE); - return -1; - } - } - - if (len > SSL3_RT_MAX_PLAIN_LENGTH) { - SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, SSL_R_DTLS_MESSAGE_TOO_BIG); - return -1; - } - - i = dtls1_write_bytes(s, type, buf_, len); - return i; -} - - /* - * this only happens when a client hello is received and a handshake - * is started. - */ -static int -have_handshake_fragment(SSL *s, int type, unsigned char *buf, - int len, int peek) -{ - - if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0)) - /* (partially) satisfy request from storage */ - { - unsigned char *src = s->d1->handshake_fragment; - unsigned char *dst = buf; - unsigned int k, n; - - /* peek == 0 */ - n = 0; - while ((len > 0) && (s->d1->handshake_fragment_len > 0)) { - *dst++ = *src++; - len--; - s->d1->handshake_fragment_len--; - n++; - } - /* move any remaining fragment bytes: */ - for (k = 0; k < s->d1->handshake_fragment_len; k++) - s->d1->handshake_fragment[k] = *src++; - return n; - } - - return 0; -} - -/* - * Call this to write data in records of type 'type' It will return <= 0 if - * not all data has been sent or non-blocking IO. - */ -int dtls1_write_bytes(SSL *s, int type, const void *buf, int len) -{ - int i; - - OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); - s->rwstate = SSL_NOTHING; - i = do_dtls1_write(s, type, buf, len, 0); - return i; -} - -int do_dtls1_write(SSL *s, int type, const unsigned char *buf, - unsigned int len, int create_empty_fragment) -{ - unsigned char *p, *pseq; - int i, mac_size, clear = 0; - int prefix_len = 0; - int eivlen; - SSL3_RECORD *wr; - SSL3_BUFFER *wb; - SSL_SESSION *sess; - - /* - * first check if there is a SSL3_BUFFER still being written out. This - * will happen with non blocking IO - */ - if (s->s3->wbuf.left != 0) { - OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */ - return (ssl3_write_pending(s, type, buf, len)); - } - - /* If we have an alert to send, lets send it */ - if (s->s3->alert_dispatch) { - i = s->method->ssl_dispatch_alert(s); - if (i <= 0) - return (i); - /* if it went, fall through and send more stuff */ - } - - if (len == 0 && !create_empty_fragment) - return 0; - - wr = &(s->s3->wrec); - wb = &(s->s3->wbuf); - sess = s->session; - - if ((sess == NULL) || - (s->enc_write_ctx == NULL) || (EVP_MD_CTX_md(s->write_hash) == NULL)) - clear = 1; - - if (clear) - mac_size = 0; - else { - mac_size = EVP_MD_CTX_size(s->write_hash); - if (mac_size < 0) - goto err; - } - - /* DTLS implements explicit IV, so no need for empty fragments */ -#if 0 - /* - * 'create_empty_fragment' is true only when this function calls itself - */ - if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done - && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER) - { - /* - * countermeasure against known-IV weakness in CBC ciphersuites (see - * http://www.openssl.org/~bodo/tls-cbc.txt) - */ - - if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) { - /* - * recursive function call with 'create_empty_fragment' set; this - * prepares and buffers the data for an empty fragment (these - * 'prefix_len' bytes are sent out later together with the actual - * payload) - */ - prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1); - if (prefix_len <= 0) - goto err; - - if (s->s3->wbuf.len < - (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE) { - /* insufficient space */ - SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - s->s3->empty_fragment_done = 1; - } -#endif - p = wb->buf + prefix_len; - - /* write the header */ - - *(p++) = type & 0xff; - wr->type = type; - /* - * Special case: for hello verify request, client version 1.0 and we - * haven't decided which version to use yet send back using version 1.0 - * header: otherwise some clients will ignore it. - */ - if (s->method->version == DTLS_ANY_VERSION) { - *(p++) = DTLS1_VERSION >> 8; - *(p++) = DTLS1_VERSION & 0xff; - } else { - *(p++) = s->version >> 8; - *(p++) = s->version & 0xff; - } - - /* field where we are to write out packet epoch, seq num and len */ - pseq = p; - p += 10; - - /* Explicit IV length, block ciphers appropriate version flag */ - if (s->enc_write_ctx) { - int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); - if (mode == EVP_CIPH_CBC_MODE) { - eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); - if (eivlen <= 1) - eivlen = 0; - } - /* Need explicit part of IV for GCM mode */ - else if (mode == EVP_CIPH_GCM_MODE) - eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; - else - eivlen = 0; - } else - eivlen = 0; - - /* lets setup the record stuff. */ - wr->data = p + eivlen; /* make room for IV in case of CBC */ - wr->length = (int)len; - wr->input = (unsigned char *)buf; - - /* - * we now 'read' from wr->input, wr->length bytes into wr->data - */ - - /* first we compress */ - if (s->compress != NULL) { - if (!ssl3_do_compress(s)) { - SSLerr(SSL_F_DO_DTLS1_WRITE, SSL_R_COMPRESSION_FAILURE); - goto err; - } - } else { - memcpy(wr->data, wr->input, wr->length); - wr->input = wr->data; - } - - /* - * we should still have the output to wr->data and the input from - * wr->input. Length should be wr->length. wr->data still points in the - * wb->buf - */ - - if (mac_size != 0) { - if (s->method->ssl3_enc->mac(s, &(p[wr->length + eivlen]), 1) < 0) - goto err; - wr->length += mac_size; - } - - /* this is true regardless of mac size */ - wr->input = p; - wr->data = p; - - if (eivlen) - wr->length += eivlen; - - if (s->method->ssl3_enc->enc(s, 1) < 1) - goto err; - - /* record length after mac and block padding */ - /* - * if (type == SSL3_RT_APPLICATION_DATA || (type == SSL3_RT_ALERT && ! - * SSL_in_init(s))) - */ - - /* there's only one epoch between handshake and app data */ - - s2n(s->d1->w_epoch, pseq); - - /* XDTLS: ?? */ - /* - * else s2n(s->d1->handshake_epoch, pseq); - */ - - memcpy(pseq, &(s->s3->write_sequence[2]), 6); - pseq += 6; - s2n(wr->length, pseq); - - if (s->msg_callback) - s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH, - DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg); - - /* - * we should now have wr->data pointing to the encrypted data, which is - * wr->length long - */ - wr->type = type; /* not needed but helps for debugging */ - wr->length += DTLS1_RT_HEADER_LENGTH; - -#if 0 /* this is now done at the message layer */ - /* buffer the record, making it easy to handle retransmits */ - if (type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC) - dtls1_buffer_record(s, wr->data, wr->length, - *((PQ_64BIT *) & (s->s3->write_sequence[0]))); -#endif - - ssl3_record_sequence_update(&(s->s3->write_sequence[0])); - - if (create_empty_fragment) { - /* - * we are in a recursive call; just return the length, don't write - * out anything here - */ - return wr->length; - } - - /* now let's set up wb */ - wb->left = prefix_len + wr->length; - wb->offset = 0; - - /* - * memorize arguments so that ssl3_write_pending can detect bad write - * retries later - */ - s->s3->wpend_tot = len; - s->s3->wpend_buf = buf; - s->s3->wpend_type = type; - s->s3->wpend_ret = len; - - /* we now just need to write the buffer */ - return ssl3_write_pending(s, type, buf, len); - err: - return -1; -} - -static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) -{ - int cmp; - unsigned int shift; - const unsigned char *seq = s->s3->read_sequence; - - cmp = satsub64be(seq, bitmap->max_seq_num); - if (cmp > 0) { - memcpy(s->s3->rrec.seq_num, seq, 8); - return 1; /* this record in new */ - } - shift = -cmp; - if (shift >= sizeof(bitmap->map) * 8) - return 0; /* stale, outside the window */ - else if (bitmap->map & (1UL << shift)) - return 0; /* record previously received */ - - memcpy(s->s3->rrec.seq_num, seq, 8); - return 1; -} - -static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) -{ - int cmp; - unsigned int shift; - const unsigned char *seq = s->s3->read_sequence; - - cmp = satsub64be(seq, bitmap->max_seq_num); - if (cmp > 0) { - shift = cmp; - if (shift < sizeof(bitmap->map) * 8) - bitmap->map <<= shift, bitmap->map |= 1UL; - else - bitmap->map = 1UL; - memcpy(bitmap->max_seq_num, seq, 8); - } else { - shift = -cmp; - if (shift < sizeof(bitmap->map) * 8) - bitmap->map |= 1UL << shift; - } -} - -int dtls1_dispatch_alert(SSL *s) -{ - int i, j; - void (*cb) (const SSL *ssl, int type, int val) = NULL; - unsigned char buf[DTLS1_AL_HEADER_LENGTH]; - unsigned char *ptr = &buf[0]; - - s->s3->alert_dispatch = 0; - - memset(buf, 0x00, sizeof(buf)); - *ptr++ = s->s3->send_alert[0]; - *ptr++ = s->s3->send_alert[1]; - -#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE - if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { - s2n(s->d1->handshake_read_seq, ptr); -# if 0 - if (s->d1->r_msg_hdr.frag_off == 0) - /* - * waiting for a new msg - */ - else - s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */ -# endif - -# if 0 - fprintf(stderr, - "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n", - s->d1->handshake_read_seq, s->d1->r_msg_hdr.seq); -# endif - l2n3(s->d1->r_msg_hdr.frag_off, ptr); - } -#endif - - i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0); - if (i <= 0) { - s->s3->alert_dispatch = 1; - /* fprintf( stderr, "not done with alert\n" ); */ - } else { - if (s->s3->send_alert[0] == SSL3_AL_FATAL -#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE - || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE -#endif - ) - (void)BIO_flush(s->wbio); - - if (s->msg_callback) - s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, - 2, s, s->msg_callback_arg); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - if (cb != NULL) { - j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; - cb(s, SSL_CB_WRITE_ALERT, j); - } - } - return (i); -} - -static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, - unsigned int *is_next_epoch) -{ - - *is_next_epoch = 0; - - /* In current epoch, accept HM, CCS, DATA, & ALERT */ - if (rr->epoch == s->d1->r_epoch) - return &s->d1->bitmap; - - /* - * Only HM and ALERT messages can be from the next epoch and only if we - * have already processed all of the unprocessed records from the last - * epoch - */ - else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && - s->d1->unprocessed_rcds.epoch != s->d1->r_epoch && - (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { - *is_next_epoch = 1; - return &s->d1->next_bitmap; - } - - return NULL; -} - -#if 0 -static int -dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, - unsigned short *priority, unsigned long *offset) -{ - - /* alerts are passed up immediately */ - if (rr->type == SSL3_RT_APPLICATION_DATA || rr->type == SSL3_RT_ALERT) - return 0; - - /* - * Only need to buffer if a handshake is underway. (this implies that - * Hello Request and Client Hello are passed up immediately) - */ - if (SSL_in_init(s)) { - unsigned char *data = rr->data; - /* need to extract the HM/CCS sequence number here */ - if (rr->type == SSL3_RT_HANDSHAKE || - rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { - unsigned short seq_num; - struct hm_header_st msg_hdr; - struct ccs_header_st ccs_hdr; - - if (rr->type == SSL3_RT_HANDSHAKE) { - dtls1_get_message_header(data, &msg_hdr); - seq_num = msg_hdr.seq; - *offset = msg_hdr.frag_off; - } else { - dtls1_get_ccs_header(data, &ccs_hdr); - seq_num = ccs_hdr.seq; - *offset = 0; - } - - /* - * this is either a record we're waiting for, or a retransmit of - * something we happened to previously receive (higher layers - * will drop the repeat silently - */ - if (seq_num < s->d1->handshake_read_seq) - return 0; - if (rr->type == SSL3_RT_HANDSHAKE && - seq_num == s->d1->handshake_read_seq && - msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off) - return 0; - else if (seq_num == s->d1->handshake_read_seq && - (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC || - msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off)) - return 0; - else { - *priority = seq_num; - return 1; - } - } else /* unknown record type */ - return 0; - } - - return 0; -} -#endif - -void dtls1_reset_seq_numbers(SSL *s, int rw) -{ - unsigned char *seq; - unsigned int seq_bytes = sizeof(s->s3->read_sequence); - - if (rw & SSL3_CC_READ) { - seq = s->s3->read_sequence; - s->d1->r_epoch++; - memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); - memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); - - /* - * We must not use any buffered messages received from the previous - * epoch - */ - dtls1_clear_received_buffer(s); - } else { - seq = s->s3->write_sequence; - memcpy(s->d1->last_write_sequence, seq, - sizeof(s->s3->write_sequence)); - s->d1->w_epoch++; - } - - memset(seq, 0x00, seq_bytes); -} diff --git a/thirdparty/openssl/ssl/d1_srtp.c b/thirdparty/openssl/ssl/d1_srtp.c deleted file mode 100644 index 64d0634a38..0000000000 --- a/thirdparty/openssl/ssl/d1_srtp.c +++ /dev/null @@ -1,448 +0,0 @@ -/* ssl/t1_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 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 - * openssl-core@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). - * - */ -/* - * DTLS code by Eric Rescorla <ekr@rtfm.com> - * - * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc. - */ - -#include <stdio.h> -#include <openssl/objects.h> -#include "ssl_locl.h" -#include "srtp.h" - -#ifndef OPENSSL_NO_SRTP - -static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = { - { - "SRTP_AES128_CM_SHA1_80", - SRTP_AES128_CM_SHA1_80, - }, - { - "SRTP_AES128_CM_SHA1_32", - SRTP_AES128_CM_SHA1_32, - }, -# if 0 - { - "SRTP_NULL_SHA1_80", - SRTP_NULL_SHA1_80, - }, - { - "SRTP_NULL_SHA1_32", - SRTP_NULL_SHA1_32, - }, -# endif - {0} -}; - -static int find_profile_by_name(char *profile_name, - SRTP_PROTECTION_PROFILE **pptr, unsigned len) -{ - SRTP_PROTECTION_PROFILE *p; - - p = srtp_known_profiles; - while (p->name) { - if ((len == strlen(p->name)) && !strncmp(p->name, profile_name, len)) { - *pptr = p; - return 0; - } - - p++; - } - - return 1; -} - -static int ssl_ctx_make_profiles(const char *profiles_string, - STACK_OF(SRTP_PROTECTION_PROFILE) **out) -{ - STACK_OF(SRTP_PROTECTION_PROFILE) *profiles; - - char *col; - char *ptr = (char *)profiles_string; - - SRTP_PROTECTION_PROFILE *p; - - if (!(profiles = sk_SRTP_PROTECTION_PROFILE_new_null())) { - SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, - SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); - return 1; - } - - do { - col = strchr(ptr, ':'); - - if (!find_profile_by_name(ptr, &p, - col ? col - ptr : (int)strlen(ptr))) { - if (sk_SRTP_PROTECTION_PROFILE_find(profiles, p) >= 0) { - SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - sk_SRTP_PROTECTION_PROFILE_free(profiles); - return 1; - } - - sk_SRTP_PROTECTION_PROFILE_push(profiles, p); - } else { - SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, - SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); - sk_SRTP_PROTECTION_PROFILE_free(profiles); - return 1; - } - - if (col) - ptr = col + 1; - } while (col); - - *out = profiles; - - return 0; -} - -int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) -{ - return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles); -} - -int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles) -{ - return ssl_ctx_make_profiles(profiles, &s->srtp_profiles); -} - -STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s) -{ - if (s != NULL) { - if (s->srtp_profiles != NULL) { - return s->srtp_profiles; - } else if ((s->ctx != NULL) && (s->ctx->srtp_profiles != NULL)) { - return s->ctx->srtp_profiles; - } - } - - return NULL; -} - -SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s) -{ - return s->srtp_profile; -} - -/* - * Note: this function returns 0 length if there are no profiles specified - */ -int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, - int maxlen) -{ - int ct = 0; - int i; - STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0; - SRTP_PROTECTION_PROFILE *prof; - - clnt = SSL_get_srtp_profiles(s); - ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */ - - if (p) { - if (ct == 0) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT, - SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); - return 1; - } - - if ((2 + ct * 2 + 1) > maxlen) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT, - SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); - return 1; - } - - /* Add the length */ - s2n(ct * 2, p); - for (i = 0; i < ct; i++) { - prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); - s2n(prof->id, p); - } - - /* Add an empty use_mki value */ - *p++ = 0; - } - - *len = 2 + ct * 2 + 1; - - return 0; -} - -int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len, - int *al) -{ - SRTP_PROTECTION_PROFILE *sprof; - STACK_OF(SRTP_PROTECTION_PROFILE) *srvr; - int ct; - int mki_len; - int i, srtp_pref; - unsigned int id; - - /* Length value + the MKI length */ - if (len < 3) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - /* Pull off the length of the cipher suite list */ - n2s(d, ct); - len -= 2; - - /* Check that it is even */ - if (ct % 2) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - /* Check that lengths are consistent */ - if (len < (ct + 1)) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - srvr = SSL_get_srtp_profiles(s); - s->srtp_profile = NULL; - /* Search all profiles for a match initially */ - srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr); - - while (ct) { - n2s(d, id); - ct -= 2; - len -= 2; - - /* - * Only look for match in profiles of higher preference than - * current match. - * If no profiles have been have been configured then this - * does nothing. - */ - for (i = 0; i < srtp_pref; i++) { - sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i); - if (sprof->id == id) { - s->srtp_profile = sprof; - srtp_pref = i; - break; - } - } - } - - /* - * Now extract the MKI value as a sanity check, but discard it for now - */ - mki_len = *d; - d++; - len--; - - if (mki_len != len) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_MKI_VALUE); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - return 0; -} - -int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, - int maxlen) -{ - if (p) { - if (maxlen < 5) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT, - SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); - return 1; - } - - if (s->srtp_profile == 0) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT, - SSL_R_USE_SRTP_NOT_NEGOTIATED); - return 1; - } - s2n(2, p); - s2n(s->srtp_profile->id, p); - *p++ = 0; - } - *len = 5; - - return 0; -} - -int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len, - int *al) -{ - unsigned id; - int i; - int ct; - - STACK_OF(SRTP_PROTECTION_PROFILE) *clnt; - SRTP_PROTECTION_PROFILE *prof; - - if (len != 5) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - n2s(d, ct); - if (ct != 2) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - n2s(d, id); - if (*d) { /* Must be no MKI, since we never offer one */ - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_MKI_VALUE); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 1; - } - - clnt = SSL_get_srtp_profiles(s); - - /* Throw an error if the server gave us an unsolicited extension */ - if (clnt == NULL) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, - SSL_R_NO_SRTP_PROFILES); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - /* - * Check to see if the server gave us something we support (and - * presumably offered) - */ - for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) { - prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); - - if (prof->id == id) { - s->srtp_profile = prof; - *al = 0; - return 0; - } - } - - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al = SSL_AD_DECODE_ERROR; - return 1; -} - -#endif diff --git a/thirdparty/openssl/ssl/d1_srvr.c b/thirdparty/openssl/ssl/d1_srvr.c deleted file mode 100644 index 8502b242e5..0000000000 --- a/thirdparty/openssl/ssl/d1_srvr.c +++ /dev/null @@ -1,985 +0,0 @@ -/* ssl/d1_srvr.c */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-2007 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 - * openssl-core@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). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include "ssl_locl.h" -#include <openssl/buffer.h> -#include <openssl/rand.h> -#include <openssl/objects.h> -#include <openssl/evp.h> -#include <openssl/x509.h> -#include <openssl/md5.h> -#include <openssl/bn.h> -#ifndef OPENSSL_NO_DH -# include <openssl/dh.h> -#endif - -static const SSL_METHOD *dtls1_get_server_method(int ver); -static int dtls1_send_hello_verify_request(SSL *s); - -static const SSL_METHOD *dtls1_get_server_method(int ver) -{ - if (ver == DTLS_ANY_VERSION) - return DTLS_server_method(); - else if (ver == DTLS1_VERSION) - return DTLSv1_server_method(); - else if (ver == DTLS1_2_VERSION) - return DTLSv1_2_server_method(); - else - return NULL; -} - -IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, - DTLSv1_server_method, - dtls1_accept, - ssl_undefined_function, - dtls1_get_server_method, DTLSv1_enc_data) - -IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, - DTLSv1_2_server_method, - dtls1_accept, - ssl_undefined_function, - dtls1_get_server_method, DTLSv1_2_enc_data) - -IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, - DTLS_server_method, - dtls1_accept, - ssl_undefined_function, - dtls1_get_server_method, DTLSv1_2_enc_data) - -int dtls1_accept(SSL *s) -{ - BUF_MEM *buf; - unsigned long Time = (unsigned long)time(NULL); - void (*cb) (const SSL *ssl, int type, int val) = NULL; - unsigned long alg_k; - int ret = -1; - int new_state, state, skip = 0; - int listen; -#ifndef OPENSSL_NO_SCTP - unsigned char sctpauthkey[64]; - char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; -#endif - - RAND_add(&Time, sizeof(Time), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - listen = s->d1->listen; - - /* init things to blank */ - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - s->d1->listen = listen; -#ifndef OPENSSL_NO_SCTP - /* - * Notify SCTP BIO socket to enter handshake mode and prevent stream - * identifier other than 0. Will be ignored if no SCTP is used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, - s->in_handshake, NULL); -#endif - - if (s->cert == NULL) { - SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_NO_CERTIFICATE_SET); - return (-1); - } -#ifndef OPENSSL_NO_HEARTBEATS - /* - * If we're awaiting a HeartbeatResponse, pretend we already got and - * don't await it anymore, because Heartbeats don't make sense during - * handshakes anyway. - */ - if (s->tlsext_hb_pending) { - dtls1_stop_timer(s); - s->tlsext_hb_pending = 0; - s->tlsext_hb_seq++; - } -#endif - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_RENEGOTIATE: - s->renegotiate = 1; - /* s->state=SSL_ST_ACCEPT; */ - - case SSL_ST_BEFORE: - case SSL_ST_ACCEPT: - case SSL_ST_BEFORE | SSL_ST_ACCEPT: - case SSL_ST_OK | SSL_ST_ACCEPT: - - s->server = 1; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { - SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR); - return -1; - } - s->type = SSL_ST_ACCEPT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - BUF_MEM_free(buf); - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - s->init_buf = buf; - } - - if (!ssl3_setup_buffers(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - s->init_num = 0; - s->d1->change_cipher_spec_ok = 0; - /* - * Should have been reset by ssl3_get_finished, too. - */ - s->s3->change_cipher_spec = 0; - - if (s->state != SSL_ST_RENEGOTIATE) { - /* - * Ok, we now need to push on a buffering BIO so that the - * output is sent in a way that TCP likes :-) ...but not with - * SCTP :-) - */ -#ifndef OPENSSL_NO_SCTP - if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) -#endif - if (!ssl_init_wbio_buffer(s, 1)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - s->state = SSL3_ST_SR_CLNT_HELLO_A; - s->ctx->stats.sess_accept++; - } else if (!s->s3->send_connection_binding && - !(s->options & - SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { - /* - * Server attempting to renegotiate with client that doesn't - * support secure renegotiation. - */ - SSLerr(SSL_F_DTLS1_ACCEPT, - SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } else { - /* - * s->state == SSL_ST_RENEGOTIATE, we will just send a - * HelloRequest - */ - s->ctx->stats.sess_accept_renegotiate++; - s->state = SSL3_ST_SW_HELLO_REQ_A; - } - - break; - - case SSL3_ST_SW_HELLO_REQ_A: - case SSL3_ST_SW_HELLO_REQ_B: - - s->shutdown = 0; - dtls1_clear_sent_buffer(s); - dtls1_start_timer(s); - ret = ssl3_send_hello_request(s); - if (ret <= 0) - goto end; - s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A; - s->state = SSL3_ST_SW_FLUSH; - s->init_num = 0; - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - break; - - case SSL3_ST_SW_HELLO_REQ_C: - s->state = SSL_ST_OK; - break; - - case SSL3_ST_SR_CLNT_HELLO_A: - case SSL3_ST_SR_CLNT_HELLO_B: - case SSL3_ST_SR_CLNT_HELLO_C: - - s->shutdown = 0; - ret = ssl3_get_client_hello(s); - if (ret <= 0) - goto end; - dtls1_stop_timer(s); - - if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) - s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A; - else - s->state = SSL3_ST_SW_SRVR_HELLO_A; - - s->init_num = 0; - - /* If we're just listening, stop here */ - if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) { - ret = 2; - s->d1->listen = 0; - /* - * Set expected sequence numbers to continue the handshake. - */ - s->d1->handshake_read_seq = 2; - s->d1->handshake_write_seq = 1; - s->d1->next_handshake_write_seq = 1; - goto end; - } - - break; - - case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: - case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: - - ret = dtls1_send_hello_verify_request(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_FLUSH; - s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A; - - /* HelloVerifyRequest resets Finished MAC */ - if (s->version != DTLS1_BAD_VER) - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - break; - -#ifndef OPENSSL_NO_SCTP - case DTLS1_SCTP_ST_SR_READ_SOCK: - - if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { - s->s3->in_read_app_data = 2; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - ret = -1; - goto end; - } - - s->state = SSL3_ST_SR_FINISHED_A; - break; - - case DTLS1_SCTP_ST_SW_WRITE_SOCK: - ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); - if (ret < 0) - goto end; - - if (ret == 0) { - if (s->d1->next_state != SSL_ST_OK) { - s->s3->in_read_app_data = 2; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - ret = -1; - goto end; - } - } - - s->state = s->d1->next_state; - break; -#endif - - case SSL3_ST_SW_SRVR_HELLO_A: - case SSL3_ST_SW_SRVR_HELLO_B: - s->renegotiate = 2; - dtls1_start_timer(s); - ret = ssl3_send_server_hello(s); - if (ret <= 0) - goto end; - - if (s->hit) { -#ifndef OPENSSL_NO_SCTP - /* - * Add new shared key for SCTP-Auth, will be ignored if no - * SCTP used. - */ - snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), - DTLS1_SCTP_AUTH_LABEL); - - if (SSL_export_keying_material(s, sctpauthkey, - sizeof(sctpauthkey), labelbuffer, - sizeof(labelbuffer), NULL, 0, 0) <= 0) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, - sizeof(sctpauthkey), sctpauthkey); -#endif -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_ticket_expected) - s->state = SSL3_ST_SW_SESSION_TICKET_A; - else - s->state = SSL3_ST_SW_CHANGE_A; -#else - s->state = SSL3_ST_SW_CHANGE_A; -#endif - } else - s->state = SSL3_ST_SW_CERT_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_CERT_A: - case SSL3_ST_SW_CERT_B: - /* Check if it is anon DH or normal PSK */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - dtls1_start_timer(s); - ret = ssl3_send_server_certificate(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_status_expected) - s->state = SSL3_ST_SW_CERT_STATUS_A; - else - s->state = SSL3_ST_SW_KEY_EXCH_A; - } else { - skip = 1; - s->state = SSL3_ST_SW_KEY_EXCH_A; - } -#else - } else - skip = 1; - - s->state = SSL3_ST_SW_KEY_EXCH_A; -#endif - s->init_num = 0; - break; - - case SSL3_ST_SW_KEY_EXCH_A: - case SSL3_ST_SW_KEY_EXCH_B: - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - - /* - * clear this, it may get reset by - * send_server_key_exchange - */ - s->s3->tmp.use_rsa_tmp = 0; - - /* - * only send if a DH key exchange or RSA but we have a sign only - * certificate - */ - if (0 - /* - * PSK: send ServerKeyExchange if PSK identity hint if - * provided - */ -#ifndef OPENSSL_NO_PSK - || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) -#endif - || (alg_k & SSL_kDHE) - || (alg_k & SSL_kEECDH) - || ((alg_k & SSL_kRSA) - && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL - || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) - && EVP_PKEY_size(s->cert->pkeys - [SSL_PKEY_RSA_ENC].privatekey) * - 8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) - ) - ) - ) - ) { - dtls1_start_timer(s); - ret = ssl3_send_server_key_exchange(s); - if (ret <= 0) - goto end; - } else - skip = 1; - - s->state = SSL3_ST_SW_CERT_REQ_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_CERT_REQ_A: - case SSL3_ST_SW_CERT_REQ_B: - if ( /* don't request cert unless asked for it: */ - !(s->verify_mode & SSL_VERIFY_PEER) || - /* - * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert - * during re-negotiation: - */ - ((s->session->peer != NULL) && - (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || - /* - * never request cert in anonymous ciphersuites (see - * section "Certificate request" in SSL 3 drafts and in - * RFC 2246): - */ - ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && - /* - * ... except when the application insists on - * verification (against the specs, but s3_clnt.c accepts - * this for SSL 3) - */ - !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || - /* - * never request cert in Kerberos ciphersuites - */ - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) - /* - * With normal PSK Certificates and Certificate Requests - * are omitted - */ - || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - /* no cert request */ - skip = 1; - s->s3->tmp.cert_request = 0; - s->state = SSL3_ST_SW_SRVR_DONE_A; -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A; - s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK; - } -#endif - } else { - s->s3->tmp.cert_request = 1; - dtls1_start_timer(s); - ret = ssl3_send_certificate_request(s); - if (ret <= 0) - goto end; -#ifndef NETSCAPE_HANG_BUG - s->state = SSL3_ST_SW_SRVR_DONE_A; -# ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A; - s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK; - } -# endif -#else - s->state = SSL3_ST_SW_FLUSH; - s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; -# ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = s->s3->tmp.next_state; - s->s3->tmp.next_state = DTLS1_SCTP_ST_SW_WRITE_SOCK; - } -# endif -#endif - s->init_num = 0; - } - break; - - case SSL3_ST_SW_SRVR_DONE_A: - case SSL3_ST_SW_SRVR_DONE_B: - dtls1_start_timer(s); - ret = ssl3_send_server_done(s); - if (ret <= 0) - goto end; - s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; - s->state = SSL3_ST_SW_FLUSH; - s->init_num = 0; - break; - - case SSL3_ST_SW_FLUSH: - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { - /* - * If the write error was fatal, stop trying - */ - if (!BIO_should_retry(s->wbio)) { - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; - } - - ret = -1; - goto end; - } - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; - break; - - case SSL3_ST_SR_CERT_A: - case SSL3_ST_SR_CERT_B: - if (s->s3->tmp.cert_request) { - ret = ssl3_get_client_certificate(s); - if (ret <= 0) - goto end; - } - s->init_num = 0; - s->state = SSL3_ST_SR_KEY_EXCH_A; - break; - - case SSL3_ST_SR_KEY_EXCH_A: - case SSL3_ST_SR_KEY_EXCH_B: - ret = ssl3_get_client_key_exchange(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_SCTP - /* - * Add new shared key for SCTP-Auth, will be ignored if no SCTP - * used. - */ - snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), - DTLS1_SCTP_AUTH_LABEL); - - if (SSL_export_keying_material(s, sctpauthkey, - sizeof(sctpauthkey), labelbuffer, - sizeof(labelbuffer), NULL, 0, 0) <= 0) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, - sizeof(sctpauthkey), sctpauthkey); -#endif - - s->state = SSL3_ST_SR_CERT_VRFY_A; - s->init_num = 0; - - if (ret == 2) { - /* - * For the ECDH ciphersuites when the client sends its ECDH - * pub key in a certificate, the CertificateVerify message is - * not sent. - */ - s->state = SSL3_ST_SR_FINISHED_A; - s->init_num = 0; - } else if (SSL_USE_SIGALGS(s)) { - s->state = SSL3_ST_SR_CERT_VRFY_A; - s->init_num = 0; - if (!s->session->peer) - break; - /* - * For sigalgs freeze the handshake buffer at this point and - * digest cached records. - */ - if (!s->s3->handshake_buffer) { - SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return -1; - } - s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; - if (!ssl3_digest_cached_records(s)) { - s->state = SSL_ST_ERR; - return -1; - } - } else { - s->state = SSL3_ST_SR_CERT_VRFY_A; - s->init_num = 0; - - /* - * We need to get hashes here so if there is a client cert, - * it can be verified - */ - s->method->ssl3_enc->cert_verify_mac(s, - NID_md5, - &(s->s3-> - tmp.cert_verify_md - [0])); - s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, - &(s->s3-> - tmp.cert_verify_md - [MD5_DIGEST_LENGTH])); - } - break; - - case SSL3_ST_SR_CERT_VRFY_A: - case SSL3_ST_SR_CERT_VRFY_B: - ret = ssl3_get_cert_verify(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && - state == SSL_ST_RENEGOTIATE) - s->state = DTLS1_SCTP_ST_SR_READ_SOCK; - else -#endif - s->state = SSL3_ST_SR_FINISHED_A; - s->init_num = 0; - break; - - case SSL3_ST_SR_FINISHED_A: - case SSL3_ST_SR_FINISHED_B: - /* - * Enable CCS. Receiving a CCS clears the flag, so make - * sure not to re-enable it to ban duplicates. This *should* be the - * first time we have received one - but we check anyway to be - * cautious. - * s->s3->change_cipher_spec is set when a CCS is - * processed in d1_pkt.c, and remains set until - * the client's Finished message is read. - */ - if (!s->s3->change_cipher_spec) - s->d1->change_cipher_spec_ok = 1; - ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, - SSL3_ST_SR_FINISHED_B); - if (ret <= 0) - goto end; - dtls1_stop_timer(s); - if (s->hit) - s->state = SSL_ST_OK; -#ifndef OPENSSL_NO_TLSEXT - else if (s->tlsext_ticket_expected) - s->state = SSL3_ST_SW_SESSION_TICKET_A; -#endif - else - s->state = SSL3_ST_SW_CHANGE_A; - s->init_num = 0; - break; - -#ifndef OPENSSL_NO_TLSEXT - case SSL3_ST_SW_SESSION_TICKET_A: - case SSL3_ST_SW_SESSION_TICKET_B: - ret = ssl3_send_newsession_ticket(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_CHANGE_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_CERT_STATUS_A: - case SSL3_ST_SW_CERT_STATUS_B: - ret = ssl3_send_cert_status(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_KEY_EXCH_A; - s->init_num = 0; - break; - -#endif - - case SSL3_ST_SW_CHANGE_A: - case SSL3_ST_SW_CHANGE_B: - - s->session->cipher = s->s3->tmp.new_cipher; - if (!s->method->ssl3_enc->setup_key_block(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - ret = dtls1_send_change_cipher_spec(s, - SSL3_ST_SW_CHANGE_A, - SSL3_ST_SW_CHANGE_B); - - if (ret <= 0) - goto end; - -#ifndef OPENSSL_NO_SCTP - if (!s->hit) { - /* - * Change to new shared key of SCTP-Auth, will be ignored if - * no SCTP used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, - 0, NULL); - } -#endif - - s->state = SSL3_ST_SW_FINISHED_A; - s->init_num = 0; - - if (!s->method->ssl3_enc->change_cipher_state(s, - SSL3_CHANGE_CIPHER_SERVER_WRITE)) - { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); - break; - - case SSL3_ST_SW_FINISHED_A: - case SSL3_ST_SW_FINISHED_B: - ret = ssl3_send_finished(s, - SSL3_ST_SW_FINISHED_A, - SSL3_ST_SW_FINISHED_B, - s->method-> - ssl3_enc->server_finished_label, - s->method-> - ssl3_enc->server_finished_label_len); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_FLUSH; - if (s->hit) { - s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; - -#ifndef OPENSSL_NO_SCTP - /* - * Change to new shared key of SCTP-Auth, will be ignored if - * no SCTP used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, - 0, NULL); -#endif - } else { - s->s3->tmp.next_state = SSL_ST_OK; -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = s->s3->tmp.next_state; - s->s3->tmp.next_state = DTLS1_SCTP_ST_SW_WRITE_SOCK; - } -#endif - } - s->init_num = 0; - break; - - case SSL_ST_OK: - /* clean a few things up */ - ssl3_cleanup_key_block(s); - -#if 0 - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; -#endif - - /* remove buffering on output */ - ssl_free_wbio_buffer(s); - - s->init_num = 0; - - if (s->renegotiate == 2) { /* skipped if we just sent a - * HelloRequest */ - s->renegotiate = 0; - s->new_session = 0; - - ssl_update_cache(s, SSL_SESS_CACHE_SERVER); - - s->ctx->stats.sess_accept_good++; - /* s->server=1; */ - s->handshake_func = dtls1_accept; - - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - } - - ret = 1; - - /* done handshaking, next message is client hello */ - s->d1->handshake_read_seq = 0; - /* next message is server hello */ - s->d1->handshake_write_seq = 0; - s->d1->next_handshake_write_seq = 0; - dtls1_clear_received_buffer(s); - goto end; - /* break; */ - - case SSL_ST_ERR: - default: - SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* break; */ - } - - if (!s->s3->tmp.reuse_message && !skip) { - if (s->debug) { - if ((ret = BIO_flush(s->wbio)) <= 0) - goto end; - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_ACCEPT_LOOP, 1); - s->state = new_state; - } - } - skip = 0; - } - end: - /* BIO_flush(s->wbio); */ - - s->in_handshake--; -#ifndef OPENSSL_NO_SCTP - /* - * Notify SCTP BIO socket to leave handshake mode and prevent stream - * identifier other than 0. Will be ignored if no SCTP is used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, - s->in_handshake, NULL); -#endif - - if (cb != NULL) - cb(s, SSL_CB_ACCEPT_EXIT, ret); - return (ret); -} - -int dtls1_send_hello_verify_request(SSL *s) -{ - unsigned int msg_len; - unsigned char *msg, *buf, *p; - - if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A) { - buf = (unsigned char *)s->init_buf->data; - - msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]); - /* Always use DTLS 1.0 version: see RFC 6347 */ - *(p++) = DTLS1_VERSION >> 8; - *(p++) = DTLS1_VERSION & 0xFF; - - if (s->ctx->app_gen_cookie_cb == NULL || - s->ctx->app_gen_cookie_cb(s, s->d1->cookie, - &(s->d1->cookie_len)) == 0) { - SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST, - ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return 0; - } - - *(p++) = (unsigned char)s->d1->cookie_len; - memcpy(p, s->d1->cookie, s->d1->cookie_len); - p += s->d1->cookie_len; - msg_len = p - msg; - - dtls1_set_message_header(s, buf, - DTLS1_MT_HELLO_VERIFY_REQUEST, msg_len, 0, - msg_len); - - s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B; - /* number of bytes to write */ - s->init_num = p - buf; - s->init_off = 0; - } - - /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */ - return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); -} diff --git a/thirdparty/openssl/ssl/kssl.c b/thirdparty/openssl/ssl/kssl.c deleted file mode 100644 index f2839bdcd7..0000000000 --- a/thirdparty/openssl/ssl/kssl.c +++ /dev/null @@ -1,2260 +0,0 @@ -/* ssl/kssl.c */ -/* - * Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 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). - * - */ - -/*- - * ssl/kssl.c -- Routines to support (& debug) Kerberos5 auth for openssl - * - * 19990701 VRS Started. - * 200011?? Jeffrey Altman, Richard Levitte - * Generalized for Heimdal, Newer MIT, & Win32. - * Integrated into main OpenSSL 0.9.7 snapshots. - * 20010413 Simon Wilkinson, VRS - * Real RFC2712 KerberosWrapper replaces AP_REQ. - */ - -#include <openssl/opensslconf.h> - -#include <string.h> - -#define KRB5_PRIVATE 1 - -#include <openssl/ssl.h> -#include <openssl/evp.h> -#include <openssl/objects.h> -#include <openssl/krb5_asn.h> -#include "kssl_lcl.h" - -#ifndef OPENSSL_NO_KRB5 - -# ifndef ENOMEM -# define ENOMEM KRB5KRB_ERR_GENERIC -# endif - -/* - * When OpenSSL is built on Windows, we do not want to require that - * the Kerberos DLLs be available in order for the OpenSSL DLLs to - * work. Therefore, all Kerberos routines are loaded at run time - * and we do not link to a .LIB file. - */ - -# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) -/* - * The purpose of the following pre-processor statements is to provide - * compatibility with different releases of MIT Kerberos for Windows. - * All versions up to 1.2 used macros. But macros do not allow for - * a binary compatible interface for DLLs. Therefore, all macros are - * being replaced by function calls. The following code will allow - * an OpenSSL DLL built on Windows to work whether or not the macro - * or function form of the routines are utilized. - */ -# ifdef krb5_cc_get_principal -# define NO_DEF_KRB5_CCACHE -# undef krb5_cc_get_principal -# endif -# define krb5_cc_get_principal kssl_krb5_cc_get_principal - -# define krb5_free_data_contents kssl_krb5_free_data_contents -# define krb5_free_context kssl_krb5_free_context -# define krb5_auth_con_free kssl_krb5_auth_con_free -# define krb5_free_principal kssl_krb5_free_principal -# define krb5_mk_req_extended kssl_krb5_mk_req_extended -# define krb5_get_credentials kssl_krb5_get_credentials -# define krb5_cc_default kssl_krb5_cc_default -# define krb5_sname_to_principal kssl_krb5_sname_to_principal -# define krb5_init_context kssl_krb5_init_context -# define krb5_free_ticket kssl_krb5_free_ticket -# define krb5_rd_req kssl_krb5_rd_req -# define krb5_kt_default kssl_krb5_kt_default -# define krb5_kt_resolve kssl_krb5_kt_resolve -/* macros in mit 1.2.2 and earlier; functions in mit 1.2.3 and greater */ -# ifndef krb5_kt_close -# define krb5_kt_close kssl_krb5_kt_close -# endif /* krb5_kt_close */ -# ifndef krb5_kt_get_entry -# define krb5_kt_get_entry kssl_krb5_kt_get_entry -# endif /* krb5_kt_get_entry */ -# define krb5_auth_con_init kssl_krb5_auth_con_init - -# define krb5_principal_compare kssl_krb5_principal_compare -# define krb5_decrypt_tkt_part kssl_krb5_decrypt_tkt_part -# define krb5_timeofday kssl_krb5_timeofday -# define krb5_rc_default kssl_krb5_rc_default - -# ifdef krb5_rc_initialize -# undef krb5_rc_initialize -# endif -# define krb5_rc_initialize kssl_krb5_rc_initialize - -# ifdef krb5_rc_get_lifespan -# undef krb5_rc_get_lifespan -# endif -# define krb5_rc_get_lifespan kssl_krb5_rc_get_lifespan - -# ifdef krb5_rc_destroy -# undef krb5_rc_destroy -# endif -# define krb5_rc_destroy kssl_krb5_rc_destroy - -# define valid_cksumtype kssl_valid_cksumtype -# define krb5_checksum_size kssl_krb5_checksum_size -# define krb5_kt_free_entry kssl_krb5_kt_free_entry -# define krb5_auth_con_setrcache kssl_krb5_auth_con_setrcache -# define krb5_auth_con_getrcache kssl_krb5_auth_con_getrcache -# define krb5_get_server_rcache kssl_krb5_get_server_rcache - -/* Prototypes for built in stubs */ -void kssl_krb5_free_data_contents(krb5_context, krb5_data *); -void kssl_krb5_free_principal(krb5_context, krb5_principal); -krb5_error_code kssl_krb5_kt_resolve(krb5_context, - krb5_const char *, krb5_keytab *); -krb5_error_code kssl_krb5_kt_default(krb5_context, krb5_keytab *); -krb5_error_code kssl_krb5_free_ticket(krb5_context, krb5_ticket *); -krb5_error_code kssl_krb5_rd_req(krb5_context, krb5_auth_context *, - krb5_const krb5_data *, - krb5_const_principal, krb5_keytab, - krb5_flags *, krb5_ticket **); - -krb5_boolean kssl_krb5_principal_compare(krb5_context, krb5_const_principal, - krb5_const_principal); -krb5_error_code kssl_krb5_mk_req_extended(krb5_context, - krb5_auth_context *, - krb5_const krb5_flags, - krb5_data *, - krb5_creds *, krb5_data *); -krb5_error_code kssl_krb5_init_context(krb5_context *); -void kssl_krb5_free_context(krb5_context); -krb5_error_code kssl_krb5_cc_default(krb5_context, krb5_ccache *); -krb5_error_code kssl_krb5_sname_to_principal(krb5_context, - krb5_const char *, - krb5_const char *, - krb5_int32, krb5_principal *); -krb5_error_code kssl_krb5_get_credentials(krb5_context, - krb5_const krb5_flags, - krb5_ccache, - krb5_creds *, krb5_creds * *); -krb5_error_code kssl_krb5_auth_con_init(krb5_context, krb5_auth_context *); -krb5_error_code kssl_krb5_cc_get_principal(krb5_context context, - krb5_ccache cache, - krb5_principal *principal); -krb5_error_code kssl_krb5_auth_con_free(krb5_context, krb5_auth_context); -size_t kssl_krb5_checksum_size(krb5_context context, krb5_cksumtype ctype); -krb5_boolean kssl_valid_cksumtype(krb5_cksumtype ctype); -krb5_error_code krb5_kt_free_entry(krb5_context, krb5_keytab_entry FAR *); -krb5_error_code kssl_krb5_auth_con_setrcache(krb5_context, - krb5_auth_context, krb5_rcache); -krb5_error_code kssl_krb5_get_server_rcache(krb5_context, - krb5_const krb5_data *, - krb5_rcache *); -krb5_error_code kssl_krb5_auth_con_getrcache(krb5_context, - krb5_auth_context, - krb5_rcache *); - -/* Function pointers (almost all Kerberos functions are _stdcall) */ -static void (_stdcall *p_krb5_free_data_contents) (krb5_context, krb5_data *) - = NULL; -static void (_stdcall *p_krb5_free_principal) (krb5_context, krb5_principal) - = NULL; -static krb5_error_code(_stdcall *p_krb5_kt_resolve) - (krb5_context, krb5_const char *, krb5_keytab *) = NULL; -static krb5_error_code(_stdcall *p_krb5_kt_default) (krb5_context, - krb5_keytab *) = NULL; -static krb5_error_code(_stdcall *p_krb5_free_ticket) (krb5_context, - krb5_ticket *) = NULL; -static krb5_error_code(_stdcall *p_krb5_rd_req) (krb5_context, - krb5_auth_context *, - krb5_const krb5_data *, - krb5_const_principal, - krb5_keytab, krb5_flags *, - krb5_ticket **) = NULL; -static krb5_error_code(_stdcall *p_krb5_mk_req_extended) - (krb5_context, krb5_auth_context *, - krb5_const krb5_flags, krb5_data *, krb5_creds *, krb5_data *) = NULL; -static krb5_error_code(_stdcall *p_krb5_init_context) (krb5_context *) = NULL; -static void (_stdcall *p_krb5_free_context) (krb5_context) = NULL; -static krb5_error_code(_stdcall *p_krb5_cc_default) (krb5_context, - krb5_ccache *) = NULL; -static krb5_error_code(_stdcall *p_krb5_sname_to_principal) - (krb5_context, krb5_const char *, krb5_const char *, - krb5_int32, krb5_principal *) = NULL; -static krb5_error_code(_stdcall *p_krb5_get_credentials) - (krb5_context, krb5_const krb5_flags, krb5_ccache, - krb5_creds *, krb5_creds **) = NULL; -static krb5_error_code(_stdcall *p_krb5_auth_con_init) - (krb5_context, krb5_auth_context *) = NULL; -static krb5_error_code(_stdcall *p_krb5_cc_get_principal) - (krb5_context context, krb5_ccache cache, krb5_principal *principal) = NULL; -static krb5_error_code(_stdcall *p_krb5_auth_con_free) - (krb5_context, krb5_auth_context) = NULL; -static krb5_error_code(_stdcall *p_krb5_decrypt_tkt_part) - (krb5_context, krb5_const krb5_keyblock *, krb5_ticket *) = NULL; -static krb5_error_code(_stdcall *p_krb5_timeofday) - (krb5_context context, krb5_int32 *timeret) = NULL; -static krb5_error_code(_stdcall *p_krb5_rc_default) - (krb5_context context, krb5_rcache *rc) = NULL; -static krb5_error_code(_stdcall *p_krb5_rc_initialize) - (krb5_context context, krb5_rcache rc, krb5_deltat lifespan) = NULL; -static krb5_error_code(_stdcall *p_krb5_rc_get_lifespan) - (krb5_context context, krb5_rcache rc, krb5_deltat *lifespan) = NULL; -static krb5_error_code(_stdcall *p_krb5_rc_destroy) - (krb5_context context, krb5_rcache rc) = NULL; -static krb5_boolean(_stdcall *p_krb5_principal_compare) - (krb5_context, krb5_const_principal, krb5_const_principal) = NULL; -static size_t (_stdcall *p_krb5_checksum_size) (krb5_context context, - krb5_cksumtype ctype) = NULL; -static krb5_boolean(_stdcall *p_valid_cksumtype) (krb5_cksumtype ctype) = - NULL; -static krb5_error_code(_stdcall *p_krb5_kt_free_entry) - (krb5_context, krb5_keytab_entry *) = NULL; -static krb5_error_code(_stdcall *p_krb5_auth_con_setrcache) (krb5_context, - krb5_auth_context, - krb5_rcache) = - NULL; -static krb5_error_code(_stdcall *p_krb5_get_server_rcache) (krb5_context, - krb5_const - krb5_data *, - krb5_rcache *) = - NULL; -static krb5_error_code(*p_krb5_auth_con_getrcache) (krb5_context, - krb5_auth_context, - krb5_rcache *) = NULL; -static krb5_error_code(_stdcall *p_krb5_kt_close) (krb5_context context, - krb5_keytab keytab) = NULL; -static krb5_error_code(_stdcall *p_krb5_kt_get_entry) (krb5_context context, - krb5_keytab keytab, - krb5_const_principal - principal, - krb5_kvno vno, - krb5_enctype enctype, - krb5_keytab_entry - *entry) = NULL; -static int krb5_loaded = 0; /* only attempt to initialize func ptrs once */ - -/* Function to Load the Kerberos 5 DLL and initialize function pointers */ -void load_krb5_dll(void) -{ - HANDLE hKRB5_32; - - krb5_loaded++; - hKRB5_32 = LoadLibrary(TEXT("KRB5_32")); - if (!hKRB5_32) - return; - - (FARPROC) p_krb5_free_data_contents = - GetProcAddress(hKRB5_32, "krb5_free_data_contents"); - (FARPROC) p_krb5_free_context = - GetProcAddress(hKRB5_32, "krb5_free_context"); - (FARPROC) p_krb5_auth_con_free = - GetProcAddress(hKRB5_32, "krb5_auth_con_free"); - (FARPROC) p_krb5_free_principal = - GetProcAddress(hKRB5_32, "krb5_free_principal"); - (FARPROC) p_krb5_mk_req_extended = - GetProcAddress(hKRB5_32, "krb5_mk_req_extended"); - (FARPROC) p_krb5_get_credentials = - GetProcAddress(hKRB5_32, "krb5_get_credentials"); - (FARPROC) p_krb5_cc_get_principal = - GetProcAddress(hKRB5_32, "krb5_cc_get_principal"); - (FARPROC) p_krb5_cc_default = GetProcAddress(hKRB5_32, "krb5_cc_default"); - (FARPROC) p_krb5_sname_to_principal = - GetProcAddress(hKRB5_32, "krb5_sname_to_principal"); - (FARPROC) p_krb5_init_context = - GetProcAddress(hKRB5_32, "krb5_init_context"); - (FARPROC) p_krb5_free_ticket = - GetProcAddress(hKRB5_32, "krb5_free_ticket"); - (FARPROC) p_krb5_rd_req = GetProcAddress(hKRB5_32, "krb5_rd_req"); - (FARPROC) p_krb5_principal_compare = - GetProcAddress(hKRB5_32, "krb5_principal_compare"); - (FARPROC) p_krb5_decrypt_tkt_part = - GetProcAddress(hKRB5_32, "krb5_decrypt_tkt_part"); - (FARPROC) p_krb5_timeofday = GetProcAddress(hKRB5_32, "krb5_timeofday"); - (FARPROC) p_krb5_rc_default = GetProcAddress(hKRB5_32, "krb5_rc_default"); - (FARPROC) p_krb5_rc_initialize = - GetProcAddress(hKRB5_32, "krb5_rc_initialize"); - (FARPROC) p_krb5_rc_get_lifespan = - GetProcAddress(hKRB5_32, "krb5_rc_get_lifespan"); - (FARPROC) p_krb5_rc_destroy = GetProcAddress(hKRB5_32, "krb5_rc_destroy"); - (FARPROC) p_krb5_kt_default = GetProcAddress(hKRB5_32, "krb5_kt_default"); - (FARPROC) p_krb5_kt_resolve = GetProcAddress(hKRB5_32, "krb5_kt_resolve"); - (FARPROC) p_krb5_auth_con_init = - GetProcAddress(hKRB5_32, "krb5_auth_con_init"); - (FARPROC) p_valid_cksumtype = GetProcAddress(hKRB5_32, "valid_cksumtype"); - (FARPROC) p_krb5_checksum_size = - GetProcAddress(hKRB5_32, "krb5_checksum_size"); - (FARPROC) p_krb5_kt_free_entry = - GetProcAddress(hKRB5_32, "krb5_kt_free_entry"); - (FARPROC) p_krb5_auth_con_setrcache = - GetProcAddress(hKRB5_32, "krb5_auth_con_setrcache"); - (FARPROC) p_krb5_get_server_rcache = - GetProcAddress(hKRB5_32, "krb5_get_server_rcache"); - (FARPROC) p_krb5_auth_con_getrcache = - GetProcAddress(hKRB5_32, "krb5_auth_con_getrcache"); - (FARPROC) p_krb5_kt_close = GetProcAddress(hKRB5_32, "krb5_kt_close"); - (FARPROC) p_krb5_kt_get_entry = - GetProcAddress(hKRB5_32, "krb5_kt_get_entry"); -} - -/* Stubs for each function to be dynamicly loaded */ -void kssl_krb5_free_data_contents(krb5_context CO, krb5_data *data) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_free_data_contents) - p_krb5_free_data_contents(CO, data); -} - -krb5_error_code -kssl_krb5_mk_req_extended(krb5_context CO, - krb5_auth_context *pACO, - krb5_const krb5_flags F, - krb5_data *pD1, krb5_creds *pC, krb5_data *pD2) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_mk_req_extended) - return (p_krb5_mk_req_extended(CO, pACO, F, pD1, pC, pD2)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_auth_con_init(krb5_context CO, krb5_auth_context *pACO) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_auth_con_init) - return (p_krb5_auth_con_init(CO, pACO)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_auth_con_free(krb5_context CO, krb5_auth_context ACO) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_auth_con_free) - return (p_krb5_auth_con_free(CO, ACO)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_get_credentials(krb5_context CO, - krb5_const krb5_flags F, - krb5_ccache CC, krb5_creds *pCR, krb5_creds **ppCR) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_get_credentials) - return (p_krb5_get_credentials(CO, F, CC, pCR, ppCR)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_sname_to_principal(krb5_context CO, - krb5_const char *pC1, - krb5_const char *pC2, - krb5_int32 I, krb5_principal *pPR) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_sname_to_principal) - return (p_krb5_sname_to_principal(CO, pC1, pC2, I, pPR)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code kssl_krb5_cc_default(krb5_context CO, krb5_ccache *pCC) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_cc_default) - return (p_krb5_cc_default(CO, pCC)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code kssl_krb5_init_context(krb5_context *pCO) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_init_context) - return (p_krb5_init_context(pCO)); - else - return KRB5KRB_ERR_GENERIC; -} - -void kssl_krb5_free_context(krb5_context CO) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_free_context) - p_krb5_free_context(CO); -} - -void kssl_krb5_free_principal(krb5_context c, krb5_principal p) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_free_principal) - p_krb5_free_principal(c, p); -} - -krb5_error_code -kssl_krb5_kt_resolve(krb5_context con, krb5_const char *sz, krb5_keytab *kt) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_kt_resolve) - return (p_krb5_kt_resolve(con, sz, kt)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code kssl_krb5_kt_default(krb5_context con, krb5_keytab *kt) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_kt_default) - return (p_krb5_kt_default(con, kt)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code kssl_krb5_free_ticket(krb5_context con, krb5_ticket *kt) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_free_ticket) - return (p_krb5_free_ticket(con, kt)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_rd_req(krb5_context con, krb5_auth_context *pacon, - krb5_const krb5_data *data, - krb5_const_principal princ, krb5_keytab keytab, - krb5_flags *flags, krb5_ticket **pptkt) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_rd_req) - return (p_krb5_rd_req(con, pacon, data, princ, keytab, flags, pptkt)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_boolean -krb5_principal_compare(krb5_context con, krb5_const_principal princ1, - krb5_const_principal princ2) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_principal_compare) - return (p_krb5_principal_compare(con, princ1, princ2)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -krb5_decrypt_tkt_part(krb5_context con, krb5_const krb5_keyblock *keys, - krb5_ticket *ticket) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_decrypt_tkt_part) - return (p_krb5_decrypt_tkt_part(con, keys, ticket)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code krb5_timeofday(krb5_context con, krb5_int32 *timeret) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_timeofday) - return (p_krb5_timeofday(con, timeret)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code krb5_rc_default(krb5_context con, krb5_rcache *rc) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_rc_default) - return (p_krb5_rc_default(con, rc)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -krb5_rc_initialize(krb5_context con, krb5_rcache rc, krb5_deltat lifespan) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_rc_initialize) - return (p_krb5_rc_initialize(con, rc, lifespan)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -krb5_rc_get_lifespan(krb5_context con, krb5_rcache rc, krb5_deltat *lifespanp) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_rc_get_lifespan) - return (p_krb5_rc_get_lifespan(con, rc, lifespanp)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code krb5_rc_destroy(krb5_context con, krb5_rcache rc) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_rc_destroy) - return (p_krb5_rc_destroy(con, rc)); - else - return KRB5KRB_ERR_GENERIC; -} - -size_t krb5_checksum_size(krb5_context context, krb5_cksumtype ctype) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_checksum_size) - return (p_krb5_checksum_size(context, ctype)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_boolean valid_cksumtype(krb5_cksumtype ctype) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_valid_cksumtype) - return (p_valid_cksumtype(ctype)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code krb5_kt_free_entry(krb5_context con, krb5_keytab_entry *entry) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_kt_free_entry) - return (p_krb5_kt_free_entry(con, entry)); - else - return KRB5KRB_ERR_GENERIC; -} - -/* Structure definitions */ -# ifndef NO_DEF_KRB5_CCACHE -# ifndef krb5_x -# define krb5_x(ptr,args) ((ptr)?((*(ptr)) args):(abort(),1)) -# define krb5_xc(ptr,args) ((ptr)?((*(ptr)) args):(abort(),(char*)0)) -# endif - -typedef krb5_pointer krb5_cc_cursor; /* cursor for sequential lookup */ - -typedef struct _krb5_ccache { - krb5_magic magic; - struct _krb5_cc_ops FAR *ops; - krb5_pointer data; -} *krb5_ccache; - -typedef struct _krb5_cc_ops { - krb5_magic magic; - char *prefix; - char *(KRB5_CALLCONV *get_name) - (krb5_context, krb5_ccache); - krb5_error_code(KRB5_CALLCONV *resolve) - (krb5_context, krb5_ccache *, const char *); - krb5_error_code(KRB5_CALLCONV *gen_new) - (krb5_context, krb5_ccache *); - krb5_error_code(KRB5_CALLCONV *init) - (krb5_context, krb5_ccache, krb5_principal); - krb5_error_code(KRB5_CALLCONV *destroy) - (krb5_context, krb5_ccache); - krb5_error_code(KRB5_CALLCONV *close) - (krb5_context, krb5_ccache); - krb5_error_code(KRB5_CALLCONV *store) - (krb5_context, krb5_ccache, krb5_creds *); - krb5_error_code(KRB5_CALLCONV *retrieve) - (krb5_context, krb5_ccache, krb5_flags, krb5_creds *, krb5_creds *); - krb5_error_code(KRB5_CALLCONV *get_princ) - (krb5_context, krb5_ccache, krb5_principal *); - krb5_error_code(KRB5_CALLCONV *get_first) - (krb5_context, krb5_ccache, krb5_cc_cursor *); - krb5_error_code(KRB5_CALLCONV *get_next) - (krb5_context, krb5_ccache, krb5_cc_cursor *, krb5_creds *); - krb5_error_code(KRB5_CALLCONV *end_get) - (krb5_context, krb5_ccache, krb5_cc_cursor *); - krb5_error_code(KRB5_CALLCONV *remove_cred) - (krb5_context, krb5_ccache, krb5_flags, krb5_creds *); - krb5_error_code(KRB5_CALLCONV *set_flags) - (krb5_context, krb5_ccache, krb5_flags); -} krb5_cc_ops; -# endif /* NO_DEF_KRB5_CCACHE */ - -krb5_error_code - kssl_krb5_cc_get_principal - (krb5_context context, krb5_ccache cache, krb5_principal *principal) { - if (p_krb5_cc_get_principal) - return (p_krb5_cc_get_principal(context, cache, principal)); - else - return (krb5_x((cache)->ops->get_princ, (context, cache, principal))); -} - -krb5_error_code -kssl_krb5_auth_con_setrcache(krb5_context con, krb5_auth_context acon, - krb5_rcache rcache) -{ - if (p_krb5_auth_con_setrcache) - return (p_krb5_auth_con_setrcache(con, acon, rcache)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_get_server_rcache(krb5_context con, krb5_const krb5_data *data, - krb5_rcache *rcache) -{ - if (p_krb5_get_server_rcache) - return (p_krb5_get_server_rcache(con, data, rcache)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_auth_con_getrcache(krb5_context con, krb5_auth_context acon, - krb5_rcache *prcache) -{ - if (p_krb5_auth_con_getrcache) - return (p_krb5_auth_con_getrcache(con, acon, prcache)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code kssl_krb5_kt_close(krb5_context context, krb5_keytab keytab) -{ - if (p_krb5_kt_close) - return (p_krb5_kt_close(context, keytab)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_kt_get_entry(krb5_context context, krb5_keytab keytab, - krb5_const_principal principal, krb5_kvno vno, - krb5_enctype enctype, krb5_keytab_entry *entry) -{ - if (p_krb5_kt_get_entry) - return (p_krb5_kt_get_entry - (context, keytab, principal, vno, enctype, entry)); - else - return KRB5KRB_ERR_GENERIC; -} -# endif /* OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32 */ - -/* - * memory allocation functions for non-temporary storage (e.g. stuff that - * gets saved into the kssl context) - */ -static void *kssl_calloc(size_t nmemb, size_t size) -{ - void *p; - - p = OPENSSL_malloc(nmemb * size); - if (p) { - memset(p, 0, nmemb * size); - } - return p; -} - -# define kssl_malloc(size) OPENSSL_malloc((size)) -# define kssl_realloc(ptr, size) OPENSSL_realloc(ptr, size) -# define kssl_free(ptr) OPENSSL_free((ptr)) - -char -*kstring(char *string) -{ - static char *null = "[NULL]"; - - return ((string == NULL) ? null : string); -} - -/* - * Given KRB5 enctype (basically DES or 3DES), return closest match openssl - * EVP_ encryption algorithm. Return NULL for unknown or problematic - * (krb5_dk_encrypt) enctypes. Assume ENCTYPE_*_RAW (krb5_raw_encrypt) are - * OK. - */ -const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype) -{ - switch (enctype) { - case ENCTYPE_DES_HMAC_SHA1: /* EVP_des_cbc(); */ - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - return EVP_des_cbc(); - break; - case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ - case ENCTYPE_DES3_CBC_SHA: - case ENCTYPE_DES3_CBC_RAW: - return EVP_des_ede3_cbc(); - break; - default: - return NULL; - break; - } -} - -/* - * Return true:1 if p "looks like" the start of the real authenticator - * described in kssl_skip_confound() below. The ASN.1 pattern is "62 xx 30 - * yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and xx and yy are - * possibly multi-byte length fields. - */ -static int kssl_test_confound(unsigned char *p) -{ - int len = 2; - int xx = 0, yy = 0; - - if (*p++ != 0x62) - return 0; - if (*p > 0x82) - return 0; - switch (*p) { - case 0x82: - p++; - xx = (*p++ << 8); - xx += *p++; - break; - case 0x81: - p++; - xx = *p++; - break; - case 0x80: - return 0; - default: - xx = *p++; - break; - } - if (*p++ != 0x30) - return 0; - if (*p > 0x82) - return 0; - switch (*p) { - case 0x82: - p++; - len += 2; - yy = (*p++ << 8); - yy += *p++; - break; - case 0x81: - p++; - len++; - yy = *p++; - break; - case 0x80: - return 0; - default: - yy = *p++; - break; - } - - return (xx - len == yy) ? 1 : 0; -} - -/* - * Allocate, fill, and return cksumlens array of checksum lengths. This - * array holds just the unique elements from the krb5_cksumarray[]. array[n] - * == 0 signals end of data. The krb5_cksumarray[] was an internal variable - * that has since been replaced by a more general method for storing the - * data. It should not be used. Instead we use real API calls and make a - * guess for what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2 - * it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010. - */ -static size_t *populate_cksumlens(void) -{ - int i, j, n; - static size_t *cklens = NULL; - -# ifdef KRB5_MIT_OLD11 - n = krb5_max_cksum; -# else - n = 0x0010; -# endif /* KRB5_MIT_OLD11 */ - -# ifdef KRB5CHECKAUTH - if (!cklens && !(cklens = (size_t *)calloc(sizeof(int), n + 1))) - return NULL; - - for (i = 0; i < n; i++) { - if (!valid_cksumtype(i)) - continue; /* array has holes */ - for (j = 0; j < n; j++) { - if (cklens[j] == 0) { - cklens[j] = krb5_checksum_size(NULL, i); - break; /* krb5 elem was new: add */ - } - if (cklens[j] == krb5_checksum_size(NULL, i)) { - break; /* ignore duplicate elements */ - } - } - } -# endif /* KRB5CHECKAUTH */ - - return cklens; -} - -/*- - * Return pointer to start of real authenticator within authenticator, or - * return NULL on error. - * Decrypted authenticator looks like this: - * [0 or 8 byte confounder] [4-24 byte checksum] [real authent'r] - * This hackery wouldn't be necessary if MIT KRB5 1.0.6 had the - * krb5_auth_con_getcksumtype() function advertised in its krb5.h. - */ -unsigned char *kssl_skip_confound(krb5_enctype etype, unsigned char *a) -{ - int i, conlen; - size_t cklen; - static size_t *cksumlens = NULL; - unsigned char *test_auth; - - conlen = (etype) ? 8 : 0; - - if (!cksumlens && !(cksumlens = populate_cksumlens())) - return NULL; - for (i = 0; (cklen = cksumlens[i]) != 0; i++) { - test_auth = a + conlen + cklen; - if (kssl_test_confound(test_auth)) - return test_auth; - } - - return NULL; -} - -/* - * Set kssl_err error info when reason text is a simple string kssl_err = - * struct { int reason; char text[KSSL_ERR_MAX+1]; } - */ -void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text) -{ - if (kssl_err == NULL) - return; - - kssl_err->reason = reason; - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, "%s", text); - return; -} - -/* - * Display contents of krb5_data struct, for debugging - */ -void print_krb5_data(char *label, krb5_data *kdata) -{ - int i; - - fprintf(stderr, "%s[%d] ", label, kdata->length); - for (i = 0; i < (int)kdata->length; i++) { - if (0 && isprint((int)kdata->data[i])) - fprintf(stderr, "%c ", kdata->data[i]); - else - fprintf(stderr, "%02x ", (unsigned char)kdata->data[i]); - } - fprintf(stderr, "\n"); -} - -/* - * Display contents of krb5_authdata struct, for debugging - */ -void print_krb5_authdata(char *label, krb5_authdata **adata) -{ - if (adata == NULL) { - fprintf(stderr, "%s, authdata==0\n", label); - return; - } - fprintf(stderr, "%s [%p]\n", label, (void *)adata); -# if 0 - { - int i; - fprintf(stderr, "%s[at%d:%d] ", label, adata->ad_type, adata->length); - for (i = 0; i < adata->length; i++) { - fprintf(stderr, (isprint(adata->contents[i])) ? "%c " : "%02x", - adata->contents[i]); - } - fprintf(stderr, "\n"); - } -# endif -} - -/* - * Display contents of krb5_keyblock struct, for debugging - */ -void print_krb5_keyblock(char *label, krb5_keyblock *keyblk) -{ - int i; - - if (keyblk == NULL) { - fprintf(stderr, "%s, keyblk==0\n", label); - return; - } -# ifdef KRB5_HEIMDAL - fprintf(stderr, "%s\n\t[et%d:%d]: ", label, keyblk->keytype, - keyblk->keyvalue->length); - for (i = 0; i < (int)keyblk->keyvalue->length; i++) { - fprintf(stderr, "%02x", - (unsigned char *)(keyblk->keyvalue->contents)[i]); - } - fprintf(stderr, "\n"); -# else - fprintf(stderr, "%s\n\t[et%d:%d]: ", label, keyblk->enctype, - keyblk->length); - for (i = 0; i < (int)keyblk->length; i++) { - fprintf(stderr, "%02x", keyblk->contents[i]); - } - fprintf(stderr, "\n"); -# endif -} - -/* - * Display contents of krb5_principal_data struct, for debugging - * (krb5_principal is typedef'd == krb5_principal_data *) - */ -static void print_krb5_princ(char *label, krb5_principal_data *princ) -{ - int i, ui, uj; - - fprintf(stderr, "%s principal Realm: ", label); - if (princ == NULL) - return; - for (ui = 0; ui < (int)princ->realm.length; ui++) - putchar(princ->realm.data[ui]); - fprintf(stderr, " (nametype %d) has %d strings:\n", princ->type, - princ->length); - for (i = 0; i < (int)princ->length; i++) { - fprintf(stderr, "\t%d [%d]: ", i, princ->data[i].length); - for (uj = 0; uj < (int)princ->data[i].length; uj++) { - putchar(princ->data[i].data[uj]); - } - fprintf(stderr, "\n"); - } - return; -} - -/*- Given krb5 service (typically "kssl") and hostname in kssl_ctx, - * Return encrypted Kerberos ticket for service @ hostname. - * If authenp is non-NULL, also return encrypted authenticator, - * whose data should be freed by caller. - * (Originally was: Create Kerberos AP_REQ message for SSL Client.) - * - * 19990628 VRS Started; Returns Kerberos AP_REQ message. - * 20010409 VRS Modified for RFC2712; Returns enc tkt. - * 20010606 VRS May also return optional authenticator. - */ -krb5_error_code kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, - /* - * OUT - */ krb5_data **enc_ticketp, - /* - * UPDATE - */ krb5_data *authenp, - /* - * OUT - */ KSSL_ERR *kssl_err) -{ - krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; - krb5_context krb5context = NULL; - krb5_auth_context krb5auth_context = NULL; - krb5_ccache krb5ccdef = NULL; - krb5_creds krb5creds, *krb5credsp = NULL; - krb5_data krb5_app_req; - - kssl_err_set(kssl_err, 0, ""); - memset((char *)&krb5creds, 0, sizeof(krb5creds)); - - if (!kssl_ctx) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n"); - goto err; - } else if (!kssl_ctx->service_host) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "kssl_ctx service_host undefined.\n"); - goto err; - } - - if ((krb5rc = krb5_init_context(&krb5context)) != 0) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "krb5_init_context() fails: %d\n", krb5rc); - kssl_err->reason = SSL_R_KRB5_C_INIT; - goto err; - } - - if ((krb5rc = krb5_sname_to_principal(krb5context, - kssl_ctx->service_host, - (kssl_ctx->service_name) ? - kssl_ctx->service_name : KRB5SVC, - KRB5_NT_SRV_HST, - &krb5creds.server)) != 0) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "krb5_sname_to_principal() fails for %s/%s\n", - kssl_ctx->service_host, - (kssl_ctx-> - service_name) ? kssl_ctx->service_name : KRB5SVC); - kssl_err->reason = SSL_R_KRB5_C_INIT; - goto err; - } - - if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) { - kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC, - "krb5_cc_default fails.\n"); - goto err; - } - - if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, - &krb5creds.client)) != 0) { - kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC, - "krb5_cc_get_principal() fails.\n"); - goto err; - } - - if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, - &krb5creds, &krb5credsp)) != 0) { - kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED, - "krb5_get_credentials() fails.\n"); - goto err; - } - - *enc_ticketp = &krb5credsp->ticket; -# ifdef KRB5_HEIMDAL - kssl_ctx->enctype = krb5credsp->session.keytype; -# else - kssl_ctx->enctype = krb5credsp->keyblock.enctype; -# endif - - krb5rc = KRB5KRB_ERR_GENERIC; - /* caller should free data of krb5_app_req */ - /* - * 20010406 VRS deleted for real KerberosWrapper 20010605 VRS reinstated - * to offer Authenticator to KerberosWrapper - */ - krb5_app_req.length = 0; - if (authenp) { - krb5_data krb5in_data; - const unsigned char *p; - long arlen; - KRB5_APREQBODY *ap_req; - - authenp->length = 0; - krb5in_data.data = NULL; - krb5in_data.length = 0; - if ((krb5rc = krb5_mk_req_extended(krb5context, - &krb5auth_context, 0, &krb5in_data, - krb5credsp, &krb5_app_req)) != 0) { - kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ, - "krb5_mk_req_extended() fails.\n"); - goto err; - } - - arlen = krb5_app_req.length; - p = (unsigned char *)krb5_app_req.data; - ap_req = (KRB5_APREQBODY *)d2i_KRB5_APREQ(NULL, &p, arlen); - if (ap_req) { - authenp->length = i2d_KRB5_ENCDATA(ap_req->authenticator, NULL); - if (authenp->length && (authenp->data = malloc(authenp->length))) { - unsigned char *adp = (unsigned char *)authenp->data; - authenp->length = - i2d_KRB5_ENCDATA(ap_req->authenticator, &adp); - } - } - - if (ap_req) - KRB5_APREQ_free((KRB5_APREQ *) ap_req); - if (krb5_app_req.length) - kssl_krb5_free_data_contents(krb5context, &krb5_app_req); - } -# ifdef KRB5_HEIMDAL - if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->session)) { - kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, - "kssl_ctx_setkey() fails.\n"); - } -# else - if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock)) { - kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, - "kssl_ctx_setkey() fails.\n"); - } -# endif - else - krb5rc = 0; - - err: -# ifdef KSSL_DEBUG - kssl_ctx_show(kssl_ctx); -# endif /* KSSL_DEBUG */ - - if (krb5creds.client) - krb5_free_principal(krb5context, krb5creds.client); - if (krb5creds.server) - krb5_free_principal(krb5context, krb5creds.server); - if (krb5auth_context) - krb5_auth_con_free(krb5context, krb5auth_context); - if (krb5context) - krb5_free_context(krb5context); - return (krb5rc); -} - -/*- - * Given d2i_-decoded asn1ticket, allocate and return a new krb5_ticket. - * Return Kerberos error code and kssl_err struct on error. - * Allocates krb5_ticket and krb5_principal; caller should free these. - * - * 20010410 VRS Implemented krb5_decode_ticket() as - * old_krb5_decode_ticket(). Missing from MIT1.0.6. - * 20010615 VRS Re-cast as openssl/asn1 d2i_*() functions. - * Re-used some of the old krb5_decode_ticket() - * code here. This tkt should alloc/free just - * like the real thing. - */ -static krb5_error_code kssl_TKT2tkt( /* IN */ krb5_context krb5context, - /* - * IN - */ KRB5_TKTBODY *asn1ticket, - /* - * OUT - */ krb5_ticket **krb5ticket, - /* - * OUT - */ KSSL_ERR *kssl_err) -{ - krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; - krb5_ticket *new5ticket = NULL; - ASN1_GENERALSTRING *gstr_svc, *gstr_host; - - *krb5ticket = NULL; - - if (asn1ticket == NULL || asn1ticket->realm == NULL || - asn1ticket->sname == NULL || - sk_ASN1_GENERALSTRING_num(asn1ticket->sname->namestring) < 2) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "Null field in asn1ticket.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - return KRB5KRB_ERR_GENERIC; - } - - if ((new5ticket = (krb5_ticket *)calloc(1, sizeof(krb5_ticket))) == NULL) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "Unable to allocate new krb5_ticket.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - return ENOMEM; /* or KRB5KRB_ERR_GENERIC; */ - } - - gstr_svc = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 0); - gstr_host = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 1); - - if ((krb5rc = kssl_build_principal_2(krb5context, - &new5ticket->server, - asn1ticket->realm->length, - (char *)asn1ticket->realm->data, - gstr_svc->length, - (char *)gstr_svc->data, - gstr_host->length, - (char *)gstr_host->data)) != 0) { - free(new5ticket); - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "Error building ticket server principal.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - return krb5rc; /* or KRB5KRB_ERR_GENERIC; */ - } - - krb5_princ_type(krb5context, new5ticket->server) = - asn1ticket->sname->nametype->data[0]; - new5ticket->enc_part.enctype = asn1ticket->encdata->etype->data[0]; - new5ticket->enc_part.kvno = asn1ticket->encdata->kvno->data[0]; - new5ticket->enc_part.ciphertext.length = - asn1ticket->encdata->cipher->length; - if ((new5ticket->enc_part.ciphertext.data = - calloc(1, asn1ticket->encdata->cipher->length)) == NULL) { - free(new5ticket); - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "Error allocating cipher in krb5ticket.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - return KRB5KRB_ERR_GENERIC; - } else { - memcpy(new5ticket->enc_part.ciphertext.data, - asn1ticket->encdata->cipher->data, - asn1ticket->encdata->cipher->length); - } - - *krb5ticket = new5ticket; - return 0; -} - -/*- - * Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"), - * and krb5 AP_REQ message & message length, - * Return Kerberos session key and client principle - * to SSL Server in KSSL_CTX *kssl_ctx. - * - * 19990702 VRS Started. - */ -krb5_error_code kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, - /* - * IN - */ krb5_data *indata, - /* - * OUT - */ krb5_ticket_times *ttimes, - /* - * OUT - */ KSSL_ERR *kssl_err) -{ - krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; - static krb5_context krb5context = NULL; - static krb5_auth_context krb5auth_context = NULL; - krb5_ticket *krb5ticket = NULL; - KRB5_TKTBODY *asn1ticket = NULL; - const unsigned char *p; - krb5_keytab krb5keytab = NULL; - krb5_keytab_entry kt_entry; - krb5_principal krb5server; - krb5_rcache rcache = NULL; - - kssl_err_set(kssl_err, 0, ""); - - if (!kssl_ctx) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n"); - goto err; - } -# ifdef KSSL_DEBUG - fprintf(stderr, "in kssl_sget_tkt(%s)\n", - kstring(kssl_ctx->service_name)); -# endif /* KSSL_DEBUG */ - - if (!krb5context && (krb5rc = krb5_init_context(&krb5context))) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_init_context() fails.\n"); - goto err; - } - if (krb5auth_context && - (krb5rc = krb5_auth_con_free(krb5context, krb5auth_context))) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_auth_con_free() fails.\n"); - goto err; - } else - krb5auth_context = NULL; - if (!krb5auth_context && - (krb5rc = krb5_auth_con_init(krb5context, &krb5auth_context))) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_auth_con_init() fails.\n"); - goto err; - } - - if ((krb5rc = krb5_auth_con_getrcache(krb5context, krb5auth_context, - &rcache))) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_auth_con_getrcache() fails.\n"); - goto err; - } - - if ((krb5rc = krb5_sname_to_principal(krb5context, NULL, - (kssl_ctx->service_name) ? - kssl_ctx->service_name : KRB5SVC, - KRB5_NT_SRV_HST, - &krb5server)) != 0) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_sname_to_principal() fails.\n"); - goto err; - } - - if (rcache == NULL) { - if ((krb5rc = krb5_get_server_rcache(krb5context, - krb5_princ_component(krb5context, - krb5server, - 0), - &rcache))) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_get_server_rcache() fails.\n"); - goto err; - } - } - - if ((krb5rc = - krb5_auth_con_setrcache(krb5context, krb5auth_context, rcache))) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_auth_con_setrcache() fails.\n"); - goto err; - } - - /* - * kssl_ctx->keytab_file == NULL ==> use Kerberos default - */ - if (kssl_ctx->keytab_file) { - krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, - &krb5keytab); - if (krb5rc) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_kt_resolve() fails.\n"); - goto err; - } - } else { - krb5rc = krb5_kt_default(krb5context, &krb5keytab); - if (krb5rc) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_kt_default() fails.\n"); - goto err; - } - } - - /*- Actual Kerberos5 krb5_recvauth() has initial conversation here - * o check KRB5_SENDAUTH_BADAUTHVERS - * unless KRB5_RECVAUTH_SKIP_VERSION - * o check KRB5_SENDAUTH_BADAPPLVERS - * o send "0" msg if all OK - */ - - /*- - * 20010411 was using AP_REQ instead of true KerberosWrapper - * - * if ((krb5rc = krb5_rd_req(krb5context, &krb5auth_context, - * &krb5in_data, krb5server, krb5keytab, - * &ap_option, &krb5ticket)) != 0) { Error } - */ - - p = (unsigned char *)indata->data; - if ((asn1ticket = (KRB5_TKTBODY *)d2i_KRB5_TICKET(NULL, &p, - (long)indata->length)) - == NULL) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "d2i_KRB5_TICKET() ASN.1 decode failure.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - goto err; - } - - /* - * Was: krb5rc = krb5_decode_ticket(krb5in_data,&krb5ticket)) != 0) - */ - if ((krb5rc = kssl_TKT2tkt(krb5context, asn1ticket, &krb5ticket, - kssl_err)) != 0) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "Error converting ASN.1 ticket to krb5_ticket.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - goto err; - } - - if (!krb5_principal_compare(krb5context, krb5server, krb5ticket->server)) { - krb5rc = KRB5_PRINC_NOMATCH; - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "server principal != ticket principal\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - goto err; - } - if ((krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, - krb5ticket->server, - krb5ticket->enc_part.kvno, - krb5ticket->enc_part.enctype, - &kt_entry)) != 0) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "krb5_kt_get_entry() fails with %x.\n", krb5rc); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - goto err; - } - if ((krb5rc = krb5_decrypt_tkt_part(krb5context, &kt_entry.key, - krb5ticket)) != 0) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "krb5_decrypt_tkt_part() failed.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - goto err; - } else { - krb5_kt_free_entry(krb5context, &kt_entry); -# ifdef KSSL_DEBUG - { - int i; - krb5_address **paddr = krb5ticket->enc_part2->caddrs; - fprintf(stderr, "Decrypted ticket fields:\n"); - fprintf(stderr, "\tflags: %X, transit-type: %X", - krb5ticket->enc_part2->flags, - krb5ticket->enc_part2->transited.tr_type); - print_krb5_data("\ttransit-data: ", - &(krb5ticket->enc_part2->transited.tr_contents)); - fprintf(stderr, "\tcaddrs: %p, authdata: %p\n", - krb5ticket->enc_part2->caddrs, - krb5ticket->enc_part2->authorization_data); - if (paddr) { - fprintf(stderr, "\tcaddrs:\n"); - for (i = 0; paddr[i] != NULL; i++) { - krb5_data d; - d.length = paddr[i]->length; - d.data = paddr[i]->contents; - print_krb5_data("\t\tIP: ", &d); - } - } - fprintf(stderr, "\tstart/auth/end times: %d / %d / %d\n", - krb5ticket->enc_part2->times.starttime, - krb5ticket->enc_part2->times.authtime, - krb5ticket->enc_part2->times.endtime); - } -# endif /* KSSL_DEBUG */ - } - - krb5rc = KRB5_NO_TKT_SUPPLIED; - if (!krb5ticket || !krb5ticket->enc_part2 || - !krb5ticket->enc_part2->client || - !krb5ticket->enc_part2->client->data || - !krb5ticket->enc_part2->session) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, - "bad ticket from krb5_rd_req.\n"); - } else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT, - &krb5ticket->enc_part2->client->realm, - krb5ticket->enc_part2->client->data, - krb5ticket->enc_part2->client->length)) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, - "kssl_ctx_setprinc() fails.\n"); - } else if (kssl_ctx_setkey(kssl_ctx, krb5ticket->enc_part2->session)) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, - "kssl_ctx_setkey() fails.\n"); - } else if (krb5ticket->enc_part2->flags & TKT_FLG_INVALID) { - krb5rc = KRB5KRB_AP_ERR_TKT_INVALID; - kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, - "invalid ticket from krb5_rd_req.\n"); - } else - krb5rc = 0; - - kssl_ctx->enctype = krb5ticket->enc_part.enctype; - ttimes->authtime = krb5ticket->enc_part2->times.authtime; - ttimes->starttime = krb5ticket->enc_part2->times.starttime; - ttimes->endtime = krb5ticket->enc_part2->times.endtime; - ttimes->renew_till = krb5ticket->enc_part2->times.renew_till; - - err: -# ifdef KSSL_DEBUG - kssl_ctx_show(kssl_ctx); -# endif /* KSSL_DEBUG */ - - if (asn1ticket) - KRB5_TICKET_free((KRB5_TICKET *) asn1ticket); - if (krb5keytab) - krb5_kt_close(krb5context, krb5keytab); - if (krb5ticket) - krb5_free_ticket(krb5context, krb5ticket); - if (krb5server) - krb5_free_principal(krb5context, krb5server); - return (krb5rc); -} - -/* - * Allocate & return a new kssl_ctx struct. - */ -KSSL_CTX *kssl_ctx_new(void) -{ - return ((KSSL_CTX *)kssl_calloc(1, sizeof(KSSL_CTX))); -} - -/* - * Frees a kssl_ctx struct and any allocated memory it holds. Returns NULL. - */ -KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx) -{ - if (kssl_ctx == NULL) - return kssl_ctx; - - if (kssl_ctx->key) - OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); - if (kssl_ctx->key) - kssl_free(kssl_ctx->key); - if (kssl_ctx->client_princ) - kssl_free(kssl_ctx->client_princ); - if (kssl_ctx->service_host) - kssl_free(kssl_ctx->service_host); - if (kssl_ctx->service_name) - kssl_free(kssl_ctx->service_name); - if (kssl_ctx->keytab_file) - kssl_free(kssl_ctx->keytab_file); - - kssl_free(kssl_ctx); - return (KSSL_CTX *)NULL; -} - -/* - * Given an array of (krb5_data *) entity (and optional realm), set the plain - * (char *) client_princ or service_host member of the kssl_ctx struct. - */ -krb5_error_code -kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, - krb5_data *realm, krb5_data *entity, int nentities) -{ - char **princ; - int length; - int i; - - if (kssl_ctx == NULL || entity == NULL) - return KSSL_CTX_ERR; - - switch (which) { - case KSSL_CLIENT: - princ = &kssl_ctx->client_princ; - break; - case KSSL_SERVER: - princ = &kssl_ctx->service_host; - break; - default: - return KSSL_CTX_ERR; - break; - } - if (*princ) - kssl_free(*princ); - - /* Add up all the entity->lengths */ - length = 0; - for (i = 0; i < nentities; i++) { - length += entity[i].length; - } - /* Add in space for the '/' character(s) (if any) */ - length += nentities - 1; - /* Space for the ('@'+realm+NULL | NULL) */ - length += ((realm) ? realm->length + 2 : 1); - - if ((*princ = kssl_calloc(1, length)) == NULL) - return KSSL_CTX_ERR; - else { - for (i = 0; i < nentities; i++) { - strncat(*princ, entity[i].data, entity[i].length); - if (i < nentities - 1) { - strcat(*princ, "/"); - } - } - if (realm) { - strcat(*princ, "@"); - (void)strncat(*princ, realm->data, realm->length); - } - } - - return KSSL_CTX_OK; -} - -/*- Set one of the plain (char *) string members of the kssl_ctx struct. - * Default values should be: - * which == KSSL_SERVICE => "khost" (KRB5SVC) - * which == KSSL_KEYTAB => "/etc/krb5.keytab" (KRB5KEYTAB) - */ -krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) -{ - char **string; - - if (!kssl_ctx) - return KSSL_CTX_ERR; - - switch (which) { - case KSSL_SERVICE: - string = &kssl_ctx->service_name; - break; - case KSSL_SERVER: - string = &kssl_ctx->service_host; - break; - case KSSL_CLIENT: - string = &kssl_ctx->client_princ; - break; - case KSSL_KEYTAB: - string = &kssl_ctx->keytab_file; - break; - default: - return KSSL_CTX_ERR; - break; - } - if (*string) - kssl_free(*string); - - if (!text) { - *string = '\0'; - return KSSL_CTX_OK; - } - - if ((*string = kssl_calloc(1, strlen(text) + 1)) == NULL) - return KSSL_CTX_ERR; - else - strcpy(*string, text); - - return KSSL_CTX_OK; -} - -/* - * Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx - * struct. Clear kssl_ctx->key if Kerberos session key is NULL. - */ -krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session) -{ - int length; - krb5_enctype enctype; - krb5_octet FAR *contents = NULL; - - if (!kssl_ctx) - return KSSL_CTX_ERR; - - if (kssl_ctx->key) { - OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); - kssl_free(kssl_ctx->key); - } - - if (session) { - -# ifdef KRB5_HEIMDAL - length = session->keyvalue->length; - enctype = session->keytype; - contents = session->keyvalue->contents; -# else - length = session->length; - enctype = session->enctype; - contents = session->contents; -# endif - kssl_ctx->enctype = enctype; - kssl_ctx->length = length; - } else { - kssl_ctx->enctype = ENCTYPE_UNKNOWN; - kssl_ctx->length = 0; - return KSSL_CTX_OK; - } - - if ((kssl_ctx->key = - (krb5_octet FAR *)kssl_calloc(1, kssl_ctx->length)) == NULL) { - kssl_ctx->length = 0; - return KSSL_CTX_ERR; - } else - memcpy(kssl_ctx->key, contents, length); - - return KSSL_CTX_OK; -} - -/* - * Display contents of kssl_ctx struct - */ -void kssl_ctx_show(KSSL_CTX *kssl_ctx) -{ - int i; - - printf("kssl_ctx: "); - if (kssl_ctx == NULL) { - printf("NULL\n"); - return; - } else - printf("%p\n", (void *)kssl_ctx); - - printf("\tservice:\t%s\n", - (kssl_ctx->service_name) ? kssl_ctx->service_name : "NULL"); - printf("\tclient:\t%s\n", - (kssl_ctx->client_princ) ? kssl_ctx->client_princ : "NULL"); - printf("\tserver:\t%s\n", - (kssl_ctx->service_host) ? kssl_ctx->service_host : "NULL"); - printf("\tkeytab:\t%s\n", - (kssl_ctx->keytab_file) ? kssl_ctx->keytab_file : "NULL"); - printf("\tkey [%d:%d]:\t", kssl_ctx->enctype, kssl_ctx->length); - - for (i = 0; i < kssl_ctx->length && kssl_ctx->key; i++) { - printf("%02x", kssl_ctx->key[i]); - } - printf("\n"); - return; -} - -int kssl_keytab_is_available(KSSL_CTX *kssl_ctx) -{ - krb5_context krb5context = NULL; - krb5_keytab krb5keytab = NULL; - krb5_keytab_entry entry; - krb5_principal princ = NULL; - krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; - int rc = 0; - - if ((krb5rc = krb5_init_context(&krb5context))) - return (0); - - /* - * kssl_ctx->keytab_file == NULL ==> use Kerberos default - */ - if (kssl_ctx->keytab_file) { - krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, - &krb5keytab); - if (krb5rc) - goto exit; - } else { - krb5rc = krb5_kt_default(krb5context, &krb5keytab); - if (krb5rc) - goto exit; - } - - /* the host key we are looking for */ - krb5rc = krb5_sname_to_principal(krb5context, NULL, - kssl_ctx-> - service_name ? kssl_ctx->service_name : - KRB5SVC, KRB5_NT_SRV_HST, &princ); - - if (krb5rc) - goto exit; - - krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, princ, - /* IGNORE_VNO */ - 0, - /* IGNORE_ENCTYPE */ - 0, &entry); - if (krb5rc == KRB5_KT_NOTFOUND) { - rc = 1; - goto exit; - } else if (krb5rc) - goto exit; - - krb5_kt_free_entry(krb5context, &entry); - rc = 1; - - exit: - if (krb5keytab) - krb5_kt_close(krb5context, krb5keytab); - if (princ) - krb5_free_principal(krb5context, princ); - if (krb5context) - krb5_free_context(krb5context); - return (rc); -} - -int kssl_tgt_is_available(KSSL_CTX *kssl_ctx) -{ - krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; - krb5_context krb5context = NULL; - krb5_ccache krb5ccdef = NULL; - krb5_creds krb5creds, *krb5credsp = NULL; - int rc = 0; - - memset((char *)&krb5creds, 0, sizeof(krb5creds)); - - if (!kssl_ctx) - return (0); - - if (!kssl_ctx->service_host) - return (0); - - if ((krb5rc = krb5_init_context(&krb5context)) != 0) - goto err; - - if ((krb5rc = krb5_sname_to_principal(krb5context, - kssl_ctx->service_host, - (kssl_ctx->service_name) ? - kssl_ctx->service_name : KRB5SVC, - KRB5_NT_SRV_HST, - &krb5creds.server)) != 0) - goto err; - - if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) - goto err; - - if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, - &krb5creds.client)) != 0) - goto err; - - if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, - &krb5creds, &krb5credsp)) != 0) - goto err; - - rc = 1; - - err: -# ifdef KSSL_DEBUG - kssl_ctx_show(kssl_ctx); -# endif /* KSSL_DEBUG */ - - if (krb5creds.client) - krb5_free_principal(krb5context, krb5creds.client); - if (krb5creds.server) - krb5_free_principal(krb5context, krb5creds.server); - if (krb5context) - krb5_free_context(krb5context); - return (rc); -} - -# if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_WIN32) -void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data) -{ -# ifdef KRB5_HEIMDAL - data->length = 0; - if (data->data) - free(data->data); -# elif defined(KRB5_MIT_OLD11) - if (data->data) { - krb5_xfree(data->data); - data->data = 0; - } -# else - krb5_free_data_contents(NULL, data); -# endif -} -# endif -/* !OPENSSL_SYS_WINDOWS && !OPENSSL_SYS_WIN32 */ - -/* - * Given pointers to KerberosTime and struct tm structs, convert the - * KerberosTime string to struct tm. Note that KerberosTime is a - * ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional seconds - * as defined in RFC 1510. Return pointer to the (partially) filled in - * struct tm on success, return NULL on failure. - */ -static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) -{ - char c, *p; - - if (!k_tm) - return NULL; - if (gtime == NULL || gtime->length < 14) - return NULL; - if (gtime->data == NULL) - return NULL; - - p = (char *)>ime->data[14]; - - c = *p; - *p = '\0'; - p -= 2; - k_tm->tm_sec = atoi(p); - *(p + 2) = c; - c = *p; - *p = '\0'; - p -= 2; - k_tm->tm_min = atoi(p); - *(p + 2) = c; - c = *p; - *p = '\0'; - p -= 2; - k_tm->tm_hour = atoi(p); - *(p + 2) = c; - c = *p; - *p = '\0'; - p -= 2; - k_tm->tm_mday = atoi(p); - *(p + 2) = c; - c = *p; - *p = '\0'; - p -= 2; - k_tm->tm_mon = atoi(p) - 1; - *(p + 2) = c; - c = *p; - *p = '\0'; - p -= 4; - k_tm->tm_year = atoi(p) - 1900; - *(p + 4) = c; - - return k_tm; -} - -/* - * Helper function for kssl_validate_times(). We need context->clockskew, - * but krb5_context is an opaque struct. So we try to sneek the clockskew - * out through the replay cache. If that fails just return a likely default - * (300 seconds). - */ -static krb5_deltat get_rc_clockskew(krb5_context context) -{ - krb5_rcache rc; - krb5_deltat clockskew; - - if (krb5_rc_default(context, &rc)) - return KSSL_CLOCKSKEW; - if (krb5_rc_initialize(context, rc, 0)) - return KSSL_CLOCKSKEW; - if (krb5_rc_get_lifespan(context, rc, &clockskew)) { - clockskew = KSSL_CLOCKSKEW; - } - (void)krb5_rc_destroy(context, rc); - return clockskew; -} - -/* - * kssl_validate_times() combines (and more importantly exposes) the MIT KRB5 - * internal function krb5_validate_times() and the in_clock_skew() macro. - * The authenticator client time is checked to be within clockskew secs of - * the current time and the current time is checked to be within the ticket - * start and expire times. Either check may be omitted by supplying a NULL - * value. Returns 0 for valid times, SSL_R_KRB5* error codes otherwise. See - * Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c 20010420 VRS - */ -krb5_error_code kssl_validate_times(krb5_timestamp atime, - krb5_ticket_times *ttimes) -{ - krb5_deltat skew; - krb5_timestamp start, now; - krb5_error_code rc; - krb5_context context; - - if ((rc = krb5_init_context(&context))) - return SSL_R_KRB5_S_BAD_TICKET; - skew = get_rc_clockskew(context); - if ((rc = krb5_timeofday(context, &now))) - return SSL_R_KRB5_S_BAD_TICKET; - krb5_free_context(context); - - if (atime && labs(atime - now) >= skew) - return SSL_R_KRB5_S_TKT_SKEW; - - if (!ttimes) - return 0; - - start = (ttimes->starttime != 0) ? ttimes->starttime : ttimes->authtime; - if (start - now > skew) - return SSL_R_KRB5_S_TKT_NYV; - if ((now - ttimes->endtime) > skew) - return SSL_R_KRB5_S_TKT_EXPIRED; - -# ifdef KSSL_DEBUG - fprintf(stderr, "kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n", - start, atime, now, skew, ttimes->endtime); -# endif /* KSSL_DEBUG */ - - return 0; -} - -/* - * Decode and decrypt given DER-encoded authenticator, then pass - * authenticator ctime back in *atimep (or 0 if time unavailable). Returns - * krb5_error_code and kssl_err on error. A NULL authenticator - * (authentp->length == 0) is not considered an error. Note that - * kssl_check_authent() makes use of the KRB5 session key; you must call - * kssl_sget_tkt() to get the key before calling this routine. - */ -krb5_error_code kssl_check_authent( - /* - * IN - */ KSSL_CTX *kssl_ctx, - /* - * IN - */ krb5_data *authentp, - /* - * OUT - */ krb5_timestamp *atimep, - /* - * OUT - */ KSSL_ERR *kssl_err) -{ - krb5_error_code krb5rc = 0; - KRB5_ENCDATA *dec_authent = NULL; - KRB5_AUTHENTBODY *auth = NULL; - krb5_enctype enctype; - EVP_CIPHER_CTX ciph_ctx; - const EVP_CIPHER *enc = NULL; - unsigned char iv[EVP_MAX_IV_LENGTH]; - const unsigned char *p; - unsigned char *unenc_authent; - int outl, unencbufsize; - struct tm tm_time, *tm_l, *tm_g; - time_t now, tl, tg, tr, tz_offset; - - EVP_CIPHER_CTX_init(&ciph_ctx); - *atimep = 0; - kssl_err_set(kssl_err, 0, ""); - -# ifndef KRB5CHECKAUTH - authentp = NULL; -# else -# if KRB5CHECKAUTH == 0 - authentp = NULL; -# endif -# endif /* KRB5CHECKAUTH */ - - if (authentp == NULL || authentp->length == 0) - return 0; - -# ifdef KSSL_DEBUG - { - unsigned int ui; - fprintf(stderr, "kssl_check_authent: authenticator[%d]:\n", - authentp->length); - p = authentp->data; - for (ui = 0; ui < authentp->length; ui++) - fprintf(stderr, "%02x ", p[ui]); - fprintf(stderr, "\n"); - } -# endif /* KSSL_DEBUG */ - - unencbufsize = 2 * authentp->length; - if ((unenc_authent = calloc(1, unencbufsize)) == NULL) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "Unable to allocate authenticator buffer.\n"); - krb5rc = KRB5KRB_ERR_GENERIC; - goto err; - } - - p = (unsigned char *)authentp->data; - if ((dec_authent = d2i_KRB5_ENCDATA(NULL, &p, - (long)authentp->length)) == NULL) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "Error decoding authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - - enctype = dec_authent->etype->data[0]; /* should = kssl_ctx->enctype */ -# if !defined(KRB5_MIT_OLD11) - switch (enctype) { - case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ - case ENCTYPE_DES3_CBC_SHA: - case ENCTYPE_DES3_CBC_RAW: - krb5rc = 0; /* Skip, can't handle derived keys */ - goto err; - } -# endif - enc = kssl_map_enc(enctype); - memset(iv, 0, sizeof iv); /* per RFC 1510 */ - - if (enc == NULL) { - /* - * Disable kssl_check_authent for ENCTYPE_DES3_CBC_SHA1. This - * enctype indicates the authenticator was encrypted using key-usage - * derived keys which openssl cannot decrypt. - */ - goto err; - } - - if (!EVP_CipherInit(&ciph_ctx, enc, kssl_ctx->key, iv, 0)) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "EVP_CipherInit error decrypting authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - outl = dec_authent->cipher->length; - if (!EVP_Cipher - (&ciph_ctx, unenc_authent, dec_authent->cipher->data, outl)) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "EVP_Cipher error decrypting authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - EVP_CIPHER_CTX_cleanup(&ciph_ctx); - -# ifdef KSSL_DEBUG - { - int padl; - fprintf(stderr, "kssl_check_authent: decrypted authenticator[%d] =\n", - outl); - for (padl = 0; padl < outl; padl++) - fprintf(stderr, "%02x ", unenc_authent[padl]); - fprintf(stderr, "\n"); - } -# endif /* KSSL_DEBUG */ - - if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "confounded by authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - outl -= p - unenc_authent; - - if ((auth = (KRB5_AUTHENTBODY *)d2i_KRB5_AUTHENT(NULL, &p, - (long)outl)) == NULL) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "Error decoding authenticator body.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - - memset(&tm_time, 0, sizeof(struct tm)); - if (k_gmtime(auth->ctime, &tm_time) && - ((tr = mktime(&tm_time)) != (time_t)(-1))) { - now = time(&now); - tm_l = localtime(&now); - tl = mktime(tm_l); - tm_g = gmtime(&now); - tg = mktime(tm_g); - tz_offset = tg - tl; - - *atimep = (krb5_timestamp)(tr - tz_offset); - } -# ifdef KSSL_DEBUG - fprintf(stderr, "kssl_check_authent: returns %d for client time ", - *atimep); - if (auth && auth->ctime && auth->ctime->length && auth->ctime->data) - fprintf(stderr, "%.*s\n", auth->ctime->length, auth->ctime->data); - else - fprintf(stderr, "NULL\n"); -# endif /* KSSL_DEBUG */ - - err: - if (auth) - KRB5_AUTHENT_free((KRB5_AUTHENT *) auth); - if (dec_authent) - KRB5_ENCDATA_free(dec_authent); - if (unenc_authent) - free(unenc_authent); - EVP_CIPHER_CTX_cleanup(&ciph_ctx); - return krb5rc; -} - -/* - * Replaces krb5_build_principal_ext(), with varargs length == 2 (svc, host), - * because I don't know how to stub varargs. Returns krb5_error_code == - * ENOMEM on alloc error, otherwise passes back newly constructed principal, - * which should be freed by caller. - */ -krb5_error_code kssl_build_principal_2( - /* - * UPDATE - */ krb5_context context, - /* - * OUT - */ krb5_principal *princ, - /* - * IN - */ int rlen, const char *realm, - /* - * IN - */ int slen, const char *svc, - /* - * IN - */ int hlen, const char *host) -{ - krb5_data *p_data = NULL; - krb5_principal new_p = NULL; - char *new_r = NULL; - - if ((p_data = (krb5_data *)calloc(2, sizeof(krb5_data))) == NULL || - (new_p = (krb5_principal)calloc(1, sizeof(krb5_principal_data))) - == NULL) - goto err; - new_p->length = 2; - new_p->data = p_data; - - if ((new_r = calloc(1, rlen + 1)) == NULL) - goto err; - memcpy(new_r, realm, rlen); - krb5_princ_set_realm_length(context, new_p, rlen); - krb5_princ_set_realm_data(context, new_p, new_r); - - if ((new_p->data[0].data = calloc(1, slen + 1)) == NULL) - goto err; - memcpy(new_p->data[0].data, svc, slen); - new_p->data[0].length = slen; - - if ((new_p->data[1].data = calloc(1, hlen + 1)) == NULL) - goto err; - memcpy(new_p->data[1].data, host, hlen); - new_p->data[1].length = hlen; - - krb5_princ_type(context, new_p) = KRB5_NT_UNKNOWN; - *princ = new_p; - return 0; - - err: - if (new_p && new_p[0].data) - free(new_p[0].data); - if (new_p && new_p[1].data) - free(new_p[1].data); - if (new_p) - free(new_p); - if (new_r) - free(new_r); - return ENOMEM; -} - -void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx) -{ - s->kssl_ctx = kctx; -} - -KSSL_CTX *SSL_get0_kssl_ctx(SSL *s) -{ - return s->kssl_ctx; -} - -char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx) -{ - if (kctx) - return kctx->client_princ; - return NULL; -} - -#else /* !OPENSSL_NO_KRB5 */ - -# if defined(PEDANTIC) || defined(OPENSSL_SYS_VMS) -static void *dummy = &dummy; -# endif - -#endif /* !OPENSSL_NO_KRB5 */ diff --git a/thirdparty/openssl/ssl/kssl_lcl.h b/thirdparty/openssl/ssl/kssl_lcl.h deleted file mode 100644 index 8e6a6d69e9..0000000000 --- a/thirdparty/openssl/ssl/kssl_lcl.h +++ /dev/null @@ -1,88 +0,0 @@ -/* ssl/kssl.h */ -/* - * Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project - * 2000. project 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 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 KSSL_LCL_H -# define KSSL_LCL_H - -# include <openssl/kssl.h> - -# ifndef OPENSSL_NO_KRB5 - -#ifdef __cplusplus -extern "C" { -#endif - -/* Private (internal to OpenSSL) */ -void print_krb5_data(char *label, krb5_data *kdata); -void print_krb5_authdata(char *label, krb5_authdata **adata); -void print_krb5_keyblock(char *label, krb5_keyblock *keyblk); - -char *kstring(char *string); -char *knumber(int len, krb5_octet *contents); - -const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype); - -int kssl_keytab_is_available(KSSL_CTX *kssl_ctx); -int kssl_tgt_is_available(KSSL_CTX *kssl_ctx); - -#ifdef __cplusplus -} -#endif -# endif /* OPENSSL_NO_KRB5 */ -#endif /* KSSL_LCL_H */ diff --git a/thirdparty/openssl/ssl/s23_clnt.c b/thirdparty/openssl/ssl/s23_clnt.c deleted file mode 100644 index b80d1fd8ce..0000000000 --- a/thirdparty/openssl/ssl/s23_clnt.c +++ /dev/null @@ -1,805 +0,0 @@ -/* ssl/s23_clnt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 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 - * openssl-core@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). - * - */ - -#include <stdio.h> -#include "ssl_locl.h" -#include <openssl/buffer.h> -#include <openssl/rand.h> -#include <openssl/objects.h> -#include <openssl/evp.h> - -static const SSL_METHOD *ssl23_get_client_method(int ver); -static int ssl23_client_hello(SSL *s); -static int ssl23_get_server_hello(SSL *s); -static const SSL_METHOD *ssl23_get_client_method(int ver) -{ -#ifndef OPENSSL_NO_SSL2 - if (ver == SSL2_VERSION) - return (SSLv2_client_method()); -#endif -#ifndef OPENSSL_NO_SSL3 - if (ver == SSL3_VERSION) - return (SSLv3_client_method()); -#endif - if (ver == TLS1_VERSION) - return (TLSv1_client_method()); - else if (ver == TLS1_1_VERSION) - return (TLSv1_1_client_method()); - else if (ver == TLS1_2_VERSION) - return (TLSv1_2_client_method()); - else - return (NULL); -} - -IMPLEMENT_ssl23_meth_func(SSLv23_client_method, - ssl_undefined_function, - ssl23_connect, ssl23_get_client_method) - -int ssl23_connect(SSL *s) -{ - BUF_MEM *buf = NULL; - unsigned long Time = (unsigned long)time(NULL); - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int ret = -1; - int new_state, state; - - RAND_add(&Time, sizeof(Time), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_BEFORE: - case SSL_ST_CONNECT: - case SSL_ST_BEFORE | SSL_ST_CONNECT: - case SSL_ST_OK | SSL_ST_CONNECT: - - if (s->session != NULL) { - SSLerr(SSL_F_SSL23_CONNECT, - SSL_R_SSL23_DOING_SESSION_ID_REUSE); - ret = -1; - goto end; - } - s->server = 0; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - /* s->version=TLS1_VERSION; */ - s->type = SSL_ST_CONNECT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - goto end; - } - if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - ret = -1; - goto end; - } - s->init_buf = buf; - buf = NULL; - } - - if (!ssl3_setup_buffers(s)) { - ret = -1; - goto end; - } - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - goto end; - } - - s->state = SSL23_ST_CW_CLNT_HELLO_A; - s->ctx->stats.sess_connect++; - s->init_num = 0; - break; - - case SSL23_ST_CW_CLNT_HELLO_A: - case SSL23_ST_CW_CLNT_HELLO_B: - - s->shutdown = 0; - ret = ssl23_client_hello(s); - if (ret <= 0) - goto end; - s->state = SSL23_ST_CR_SRVR_HELLO_A; - s->init_num = 0; - - break; - - case SSL23_ST_CR_SRVR_HELLO_A: - case SSL23_ST_CR_SRVR_HELLO_B: - ret = ssl23_get_server_hello(s); - if (ret >= 0) - cb = NULL; - goto end; - /* break; */ - - default: - SSLerr(SSL_F_SSL23_CONNECT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* break; */ - } - - if (s->debug) { - (void)BIO_flush(s->wbio); - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_CONNECT_LOOP, 1); - s->state = new_state; - } - } - end: - s->in_handshake--; - if (buf != NULL) - BUF_MEM_free(buf); - if (cb != NULL) - cb(s, SSL_CB_CONNECT_EXIT, ret); - return (ret); -} - -static int ssl23_no_ssl2_ciphers(SSL *s) -{ - SSL_CIPHER *cipher; - STACK_OF(SSL_CIPHER) *ciphers; - int i; - ciphers = SSL_get_ciphers(s); - for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { - cipher = sk_SSL_CIPHER_value(ciphers, i); - if (cipher->algorithm_ssl == SSL_SSLV2) - return 0; - } - return 1; -} - -/* - * Fill a ClientRandom or ServerRandom field of length len. Returns <= 0 on - * failure, 1 on success. - */ -int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len) -{ - int send_time = 0; - if (len < 4) - return 0; - if (server) - send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0; - else - send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0; - if (send_time) { - unsigned long Time = (unsigned long)time(NULL); - unsigned char *p = result; - l2n(Time, p); - return RAND_bytes(p, len - 4); - } else - return RAND_bytes(result, len); -} - -static int ssl23_client_hello(SSL *s) -{ - unsigned char *buf; - unsigned char *p, *d; - int i, ch_len; - unsigned long l; - int ssl2_compat; - int version = 0, version_major, version_minor; - int al = 0; -#ifndef OPENSSL_NO_COMP - int j; - SSL_COMP *comp; -#endif - int ret; - unsigned long mask, options = s->options; - - ssl2_compat = (options & SSL_OP_NO_SSLv2) ? 0 : 1; - - if (ssl2_compat && ssl23_no_ssl2_ciphers(s)) - ssl2_compat = 0; - - /* - * SSL_OP_NO_X disables all protocols above X *if* there are - * some protocols below X enabled. This is required in order - * to maintain "version capability" vector contiguous. So - * that if application wants to disable TLS1.0 in favour of - * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the - * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. - */ - mask = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 -#if !defined(OPENSSL_NO_SSL3) - | SSL_OP_NO_SSLv3 -#endif -#if !defined(OPENSSL_NO_SSL2) - | (ssl2_compat ? SSL_OP_NO_SSLv2 : 0) -#endif - ; -#if !defined(OPENSSL_NO_TLS1_2_CLIENT) - version = TLS1_2_VERSION; - - if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask) - version = TLS1_1_VERSION; -#else - version = TLS1_1_VERSION; -#endif - mask &= ~SSL_OP_NO_TLSv1_1; - if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask) - version = TLS1_VERSION; - mask &= ~SSL_OP_NO_TLSv1; -#if !defined(OPENSSL_NO_SSL3) - if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask) - version = SSL3_VERSION; - mask &= ~SSL_OP_NO_SSLv3; -#endif -#if !defined(OPENSSL_NO_SSL2) - if ((options & SSL_OP_NO_SSLv3) && (options & mask) != mask) - version = SSL2_VERSION; -#endif - -#ifndef OPENSSL_NO_TLSEXT - if (version != SSL2_VERSION) { - /* - * have to disable SSL 2.0 compatibility if we need TLS extensions - */ - - if (s->tlsext_hostname != NULL) - ssl2_compat = 0; - if (s->tlsext_status_type != -1) - ssl2_compat = 0; -# ifdef TLSEXT_TYPE_opaque_prf_input - if (s->ctx->tlsext_opaque_prf_input_callback != 0 - || s->tlsext_opaque_prf_input != NULL) - ssl2_compat = 0; -# endif - if (s->cert->cli_ext.meths_count != 0) - ssl2_compat = 0; - } -#endif - - buf = (unsigned char *)s->init_buf->data; - if (s->state == SSL23_ST_CW_CLNT_HELLO_A) { - /* - * Since we're sending s23 client hello, we're not reusing a session, as - * we'd be using the method from the saved session instead - */ - if (!ssl_get_new_session(s, 0)) { - return -1; - } - - p = s->s3->client_random; - if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0) - return -1; - - if (version == TLS1_2_VERSION) { - version_major = TLS1_2_VERSION_MAJOR; - version_minor = TLS1_2_VERSION_MINOR; - } else if (tls1_suiteb(s)) { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, - SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); - return -1; - } else if (version == TLS1_1_VERSION) { - version_major = TLS1_1_VERSION_MAJOR; - version_minor = TLS1_1_VERSION_MINOR; - } else if (version == TLS1_VERSION) { - version_major = TLS1_VERSION_MAJOR; - version_minor = TLS1_VERSION_MINOR; - } -#ifdef OPENSSL_FIPS - else if (FIPS_mode()) { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, - SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - return -1; - } -#endif - else if (version == SSL3_VERSION) { - version_major = SSL3_VERSION_MAJOR; - version_minor = SSL3_VERSION_MINOR; - } else if (version == SSL2_VERSION) { - version_major = SSL2_VERSION_MAJOR; - version_minor = SSL2_VERSION_MINOR; - } else { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_PROTOCOLS_AVAILABLE); - return (-1); - } - - s->client_version = version; - - if (ssl2_compat) { - /* create SSL 2.0 compatible Client Hello */ - - /* two byte record header will be written last */ - d = &(buf[2]); - p = d + 9; /* leave space for message type, version, - * individual length fields */ - - *(d++) = SSL2_MT_CLIENT_HELLO; - *(d++) = version_major; - *(d++) = version_minor; - - /* Ciphers supported */ - i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), p, 0); - if (i == 0) { - /* no ciphers */ - SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); - return -1; - } - s2n(i, d); - p += i; - - /* - * put in the session-id length (zero since there is no reuse) - */ - s2n(0, d); - - if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) - ch_len = SSL2_CHALLENGE_LENGTH; - else - ch_len = SSL2_MAX_CHALLENGE_LENGTH; - - /* write out sslv2 challenge */ - /* - * Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because it - * is one of SSL2_MAX_CHALLENGE_LENGTH (32) or - * SSL2_MAX_CHALLENGE_LENGTH (16), but leave the check in for - * futurproofing - */ - if (SSL3_RANDOM_SIZE < ch_len) - i = SSL3_RANDOM_SIZE; - else - i = ch_len; - s2n(i, d); - memset(&(s->s3->client_random[0]), 0, SSL3_RANDOM_SIZE); - if (RAND_bytes (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) - <= 0) - return -1; - - memcpy(p, &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i); - p += i; - - i = p - &(buf[2]); - buf[0] = ((i >> 8) & 0xff) | 0x80; - buf[1] = (i & 0xff); - - /* number of bytes to write */ - s->init_num = i + 2; - s->init_off = 0; - - ssl3_finish_mac(s, &(buf[2]), i); - } else { - /* create Client Hello in SSL 3.0/TLS 1.0 format */ - - /* - * do the record header (5 bytes) and handshake message header (4 - * bytes) last - */ - d = p = &(buf[9]); - - *(p++) = version_major; - *(p++) = version_minor; - - /* Random stuff */ - memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; - - /* Session ID (zero since there is no reuse) */ - *(p++) = 0; - - /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */ - i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), - ssl3_put_cipher_by_char); - if (i == 0) { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); - return -1; - } -#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH - /* - * Some servers hang if client hello > 256 bytes as hack - * workaround chop number of supported ciphers to keep it well - * below this if we use TLS v1.2 - */ - if (TLS1_get_version(s) >= TLS1_2_VERSION - && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH) - i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1; -#endif - s2n(i, p); - p += i; - - /* COMPRESSION */ -#ifdef OPENSSL_NO_COMP - *(p++) = 1; -#else - if ((s->options & SSL_OP_NO_COMPRESSION) - || !s->ctx->comp_methods) - j = 0; - else - j = sk_SSL_COMP_num(s->ctx->comp_methods); - *(p++) = 1 + j; - for (i = 0; i < j; i++) { - comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); - *(p++) = comp->id; - } -#endif - *(p++) = 0; /* Add the NULL method */ - -#ifndef OPENSSL_NO_TLSEXT - /* TLS extensions */ - if (ssl_prepare_clienthello_tlsext(s) <= 0) { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); - return -1; - } - if ((p = - ssl_add_clienthello_tlsext(s, p, - buf + SSL3_RT_MAX_PLAIN_LENGTH, - &al)) == NULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - return -1; - } -#endif - - l = p - d; - - /* fill in 4-byte handshake header */ - d = &(buf[5]); - *(d++) = SSL3_MT_CLIENT_HELLO; - l2n3(l, d); - - l += 4; - - if (l > SSL3_RT_MAX_PLAIN_LENGTH) { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - return -1; - } - - /* fill in 5-byte record header */ - d = buf; - *(d++) = SSL3_RT_HANDSHAKE; - *(d++) = version_major; - /* - * Some servers hang if we use long client hellos and a record - * number > TLS 1.0. - */ - if (TLS1_get_client_version(s) > TLS1_VERSION) - *(d++) = 1; - else - *(d++) = version_minor; - s2n((int)l, d); - - /* number of bytes to write */ - s->init_num = p - buf; - s->init_off = 0; - - ssl3_finish_mac(s, &(buf[5]), s->init_num - 5); - } - - s->state = SSL23_ST_CW_CLNT_HELLO_B; - s->init_off = 0; - } - - /* SSL3_ST_CW_CLNT_HELLO_B */ - ret = ssl23_write_bytes(s); - - if ((ret >= 2) && s->msg_callback) { - /* Client Hello has been sent; tell msg_callback */ - - if (ssl2_compat) - s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data + 2, - ret - 2, s, s->msg_callback_arg); - else { - s->msg_callback(1, version, SSL3_RT_HEADER, s->init_buf->data, 5, - s, s->msg_callback_arg); - s->msg_callback(1, version, SSL3_RT_HANDSHAKE, - s->init_buf->data + 5, ret - 5, s, - s->msg_callback_arg); - } - } - - return ret; -} - -static int ssl23_get_server_hello(SSL *s) -{ - char buf[8]; - unsigned char *p; - int i; - int n; - - n = ssl23_read_bytes(s, 7); - - if (n != 7) - return (n); - p = s->packet; - - memcpy(buf, p, n); - - if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) && - (p[5] == 0x00) && (p[6] == 0x02)) { -#ifdef OPENSSL_NO_SSL2 - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; -#else - /* we are talking sslv2 */ - /* - * we need to clean up the SSLv3 setup and put in the sslv2 stuff. - */ - int ch_len; - - if (s->options & SSL_OP_NO_SSLv2) { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; - } - if (s->s2 == NULL) { - if (!ssl2_new(s)) - goto err; - } else - ssl2_clear(s); - - if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) - ch_len = SSL2_CHALLENGE_LENGTH; - else - ch_len = SSL2_MAX_CHALLENGE_LENGTH; - - /* write out sslv2 challenge */ - /* - * Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because it is - * one of SSL2_MAX_CHALLENGE_LENGTH (32) or SSL2_MAX_CHALLENGE_LENGTH - * (16), but leave the check in for futurproofing - */ - i = (SSL3_RANDOM_SIZE < ch_len) - ? SSL3_RANDOM_SIZE : ch_len; - s->s2->challenge_length = i; - memcpy(s->s2->challenge, - &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i); - - if (s->s3 != NULL) - ssl3_free(s); - - if (!BUF_MEM_grow_clean(s->init_buf, - SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, ERR_R_BUF_LIB); - goto err; - } - - s->state = SSL2_ST_GET_SERVER_HELLO_A; - if (!(s->client_version == SSL2_VERSION)) - /* - * use special padding (SSL 3.0 draft/RFC 2246, App. E.2) - */ - s->s2->ssl2_rollback = 1; - - /* - * setup the 7 bytes we have read so we get them from the sslv2 - * buffer - */ - s->rstate = SSL_ST_READ_HEADER; - s->packet_length = n; - s->packet = &(s->s2->rbuf[0]); - memcpy(s->packet, buf, n); - s->s2->rbuf_left = n; - s->s2->rbuf_offs = 0; - - /* we have already written one */ - s->s2->write_sequence = 1; - - s->method = SSLv2_client_method(); - s->handshake_func = s->method->ssl_connect; -#endif - } else if (p[1] == SSL3_VERSION_MAJOR && - p[2] <= TLS1_2_VERSION_MINOR && - ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) || - (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2))) { - /* we have sslv3 or tls1 (server hello or alert) */ - -#ifndef OPENSSL_NO_SSL3 - if ((p[2] == SSL3_VERSION_MINOR) && !(s->options & SSL_OP_NO_SSLv3)) { -# ifdef OPENSSL_FIPS - if (FIPS_mode()) { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, - SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - goto err; - } -# endif - s->version = SSL3_VERSION; - s->method = SSLv3_client_method(); - } else -#endif - if ((p[2] == TLS1_VERSION_MINOR) && !(s->options & SSL_OP_NO_TLSv1)) { - s->version = TLS1_VERSION; - s->method = TLSv1_client_method(); - } else if ((p[2] == TLS1_1_VERSION_MINOR) && - !(s->options & SSL_OP_NO_TLSv1_1)) { - s->version = TLS1_1_VERSION; - s->method = TLSv1_1_client_method(); - } else if ((p[2] == TLS1_2_VERSION_MINOR) && - !(s->options & SSL_OP_NO_TLSv1_2)) { - s->version = TLS1_2_VERSION; - s->method = TLSv1_2_client_method(); - } else { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; - } - - s->session->ssl_version = s->version; - - /* ensure that TLS_MAX_VERSION is up-to-date */ - OPENSSL_assert(s->version <= TLS_MAX_VERSION); - - if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) { - /* fatal alert */ - - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int j; - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - i = p[5]; - if (cb != NULL) { - j = (i << 8) | p[6]; - cb(s, SSL_CB_READ_ALERT, j); - } - - if (s->msg_callback) { - s->msg_callback(0, s->version, SSL3_RT_HEADER, p, 5, s, - s->msg_callback_arg); - s->msg_callback(0, s->version, SSL3_RT_ALERT, p + 5, 2, s, - s->msg_callback_arg); - } - - s->rwstate = SSL_NOTHING; - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_AD_REASON_OFFSET + p[6]); - goto err; - } - - if (!ssl_init_wbio_buffer(s, 1)) - goto err; - - /* we are in this state */ - s->state = SSL3_ST_CR_SRVR_HELLO_A; - - /* - * put the 7 bytes we have read into the input buffer for SSLv3 - */ - s->rstate = SSL_ST_READ_HEADER; - s->packet_length = n; - if (s->s3->rbuf.buf == NULL) - if (!ssl3_setup_read_buffer(s)) - goto err; - s->packet = &(s->s3->rbuf.buf[0]); - memcpy(s->packet, buf, n); - s->s3->rbuf.left = n; - s->s3->rbuf.offset = 0; - - s->handshake_func = s->method->ssl_connect; - } else { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNKNOWN_PROTOCOL); - goto err; - } - s->init_num = 0; - - return (SSL_connect(s)); - err: - return (-1); -} diff --git a/thirdparty/openssl/ssl/s23_lib.c b/thirdparty/openssl/ssl/s23_lib.c deleted file mode 100644 index 9056d39e83..0000000000 --- a/thirdparty/openssl/ssl/s23_lib.c +++ /dev/null @@ -1,185 +0,0 @@ -/* ssl/s23_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include <openssl/objects.h> -#include "ssl_locl.h" - -long ssl23_default_timeout(void) -{ - return (300); -} - -int ssl23_num_ciphers(void) -{ - return (ssl3_num_ciphers() -#ifndef OPENSSL_NO_SSL2 - + ssl2_num_ciphers() -#endif - ); -} - -const SSL_CIPHER *ssl23_get_cipher(unsigned int u) -{ - unsigned int uu = ssl3_num_ciphers(); - - if (u < uu) - return (ssl3_get_cipher(u)); - else -#ifndef OPENSSL_NO_SSL2 - return (ssl2_get_cipher(u - uu)); -#else - return (NULL); -#endif -} - -/* - * This function needs to check if the ciphers required are actually - * available - */ -const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p) -{ - const SSL_CIPHER *cp; - - cp = ssl3_get_cipher_by_char(p); -#ifndef OPENSSL_NO_SSL2 - if (cp == NULL) - cp = ssl2_get_cipher_by_char(p); -#endif - return (cp); -} - -int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) -{ - long l; - - /* We can write SSLv2 and SSLv3 ciphers */ - /* but no ECC ciphers */ - if (c->algorithm_mkey == SSL_kECDHr || - c->algorithm_mkey == SSL_kECDHe || - c->algorithm_mkey == SSL_kEECDH || - c->algorithm_auth == SSL_aECDH || c->algorithm_auth == SSL_aECDSA) - return 0; - if (p != NULL) { - l = c->id; - p[0] = ((unsigned char)(l >> 16L)) & 0xFF; - p[1] = ((unsigned char)(l >> 8L)) & 0xFF; - p[2] = ((unsigned char)(l)) & 0xFF; - } - return (3); -} - -int ssl23_read(SSL *s, void *buf, int len) -{ - int n; - - clear_sys_error(); - if (SSL_in_init(s) && (!s->in_handshake)) { - n = s->handshake_func(s); - if (n < 0) - return (n); - if (n == 0) { - SSLerr(SSL_F_SSL23_READ, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - return (SSL_read(s, buf, len)); - } else { - ssl_undefined_function(s); - return (-1); - } -} - -int ssl23_peek(SSL *s, void *buf, int len) -{ - int n; - - clear_sys_error(); - if (SSL_in_init(s) && (!s->in_handshake)) { - n = s->handshake_func(s); - if (n < 0) - return (n); - if (n == 0) { - SSLerr(SSL_F_SSL23_PEEK, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - return (SSL_peek(s, buf, len)); - } else { - ssl_undefined_function(s); - return (-1); - } -} - -int ssl23_write(SSL *s, const void *buf, int len) -{ - int n; - - clear_sys_error(); - if (SSL_in_init(s) && (!s->in_handshake)) { - n = s->handshake_func(s); - if (n < 0) - return (n); - if (n == 0) { - SSLerr(SSL_F_SSL23_WRITE, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - return (SSL_write(s, buf, len)); - } else { - ssl_undefined_function(s); - return (-1); - } -} diff --git a/thirdparty/openssl/ssl/s23_meth.c b/thirdparty/openssl/ssl/s23_meth.c deleted file mode 100644 index eb76098792..0000000000 --- a/thirdparty/openssl/ssl/s23_meth.c +++ /dev/null @@ -1,89 +0,0 @@ -/* ssl/s23_meth.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include <openssl/objects.h> -#include "ssl_locl.h" - -static const SSL_METHOD *ssl23_get_method(int ver); -static const SSL_METHOD *ssl23_get_method(int ver) -{ -#ifndef OPENSSL_NO_SSL2 - if (ver == SSL2_VERSION) - return (SSLv2_method()); - else -#endif -#ifndef OPENSSL_NO_SSL3 - if (ver == SSL3_VERSION) - return (SSLv3_method()); - else -#endif -#ifndef OPENSSL_NO_TLS1 - if (ver == TLS1_VERSION) - return (TLSv1_method()); - else if (ver == TLS1_1_VERSION) - return (TLSv1_1_method()); - else if (ver == TLS1_2_VERSION) - return (TLSv1_2_method()); - else -#endif - return (NULL); -} - -IMPLEMENT_ssl23_meth_func(SSLv23_method, - ssl23_accept, ssl23_connect, ssl23_get_method) diff --git a/thirdparty/openssl/ssl/s23_pkt.c b/thirdparty/openssl/ssl/s23_pkt.c deleted file mode 100644 index 6544180efe..0000000000 --- a/thirdparty/openssl/ssl/s23_pkt.c +++ /dev/null @@ -1,119 +0,0 @@ -/* ssl/s23_pkt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include <errno.h> -#define USE_SOCKETS -#include "ssl_locl.h" -#include <openssl/evp.h> -#include <openssl/buffer.h> - -/* - * Return values are as per SSL_write() - */ -int ssl23_write_bytes(SSL *s) -{ - int i, num, tot; - char *buf; - - buf = s->init_buf->data; - tot = s->init_off; - num = s->init_num; - for (;;) { - s->rwstate = SSL_WRITING; - i = BIO_write(s->wbio, &(buf[tot]), num); - if (i <= 0) { - s->init_off = tot; - s->init_num = num; - return i; - } - s->rwstate = SSL_NOTHING; - if (i == num) - return (tot + i); - - num -= i; - tot += i; - } -} - -/* return regularly only when we have read (at least) 'n' bytes - * - * Return values are as per SSL_read() - */ -int ssl23_read_bytes(SSL *s, int n) -{ - unsigned char *p; - int j; - - if (s->packet_length < (unsigned int)n) { - p = s->packet; - - for (;;) { - s->rwstate = SSL_READING; - j = BIO_read(s->rbio, (char *)&(p[s->packet_length]), - n - s->packet_length); - if (j <= 0) - return j; - s->rwstate = SSL_NOTHING; - s->packet_length += j; - if (s->packet_length >= (unsigned int)n) - return (s->packet_length); - } - } - return (n); -} diff --git a/thirdparty/openssl/ssl/s23_srvr.c b/thirdparty/openssl/ssl/s23_srvr.c deleted file mode 100644 index d3f6db15cc..0000000000 --- a/thirdparty/openssl/ssl/s23_srvr.c +++ /dev/null @@ -1,655 +0,0 @@ -/* ssl/s23_srvr.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 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 - * openssl-core@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). - * - */ - -#include <stdio.h> -#include "ssl_locl.h" -#include <openssl/buffer.h> -#include <openssl/rand.h> -#include <openssl/objects.h> -#include <openssl/evp.h> -#ifdef OPENSSL_FIPS -# include <openssl/fips.h> -#endif - -static const SSL_METHOD *ssl23_get_server_method(int ver); -int ssl23_get_client_hello(SSL *s); -static const SSL_METHOD *ssl23_get_server_method(int ver) -{ -#ifndef OPENSSL_NO_SSL2 - if (ver == SSL2_VERSION) - return (SSLv2_server_method()); -#endif -#ifndef OPENSSL_NO_SSL3 - if (ver == SSL3_VERSION) - return (SSLv3_server_method()); -#endif - if (ver == TLS1_VERSION) - return (TLSv1_server_method()); - else if (ver == TLS1_1_VERSION) - return (TLSv1_1_server_method()); - else if (ver == TLS1_2_VERSION) - return (TLSv1_2_server_method()); - else - return (NULL); -} - -IMPLEMENT_ssl23_meth_func(SSLv23_server_method, - ssl23_accept, - ssl_undefined_function, ssl23_get_server_method) - -int ssl23_accept(SSL *s) -{ - BUF_MEM *buf; - unsigned long Time = (unsigned long)time(NULL); - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int ret = -1; - int new_state, state; - - RAND_add(&Time, sizeof(Time), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_BEFORE: - case SSL_ST_ACCEPT: - case SSL_ST_BEFORE | SSL_ST_ACCEPT: - case SSL_ST_OK | SSL_ST_ACCEPT: - - s->server = 1; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - /* s->version=SSL3_VERSION; */ - s->type = SSL_ST_ACCEPT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - goto end; - } - if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - BUF_MEM_free(buf); - ret = -1; - goto end; - } - s->init_buf = buf; - } - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - goto end; - } - - s->state = SSL23_ST_SR_CLNT_HELLO_A; - s->ctx->stats.sess_accept++; - s->init_num = 0; - break; - - case SSL23_ST_SR_CLNT_HELLO_A: - case SSL23_ST_SR_CLNT_HELLO_B: - - s->shutdown = 0; - ret = ssl23_get_client_hello(s); - if (ret >= 0) - cb = NULL; - goto end; - /* break; */ - - default: - SSLerr(SSL_F_SSL23_ACCEPT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* break; */ - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_ACCEPT_LOOP, 1); - s->state = new_state; - } - } - end: - s->in_handshake--; - if (cb != NULL) - cb(s, SSL_CB_ACCEPT_EXIT, ret); - return (ret); -} - -int ssl23_get_client_hello(SSL *s) -{ - /*- - * Request this many bytes in initial read. - * We can detect SSL 3.0/TLS 1.0 Client Hellos - * ('type == 3') correctly only when the following - * is in a single record, which is not guaranteed by - * the protocol specification: - * Byte Content - * 0 type \ - * 1/2 version > record header - * 3/4 length / - * 5 msg_type \ - * 6-8 length > Client Hello message - * 9/10 client_version / - */ - char buf_space[11]; - char *buf = &(buf_space[0]); - unsigned char *p, *d, *d_len, *dd; - unsigned int i; - unsigned int csl, sil, cl; - int n = 0, j; - int type = 0; - int v[2]; - - if (s->state == SSL23_ST_SR_CLNT_HELLO_A) { - /* read the initial header */ - v[0] = v[1] = 0; - - if (!ssl3_setup_buffers(s)) - goto err; - - n = ssl23_read_bytes(s, sizeof buf_space); - if (n != sizeof buf_space) - return (n); /* n == -1 || n == 0 */ - - p = s->packet; - - memcpy(buf, p, n); - - if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) { - /* - * SSLv2 header - */ - if ((p[3] == 0x00) && (p[4] == 0x02)) { - v[0] = p[3]; - v[1] = p[4]; - /* SSLv2 */ - if (!(s->options & SSL_OP_NO_SSLv2)) - type = 1; - } else if (p[3] == SSL3_VERSION_MAJOR) { - v[0] = p[3]; - v[1] = p[4]; - /* SSLv3/TLSv1 */ - if (p[4] >= TLS1_VERSION_MINOR) { - if (p[4] >= TLS1_2_VERSION_MINOR && - !(s->options & SSL_OP_NO_TLSv1_2)) { - s->version = TLS1_2_VERSION; - s->state = SSL23_ST_SR_CLNT_HELLO_B; - } else if (p[4] >= TLS1_1_VERSION_MINOR && - !(s->options & SSL_OP_NO_TLSv1_1)) { - s->version = TLS1_1_VERSION; - /* - * type=2; - *//* - * done later to survive restarts - */ - s->state = SSL23_ST_SR_CLNT_HELLO_B; - } else if (!(s->options & SSL_OP_NO_TLSv1)) { - s->version = TLS1_VERSION; - /* - * type=2; - *//* - * done later to survive restarts - */ - s->state = SSL23_ST_SR_CLNT_HELLO_B; - } else if (!(s->options & SSL_OP_NO_SSLv3)) { - s->version = SSL3_VERSION; - /* type=2; */ - s->state = SSL23_ST_SR_CLNT_HELLO_B; - } else if (!(s->options & SSL_OP_NO_SSLv2)) { - type = 1; - } - } else if (!(s->options & SSL_OP_NO_SSLv3)) { - s->version = SSL3_VERSION; - /* type=2; */ - s->state = SSL23_ST_SR_CLNT_HELLO_B; - } else if (!(s->options & SSL_OP_NO_SSLv2)) - type = 1; - - } - } - /* p[4] < 5 ... silly record length? */ - else if ((p[0] == SSL3_RT_HANDSHAKE) && - (p[1] == SSL3_VERSION_MAJOR) && - (p[5] == SSL3_MT_CLIENT_HELLO) && ((p[3] == 0 && p[4] < 5) - || (p[9] >= p[1]))) { - /* - * SSLv3 or tls1 header - */ - - v[0] = p[1]; /* major version (= SSL3_VERSION_MAJOR) */ - /* - * We must look at client_version inside the Client Hello message - * to get the correct minor version. However if we have only a - * pathologically small fragment of the Client Hello message, this - * would be difficult, and we'd have to read more records to find - * out. No known SSL 3.0 client fragments ClientHello like this, - * so we simply reject such connections to avoid protocol version - * downgrade attacks. - */ - if (p[3] == 0 && p[4] < 6) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_SMALL); - goto err; - } - /* - * if major version number > 3 set minor to a value which will - * use the highest version 3 we support. If TLS 2.0 ever appears - * we will need to revise this.... - */ - if (p[9] > SSL3_VERSION_MAJOR) - v[1] = 0xff; - else - v[1] = p[10]; /* minor version according to client_version */ - if (v[1] >= TLS1_VERSION_MINOR) { - if (v[1] >= TLS1_2_VERSION_MINOR && - !(s->options & SSL_OP_NO_TLSv1_2)) { - s->version = TLS1_2_VERSION; - type = 3; - } else if (v[1] >= TLS1_1_VERSION_MINOR && - !(s->options & SSL_OP_NO_TLSv1_1)) { - s->version = TLS1_1_VERSION; - type = 3; - } else if (!(s->options & SSL_OP_NO_TLSv1)) { - s->version = TLS1_VERSION; - type = 3; - } else if (!(s->options & SSL_OP_NO_SSLv3)) { - s->version = SSL3_VERSION; - type = 3; - } - } else { - /* client requests SSL 3.0 */ - if (!(s->options & SSL_OP_NO_SSLv3)) { - s->version = SSL3_VERSION; - type = 3; - } else if (!(s->options & SSL_OP_NO_TLSv1)) { - /* - * we won't be able to use TLS of course, but this will - * send an appropriate alert - */ - s->version = TLS1_VERSION; - type = 3; - } - } - } else if ((strncmp("GET ", (char *)p, 4) == 0) || - (strncmp("POST ", (char *)p, 5) == 0) || - (strncmp("HEAD ", (char *)p, 5) == 0) || - (strncmp("PUT ", (char *)p, 4) == 0)) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTP_REQUEST); - goto err; - } else if (strncmp("CONNECT", (char *)p, 7) == 0) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTPS_PROXY_REQUEST); - goto err; - } - } - - /* ensure that TLS_MAX_VERSION is up-to-date */ - OPENSSL_assert(s->version <= TLS_MAX_VERSION); - - if (s->version < TLS1_2_VERSION && tls1_suiteb(s)) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, - SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); - goto err; - } -#ifdef OPENSSL_FIPS - if (FIPS_mode() && (s->version < TLS1_VERSION)) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, - SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - goto err; - } -#endif - - if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { - /* - * we have SSLv3/TLSv1 in an SSLv2 header (other cases skip this - * state) - */ - - type = 2; - p = s->packet; - v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ - v[1] = p[4]; - - /*- - * An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 - * header is sent directly on the wire, not wrapped as a TLS - * record. It's format is: - * Byte Content - * 0-1 msg_length - * 2 msg_type - * 3-4 version - * 5-6 cipher_spec_length - * 7-8 session_id_length - * 9-10 challenge_length - * ... ... - */ - n = ((p[0] & 0x7f) << 8) | p[1]; - if (n > (1024 * 4)) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_LARGE); - goto err; - } - if (n < 9) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, - SSL_R_RECORD_LENGTH_MISMATCH); - goto err; - } - - j = ssl23_read_bytes(s, n + 2); - /* - * We previously read 11 bytes, so if j > 0, we must have j == n+2 == - * s->packet_length. We have at least 11 valid packet bytes. - */ - if (j <= 0) - return (j); - - ssl3_finish_mac(s, s->packet + 2, s->packet_length - 2); - - /* CLIENT-HELLO */ - if (s->msg_callback) - s->msg_callback(0, SSL2_VERSION, 0, s->packet + 2, - s->packet_length - 2, s, s->msg_callback_arg); - - p = s->packet; - p += 5; - n2s(p, csl); - n2s(p, sil); - n2s(p, cl); - d = (unsigned char *)s->init_buf->data; - if ((csl + sil + cl + 11) != s->packet_length) { /* We can't have TLS - * extensions in SSL - * 2.0 format * - * Client Hello, can - * we? Error - * condition should - * be * '>' - * otherweise */ - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, - SSL_R_RECORD_LENGTH_MISMATCH); - goto err; - } - - /* record header: msg_type ... */ - *(d++) = SSL3_MT_CLIENT_HELLO; - /* ... and length (actual value will be written later) */ - d_len = d; - d += 3; - - /* client_version */ - *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */ - *(d++) = v[1]; - - /* lets populate the random area */ - /* get the challenge_length */ - i = (cl > SSL3_RANDOM_SIZE) ? SSL3_RANDOM_SIZE : cl; - memset(d, 0, SSL3_RANDOM_SIZE); - memcpy(&(d[SSL3_RANDOM_SIZE - i]), &(p[csl + sil]), i); - d += SSL3_RANDOM_SIZE; - - /* no session-id reuse */ - *(d++) = 0; - - /* ciphers */ - j = 0; - dd = d; - d += 2; - for (i = 0; i < csl; i += 3) { - if (p[i] != 0) - continue; - *(d++) = p[i + 1]; - *(d++) = p[i + 2]; - j += 2; - } - s2n(j, dd); - - /* COMPRESSION */ - *(d++) = 1; - *(d++) = 0; - -#if 0 - /* copy any remaining data with may be extensions */ - p = p + csl + sil + cl; - while (p < s->packet + s->packet_length) { - *(d++) = *(p++); - } -#endif - - i = (d - (unsigned char *)s->init_buf->data) - 4; - l2n3((long)i, d_len); - - /* get the data reused from the init_buf */ - s->s3->tmp.reuse_message = 1; - s->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO; - s->s3->tmp.message_size = i; - } - - /* imaginary new state (for program structure): */ - /* s->state = SSL23_SR_CLNT_HELLO_C */ - - if (type == 1) { -#ifdef OPENSSL_NO_SSL2 - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; -#else - /* we are talking sslv2 */ - /* - * we need to clean up the SSLv3/TLSv1 setup and put in the sslv2 - * stuff. - */ - - if (s->s2 == NULL) { - if (!ssl2_new(s)) - goto err; - } else - ssl2_clear(s); - - if (s->s3 != NULL) - ssl3_free(s); - - if (!BUF_MEM_grow_clean(s->init_buf, - SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { - goto err; - } - - s->state = SSL2_ST_GET_CLIENT_HELLO_A; - if (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3) - s->s2->ssl2_rollback = 0; - else - /* - * reject SSL 2.0 session if client supports SSL 3.0 or TLS 1.0 - * (SSL 3.0 draft/RFC 2246, App. E.2) - */ - s->s2->ssl2_rollback = 1; - - /* - * setup the n bytes we have read so we get them from the sslv2 - * buffer - */ - s->rstate = SSL_ST_READ_HEADER; - s->packet_length = n; - s->packet = &(s->s2->rbuf[0]); - memcpy(s->packet, buf, n); - s->s2->rbuf_left = n; - s->s2->rbuf_offs = 0; - - s->method = SSLv2_server_method(); - s->handshake_func = s->method->ssl_accept; -#endif - } - - if ((type == 2) || (type == 3)) { - /* - * we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) - */ - const SSL_METHOD *new_method; - new_method = ssl23_get_server_method(s->version); - if (new_method == NULL) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; - } - s->method = new_method; - - if (!ssl_init_wbio_buffer(s, 1)) - goto err; - - /* we are in this state */ - s->state = SSL3_ST_SR_CLNT_HELLO_A; - - if (type == 3) { - /* - * put the 'n' bytes we have read into the input buffer for SSLv3 - */ - s->rstate = SSL_ST_READ_HEADER; - s->packet_length = n; - if (s->s3->rbuf.buf == NULL) - if (!ssl3_setup_read_buffer(s)) - goto err; - - s->packet = &(s->s3->rbuf.buf[0]); - memcpy(s->packet, buf, n); - s->s3->rbuf.left = n; - s->s3->rbuf.offset = 0; - } else { - s->packet_length = 0; - s->s3->rbuf.left = 0; - s->s3->rbuf.offset = 0; - } -#if 0 /* ssl3_get_client_hello does this */ - s->client_version = (v[0] << 8) | v[1]; -#endif - s->handshake_func = s->method->ssl_accept; - } - - if ((type < 1) || (type > 3)) { - /* bad, very bad */ - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); - goto err; - } - s->init_num = 0; - - if (buf != buf_space) - OPENSSL_free(buf); - return (SSL_accept(s)); - err: - if (buf != buf_space) - OPENSSL_free(buf); - return (-1); -} diff --git a/thirdparty/openssl/ssl/s2_clnt.c b/thirdparty/openssl/ssl/s2_clnt.c deleted file mode 100644 index 20de1a8217..0000000000 --- a/thirdparty/openssl/ssl/s2_clnt.c +++ /dev/null @@ -1,1094 +0,0 @@ -/* ssl/s2_clnt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2001 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 - * openssl-core@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). - * - */ - -#include "ssl_locl.h" -#ifndef OPENSSL_NO_SSL2 -# include <stdio.h> -# include <openssl/rand.h> -# include <openssl/buffer.h> -# include <openssl/objects.h> -# include <openssl/evp.h> - -static const SSL_METHOD *ssl2_get_client_method(int ver); -static int get_server_finished(SSL *s); -static int get_server_verify(SSL *s); -static int get_server_hello(SSL *s); -static int client_hello(SSL *s); -static int client_master_key(SSL *s); -static int client_finished(SSL *s); -static int client_certificate(SSL *s); -static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from, - unsigned char *to, int padding); -# define BREAK break - -static const SSL_METHOD *ssl2_get_client_method(int ver) -{ - if (ver == SSL2_VERSION) - return (SSLv2_client_method()); - else - return (NULL); -} - -IMPLEMENT_ssl2_meth_func(SSLv2_client_method, - ssl_undefined_function, - ssl2_connect, ssl2_get_client_method) - -int ssl2_connect(SSL *s) -{ - unsigned long l = (unsigned long)time(NULL); - BUF_MEM *buf = NULL; - int ret = -1; - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int new_state, state; - - RAND_add(&l, sizeof(l), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - /* init things to blank */ - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_BEFORE: - case SSL_ST_CONNECT: - case SSL_ST_BEFORE | SSL_ST_CONNECT: - case SSL_ST_OK | SSL_ST_CONNECT: - - s->server = 0; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - s->version = SSL2_VERSION; - s->type = SSL_ST_CONNECT; - - buf = s->init_buf; - if ((buf == NULL) && ((buf = BUF_MEM_new()) == NULL)) { - ret = -1; - goto end; - } - if (!BUF_MEM_grow(buf, SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { - if (buf == s->init_buf) - buf = NULL; - ret = -1; - goto end; - } - s->init_buf = buf; - buf = NULL; - s->init_num = 0; - s->state = SSL2_ST_SEND_CLIENT_HELLO_A; - s->ctx->stats.sess_connect++; - s->handshake_func = ssl2_connect; - BREAK; - - case SSL2_ST_SEND_CLIENT_HELLO_A: - case SSL2_ST_SEND_CLIENT_HELLO_B: - s->shutdown = 0; - ret = client_hello(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_GET_SERVER_HELLO_A; - BREAK; - - case SSL2_ST_GET_SERVER_HELLO_A: - case SSL2_ST_GET_SERVER_HELLO_B: - ret = get_server_hello(s); - if (ret <= 0) - goto end; - s->init_num = 0; - if (!s->hit) { /* new session */ - s->state = SSL2_ST_SEND_CLIENT_MASTER_KEY_A; - BREAK; - } else { - s->state = SSL2_ST_CLIENT_START_ENCRYPTION; - break; - } - - case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: - case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: - ret = client_master_key(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_CLIENT_START_ENCRYPTION; - break; - - case SSL2_ST_CLIENT_START_ENCRYPTION: - /* - * Ok, we now have all the stuff needed to start encrypting, so - * lets fire it up :-) - */ - if (!ssl2_enc_init(s, 1)) { - ret = -1; - goto end; - } - s->s2->clear_text = 0; - s->state = SSL2_ST_SEND_CLIENT_FINISHED_A; - break; - - case SSL2_ST_SEND_CLIENT_FINISHED_A: - case SSL2_ST_SEND_CLIENT_FINISHED_B: - ret = client_finished(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_GET_SERVER_VERIFY_A; - break; - - case SSL2_ST_GET_SERVER_VERIFY_A: - case SSL2_ST_GET_SERVER_VERIFY_B: - ret = get_server_verify(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_GET_SERVER_FINISHED_A; - break; - - case SSL2_ST_GET_SERVER_FINISHED_A: - case SSL2_ST_GET_SERVER_FINISHED_B: - ret = get_server_finished(s); - if (ret <= 0) - goto end; - break; - - case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: - case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: - case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: - case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: - case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: - ret = client_certificate(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_GET_SERVER_FINISHED_A; - break; - - case SSL_ST_OK: - if (s->init_buf != NULL) { - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - } - s->init_num = 0; - /* ERR_clear_error(); */ - - /* - * If we want to cache session-ids in the client and we - * successfully add the session-id to the cache, and there is a - * callback, then pass it out. 26/11/96 - eay - only add if not a - * re-used session. - */ - - ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); - if (s->hit) - s->ctx->stats.sess_hit++; - - ret = 1; - /* s->server=0; */ - s->ctx->stats.sess_connect_good++; - - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - - goto end; - /* break; */ - default: - SSLerr(SSL_F_SSL2_CONNECT, SSL_R_UNKNOWN_STATE); - return (-1); - /* break; */ - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_CONNECT_LOOP, 1); - s->state = new_state; - } - } - end: - s->in_handshake--; - if (buf != NULL) - BUF_MEM_free(buf); - if (cb != NULL) - cb(s, SSL_CB_CONNECT_EXIT, ret); - return (ret); -} - -static int get_server_hello(SSL *s) -{ - unsigned char *buf; - unsigned char *p; - int i, j; - unsigned long len; - STACK_OF(SSL_CIPHER) *sk = NULL, *cl, *prio, *allow; - - buf = (unsigned char *)s->init_buf->data; - p = buf; - if (s->state == SSL2_ST_GET_SERVER_HELLO_A) { - i = ssl2_read(s, (char *)&(buf[s->init_num]), 11 - s->init_num); - if (i < (11 - s->init_num)) - return (ssl2_part_read(s, SSL_F_GET_SERVER_HELLO, i)); - s->init_num = 11; - - if (*(p++) != SSL2_MT_SERVER_HELLO) { - if (p[-1] != SSL2_MT_ERROR) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_READ_WRONG_PACKET_TYPE); - } else - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_PEER_ERROR); - return (-1); - } -# if 0 - s->hit = (*(p++)) ? 1 : 0; - /* - * Some [PPC?] compilers fail to increment p in above statement, e.g. - * one provided with Rhapsody 5.5, but most recent example XL C 11.1 - * for AIX, even without optimization flag... - */ -# else - s->hit = (*p) ? 1 : 0; - p++; -# endif - s->s2->tmp.cert_type = *(p++); - n2s(p, i); - if (i < s->version) - s->version = i; - n2s(p, i); - s->s2->tmp.cert_length = i; - n2s(p, i); - s->s2->tmp.csl = i; - n2s(p, i); - s->s2->tmp.conn_id_length = i; - s->state = SSL2_ST_GET_SERVER_HELLO_B; - } - - /* SSL2_ST_GET_SERVER_HELLO_B */ - len = - 11 + (unsigned long)s->s2->tmp.cert_length + - (unsigned long)s->s2->tmp.csl + - (unsigned long)s->s2->tmp.conn_id_length; - if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_MESSAGE_TOO_LONG); - return -1; - } - j = (int)len - s->init_num; - i = ssl2_read(s, (char *)&(buf[s->init_num]), j); - if (i != j) - return (ssl2_part_read(s, SSL_F_GET_SERVER_HELLO, i)); - if (s->msg_callback) { - /* SERVER-HELLO */ - s->msg_callback(0, s->version, 0, buf, (size_t)len, s, - s->msg_callback_arg); - } - - /* things are looking good */ - - p = buf + 11; - if (s->hit) { - if (s->s2->tmp.cert_length != 0) { - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_REUSE_CERT_LENGTH_NOT_ZERO); - return (-1); - } - if (s->s2->tmp.cert_type != 0) { - if (!(s->options & SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG)) { - SSLerr(SSL_F_GET_SERVER_HELLO, - SSL_R_REUSE_CERT_TYPE_NOT_ZERO); - return (-1); - } - } - if (s->s2->tmp.csl != 0) { - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_REUSE_CIPHER_LIST_NOT_ZERO); - return (-1); - } - } else { -# if 0 - /* very bad */ - memset(s->session->session_id, 0, - SSL_MAX_SSL_SESSION_ID_LENGTH_IN_BYTES); - s->session->session_id_length = 0; -# endif - - /* - * we need to do this in case we were trying to reuse a client - * session but others are already reusing it. If this was a new - * 'blank' session ID, the session-id length will still be 0 - */ - if (s->session->session_id_length > 0) { - if (!ssl_get_new_session(s, 0)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - return (-1); - } - } - - if (ssl2_set_certificate(s, s->s2->tmp.cert_type, - s->s2->tmp.cert_length, p) <= 0) { - ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE); - return (-1); - } - p += s->s2->tmp.cert_length; - - if (s->s2->tmp.csl == 0) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_NO_CIPHER_LIST); - return (-1); - } - - /* - * We have just received a list of ciphers back from the server. We - * need to get the ones that match, then select the one we want the - * most :-). - */ - - /* load the ciphers */ - sk = ssl_bytes_to_cipher_list(s, p, s->s2->tmp.csl, - &s->session->ciphers); - p += s->s2->tmp.csl; - if (sk == NULL) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_MALLOC_FAILURE); - return (-1); - } - - (void)sk_SSL_CIPHER_set_cmp_func(sk, ssl_cipher_ptr_id_cmp); - - /* get the array of ciphers we will accept */ - cl = SSL_get_ciphers(s); - (void)sk_SSL_CIPHER_set_cmp_func(cl, ssl_cipher_ptr_id_cmp); - - /* - * If server preference flag set, choose the first - * (highest priority) cipher the server sends, otherwise - * client preference has priority. - */ - if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { - prio = sk; - allow = cl; - } else { - prio = cl; - allow = sk; - } - /* - * In theory we could have ciphers sent back that we don't want to - * use but that does not matter since we will check against the list - * we originally sent and for performance reasons we should not - * bother to match the two lists up just to check. - */ - for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { - if (sk_SSL_CIPHER_find(allow, sk_SSL_CIPHER_value(prio, i)) >= 0) - break; - } - - if (i >= sk_SSL_CIPHER_num(prio)) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_NO_CIPHER_MATCH); - return (-1); - } - s->session->cipher = sk_SSL_CIPHER_value(prio, i); - - if (s->session->peer != NULL) { /* can't happen */ - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - return (-1); - } - - s->session->peer = s->session->sess_cert->peer_key->x509; - /* peer_key->x509 has been set by ssl2_set_certificate. */ - CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509); - } - - if (s->session->sess_cert == NULL - || s->session->peer != s->session->sess_cert->peer_key->x509) - /* can't happen */ - { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - return (-1); - } - - s->s2->conn_id_length = s->s2->tmp.conn_id_length; - if (s->s2->conn_id_length > sizeof s->s2->conn_id) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_SSL2_CONNECTION_ID_TOO_LONG); - return -1; - } - memcpy(s->s2->conn_id, p, s->s2->tmp.conn_id_length); - return (1); -} - -static int client_hello(SSL *s) -{ - unsigned char *buf; - unsigned char *p, *d; -/* CIPHER **cipher;*/ - int i, n, j; - - buf = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_SEND_CLIENT_HELLO_A) { - if ((s->session == NULL) || (s->session->ssl_version != s->version)) { - if (!ssl_get_new_session(s, 0)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - return (-1); - } - } - /* else use the pre-loaded session */ - - p = buf; /* header */ - d = p + 9; /* data section */ - *(p++) = SSL2_MT_CLIENT_HELLO; /* type */ - s2n(SSL2_VERSION, p); /* version */ - n = j = 0; - - n = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), d, 0); - d += n; - - if (n == 0) { - SSLerr(SSL_F_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); - return (-1); - } - - s2n(n, p); /* cipher spec num bytes */ - - if ((s->session->session_id_length > 0) && - (s->session->session_id_length <= - SSL2_MAX_SSL_SESSION_ID_LENGTH)) { - i = s->session->session_id_length; - s2n(i, p); /* session id length */ - memcpy(d, s->session->session_id, (unsigned int)i); - d += i; - } else { - s2n(0, p); - } - - s->s2->challenge_length = SSL2_CHALLENGE_LENGTH; - s2n(SSL2_CHALLENGE_LENGTH, p); /* challenge length */ - /* - * challenge id data - */ - if (RAND_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0) - return -1; - memcpy(d, s->s2->challenge, SSL2_CHALLENGE_LENGTH); - d += SSL2_CHALLENGE_LENGTH; - - s->state = SSL2_ST_SEND_CLIENT_HELLO_B; - s->init_num = d - buf; - s->init_off = 0; - } - /* SSL2_ST_SEND_CLIENT_HELLO_B */ - return (ssl2_do_write(s)); -} - -static int client_master_key(SSL *s) -{ - unsigned char *buf; - unsigned char *p, *d; - int clear, enc, karg, i; - SSL_SESSION *sess; - const EVP_CIPHER *c; - const EVP_MD *md; - - buf = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A) { - - if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_CLIENT_MASTER_KEY, - SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); - return (-1); - } - sess = s->session; - p = buf; - d = p + 10; - *(p++) = SSL2_MT_CLIENT_MASTER_KEY; /* type */ - - i = ssl_put_cipher_by_char(s, sess->cipher, p); - p += i; - - /* make key_arg data */ - i = EVP_CIPHER_iv_length(c); - sess->key_arg_length = i; - if (i > SSL_MAX_KEY_ARG_LENGTH) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); - return -1; - } - if (i > 0) - if (RAND_bytes(sess->key_arg, i) <= 0) - return -1; - - /* make a master key */ - i = EVP_CIPHER_key_length(c); - sess->master_key_length = i; - if (i > 0) { - if (i > (int)sizeof(sess->master_key)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); - return -1; - } - if (RAND_bytes(sess->master_key, i) <= 0) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - return (-1); - } - } - - if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) - enc = 8; - else if (SSL_C_IS_EXPORT(sess->cipher)) - enc = 5; - else - enc = i; - - if ((int)i < enc) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_CLIENT_MASTER_KEY, SSL_R_CIPHER_TABLE_SRC_ERROR); - return (-1); - } - clear = i - enc; - s2n(clear, p); - memcpy(d, sess->master_key, (unsigned int)clear); - d += clear; - - enc = ssl_rsa_public_encrypt(sess->sess_cert, enc, - &(sess->master_key[clear]), d, - (s-> - s2->ssl2_rollback) ? RSA_SSLV23_PADDING - : RSA_PKCS1_PADDING); - if (enc <= 0) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_CLIENT_MASTER_KEY, SSL_R_PUBLIC_KEY_ENCRYPT_ERROR); - return (-1); - } -# ifdef PKCS1_CHECK - if (s->options & SSL_OP_PKCS1_CHECK_1) - d[1]++; - if (s->options & SSL_OP_PKCS1_CHECK_2) - sess->master_key[clear]++; -# endif - s2n(enc, p); - d += enc; - karg = sess->key_arg_length; - s2n(karg, p); /* key arg size */ - if (karg > (int)sizeof(sess->key_arg)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); - return -1; - } - memcpy(d, sess->key_arg, (unsigned int)karg); - d += karg; - - s->state = SSL2_ST_SEND_CLIENT_MASTER_KEY_B; - s->init_num = d - buf; - s->init_off = 0; - } - - /* SSL2_ST_SEND_CLIENT_MASTER_KEY_B */ - return (ssl2_do_write(s)); -} - -static int client_finished(SSL *s) -{ - unsigned char *p; - - if (s->state == SSL2_ST_SEND_CLIENT_FINISHED_A) { - p = (unsigned char *)s->init_buf->data; - *(p++) = SSL2_MT_CLIENT_FINISHED; - if (s->s2->conn_id_length > sizeof s->s2->conn_id) { - SSLerr(SSL_F_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR); - return -1; - } - memcpy(p, s->s2->conn_id, (unsigned int)s->s2->conn_id_length); - - s->state = SSL2_ST_SEND_CLIENT_FINISHED_B; - s->init_num = s->s2->conn_id_length + 1; - s->init_off = 0; - } - return (ssl2_do_write(s)); -} - -/* read the data and then respond */ -static int client_certificate(SSL *s) -{ - unsigned char *buf; - unsigned char *p, *d; - int i; - unsigned int n; - int cert_ch_len; - unsigned char *cert_ch; - - buf = (unsigned char *)s->init_buf->data; - - /* - * We have a cert associated with the SSL, so attach it to the session if - * it does not have one - */ - - if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A) { - i = ssl2_read(s, (char *)&(buf[s->init_num]), - SSL2_MAX_CERT_CHALLENGE_LENGTH + 2 - s->init_num); - if (i < (SSL2_MIN_CERT_CHALLENGE_LENGTH + 2 - s->init_num)) - return (ssl2_part_read(s, SSL_F_CLIENT_CERTIFICATE, i)); - s->init_num += i; - if (s->msg_callback) { - /* REQUEST-CERTIFICATE */ - s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, - s->msg_callback_arg); - } - - /* type=buf[0]; */ - /* type eq x509 */ - if (buf[1] != SSL2_AT_MD5_WITH_RSA_ENCRYPTION) { - ssl2_return_error(s, SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE); - SSLerr(SSL_F_CLIENT_CERTIFICATE, SSL_R_BAD_AUTHENTICATION_TYPE); - return (-1); - } - - if ((s->cert == NULL) || - (s->cert->key->x509 == NULL) || - (s->cert->key->privatekey == NULL)) { - s->state = SSL2_ST_X509_GET_CLIENT_CERTIFICATE; - } else - s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_C; - } - - cert_ch = buf + 2; - cert_ch_len = s->init_num - 2; - - if (s->state == SSL2_ST_X509_GET_CLIENT_CERTIFICATE) { - X509 *x509 = NULL; - EVP_PKEY *pkey = NULL; - - /* - * If we get an error we need to ssl->rwstate=SSL_X509_LOOKUP; - * return(error); We should then be retried when things are ok and we - * can get a cert or not - */ - - i = 0; - if (s->ctx->client_cert_cb != NULL) { - i = s->ctx->client_cert_cb(s, &(x509), &(pkey)); - } - - if (i < 0) { - s->rwstate = SSL_X509_LOOKUP; - return (-1); - } - s->rwstate = SSL_NOTHING; - - if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { - s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_C; - if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) { - i = 0; - } - X509_free(x509); - EVP_PKEY_free(pkey); - } else if (i == 1) { - if (x509 != NULL) - X509_free(x509); - if (pkey != NULL) - EVP_PKEY_free(pkey); - SSLerr(SSL_F_CLIENT_CERTIFICATE, - SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); - i = 0; - } - - if (i == 0) { - /* - * We have no client certificate to respond with so send the - * correct error message back - */ - s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_B; - p = buf; - *(p++) = SSL2_MT_ERROR; - s2n(SSL2_PE_NO_CERTIFICATE, p); - s->init_off = 0; - s->init_num = 3; - /* Write is done at the end */ - } - } - - if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B) { - return (ssl2_do_write(s)); - } - - if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C) { - EVP_MD_CTX ctx; - - /* - * ok, now we calculate the checksum do it first so we can reuse buf - * :-) - */ - p = buf; - EVP_MD_CTX_init(&ctx); - EVP_SignInit_ex(&ctx, s->ctx->rsa_md5, NULL); - EVP_SignUpdate(&ctx, s->s2->key_material, s->s2->key_material_length); - EVP_SignUpdate(&ctx, cert_ch, (unsigned int)cert_ch_len); - i = i2d_X509(s->session->sess_cert->peer_key->x509, &p); - /* - * Don't update the signature if it fails - FIXME: probably should - * handle this better - */ - if (i > 0) - EVP_SignUpdate(&ctx, buf, (unsigned int)i); - - p = buf; - d = p + 6; - *(p++) = SSL2_MT_CLIENT_CERTIFICATE; - *(p++) = SSL2_CT_X509_CERTIFICATE; - n = i2d_X509(s->cert->key->x509, &d); - s2n(n, p); - - if (!EVP_SignFinal(&ctx, d, &n, s->cert->key->privatekey)) { - /* - * this is not good. If things have failed it means there so - * something wrong with the key. We will continue with a 0 length - * signature - */ - } - EVP_MD_CTX_cleanup(&ctx); - s2n(n, p); - d += n; - - s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_D; - s->init_num = d - buf; - s->init_off = 0; - } - /* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */ - return (ssl2_do_write(s)); -} - -static int get_server_verify(SSL *s) -{ - unsigned char *p; - int i, n, len; - - p = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_GET_SERVER_VERIFY_A) { - i = ssl2_read(s, (char *)&(p[s->init_num]), 1 - s->init_num); - if (i < (1 - s->init_num)) - return (ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i)); - s->init_num += i; - - s->state = SSL2_ST_GET_SERVER_VERIFY_B; - if (*p != SSL2_MT_SERVER_VERIFY) { - if (p[0] != SSL2_MT_ERROR) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_READ_WRONG_PACKET_TYPE); - } else { - SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_PEER_ERROR); - /* try to read the error message */ - i = ssl2_read(s, (char *)&(p[s->init_num]), 3 - s->init_num); - return ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i); - } - return (-1); - } - } - - p = (unsigned char *)s->init_buf->data; - len = 1 + s->s2->challenge_length; - n = len - s->init_num; - i = ssl2_read(s, (char *)&(p[s->init_num]), n); - if (i < n) - return (ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i)); - if (s->msg_callback) { - /* SERVER-VERIFY */ - s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); - } - p += 1; - - if (CRYPTO_memcmp(p, s->s2->challenge, s->s2->challenge_length) != 0) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_CHALLENGE_IS_DIFFERENT); - return (-1); - } - return (1); -} - -static int get_server_finished(SSL *s) -{ - unsigned char *buf; - unsigned char *p; - int i, n, len; - - buf = (unsigned char *)s->init_buf->data; - p = buf; - if (s->state == SSL2_ST_GET_SERVER_FINISHED_A) { - i = ssl2_read(s, (char *)&(buf[s->init_num]), 1 - s->init_num); - if (i < (1 - s->init_num)) - return (ssl2_part_read(s, SSL_F_GET_SERVER_FINISHED, i)); - s->init_num += i; - - if (*p == SSL2_MT_REQUEST_CERTIFICATE) { - s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_A; - return (1); - } else if (*p != SSL2_MT_SERVER_FINISHED) { - if (p[0] != SSL2_MT_ERROR) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_FINISHED, - SSL_R_READ_WRONG_PACKET_TYPE); - } else { - SSLerr(SSL_F_GET_SERVER_FINISHED, SSL_R_PEER_ERROR); - /* try to read the error message */ - i = ssl2_read(s, (char *)&(p[s->init_num]), 3 - s->init_num); - return ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i); - } - return (-1); - } - s->state = SSL2_ST_GET_SERVER_FINISHED_B; - } - - len = 1 + SSL2_SSL_SESSION_ID_LENGTH; - n = len - s->init_num; - i = ssl2_read(s, (char *)&(buf[s->init_num]), n); - if (i < n) { - /* - * XXX could be shorter than SSL2_SSL_SESSION_ID_LENGTH, - * that's the maximum - */ - return (ssl2_part_read(s, SSL_F_GET_SERVER_FINISHED, i)); - } - s->init_num += i; - if (s->msg_callback) { - /* SERVER-FINISHED */ - s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, - s->msg_callback_arg); - } - - if (!s->hit) { /* new session */ - /* new session-id */ - /* - * Make sure we were not trying to re-use an old SSL_SESSION or bad - * things can happen - */ - /* ZZZZZZZZZZZZZ */ - s->session->session_id_length = SSL2_SSL_SESSION_ID_LENGTH; - memcpy(s->session->session_id, p + 1, SSL2_SSL_SESSION_ID_LENGTH); - } else { - if (!(s->options & SSL_OP_MICROSOFT_SESS_ID_BUG)) { - if ((s->session->session_id_length > - sizeof s->session->session_id) - || (0 != - memcmp(buf + 1, s->session->session_id, - (unsigned int)s->session->session_id_length))) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_FINISHED, - SSL_R_SSL_SESSION_ID_IS_DIFFERENT); - return (-1); - } - } - } - s->state = SSL_ST_OK; - return (1); -} - -/* loads in the certificate from the server */ -int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data) -{ - STACK_OF(X509) *sk = NULL; - EVP_PKEY *pkey = NULL; - SESS_CERT *sc = NULL; - int i; - X509 *x509 = NULL; - int ret = 0; - - x509 = d2i_X509(NULL, &data, (long)len); - if (x509 == NULL) { - SSLerr(SSL_F_SSL2_SET_CERTIFICATE, ERR_R_X509_LIB); - goto err; - } - - if ((sk = sk_X509_new_null()) == NULL || !sk_X509_push(sk, x509)) { - SSLerr(SSL_F_SSL2_SET_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - - i = ssl_verify_cert_chain(s, sk); - - if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)) { - SSLerr(SSL_F_SSL2_SET_CERTIFICATE, SSL_R_CERTIFICATE_VERIFY_FAILED); - goto err; - } - ERR_clear_error(); /* but we keep s->verify_result */ - s->session->verify_result = s->verify_result; - - /* server's cert for this session */ - sc = ssl_sess_cert_new(); - if (sc == NULL) { - ret = -1; - goto err; - } - if (s->session->sess_cert) - ssl_sess_cert_free(s->session->sess_cert); - s->session->sess_cert = sc; - - sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509 = x509; - sc->peer_key = &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]); - - pkey = X509_get_pubkey(x509); - x509 = NULL; - if (pkey == NULL) { - SSLerr(SSL_F_SSL2_SET_CERTIFICATE, - SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY); - goto err; - } - if (pkey->type != EVP_PKEY_RSA) { - SSLerr(SSL_F_SSL2_SET_CERTIFICATE, SSL_R_PUBLIC_KEY_NOT_RSA); - goto err; - } - - if (!ssl_set_peer_cert_type(sc, SSL2_CT_X509_CERTIFICATE)) - goto err; - ret = 1; - err: - sk_X509_free(sk); - X509_free(x509); - EVP_PKEY_free(pkey); - return (ret); -} - -static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from, - unsigned char *to, int padding) -{ - EVP_PKEY *pkey = NULL; - int i = -1; - - if ((sc == NULL) || (sc->peer_key->x509 == NULL) || - ((pkey = X509_get_pubkey(sc->peer_key->x509)) == NULL)) { - SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, SSL_R_NO_PUBLICKEY); - return (-1); - } - if (pkey->type != EVP_PKEY_RSA) { - SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, SSL_R_PUBLIC_KEY_IS_NOT_RSA); - goto end; - } - - /* we have the public key */ - i = RSA_public_encrypt(len, from, to, pkey->pkey.rsa, padding); - if (i < 0) - SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, ERR_R_RSA_LIB); - end: - EVP_PKEY_free(pkey); - return (i); -} -#else /* !OPENSSL_NO_SSL2 */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif diff --git a/thirdparty/openssl/ssl/s2_enc.c b/thirdparty/openssl/ssl/s2_enc.c deleted file mode 100644 index 23eef72aa4..0000000000 --- a/thirdparty/openssl/ssl/s2_enc.c +++ /dev/null @@ -1,197 +0,0 @@ -/* ssl/s2_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "ssl_locl.h" -#ifndef OPENSSL_NO_SSL2 -# include <stdio.h> - -int ssl2_enc_init(SSL *s, int client) -{ - /* Max number of bytes needed */ - EVP_CIPHER_CTX *rs, *ws; - const EVP_CIPHER *c; - const EVP_MD *md; - int num; - - if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_SSL2_ENC_INIT, SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); - return (0); - } - ssl_replace_hash(&s->read_hash, md); - ssl_replace_hash(&s->write_hash, md); - - if ((s->enc_read_ctx == NULL) && ((s->enc_read_ctx = (EVP_CIPHER_CTX *) - OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) - == NULL)) - goto err; - - /* - * make sure it's intialized in case the malloc for enc_write_ctx fails - * and we exit with an error - */ - rs = s->enc_read_ctx; - EVP_CIPHER_CTX_init(rs); - - if ((s->enc_write_ctx == NULL) && ((s->enc_write_ctx = (EVP_CIPHER_CTX *) - OPENSSL_malloc(sizeof - (EVP_CIPHER_CTX))) == - NULL)) - goto err; - - ws = s->enc_write_ctx; - EVP_CIPHER_CTX_init(ws); - - num = c->key_len; - s->s2->key_material_length = num * 2; - OPENSSL_assert(s->s2->key_material_length <= sizeof s->s2->key_material); - - if (ssl2_generate_key_material(s) <= 0) - return 0; - - OPENSSL_assert(c->iv_len <= (int)sizeof(s->session->key_arg)); - EVP_EncryptInit_ex(ws, c, NULL, - &(s->s2->key_material[(client) ? num : 0]), - s->session->key_arg); - EVP_DecryptInit_ex(rs, c, NULL, - &(s->s2->key_material[(client) ? 0 : num]), - s->session->key_arg); - s->s2->read_key = &(s->s2->key_material[(client) ? 0 : num]); - s->s2->write_key = &(s->s2->key_material[(client) ? num : 0]); - return (1); - err: - SSLerr(SSL_F_SSL2_ENC_INIT, ERR_R_MALLOC_FAILURE); - return (0); -} - -/* - * read/writes from s->s2->mac_data using length for encrypt and decrypt. - * It sets s->s2->padding and s->[rw]length if we are encrypting Returns 0 on - * error and 1 on success - */ -int ssl2_enc(SSL *s, int send) -{ - EVP_CIPHER_CTX *ds; - unsigned long l; - int bs; - - if (send) { - ds = s->enc_write_ctx; - l = s->s2->wlength; - } else { - ds = s->enc_read_ctx; - l = s->s2->rlength; - } - - /* check for NULL cipher */ - if (ds == NULL) - return 1; - - bs = ds->cipher->block_size; - /* - * This should be using (bs-1) and bs instead of 7 and 8, but what the - * hell. - */ - if (bs == 8) - l = (l + 7) / 8 * 8; - - if (EVP_Cipher(ds, s->s2->mac_data, s->s2->mac_data, l) < 1) - return 0; - - return 1; -} - -void ssl2_mac(SSL *s, unsigned char *md, int send) -{ - EVP_MD_CTX c; - unsigned char sequence[4], *p, *sec, *act; - unsigned long seq; - unsigned int len; - - if (send) { - seq = s->s2->write_sequence; - sec = s->s2->write_key; - len = s->s2->wact_data_length; - act = s->s2->wact_data; - } else { - seq = s->s2->read_sequence; - sec = s->s2->read_key; - len = s->s2->ract_data_length; - act = s->s2->ract_data; - } - - p = &(sequence[0]); - l2n(seq, p); - - /* There has to be a MAC algorithm. */ - EVP_MD_CTX_init(&c); - EVP_MD_CTX_copy(&c, s->read_hash); - EVP_DigestUpdate(&c, sec, EVP_CIPHER_CTX_key_length(s->enc_read_ctx)); - EVP_DigestUpdate(&c, act, len); - /* the above line also does the pad data */ - EVP_DigestUpdate(&c, sequence, 4); - EVP_DigestFinal_ex(&c, md, NULL); - EVP_MD_CTX_cleanup(&c); -} -#else /* !OPENSSL_NO_SSL2 */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif diff --git a/thirdparty/openssl/ssl/s2_lib.c b/thirdparty/openssl/ssl/s2_lib.c deleted file mode 100644 index cc1360307b..0000000000 --- a/thirdparty/openssl/ssl/s2_lib.c +++ /dev/null @@ -1,570 +0,0 @@ -/* ssl/s2_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 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 - * openssl-core@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). - * - */ - -#include "ssl_locl.h" -#ifndef OPENSSL_NO_SSL2 -# include <stdio.h> -# include <openssl/objects.h> -# include <openssl/evp.h> -# include <openssl/md5.h> - -const char ssl2_version_str[] = "SSLv2" OPENSSL_VERSION_PTEXT; - -# define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER)) - -/* list of available SSLv2 ciphers (sorted by id) */ -OPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[] = { -# if 0 -/* NULL_WITH_MD5 v3 */ - { - 1, - SSL2_TXT_NULL_WITH_MD5, - SSL2_CK_NULL_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_eNULL, - SSL_MD5, - SSL_SSLV2, - SSL_EXPORT | SSL_EXP40 | SSL_STRONG_NONE, - 0, - 0, - 0, - }, -# endif - -/* RC4_128_WITH_MD5 */ - { - 1, - SSL2_TXT_RC4_128_WITH_MD5, - SSL2_CK_RC4_128_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - 0, - 128, - 128, - }, - -# if 0 -/* RC4_128_EXPORT40_WITH_MD5 */ - { - 1, - SSL2_TXT_RC4_128_EXPORT40_WITH_MD5, - SSL2_CK_RC4_128_EXPORT40_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL2_CF_5_BYTE_ENC, - 40, - 128, - }, -# endif - -/* RC2_128_CBC_WITH_MD5 */ - { - 1, - SSL2_TXT_RC2_128_CBC_WITH_MD5, - SSL2_CK_RC2_128_CBC_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC2, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - 0, - 128, - 128, - }, - -# if 0 -/* RC2_128_CBC_EXPORT40_WITH_MD5 */ - { - 1, - SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5, - SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC2, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL2_CF_5_BYTE_ENC, - 40, - 128, - }, -# endif - -# ifndef OPENSSL_NO_IDEA -/* IDEA_128_CBC_WITH_MD5 */ - { - 1, - SSL2_TXT_IDEA_128_CBC_WITH_MD5, - SSL2_CK_IDEA_128_CBC_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_IDEA, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - 0, - 128, - 128, - }, -# endif - -# if 0 -/* DES_64_CBC_WITH_MD5 */ - { - 1, - SSL2_TXT_DES_64_CBC_WITH_MD5, - SSL2_CK_DES_64_CBC_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_DES, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - 0, - 56, - 56, - }, -# endif - -/* DES_192_EDE3_CBC_WITH_MD5 */ - { - 1, - SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5, - SSL2_CK_DES_192_EDE3_CBC_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_3DES, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - 0, - 112, - 168, - }, - -# if 0 -/* RC4_64_WITH_MD5 */ - { - 1, - SSL2_TXT_RC4_64_WITH_MD5, - SSL2_CK_RC4_64_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL2_CF_8_BYTE_ENC, - 64, - 64, - }, -# endif - -# if 0 -/* NULL SSLeay (testing) */ - { - 0, - SSL2_TXT_NULL, - SSL2_CK_NULL, - 0, - 0, - 0, - 0, - SSL_SSLV2, - SSL_STRONG_NONE, - 0, - 0, - 0, - }, -# endif - -/* end of list :-) */ -}; - -long ssl2_default_timeout(void) -{ - return (300); -} - -int ssl2_num_ciphers(void) -{ - return (SSL2_NUM_CIPHERS); -} - -const SSL_CIPHER *ssl2_get_cipher(unsigned int u) -{ - if (u < SSL2_NUM_CIPHERS) - return (&(ssl2_ciphers[SSL2_NUM_CIPHERS - 1 - u])); - else - return (NULL); -} - -int ssl2_pending(const SSL *s) -{ - return SSL_in_init(s) ? 0 : s->s2->ract_data_length; -} - -int ssl2_new(SSL *s) -{ - SSL2_STATE *s2; - - if ((s2 = OPENSSL_malloc(sizeof *s2)) == NULL) - goto err; - memset(s2, 0, sizeof *s2); - -# if SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER + 3 > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2 -# error "assertion failed" -# endif - - if ((s2->rbuf = - OPENSSL_malloc(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2)) == NULL) - goto err; - /* - * wbuf needs one byte more because when using two-byte headers, we leave - * the first byte unused in do_ssl_write (s2_pkt.c) - */ - if ((s2->wbuf = - OPENSSL_malloc(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 3)) == NULL) - goto err; - s->s2 = s2; - - ssl2_clear(s); - return (1); - err: - if (s2 != NULL) { - if (s2->wbuf != NULL) - OPENSSL_free(s2->wbuf); - if (s2->rbuf != NULL) - OPENSSL_free(s2->rbuf); - OPENSSL_free(s2); - } - return (0); -} - -void ssl2_free(SSL *s) -{ - SSL2_STATE *s2; - - if (s == NULL) - return; - - s2 = s->s2; - if (s2->rbuf != NULL) - OPENSSL_free(s2->rbuf); - if (s2->wbuf != NULL) - OPENSSL_free(s2->wbuf); - OPENSSL_cleanse(s2, sizeof *s2); - OPENSSL_free(s2); - s->s2 = NULL; -} - -void ssl2_clear(SSL *s) -{ - SSL2_STATE *s2; - unsigned char *rbuf, *wbuf; - - s2 = s->s2; - - rbuf = s2->rbuf; - wbuf = s2->wbuf; - - memset(s2, 0, sizeof *s2); - - s2->rbuf = rbuf; - s2->wbuf = wbuf; - s2->clear_text = 1; - s->packet = s2->rbuf; - s->version = SSL2_VERSION; - s->packet_length = 0; -} - -long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg) -{ - int ret = 0; - - switch (cmd) { - case SSL_CTRL_GET_SESSION_REUSED: - ret = s->hit; - break; - case SSL_CTRL_CHECK_PROTO_VERSION: - return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg); - default: - break; - } - return (ret); -} - -long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) -{ - return (0); -} - -long ssl2_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) -{ - return (0); -} - -long ssl2_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) -{ - return (0); -} - -/* - * This function needs to check if the ciphers required are actually - * available - */ -const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p) -{ - SSL_CIPHER c; - const SSL_CIPHER *cp; - unsigned long id; - - id = 0x02000000L | ((unsigned long)p[0] << 16L) | - ((unsigned long)p[1] << 8L) | (unsigned long)p[2]; - c.id = id; - cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS); - return cp; -} - -int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) -{ - long l; - - if (p != NULL) { - l = c->id; - if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) - return (0); - p[0] = ((unsigned char)(l >> 16L)) & 0xFF; - p[1] = ((unsigned char)(l >> 8L)) & 0xFF; - p[2] = ((unsigned char)(l)) & 0xFF; - } - return (3); -} - -int ssl2_generate_key_material(SSL *s) -{ - unsigned int i; - EVP_MD_CTX ctx; - unsigned char *km; - unsigned char c = '0'; - const EVP_MD *md5; - int md_size; - - md5 = EVP_md5(); - -# ifdef CHARSET_EBCDIC - c = os_toascii['0']; /* Must be an ASCII '0', not EBCDIC '0', see - * SSLv2 docu */ -# endif - EVP_MD_CTX_init(&ctx); - km = s->s2->key_material; - - if (s->session->master_key_length < 0 || - s->session->master_key_length > (int)sizeof(s->session->master_key)) { - SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR); - return 0; - } - md_size = EVP_MD_size(md5); - if (md_size < 0) - return 0; - for (i = 0; i < s->s2->key_material_length; i += md_size) { - if (((km - s->s2->key_material) + md_size) > - (int)sizeof(s->s2->key_material)) { - /* - * EVP_DigestFinal_ex() below would write beyond buffer - */ - SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR); - return 0; - } - - EVP_DigestInit_ex(&ctx, md5, NULL); - - OPENSSL_assert(s->session->master_key_length >= 0 - && s->session->master_key_length - <= (int)sizeof(s->session->master_key)); - EVP_DigestUpdate(&ctx, s->session->master_key, - s->session->master_key_length); - EVP_DigestUpdate(&ctx, &c, 1); - c++; - EVP_DigestUpdate(&ctx, s->s2->challenge, s->s2->challenge_length); - EVP_DigestUpdate(&ctx, s->s2->conn_id, s->s2->conn_id_length); - EVP_DigestFinal_ex(&ctx, km, NULL); - km += md_size; - } - - EVP_MD_CTX_cleanup(&ctx); - return 1; -} - -void ssl2_return_error(SSL *s, int err) -{ - if (!s->error) { - s->error = 3; - s->error_code = err; - - ssl2_write_error(s); - } -} - -void ssl2_write_error(SSL *s) -{ - unsigned char buf[3]; - int i, error; - - buf[0] = SSL2_MT_ERROR; - buf[1] = (s->error_code >> 8) & 0xff; - buf[2] = (s->error_code) & 0xff; - -/* state=s->rwstate;*/ - - error = s->error; /* number of bytes left to write */ - s->error = 0; - OPENSSL_assert(error >= 0 && error <= (int)sizeof(buf)); - i = ssl2_write(s, &(buf[3 - error]), error); - -/* if (i == error) s->rwstate=state; */ - - if (i < 0) - s->error = error; - else { - s->error = error - i; - - if (s->error == 0) - if (s->msg_callback) { - /* ERROR */ - s->msg_callback(1, s->version, 0, buf, 3, s, - s->msg_callback_arg); - } - } -} - -int ssl2_shutdown(SSL *s) -{ - s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); - return (1); -} -#else /* !OPENSSL_NO_SSL2 */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif diff --git a/thirdparty/openssl/ssl/s2_meth.c b/thirdparty/openssl/ssl/s2_meth.c deleted file mode 100644 index 73885b7ecf..0000000000 --- a/thirdparty/openssl/ssl/s2_meth.c +++ /dev/null @@ -1,91 +0,0 @@ -/* ssl/s2_meth.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "ssl_locl.h" -#ifndef OPENSSL_NO_SSL2_METHOD -# ifndef OPENSSL_NO_SSL2 -# include <stdio.h> -# include <openssl/objects.h> - -static const SSL_METHOD *ssl2_get_method(int ver); -static const SSL_METHOD *ssl2_get_method(int ver) -{ - if (ver == SSL2_VERSION) - return (SSLv2_method()); - else - return (NULL); -} - -IMPLEMENT_ssl2_meth_func(SSLv2_method, - ssl2_accept, ssl2_connect, ssl2_get_method) - -# else /* !OPENSSL_NO_SSL2 */ - -const SSL_METHOD *SSLv2_method(void) { return NULL; } -const SSL_METHOD *SSLv2_client_method(void) { return NULL; } -const SSL_METHOD *SSLv2_server_method(void) { return NULL; } - -# endif - -#else /* !OPENSSL_NO_SSL2_METHOD */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif diff --git a/thirdparty/openssl/ssl/s2_pkt.c b/thirdparty/openssl/ssl/s2_pkt.c deleted file mode 100644 index e44bc0335a..0000000000 --- a/thirdparty/openssl/ssl/s2_pkt.c +++ /dev/null @@ -1,731 +0,0 @@ -/* ssl/s2_pkt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2001 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 - * openssl-core@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). - * - */ - -#include "ssl_locl.h" -#ifndef OPENSSL_NO_SSL2 -# include <stdio.h> -# include <errno.h> -# define USE_SOCKETS - -static int read_n(SSL *s, unsigned int n, unsigned int max, - unsigned int extend); -static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len); -static int write_pending(SSL *s, const unsigned char *buf, unsigned int len); -static int ssl_mt_error(int n); - -/* - * SSL 2.0 imlementation for SSL_read/SSL_peek - This routine will return 0 - * to len bytes, decrypted etc if required. - */ -static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) -{ - int n; - unsigned char mac[MAX_MAC_SIZE]; - unsigned char *p; - int i; - int mac_size; - - ssl2_read_again: - if (SSL_in_init(s) && !s->in_handshake) { - n = s->handshake_func(s); - if (n < 0) - return (n); - if (n == 0) { - SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - } - - clear_sys_error(); - s->rwstate = SSL_NOTHING; - if (len <= 0) - return (len); - - if (s->s2->ract_data_length != 0) { /* read from buffer */ - if (len > s->s2->ract_data_length) - n = s->s2->ract_data_length; - else - n = len; - - memcpy(buf, s->s2->ract_data, (unsigned int)n); - if (!peek) { - s->s2->ract_data_length -= n; - s->s2->ract_data += n; - if (s->s2->ract_data_length == 0) - s->rstate = SSL_ST_READ_HEADER; - } - - return (n); - } - - /* - * s->s2->ract_data_length == 0 Fill the buffer, then goto - * ssl2_read_again. - */ - - if (s->rstate == SSL_ST_READ_HEADER) { - if (s->first_packet) { - n = read_n(s, 5, SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2, 0); - if (n <= 0) - return (n); /* error or non-blocking */ - s->first_packet = 0; - p = s->packet; - if (!((p[0] & 0x80) && ((p[2] == SSL2_MT_CLIENT_HELLO) || - (p[2] == SSL2_MT_SERVER_HELLO)))) { - SSLerr(SSL_F_SSL2_READ_INTERNAL, - SSL_R_NON_SSLV2_INITIAL_PACKET); - return (-1); - } - } else { - n = read_n(s, 2, SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2, 0); - if (n <= 0) - return (n); /* error or non-blocking */ - } - /* part read stuff */ - - s->rstate = SSL_ST_READ_BODY; - p = s->packet; - /* Do header */ - /* - * s->s2->padding=0; - */ - s->s2->escape = 0; - s->s2->rlength = (((unsigned int)p[0]) << 8) | ((unsigned int)p[1]); - if ((p[0] & TWO_BYTE_BIT)) { /* Two byte header? */ - s->s2->three_byte_header = 0; - s->s2->rlength &= TWO_BYTE_MASK; - } else { - s->s2->three_byte_header = 1; - s->s2->rlength &= THREE_BYTE_MASK; - - /* security >s2->escape */ - s->s2->escape = ((p[0] & SEC_ESC_BIT)) ? 1 : 0; - } - } - - if (s->rstate == SSL_ST_READ_BODY) { - n = s->s2->rlength + 2 + s->s2->three_byte_header; - if (n > (int)s->packet_length) { - n -= s->packet_length; - i = read_n(s, (unsigned int)n, (unsigned int)n, 1); - if (i <= 0) - return (i); /* ERROR */ - } - - p = &(s->packet[2]); - s->rstate = SSL_ST_READ_HEADER; - if (s->s2->three_byte_header) - s->s2->padding = *(p++); - else - s->s2->padding = 0; - - /* Data portion */ - if (s->s2->clear_text) { - mac_size = 0; - s->s2->mac_data = p; - s->s2->ract_data = p; - if (s->s2->padding) { - SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_ILLEGAL_PADDING); - return (-1); - } - } else { - mac_size = EVP_MD_CTX_size(s->read_hash); - if (mac_size < 0) - return -1; - OPENSSL_assert(mac_size <= MAX_MAC_SIZE); - s->s2->mac_data = p; - s->s2->ract_data = &p[mac_size]; - if (s->s2->padding + mac_size > s->s2->rlength) { - SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_ILLEGAL_PADDING); - return (-1); - } - } - - s->s2->ract_data_length = s->s2->rlength; - /* - * added a check for length > max_size in case encryption was not - * turned on yet due to an error - */ - if ((!s->s2->clear_text) && - (s->s2->rlength >= (unsigned int)mac_size)) { - if (!ssl2_enc(s, 0)) { - SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_DECRYPTION_FAILED); - return (-1); - } - s->s2->ract_data_length -= mac_size; - ssl2_mac(s, mac, 0); - s->s2->ract_data_length -= s->s2->padding; - if ((CRYPTO_memcmp(mac, s->s2->mac_data, mac_size) != 0) || - (s->s2->rlength % - EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0)) { - SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_BAD_MAC_DECODE); - return (-1); - } - } - INC32(s->s2->read_sequence); /* expect next number */ - /* s->s2->ract_data is now available for processing */ - - /* - * Possibly the packet that we just read had 0 actual data bytes. - * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.) - * In this case, returning 0 would be interpreted by the caller as - * indicating EOF, so it's not a good idea. Instead, we just - * continue reading; thus ssl2_read_internal may have to process - * multiple packets before it can return. [Note that using select() - * for blocking sockets *never* guarantees that the next SSL_read - * will not block -- the available data may contain incomplete - * packets, and except for SSL 2, renegotiation can confuse things - * even more.] - */ - - goto ssl2_read_again; /* This should really be "return - * ssl2_read(s,buf,len)", but that would - * allow for denial-of-service attacks if a C - * compiler is used that does not recognize - * end-recursion. */ - } else { - SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_BAD_STATE); - return (-1); - } -} - -int ssl2_read(SSL *s, void *buf, int len) -{ - return ssl2_read_internal(s, buf, len, 0); -} - -int ssl2_peek(SSL *s, void *buf, int len) -{ - return ssl2_read_internal(s, buf, len, 1); -} - -/* - * Return values are as per SSL_read() - */ -static int read_n(SSL *s, unsigned int n, unsigned int max, - unsigned int extend) -{ - int i, off, newb; - - /* - * if there is stuff still in the buffer from a previous read, and there - * is more than we want, take some. - */ - if (s->s2->rbuf_left >= (int)n) { - if (extend) - s->packet_length += n; - else { - s->packet = &(s->s2->rbuf[s->s2->rbuf_offs]); - s->packet_length = n; - } - s->s2->rbuf_left -= n; - s->s2->rbuf_offs += n; - return (n); - } - - if (!s->read_ahead) - max = n; - if (max > (unsigned int)(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2)) - max = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2; - - /* - * Else we want more than we have. First, if there is some left or we - * want to extend - */ - off = 0; - if ((s->s2->rbuf_left != 0) || ((s->packet_length != 0) && extend)) { - newb = s->s2->rbuf_left; - if (extend) { - off = s->packet_length; - if (s->packet != s->s2->rbuf) - memcpy(s->s2->rbuf, s->packet, (unsigned int)newb + off); - } else if (s->s2->rbuf_offs != 0) { - memcpy(s->s2->rbuf, &(s->s2->rbuf[s->s2->rbuf_offs]), - (unsigned int)newb); - s->s2->rbuf_offs = 0; - } - s->s2->rbuf_left = 0; - } else - newb = 0; - - /* - * off is the offset to start writing too. r->s2->rbuf_offs is the - * 'unread data', now 0. newb is the number of new bytes so far - */ - s->packet = s->s2->rbuf; - while (newb < (int)n) { - clear_sys_error(); - if (s->rbio != NULL) { - s->rwstate = SSL_READING; - i = BIO_read(s->rbio, (char *)&(s->s2->rbuf[off + newb]), - max - newb); - } else { - SSLerr(SSL_F_READ_N, SSL_R_READ_BIO_NOT_SET); - i = -1; - } -# ifdef PKT_DEBUG - if (s->debug & 0x01) - sleep(1); -# endif - if (i <= 0) { - s->s2->rbuf_left += newb; - return i; - } - newb += i; - } - - /* record unread data */ - if (newb > (int)n) { - s->s2->rbuf_offs = n + off; - s->s2->rbuf_left = newb - n; - } else { - s->s2->rbuf_offs = 0; - s->s2->rbuf_left = 0; - } - if (extend) - s->packet_length += n; - else - s->packet_length = n; - s->rwstate = SSL_NOTHING; - return (n); -} - -int ssl2_write(SSL *s, const void *_buf, int len) -{ - const unsigned char *buf = _buf; - unsigned int n, tot; - int i; - - if (SSL_in_init(s) && !s->in_handshake) { - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_SSL2_WRITE, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - } - - if (s->error) { - ssl2_write_error(s); - if (s->error) - return (-1); - } - - clear_sys_error(); - s->rwstate = SSL_NOTHING; - if (len <= 0) - return (len); - - tot = s->s2->wnum; - s->s2->wnum = 0; - - n = (len - tot); - for (;;) { - i = n_do_ssl_write(s, &(buf[tot]), n); - if (i <= 0) { - s->s2->wnum = tot; - return (i); - } - if ((i == (int)n) || (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { - return (tot + i); - } - - n -= i; - tot += i; - } -} - -/* - * Return values are as per SSL_write() - */ -static int write_pending(SSL *s, const unsigned char *buf, unsigned int len) -{ - int i; - - /* s->s2->wpend_len != 0 MUST be true. */ - - /* - * check that they have given us the same buffer to write - */ - if ((s->s2->wpend_tot > (int)len) || - ((s->s2->wpend_buf != buf) && - !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))) { - SSLerr(SSL_F_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY); - return (-1); - } - - for (;;) { - clear_sys_error(); - if (s->wbio != NULL) { - s->rwstate = SSL_WRITING; - i = BIO_write(s->wbio, - (char *)&(s->s2->write_ptr[s->s2->wpend_off]), - (unsigned int)s->s2->wpend_len); - } else { - SSLerr(SSL_F_WRITE_PENDING, SSL_R_WRITE_BIO_NOT_SET); - i = -1; - } -# ifdef PKT_DEBUG - if (s->debug & 0x01) - sleep(1); -# endif - if (i == s->s2->wpend_len) { - s->s2->wpend_len = 0; - s->rwstate = SSL_NOTHING; - return (s->s2->wpend_ret); - } else if (i <= 0) - return i; - s->s2->wpend_off += i; - s->s2->wpend_len -= i; - } -} - -static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) -{ - unsigned int j, k, olen, p, bs; - int mac_size; - register unsigned char *pp; - - olen = len; - - /* - * first check if there is data from an encryption waiting to be sent - - * it must be sent because the other end is waiting. This will happen - * with non-blocking IO. We print it and then return. - */ - if (s->s2->wpend_len != 0) - return (write_pending(s, buf, len)); - - /* set mac_size to mac size */ - if (s->s2->clear_text) - mac_size = 0; - else { - mac_size = EVP_MD_CTX_size(s->write_hash); - if (mac_size < 0) - return -1; - } - - /* lets set the pad p */ - if (s->s2->clear_text) { - if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) - len = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER; - p = 0; - s->s2->three_byte_header = 0; - /* len=len; */ - } else { - bs = EVP_CIPHER_CTX_block_size(s->enc_read_ctx); - j = len + mac_size; - /* - * Two-byte headers allow for a larger record length than three-byte - * headers, but we can't use them if we need padding or if we have to - * set the escape bit. - */ - if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) && (!s->s2->escape)) { - if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) - j = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER; - /* - * set k to the max number of bytes with 2 byte header - */ - k = j - (j % bs); - /* how many data bytes? */ - len = k - mac_size; - s->s2->three_byte_header = 0; - p = 0; - } else if ((bs <= 1) && (!s->s2->escape)) { - /*- - * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, thus - * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER - */ - s->s2->three_byte_header = 0; - p = 0; - } else { /* we may have to use a 3 byte header */ - - /*- - * If s->s2->escape is not set, then - * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, and thus - * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER. - */ - p = (j % bs); - p = (p == 0) ? 0 : (bs - p); - if (s->s2->escape) { - s->s2->three_byte_header = 1; - if (j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) - j = SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER; - } else - s->s2->three_byte_header = (p == 0) ? 0 : 1; - } - } - - /*- - * Now - * j <= SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER - * holds, and if s->s2->three_byte_header is set, then even - * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER. - */ - - /* - * mac_size is the number of MAC bytes len is the number of data bytes we - * are going to send p is the number of padding bytes (if it is a - * two-byte header, then p == 0) - */ - - s->s2->wlength = len; - s->s2->padding = p; - s->s2->mac_data = &(s->s2->wbuf[3]); - s->s2->wact_data = &(s->s2->wbuf[3 + mac_size]); - - /* - * It would be clearer to write this as follows: - * if (mac_size + len + p > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) - * However |len| is user input that could in theory be very large. We - * know |mac_size| and |p| are small, so to avoid any possibility of - * overflow we write it like this. - * - * In theory this should never fail because the logic above should have - * modified |len| if it is too big. But we are being cautious. - */ - if (len > (SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER - (mac_size + p))) { - return -1; - } - /* we copy the data into s->s2->wbuf */ - memcpy(s->s2->wact_data, buf, len); - if (p) - memset(&(s->s2->wact_data[len]), 0, p); /* arbitrary padding */ - - if (!s->s2->clear_text) { - s->s2->wact_data_length = len + p; - ssl2_mac(s, s->s2->mac_data, 1); - s->s2->wlength += p + mac_size; - if (ssl2_enc(s, 1) < 1) - return -1; - } - - /* package up the header */ - s->s2->wpend_len = s->s2->wlength; - if (s->s2->three_byte_header) { /* 3 byte header */ - pp = s->s2->mac_data; - pp -= 3; - pp[0] = (s->s2->wlength >> 8) & (THREE_BYTE_MASK >> 8); - if (s->s2->escape) - pp[0] |= SEC_ESC_BIT; - pp[1] = s->s2->wlength & 0xff; - pp[2] = s->s2->padding; - s->s2->wpend_len += 3; - } else { - pp = s->s2->mac_data; - pp -= 2; - pp[0] = ((s->s2->wlength >> 8) & (TWO_BYTE_MASK >> 8)) | TWO_BYTE_BIT; - pp[1] = s->s2->wlength & 0xff; - s->s2->wpend_len += 2; - } - s->s2->write_ptr = pp; - - INC32(s->s2->write_sequence); /* expect next number */ - - /* lets try to actually write the data */ - s->s2->wpend_tot = olen; - s->s2->wpend_buf = buf; - - s->s2->wpend_ret = len; - - s->s2->wpend_off = 0; - return (write_pending(s, buf, olen)); -} - -int ssl2_part_read(SSL *s, unsigned long f, int i) -{ - unsigned char *p; - int j; - - if (i < 0) { - /* ssl2_return_error(s); */ - /* - * for non-blocking io, this is not necessarily fatal - */ - return (i); - } else { - s->init_num += i; - - /* - * Check for error. While there are recoverable errors, this - * function is not called when those must be expected; any error - * detected here is fatal. - */ - if (s->init_num >= 3) { - p = (unsigned char *)s->init_buf->data; - if (p[0] == SSL2_MT_ERROR) { - j = (p[1] << 8) | p[2]; - SSLerr((int)f, ssl_mt_error(j)); - s->init_num -= 3; - if (s->init_num > 0) - memmove(p, p + 3, s->init_num); - } - } - - /* - * If it's not an error message, we have some error anyway -- the - * message was shorter than expected. This too is treated as fatal - * (at least if SSL_get_error is asked for its opinion). - */ - return (0); - } -} - -int ssl2_do_write(SSL *s) -{ - int ret; - - ret = ssl2_write(s, &s->init_buf->data[s->init_off], s->init_num); - if (ret == s->init_num) { - if (s->msg_callback) - s->msg_callback(1, s->version, 0, s->init_buf->data, - (size_t)(s->init_off + s->init_num), s, - s->msg_callback_arg); - return (1); - } - if (ret < 0) - return (-1); - s->init_off += ret; - s->init_num -= ret; - return (0); -} - -static int ssl_mt_error(int n) -{ - int ret; - - switch (n) { - case SSL2_PE_NO_CIPHER: - ret = SSL_R_PEER_ERROR_NO_CIPHER; - break; - case SSL2_PE_NO_CERTIFICATE: - ret = SSL_R_PEER_ERROR_NO_CERTIFICATE; - break; - case SSL2_PE_BAD_CERTIFICATE: - ret = SSL_R_PEER_ERROR_CERTIFICATE; - break; - case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE: - ret = SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE; - break; - default: - ret = SSL_R_UNKNOWN_REMOTE_ERROR_TYPE; - break; - } - return (ret); -} -#else /* !OPENSSL_NO_SSL2 */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif diff --git a/thirdparty/openssl/ssl/s2_srvr.c b/thirdparty/openssl/ssl/s2_srvr.c deleted file mode 100644 index d3b243c27e..0000000000 --- a/thirdparty/openssl/ssl/s2_srvr.c +++ /dev/null @@ -1,1167 +0,0 @@ -/* ssl/s2_srvr.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2001 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 - * openssl-core@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). - * - */ - -#include "ssl_locl.h" -#ifndef OPENSSL_NO_SSL2 -#include "../crypto/constant_time_locl.h" -# include <stdio.h> -# include <openssl/bio.h> -# include <openssl/rand.h> -# include <openssl/objects.h> -# include <openssl/evp.h> - -static const SSL_METHOD *ssl2_get_server_method(int ver); -static int get_client_master_key(SSL *s); -static int get_client_hello(SSL *s); -static int server_hello(SSL *s); -static int get_client_finished(SSL *s); -static int server_verify(SSL *s); -static int server_finish(SSL *s); -static int request_certificate(SSL *s); -static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from, - unsigned char *to, int padding); -# define BREAK break - -static const SSL_METHOD *ssl2_get_server_method(int ver) -{ - if (ver == SSL2_VERSION) - return (SSLv2_server_method()); - else - return (NULL); -} - -IMPLEMENT_ssl2_meth_func(SSLv2_server_method, - ssl2_accept, - ssl_undefined_function, ssl2_get_server_method) - -int ssl2_accept(SSL *s) -{ - unsigned long l = (unsigned long)time(NULL); - BUF_MEM *buf = NULL; - int ret = -1; - long num1; - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int new_state, state; - - RAND_add(&l, sizeof(l), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - /* init things to blank */ - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - if (s->cert == NULL) { - SSLerr(SSL_F_SSL2_ACCEPT, SSL_R_NO_CERTIFICATE_SET); - return (-1); - } - - clear_sys_error(); - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_BEFORE: - case SSL_ST_ACCEPT: - case SSL_ST_BEFORE | SSL_ST_ACCEPT: - case SSL_ST_OK | SSL_ST_ACCEPT: - - s->server = 1; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - s->version = SSL2_VERSION; - s->type = SSL_ST_ACCEPT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - goto end; - } - if (!BUF_MEM_grow - (buf, (int)SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { - BUF_MEM_free(buf); - ret = -1; - goto end; - } - s->init_buf = buf; - } - s->init_num = 0; - s->ctx->stats.sess_accept++; - s->handshake_func = ssl2_accept; - s->state = SSL2_ST_GET_CLIENT_HELLO_A; - BREAK; - - case SSL2_ST_GET_CLIENT_HELLO_A: - case SSL2_ST_GET_CLIENT_HELLO_B: - case SSL2_ST_GET_CLIENT_HELLO_C: - s->shutdown = 0; - ret = get_client_hello(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_SEND_SERVER_HELLO_A; - BREAK; - - case SSL2_ST_SEND_SERVER_HELLO_A: - case SSL2_ST_SEND_SERVER_HELLO_B: - ret = server_hello(s); - if (ret <= 0) - goto end; - s->init_num = 0; - if (!s->hit) { - s->state = SSL2_ST_GET_CLIENT_MASTER_KEY_A; - BREAK; - } else { - s->state = SSL2_ST_SERVER_START_ENCRYPTION; - BREAK; - } - case SSL2_ST_GET_CLIENT_MASTER_KEY_A: - case SSL2_ST_GET_CLIENT_MASTER_KEY_B: - ret = get_client_master_key(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_SERVER_START_ENCRYPTION; - BREAK; - - case SSL2_ST_SERVER_START_ENCRYPTION: - /* - * Ok we how have sent all the stuff needed to start encrypting, - * the next packet back will be encrypted. - */ - if (!ssl2_enc_init(s, 0)) { - ret = -1; - goto end; - } - s->s2->clear_text = 0; - s->state = SSL2_ST_SEND_SERVER_VERIFY_A; - BREAK; - - case SSL2_ST_SEND_SERVER_VERIFY_A: - case SSL2_ST_SEND_SERVER_VERIFY_B: - ret = server_verify(s); - if (ret <= 0) - goto end; - s->init_num = 0; - if (s->hit) { - /* - * If we are in here, we have been buffering the output, so - * we need to flush it and remove buffering from future - * traffic - */ - s->state = SSL2_ST_SEND_SERVER_VERIFY_C; - BREAK; - } else { - s->state = SSL2_ST_GET_CLIENT_FINISHED_A; - break; - } - - case SSL2_ST_SEND_SERVER_VERIFY_C: - /* get the number of bytes to write */ - num1 = BIO_ctrl(s->wbio, BIO_CTRL_INFO, 0, NULL); - if (num1 > 0) { - s->rwstate = SSL_WRITING; - num1 = BIO_flush(s->wbio); - if (num1 <= 0) { - ret = -1; - goto end; - } - s->rwstate = SSL_NOTHING; - } - - /* flushed and now remove buffering */ - s->wbio = BIO_pop(s->wbio); - - s->state = SSL2_ST_GET_CLIENT_FINISHED_A; - BREAK; - - case SSL2_ST_GET_CLIENT_FINISHED_A: - case SSL2_ST_GET_CLIENT_FINISHED_B: - ret = get_client_finished(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_A; - BREAK; - - case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: - case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: - case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: - case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: - /* - * don't do a 'request certificate' if we don't want to, or we - * already have one, and we only want to do it once. - */ - if (!(s->verify_mode & SSL_VERIFY_PEER) || - ((s->session->peer != NULL) && - (s->verify_mode & SSL_VERIFY_CLIENT_ONCE))) { - s->state = SSL2_ST_SEND_SERVER_FINISHED_A; - break; - } else { - ret = request_certificate(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_SEND_SERVER_FINISHED_A; - } - BREAK; - - case SSL2_ST_SEND_SERVER_FINISHED_A: - case SSL2_ST_SEND_SERVER_FINISHED_B: - ret = server_finish(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL_ST_OK; - break; - - case SSL_ST_OK: - BUF_MEM_free(s->init_buf); - ssl_free_wbio_buffer(s); - s->init_buf = NULL; - s->init_num = 0; - /* ERR_clear_error(); */ - - ssl_update_cache(s, SSL_SESS_CACHE_SERVER); - - s->ctx->stats.sess_accept_good++; - /* s->server=1; */ - ret = 1; - - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - - goto end; - /* BREAK; */ - - default: - SSLerr(SSL_F_SSL2_ACCEPT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* BREAK; */ - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_ACCEPT_LOOP, 1); - s->state = new_state; - } - } - end: - s->in_handshake--; - if (cb != NULL) - cb(s, SSL_CB_ACCEPT_EXIT, ret); - return (ret); -} - -static int get_client_master_key(SSL *s) -{ - int is_export, i, n, keya; - unsigned int num_encrypted_key_bytes, key_length; - unsigned long len; - unsigned char *p; - const SSL_CIPHER *cp; - const EVP_CIPHER *c; - const EVP_MD *md; - unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; - unsigned char decrypt_good; - size_t j; - - p = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A) { - i = ssl2_read(s, (char *)&(p[s->init_num]), 10 - s->init_num); - - if (i < (10 - s->init_num)) - return (ssl2_part_read(s, SSL_F_GET_CLIENT_MASTER_KEY, i)); - s->init_num = 10; - - if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY) { - if (p[-1] != SSL2_MT_ERROR) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, - SSL_R_READ_WRONG_PACKET_TYPE); - } else - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR); - return (-1); - } - - cp = ssl2_get_cipher_by_char(p); - if (cp == NULL || sk_SSL_CIPHER_find(s->session->ciphers, cp) < 0) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH); - return (-1); - } - s->session->cipher = cp; - - p += 3; - n2s(p, i); - s->s2->tmp.clear = i; - n2s(p, i); - s->s2->tmp.enc = i; - n2s(p, i); - if (i > SSL_MAX_KEY_ARG_LENGTH) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG); - return -1; - } - s->session->key_arg_length = i; - s->state = SSL2_ST_GET_CLIENT_MASTER_KEY_B; - } - - /* SSL2_ST_GET_CLIENT_MASTER_KEY_B */ - p = (unsigned char *)s->init_buf->data; - if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); - return -1; - } - keya = s->session->key_arg_length; - len = - 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + - (unsigned long)keya; - if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_MESSAGE_TOO_LONG); - return -1; - } - n = (int)len - s->init_num; - i = ssl2_read(s, (char *)&(p[s->init_num]), n); - if (i != n) - return (ssl2_part_read(s, SSL_F_GET_CLIENT_MASTER_KEY, i)); - if (s->msg_callback) { - /* CLIENT-MASTER-KEY */ - s->msg_callback(0, s->version, 0, p, (size_t)len, s, - s->msg_callback_arg); - } - p += 10; - - memcpy(s->session->key_arg, &(p[s->s2->tmp.clear + s->s2->tmp.enc]), - (unsigned int)keya); - - if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_PRIVATEKEY); - return (-1); - } - - is_export = SSL_C_IS_EXPORT(s->session->cipher); - - if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, - SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); - return (0); - } - - /* - * The format of the CLIENT-MASTER-KEY message is - * 1 byte message type - * 3 bytes cipher - * 2-byte clear key length (stored in s->s2->tmp.clear) - * 2-byte encrypted key length (stored in s->s2->tmp.enc) - * 2-byte key args length (IV etc) - * clear key - * encrypted key - * key args - * - * If the cipher is an export cipher, then the encrypted key bytes - * are a fixed portion of the total key (5 or 8 bytes). The size of - * this portion is in |num_encrypted_key_bytes|. If the cipher is not an - * export cipher, then the entire key material is encrypted (i.e., clear - * key length must be zero). - */ - key_length = (unsigned int)EVP_CIPHER_key_length(c); - if (key_length > SSL_MAX_MASTER_KEY_LENGTH) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); - return -1; - } - - if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) { - is_export = 1; - num_encrypted_key_bytes = 8; - } else if (is_export) { - num_encrypted_key_bytes = 5; - } else { - num_encrypted_key_bytes = key_length; - } - - if (s->s2->tmp.clear + num_encrypted_key_bytes != key_length) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_LENGTH); - return -1; - } - /* - * The encrypted blob must decrypt to the encrypted portion of the key. - * Decryption can't be expanding, so if we don't have enough encrypted - * bytes to fit the key in the buffer, stop now. - */ - if (s->s2->tmp.enc < num_encrypted_key_bytes) { - ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_LENGTH_TOO_SHORT); - return -1; - } - - /* - * We must not leak whether a decryption failure occurs because of - * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, - * section 7.4.7.1). The code follows that advice of the TLS RFC and - * generates a random premaster secret for the case that the decrypt - * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 - */ - - if (RAND_bytes(rand_premaster_secret, - (int)num_encrypted_key_bytes) <= 0) - return 0; - - i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc, - &(p[s->s2->tmp.clear]), - &(p[s->s2->tmp.clear]), - (s->s2->ssl2_rollback) ? RSA_SSLV23_PADDING : - RSA_PKCS1_PADDING); - ERR_clear_error(); - /* - * If a bad decrypt, continue with protocol but with a random master - * secret (Bleichenbacher attack) - */ - decrypt_good = constant_time_eq_int_8(i, (int)num_encrypted_key_bytes); - for (j = 0; j < num_encrypted_key_bytes; j++) { - p[s->s2->tmp.clear + j] = - constant_time_select_8(decrypt_good, p[s->s2->tmp.clear + j], - rand_premaster_secret[j]); - } - - s->session->master_key_length = (int)key_length; - memcpy(s->session->master_key, p, key_length); - OPENSSL_cleanse(p, key_length); - - return 1; -} - -static int get_client_hello(SSL *s) -{ - int i, n; - unsigned long len; - unsigned char *p; - STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */ - STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */ - STACK_OF(SSL_CIPHER) *prio, *allow; - int z; - - /* - * This is a bit of a hack to check for the correct packet type the first - * time round. - */ - if (s->state == SSL2_ST_GET_CLIENT_HELLO_A) { - s->first_packet = 1; - s->state = SSL2_ST_GET_CLIENT_HELLO_B; - } - - p = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_GET_CLIENT_HELLO_B) { - i = ssl2_read(s, (char *)&(p[s->init_num]), 9 - s->init_num); - if (i < (9 - s->init_num)) - return (ssl2_part_read(s, SSL_F_GET_CLIENT_HELLO, i)); - s->init_num = 9; - - if (*(p++) != SSL2_MT_CLIENT_HELLO) { - if (p[-1] != SSL2_MT_ERROR) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_READ_WRONG_PACKET_TYPE); - } else - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_PEER_ERROR); - return (-1); - } - n2s(p, i); - if (i < s->version) - s->version = i; - n2s(p, i); - s->s2->tmp.cipher_spec_length = i; - n2s(p, i); - s->s2->tmp.session_id_length = i; - if ((i < 0) || (i > SSL_MAX_SSL_SESSION_ID_LENGTH)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); - return -1; - } - n2s(p, i); - s->s2->challenge_length = i; - if ((i < SSL2_MIN_CHALLENGE_LENGTH) || - (i > SSL2_MAX_CHALLENGE_LENGTH)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_INVALID_CHALLENGE_LENGTH); - return (-1); - } - s->state = SSL2_ST_GET_CLIENT_HELLO_C; - } - - /* SSL2_ST_GET_CLIENT_HELLO_C */ - p = (unsigned char *)s->init_buf->data; - len = - 9 + (unsigned long)s->s2->tmp.cipher_spec_length + - (unsigned long)s->s2->challenge_length + - (unsigned long)s->s2->tmp.session_id_length; - if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_MESSAGE_TOO_LONG); - return -1; - } - n = (int)len - s->init_num; - i = ssl2_read(s, (char *)&(p[s->init_num]), n); - if (i != n) - return (ssl2_part_read(s, SSL_F_GET_CLIENT_HELLO, i)); - if (s->msg_callback) { - /* CLIENT-HELLO */ - s->msg_callback(0, s->version, 0, p, (size_t)len, s, - s->msg_callback_arg); - } - p += 9; - - /* - * get session-id before cipher stuff so we can get out session structure - * if it is cached - */ - /* session-id */ - if ((s->s2->tmp.session_id_length != 0) && - (s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_BAD_SSL_SESSION_ID_LENGTH); - return (-1); - } - - if (s->s2->tmp.session_id_length == 0) { - if (!ssl_get_new_session(s, 1)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - return (-1); - } - } else { - i = ssl_get_prev_session(s, &(p[s->s2->tmp.cipher_spec_length]), - s->s2->tmp.session_id_length, NULL); - if (i == 1) { /* previous session */ - s->hit = 1; - } else if (i == -1) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - return (-1); - } else { - if (s->cert == NULL) { - ssl2_return_error(s, SSL2_PE_NO_CERTIFICATE); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CERTIFICATE_SET); - return (-1); - } - - if (!ssl_get_new_session(s, 1)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - return (-1); - } - } - } - - if (!s->hit) { - cs = ssl_bytes_to_cipher_list(s, p, s->s2->tmp.cipher_spec_length, - &s->session->ciphers); - if (cs == NULL) - goto mem_err; - - cl = SSL_get_ciphers(s); - - if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { - prio = sk_SSL_CIPHER_dup(cl); - if (prio == NULL) - goto mem_err; - allow = cs; - } else { - prio = cs; - allow = cl; - } - - /* Generate list of SSLv2 ciphers shared between client and server */ - for (z = 0; z < sk_SSL_CIPHER_num(prio); z++) { - const SSL_CIPHER *cp = sk_SSL_CIPHER_value(prio, z); - if ((cp->algorithm_ssl & SSL_SSLV2) == 0 || - sk_SSL_CIPHER_find(allow, cp) < 0) { - (void)sk_SSL_CIPHER_delete(prio, z); - z--; - } - } - if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { - sk_SSL_CIPHER_free(s->session->ciphers); - s->session->ciphers = prio; - } - - /* Make sure we have at least one cipher in common */ - if (sk_SSL_CIPHER_num(s->session->ciphers) == 0) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CIPHER_MATCH); - return -1; - } - /* - * s->session->ciphers should now have a list of ciphers that are on - * both the client and server. This list is ordered by the order the - * client sent the ciphers or in the order of the server's preference - * if SSL_OP_CIPHER_SERVER_PREFERENCE was set. - */ - } - p += s->s2->tmp.cipher_spec_length; - /* done cipher selection */ - - /* session id extracted already */ - p += s->s2->tmp.session_id_length; - - /* challenge */ - if (s->s2->challenge_length > sizeof s->s2->challenge) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - return -1; - } - memcpy(s->s2->challenge, p, (unsigned int)s->s2->challenge_length); - return (1); - mem_err: - SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_MALLOC_FAILURE); - return (0); -} - -static int server_hello(SSL *s) -{ - unsigned char *p, *d; - int n, hit; - - p = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_SEND_SERVER_HELLO_A) { - d = p + 11; - *(p++) = SSL2_MT_SERVER_HELLO; /* type */ - hit = s->hit; - *(p++) = (unsigned char)hit; -# if 1 - if (!hit) { - if (s->session->sess_cert != NULL) - /* - * This can't really happen because get_client_hello has - * called ssl_get_new_session, which does not set sess_cert. - */ - ssl_sess_cert_free(s->session->sess_cert); - s->session->sess_cert = ssl_sess_cert_new(); - if (s->session->sess_cert == NULL) { - SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE); - return (-1); - } - } - /* - * If 'hit' is set, then s->sess_cert may be non-NULL or NULL, - * depending on whether it survived in the internal cache or was - * retrieved from an external cache. If it is NULL, we cannot put any - * useful data in it anyway, so we don't touch it. - */ - -# else /* That's what used to be done when cert_st - * and sess_cert_st were * the same. */ - if (!hit) { /* else add cert to session */ - CRYPTO_add(&s->cert->references, 1, CRYPTO_LOCK_SSL_CERT); - if (s->session->sess_cert != NULL) - ssl_cert_free(s->session->sess_cert); - s->session->sess_cert = s->cert; - } else { /* We have a session id-cache hit, if the * - * session-id has no certificate listed - * against * the 'cert' structure, grab the - * 'old' one * listed against the SSL - * connection */ - if (s->session->sess_cert == NULL) { - CRYPTO_add(&s->cert->references, 1, CRYPTO_LOCK_SSL_CERT); - s->session->sess_cert = s->cert; - } - } -# endif - - if (s->cert == NULL) { - ssl2_return_error(s, SSL2_PE_NO_CERTIFICATE); - SSLerr(SSL_F_SERVER_HELLO, SSL_R_NO_CERTIFICATE_SPECIFIED); - return (-1); - } - - if (hit) { - *(p++) = 0; /* no certificate type */ - s2n(s->version, p); /* version */ - s2n(0, p); /* cert len */ - s2n(0, p); /* ciphers len */ - } else { - /* EAY EAY */ - /* put certificate type */ - *(p++) = SSL2_CT_X509_CERTIFICATE; - s2n(s->version, p); /* version */ - n = i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, NULL); - s2n(n, p); /* certificate length */ - i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, &d); - n = 0; - - /* - * lets send out the ciphers we like in the prefered order - */ - n = ssl_cipher_list_to_bytes(s, s->session->ciphers, d, 0); - d += n; - s2n(n, p); /* add cipher length */ - } - - /* make and send conn_id */ - s2n(SSL2_CONNECTION_ID_LENGTH, p); /* add conn_id length */ - s->s2->conn_id_length = SSL2_CONNECTION_ID_LENGTH; - if (RAND_bytes(s->s2->conn_id, (int)s->s2->conn_id_length) <= 0) - return -1; - memcpy(d, s->s2->conn_id, SSL2_CONNECTION_ID_LENGTH); - d += SSL2_CONNECTION_ID_LENGTH; - - s->state = SSL2_ST_SEND_SERVER_HELLO_B; - s->init_num = d - (unsigned char *)s->init_buf->data; - s->init_off = 0; - } - /* SSL2_ST_SEND_SERVER_HELLO_B */ - /* - * If we are using TCP/IP, the performance is bad if we do 2 writes - * without a read between them. This occurs when Session-id reuse is - * used, so I will put in a buffering module - */ - if (s->hit) { - if (!ssl_init_wbio_buffer(s, 1)) - return (-1); - } - - return (ssl2_do_write(s)); -} - -static int get_client_finished(SSL *s) -{ - unsigned char *p; - int i, n; - unsigned long len; - - p = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A) { - i = ssl2_read(s, (char *)&(p[s->init_num]), 1 - s->init_num); - if (i < 1 - s->init_num) - return (ssl2_part_read(s, SSL_F_GET_CLIENT_FINISHED, i)); - s->init_num += i; - - if (*p != SSL2_MT_CLIENT_FINISHED) { - if (*p != SSL2_MT_ERROR) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_FINISHED, - SSL_R_READ_WRONG_PACKET_TYPE); - } else { - SSLerr(SSL_F_GET_CLIENT_FINISHED, SSL_R_PEER_ERROR); - /* try to read the error message */ - i = ssl2_read(s, (char *)&(p[s->init_num]), 3 - s->init_num); - return ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i); - } - return (-1); - } - s->state = SSL2_ST_GET_CLIENT_FINISHED_B; - } - - /* SSL2_ST_GET_CLIENT_FINISHED_B */ - if (s->s2->conn_id_length > sizeof s->s2->conn_id) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR); - return -1; - } - len = 1 + (unsigned long)s->s2->conn_id_length; - n = (int)len - s->init_num; - i = ssl2_read(s, (char *)&(p[s->init_num]), n); - if (i < n) { - return (ssl2_part_read(s, SSL_F_GET_CLIENT_FINISHED, i)); - } - if (s->msg_callback) { - /* CLIENT-FINISHED */ - s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); - } - p += 1; - if (memcmp(p, s->s2->conn_id, s->s2->conn_id_length) != 0) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_FINISHED, SSL_R_CONNECTION_ID_IS_DIFFERENT); - return (-1); - } - return (1); -} - -static int server_verify(SSL *s) -{ - unsigned char *p; - - if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A) { - p = (unsigned char *)s->init_buf->data; - *(p++) = SSL2_MT_SERVER_VERIFY; - if (s->s2->challenge_length > sizeof s->s2->challenge) { - SSLerr(SSL_F_SERVER_VERIFY, ERR_R_INTERNAL_ERROR); - return -1; - } - memcpy(p, s->s2->challenge, (unsigned int)s->s2->challenge_length); - /* p+=s->s2->challenge_length; */ - - s->state = SSL2_ST_SEND_SERVER_VERIFY_B; - s->init_num = s->s2->challenge_length + 1; - s->init_off = 0; - } - return (ssl2_do_write(s)); -} - -static int server_finish(SSL *s) -{ - unsigned char *p; - - if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A) { - p = (unsigned char *)s->init_buf->data; - *(p++) = SSL2_MT_SERVER_FINISHED; - - if (s->session->session_id_length > sizeof s->session->session_id) { - SSLerr(SSL_F_SERVER_FINISH, ERR_R_INTERNAL_ERROR); - return -1; - } - memcpy(p, s->session->session_id, - (unsigned int)s->session->session_id_length); - /* p+=s->session->session_id_length; */ - - s->state = SSL2_ST_SEND_SERVER_FINISHED_B; - s->init_num = s->session->session_id_length + 1; - s->init_off = 0; - } - - /* SSL2_ST_SEND_SERVER_FINISHED_B */ - return (ssl2_do_write(s)); -} - -/* send the request and check the response */ -static int request_certificate(SSL *s) -{ - const unsigned char *cp; - unsigned char *p, *p2, *buf2; - unsigned char *ccd; - int i, j, ctype, ret = -1; - unsigned long len; - X509 *x509 = NULL; - STACK_OF(X509) *sk = NULL; - - ccd = s->s2->tmp.ccl; - if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A) { - p = (unsigned char *)s->init_buf->data; - *(p++) = SSL2_MT_REQUEST_CERTIFICATE; - *(p++) = SSL2_AT_MD5_WITH_RSA_ENCRYPTION; - if (RAND_bytes(ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0) - return -1; - memcpy(p, ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH); - - s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_B; - s->init_num = SSL2_MIN_CERT_CHALLENGE_LENGTH + 2; - s->init_off = 0; - } - - if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B) { - i = ssl2_do_write(s); - if (i <= 0) { - ret = i; - goto end; - } - - s->init_num = 0; - s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_C; - } - - if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C) { - p = (unsigned char *)s->init_buf->data; - /* try to read 6 octets ... */ - i = ssl2_read(s, (char *)&(p[s->init_num]), 6 - s->init_num); - /* - * ... but don't call ssl2_part_read now if we got at least 3 - * (probably NO-CERTIFICATE-ERROR) - */ - if (i < 3 - s->init_num) { - ret = ssl2_part_read(s, SSL_F_REQUEST_CERTIFICATE, i); - goto end; - } - s->init_num += i; - - if ((s->init_num >= 3) && (p[0] == SSL2_MT_ERROR)) { - n2s(p, i); - if (i != SSL2_PE_NO_CERTIFICATE) { - /* - * not the error message we expected -- let ssl2_part_read - * handle it - */ - s->init_num -= 3; - ret = ssl2_part_read(s, SSL_F_REQUEST_CERTIFICATE, 3); - goto end; - } - - if (s->msg_callback) { - /* ERROR */ - s->msg_callback(0, s->version, 0, p, 3, s, - s->msg_callback_arg); - } - - /* - * this is the one place where we can recover from an SSL 2.0 - * error - */ - - if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { - ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE); - SSLerr(SSL_F_REQUEST_CERTIFICATE, - SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - goto end; - } - ret = 1; - goto end; - } - if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (s->init_num < 6)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_SHORT_READ); - goto end; - } - if (s->init_num != 6) { - SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_INTERNAL_ERROR); - goto end; - } - - /* ok we have a response */ - /* certificate type, there is only one right now. */ - ctype = *(p++); - if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION) { - ssl2_return_error(s, SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE); - SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_BAD_RESPONSE_ARGUMENT); - goto end; - } - n2s(p, i); - s->s2->tmp.clen = i; - n2s(p, i); - s->s2->tmp.rlen = i; - s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_D; - } - - /* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */ - p = (unsigned char *)s->init_buf->data; - len = 6 + (unsigned long)s->s2->tmp.clen + (unsigned long)s->s2->tmp.rlen; - if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { - SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_MESSAGE_TOO_LONG); - goto end; - } - j = (int)len - s->init_num; - i = ssl2_read(s, (char *)&(p[s->init_num]), j); - if (i < j) { - ret = ssl2_part_read(s, SSL_F_REQUEST_CERTIFICATE, i); - goto end; - } - if (s->msg_callback) { - /* CLIENT-CERTIFICATE */ - s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); - } - p += 6; - - cp = p; - x509 = (X509 *)d2i_X509(NULL, &cp, (long)s->s2->tmp.clen); - if (x509 == NULL) { - SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_X509_LIB); - goto msg_end; - } - - if (((sk = sk_X509_new_null()) == NULL) || (!sk_X509_push(sk, x509))) { - SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto msg_end; - } - - i = ssl_verify_cert_chain(s, sk); - - if (i > 0) { /* we like the packet, now check the chksum */ - EVP_MD_CTX ctx; - EVP_PKEY *pkey = NULL; - - EVP_MD_CTX_init(&ctx); - if (!EVP_VerifyInit_ex(&ctx, s->ctx->rsa_md5, NULL) - || !EVP_VerifyUpdate(&ctx, s->s2->key_material, - s->s2->key_material_length) - || !EVP_VerifyUpdate(&ctx, ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH)) - goto msg_end; - - i = i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, NULL); - buf2 = OPENSSL_malloc((unsigned int)i); - if (buf2 == NULL) { - SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto msg_end; - } - p2 = buf2; - i = i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, &p2); - if (!EVP_VerifyUpdate(&ctx, buf2, (unsigned int)i)) { - OPENSSL_free(buf2); - goto msg_end; - } - OPENSSL_free(buf2); - - pkey = X509_get_pubkey(x509); - if (pkey == NULL) - goto end; - i = EVP_VerifyFinal(&ctx, cp, s->s2->tmp.rlen, pkey); - EVP_PKEY_free(pkey); - EVP_MD_CTX_cleanup(&ctx); - - if (i > 0) { - if (s->session->peer != NULL) - X509_free(s->session->peer); - s->session->peer = x509; - CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); - s->session->verify_result = s->verify_result; - ret = 1; - goto end; - } else { - SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_BAD_CHECKSUM); - goto msg_end; - } - } else { - msg_end: - ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE); - } - end: - sk_X509_free(sk); - X509_free(x509); - return (ret); -} - -static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from, - unsigned char *to, int padding) -{ - RSA *rsa; - int i; - - if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)) { - SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT, SSL_R_NO_PRIVATEKEY); - return (-1); - } - if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA) { - SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT, SSL_R_PUBLIC_KEY_IS_NOT_RSA); - return (-1); - } - rsa = c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa; - - /* we have the public key */ - i = RSA_private_decrypt(len, from, to, rsa, padding); - if (i < 0) - SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT, ERR_R_RSA_LIB); - return (i); -} -#else /* !OPENSSL_NO_SSL2 */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif diff --git a/thirdparty/openssl/ssl/s3_both.c b/thirdparty/openssl/ssl/s3_both.c deleted file mode 100644 index 054ded1c99..0000000000 --- a/thirdparty/openssl/ssl/s3_both.c +++ /dev/null @@ -1,758 +0,0 @@ -/* ssl/s3_both.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2002 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 - * openssl-core@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). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#include <limits.h> -#include <string.h> -#include <stdio.h> -#include "ssl_locl.h" -#include <openssl/buffer.h> -#include <openssl/rand.h> -#include <openssl/objects.h> -#include <openssl/evp.h> -#include <openssl/x509.h> - -/* - * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or - * SSL3_RT_CHANGE_CIPHER_SPEC) - */ -int ssl3_do_write(SSL *s, int type) -{ - int ret; - - ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], - s->init_num); - if (ret < 0) - return (-1); - if (type == SSL3_RT_HANDSHAKE) - /* - * should not be done for 'Hello Request's, but in that case we'll - * ignore the result anyway - */ - ssl3_finish_mac(s, (unsigned char *)&s->init_buf->data[s->init_off], - ret); - - if (ret == s->init_num) { - if (s->msg_callback) - s->msg_callback(1, s->version, type, s->init_buf->data, - (size_t)(s->init_off + s->init_num), s, - s->msg_callback_arg); - return (1); - } - s->init_off += ret; - s->init_num -= ret; - return (0); -} - -int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) -{ - unsigned char *p; - int i; - unsigned long l; - - if (s->state == a) { - p = ssl_handshake_start(s); - - i = s->method->ssl3_enc->final_finish_mac(s, - sender, slen, - s->s3->tmp.finish_md); - if (i <= 0) - return 0; - s->s3->tmp.finish_md_len = i; - memcpy(p, s->s3->tmp.finish_md, i); - l = i; - - /* - * Copy the finished so we can use it for renegotiation checks - */ - if (s->type == SSL_ST_CONNECT) { - OPENSSL_assert(i <= EVP_MAX_MD_SIZE); - memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, i); - s->s3->previous_client_finished_len = i; - } else { - OPENSSL_assert(i <= EVP_MAX_MD_SIZE); - memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, i); - s->s3->previous_server_finished_len = i; - } - -#ifdef OPENSSL_SYS_WIN16 - /* - * MSVC 1.5 does not clear the top bytes of the word unless I do - * this. - */ - l &= 0xffff; -#endif - ssl_set_handshake_header(s, SSL3_MT_FINISHED, l); - s->state = b; - } - - /* SSL3_ST_SEND_xxxxxx_HELLO_B */ - return ssl_do_write(s); -} - -#ifndef OPENSSL_NO_NEXTPROTONEG -/* - * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen - * to far. - */ -static void ssl3_take_mac(SSL *s) -{ - const char *sender; - int slen; - /* - * If no new cipher setup return immediately: other functions will set - * the appropriate error. - */ - if (s->s3->tmp.new_cipher == NULL) - return; - if (s->state & SSL_ST_CONNECT) { - sender = s->method->ssl3_enc->server_finished_label; - slen = s->method->ssl3_enc->server_finished_label_len; - } else { - sender = s->method->ssl3_enc->client_finished_label; - slen = s->method->ssl3_enc->client_finished_label_len; - } - - s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s, - sender, - slen, - s->s3->tmp.peer_finish_md); -} -#endif - -int ssl3_get_finished(SSL *s, int a, int b) -{ - int al, i, ok; - long n; - unsigned char *p; - -#ifdef OPENSSL_NO_NEXTPROTONEG - /* - * the mac has already been generated when we received the change cipher - * spec message and is in s->s3->tmp.peer_finish_md - */ -#endif - - /* 64 argument should actually be 36+4 :-) */ - n = s->method->ssl_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok); - - if (!ok) - return ((int)n); - - /* If this occurs, we have missed a message */ - if (!s->s3->change_cipher_spec) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_GOT_A_FIN_BEFORE_A_CCS); - goto f_err; - } - s->s3->change_cipher_spec = 0; - - p = (unsigned char *)s->init_msg; - i = s->s3->tmp.peer_finish_md_len; - - if (i != n) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_BAD_DIGEST_LENGTH); - goto f_err; - } - - if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_DIGEST_CHECK_FAILED); - goto f_err; - } - - /* - * Copy the finished so we can use it for renegotiation checks - */ - if (s->type == SSL_ST_ACCEPT) { - OPENSSL_assert(i <= EVP_MAX_MD_SIZE); - memcpy(s->s3->previous_client_finished, s->s3->tmp.peer_finish_md, i); - s->s3->previous_client_finished_len = i; - } else { - OPENSSL_assert(i <= EVP_MAX_MD_SIZE); - memcpy(s->s3->previous_server_finished, s->s3->tmp.peer_finish_md, i); - s->s3->previous_server_finished_len = i; - } - - return (1); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return (0); -} - -/*- - * for these 2 messages, we need to - * ssl->enc_read_ctx re-init - * ssl->s3->read_sequence zero - * ssl->s3->read_mac_secret re-init - * ssl->session->read_sym_enc assign - * ssl->session->read_compression assign - * ssl->session->read_hash assign - */ -int ssl3_send_change_cipher_spec(SSL *s, int a, int b) -{ - unsigned char *p; - - if (s->state == a) { - p = (unsigned char *)s->init_buf->data; - *p = SSL3_MT_CCS; - s->init_num = 1; - s->init_off = 0; - - s->state = b; - } - - /* SSL3_ST_CW_CHANGE_B */ - return (ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC)); -} - -unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk) -{ - unsigned char *p; - unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s); - - if (!ssl_add_cert_chain(s, cpk, &l)) - return 0; - - l -= 3 + SSL_HM_HEADER_LENGTH(s); - p = ssl_handshake_start(s); - l2n3(l, p); - l += 3; - ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l); - return l + SSL_HM_HEADER_LENGTH(s); -} - -/* - * Obtain handshake message of message type 'mt' (any if mt == -1), maximum - * acceptable body length 'max'. The first four bytes (msg_type and length) - * are read in state 'st1', the body is read in state 'stn'. - */ -long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) -{ - unsigned char *p; - unsigned long l; - long n; - int i, al; - - if (s->s3->tmp.reuse_message) { - s->s3->tmp.reuse_message = 0; - if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - *ok = 1; - s->state = stn; - s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; - s->init_num = (int)s->s3->tmp.message_size; - return s->init_num; - } - - p = (unsigned char *)s->init_buf->data; - - if (s->state == st1) { /* s->init_num < SSL3_HM_HEADER_LENGTH */ - int skip_message; - - do { - while (s->init_num < SSL3_HM_HEADER_LENGTH) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, - &p[s->init_num], - SSL3_HM_HEADER_LENGTH - - s->init_num, 0); - if (i <= 0) { - s->rwstate = SSL_READING; - *ok = 0; - return i; - } - s->init_num += i; - } - - skip_message = 0; - if (!s->server) - if (p[0] == SSL3_MT_HELLO_REQUEST) - /* - * The server may always send 'Hello Request' messages -- - * we are doing a handshake anyway now, so ignore them if - * their format is correct. Does not count for 'Finished' - * MAC. - */ - if (p[1] == 0 && p[2] == 0 && p[3] == 0) { - s->init_num = 0; - skip_message = 1; - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, SSL3_HM_HEADER_LENGTH, s, - s->msg_callback_arg); - } - } - while (skip_message); - - /* s->init_num == SSL3_HM_HEADER_LENGTH */ - - if ((mt >= 0) && (*p != mt)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - - s->s3->tmp.message_type = *(p++); - - n2l3(p, l); - if (l > (unsigned long)max) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); - goto f_err; - } - /* - * Make buffer slightly larger than message length as a precaution - * against small OOB reads e.g. CVE-2016-6306 - */ - if (l - && !BUF_MEM_grow_clean(s->init_buf, - (int)l + SSL3_HM_HEADER_LENGTH + 16)) { - SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB); - goto err; - } - s->s3->tmp.message_size = l; - s->state = stn; - - s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; - s->init_num = 0; - } - - /* next state (stn) */ - p = s->init_msg; - n = s->s3->tmp.message_size - s->init_num; - while (n > 0) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], - n, 0); - if (i <= 0) { - s->rwstate = SSL_READING; - *ok = 0; - return i; - } - s->init_num += i; - n -= i; - } - -#ifndef OPENSSL_NO_NEXTPROTONEG - /* - * If receiving Finished, record MAC of prior handshake messages for - * Finished verification. - */ - if (*s->init_buf->data == SSL3_MT_FINISHED) - ssl3_take_mac(s); -#endif - - /* Feed this message into MAC computation. */ - ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, - s->init_num + SSL3_HM_HEADER_LENGTH); - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, - (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s, - s->msg_callback_arg); - *ok = 1; - return s->init_num; - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - *ok = 0; - return (-1); -} - -int ssl_cert_type(X509 *x, EVP_PKEY *pkey) -{ - EVP_PKEY *pk; - int ret = -1, i; - - if (pkey == NULL) - pk = X509_get_pubkey(x); - else - pk = pkey; - if (pk == NULL) - goto err; - - i = pk->type; - if (i == EVP_PKEY_RSA) { - ret = SSL_PKEY_RSA_ENC; - } else if (i == EVP_PKEY_DSA) { - ret = SSL_PKEY_DSA_SIGN; - } -#ifndef OPENSSL_NO_EC - else if (i == EVP_PKEY_EC) { - ret = SSL_PKEY_ECC; - } -#endif - else if (i == NID_id_GostR3410_94 || i == NID_id_GostR3410_94_cc) { - ret = SSL_PKEY_GOST94; - } else if (i == NID_id_GostR3410_2001 || i == NID_id_GostR3410_2001_cc) { - ret = SSL_PKEY_GOST01; - } else if (x && (i == EVP_PKEY_DH || i == EVP_PKEY_DHX)) { - /* - * For DH two cases: DH certificate signed with RSA and DH - * certificate signed with DSA. - */ - i = X509_certificate_type(x, pk); - if (i & EVP_PKS_RSA) - ret = SSL_PKEY_DH_RSA; - else if (i & EVP_PKS_DSA) - ret = SSL_PKEY_DH_DSA; - } - - err: - if (!pkey) - EVP_PKEY_free(pk); - return (ret); -} - -int ssl_verify_alarm_type(long type) -{ - int al; - - switch (type) { - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - case X509_V_ERR_UNABLE_TO_GET_CRL: - case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: - al = SSL_AD_UNKNOWN_CA; - break; - case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: - case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: - case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: - case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: - case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: - case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: - case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: - case X509_V_ERR_CERT_NOT_YET_VALID: - case X509_V_ERR_CRL_NOT_YET_VALID: - case X509_V_ERR_CERT_UNTRUSTED: - case X509_V_ERR_CERT_REJECTED: - case X509_V_ERR_HOSTNAME_MISMATCH: - case X509_V_ERR_EMAIL_MISMATCH: - case X509_V_ERR_IP_ADDRESS_MISMATCH: - al = SSL_AD_BAD_CERTIFICATE; - break; - case X509_V_ERR_CERT_SIGNATURE_FAILURE: - case X509_V_ERR_CRL_SIGNATURE_FAILURE: - al = SSL_AD_DECRYPT_ERROR; - break; - case X509_V_ERR_CERT_HAS_EXPIRED: - case X509_V_ERR_CRL_HAS_EXPIRED: - al = SSL_AD_CERTIFICATE_EXPIRED; - break; - case X509_V_ERR_CERT_REVOKED: - al = SSL_AD_CERTIFICATE_REVOKED; - break; - case X509_V_ERR_UNSPECIFIED: - case X509_V_ERR_OUT_OF_MEM: - case X509_V_ERR_INVALID_CALL: - case X509_V_ERR_STORE_LOOKUP: - al = SSL_AD_INTERNAL_ERROR; - break; - case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: - case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: - case X509_V_ERR_CERT_CHAIN_TOO_LONG: - case X509_V_ERR_PATH_LENGTH_EXCEEDED: - case X509_V_ERR_INVALID_CA: - al = SSL_AD_UNKNOWN_CA; - break; - case X509_V_ERR_APPLICATION_VERIFICATION: - al = SSL_AD_HANDSHAKE_FAILURE; - break; - case X509_V_ERR_INVALID_PURPOSE: - al = SSL_AD_UNSUPPORTED_CERTIFICATE; - break; - default: - al = SSL_AD_CERTIFICATE_UNKNOWN; - break; - } - return (al); -} - -#ifndef OPENSSL_NO_BUF_FREELISTS -/*- - * On some platforms, malloc() performance is bad enough that you can't just - * free() and malloc() buffers all the time, so we need to use freelists from - * unused buffers. Currently, each freelist holds memory chunks of only a - * given size (list->chunklen); other sized chunks are freed and malloced. - * This doesn't help much if you're using many different SSL option settings - * with a given context. (The options affecting buffer size are - * max_send_fragment, read buffer vs write buffer, - * SSL_OP_MICROSOFT_BIG_WRITE_BUFFER, SSL_OP_NO_COMPRESSION, and - * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS.) Using a separate freelist for every - * possible size is not an option, since max_send_fragment can take on many - * different values. - * - * If you are on a platform with a slow malloc(), and you're using SSL - * connections with many different settings for these options, and you need to - * use the SSL_MOD_RELEASE_BUFFERS feature, you have a few options: - * - Link against a faster malloc implementation. - * - Use a separate SSL_CTX for each option set. - * - Improve this code. - */ -static void *freelist_extract(SSL_CTX *ctx, int for_read, int sz) -{ - SSL3_BUF_FREELIST *list; - SSL3_BUF_FREELIST_ENTRY *ent = NULL; - void *result = NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist; - if (list != NULL && sz == (int)list->chunklen) - ent = list->head; - if (ent != NULL) { - list->head = ent->next; - result = ent; - if (--list->len == 0) - list->chunklen = 0; - } - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - if (!result) - result = OPENSSL_malloc(sz); - return result; -} - -static void freelist_insert(SSL_CTX *ctx, int for_read, size_t sz, void *mem) -{ - SSL3_BUF_FREELIST *list; - SSL3_BUF_FREELIST_ENTRY *ent; - - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist; - if (list != NULL && - (sz == list->chunklen || list->chunklen == 0) && - list->len < ctx->freelist_max_len && sz >= sizeof(*ent)) { - list->chunklen = sz; - ent = mem; - ent->next = list->head; - list->head = ent; - ++list->len; - mem = NULL; - } - - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - if (mem) - OPENSSL_free(mem); -} -#else -# define freelist_extract(c,fr,sz) OPENSSL_malloc(sz) -# define freelist_insert(c,fr,sz,m) OPENSSL_free(m) -#endif - -int ssl3_setup_read_buffer(SSL *s) -{ - unsigned char *p; - size_t len, align = 0, headerlen; - - if (SSL_IS_DTLS(s)) - headerlen = DTLS1_RT_HEADER_LENGTH; - else - headerlen = SSL3_RT_HEADER_LENGTH; - -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); -#endif - - if (s->s3->rbuf.buf == NULL) { - len = SSL3_RT_MAX_PLAIN_LENGTH - + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align; - if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) { - s->s3->init_extra = 1; - len += SSL3_RT_MAX_EXTRA; - } -#ifndef OPENSSL_NO_COMP - if (!(s->options & SSL_OP_NO_COMPRESSION)) - len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; -#endif - if ((p = freelist_extract(s->ctx, 1, len)) == NULL) - goto err; - s->s3->rbuf.buf = p; - s->s3->rbuf.len = len; - } - - s->packet = &(s->s3->rbuf.buf[0]); - return 1; - - err: - SSLerr(SSL_F_SSL3_SETUP_READ_BUFFER, ERR_R_MALLOC_FAILURE); - return 0; -} - -int ssl3_setup_write_buffer(SSL *s) -{ - unsigned char *p; - size_t len, align = 0, headerlen; - - if (SSL_IS_DTLS(s)) - headerlen = DTLS1_RT_HEADER_LENGTH + 1; - else - headerlen = SSL3_RT_HEADER_LENGTH; - -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); -#endif - - if (s->s3->wbuf.buf == NULL) { - len = s->max_send_fragment - + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align; -#ifndef OPENSSL_NO_COMP - if (!(s->options & SSL_OP_NO_COMPRESSION)) - len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; -#endif - if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) - len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; - - if ((p = freelist_extract(s->ctx, 0, len)) == NULL) - goto err; - s->s3->wbuf.buf = p; - s->s3->wbuf.len = len; - } - - return 1; - - err: - SSLerr(SSL_F_SSL3_SETUP_WRITE_BUFFER, ERR_R_MALLOC_FAILURE); - return 0; -} - -int ssl3_setup_buffers(SSL *s) -{ - if (!ssl3_setup_read_buffer(s)) - return 0; - if (!ssl3_setup_write_buffer(s)) - return 0; - return 1; -} - -int ssl3_release_write_buffer(SSL *s) -{ - if (s->s3->wbuf.buf != NULL) { - freelist_insert(s->ctx, 0, s->s3->wbuf.len, s->s3->wbuf.buf); - s->s3->wbuf.buf = NULL; - } - return 1; -} - -int ssl3_release_read_buffer(SSL *s) -{ - if (s->s3->rbuf.buf != NULL) { - freelist_insert(s->ctx, 1, s->s3->rbuf.len, s->s3->rbuf.buf); - s->s3->rbuf.buf = NULL; - } - return 1; -} diff --git a/thirdparty/openssl/ssl/s3_cbc.c b/thirdparty/openssl/ssl/s3_cbc.c deleted file mode 100644 index 557622f513..0000000000 --- a/thirdparty/openssl/ssl/s3_cbc.c +++ /dev/null @@ -1,820 +0,0 @@ -/* ssl/s3_cbc.c */ -/* ==================================================================== - * Copyright (c) 2012 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 - * openssl-core@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). - * - */ - -#include "../crypto/constant_time_locl.h" -#include "ssl_locl.h" - -#include <openssl/md5.h> -#include <openssl/sha.h> - -/* - * MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's - * length field. (SHA-384/512 have 128-bit length.) - */ -#define MAX_HASH_BIT_COUNT_BYTES 16 - -/* - * MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support. - * Currently SHA-384/512 has a 128-byte block size and that's the largest - * supported by TLS.) - */ -#define MAX_HASH_BLOCK_SIZE 128 - -/*- - * ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC - * record in |rec| by updating |rec->length| in constant time. - * - * block_size: the block size of the cipher used to encrypt the record. - * returns: - * 0: (in non-constant time) if the record is publicly invalid. - * 1: if the padding was valid - * -1: otherwise. - */ -int ssl3_cbc_remove_padding(const SSL *s, - SSL3_RECORD *rec, - unsigned block_size, unsigned mac_size) -{ - unsigned padding_length, good; - const unsigned overhead = 1 /* padding length byte */ + mac_size; - - /* - * These lengths are all public so we can test them in non-constant time. - */ - if (overhead > rec->length) - return 0; - - padding_length = rec->data[rec->length - 1]; - good = constant_time_ge(rec->length, padding_length + overhead); - /* SSLv3 requires that the padding is minimal. */ - good &= constant_time_ge(block_size, padding_length + 1); - padding_length = good & (padding_length + 1); - rec->length -= padding_length; - rec->type |= padding_length << 8; /* kludge: pass padding length */ - return constant_time_select_int(good, 1, -1); -} - -/*- - * tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC - * record in |rec| in constant time and returns 1 if the padding is valid and - * -1 otherwise. It also removes any explicit IV from the start of the record - * without leaking any timing about whether there was enough space after the - * padding was removed. - * - * block_size: the block size of the cipher used to encrypt the record. - * returns: - * 0: (in non-constant time) if the record is publicly invalid. - * 1: if the padding was valid - * -1: otherwise. - */ -int tls1_cbc_remove_padding(const SSL *s, - SSL3_RECORD *rec, - unsigned block_size, unsigned mac_size) -{ - unsigned padding_length, good, to_check, i; - const unsigned overhead = 1 /* padding length byte */ + mac_size; - /* Check if version requires explicit IV */ - if (SSL_USE_EXPLICIT_IV(s)) { - /* - * These lengths are all public so we can test them in non-constant - * time. - */ - if (overhead + block_size > rec->length) - return 0; - /* We can now safely skip explicit IV */ - rec->data += block_size; - rec->input += block_size; - rec->length -= block_size; - } else if (overhead > rec->length) - return 0; - - padding_length = rec->data[rec->length - 1]; - - /* - * NB: if compression is in operation the first packet may not be of even - * length so the padding bug check cannot be performed. This bug - * workaround has been around since SSLeay so hopefully it is either - * fixed now or no buggy implementation supports compression [steve] - */ - if ((s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand) { - /* First packet is even in size, so check */ - if ((CRYPTO_memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0", 8) == 0) && - !(padding_length & 1)) { - s->s3->flags |= TLS1_FLAGS_TLS_PADDING_BUG; - } - if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) && padding_length > 0) { - padding_length--; - } - } - - if (EVP_CIPHER_flags(s->enc_read_ctx->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { - /* padding is already verified */ - rec->length -= padding_length + 1; - return 1; - } - - good = constant_time_ge(rec->length, overhead + padding_length); - /* - * The padding consists of a length byte at the end of the record and - * then that many bytes of padding, all with the same value as the length - * byte. Thus, with the length byte included, there are i+1 bytes of - * padding. We can't check just |padding_length+1| bytes because that - * leaks decrypted information. Therefore we always have to check the - * maximum amount of padding possible. (Again, the length of the record - * is public information so we can use it.) - */ - to_check = 255; /* maximum amount of padding. */ - if (to_check > rec->length - 1) - to_check = rec->length - 1; - - for (i = 0; i < to_check; i++) { - unsigned char mask = constant_time_ge_8(padding_length, i); - unsigned char b = rec->data[rec->length - 1 - i]; - /* - * The final |padding_length+1| bytes should all have the value - * |padding_length|. Therefore the XOR should be zero. - */ - good &= ~(mask & (padding_length ^ b)); - } - - /* - * If any of the final |padding_length+1| bytes had the wrong value, one - * or more of the lower eight bits of |good| will be cleared. - */ - good = constant_time_eq(0xff, good & 0xff); - padding_length = good & (padding_length + 1); - rec->length -= padding_length; - rec->type |= padding_length << 8; /* kludge: pass padding length */ - - return constant_time_select_int(good, 1, -1); -} - -/*- - * ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in - * constant time (independent of the concrete value of rec->length, which may - * vary within a 256-byte window). - * - * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to - * this function. - * - * On entry: - * rec->orig_len >= md_size - * md_size <= EVP_MAX_MD_SIZE - * - * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with - * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into - * a single or pair of cache-lines, then the variable memory accesses don't - * actually affect the timing. CPUs with smaller cache-lines [if any] are - * not multi-core and are not considered vulnerable to cache-timing attacks. - */ -#define CBC_MAC_ROTATE_IN_PLACE - -void ssl3_cbc_copy_mac(unsigned char *out, - const SSL3_RECORD *rec, - unsigned md_size, unsigned orig_len) -{ -#if defined(CBC_MAC_ROTATE_IN_PLACE) - unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; - unsigned char *rotated_mac; -#else - unsigned char rotated_mac[EVP_MAX_MD_SIZE]; -#endif - - /* - * mac_end is the index of |rec->data| just after the end of the MAC. - */ - unsigned mac_end = rec->length; - unsigned mac_start = mac_end - md_size; - /* - * scan_start contains the number of bytes that we can ignore because the - * MAC's position can only vary by 255 bytes. - */ - unsigned scan_start = 0; - unsigned i, j; - unsigned div_spoiler; - unsigned rotate_offset; - - OPENSSL_assert(orig_len >= md_size); - OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); - -#if defined(CBC_MAC_ROTATE_IN_PLACE) - rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf) & 63); -#endif - - /* This information is public so it's safe to branch based on it. */ - if (orig_len > md_size + 255 + 1) - scan_start = orig_len - (md_size + 255 + 1); - /* - * div_spoiler contains a multiple of md_size that is used to cause the - * modulo operation to be constant time. Without this, the time varies - * based on the amount of padding when running on Intel chips at least. - * The aim of right-shifting md_size is so that the compiler doesn't - * figure out that it can remove div_spoiler as that would require it to - * prove that md_size is always even, which I hope is beyond it. - */ - div_spoiler = md_size >> 1; - div_spoiler <<= (sizeof(div_spoiler) - 1) * 8; - rotate_offset = (div_spoiler + mac_start - scan_start) % md_size; - - memset(rotated_mac, 0, md_size); - for (i = scan_start, j = 0; i < orig_len; i++) { - unsigned char mac_started = constant_time_ge_8(i, mac_start); - unsigned char mac_ended = constant_time_ge_8(i, mac_end); - unsigned char b = rec->data[i]; - rotated_mac[j++] |= b & mac_started & ~mac_ended; - j &= constant_time_lt(j, md_size); - } - - /* Now rotate the MAC */ -#if defined(CBC_MAC_ROTATE_IN_PLACE) - j = 0; - for (i = 0; i < md_size; i++) { - /* in case cache-line is 32 bytes, touch second line */ - ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32]; - out[j++] = rotated_mac[rotate_offset++]; - rotate_offset &= constant_time_lt(rotate_offset, md_size); - } -#else - memset(out, 0, md_size); - rotate_offset = md_size - rotate_offset; - rotate_offset &= constant_time_lt(rotate_offset, md_size); - for (i = 0; i < md_size; i++) { - for (j = 0; j < md_size; j++) - out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset); - rotate_offset++; - rotate_offset &= constant_time_lt(rotate_offset, md_size); - } -#endif -} - -/* - * u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in - * little-endian order. The value of p is advanced by four. - */ -#define u32toLE(n, p) \ - (*((p)++)=(unsigned char)(n), \ - *((p)++)=(unsigned char)(n>>8), \ - *((p)++)=(unsigned char)(n>>16), \ - *((p)++)=(unsigned char)(n>>24)) - -/* - * These functions serialize the state of a hash and thus perform the - * standard "final" operation without adding the padding and length that such - * a function typically does. - */ -static void tls1_md5_final_raw(void *ctx, unsigned char *md_out) -{ - MD5_CTX *md5 = ctx; - u32toLE(md5->A, md_out); - u32toLE(md5->B, md_out); - u32toLE(md5->C, md_out); - u32toLE(md5->D, md_out); -} - -static void tls1_sha1_final_raw(void *ctx, unsigned char *md_out) -{ - SHA_CTX *sha1 = ctx; - l2n(sha1->h0, md_out); - l2n(sha1->h1, md_out); - l2n(sha1->h2, md_out); - l2n(sha1->h3, md_out); - l2n(sha1->h4, md_out); -} - -#define LARGEST_DIGEST_CTX SHA_CTX - -#ifndef OPENSSL_NO_SHA256 -static void tls1_sha256_final_raw(void *ctx, unsigned char *md_out) -{ - SHA256_CTX *sha256 = ctx; - unsigned i; - - for (i = 0; i < 8; i++) { - l2n(sha256->h[i], md_out); - } -} - -# undef LARGEST_DIGEST_CTX -# define LARGEST_DIGEST_CTX SHA256_CTX -#endif - -#ifndef OPENSSL_NO_SHA512 -static void tls1_sha512_final_raw(void *ctx, unsigned char *md_out) -{ - SHA512_CTX *sha512 = ctx; - unsigned i; - - for (i = 0; i < 8; i++) { - l2n8(sha512->h[i], md_out); - } -} - -# undef LARGEST_DIGEST_CTX -# define LARGEST_DIGEST_CTX SHA512_CTX -#endif - -/* - * ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function - * which ssl3_cbc_digest_record supports. - */ -char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return 0; -#endif - switch (EVP_MD_CTX_type(ctx)) { - case NID_md5: - case NID_sha1: -#ifndef OPENSSL_NO_SHA256 - case NID_sha224: - case NID_sha256: -#endif -#ifndef OPENSSL_NO_SHA512 - case NID_sha384: - case NID_sha512: -#endif - return 1; - default: - return 0; - } -} - -/*- - * ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS - * record. - * - * ctx: the EVP_MD_CTX from which we take the hash function. - * ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX. - * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. - * md_out_size: if non-NULL, the number of output bytes is written here. - * header: the 13-byte, TLS record header. - * data: the record data itself, less any preceeding explicit IV. - * data_plus_mac_size: the secret, reported length of the data and MAC - * once the padding has been removed. - * data_plus_mac_plus_padding_size: the public length of the whole - * record, including padding. - * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS. - * - * On entry: by virtue of having been through one of the remove_padding - * functions, above, we know that data_plus_mac_size is large enough to contain - * a padding byte and MAC. (If the padding was invalid, it might contain the - * padding too. ) - * Returns 1 on success or 0 on error - */ -int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, - unsigned char *md_out, - size_t *md_out_size, - const unsigned char header[13], - const unsigned char *data, - size_t data_plus_mac_size, - size_t data_plus_mac_plus_padding_size, - const unsigned char *mac_secret, - unsigned mac_secret_length, char is_sslv3) -{ - union { - double align; - unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; - } md_state; - void (*md_final_raw) (void *ctx, unsigned char *md_out); - void (*md_transform) (void *ctx, const unsigned char *block); - unsigned md_size, md_block_size = 64; - unsigned sslv3_pad_length = 40, header_length, variance_blocks, - len, max_mac_bytes, num_blocks, - num_starting_blocks, k, mac_end_offset, c, index_a, index_b; - unsigned int bits; /* at most 18 bits */ - unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES]; - /* hmac_pad is the masked HMAC key. */ - unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE]; - unsigned char first_block[MAX_HASH_BLOCK_SIZE]; - unsigned char mac_out[EVP_MAX_MD_SIZE]; - unsigned i, j, md_out_size_u; - EVP_MD_CTX md_ctx; - /* - * mdLengthSize is the number of bytes in the length field that - * terminates * the hash. - */ - unsigned md_length_size = 8; - char length_is_big_endian = 1; - - /* - * This is a, hopefully redundant, check that allows us to forget about - * many possible overflows later in this function. - */ - OPENSSL_assert(data_plus_mac_plus_padding_size < 1024 * 1024); - - switch (EVP_MD_CTX_type(ctx)) { - case NID_md5: - if (MD5_Init((MD5_CTX *)md_state.c) <= 0) - return 0; - md_final_raw = tls1_md5_final_raw; - md_transform = - (void (*)(void *ctx, const unsigned char *block))MD5_Transform; - md_size = 16; - sslv3_pad_length = 48; - length_is_big_endian = 0; - break; - case NID_sha1: - if (SHA1_Init((SHA_CTX *)md_state.c) <= 0) - return 0; - md_final_raw = tls1_sha1_final_raw; - md_transform = - (void (*)(void *ctx, const unsigned char *block))SHA1_Transform; - md_size = 20; - break; -#ifndef OPENSSL_NO_SHA256 - case NID_sha224: - if (SHA224_Init((SHA256_CTX *)md_state.c) <= 0) - return 0; - md_final_raw = tls1_sha256_final_raw; - md_transform = - (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; - md_size = 224 / 8; - break; - case NID_sha256: - if (SHA256_Init((SHA256_CTX *)md_state.c) <= 0) - return 0; - md_final_raw = tls1_sha256_final_raw; - md_transform = - (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; - md_size = 32; - break; -#endif -#ifndef OPENSSL_NO_SHA512 - case NID_sha384: - if (SHA384_Init((SHA512_CTX *)md_state.c) <= 0) - return 0; - md_final_raw = tls1_sha512_final_raw; - md_transform = - (void (*)(void *ctx, const unsigned char *block))SHA512_Transform; - md_size = 384 / 8; - md_block_size = 128; - md_length_size = 16; - break; - case NID_sha512: - if (SHA512_Init((SHA512_CTX *)md_state.c) <= 0) - return 0; - md_final_raw = tls1_sha512_final_raw; - md_transform = - (void (*)(void *ctx, const unsigned char *block))SHA512_Transform; - md_size = 64; - md_block_size = 128; - md_length_size = 16; - break; -#endif - default: - /* - * ssl3_cbc_record_digest_supported should have been called first to - * check that the hash function is supported. - */ - OPENSSL_assert(0); - if (md_out_size) - *md_out_size = 0; - return 0; - } - - OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); - OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE); - OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); - - header_length = 13; - if (is_sslv3) { - header_length = mac_secret_length + sslv3_pad_length + 8 /* sequence - * number */ + - 1 /* record type */ + - 2 /* record length */ ; - } - - /* - * variance_blocks is the number of blocks of the hash that we have to - * calculate in constant time because they could be altered by the - * padding value. In SSLv3, the padding must be minimal so the end of - * the plaintext varies by, at most, 15+20 = 35 bytes. (We conservatively - * assume that the MAC size varies from 0..20 bytes.) In case the 9 bytes - * of hash termination (0x80 + 64-bit length) don't fit in the final - * block, we say that the final two blocks can vary based on the padding. - * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not - * required to be minimal. Therefore we say that the final six blocks can - * vary based on the padding. Later in the function, if the message is - * short and there obviously cannot be this many blocks then - * variance_blocks can be reduced. - */ - variance_blocks = is_sslv3 ? 2 : 6; - /* - * From now on we're dealing with the MAC, which conceptually has 13 - * bytes of `header' before the start of the data (TLS) or 71/75 bytes - * (SSLv3) - */ - len = data_plus_mac_plus_padding_size + header_length; - /* - * max_mac_bytes contains the maximum bytes of bytes in the MAC, - * including * |header|, assuming that there's no padding. - */ - max_mac_bytes = len - md_size - 1; - /* num_blocks is the maximum number of hash blocks. */ - num_blocks = - (max_mac_bytes + 1 + md_length_size + md_block_size - - 1) / md_block_size; - /* - * In order to calculate the MAC in constant time we have to handle the - * final blocks specially because the padding value could cause the end - * to appear somewhere in the final |variance_blocks| blocks and we can't - * leak where. However, |num_starting_blocks| worth of data can be hashed - * right away because no padding value can affect whether they are - * plaintext. - */ - num_starting_blocks = 0; - /* - * k is the starting byte offset into the conceptual header||data where - * we start processing. - */ - k = 0; - /* - * mac_end_offset is the index just past the end of the data to be MACed. - */ - mac_end_offset = data_plus_mac_size + header_length - md_size; - /* - * c is the index of the 0x80 byte in the final hash block that contains - * application data. - */ - c = mac_end_offset % md_block_size; - /* - * index_a is the hash block number that contains the 0x80 terminating - * value. - */ - index_a = mac_end_offset / md_block_size; - /* - * index_b is the hash block number that contains the 64-bit hash length, - * in bits. - */ - index_b = (mac_end_offset + md_length_size) / md_block_size; - /* - * bits is the hash-length in bits. It includes the additional hash block - * for the masked HMAC key, or whole of |header| in the case of SSLv3. - */ - - /* - * For SSLv3, if we're going to have any starting blocks then we need at - * least two because the header is larger than a single block. - */ - if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) { - num_starting_blocks = num_blocks - variance_blocks; - k = md_block_size * num_starting_blocks; - } - - bits = 8 * mac_end_offset; - if (!is_sslv3) { - /* - * Compute the initial HMAC block. For SSLv3, the padding and secret - * bytes are included in |header| because they take more than a - * single block. - */ - bits += 8 * md_block_size; - memset(hmac_pad, 0, md_block_size); - OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad)); - memcpy(hmac_pad, mac_secret, mac_secret_length); - for (i = 0; i < md_block_size; i++) - hmac_pad[i] ^= 0x36; - - md_transform(md_state.c, hmac_pad); - } - - if (length_is_big_endian) { - memset(length_bytes, 0, md_length_size - 4); - length_bytes[md_length_size - 4] = (unsigned char)(bits >> 24); - length_bytes[md_length_size - 3] = (unsigned char)(bits >> 16); - length_bytes[md_length_size - 2] = (unsigned char)(bits >> 8); - length_bytes[md_length_size - 1] = (unsigned char)bits; - } else { - memset(length_bytes, 0, md_length_size); - length_bytes[md_length_size - 5] = (unsigned char)(bits >> 24); - length_bytes[md_length_size - 6] = (unsigned char)(bits >> 16); - length_bytes[md_length_size - 7] = (unsigned char)(bits >> 8); - length_bytes[md_length_size - 8] = (unsigned char)bits; - } - - if (k > 0) { - if (is_sslv3) { - unsigned overhang; - - /* - * The SSLv3 header is larger than a single block. overhang is - * the number of bytes beyond a single block that the header - * consumes: either 7 bytes (SHA1) or 11 bytes (MD5). There are no - * ciphersuites in SSLv3 that are not SHA1 or MD5 based and - * therefore we can be confident that the header_length will be - * greater than |md_block_size|. However we add a sanity check just - * in case - */ - if (header_length <= md_block_size) { - /* Should never happen */ - return 0; - } - overhang = header_length - md_block_size; - md_transform(md_state.c, header); - memcpy(first_block, header + md_block_size, overhang); - memcpy(first_block + overhang, data, md_block_size - overhang); - md_transform(md_state.c, first_block); - for (i = 1; i < k / md_block_size - 1; i++) - md_transform(md_state.c, data + md_block_size * i - overhang); - } else { - /* k is a multiple of md_block_size. */ - memcpy(first_block, header, 13); - memcpy(first_block + 13, data, md_block_size - 13); - md_transform(md_state.c, first_block); - for (i = 1; i < k / md_block_size; i++) - md_transform(md_state.c, data + md_block_size * i - 13); - } - } - - memset(mac_out, 0, sizeof(mac_out)); - - /* - * We now process the final hash blocks. For each block, we construct it - * in constant time. If the |i==index_a| then we'll include the 0x80 - * bytes and zero pad etc. For each block we selectively copy it, in - * constant time, to |mac_out|. - */ - for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks; - i++) { - unsigned char block[MAX_HASH_BLOCK_SIZE]; - unsigned char is_block_a = constant_time_eq_8(i, index_a); - unsigned char is_block_b = constant_time_eq_8(i, index_b); - for (j = 0; j < md_block_size; j++) { - unsigned char b = 0, is_past_c, is_past_cp1; - if (k < header_length) - b = header[k]; - else if (k < data_plus_mac_plus_padding_size + header_length) - b = data[k - header_length]; - k++; - - is_past_c = is_block_a & constant_time_ge_8(j, c); - is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1); - /* - * If this is the block containing the end of the application - * data, and we are at the offset for the 0x80 value, then - * overwrite b with 0x80. - */ - b = constant_time_select_8(is_past_c, 0x80, b); - /* - * If this the the block containing the end of the application - * data and we're past the 0x80 value then just write zero. - */ - b = b & ~is_past_cp1; - /* - * If this is index_b (the final block), but not index_a (the end - * of the data), then the 64-bit length didn't fit into index_a - * and we're having to add an extra block of zeros. - */ - b &= ~is_block_b | is_block_a; - - /* - * The final bytes of one of the blocks contains the length. - */ - if (j >= md_block_size - md_length_size) { - /* If this is index_b, write a length byte. */ - b = constant_time_select_8(is_block_b, - length_bytes[j - - (md_block_size - - md_length_size)], b); - } - block[j] = b; - } - - md_transform(md_state.c, block); - md_final_raw(md_state.c, block); - /* If this is index_b, copy the hash value to |mac_out|. */ - for (j = 0; j < md_size; j++) - mac_out[j] |= block[j] & is_block_b; - } - - EVP_MD_CTX_init(&md_ctx); - if (EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */ ) <= 0) - goto err; - if (is_sslv3) { - /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */ - memset(hmac_pad, 0x5c, sslv3_pad_length); - - if (EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length) <= 0 - || EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length) <= 0 - || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0) - goto err; - } else { - /* Complete the HMAC in the standard manner. */ - for (i = 0; i < md_block_size; i++) - hmac_pad[i] ^= 0x6a; - - if (EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size) <= 0 - || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0) - goto err; - } - EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); - if (md_out_size) - *md_out_size = md_out_size_u; - EVP_MD_CTX_cleanup(&md_ctx); - - return 1; -err: - EVP_MD_CTX_cleanup(&md_ctx); - return 0; -} - -#ifdef OPENSSL_FIPS - -/* - * Due to the need to use EVP in FIPS mode we can't reimplement digests but - * we can ensure the number of blocks processed is equal for all cases by - * digesting additional data. - */ - -void tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx, - EVP_MD_CTX *mac_ctx, const unsigned char *data, - size_t data_len, size_t orig_len) -{ - size_t block_size, digest_pad, blocks_data, blocks_orig; - if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE) - return; - block_size = EVP_MD_CTX_block_size(mac_ctx); - /*- - * We are in FIPS mode if we get this far so we know we have only SHA* - * digests and TLS to deal with. - * Minimum digest padding length is 17 for SHA384/SHA512 and 9 - * otherwise. - * Additional header is 13 bytes. To get the number of digest blocks - * processed round up the amount of data plus padding to the nearest - * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise. - * So we have: - * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size - * equivalently: - * blocks = (payload_len + digest_pad + 12)/block_size + 1 - * HMAC adds a constant overhead. - * We're ultimately only interested in differences so this becomes - * blocks = (payload_len + 29)/128 - * for SHA384/SHA512 and - * blocks = (payload_len + 21)/64 - * otherwise. - */ - digest_pad = block_size == 64 ? 21 : 29; - blocks_orig = (orig_len + digest_pad) / block_size; - blocks_data = (data_len + digest_pad) / block_size; - /* - * MAC enough blocks to make up the difference between the original and - * actual lengths plus one extra block to ensure this is never a no op. - * The "data" pointer should always have enough space to perform this - * operation as it is large enough for a maximum length TLS buffer. - */ - EVP_DigestSignUpdate(mac_ctx, data, - (blocks_orig - blocks_data + 1) * block_size); -} -#endif diff --git a/thirdparty/openssl/ssl/s3_clnt.c b/thirdparty/openssl/ssl/s3_clnt.c deleted file mode 100644 index 5b8b2da59f..0000000000 --- a/thirdparty/openssl/ssl/s3_clnt.c +++ /dev/null @@ -1,3787 +0,0 @@ -/* ssl/s3_clnt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 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 - * openssl-core@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). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the OpenSSL open source - * license provided above. - * - * ECC cipher suite support in OpenSSL originally written by - * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include <stdio.h> -#include "ssl_locl.h" -#include "kssl_lcl.h" -#include <openssl/buffer.h> -#include <openssl/rand.h> -#include <openssl/objects.h> -#include <openssl/evp.h> -#include <openssl/md5.h> -#ifdef OPENSSL_FIPS -# include <openssl/fips.h> -#endif -#ifndef OPENSSL_NO_DH -# include <openssl/dh.h> -#endif -#include <openssl/bn.h> -#ifndef OPENSSL_NO_ENGINE -# include <openssl/engine.h> -#endif - -static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b); -#ifndef OPENSSL_NO_TLSEXT -static int ssl3_check_finished(SSL *s); -#endif - -#ifndef OPENSSL_NO_SSL3_METHOD -static const SSL_METHOD *ssl3_get_client_method(int ver) -{ - if (ver == SSL3_VERSION) - return (SSLv3_client_method()); - else - return (NULL); -} - -IMPLEMENT_ssl3_meth_func(SSLv3_client_method, - ssl_undefined_function, - ssl3_connect, ssl3_get_client_method) -#endif -int ssl3_connect(SSL *s) -{ - BUF_MEM *buf = NULL; - unsigned long Time = (unsigned long)time(NULL); - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int ret = -1; - int new_state, state, skip = 0; - - RAND_add(&Time, sizeof(Time), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - -#ifndef OPENSSL_NO_HEARTBEATS - /* - * If we're awaiting a HeartbeatResponse, pretend we already got and - * don't await it anymore, because Heartbeats don't make sense during - * handshakes anyway. - */ - if (s->tlsext_hb_pending) { - s->tlsext_hb_pending = 0; - s->tlsext_hb_seq++; - } -#endif - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_RENEGOTIATE: - s->renegotiate = 1; - s->state = SSL_ST_CONNECT; - s->ctx->stats.sess_connect_renegotiate++; - /* break */ - case SSL_ST_BEFORE: - case SSL_ST_CONNECT: - case SSL_ST_BEFORE | SSL_ST_CONNECT: - case SSL_ST_OK | SSL_ST_CONNECT: - - s->server = 0; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - if ((s->version & 0xff00) != 0x0300) { - SSLerr(SSL_F_SSL3_CONNECT, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - ret = -1; - goto end; - } - - /* s->version=SSL3_VERSION; */ - s->type = SSL_ST_CONNECT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - s->init_buf = buf; - buf = NULL; - } - - if (!ssl3_setup_buffers(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - /* setup buffing BIO */ - if (!ssl_init_wbio_buffer(s, 0)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - /* don't push the buffering BIO quite yet */ - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - s->state = SSL3_ST_CW_CLNT_HELLO_A; - s->ctx->stats.sess_connect++; - s->init_num = 0; - s->s3->flags &= ~SSL3_FLAGS_CCS_OK; - /* - * Should have been reset by ssl3_get_finished, too. - */ - s->s3->change_cipher_spec = 0; - break; - - case SSL3_ST_CW_CLNT_HELLO_A: - case SSL3_ST_CW_CLNT_HELLO_B: - - s->shutdown = 0; - ret = ssl3_client_hello(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_SRVR_HELLO_A; - s->init_num = 0; - - /* turn on buffering for the next lot of output */ - if (s->bbio != s->wbio) - s->wbio = BIO_push(s->bbio, s->wbio); - - break; - - case SSL3_ST_CR_SRVR_HELLO_A: - case SSL3_ST_CR_SRVR_HELLO_B: - ret = ssl3_get_server_hello(s); - if (ret <= 0) - goto end; - - if (s->hit) { - s->state = SSL3_ST_CR_FINISHED_A; -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_ticket_expected) { - /* receive renewed session ticket */ - s->state = SSL3_ST_CR_SESSION_TICKET_A; - } -#endif - } else { - s->state = SSL3_ST_CR_CERT_A; - } - s->init_num = 0; - break; - case SSL3_ST_CR_CERT_A: - case SSL3_ST_CR_CERT_B: -#ifndef OPENSSL_NO_TLSEXT - /* Noop (ret = 0) for everything but EAP-FAST. */ - ret = ssl3_check_finished(s); - if (ret < 0) - goto end; - if (ret == 1) { - s->hit = 1; - s->state = SSL3_ST_CR_FINISHED_A; - s->init_num = 0; - break; - } -#endif - /* Check if it is anon DH/ECDH, SRP auth */ - /* or PSK */ - if (! - (s->s3->tmp. - new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - ret = ssl3_get_server_certificate(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_status_expected) - s->state = SSL3_ST_CR_CERT_STATUS_A; - else - s->state = SSL3_ST_CR_KEY_EXCH_A; - } else { - skip = 1; - s->state = SSL3_ST_CR_KEY_EXCH_A; - } -#else - } else - skip = 1; - - s->state = SSL3_ST_CR_KEY_EXCH_A; -#endif - s->init_num = 0; - break; - - case SSL3_ST_CR_KEY_EXCH_A: - case SSL3_ST_CR_KEY_EXCH_B: - ret = ssl3_get_key_exchange(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_CERT_REQ_A; - s->init_num = 0; - - /* - * at this point we check that we have the required stuff from - * the server - */ - if (!ssl3_check_cert_and_algorithm(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - break; - - case SSL3_ST_CR_CERT_REQ_A: - case SSL3_ST_CR_CERT_REQ_B: - ret = ssl3_get_certificate_request(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_SRVR_DONE_A; - s->init_num = 0; - break; - - case SSL3_ST_CR_SRVR_DONE_A: - case SSL3_ST_CR_SRVR_DONE_B: - ret = ssl3_get_server_done(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_SRP - if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) { - if ((ret = SRP_Calc_A_param(s)) <= 0) { - SSLerr(SSL_F_SSL3_CONNECT, SSL_R_SRP_A_CALC); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - goto end; - } - } -#endif - if (s->s3->tmp.cert_req) - s->state = SSL3_ST_CW_CERT_A; - else - s->state = SSL3_ST_CW_KEY_EXCH_A; - s->init_num = 0; - - break; - - case SSL3_ST_CW_CERT_A: - case SSL3_ST_CW_CERT_B: - case SSL3_ST_CW_CERT_C: - case SSL3_ST_CW_CERT_D: - ret = ssl3_send_client_certificate(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CW_KEY_EXCH_A; - s->init_num = 0; - break; - - case SSL3_ST_CW_KEY_EXCH_A: - case SSL3_ST_CW_KEY_EXCH_B: - ret = ssl3_send_client_key_exchange(s); - if (ret <= 0) - goto end; - /* - * EAY EAY EAY need to check for DH fix cert sent back - */ - /* - * For TLS, cert_req is set to 2, so a cert chain of nothing is - * sent, but no verify packet is sent - */ - /* - * XXX: For now, we do not support client authentication in ECDH - * cipher suites with ECDH (rather than ECDSA) certificates. We - * need to skip the certificate verify message when client's - * ECDH public key is sent inside the client certificate. - */ - if (s->s3->tmp.cert_req == 1) { - s->state = SSL3_ST_CW_CERT_VRFY_A; - } else { - s->state = SSL3_ST_CW_CHANGE_A; - } - if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { - s->state = SSL3_ST_CW_CHANGE_A; - } - - s->init_num = 0; - break; - - case SSL3_ST_CW_CERT_VRFY_A: - case SSL3_ST_CW_CERT_VRFY_B: - ret = ssl3_send_client_verify(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CW_CHANGE_A; - s->init_num = 0; - break; - - case SSL3_ST_CW_CHANGE_A: - case SSL3_ST_CW_CHANGE_B: - ret = ssl3_send_change_cipher_spec(s, - SSL3_ST_CW_CHANGE_A, - SSL3_ST_CW_CHANGE_B); - if (ret <= 0) - goto end; - -#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) - s->state = SSL3_ST_CW_FINISHED_A; -#else - if (s->s3->next_proto_neg_seen) - s->state = SSL3_ST_CW_NEXT_PROTO_A; - else - s->state = SSL3_ST_CW_FINISHED_A; -#endif - s->init_num = 0; - - s->session->cipher = s->s3->tmp.new_cipher; -#ifdef OPENSSL_NO_COMP - s->session->compress_meth = 0; -#else - if (s->s3->tmp.new_compression == NULL) - s->session->compress_meth = 0; - else - s->session->compress_meth = s->s3->tmp.new_compression->id; -#endif - if (!s->method->ssl3_enc->setup_key_block(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - if (!s->method->ssl3_enc->change_cipher_state(s, - SSL3_CHANGE_CIPHER_CLIENT_WRITE)) - { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - break; - -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) - case SSL3_ST_CW_NEXT_PROTO_A: - case SSL3_ST_CW_NEXT_PROTO_B: - ret = ssl3_send_next_proto(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CW_FINISHED_A; - break; -#endif - - case SSL3_ST_CW_FINISHED_A: - case SSL3_ST_CW_FINISHED_B: - ret = ssl3_send_finished(s, - SSL3_ST_CW_FINISHED_A, - SSL3_ST_CW_FINISHED_B, - s->method-> - ssl3_enc->client_finished_label, - s->method-> - ssl3_enc->client_finished_label_len); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CW_FLUSH; - - /* clear flags */ - s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; - if (s->hit) { - s->s3->tmp.next_state = SSL_ST_OK; - if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) { - s->state = SSL_ST_OK; - s->s3->flags |= SSL3_FLAGS_POP_BUFFER; - s->s3->delay_buf_pop_ret = 0; - } - } else { -#ifndef OPENSSL_NO_TLSEXT - /* - * Allow NewSessionTicket if ticket expected - */ - if (s->tlsext_ticket_expected) - s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; - else -#endif - - s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A; - } - s->init_num = 0; - break; - -#ifndef OPENSSL_NO_TLSEXT - case SSL3_ST_CR_SESSION_TICKET_A: - case SSL3_ST_CR_SESSION_TICKET_B: - ret = ssl3_get_new_session_ticket(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_FINISHED_A; - s->init_num = 0; - break; - - case SSL3_ST_CR_CERT_STATUS_A: - case SSL3_ST_CR_CERT_STATUS_B: - ret = ssl3_get_cert_status(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_KEY_EXCH_A; - s->init_num = 0; - break; -#endif - - case SSL3_ST_CR_FINISHED_A: - case SSL3_ST_CR_FINISHED_B: - if (!s->s3->change_cipher_spec) - s->s3->flags |= SSL3_FLAGS_CCS_OK; - ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, - SSL3_ST_CR_FINISHED_B); - if (ret <= 0) - goto end; - - if (s->hit) - s->state = SSL3_ST_CW_CHANGE_A; - else - s->state = SSL_ST_OK; - s->init_num = 0; - break; - - case SSL3_ST_CW_FLUSH: - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { - ret = -1; - goto end; - } - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; - break; - - case SSL_ST_OK: - /* clean a few things up */ - ssl3_cleanup_key_block(s); - - if (s->init_buf != NULL) { - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - } - - /* - * If we are not 'joining' the last two packets, remove the - * buffering now - */ - if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) - ssl_free_wbio_buffer(s); - /* else do it later in ssl3_write */ - - s->init_num = 0; - s->renegotiate = 0; - s->new_session = 0; - - ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); - if (s->hit) - s->ctx->stats.sess_hit++; - - ret = 1; - /* s->server=0; */ - s->handshake_func = ssl3_connect; - s->ctx->stats.sess_connect_good++; - - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - - goto end; - /* break; */ - - case SSL_ST_ERR: - default: - SSLerr(SSL_F_SSL3_CONNECT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* break; */ - } - - /* did we do anything */ - if (!s->s3->tmp.reuse_message && !skip) { - if (s->debug) { - if ((ret = BIO_flush(s->wbio)) <= 0) - goto end; - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_CONNECT_LOOP, 1); - s->state = new_state; - } - } - skip = 0; - } - end: - s->in_handshake--; - if (buf != NULL) - BUF_MEM_free(buf); - if (cb != NULL) - cb(s, SSL_CB_CONNECT_EXIT, ret); - return (ret); -} - -int ssl3_client_hello(SSL *s) -{ - unsigned char *buf; - unsigned char *p, *d; - int i; - unsigned long l; - int al = 0; -#ifndef OPENSSL_NO_COMP - int j; - SSL_COMP *comp; -#endif - - buf = (unsigned char *)s->init_buf->data; - if (s->state == SSL3_ST_CW_CLNT_HELLO_A) { - SSL_SESSION *sess = s->session; - if ((sess == NULL) || (sess->ssl_version != s->version) || -#ifdef OPENSSL_NO_TLSEXT - !sess->session_id_length || -#else - /* - * In the case of EAP-FAST, we can have a pre-shared - * "ticket" without a session ID. - */ - (!sess->session_id_length && !sess->tlsext_tick) || -#endif - (sess->not_resumable)) { - if (!ssl_get_new_session(s, 0)) - goto err; - } - if (s->method->version == DTLS_ANY_VERSION) { - /* Determine which DTLS version to use */ - int options = s->options; - /* If DTLS 1.2 disabled correct the version number */ - if (options & SSL_OP_NO_DTLSv1_2) { - if (tls1_suiteb(s)) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, - SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); - goto err; - } - /* - * Disabling all versions is silly: return an error. - */ - if (options & SSL_OP_NO_DTLSv1) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_WRONG_SSL_VERSION); - goto err; - } - /* - * Update method so we don't use any DTLS 1.2 features. - */ - s->method = DTLSv1_client_method(); - s->version = DTLS1_VERSION; - } else { - /* - * We only support one version: update method - */ - if (options & SSL_OP_NO_DTLSv1) - s->method = DTLSv1_2_client_method(); - s->version = DTLS1_2_VERSION; - } - s->client_version = s->version; - } - /* else use the pre-loaded session */ - - p = s->s3->client_random; - - /* - * for DTLS if client_random is initialized, reuse it, we are - * required to use same upon reply to HelloVerify - */ - if (SSL_IS_DTLS(s)) { - size_t idx; - i = 1; - for (idx = 0; idx < sizeof(s->s3->client_random); idx++) { - if (p[idx]) { - i = 0; - break; - } - } - } else - i = 1; - - if (i && ssl_fill_hello_random(s, 0, p, - sizeof(s->s3->client_random)) <= 0) - goto err; - - /* Do the message type and length last */ - d = p = ssl_handshake_start(s); - - /*- - * version indicates the negotiated version: for example from - * an SSLv2/v3 compatible client hello). The client_version - * field is the maximum version we permit and it is also - * used in RSA encrypted premaster secrets. Some servers can - * choke if we initially report a higher version then - * renegotiate to a lower one in the premaster secret. This - * didn't happen with TLS 1.0 as most servers supported it - * but it can with TLS 1.1 or later if the server only supports - * 1.0. - * - * Possible scenario with previous logic: - * 1. Client hello indicates TLS 1.2 - * 2. Server hello says TLS 1.0 - * 3. RSA encrypted premaster secret uses 1.2. - * 4. Handhaked proceeds using TLS 1.0. - * 5. Server sends hello request to renegotiate. - * 6. Client hello indicates TLS v1.0 as we now - * know that is maximum server supports. - * 7. Server chokes on RSA encrypted premaster secret - * containing version 1.0. - * - * For interoperability it should be OK to always use the - * maximum version we support in client hello and then rely - * on the checking of version to ensure the servers isn't - * being inconsistent: for example initially negotiating with - * TLS 1.0 and renegotiating with TLS 1.2. We do this by using - * client_version in client hello and not resetting it to - * the negotiated version. - */ -#if 0 - *(p++) = s->version >> 8; - *(p++) = s->version & 0xff; - s->client_version = s->version; -#else - *(p++) = s->client_version >> 8; - *(p++) = s->client_version & 0xff; -#endif - - /* Random stuff */ - memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; - - /* Session ID */ - if (s->new_session) - i = 0; - else - i = s->session->session_id_length; - *(p++) = i; - if (i != 0) { - if (i > (int)sizeof(s->session->session_id)) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; - } - memcpy(p, s->session->session_id, i); - p += i; - } - - /* cookie stuff for DTLS */ - if (SSL_IS_DTLS(s)) { - if (s->d1->cookie_len > sizeof(s->d1->cookie)) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; - } - *(p++) = s->d1->cookie_len; - memcpy(p, s->d1->cookie, s->d1->cookie_len); - p += s->d1->cookie_len; - } - - /* Ciphers supported */ - i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), 0); - if (i == 0) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); - goto err; - } -#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH - /* - * Some servers hang if client hello > 256 bytes as hack workaround - * chop number of supported ciphers to keep it well below this if we - * use TLS v1.2 - */ - if (TLS1_get_version(s) >= TLS1_2_VERSION - && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH) - i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1; -#endif - s2n(i, p); - p += i; - - /* COMPRESSION */ -#ifdef OPENSSL_NO_COMP - *(p++) = 1; -#else - - if ((s->options & SSL_OP_NO_COMPRESSION) - || !s->ctx->comp_methods) - j = 0; - else - j = sk_SSL_COMP_num(s->ctx->comp_methods); - *(p++) = 1 + j; - for (i = 0; i < j; i++) { - comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); - *(p++) = comp->id; - } -#endif - *(p++) = 0; /* Add the NULL method */ - -#ifndef OPENSSL_NO_TLSEXT - /* TLS extensions */ - if (ssl_prepare_clienthello_tlsext(s) <= 0) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); - goto err; - } - if ((p = - ssl_add_clienthello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH, - &al)) == NULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; - } -#endif - - l = p - d; - ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l); - s->state = SSL3_ST_CW_CLNT_HELLO_B; - } - - /* SSL3_ST_CW_CLNT_HELLO_B */ - return ssl_do_write(s); - err: - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_get_server_hello(SSL *s) -{ - STACK_OF(SSL_CIPHER) *sk; - const SSL_CIPHER *c; - CERT *ct = s->cert; - unsigned char *p, *d; - int i, al = SSL_AD_INTERNAL_ERROR, ok; - unsigned int j; - long n; -#ifndef OPENSSL_NO_COMP - SSL_COMP *comp; -#endif - /* - * Hello verify request and/or server hello version may not match so set - * first packet if we're negotiating version. - */ - if (SSL_IS_DTLS(s)) - s->first_packet = 1; - - n = s->method->ssl_get_message(s, - SSL3_ST_CR_SRVR_HELLO_A, - SSL3_ST_CR_SRVR_HELLO_B, -1, 20000, &ok); - - if (!ok) - return ((int)n); - - if (SSL_IS_DTLS(s)) { - s->first_packet = 0; - if (s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST) { - if (s->d1->send_cookie == 0) { - s->s3->tmp.reuse_message = 1; - return 1; - } else { /* already sent a cookie */ - - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_MESSAGE_TYPE); - goto f_err; - } - } - } - - if (s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_MESSAGE_TYPE); - goto f_err; - } - - d = p = (unsigned char *)s->init_msg; - if (s->method->version == DTLS_ANY_VERSION) { - /* Work out correct protocol version to use */ - int hversion = (p[0] << 8) | p[1]; - int options = s->options; - if (hversion == DTLS1_2_VERSION && !(options & SSL_OP_NO_DTLSv1_2)) - s->method = DTLSv1_2_client_method(); - else if (tls1_suiteb(s)) { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); - s->version = hversion; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } else if (hversion == DTLS1_VERSION && !(options & SSL_OP_NO_DTLSv1)) - s->method = DTLSv1_client_method(); - else { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION); - s->version = hversion; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } - s->session->ssl_version = s->version = s->method->version; - } - - if ((p[0] != (s->version >> 8)) || (p[1] != (s->version & 0xff))) { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION); - s->version = (s->version & 0xff00) | p[1]; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } - p += 2; - - /* load the server hello data */ - /* load the server random */ - memcpy(s->s3->server_random, p, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; - - s->hit = 0; - - /* get the session-id */ - j = *(p++); - - if ((j > sizeof s->session->session_id) || (j > SSL3_SESSION_ID_SIZE)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_SSL3_SESSION_ID_TOO_LONG); - goto f_err; - } -#ifndef OPENSSL_NO_TLSEXT - /* - * Check if we can resume the session based on external pre-shared secret. - * EAP-FAST (RFC 4851) supports two types of session resumption. - * Resumption based on server-side state works with session IDs. - * Resumption based on pre-shared Protected Access Credentials (PACs) - * works by overriding the SessionTicket extension at the application - * layer, and does not send a session ID. (We do not know whether EAP-FAST - * servers would honour the session ID.) Therefore, the session ID alone - * is not a reliable indicator of session resumption, so we first check if - * we can resume, and later peek at the next handshake message to see if the - * server wants to resume. - */ - if (s->version >= TLS1_VERSION && s->tls_session_secret_cb && - s->session->tlsext_tick) { - SSL_CIPHER *pref_cipher = NULL; - s->session->master_key_length = sizeof(s->session->master_key); - if (s->tls_session_secret_cb(s, s->session->master_key, - &s->session->master_key_length, - NULL, &pref_cipher, - s->tls_session_secret_cb_arg)) { - s->session->cipher = pref_cipher ? - pref_cipher : ssl_get_cipher_by_char(s, p + j); - } else { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - } -#endif /* OPENSSL_NO_TLSEXT */ - - if (j != 0 && j == s->session->session_id_length - && memcmp(p, s->session->session_id, j) == 0) { - if (s->sid_ctx_length != s->session->sid_ctx_length - || memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) { - /* actually a client application bug */ - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); - goto f_err; - } - s->hit = 1; - } else { - /* - * If we were trying for session-id reuse but the server - * didn't echo the ID, make a new SSL_SESSION. - * In the case of EAP-FAST and PAC, we do not send a session ID, - * so the PAC-based session secret is always preserved. It'll be - * overwritten if the server refuses resumption. - */ - if (s->session->session_id_length > 0) { - if (!ssl_get_new_session(s, 0)) { - goto f_err; - } - } - s->session->session_id_length = j; - memcpy(s->session->session_id, p, j); /* j could be 0 */ - } - p += j; - c = ssl_get_cipher_by_char(s, p); - if (c == NULL) { - /* unknown cipher */ - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_UNKNOWN_CIPHER_RETURNED); - goto f_err; - } - /* Set version disabled mask now we know version */ - if (!SSL_USE_TLS1_2_CIPHERS(s)) - ct->mask_ssl = SSL_TLSV1_2; - else - ct->mask_ssl = 0; - /* - * If it is a disabled cipher we didn't send it in client hello, so - * return an error. - */ - if (c->algorithm_ssl & ct->mask_ssl || - c->algorithm_mkey & ct->mask_k || c->algorithm_auth & ct->mask_a) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED); - goto f_err; - } - p += ssl_put_cipher_by_char(s, NULL, NULL); - - sk = ssl_get_ciphers_by_id(s); - i = sk_SSL_CIPHER_find(sk, c); - if (i < 0) { - /* we did not say we would use this cipher */ - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED); - goto f_err; - } - - /* - * Depending on the session caching (internal/external), the cipher - * and/or cipher_id values may not be set. Make sure that cipher_id is - * set and use it for comparison. - */ - if (s->session->cipher) - s->session->cipher_id = s->session->cipher->id; - if (s->hit && (s->session->cipher_id != c->id)) { -/* Workaround is now obsolete */ -#if 0 - if (!(s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)) -#endif - { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); - goto f_err; - } - } - s->s3->tmp.new_cipher = c; - /* - * Don't digest cached records if no sigalgs: we may need them for client - * authentication. - */ - if (!SSL_USE_SIGALGS(s) && !ssl3_digest_cached_records(s)) - goto f_err; - /* lets get the compression algorithm */ - /* COMPRESSION */ -#ifdef OPENSSL_NO_COMP - if (*(p++) != 0) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); - goto f_err; - } - /* - * If compression is disabled we'd better not try to resume a session - * using compression. - */ - if (s->session->compress_meth != 0) { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_INCONSISTENT_COMPRESSION); - goto f_err; - } -#else - j = *(p++); - if (s->hit && j != s->session->compress_meth) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED); - goto f_err; - } - if (j == 0) - comp = NULL; - else if (s->options & SSL_OP_NO_COMPRESSION) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_COMPRESSION_DISABLED); - goto f_err; - } else - comp = ssl3_comp_find(s->ctx->comp_methods, j); - - if ((j != 0) && (comp == NULL)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); - goto f_err; - } else { - s->s3->tmp.new_compression = comp; - } -#endif - -#ifndef OPENSSL_NO_TLSEXT - /* TLS extensions */ - if (!ssl_parse_serverhello_tlsext(s, &p, d, n)) { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_PARSE_TLSEXT); - goto err; - } -#endif - - if (p != (d + n)) { - /* wrong packet length */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_PACKET_LENGTH); - goto f_err; - } - - return (1); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_get_server_certificate(SSL *s) -{ - int al, i, ok, ret = -1; - unsigned long n, nc, llen, l; - X509 *x = NULL; - const unsigned char *q, *p; - unsigned char *d; - STACK_OF(X509) *sk = NULL; - SESS_CERT *sc; - EVP_PKEY *pkey = NULL; - int need_cert = 1; /* VRS: 0=> will allow null cert if auth == - * KRB5 */ - - n = s->method->ssl_get_message(s, - SSL3_ST_CR_CERT_A, - SSL3_ST_CR_CERT_B, - -1, s->max_cert_list, &ok); - - if (!ok) - return ((int)n); - - if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) || - ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) && - (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE))) { - s->s3->tmp.reuse_message = 1; - return (1); - } - - if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, SSL_R_BAD_MESSAGE_TYPE); - goto f_err; - } - p = d = (unsigned char *)s->init_msg; - - if ((sk = sk_X509_new_null()) == NULL) { - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - - n2l3(p, llen); - if (llen + 3 != n) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - for (nc = 0; nc < llen;) { - if (nc + 3 > llen) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - n2l3(p, l); - if ((l + nc + 3) > llen) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - - q = p; - x = d2i_X509(NULL, &q, l); - if (x == NULL) { - al = SSL_AD_BAD_CERTIFICATE; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_ASN1_LIB); - goto f_err; - } - if (q != (p + l)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - if (!sk_X509_push(sk, x)) { - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - x = NULL; - nc += l + 3; - p = q; - } - - i = ssl_verify_cert_chain(s, sk); - if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0) -#ifndef OPENSSL_NO_KRB5 - && !((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) && - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) -#endif /* OPENSSL_NO_KRB5 */ - ) { - al = ssl_verify_alarm_type(s->verify_result); - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_CERTIFICATE_VERIFY_FAILED); - goto f_err; - } - ERR_clear_error(); /* but we keep s->verify_result */ - - sc = ssl_sess_cert_new(); - if (sc == NULL) - goto err; - - if (s->session->sess_cert) - ssl_sess_cert_free(s->session->sess_cert); - s->session->sess_cert = sc; - - sc->cert_chain = sk; - /* - * Inconsistency alert: cert_chain does include the peer's certificate, - * which we don't include in s3_srvr.c - */ - x = sk_X509_value(sk, 0); - sk = NULL; - /* - * VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end - */ - - pkey = X509_get_pubkey(x); - - /* VRS: allow null cert if auth == KRB5 */ - need_cert = ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) && - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) - ? 0 : 1; - -#ifdef KSSL_DEBUG - fprintf(stderr, "pkey,x = %p, %p\n", pkey, x); - fprintf(stderr, "ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x, pkey)); - fprintf(stderr, "cipher, alg, nc = %s, %lx, %lx, %d\n", - s->s3->tmp.new_cipher->name, - s->s3->tmp.new_cipher->algorithm_mkey, - s->s3->tmp.new_cipher->algorithm_auth, need_cert); -#endif /* KSSL_DEBUG */ - - if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))) { - x = NULL; - al = SSL3_AL_FATAL; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); - goto f_err; - } - - i = ssl_cert_type(x, pkey); - if (need_cert && i < 0) { - x = NULL; - al = SSL3_AL_FATAL; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_UNKNOWN_CERTIFICATE_TYPE); - goto f_err; - } - - if (need_cert) { - int exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher); - if (exp_idx >= 0 && i != exp_idx) { - x = NULL; - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_WRONG_CERTIFICATE_TYPE); - goto f_err; - } - sc->peer_cert_type = i; - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); - /* - * Why would the following ever happen? We just created sc a couple - * of lines ago. - */ - if (sc->peer_pkeys[i].x509 != NULL) - X509_free(sc->peer_pkeys[i].x509); - sc->peer_pkeys[i].x509 = x; - sc->peer_key = &(sc->peer_pkeys[i]); - - if (s->session->peer != NULL) - X509_free(s->session->peer); - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); - s->session->peer = x; - } else { - sc->peer_cert_type = i; - sc->peer_key = NULL; - - if (s->session->peer != NULL) - X509_free(s->session->peer); - s->session->peer = NULL; - } - s->session->verify_result = s->verify_result; - - x = NULL; - ret = 1; - if (0) { - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - s->state = SSL_ST_ERR; - } - - EVP_PKEY_free(pkey); - X509_free(x); - sk_X509_pop_free(sk, X509_free); - return (ret); -} - -int ssl3_get_key_exchange(SSL *s) -{ -#ifndef OPENSSL_NO_RSA - unsigned char *q, md_buf[EVP_MAX_MD_SIZE * 2]; -#endif - EVP_MD_CTX md_ctx; - unsigned char *param, *p; - int al, j, ok; - long i, param_len, n, alg_k, alg_a; - EVP_PKEY *pkey = NULL; - const EVP_MD *md = NULL; -#ifndef OPENSSL_NO_RSA - RSA *rsa = NULL; -#endif -#ifndef OPENSSL_NO_DH - DH *dh = NULL; -#endif -#ifndef OPENSSL_NO_ECDH - EC_KEY *ecdh = NULL; - BN_CTX *bn_ctx = NULL; - EC_POINT *srvr_ecpoint = NULL; - int curve_nid = 0; - int encoded_pt_len = 0; -#endif - - EVP_MD_CTX_init(&md_ctx); - - /* - * use same message size as in ssl3_get_certificate_request() as - * ServerKeyExchange message may be skipped - */ - n = s->method->ssl_get_message(s, - SSL3_ST_CR_KEY_EXCH_A, - SSL3_ST_CR_KEY_EXCH_B, - -1, s->max_cert_list, &ok); - if (!ok) - return ((int)n); - - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - - if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) { - /* - * Can't skip server key exchange if this is an ephemeral - * ciphersuite. - */ - if (alg_k & (SSL_kDHE | SSL_kECDHE)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); - al = SSL_AD_UNEXPECTED_MESSAGE; - goto f_err; - } -#ifndef OPENSSL_NO_PSK - /* - * In plain PSK ciphersuite, ServerKeyExchange can be omitted if no - * identity hint is sent. Set session->sess_cert anyway to avoid - * problems later. - */ - if (alg_k & SSL_kPSK) { - s->session->sess_cert = ssl_sess_cert_new(); - if (s->ctx->psk_identity_hint) - OPENSSL_free(s->ctx->psk_identity_hint); - s->ctx->psk_identity_hint = NULL; - } -#endif - s->s3->tmp.reuse_message = 1; - return (1); - } - - param = p = (unsigned char *)s->init_msg; - if (s->session->sess_cert != NULL) { -#ifndef OPENSSL_NO_RSA - if (s->session->sess_cert->peer_rsa_tmp != NULL) { - RSA_free(s->session->sess_cert->peer_rsa_tmp); - s->session->sess_cert->peer_rsa_tmp = NULL; - } -#endif -#ifndef OPENSSL_NO_DH - if (s->session->sess_cert->peer_dh_tmp) { - DH_free(s->session->sess_cert->peer_dh_tmp); - s->session->sess_cert->peer_dh_tmp = NULL; - } -#endif -#ifndef OPENSSL_NO_ECDH - if (s->session->sess_cert->peer_ecdh_tmp) { - EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp); - s->session->sess_cert->peer_ecdh_tmp = NULL; - } -#endif - } else { - s->session->sess_cert = ssl_sess_cert_new(); - } - - /* Total length of the parameters including the length prefix */ - param_len = 0; - - alg_a = s->s3->tmp.new_cipher->algorithm_auth; - - al = SSL_AD_DECODE_ERROR; - -#ifndef OPENSSL_NO_PSK - if (alg_k & SSL_kPSK) { - param_len = 2; - if (param_len > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p, i); - - /* - * Store PSK identity hint for later use, hint is used in - * ssl3_send_client_key_exchange. Assume that the maximum length of - * a PSK identity hint can be as long as the maximum length of a PSK - * identity. - */ - if (i > PSK_MAX_IDENTITY_LEN) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG); - goto f_err; - } - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, - SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH); - goto f_err; - } - param_len += i; - - s->session->psk_identity_hint = BUF_strndup((char *)p, i); - if (s->session->psk_identity_hint == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto f_err; - } - - p += i; - n -= param_len; - } else -#endif /* !OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_SRP - if (alg_k & SSL_kSRP) { - param_len = 2; - if (param_len > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_N_LENGTH); - goto f_err; - } - param_len += i; - - if (!(s->srp_ctx.N = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - - if (2 > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - param_len += 2; - - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_G_LENGTH); - goto f_err; - } - param_len += i; - - if (!(s->srp_ctx.g = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - - if (1 > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - param_len += 1; - - i = (unsigned int)(p[0]); - p++; - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_S_LENGTH); - goto f_err; - } - param_len += i; - - if (!(s->srp_ctx.s = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - - if (2 > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - param_len += 2; - - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_B_LENGTH); - goto f_err; - } - param_len += i; - - if (!(s->srp_ctx.B = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - n -= param_len; - - if (!srp_verify_server_param(s, &al)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_PARAMETERS); - goto f_err; - } - -/* We must check if there is a certificate */ -# ifndef OPENSSL_NO_RSA - if (alg_a & SSL_aRSA) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); -# else - if (0) ; -# endif -# ifndef OPENSSL_NO_DSA - else if (alg_a & SSL_aDSS) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN]. - x509); -# endif - } else -#endif /* !OPENSSL_NO_SRP */ -#ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { - /* Temporary RSA keys only allowed in export ciphersuites */ - if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - if ((rsa = RSA_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - param_len = 2; - if (param_len > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_MODULUS_LENGTH); - goto f_err; - } - param_len += i; - - if (!(rsa->n = BN_bin2bn(p, i, rsa->n))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - - if (2 > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - param_len += 2; - - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_E_LENGTH); - goto f_err; - } - param_len += i; - - if (!(rsa->e = BN_bin2bn(p, i, rsa->e))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - n -= param_len; - - /* this should be because we are using an export cipher */ - if (alg_a & SSL_aRSA) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); - else { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (EVP_PKEY_bits(pkey) <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - - s->session->sess_cert->peer_rsa_tmp = rsa; - rsa = NULL; - } -#else /* OPENSSL_NO_RSA */ - if (0) ; -#endif -#ifndef OPENSSL_NO_DH - else if (alg_k & SSL_kEDH) { - if ((dh = DH_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_DH_LIB); - goto err; - } - - param_len = 2; - if (param_len > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_LENGTH); - goto f_err; - } - param_len += i; - - if (!(dh->p = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - - if (2 > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - param_len += 2; - - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_LENGTH); - goto f_err; - } - param_len += i; - - if (!(dh->g = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - - if (2 > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - param_len += 2; - - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_LENGTH); - goto f_err; - } - param_len += i; - - if (!(dh->pub_key = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - n -= param_len; - - if (BN_is_zero(dh->pub_key)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_VALUE); - goto f_err; - } - - /*- - * Check that p and g are suitable enough - * - * p is odd - * 1 < g < p - 1 - */ - { - BIGNUM *tmp = NULL; - - if (!BN_is_odd(dh->p)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE); - goto f_err; - } - if (BN_is_negative(dh->g) || BN_is_zero(dh->g) - || BN_is_one(dh->g)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE); - goto f_err; - } - if ((tmp = BN_new()) == NULL - || BN_copy(tmp, dh->p) == NULL - || !BN_sub_word(tmp, 1)) { - BN_free(tmp); - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - if (BN_cmp(dh->g, tmp) >= 0) { - BN_free(tmp); - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE); - goto f_err; - } - BN_free(tmp); - } - -# ifndef OPENSSL_NO_RSA - if (alg_a & SSL_aRSA) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); -# else - if (0) ; -# endif -# ifndef OPENSSL_NO_DSA - else if (alg_a & SSL_aDSS) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN]. - x509); -# endif - /* else anonymous DH, so no certificate or pkey. */ - - s->session->sess_cert->peer_dh_tmp = dh; - dh = NULL; - } else if ((alg_k & SSL_kDHr) || (alg_k & SSL_kDHd)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, - SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER); - goto f_err; - } -#endif /* !OPENSSL_NO_DH */ - -#ifndef OPENSSL_NO_ECDH - else if (alg_k & SSL_kEECDH) { - EC_GROUP *ngroup; - const EC_GROUP *group; - - if ((ecdh = EC_KEY_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * Extract elliptic curve parameters and the server's ephemeral ECDH - * public key. Keep accumulating lengths of various components in - * param_len and make sure it never exceeds n. - */ - - /* - * XXX: For now we only support named (not generic) curves and the - * ECParameters in this case is just three bytes. We also need one - * byte for the length of the encoded point - */ - param_len = 4; - if (param_len > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - /* - * Check curve is one of our preferences, if not server has sent an - * invalid curve. ECParameters is 3 bytes. - */ - if (!tls1_check_curve(s, p, 3)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_CURVE); - goto f_err; - } - - if ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, - SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); - goto f_err; - } - - ngroup = EC_GROUP_new_by_curve_name(curve_nid); - if (ngroup == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - if (EC_KEY_set_group(ecdh, ngroup) == 0) { - EC_GROUP_free(ngroup); - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - EC_GROUP_free(ngroup); - - group = EC_KEY_get0_group(ecdh); - - if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - (EC_GROUP_get_degree(group) > 163)) { - al = SSL_AD_EXPORT_RESTRICTION; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, - SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); - goto f_err; - } - - p += 3; - - /* Next, get the encoded ECPoint */ - if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) || - ((bn_ctx = BN_CTX_new()) == NULL)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - encoded_pt_len = *p; /* length of encoded point */ - p += 1; - - if ((encoded_pt_len > n - param_len) || - (EC_POINT_oct2point(group, srvr_ecpoint, - p, encoded_pt_len, bn_ctx) == 0)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT); - goto f_err; - } - param_len += encoded_pt_len; - - n -= param_len; - p += encoded_pt_len; - - /* - * The ECC/TLS specification does not mention the use of DSA to sign - * ECParameters in the server key exchange message. We do support RSA - * and ECDSA. - */ - if (0) ; -# ifndef OPENSSL_NO_RSA - else if (alg_a & SSL_aRSA) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); -# endif -# ifndef OPENSSL_NO_ECDSA - else if (alg_a & SSL_aECDSA) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); -# endif - /* else anonymous ECDH, so no certificate or pkey. */ - EC_KEY_set_public_key(ecdh, srvr_ecpoint); - s->session->sess_cert->peer_ecdh_tmp = ecdh; - ecdh = NULL; - BN_CTX_free(bn_ctx); - bn_ctx = NULL; - EC_POINT_free(srvr_ecpoint); - srvr_ecpoint = NULL; - } else if (alg_k) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } -#endif /* !OPENSSL_NO_ECDH */ - - /* p points to the next byte, there are 'n' bytes left */ - - /* if it was signed, check the signature */ - if (pkey != NULL) { - if (SSL_USE_SIGALGS(s)) { - int rv; - if (2 > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - rv = tls12_check_peer_sigalg(&md, s, p, pkey); - if (rv == -1) - goto err; - else if (rv == 0) { - goto f_err; - } -#ifdef SSL_DEBUG - fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); -#endif - p += 2; - n -= 2; - } else - md = EVP_sha1(); - - if (2 > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p, i); - n -= 2; - j = EVP_PKEY_size(pkey); - - /* - * Check signature length. If n is 0 then signature is empty - */ - if ((i != n) || (n > j) || (n <= 0)) { - /* wrong packet length */ - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_SIGNATURE_LENGTH); - goto f_err; - } -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { - int num; - unsigned int size; - - j = 0; - q = md_buf; - for (num = 2; num > 0; num--) { - EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - if (EVP_DigestInit_ex(&md_ctx, - (num == 2) ? s->ctx->md5 : s->ctx->sha1, - NULL) <= 0 - || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(&md_ctx, param, param_len) <= 0 - || EVP_DigestFinal_ex(&md_ctx, q, &size) <= 0) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - q += size; - j += size; - } - i = RSA_verify(NID_md5_sha1, md_buf, j, p, n, pkey->pkey.rsa); - if (i < 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_DECRYPT); - goto f_err; - } - if (i == 0) { - /* bad signature */ - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE); - goto f_err; - } - } else -#endif - { - if (EVP_VerifyInit_ex(&md_ctx, md, NULL) <= 0 - || EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_VerifyUpdate(&md_ctx, param, param_len) <= 0) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EVP_LIB); - goto f_err; - } - if (EVP_VerifyFinal(&md_ctx, p, (int)n, pkey) <= 0) { - /* bad signature */ - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE); - goto f_err; - } - } - } else { - /* aNULL, aSRP or kPSK do not need public keys */ - if (!(alg_a & (SSL_aNULL | SSL_aSRP)) && !(alg_k & SSL_kPSK)) { - /* Might be wrong key type, check it */ - if (ssl3_check_cert_and_algorithm(s)) - /* Otherwise this shouldn't happen */ - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - /* still data left over */ - if (n != 0) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_EXTRA_DATA_IN_MESSAGE); - goto f_err; - } - } - EVP_PKEY_free(pkey); - EVP_MD_CTX_cleanup(&md_ctx); - return (1); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - EVP_PKEY_free(pkey); -#ifndef OPENSSL_NO_RSA - if (rsa != NULL) - RSA_free(rsa); -#endif -#ifndef OPENSSL_NO_DH - if (dh != NULL) - DH_free(dh); -#endif -#ifndef OPENSSL_NO_ECDH - BN_CTX_free(bn_ctx); - EC_POINT_free(srvr_ecpoint); - if (ecdh != NULL) - EC_KEY_free(ecdh); -#endif - EVP_MD_CTX_cleanup(&md_ctx); - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_get_certificate_request(SSL *s) -{ - int ok, ret = 0; - unsigned long n, nc, l; - unsigned int llen, ctype_num, i; - X509_NAME *xn = NULL; - const unsigned char *p, *q; - unsigned char *d; - STACK_OF(X509_NAME) *ca_sk = NULL; - - n = s->method->ssl_get_message(s, - SSL3_ST_CR_CERT_REQ_A, - SSL3_ST_CR_CERT_REQ_B, - -1, s->max_cert_list, &ok); - - if (!ok) - return ((int)n); - - s->s3->tmp.cert_req = 0; - - if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE) { - s->s3->tmp.reuse_message = 1; - /* - * If we get here we don't need any cached handshake records as we - * wont be doing client auth. - */ - if (s->s3->handshake_buffer) { - if (!ssl3_digest_cached_records(s)) - goto err; - } - return (1); - } - - if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_WRONG_MESSAGE_TYPE); - goto err; - } - - /* TLS does not like anon-DH with client cert */ - if (s->version > SSL3_VERSION) { - if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, - SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER); - goto err; - } - } - - p = d = (unsigned char *)s->init_msg; - - if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) { - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* get the certificate types */ - ctype_num = *(p++); - if (s->cert->ctypes) { - OPENSSL_free(s->cert->ctypes); - s->cert->ctypes = NULL; - } - if (ctype_num > SSL3_CT_NUMBER) { - /* If we exceed static buffer copy all to cert structure */ - s->cert->ctypes = OPENSSL_malloc(ctype_num); - if (s->cert->ctypes == NULL) { - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); - goto err; - } - memcpy(s->cert->ctypes, p, ctype_num); - s->cert->ctype_num = (size_t)ctype_num; - ctype_num = SSL3_CT_NUMBER; - } - for (i = 0; i < ctype_num; i++) - s->s3->tmp.ctype[i] = p[i]; - p += p[-1]; - if (SSL_USE_SIGALGS(s)) { - n2s(p, llen); - /* - * Check we have enough room for signature algorithms and following - * length value. - */ - if ((unsigned long)(p - d + llen + 2) > n) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - /* Clear certificate digests and validity flags */ - for (i = 0; i < SSL_PKEY_NUM; i++) { - s->cert->pkeys[i].digest = NULL; - s->cert->pkeys[i].valid_flags = 0; - } - if ((llen & 1) || !tls1_save_sigalgs(s, p, llen)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, - SSL_R_SIGNATURE_ALGORITHMS_ERROR); - goto err; - } - if (!tls1_process_sigalgs(s)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); - goto err; - } - p += llen; - } - - /* get the CA RDNs */ - n2s(p, llen); -#if 0 - { - FILE *out; - out = fopen("/tmp/vsign.der", "w"); - fwrite(p, 1, llen, out); - fclose(out); - } -#endif - - if ((unsigned long)(p - d + llen) != n) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH); - goto err; - } - - for (nc = 0; nc < llen;) { - if (nc + 2 > llen) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); - goto err; - } - n2s(p, l); - if ((l + nc + 2) > llen) { - if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) - goto cont; /* netscape bugs */ - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); - goto err; - } - - q = p; - - if ((xn = d2i_X509_NAME(NULL, &q, l)) == NULL) { - /* If netscape tolerance is on, ignore errors */ - if (s->options & SSL_OP_NETSCAPE_CA_DN_BUG) - goto cont; - else { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_ASN1_LIB); - goto err; - } - } - - if (q != (p + l)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, - SSL_R_CA_DN_LENGTH_MISMATCH); - goto err; - } - if (!sk_X509_NAME_push(ca_sk, xn)) { - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); - goto err; - } - xn = NULL; - - p += l; - nc += l + 2; - } - - if (0) { - cont: - ERR_clear_error(); - } - - /* we should setup a certificate to return.... */ - s->s3->tmp.cert_req = 1; - s->s3->tmp.ctype_num = ctype_num; - if (s->s3->tmp.ca_names != NULL) - sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); - s->s3->tmp.ca_names = ca_sk; - ca_sk = NULL; - - ret = 1; - goto done; - err: - s->state = SSL_ST_ERR; - done: - X509_NAME_free(xn); - if (ca_sk != NULL) - sk_X509_NAME_pop_free(ca_sk, X509_NAME_free); - return (ret); -} - -static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b) -{ - return (X509_NAME_cmp(*a, *b)); -} - -#ifndef OPENSSL_NO_TLSEXT -int ssl3_get_new_session_ticket(SSL *s) -{ - int ok, al, ret = 0, ticklen; - long n; - const unsigned char *p; - unsigned char *d; - unsigned long ticket_lifetime_hint; - - n = s->method->ssl_get_message(s, - SSL3_ST_CR_SESSION_TICKET_A, - SSL3_ST_CR_SESSION_TICKET_B, - SSL3_MT_NEWSESSION_TICKET, 16384, &ok); - - if (!ok) - return ((int)n); - - if (n < 6) { - /* need at least ticket_lifetime_hint + ticket length */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - - p = d = (unsigned char *)s->init_msg; - - n2l(p, ticket_lifetime_hint); - n2s(p, ticklen); - /* ticket_lifetime_hint + ticket_length + ticket */ - if (ticklen + 6 != n) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - - /* Server is allowed to change its mind and send an empty ticket. */ - if (ticklen == 0) - return 1; - - if (s->session->session_id_length > 0) { - int i = s->session_ctx->session_cache_mode; - SSL_SESSION *new_sess; - /* - * We reused an existing session, so we need to replace it with a new - * one - */ - if (i & SSL_SESS_CACHE_CLIENT) { - /* - * Remove the old session from the cache - */ - if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE) { - if (s->session_ctx->remove_session_cb != NULL) - s->session_ctx->remove_session_cb(s->session_ctx, - s->session); - } else { - /* We carry on if this fails */ - SSL_CTX_remove_session(s->session_ctx, s->session); - } - } - - if ((new_sess = ssl_session_dup(s->session, 0)) == 0) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); - goto f_err; - } - - SSL_SESSION_free(s->session); - s->session = new_sess; - } - - if (s->session->tlsext_tick) { - OPENSSL_free(s->session->tlsext_tick); - s->session->tlsext_ticklen = 0; - } - s->session->tlsext_tick = OPENSSL_malloc(ticklen); - if (!s->session->tlsext_tick) { - SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); - goto err; - } - memcpy(s->session->tlsext_tick, p, ticklen); - s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint; - s->session->tlsext_ticklen = ticklen; - /* - * There are two ways to detect a resumed ticket session. One is to set - * an appropriate session ID and then the server must return a match in - * ServerHello. This allows the normal client session ID matching to work - * and we know much earlier that the ticket has been accepted. The - * other way is to set zero length session ID when the ticket is - * presented and rely on the handshake to determine session resumption. - * We choose the former approach because this fits in with assumptions - * elsewhere in OpenSSL. The session ID is set to the SHA256 (or SHA1 is - * SHA256 is disabled) hash of the ticket. - */ - EVP_Digest(p, ticklen, - s->session->session_id, &s->session->session_id_length, -# ifndef OPENSSL_NO_SHA256 - EVP_sha256(), NULL); -# else - EVP_sha1(), NULL); -# endif - ret = 1; - return (ret); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_get_cert_status(SSL *s) -{ - int ok, al; - unsigned long resplen, n; - const unsigned char *p; - - n = s->method->ssl_get_message(s, - SSL3_ST_CR_CERT_STATUS_A, - SSL3_ST_CR_CERT_STATUS_B, - -1, 16384, &ok); - - if (!ok) - return ((int)n); - - if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_STATUS) { - /* - * The CertificateStatus message is optional even if - * tlsext_status_expected is set - */ - s->s3->tmp.reuse_message = 1; - } else { - if (n < 4) { - /* need at least status type + length */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - p = (unsigned char *)s->init_msg; - if (*p++ != TLSEXT_STATUSTYPE_ocsp) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_UNSUPPORTED_STATUS_TYPE); - goto f_err; - } - n2l3(p, resplen); - if (resplen + 4 != n) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - s->tlsext_ocsp_resp = BUF_memdup(p, resplen); - if (s->tlsext_ocsp_resp == NULL) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_STATUS, ERR_R_MALLOC_FAILURE); - goto f_err; - } - s->tlsext_ocsp_resplen = resplen; - } - if (s->ctx->tlsext_status_cb) { - int ret; - ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); - if (ret == 0) { - al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; - SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_INVALID_STATUS_RESPONSE); - goto f_err; - } - if (ret < 0) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_STATUS, ERR_R_MALLOC_FAILURE); - goto f_err; - } - } - return 1; - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - s->state = SSL_ST_ERR; - return (-1); -} -#endif - -int ssl3_get_server_done(SSL *s) -{ - int ok, ret = 0; - long n; - - /* Second to last param should be very small, like 0 :-) */ - n = s->method->ssl_get_message(s, - SSL3_ST_CR_SRVR_DONE_A, - SSL3_ST_CR_SRVR_DONE_B, - SSL3_MT_SERVER_DONE, 30, &ok); - - if (!ok) - return ((int)n); - if (n > 0) { - /* should contain no data */ - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_SERVER_DONE, SSL_R_LENGTH_MISMATCH); - s->state = SSL_ST_ERR; - return -1; - } - ret = 1; - return (ret); -} - -#ifndef OPENSSL_NO_DH -static DH *get_server_static_dh_key(SESS_CERT *scert) -{ - DH *dh_srvr = NULL; - EVP_PKEY *spkey = NULL; - int idx = scert->peer_cert_type; - - if (idx >= 0) - spkey = X509_get_pubkey(scert->peer_pkeys[idx].x509); - if (spkey) { - dh_srvr = EVP_PKEY_get1_DH(spkey); - EVP_PKEY_free(spkey); - } - if (dh_srvr == NULL) - SSLerr(SSL_F_GET_SERVER_STATIC_DH_KEY, ERR_R_INTERNAL_ERROR); - return dh_srvr; -} -#endif - -int ssl3_send_client_key_exchange(SSL *s) -{ - unsigned char *p; - int n; - unsigned long alg_k; -#ifndef OPENSSL_NO_RSA - unsigned char *q; - EVP_PKEY *pkey = NULL; -#endif -#ifndef OPENSSL_NO_KRB5 - KSSL_ERR kssl_err; -#endif /* OPENSSL_NO_KRB5 */ -#ifndef OPENSSL_NO_ECDH - EC_KEY *clnt_ecdh = NULL; - const EC_POINT *srvr_ecpoint = NULL; - EVP_PKEY *srvr_pub_pkey = NULL; - unsigned char *encodedPoint = NULL; - int encoded_pt_len = 0; - BN_CTX *bn_ctx = NULL; -#endif - - if (s->state == SSL3_ST_CW_KEY_EXCH_A) { - p = ssl_handshake_start(s); - - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - - /* Fool emacs indentation */ - if (0) { - } -#ifndef OPENSSL_NO_RSA - else if (alg_k & SSL_kRSA) { - RSA *rsa; - unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; - - if (s->session->sess_cert == NULL) { - /* - * We should always have a server certificate with SSL_kRSA. - */ - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - if (s->session->sess_cert->peer_rsa_tmp != NULL) - rsa = s->session->sess_cert->peer_rsa_tmp; - else { - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC]. - x509); - if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) - || (pkey->pkey.rsa == NULL)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - EVP_PKEY_free(pkey); - goto err; - } - rsa = pkey->pkey.rsa; - EVP_PKEY_free(pkey); - } - - tmp_buf[0] = s->client_version >> 8; - tmp_buf[1] = s->client_version & 0xff; - if (RAND_bytes(&(tmp_buf[2]), sizeof tmp_buf - 2) <= 0) - goto err; - - s->session->master_key_length = sizeof tmp_buf; - - q = p; - /* Fix buf for TLS and beyond */ - if (s->version > SSL3_VERSION) - p += 2; - n = RSA_public_encrypt(sizeof tmp_buf, - tmp_buf, p, rsa, RSA_PKCS1_PADDING); -# ifdef PKCS1_CHECK - if (s->options & SSL_OP_PKCS1_CHECK_1) - p[1]++; - if (s->options & SSL_OP_PKCS1_CHECK_2) - tmp_buf[0] = 0x70; -# endif - if (n <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_BAD_RSA_ENCRYPT); - goto err; - } - - /* Fix buf for TLS and beyond */ - if (s->version > SSL3_VERSION) { - s2n(n, q); - n += 2; - } - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - tmp_buf, - sizeof tmp_buf); - OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); - } -#endif -#ifndef OPENSSL_NO_KRB5 - else if (alg_k & SSL_kKRB5) { - krb5_error_code krb5rc; - KSSL_CTX *kssl_ctx = s->kssl_ctx; - /* krb5_data krb5_ap_req; */ - krb5_data *enc_ticket; - krb5_data authenticator, *authp = NULL; - EVP_CIPHER_CTX ciph_ctx; - const EVP_CIPHER *enc = NULL; - unsigned char iv[EVP_MAX_IV_LENGTH]; - unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; - unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_IV_LENGTH]; - int padl, outl = sizeof(epms); - - EVP_CIPHER_CTX_init(&ciph_ctx); - -# ifdef KSSL_DEBUG - fprintf(stderr, "ssl3_send_client_key_exchange(%lx & %lx)\n", - alg_k, SSL_kKRB5); -# endif /* KSSL_DEBUG */ - - authp = NULL; -# ifdef KRB5SENDAUTH - if (KRB5SENDAUTH) - authp = &authenticator; -# endif /* KRB5SENDAUTH */ - - krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp, &kssl_err); - enc = kssl_map_enc(kssl_ctx->enctype); - if (enc == NULL) - goto err; -# ifdef KSSL_DEBUG - { - fprintf(stderr, "kssl_cget_tkt rtn %d\n", krb5rc); - if (krb5rc && kssl_err.text) - fprintf(stderr, "kssl_cget_tkt kssl_err=%s\n", - kssl_err.text); - } -# endif /* KSSL_DEBUG */ - - if (krb5rc) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, kssl_err.reason); - goto err; - } - - /*- - * 20010406 VRS - Earlier versions used KRB5 AP_REQ - * in place of RFC 2712 KerberosWrapper, as in: - * - * Send ticket (copy to *p, set n = length) - * n = krb5_ap_req.length; - * memcpy(p, krb5_ap_req.data, krb5_ap_req.length); - * if (krb5_ap_req.data) - * kssl_krb5_free_data_contents(NULL,&krb5_ap_req); - * - * Now using real RFC 2712 KerberosWrapper - * (Thanks to Simon Wilkinson <sxw@sxw.org.uk>) - * Note: 2712 "opaque" types are here replaced - * with a 2-byte length followed by the value. - * Example: - * KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms - * Where "xx xx" = length bytes. Shown here with - * optional authenticator omitted. - */ - - /* KerberosWrapper.Ticket */ - s2n(enc_ticket->length, p); - memcpy(p, enc_ticket->data, enc_ticket->length); - p += enc_ticket->length; - n = enc_ticket->length + 2; - - /* KerberosWrapper.Authenticator */ - if (authp && authp->length) { - s2n(authp->length, p); - memcpy(p, authp->data, authp->length); - p += authp->length; - n += authp->length + 2; - - free(authp->data); - authp->data = NULL; - authp->length = 0; - } else { - s2n(0, p); /* null authenticator length */ - n += 2; - } - - tmp_buf[0] = s->client_version >> 8; - tmp_buf[1] = s->client_version & 0xff; - if (RAND_bytes(&(tmp_buf[2]), sizeof tmp_buf - 2) <= 0) - goto err; - - /*- - * 20010420 VRS. Tried it this way; failed. - * EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL); - * EVP_CIPHER_CTX_set_key_length(&ciph_ctx, - * kssl_ctx->length); - * EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv); - */ - - memset(iv, 0, sizeof iv); /* per RFC 1510 */ - EVP_EncryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv); - EVP_EncryptUpdate(&ciph_ctx, epms, &outl, tmp_buf, - sizeof tmp_buf); - EVP_EncryptFinal_ex(&ciph_ctx, &(epms[outl]), &padl); - outl += padl; - if (outl > (int)sizeof epms) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - EVP_CIPHER_CTX_cleanup(&ciph_ctx); - - /* KerberosWrapper.EncryptedPreMasterSecret */ - s2n(outl, p); - memcpy(p, epms, outl); - p += outl; - n += outl + 2; - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - tmp_buf, - sizeof tmp_buf); - - OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); - OPENSSL_cleanse(epms, outl); - } -#endif -#ifndef OPENSSL_NO_DH - else if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) { - DH *dh_srvr, *dh_clnt; - SESS_CERT *scert = s->session->sess_cert; - - if (scert == NULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_UNEXPECTED_MESSAGE); - goto err; - } - - if (scert->peer_dh_tmp != NULL) { - dh_srvr = scert->peer_dh_tmp; - } else { - dh_srvr = get_server_static_dh_key(scert); - if (dh_srvr == NULL) - goto err; - } - - if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { - /* Use client certificate key */ - EVP_PKEY *clkey = s->cert->key->privatekey; - dh_clnt = NULL; - if (clkey) - dh_clnt = EVP_PKEY_get1_DH(clkey); - if (dh_clnt == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - } else { - /* generate a new random key */ - if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); - goto err; - } - if (!DH_generate_key(dh_clnt)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); - DH_free(dh_clnt); - goto err; - } - } - - /* - * use the 'p' output buffer for the DH key, but make sure to - * clear it out afterwards - */ - - n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt); - if (scert->peer_dh_tmp == NULL) - DH_free(dh_srvr); - - if (n <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); - DH_free(dh_clnt); - goto err; - } - - /* generate master key from the result */ - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, n); - /* clean up */ - memset(p, 0, n); - - if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) - n = 0; - else { - /* send off the data */ - n = BN_num_bytes(dh_clnt->pub_key); - s2n(n, p); - BN_bn2bin(dh_clnt->pub_key, p); - n += 2; - } - - DH_free(dh_clnt); - } -#endif - -#ifndef OPENSSL_NO_ECDH - else if (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) { - const EC_GROUP *srvr_group = NULL; - EC_KEY *tkey; - int ecdh_clnt_cert = 0; - int field_size = 0; - - if (s->session->sess_cert == NULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_UNEXPECTED_MESSAGE); - goto err; - } - - /* - * Did we send out the client's ECDH share for use in premaster - * computation as part of client certificate? If so, set - * ecdh_clnt_cert to 1. - */ - if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->cert != NULL)) { - /*- - * XXX: For now, we do not support client - * authentication using ECDH certificates. - * To add such support, one needs to add - * code that checks for appropriate - * conditions and sets ecdh_clnt_cert to 1. - * For example, the cert have an ECC - * key on the same curve as the server's - * and the key should be authorized for - * key agreement. - * - * One also needs to add code in ssl3_connect - * to skip sending the certificate verify - * message. - * - * if ((s->cert->key->privatekey != NULL) && - * (s->cert->key->privatekey->type == - * EVP_PKEY_EC) && ...) - * ecdh_clnt_cert = 1; - */ - } - - if (s->session->sess_cert->peer_ecdh_tmp != NULL) { - tkey = s->session->sess_cert->peer_ecdh_tmp; - } else { - /* Get the Server Public Key from Cert */ - srvr_pub_pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); - if ((srvr_pub_pkey == NULL) - || (srvr_pub_pkey->type != EVP_PKEY_EC) - || (srvr_pub_pkey->pkey.ec == NULL)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - tkey = srvr_pub_pkey->pkey.ec; - } - - srvr_group = EC_KEY_get0_group(tkey); - srvr_ecpoint = EC_KEY_get0_public_key(tkey); - - if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - if ((clnt_ecdh = EC_KEY_new()) == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - if (ecdh_clnt_cert) { - /* - * Reuse key info from our certificate We only need our - * private key to perform the ECDH computation. - */ - const BIGNUM *priv_key; - tkey = s->cert->key->privatekey->pkey.ec; - priv_key = EC_KEY_get0_private_key(tkey); - if (priv_key == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - } else { - /* Generate a new ECDH key pair */ - if (!(EC_KEY_generate_key(clnt_ecdh))) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_ECDH_LIB); - goto err; - } - } - - /* - * use the 'p' output buffer for the ECDH key, but make sure to - * clear it out afterwards - */ - - field_size = EC_GROUP_get_degree(srvr_group); - if (field_size <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - n = ECDH_compute_key(p, (field_size + 7) / 8, srvr_ecpoint, - clnt_ecdh, NULL); - if (n <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - - /* generate master key from the result */ - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, n); - - memset(p, 0, n); /* clean up */ - - if (ecdh_clnt_cert) { - /* Send empty client key exch message */ - n = 0; - } else { - /* - * First check the size of encoding and allocate memory - * accordingly. - */ - encoded_pt_len = - EC_POINT_point2oct(srvr_group, - EC_KEY_get0_public_key(clnt_ecdh), - POINT_CONVERSION_UNCOMPRESSED, - NULL, 0, NULL); - - encodedPoint = (unsigned char *) - OPENSSL_malloc(encoded_pt_len * sizeof(unsigned char)); - bn_ctx = BN_CTX_new(); - if ((encodedPoint == NULL) || (bn_ctx == NULL)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Encode the public key */ - n = EC_POINT_point2oct(srvr_group, - EC_KEY_get0_public_key(clnt_ecdh), - POINT_CONVERSION_UNCOMPRESSED, - encodedPoint, encoded_pt_len, bn_ctx); - - *p = n; /* length of encoded point */ - /* Encoded point will be copied here */ - p += 1; - /* copy the point */ - memcpy((unsigned char *)p, encodedPoint, n); - /* increment n to account for length field */ - n += 1; - } - - /* Free allocated memory */ - BN_CTX_free(bn_ctx); - if (encodedPoint != NULL) - OPENSSL_free(encodedPoint); - if (clnt_ecdh != NULL) - EC_KEY_free(clnt_ecdh); - EVP_PKEY_free(srvr_pub_pkey); - } -#endif /* !OPENSSL_NO_ECDH */ - else if (alg_k & SSL_kGOST) { - /* GOST key exchange message creation */ - EVP_PKEY_CTX *pkey_ctx; - X509 *peer_cert; - size_t msglen; - unsigned int md_len; - int keytype; - unsigned char premaster_secret[32], shared_ukm[32], tmp[256]; - EVP_MD_CTX *ukm_hash; - EVP_PKEY *pub_key; - - /* - * Get server sertificate PKEY and create ctx from it - */ - peer_cert = - s->session-> - sess_cert->peer_pkeys[(keytype = SSL_PKEY_GOST01)].x509; - if (!peer_cert) - peer_cert = - s->session-> - sess_cert->peer_pkeys[(keytype = SSL_PKEY_GOST94)].x509; - if (!peer_cert) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); - goto err; - } - - pkey_ctx = EVP_PKEY_CTX_new(pub_key = - X509_get_pubkey(peer_cert), NULL); - if (pkey_ctx == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - /* - * If we have send a certificate, and certificate key - * - * * parameters match those of server certificate, use - * certificate key for key exchange - */ - - /* Otherwise, generate ephemeral key pair */ - - if (pkey_ctx == NULL - || EVP_PKEY_encrypt_init(pkey_ctx) <= 0 - /* Generate session key */ - || RAND_bytes(premaster_secret, 32) <= 0) { - EVP_PKEY_CTX_free(pkey_ctx); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - /* - * Compute shared IV and store it in algorithm-specific context - * data - */ - ukm_hash = EVP_MD_CTX_create(); - if (EVP_DigestInit(ukm_hash, - EVP_get_digestbynid(NID_id_GostR3411_94)) <= 0 - || EVP_DigestUpdate(ukm_hash, s->s3->client_random, - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(ukm_hash, s->s3->server_random, - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) { - EVP_MD_CTX_destroy(ukm_hash); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - EVP_MD_CTX_destroy(ukm_hash); - if (EVP_PKEY_CTX_ctrl - (pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8, - shared_ukm) < 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_LIBRARY_BUG); - goto err; - } - /* Make GOST keytransport blob message */ - /* - * Encapsulate it into sequence - */ - *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED; - msglen = 255; - if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, 32) - <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_LIBRARY_BUG); - goto err; - } - if (msglen >= 0x80) { - *(p++) = 0x81; - *(p++) = msglen & 0xff; - n = msglen + 3; - } else { - *(p++) = msglen & 0xff; - n = msglen + 2; - } - memcpy(p, tmp, msglen); - EVP_PKEY_CTX_free(pkey_ctx); - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - premaster_secret, - 32); - EVP_PKEY_free(pub_key); - - } -#ifndef OPENSSL_NO_SRP - else if (alg_k & SSL_kSRP) { - if (s->srp_ctx.A != NULL) { - /* send off the data */ - n = BN_num_bytes(s->srp_ctx.A); - s2n(n, p); - BN_bn2bin(s->srp_ctx.A, p); - n += 2; - } else { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - if (s->session->srp_username != NULL) - OPENSSL_free(s->session->srp_username); - s->session->srp_username = BUF_strdup(s->srp_ctx.login); - if (s->session->srp_username == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - if ((s->session->master_key_length = - SRP_generate_client_master_secret(s, - s->session->master_key)) < - 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - } -#endif -#ifndef OPENSSL_NO_PSK - else if (alg_k & SSL_kPSK) { - /* - * The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes to return a - * \0-terminated identity. The last byte is for us for simulating - * strnlen. - */ - char identity[PSK_MAX_IDENTITY_LEN + 2]; - size_t identity_len; - unsigned char *t = NULL; - unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4]; - unsigned int pre_ms_len = 0, psk_len = 0; - int psk_err = 1; - - n = 0; - if (s->psk_client_callback == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_NO_CLIENT_CB); - goto err; - } - - memset(identity, 0, sizeof(identity)); - psk_len = s->psk_client_callback(s, s->session->psk_identity_hint, - identity, sizeof(identity) - 1, - psk_or_pre_ms, - sizeof(psk_or_pre_ms)); - if (psk_len > PSK_MAX_PSK_LEN) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto psk_err; - } else if (psk_len == 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_IDENTITY_NOT_FOUND); - goto psk_err; - } - identity[PSK_MAX_IDENTITY_LEN + 1] = '\0'; - identity_len = strlen(identity); - if (identity_len > PSK_MAX_IDENTITY_LEN) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto psk_err; - } - /* create PSK pre_master_secret */ - pre_ms_len = 2 + psk_len + 2 + psk_len; - t = psk_or_pre_ms; - memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len); - s2n(psk_len, t); - memset(t, 0, psk_len); - t += psk_len; - s2n(psk_len, t); - - if (s->session->psk_identity_hint != NULL) - OPENSSL_free(s->session->psk_identity_hint); - s->session->psk_identity_hint = - BUF_strdup(s->ctx->psk_identity_hint); - if (s->ctx->psk_identity_hint != NULL - && s->session->psk_identity_hint == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto psk_err; - } - - if (s->session->psk_identity != NULL) - OPENSSL_free(s->session->psk_identity); - s->session->psk_identity = BUF_strdup(identity); - if (s->session->psk_identity == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto psk_err; - } - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - psk_or_pre_ms, - pre_ms_len); - s2n(identity_len, p); - memcpy(p, identity, identity_len); - n = 2 + identity_len; - psk_err = 0; - psk_err: - OPENSSL_cleanse(identity, sizeof(identity)); - OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); - if (psk_err != 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - goto err; - } - } -#endif - else { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - - ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, n); - s->state = SSL3_ST_CW_KEY_EXCH_B; - } - - /* SSL3_ST_CW_KEY_EXCH_B */ - return ssl_do_write(s); - err: -#ifndef OPENSSL_NO_ECDH - BN_CTX_free(bn_ctx); - if (encodedPoint != NULL) - OPENSSL_free(encodedPoint); - if (clnt_ecdh != NULL) - EC_KEY_free(clnt_ecdh); - EVP_PKEY_free(srvr_pub_pkey); -#endif - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_send_client_verify(SSL *s) -{ - unsigned char *p; - unsigned char data[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; - EVP_PKEY *pkey; - EVP_PKEY_CTX *pctx = NULL; - EVP_MD_CTX mctx; - unsigned u = 0; - unsigned long n; - int j; - - EVP_MD_CTX_init(&mctx); - - if (s->state == SSL3_ST_CW_CERT_VRFY_A) { - p = ssl_handshake_start(s); - pkey = s->cert->key->privatekey; -/* Create context from key and test if sha1 is allowed as digest */ - pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (pctx == NULL || EVP_PKEY_sign_init(pctx) <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) { - if (!SSL_USE_SIGALGS(s)) - s->method->ssl3_enc->cert_verify_mac(s, - NID_sha1, - &(data - [MD5_DIGEST_LENGTH])); - } else { - ERR_clear_error(); - } - /* - * For TLS v1.2 send signature algorithm and signature using agreed - * digest and cached handshake records. - */ - if (SSL_USE_SIGALGS(s)) { - long hdatalen = 0; - void *hdata; - const EVP_MD *md = s->cert->key->digest; - hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); - if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - p += 2; -#ifdef SSL_DEBUG - fprintf(stderr, "Using TLS 1.2 with client alg %s\n", - EVP_MD_name(md)); -#endif - if (!EVP_SignInit_ex(&mctx, md, NULL) - || !EVP_SignUpdate(&mctx, hdata, hdatalen) - || !EVP_SignFinal(&mctx, p + 2, &u, pkey)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_EVP_LIB); - goto err; - } - s2n(u, p); - n = u + 4; - if (!ssl3_digest_cached_records(s)) - goto err; - } else -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) { - s->method->ssl3_enc->cert_verify_mac(s, NID_md5, &(data[0])); - if (RSA_sign(NID_md5_sha1, data, - MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, - &(p[2]), &u, pkey->pkey.rsa) <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_RSA_LIB); - goto err; - } - s2n(u, p); - n = u + 2; - } else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) { - if (!DSA_sign(pkey->save_type, - &(data[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, &(p[2]), - (unsigned int *)&j, pkey->pkey.dsa)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_DSA_LIB); - goto err; - } - s2n(j, p); - n = j + 2; - } else -#endif -#ifndef OPENSSL_NO_ECDSA - if (pkey->type == EVP_PKEY_EC) { - if (!ECDSA_sign(pkey->save_type, - &(data[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, &(p[2]), - (unsigned int *)&j, pkey->pkey.ec)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_ECDSA_LIB); - goto err; - } - s2n(j, p); - n = j + 2; - } else -#endif - if (pkey->type == NID_id_GostR3410_94 - || pkey->type == NID_id_GostR3410_2001) { - unsigned char signbuf[64]; - int i; - size_t sigsize = 64; - s->method->ssl3_enc->cert_verify_mac(s, - NID_id_GostR3411_94, data); - if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - for (i = 63, j = 0; i >= 0; j++, i--) { - p[2 + j] = signbuf[i]; - } - s2n(j, p); - n = j + 2; - } else { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n); - s->state = SSL3_ST_CW_CERT_VRFY_B; - } - EVP_MD_CTX_cleanup(&mctx); - EVP_PKEY_CTX_free(pctx); - return ssl_do_write(s); - err: - EVP_MD_CTX_cleanup(&mctx); - EVP_PKEY_CTX_free(pctx); - s->state = SSL_ST_ERR; - return (-1); -} - -/* - * Check a certificate can be used for client authentication. Currently check - * cert exists, if we have a suitable digest for TLS 1.2 if static DH client - * certificates can be used and optionally checks suitability for Suite B. - */ -static int ssl3_check_client_certificate(SSL *s) -{ - unsigned long alg_k; - if (!s->cert || !s->cert->key->x509 || !s->cert->key->privatekey) - return 0; - /* If no suitable signature algorithm can't use certificate */ - if (SSL_USE_SIGALGS(s) && !s->cert->key->digest) - return 0; - /* - * If strict mode check suitability of chain before using it. This also - * adjusts suite B digest if necessary. - */ - if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT && - !tls1_check_chain(s, NULL, NULL, NULL, -2)) - return 0; - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - /* See if we can use client certificate for fixed DH */ - if (alg_k & (SSL_kDHr | SSL_kDHd)) { - SESS_CERT *scert = s->session->sess_cert; - int i = scert->peer_cert_type; - EVP_PKEY *clkey = NULL, *spkey = NULL; - clkey = s->cert->key->privatekey; - /* If client key not DH assume it can be used */ - if (EVP_PKEY_id(clkey) != EVP_PKEY_DH) - return 1; - if (i >= 0) - spkey = X509_get_pubkey(scert->peer_pkeys[i].x509); - if (spkey) { - /* Compare server and client parameters */ - i = EVP_PKEY_cmp_parameters(clkey, spkey); - EVP_PKEY_free(spkey); - if (i != 1) - return 0; - } - s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; - } - return 1; -} - -int ssl3_send_client_certificate(SSL *s) -{ - X509 *x509 = NULL; - EVP_PKEY *pkey = NULL; - int i; - - if (s->state == SSL3_ST_CW_CERT_A) { - /* Let cert callback update client certificates if required */ - if (s->cert->cert_cb) { - i = s->cert->cert_cb(s, s->cert->cert_cb_arg); - if (i < 0) { - s->rwstate = SSL_X509_LOOKUP; - return -1; - } - if (i == 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return 0; - } - s->rwstate = SSL_NOTHING; - } - if (ssl3_check_client_certificate(s)) - s->state = SSL3_ST_CW_CERT_C; - else - s->state = SSL3_ST_CW_CERT_B; - } - - /* We need to get a client cert */ - if (s->state == SSL3_ST_CW_CERT_B) { - /* - * If we get an error, we need to ssl->rwstate=SSL_X509_LOOKUP; - * return(-1); We then get retied later - */ - i = ssl_do_client_cert_cb(s, &x509, &pkey); - if (i < 0) { - s->rwstate = SSL_X509_LOOKUP; - return (-1); - } - s->rwstate = SSL_NOTHING; - if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { - s->state = SSL3_ST_CW_CERT_B; - if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) - i = 0; - } else if (i == 1) { - i = 0; - SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, - SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); - } - - if (x509 != NULL) - X509_free(x509); - if (pkey != NULL) - EVP_PKEY_free(pkey); - if (i && !ssl3_check_client_certificate(s)) - i = 0; - if (i == 0) { - if (s->version == SSL3_VERSION) { - s->s3->tmp.cert_req = 0; - ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE); - return (1); - } else { - s->s3->tmp.cert_req = 2; - } - } - - /* Ok, we have a cert */ - s->state = SSL3_ST_CW_CERT_C; - } - - if (s->state == SSL3_ST_CW_CERT_C) { - s->state = SSL3_ST_CW_CERT_D; - if (!ssl3_output_cert_chain(s, - (s->s3->tmp.cert_req == - 2) ? NULL : s->cert->key)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return 0; - } - } - /* SSL3_ST_CW_CERT_D */ - return ssl_do_write(s); -} - -#define has_bits(i,m) (((i)&(m)) == (m)) - -int ssl3_check_cert_and_algorithm(SSL *s) -{ - int i, idx; - long alg_k, alg_a; - EVP_PKEY *pkey = NULL; - int pkey_bits; - SESS_CERT *sc; -#ifndef OPENSSL_NO_RSA - RSA *rsa; -#endif -#ifndef OPENSSL_NO_DH - DH *dh; -#endif - int al = SSL_AD_HANDSHAKE_FAILURE; - - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - alg_a = s->s3->tmp.new_cipher->algorithm_auth; - - /* we don't have a certificate */ - if ((alg_a & (SSL_aNULL | SSL_aKRB5)) || (alg_k & SSL_kPSK)) - return (1); - - sc = s->session->sess_cert; - if (sc == NULL) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); - goto err; - } -#ifndef OPENSSL_NO_RSA - rsa = s->session->sess_cert->peer_rsa_tmp; -#endif -#ifndef OPENSSL_NO_DH - dh = s->session->sess_cert->peer_dh_tmp; -#endif - - /* This is the passed certificate */ - - idx = sc->peer_cert_type; -#ifndef OPENSSL_NO_ECDH - if (idx == SSL_PKEY_ECC) { - if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509, s) == 0) { - /* check failed */ - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_BAD_ECC_CERT); - goto f_err; - } else { - return 1; - } - } else if (alg_a & SSL_aECDSA) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_ECDSA_SIGNING_CERT); - goto f_err; - } else if (alg_k & (SSL_kECDHr | SSL_kECDHe)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_MISSING_ECDH_CERT); - goto f_err; - } -#endif - pkey = X509_get_pubkey(sc->peer_pkeys[idx].x509); - pkey_bits = EVP_PKEY_bits(pkey); - i = X509_certificate_type(sc->peer_pkeys[idx].x509, pkey); - EVP_PKEY_free(pkey); - - /* Check that we have a certificate if we require one */ - if ((alg_a & SSL_aRSA) && !has_bits(i, EVP_PK_RSA | EVP_PKT_SIGN)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_RSA_SIGNING_CERT); - goto f_err; - } -#ifndef OPENSSL_NO_DSA - else if ((alg_a & SSL_aDSS) && !has_bits(i, EVP_PK_DSA | EVP_PKT_SIGN)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_DSA_SIGNING_CERT); - goto f_err; - } -#endif -#ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { - if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_RSA_ENCRYPTING_CERT); - goto f_err; - } else if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { - if (pkey_bits <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { - if (!has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_RSA_ENCRYPTING_CERT); - goto f_err; - } - if (rsa != NULL) { - /* server key exchange is not allowed. */ - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); - goto f_err; - } - } - } - } -#endif -#ifndef OPENSSL_NO_DH - if ((alg_k & SSL_kEDH) && dh == NULL) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); - goto f_err; - } - if ((alg_k & SSL_kDHr) && !SSL_USE_SIGALGS(s) && - !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_DH_RSA_CERT); - goto f_err; - } -# ifndef OPENSSL_NO_DSA - if ((alg_k & SSL_kDHd) && !SSL_USE_SIGALGS(s) && - !has_bits(i, EVP_PK_DH | EVP_PKS_DSA)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_DH_DSA_CERT); - goto f_err; - } -# endif - - if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd)) { - int dh_size; - if (alg_k & SSL_kDHE) { - dh_size = BN_num_bits(dh->p); - } else { - DH *dh_srvr = get_server_static_dh_key(sc); - if (dh_srvr == NULL) - goto f_err; - dh_size = BN_num_bits(dh_srvr->p); - DH_free(dh_srvr); - } - - if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 1024) - || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL); - goto f_err; - } - } -#endif /* !OPENSSL_NO_DH */ - - if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { -#ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { - if (rsa == NULL) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_EXPORT_TMP_RSA_KEY); - goto f_err; - } else if (BN_num_bits(rsa->n) > - SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { - /* We have a temporary RSA key but it's too large. */ - al = SSL_AD_EXPORT_RESTRICTION; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_EXPORT_TMP_RSA_KEY); - goto f_err; - } - } else -#endif -#ifndef OPENSSL_NO_DH - if (alg_k & SSL_kDHE) { - if (BN_num_bits(dh->p) > - SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { - /* We have a temporary DH key but it's too large. */ - al = SSL_AD_EXPORT_RESTRICTION; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_EXPORT_TMP_DH_KEY); - goto f_err; - } - } else if (alg_k & (SSL_kDHr | SSL_kDHd)) { - /* The cert should have had an export DH key. */ - al = SSL_AD_EXPORT_RESTRICTION; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_EXPORT_TMP_DH_KEY); - goto f_err; - } else -#endif - { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); - goto f_err; - } - } - return (1); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - return (0); -} - -#ifndef OPENSSL_NO_TLSEXT -/* - * Normally, we can tell if the server is resuming the session from - * the session ID. EAP-FAST (RFC 4851), however, relies on the next server - * message after the ServerHello to determine if the server is resuming. - * Therefore, we allow EAP-FAST to peek ahead. - * ssl3_check_finished returns 1 if we are resuming from an external - * pre-shared secret, we have a "ticket" and the next server handshake message - * is Finished; and 0 otherwise. It returns -1 upon an error. - */ -static int ssl3_check_finished(SSL *s) -{ - int ok = 0; - - if (s->version < TLS1_VERSION || !s->tls_session_secret_cb || - !s->session->tlsext_tick) - return 0; - - /* Need to permit this temporarily, in case the next message is Finished. */ - s->s3->flags |= SSL3_FLAGS_CCS_OK; - /* - * This function is called when we might get a Certificate message instead, - * so permit appropriate message length. - * We ignore the return value as we're only interested in the message type - * and not its length. - */ - s->method->ssl_get_message(s, - SSL3_ST_CR_CERT_A, - SSL3_ST_CR_CERT_B, - -1, s->max_cert_list, &ok); - s->s3->flags &= ~SSL3_FLAGS_CCS_OK; - - if (!ok) - return -1; - - s->s3->tmp.reuse_message = 1; - - if (s->s3->tmp.message_type == SSL3_MT_FINISHED) - return 1; - - /* If we're not done, then the CCS arrived early and we should bail. */ - if (s->s3->change_cipher_spec) { - SSLerr(SSL_F_SSL3_CHECK_FINISHED, SSL_R_CCS_RECEIVED_EARLY); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); - return -1; - } - - return 0; -} - -# ifndef OPENSSL_NO_NEXTPROTONEG -int ssl3_send_next_proto(SSL *s) -{ - unsigned int len, padding_len; - unsigned char *d; - - if (s->state == SSL3_ST_CW_NEXT_PROTO_A) { - len = s->next_proto_negotiated_len; - padding_len = 32 - ((len + 2) % 32); - d = (unsigned char *)s->init_buf->data; - d[4] = len; - memcpy(d + 5, s->next_proto_negotiated, len); - d[5 + len] = padding_len; - memset(d + 6 + len, 0, padding_len); - *(d++) = SSL3_MT_NEXT_PROTO; - l2n3(2 + len + padding_len, d); - s->state = SSL3_ST_CW_NEXT_PROTO_B; - s->init_num = 4 + 2 + len + padding_len; - s->init_off = 0; - } - - return ssl3_do_write(s, SSL3_RT_HANDSHAKE); -} -#endif /* !OPENSSL_NO_NEXTPROTONEG */ -#endif /* !OPENSSL_NO_TLSEXT */ - -int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) -{ - int i = 0; -#ifndef OPENSSL_NO_ENGINE - if (s->ctx->client_cert_engine) { - i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s, - SSL_get_client_CA_list(s), - px509, ppkey, NULL, NULL, NULL); - if (i != 0) - return i; - } -#endif - if (s->ctx->client_cert_cb) - i = s->ctx->client_cert_cb(s, px509, ppkey); - return i; -} diff --git a/thirdparty/openssl/ssl/s3_enc.c b/thirdparty/openssl/ssl/s3_enc.c deleted file mode 100644 index 1eee9d9b21..0000000000 --- a/thirdparty/openssl/ssl/s3_enc.c +++ /dev/null @@ -1,1000 +0,0 @@ -/* ssl/s3_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 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 - * openssl-core@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). - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include <stdio.h> -#include "ssl_locl.h" -#include <openssl/evp.h> -#include <openssl/md5.h> - -static unsigned char ssl3_pad_1[48] = { - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 -}; - -static unsigned char ssl3_pad_2[48] = { - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c -}; - -static int ssl3_handshake_mac(SSL *s, int md_nid, - const char *sender, int len, unsigned char *p); -static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) -{ - EVP_MD_CTX m5; - EVP_MD_CTX s1; - unsigned char buf[16], smd[SHA_DIGEST_LENGTH]; - unsigned char c = 'A'; - unsigned int i, j, k; - -#ifdef CHARSET_EBCDIC - c = os_toascii[c]; /* 'A' in ASCII */ -#endif - k = 0; - EVP_MD_CTX_init(&m5); - EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - EVP_MD_CTX_init(&s1); - for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) { - k++; - if (k > sizeof(buf)) - /* bug: 'buf' is too small for this ciphersuite */ - goto err; - - for (j = 0; j < k; j++) - buf[j] = c; - c++; - if (!EVP_DigestInit_ex(&s1, EVP_sha1(), NULL) || - !EVP_DigestUpdate(&s1, buf, k) || - !EVP_DigestUpdate(&s1, s->session->master_key, - s->session->master_key_length) || - !EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE) || - !EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE) || - !EVP_DigestFinal_ex(&s1, smd, NULL)) - goto err2; - - if (!EVP_DigestInit_ex(&m5, EVP_md5(), NULL) || - !EVP_DigestUpdate(&m5, s->session->master_key, - s->session->master_key_length) || - !EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH)) - goto err2; - if ((int)(i + MD5_DIGEST_LENGTH) > num) { - if (!EVP_DigestFinal_ex(&m5, smd, NULL)) - goto err2; - memcpy(km, smd, (num - i)); - } else - if (!EVP_DigestFinal_ex(&m5, km, NULL)) - goto err2; - - km += MD5_DIGEST_LENGTH; - } - OPENSSL_cleanse(smd, SHA_DIGEST_LENGTH); - EVP_MD_CTX_cleanup(&m5); - EVP_MD_CTX_cleanup(&s1); - return 1; - err: - SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); - err2: - EVP_MD_CTX_cleanup(&m5); - EVP_MD_CTX_cleanup(&s1); - return 0; -} - -int ssl3_change_cipher_state(SSL *s, int which) -{ - unsigned char *p, *mac_secret; - unsigned char exp_key[EVP_MAX_KEY_LENGTH]; - unsigned char exp_iv[EVP_MAX_IV_LENGTH]; - unsigned char *ms, *key, *iv, *er1, *er2; - EVP_CIPHER_CTX *dd; - const EVP_CIPHER *c; -#ifndef OPENSSL_NO_COMP - COMP_METHOD *comp; -#endif - const EVP_MD *m; - EVP_MD_CTX md; - int is_exp, n, i, j, k, cl; - int reuse_dd = 0; - - is_exp = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); - c = s->s3->tmp.new_sym_enc; - m = s->s3->tmp.new_hash; - /* m == NULL will lead to a crash later */ - OPENSSL_assert(m); -#ifndef OPENSSL_NO_COMP - if (s->s3->tmp.new_compression == NULL) - comp = NULL; - else - comp = s->s3->tmp.new_compression->method; -#endif - - if (which & SSL3_CC_READ) { - if (s->enc_read_ctx != NULL) - reuse_dd = 1; - else if ((s->enc_read_ctx = - OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) - goto err; - else - /* - * make sure it's intialized in case we exit later with an error - */ - EVP_CIPHER_CTX_init(s->enc_read_ctx); - dd = s->enc_read_ctx; - - if (ssl_replace_hash(&s->read_hash, m) == NULL) { - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } -#ifndef OPENSSL_NO_COMP - /* COMPRESS */ - if (s->expand != NULL) { - COMP_CTX_free(s->expand); - s->expand = NULL; - } - if (comp != NULL) { - s->expand = COMP_CTX_new(comp); - if (s->expand == NULL) { - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, - SSL_R_COMPRESSION_LIBRARY_ERROR); - goto err2; - } - if (s->s3->rrec.comp == NULL) - s->s3->rrec.comp = (unsigned char *) - OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH); - if (s->s3->rrec.comp == NULL) - goto err; - } -#endif - memset(&(s->s3->read_sequence[0]), 0, 8); - mac_secret = &(s->s3->read_mac_secret[0]); - } else { - if (s->enc_write_ctx != NULL) - reuse_dd = 1; - else if ((s->enc_write_ctx = - OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) - goto err; - else - /* - * make sure it's intialized in case we exit later with an error - */ - EVP_CIPHER_CTX_init(s->enc_write_ctx); - dd = s->enc_write_ctx; - if (ssl_replace_hash(&s->write_hash, m) == NULL) { - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } -#ifndef OPENSSL_NO_COMP - /* COMPRESS */ - if (s->compress != NULL) { - COMP_CTX_free(s->compress); - s->compress = NULL; - } - if (comp != NULL) { - s->compress = COMP_CTX_new(comp); - if (s->compress == NULL) { - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, - SSL_R_COMPRESSION_LIBRARY_ERROR); - goto err2; - } - } -#endif - memset(&(s->s3->write_sequence[0]), 0, 8); - mac_secret = &(s->s3->write_mac_secret[0]); - } - - if (reuse_dd) - EVP_CIPHER_CTX_cleanup(dd); - - p = s->s3->tmp.key_block; - i = EVP_MD_size(m); - if (i < 0) - goto err2; - cl = EVP_CIPHER_key_length(c); - j = is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? - cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; - /* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */ - k = EVP_CIPHER_iv_length(c); - if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || - (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { - ms = &(p[0]); - n = i + i; - key = &(p[n]); - n += j + j; - iv = &(p[n]); - n += k + k; - er1 = &(s->s3->client_random[0]); - er2 = &(s->s3->server_random[0]); - } else { - n = i; - ms = &(p[n]); - n += i + j; - key = &(p[n]); - n += j + k; - iv = &(p[n]); - n += k; - er1 = &(s->s3->server_random[0]); - er2 = &(s->s3->client_random[0]); - } - - if (n > s->s3->tmp.key_block_length) { - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } - - EVP_MD_CTX_init(&md); - memcpy(mac_secret, ms, i); - if (is_exp) { - /* - * In here I set both the read and write key/iv to the same value - * since only the correct one will be used :-). - */ - if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) || - !EVP_DigestUpdate(&md, key, j) || - !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) || - !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) || - !EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL)) { - EVP_MD_CTX_cleanup(&md); - goto err2; - } - key = &(exp_key[0]); - - if (k > 0) { - if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) || - !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) || - !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) || - !EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL)) { - EVP_MD_CTX_cleanup(&md); - goto err2; - } - iv = &(exp_iv[0]); - } - } - EVP_MD_CTX_cleanup(&md); - - s->session->key_arg_length = 0; - - if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) - goto err2; - -#ifdef OPENSSL_SSL_TRACE_CRYPTO - if (s->msg_callback) { - - int wh = which & SSL3_CC_WRITE ? - TLS1_RT_CRYPTO_WRITE : TLS1_RT_CRYPTO_READ; - s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC, - mac_secret, EVP_MD_size(m), s, s->msg_callback_arg); - if (c->key_len) - s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY, - key, c->key_len, s, s->msg_callback_arg); - if (k) { - s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_IV, - iv, k, s, s->msg_callback_arg); - } - } -#endif - - OPENSSL_cleanse(&(exp_key[0]), sizeof(exp_key)); - OPENSSL_cleanse(&(exp_iv[0]), sizeof(exp_iv)); - return (1); - err: - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); - err2: - return (0); -} - -int ssl3_setup_key_block(SSL *s) -{ - unsigned char *p; - const EVP_CIPHER *c; - const EVP_MD *hash; - int num; - int ret = 0; - SSL_COMP *comp; - - if (s->s3->tmp.key_block_length != 0) - return (1); - - if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp)) { - SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); - return (0); - } - - s->s3->tmp.new_sym_enc = c; - s->s3->tmp.new_hash = hash; -#ifdef OPENSSL_NO_COMP - s->s3->tmp.new_compression = NULL; -#else - s->s3->tmp.new_compression = comp; -#endif - - num = EVP_MD_size(hash); - if (num < 0) - return 0; - - num = EVP_CIPHER_key_length(c) + num + EVP_CIPHER_iv_length(c); - num *= 2; - - ssl3_cleanup_key_block(s); - - if ((p = OPENSSL_malloc(num)) == NULL) - goto err; - - s->s3->tmp.key_block_length = num; - s->s3->tmp.key_block = p; - - ret = ssl3_generate_key_block(s, p, num); - - if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) { - /* - * enable vulnerability countermeasure for CBC ciphers with known-IV - * problem (http://www.openssl.org/~bodo/tls-cbc.txt) - */ - s->s3->need_empty_fragments = 1; - - if (s->session->cipher != NULL) { - if (s->session->cipher->algorithm_enc == SSL_eNULL) - s->s3->need_empty_fragments = 0; - -#ifndef OPENSSL_NO_RC4 - if (s->session->cipher->algorithm_enc == SSL_RC4) - s->s3->need_empty_fragments = 0; -#endif - } - } - - return ret; - - err: - SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); - return (0); -} - -void ssl3_cleanup_key_block(SSL *s) -{ - if (s->s3->tmp.key_block != NULL) { - OPENSSL_cleanse(s->s3->tmp.key_block, s->s3->tmp.key_block_length); - OPENSSL_free(s->s3->tmp.key_block); - s->s3->tmp.key_block = NULL; - } - s->s3->tmp.key_block_length = 0; -} - -/*- - * ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. - * - * Returns: - * 0: (in non-constant time) if the record is publically invalid (i.e. too - * short etc). - * 1: if the record's padding is valid / the encryption was successful. - * -1: if the record's padding is invalid or, if sending, an internal error - * occured. - */ -int ssl3_enc(SSL *s, int send) -{ - SSL3_RECORD *rec; - EVP_CIPHER_CTX *ds; - unsigned long l; - int bs, i, mac_size = 0; - const EVP_CIPHER *enc; - - if (send) { - ds = s->enc_write_ctx; - rec = &(s->s3->wrec); - if (s->enc_write_ctx == NULL) - enc = NULL; - else - enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); - } else { - ds = s->enc_read_ctx; - rec = &(s->s3->rrec); - if (s->enc_read_ctx == NULL) - enc = NULL; - else - enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); - } - - if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { - memmove(rec->data, rec->input, rec->length); - rec->input = rec->data; - } else { - l = rec->length; - bs = EVP_CIPHER_block_size(ds->cipher); - - /* COMPRESS */ - - if ((bs != 1) && send) { - i = bs - ((int)l % bs); - - /* we need to add 'i-1' padding bytes */ - l += i; - /* - * the last of these zero bytes will be overwritten with the - * padding length. - */ - memset(&rec->input[rec->length], 0, i); - rec->length += i; - rec->input[l - 1] = (i - 1); - } - - if (!send) { - if (l == 0 || l % bs != 0) - return 0; - /* otherwise, rec->length >= bs */ - } - - if (EVP_Cipher(ds, rec->data, rec->input, l) < 1) - return -1; - - if (EVP_MD_CTX_md(s->read_hash) != NULL) - mac_size = EVP_MD_CTX_size(s->read_hash); - if ((bs != 1) && !send) - return ssl3_cbc_remove_padding(s, rec, bs, mac_size); - } - return 1; -} - -int ssl3_init_finished_mac(SSL *s) -{ - if (s->s3->handshake_buffer) - BIO_free(s->s3->handshake_buffer); - if (s->s3->handshake_dgst) - ssl3_free_digest_list(s); - s->s3->handshake_buffer = BIO_new(BIO_s_mem()); - if (s->s3->handshake_buffer == NULL) - return 0; - (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE); - return 1; -} - -void ssl3_free_digest_list(SSL *s) -{ - int i; - if (!s->s3->handshake_dgst) - return; - for (i = 0; i < SSL_MAX_DIGEST; i++) { - if (s->s3->handshake_dgst[i]) - EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]); - } - OPENSSL_free(s->s3->handshake_dgst); - s->s3->handshake_dgst = NULL; -} - -void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len) -{ - if (s->s3->handshake_buffer - && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) { - BIO_write(s->s3->handshake_buffer, (void *)buf, len); - } else { - int i; - for (i = 0; i < SSL_MAX_DIGEST; i++) { - if (s->s3->handshake_dgst[i] != NULL) - EVP_DigestUpdate(s->s3->handshake_dgst[i], buf, len); - } - } -} - -int ssl3_digest_cached_records(SSL *s) -{ - int i; - long mask; - const EVP_MD *md; - long hdatalen; - void *hdata; - - /* Allocate handshake_dgst array */ - ssl3_free_digest_list(s); - s->s3->handshake_dgst = - OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); - if (s->s3->handshake_dgst == NULL) { - SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE); - return 0; - } - memset(s->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); - hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); - if (hdatalen <= 0) { - SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH); - return 0; - } - - /* Loop through bitso of algorithm2 field and create MD_CTX-es */ - for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) { - if ((mask & ssl_get_algorithm2(s)) && md) { - s->s3->handshake_dgst[i] = EVP_MD_CTX_create(); - if (s->s3->handshake_dgst[i] == NULL) { - SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE); - return 0; - } -#ifdef OPENSSL_FIPS - if (EVP_MD_nid(md) == NID_md5) { - EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i], - EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - } -#endif - if (!EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL) - || !EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, - hdatalen)) { - SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_INTERNAL_ERROR); - return 0; - } - } else { - s->s3->handshake_dgst[i] = NULL; - } - } - if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) { - /* Free handshake_buffer BIO */ - BIO_free(s->s3->handshake_buffer); - s->s3->handshake_buffer = NULL; - } - - return 1; -} - -int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p) -{ - return (ssl3_handshake_mac(s, md_nid, NULL, 0, p)); -} - -int ssl3_final_finish_mac(SSL *s, - const char *sender, int len, unsigned char *p) -{ - int ret, sha1len; - ret = ssl3_handshake_mac(s, NID_md5, sender, len, p); - if (ret == 0) - return 0; - - p += ret; - - sha1len = ssl3_handshake_mac(s, NID_sha1, sender, len, p); - if (sha1len == 0) - return 0; - - ret += sha1len; - return (ret); -} - -static int ssl3_handshake_mac(SSL *s, int md_nid, - const char *sender, int len, unsigned char *p) -{ - unsigned int ret; - int npad, n; - unsigned int i; - unsigned char md_buf[EVP_MAX_MD_SIZE]; - EVP_MD_CTX ctx, *d = NULL; - - if (s->s3->handshake_buffer) - if (!ssl3_digest_cached_records(s)) - return 0; - - /* - * Search for digest of specified type in the handshake_dgst array - */ - for (i = 0; i < SSL_MAX_DIGEST; i++) { - if (s->s3->handshake_dgst[i] - && EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) { - d = s->s3->handshake_dgst[i]; - break; - } - } - if (!d) { - SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, SSL_R_NO_REQUIRED_DIGEST); - return 0; - } - EVP_MD_CTX_init(&ctx); - EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - EVP_MD_CTX_copy_ex(&ctx, d); - n = EVP_MD_CTX_size(&ctx); - if (n < 0) - return 0; - - npad = (48 / n) * n; - if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0) - || EVP_DigestUpdate(&ctx, s->session->master_key, - s->session->master_key_length) <= 0 - || EVP_DigestUpdate(&ctx, ssl3_pad_1, npad) <= 0 - || EVP_DigestFinal_ex(&ctx, md_buf, &i) <= 0 - - || EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL) <= 0 - || EVP_DigestUpdate(&ctx, s->session->master_key, - s->session->master_key_length) <= 0 - || EVP_DigestUpdate(&ctx, ssl3_pad_2, npad) <= 0 - || EVP_DigestUpdate(&ctx, md_buf, i) <= 0 - || EVP_DigestFinal_ex(&ctx, p, &ret) <= 0) { - SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR); - ret = 0; - } - - EVP_MD_CTX_cleanup(&ctx); - - return ((int)ret); -} - -int n_ssl3_mac(SSL *ssl, unsigned char *md, int send) -{ - SSL3_RECORD *rec; - unsigned char *mac_sec, *seq; - EVP_MD_CTX md_ctx; - const EVP_MD_CTX *hash; - unsigned char *p, rec_char; - size_t md_size, orig_len; - int npad; - int t; - - if (send) { - rec = &(ssl->s3->wrec); - mac_sec = &(ssl->s3->write_mac_secret[0]); - seq = &(ssl->s3->write_sequence[0]); - hash = ssl->write_hash; - } else { - rec = &(ssl->s3->rrec); - mac_sec = &(ssl->s3->read_mac_secret[0]); - seq = &(ssl->s3->read_sequence[0]); - hash = ssl->read_hash; - } - - t = EVP_MD_CTX_size(hash); - if (t < 0) - return -1; - md_size = t; - npad = (48 / md_size) * md_size; - - /* - * kludge: ssl3_cbc_remove_padding passes padding length in rec->type - */ - orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8); - rec->type &= 0xff; - - if (!send && - EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && - ssl3_cbc_record_digest_supported(hash)) { - /* - * This is a CBC-encrypted record. We must avoid leaking any - * timing-side channel information about how many blocks of data we - * are hashing because that gives an attacker a timing-oracle. - */ - - /*- - * npad is, at most, 48 bytes and that's with MD5: - * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75. - * - * With SHA-1 (the largest hash speced for SSLv3) the hash size - * goes up 4, but npad goes down by 8, resulting in a smaller - * total size. - */ - unsigned char header[75]; - unsigned j = 0; - memcpy(header + j, mac_sec, md_size); - j += md_size; - memcpy(header + j, ssl3_pad_1, npad); - j += npad; - memcpy(header + j, seq, 8); - j += 8; - header[j++] = rec->type; - header[j++] = rec->length >> 8; - header[j++] = rec->length & 0xff; - - /* Final param == is SSLv3 */ - if (ssl3_cbc_digest_record(hash, - md, &md_size, - header, rec->input, - rec->length + md_size, orig_len, - mac_sec, md_size, 1) <= 0) - return -1; - } else { - unsigned int md_size_u; - /* Chop the digest off the end :-) */ - EVP_MD_CTX_init(&md_ctx); - - rec_char = rec->type; - p = md; - s2n(rec->length, p); - if (EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0 - || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0 - || EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad) <= 0 - || EVP_DigestUpdate(&md_ctx, seq, 8) <= 0 - || EVP_DigestUpdate(&md_ctx, &rec_char, 1) <= 0 - || EVP_DigestUpdate(&md_ctx, md, 2) <= 0 - || EVP_DigestUpdate(&md_ctx, rec->input, rec->length) <= 0 - || EVP_DigestFinal_ex(&md_ctx, md, NULL) <= 0 - || EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0 - || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0 - || EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad) <= 0 - || EVP_DigestUpdate(&md_ctx, md, md_size) <= 0 - || EVP_DigestFinal_ex(&md_ctx, md, &md_size_u) <= 0) { - EVP_MD_CTX_cleanup(&md_ctx); - return -1; - } - md_size = md_size_u; - - EVP_MD_CTX_cleanup(&md_ctx); - } - - ssl3_record_sequence_update(seq); - return (md_size); -} - -void ssl3_record_sequence_update(unsigned char *seq) -{ - int i; - - for (i = 7; i >= 0; i--) { - ++seq[i]; - if (seq[i] != 0) - break; - } -} - -int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, - int len) -{ - static const unsigned char *salt[3] = { -#ifndef CHARSET_EBCDIC - (const unsigned char *)"A", - (const unsigned char *)"BB", - (const unsigned char *)"CCC", -#else - (const unsigned char *)"\x41", - (const unsigned char *)"\x42\x42", - (const unsigned char *)"\x43\x43\x43", -#endif - }; - unsigned char buf[EVP_MAX_MD_SIZE]; - EVP_MD_CTX ctx; - int i, ret = 0; - unsigned int n; -#ifdef OPENSSL_SSL_TRACE_CRYPTO - unsigned char *tmpout = out; -#endif - - EVP_MD_CTX_init(&ctx); - for (i = 0; i < 3; i++) { - if (EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL) <= 0 - || EVP_DigestUpdate(&ctx, salt[i], - strlen((const char *)salt[i])) <= 0 - || EVP_DigestUpdate(&ctx, p, len) <= 0 - || EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestFinal_ex(&ctx, buf, &n) <= 0 - - || EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL) <= 0 - || EVP_DigestUpdate(&ctx, p, len) <= 0 - || EVP_DigestUpdate(&ctx, buf, n) <= 0 - || EVP_DigestFinal_ex(&ctx, out, &n) <= 0) { - SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR); - ret = 0; - break; - } - out += n; - ret += n; - } - EVP_MD_CTX_cleanup(&ctx); - -#ifdef OPENSSL_SSL_TRACE_CRYPTO - if (ret > 0 && s->msg_callback) { - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER, - p, len, s, s->msg_callback_arg); - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM, - s->s3->client_random, SSL3_RANDOM_SIZE, - s, s->msg_callback_arg); - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM, - s->s3->server_random, SSL3_RANDOM_SIZE, - s, s->msg_callback_arg); - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER, - tmpout, SSL3_MASTER_SECRET_SIZE, - s, s->msg_callback_arg); - } -#endif - OPENSSL_cleanse(buf, sizeof(buf)); - return (ret); -} - -int ssl3_alert_code(int code) -{ - switch (code) { - case SSL_AD_CLOSE_NOTIFY: - return (SSL3_AD_CLOSE_NOTIFY); - case SSL_AD_UNEXPECTED_MESSAGE: - return (SSL3_AD_UNEXPECTED_MESSAGE); - case SSL_AD_BAD_RECORD_MAC: - return (SSL3_AD_BAD_RECORD_MAC); - case SSL_AD_DECRYPTION_FAILED: - return (SSL3_AD_BAD_RECORD_MAC); - case SSL_AD_RECORD_OVERFLOW: - return (SSL3_AD_BAD_RECORD_MAC); - case SSL_AD_DECOMPRESSION_FAILURE: - return (SSL3_AD_DECOMPRESSION_FAILURE); - case SSL_AD_HANDSHAKE_FAILURE: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_NO_CERTIFICATE: - return (SSL3_AD_NO_CERTIFICATE); - case SSL_AD_BAD_CERTIFICATE: - return (SSL3_AD_BAD_CERTIFICATE); - case SSL_AD_UNSUPPORTED_CERTIFICATE: - return (SSL3_AD_UNSUPPORTED_CERTIFICATE); - case SSL_AD_CERTIFICATE_REVOKED: - return (SSL3_AD_CERTIFICATE_REVOKED); - case SSL_AD_CERTIFICATE_EXPIRED: - return (SSL3_AD_CERTIFICATE_EXPIRED); - case SSL_AD_CERTIFICATE_UNKNOWN: - return (SSL3_AD_CERTIFICATE_UNKNOWN); - case SSL_AD_ILLEGAL_PARAMETER: - return (SSL3_AD_ILLEGAL_PARAMETER); - case SSL_AD_UNKNOWN_CA: - return (SSL3_AD_BAD_CERTIFICATE); - case SSL_AD_ACCESS_DENIED: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_DECODE_ERROR: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_DECRYPT_ERROR: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_EXPORT_RESTRICTION: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_PROTOCOL_VERSION: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_INSUFFICIENT_SECURITY: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_INTERNAL_ERROR: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_USER_CANCELLED: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_NO_RENEGOTIATION: - return (-1); /* Don't send it :-) */ - case SSL_AD_UNSUPPORTED_EXTENSION: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_CERTIFICATE_UNOBTAINABLE: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_UNRECOGNIZED_NAME: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_UNKNOWN_PSK_IDENTITY: - return (TLS1_AD_UNKNOWN_PSK_IDENTITY); - case SSL_AD_INAPPROPRIATE_FALLBACK: - return (TLS1_AD_INAPPROPRIATE_FALLBACK); - default: - return (-1); - } -} diff --git a/thirdparty/openssl/ssl/s3_lib.c b/thirdparty/openssl/ssl/s3_lib.c deleted file mode 100644 index 1014a3fce1..0000000000 --- a/thirdparty/openssl/ssl/s3_lib.c +++ /dev/null @@ -1,4539 +0,0 @@ -/* ssl/s3_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 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 - * openssl-core@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). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the OpenSSL open source - * license provided above. - * - * ECC cipher suite support in OpenSSL originally written by - * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include <stdio.h> -#include <openssl/objects.h> -#include "ssl_locl.h" -#include "kssl_lcl.h" -#include <openssl/md5.h> -#ifndef OPENSSL_NO_DH -# include <openssl/dh.h> -#endif - -const char ssl3_version_str[] = "SSLv3" OPENSSL_VERSION_PTEXT; - -#define SSL3_NUM_CIPHERS (sizeof(ssl3_ciphers)/sizeof(SSL_CIPHER)) - -/* list of available SSLv3 ciphers (sorted by id) */ -OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { - -/* The RSA ciphers */ -/* Cipher 01 */ - { - 1, - SSL3_TXT_RSA_NULL_MD5, - SSL3_CK_RSA_NULL_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_eNULL, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_EXP | SSL_STRONG_NONE, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - -/* Cipher 02 */ - { - 1, - SSL3_TXT_RSA_NULL_SHA, - SSL3_CK_RSA_NULL_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_eNULL, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - -/* Cipher 03 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_RSA_RC4_40_MD5, - SSL3_CK_RSA_RC4_40_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -#endif - -/* Cipher 04 */ - { - 1, - SSL3_TXT_RSA_RC4_128_MD5, - SSL3_CK_RSA_RC4_128_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 05 */ - { - 1, - SSL3_TXT_RSA_RC4_128_SHA, - SSL3_CK_RSA_RC4_128_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 06 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_RSA_RC2_40_MD5, - SSL3_CK_RSA_RC2_40_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC2, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -#endif - -/* Cipher 07 */ -#ifndef OPENSSL_NO_IDEA - { - 1, - SSL3_TXT_RSA_IDEA_128_SHA, - SSL3_CK_RSA_IDEA_128_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_IDEA, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -#endif - -/* Cipher 08 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_RSA_DES_40_CBC_SHA, - SSL3_CK_RSA_DES_40_CBC_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -#endif - -/* Cipher 09 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_RSA_DES_64_CBC_SHA, - SSL3_CK_RSA_DES_64_CBC_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -#endif - -/* Cipher 0A */ - { - 1, - SSL3_TXT_RSA_DES_192_CBC3_SHA, - SSL3_CK_RSA_DES_192_CBC3_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* The DH ciphers */ -/* Cipher 0B */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 0, - SSL3_TXT_DH_DSS_DES_40_CBC_SHA, - SSL3_CK_DH_DSS_DES_40_CBC_SHA, - SSL_kDHd, - SSL_aDH, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -#endif - -/* Cipher 0C */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_DH_DSS_DES_64_CBC_SHA, - SSL3_CK_DH_DSS_DES_64_CBC_SHA, - SSL_kDHd, - SSL_aDH, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -#endif - -/* Cipher 0D */ - { - 1, - SSL3_TXT_DH_DSS_DES_192_CBC3_SHA, - SSL3_CK_DH_DSS_DES_192_CBC3_SHA, - SSL_kDHd, - SSL_aDH, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* Cipher 0E */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 0, - SSL3_TXT_DH_RSA_DES_40_CBC_SHA, - SSL3_CK_DH_RSA_DES_40_CBC_SHA, - SSL_kDHr, - SSL_aDH, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -#endif - -/* Cipher 0F */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_DH_RSA_DES_64_CBC_SHA, - SSL3_CK_DH_RSA_DES_64_CBC_SHA, - SSL_kDHr, - SSL_aDH, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -#endif - -/* Cipher 10 */ - { - 1, - SSL3_TXT_DH_RSA_DES_192_CBC3_SHA, - SSL3_CK_DH_RSA_DES_192_CBC3_SHA, - SSL_kDHr, - SSL_aDH, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* The Ephemeral DH ciphers */ -/* Cipher 11 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_EDH_DSS_DES_40_CBC_SHA, - SSL3_CK_EDH_DSS_DES_40_CBC_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -#endif - -/* Cipher 12 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_EDH_DSS_DES_64_CBC_SHA, - SSL3_CK_EDH_DSS_DES_64_CBC_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -#endif - -/* Cipher 13 */ - { - 1, - SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA, - SSL3_CK_EDH_DSS_DES_192_CBC3_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* Cipher 14 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_EDH_RSA_DES_40_CBC_SHA, - SSL3_CK_EDH_RSA_DES_40_CBC_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -#endif - -/* Cipher 15 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_EDH_RSA_DES_64_CBC_SHA, - SSL3_CK_EDH_RSA_DES_64_CBC_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -#endif - -/* Cipher 16 */ - { - 1, - SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA, - SSL3_CK_EDH_RSA_DES_192_CBC3_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* Cipher 17 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_ADH_RC4_40_MD5, - SSL3_CK_ADH_RC4_40_MD5, - SSL_kEDH, - SSL_aNULL, - SSL_RC4, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -#endif - -/* Cipher 18 */ - { - 1, - SSL3_TXT_ADH_RC4_128_MD5, - SSL3_CK_ADH_RC4_128_MD5, - SSL_kEDH, - SSL_aNULL, - SSL_RC4, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 19 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_ADH_DES_40_CBC_SHA, - SSL3_CK_ADH_DES_40_CBC_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -#endif - -/* Cipher 1A */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_ADH_DES_64_CBC_SHA, - SSL3_CK_ADH_DES_64_CBC_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -#endif - -/* Cipher 1B */ - { - 1, - SSL3_TXT_ADH_DES_192_CBC_SHA, - SSL3_CK_ADH_DES_192_CBC_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* Fortezza ciphersuite from SSL 3.0 spec */ -#if 0 -/* Cipher 1C */ - { - 0, - SSL3_TXT_FZA_DMS_NULL_SHA, - SSL3_CK_FZA_DMS_NULL_SHA, - SSL_kFZA, - SSL_aFZA, - SSL_eNULL, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_STRONG_NONE, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - -/* Cipher 1D */ - { - 0, - SSL3_TXT_FZA_DMS_FZA_SHA, - SSL3_CK_FZA_DMS_FZA_SHA, - SSL_kFZA, - SSL_aFZA, - SSL_eFZA, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_STRONG_NONE, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - -/* Cipher 1E */ - { - 0, - SSL3_TXT_FZA_DMS_RC4_SHA, - SSL3_CK_FZA_DMS_RC4_SHA, - SSL_kFZA, - SSL_aFZA, - SSL_RC4, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -#endif - -#ifndef OPENSSL_NO_KRB5 -/* The Kerberos ciphers*/ -/* Cipher 1E */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_DES_64_CBC_SHA, - SSL3_CK_KRB5_DES_64_CBC_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -# endif - -/* Cipher 1F */ - { - 1, - SSL3_TXT_KRB5_DES_192_CBC3_SHA, - SSL3_CK_KRB5_DES_192_CBC3_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* Cipher 20 */ - { - 1, - SSL3_TXT_KRB5_RC4_128_SHA, - SSL3_CK_KRB5_RC4_128_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_RC4, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 21 */ - { - 1, - SSL3_TXT_KRB5_IDEA_128_CBC_SHA, - SSL3_CK_KRB5_IDEA_128_CBC_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_IDEA, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 22 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_DES_64_CBC_MD5, - SSL3_CK_KRB5_DES_64_CBC_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_DES, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -# endif - -/* Cipher 23 */ - { - 1, - SSL3_TXT_KRB5_DES_192_CBC3_MD5, - SSL3_CK_KRB5_DES_192_CBC3_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_3DES, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* Cipher 24 */ - { - 1, - SSL3_TXT_KRB5_RC4_128_MD5, - SSL3_CK_KRB5_RC4_128_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_RC4, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 25 */ - { - 1, - SSL3_TXT_KRB5_IDEA_128_CBC_MD5, - SSL3_CK_KRB5_IDEA_128_CBC_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_IDEA, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 26 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_DES_40_CBC_SHA, - SSL3_CK_KRB5_DES_40_CBC_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -# endif - -/* Cipher 27 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_RC2_40_CBC_SHA, - SSL3_CK_KRB5_RC2_40_CBC_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_RC2, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -# endif - -/* Cipher 28 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_RC4_40_SHA, - SSL3_CK_KRB5_RC4_40_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_RC4, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -# endif - -/* Cipher 29 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_DES_40_CBC_MD5, - SSL3_CK_KRB5_DES_40_CBC_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_DES, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -# endif - -/* Cipher 2A */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_RC2_40_CBC_MD5, - SSL3_CK_KRB5_RC2_40_CBC_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_RC2, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -# endif - -/* Cipher 2B */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_RC4_40_MD5, - SSL3_CK_KRB5_RC4_40_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_RC4, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -# endif -#endif /* OPENSSL_NO_KRB5 */ - -/* New AES ciphersuites */ -/* Cipher 2F */ - { - 1, - TLS1_TXT_RSA_WITH_AES_128_SHA, - TLS1_CK_RSA_WITH_AES_128_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -/* Cipher 30 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_AES_128_SHA, - TLS1_CK_DH_DSS_WITH_AES_128_SHA, - SSL_kDHd, - SSL_aDH, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -/* Cipher 31 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_AES_128_SHA, - TLS1_CK_DH_RSA_WITH_AES_128_SHA, - SSL_kDHr, - SSL_aDH, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -/* Cipher 32 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_AES_128_SHA, - TLS1_CK_DHE_DSS_WITH_AES_128_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -/* Cipher 33 */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, - TLS1_CK_DHE_RSA_WITH_AES_128_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -/* Cipher 34 */ - { - 1, - TLS1_TXT_ADH_WITH_AES_128_SHA, - TLS1_CK_ADH_WITH_AES_128_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 35 */ - { - 1, - TLS1_TXT_RSA_WITH_AES_256_SHA, - TLS1_CK_RSA_WITH_AES_256_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, -/* Cipher 36 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_AES_256_SHA, - TLS1_CK_DH_DSS_WITH_AES_256_SHA, - SSL_kDHd, - SSL_aDH, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - -/* Cipher 37 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_AES_256_SHA, - TLS1_CK_DH_RSA_WITH_AES_256_SHA, - SSL_kDHr, - SSL_aDH, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - -/* Cipher 38 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_AES_256_SHA, - TLS1_CK_DHE_DSS_WITH_AES_256_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - -/* Cipher 39 */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, - TLS1_CK_DHE_RSA_WITH_AES_256_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 3A */ - { - 1, - TLS1_TXT_ADH_WITH_AES_256_SHA, - TLS1_CK_ADH_WITH_AES_256_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* TLS v1.2 ciphersuites */ - /* Cipher 3B */ - { - 1, - TLS1_TXT_RSA_WITH_NULL_SHA256, - TLS1_CK_RSA_WITH_NULL_SHA256, - SSL_kRSA, - SSL_aRSA, - SSL_eNULL, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - - /* Cipher 3C */ - { - 1, - TLS1_TXT_RSA_WITH_AES_128_SHA256, - TLS1_CK_RSA_WITH_AES_128_SHA256, - SSL_kRSA, - SSL_aRSA, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 3D */ - { - 1, - TLS1_TXT_RSA_WITH_AES_256_SHA256, - TLS1_CK_RSA_WITH_AES_256_SHA256, - SSL_kRSA, - SSL_aRSA, - SSL_AES256, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 3E */ - { - 1, - TLS1_TXT_DH_DSS_WITH_AES_128_SHA256, - TLS1_CK_DH_DSS_WITH_AES_128_SHA256, - SSL_kDHd, - SSL_aDH, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 3F */ - { - 1, - TLS1_TXT_DH_RSA_WITH_AES_128_SHA256, - TLS1_CK_DH_RSA_WITH_AES_128_SHA256, - SSL_kDHr, - SSL_aDH, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 40 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256, - TLS1_CK_DHE_DSS_WITH_AES_128_SHA256, - SSL_kEDH, - SSL_aDSS, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -#ifndef OPENSSL_NO_CAMELLIA - /* Camellia ciphersuites from RFC4132 (128-bit portion) */ - - /* Cipher 41 */ - { - 1, - TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA, - TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_CAMELLIA128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 42 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, - TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, - SSL_kDHd, - SSL_aDH, - SSL_CAMELLIA128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 43 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, - TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, - SSL_kDHr, - SSL_aDH, - SSL_CAMELLIA128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 44 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, - TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_CAMELLIA128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 45 */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, - TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_CAMELLIA128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 46 */ - { - 1, - TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA, - TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_CAMELLIA128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -#endif /* OPENSSL_NO_CAMELLIA */ - -#if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES - /* New TLS Export CipherSuites from expired ID */ -# if 0 - /* Cipher 60 */ - { - 1, - TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5, - TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_MD5, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 128, - }, - - /* Cipher 61 */ - { - 1, - TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, - TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC2, - SSL_MD5, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 128, - }, -# endif - - /* Cipher 62 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA, - TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -# endif - - /* Cipher 63 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, - TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -# endif - - /* Cipher 64 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA, - TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 128, - }, -# endif - - /* Cipher 65 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, - TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 128, - }, -# endif - - /* Cipher 66 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA, - TLS1_CK_DHE_DSS_WITH_RC4_128_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -#endif - - /* TLS v1.2 ciphersuites */ - /* Cipher 67 */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256, - TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, - SSL_kEDH, - SSL_aRSA, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 68 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_AES_256_SHA256, - TLS1_CK_DH_DSS_WITH_AES_256_SHA256, - SSL_kDHd, - SSL_aDH, - SSL_AES256, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 69 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_AES_256_SHA256, - TLS1_CK_DH_RSA_WITH_AES_256_SHA256, - SSL_kDHr, - SSL_aDH, - SSL_AES256, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 6A */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256, - TLS1_CK_DHE_DSS_WITH_AES_256_SHA256, - SSL_kEDH, - SSL_aDSS, - SSL_AES256, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 6B */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256, - TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, - SSL_kEDH, - SSL_aRSA, - SSL_AES256, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 6C */ - { - 1, - TLS1_TXT_ADH_WITH_AES_128_SHA256, - TLS1_CK_ADH_WITH_AES_128_SHA256, - SSL_kEDH, - SSL_aNULL, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 6D */ - { - 1, - TLS1_TXT_ADH_WITH_AES_256_SHA256, - TLS1_CK_ADH_WITH_AES_256_SHA256, - SSL_kEDH, - SSL_aNULL, - SSL_AES256, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* GOST Ciphersuites */ - - { - 1, - "GOST94-GOST89-GOST89", - 0x3000080, - SSL_kGOST, - SSL_aGOST94, - SSL_eGOST2814789CNT, - SSL_GOST89MAC, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94 | TLS1_STREAM_MAC, - 256, - 256}, - { - 1, - "GOST2001-GOST89-GOST89", - 0x3000081, - SSL_kGOST, - SSL_aGOST01, - SSL_eGOST2814789CNT, - SSL_GOST89MAC, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94 | TLS1_STREAM_MAC, - 256, - 256}, - { - 1, - "GOST94-NULL-GOST94", - 0x3000082, - SSL_kGOST, - SSL_aGOST94, - SSL_eNULL, - SSL_GOST94, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE, - SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94, - 0, - 0}, - { - 1, - "GOST2001-NULL-GOST94", - 0x3000083, - SSL_kGOST, - SSL_aGOST01, - SSL_eNULL, - SSL_GOST94, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE, - SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94, - 0, - 0}, - -#ifndef OPENSSL_NO_CAMELLIA - /* Camellia ciphersuites from RFC4132 (256-bit portion) */ - - /* Cipher 84 */ - { - 1, - TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA, - TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_CAMELLIA256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - /* Cipher 85 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, - TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, - SSL_kDHd, - SSL_aDH, - SSL_CAMELLIA256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 86 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, - TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, - SSL_kDHr, - SSL_aDH, - SSL_CAMELLIA256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 87 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, - TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_CAMELLIA256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 88 */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, - TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_CAMELLIA256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 89 */ - { - 1, - TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA, - TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_CAMELLIA256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, -#endif /* OPENSSL_NO_CAMELLIA */ - -#ifndef OPENSSL_NO_PSK - /* Cipher 8A */ - { - 1, - TLS1_TXT_PSK_WITH_RC4_128_SHA, - TLS1_CK_PSK_WITH_RC4_128_SHA, - SSL_kPSK, - SSL_aPSK, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 8B */ - { - 1, - TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA, - TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA, - SSL_kPSK, - SSL_aPSK, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher 8C */ - { - 1, - TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, - TLS1_CK_PSK_WITH_AES_128_CBC_SHA, - SSL_kPSK, - SSL_aPSK, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 8D */ - { - 1, - TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, - TLS1_CK_PSK_WITH_AES_256_CBC_SHA, - SSL_kPSK, - SSL_aPSK, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, -#endif /* OPENSSL_NO_PSK */ - -#ifndef OPENSSL_NO_SEED - /* SEED ciphersuites from RFC4162 */ - - /* Cipher 96 */ - { - 1, - TLS1_TXT_RSA_WITH_SEED_SHA, - TLS1_CK_RSA_WITH_SEED_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_SEED, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 97 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_SEED_SHA, - TLS1_CK_DH_DSS_WITH_SEED_SHA, - SSL_kDHd, - SSL_aDH, - SSL_SEED, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 98 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_SEED_SHA, - TLS1_CK_DH_RSA_WITH_SEED_SHA, - SSL_kDHr, - SSL_aDH, - SSL_SEED, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 99 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_SEED_SHA, - TLS1_CK_DHE_DSS_WITH_SEED_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_SEED, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 9A */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_SEED_SHA, - TLS1_CK_DHE_RSA_WITH_SEED_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_SEED, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 9B */ - { - 1, - TLS1_TXT_ADH_WITH_SEED_SHA, - TLS1_CK_ADH_WITH_SEED_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_SEED, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -#endif /* OPENSSL_NO_SEED */ - - /* GCM ciphersuites from RFC5288 */ - - /* Cipher 9C */ - { - 1, - TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, - SSL_kRSA, - SSL_aRSA, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher 9D */ - { - 1, - TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, - SSL_kRSA, - SSL_aRSA, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher 9E */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, - SSL_kEDH, - SSL_aRSA, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher 9F */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, - SSL_kEDH, - SSL_aRSA, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher A0 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256, - SSL_kDHr, - SSL_aDH, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher A1 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384, - SSL_kDHr, - SSL_aDH, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher A2 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256, - TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256, - SSL_kEDH, - SSL_aDSS, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher A3 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384, - TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384, - SSL_kEDH, - SSL_aDSS, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher A4 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256, - TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256, - SSL_kDHd, - SSL_aDH, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher A5 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384, - TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384, - SSL_kDHd, - SSL_aDH, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher A6 */ - { - 1, - TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256, - TLS1_CK_ADH_WITH_AES_128_GCM_SHA256, - SSL_kEDH, - SSL_aNULL, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher A7 */ - { - 1, - TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384, - TLS1_CK_ADH_WITH_AES_256_GCM_SHA384, - SSL_kEDH, - SSL_aNULL, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - { - 1, - "SCSV", - SSL3_CK_SCSV, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0}, -#endif - -#ifndef OPENSSL_NO_ECDH - /* Cipher C001 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA, - TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA, - SSL_kECDHe, - SSL_aECDH, - SSL_eNULL, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - - /* Cipher C002 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA, - TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA, - SSL_kECDHe, - SSL_aECDH, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C003 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, - SSL_kECDHe, - SSL_aECDH, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C004 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - SSL_kECDHe, - SSL_aECDH, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C005 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - SSL_kECDHe, - SSL_aECDH, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher C006 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA, - SSL_kEECDH, - SSL_aECDSA, - SSL_eNULL, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - - /* Cipher C007 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, - SSL_kEECDH, - SSL_aECDSA, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C008 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, - SSL_kEECDH, - SSL_aECDSA, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C009 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - SSL_kEECDH, - SSL_aECDSA, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C00A */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - SSL_kEECDH, - SSL_aECDSA, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher C00B */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_NULL_SHA, - TLS1_CK_ECDH_RSA_WITH_NULL_SHA, - SSL_kECDHr, - SSL_aECDH, - SSL_eNULL, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - - /* Cipher C00C */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA, - TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA, - SSL_kECDHr, - SSL_aECDH, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C00D */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA, - SSL_kECDHr, - SSL_aECDH, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C00E */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA, - SSL_kECDHr, - SSL_aECDH, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C00F */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA, - SSL_kECDHr, - SSL_aECDH, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher C010 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA, - TLS1_CK_ECDHE_RSA_WITH_NULL_SHA, - SSL_kEECDH, - SSL_aRSA, - SSL_eNULL, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - - /* Cipher C011 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, - TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, - SSL_kEECDH, - SSL_aRSA, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C012 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA, - SSL_kEECDH, - SSL_aRSA, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C013 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, - SSL_kEECDH, - SSL_aRSA, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C014 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, - SSL_kEECDH, - SSL_aRSA, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher C015 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_NULL_SHA, - TLS1_CK_ECDH_anon_WITH_NULL_SHA, - SSL_kEECDH, - SSL_aNULL, - SSL_eNULL, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - - /* Cipher C016 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA, - TLS1_CK_ECDH_anon_WITH_RC4_128_SHA, - SSL_kEECDH, - SSL_aNULL, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C017 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA, - SSL_kEECDH, - SSL_aNULL, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C018 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA, - SSL_kEECDH, - SSL_aNULL, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C019 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA, - SSL_kEECDH, - SSL_aNULL, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, -#endif /* OPENSSL_NO_ECDH */ - -#ifndef OPENSSL_NO_SRP - /* Cipher C01A */ - { - 1, - TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA, - TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA, - SSL_kSRP, - SSL_aSRP, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C01B */ - { - 1, - TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, - TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, - SSL_kSRP, - SSL_aRSA, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C01C */ - { - 1, - TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, - TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, - SSL_kSRP, - SSL_aDSS, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C01D */ - { - 1, - TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA, - TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA, - SSL_kSRP, - SSL_aSRP, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C01E */ - { - 1, - TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, - TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, - SSL_kSRP, - SSL_aRSA, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C01F */ - { - 1, - TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, - TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, - SSL_kSRP, - SSL_aDSS, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C020 */ - { - 1, - TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA, - TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA, - SSL_kSRP, - SSL_aSRP, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher C021 */ - { - 1, - TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, - TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, - SSL_kSRP, - SSL_aRSA, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher C022 */ - { - 1, - TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, - TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, - SSL_kSRP, - SSL_aDSS, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, -#endif /* OPENSSL_NO_SRP */ -#ifndef OPENSSL_NO_ECDH - - /* HMAC based TLS v1.2 ciphersuites from RFC5289 */ - - /* Cipher C023 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256, - TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, - SSL_kEECDH, - SSL_aECDSA, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C024 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384, - TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, - SSL_kEECDH, - SSL_aECDSA, - SSL_AES256, - SSL_SHA384, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher C025 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256, - TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256, - SSL_kECDHe, - SSL_aECDH, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C026 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384, - TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384, - SSL_kECDHe, - SSL_aECDH, - SSL_AES256, - SSL_SHA384, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher C027 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256, - TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, - SSL_kEECDH, - SSL_aRSA, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C028 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384, - TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, - SSL_kEECDH, - SSL_aRSA, - SSL_AES256, - SSL_SHA384, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher C029 */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256, - TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256, - SSL_kECDHr, - SSL_aECDH, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C02A */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384, - TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384, - SSL_kECDHr, - SSL_aECDH, - SSL_AES256, - SSL_SHA384, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* GCM based TLS v1.2 ciphersuites from RFC5289 */ - - /* Cipher C02B */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - SSL_kEECDH, - SSL_aECDSA, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C02C */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - SSL_kEECDH, - SSL_aECDSA, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher C02D */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - SSL_kECDHe, - SSL_aECDH, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C02E */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - SSL_kECDHe, - SSL_aECDH, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher C02F */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - SSL_kEECDH, - SSL_aRSA, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C030 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - SSL_kEECDH, - SSL_aRSA, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher C031 */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256, - SSL_kECDHr, - SSL_aECDH, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C032 */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384, - SSL_kECDHr, - SSL_aECDH, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - -#endif /* OPENSSL_NO_ECDH */ - -#ifdef TEMP_GOST_TLS -/* Cipher FF00 */ - { - 1, - "GOST-MD5", - 0x0300ff00, - SSL_kRSA, - SSL_aRSA, - SSL_eGOST2814789CNT, - SSL_MD5, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - { - 1, - "GOST-GOST94", - 0x0300ff01, - SSL_kRSA, - SSL_aRSA, - SSL_eGOST2814789CNT, - SSL_GOST94, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256}, - { - 1, - "GOST-GOST89MAC", - 0x0300ff02, - SSL_kRSA, - SSL_aRSA, - SSL_eGOST2814789CNT, - SSL_GOST89MAC, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256}, - { - 1, - "GOST-GOST89STREAM", - 0x0300ff03, - SSL_kRSA, - SSL_aRSA, - SSL_eGOST2814789CNT, - SSL_GOST89MAC, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF | TLS1_STREAM_MAC, - 256, - 256}, -#endif - -/* end of list */ -}; - -SSL3_ENC_METHOD SSLv3_enc_data = { - ssl3_enc, - n_ssl3_mac, - ssl3_setup_key_block, - ssl3_generate_master_secret, - ssl3_change_cipher_state, - ssl3_final_finish_mac, - MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, - ssl3_cert_verify_mac, - SSL3_MD_CLIENT_FINISHED_CONST, 4, - SSL3_MD_SERVER_FINISHED_CONST, 4, - ssl3_alert_code, - (int (*)(SSL *, unsigned char *, size_t, const char *, - size_t, const unsigned char *, size_t, - int use_context))ssl_undefined_function, - 0, - SSL3_HM_HEADER_LENGTH, - ssl3_set_handshake_header, - ssl3_handshake_write -}; - -long ssl3_default_timeout(void) -{ - /* - * 2 hours, the 24 hours mentioned in the SSLv3 spec is way too long for - * http, the cache would over fill - */ - return (60 * 60 * 2); -} - -int ssl3_num_ciphers(void) -{ - return (SSL3_NUM_CIPHERS); -} - -const SSL_CIPHER *ssl3_get_cipher(unsigned int u) -{ - if (u < SSL3_NUM_CIPHERS) - return (&(ssl3_ciphers[SSL3_NUM_CIPHERS - 1 - u])); - else - return (NULL); -} - -int ssl3_pending(const SSL *s) -{ - if (s->rstate == SSL_ST_READ_BODY) - return 0; - - return (s->s3->rrec.type == - SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length : 0; -} - -void ssl3_set_handshake_header(SSL *s, int htype, unsigned long len) -{ - unsigned char *p = (unsigned char *)s->init_buf->data; - *(p++) = htype; - l2n3(len, p); - s->init_num = (int)len + SSL3_HM_HEADER_LENGTH; - s->init_off = 0; -} - -int ssl3_handshake_write(SSL *s) -{ - return ssl3_do_write(s, SSL3_RT_HANDSHAKE); -} - -int ssl3_new(SSL *s) -{ - SSL3_STATE *s3; - - if ((s3 = OPENSSL_malloc(sizeof *s3)) == NULL) - goto err; - memset(s3, 0, sizeof *s3); - memset(s3->rrec.seq_num, 0, sizeof(s3->rrec.seq_num)); - memset(s3->wrec.seq_num, 0, sizeof(s3->wrec.seq_num)); - - s->s3 = s3; - -#ifndef OPENSSL_NO_SRP - SSL_SRP_CTX_init(s); -#endif - s->method->ssl_clear(s); - return (1); - err: - return (0); -} - -void ssl3_free(SSL *s) -{ - if (s == NULL || s->s3 == NULL) - return; - -#ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->client_opaque_prf_input != NULL) - OPENSSL_free(s->s3->client_opaque_prf_input); - if (s->s3->server_opaque_prf_input != NULL) - OPENSSL_free(s->s3->server_opaque_prf_input); -#endif - - ssl3_cleanup_key_block(s); - if (s->s3->rbuf.buf != NULL) - ssl3_release_read_buffer(s); - if (s->s3->wbuf.buf != NULL) - ssl3_release_write_buffer(s); - if (s->s3->rrec.comp != NULL) - OPENSSL_free(s->s3->rrec.comp); -#ifndef OPENSSL_NO_DH - if (s->s3->tmp.dh != NULL) - DH_free(s->s3->tmp.dh); -#endif -#ifndef OPENSSL_NO_ECDH - if (s->s3->tmp.ecdh != NULL) - EC_KEY_free(s->s3->tmp.ecdh); -#endif - - if (s->s3->tmp.ca_names != NULL) - sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); - if (s->s3->handshake_buffer) { - BIO_free(s->s3->handshake_buffer); - } - if (s->s3->handshake_dgst) - ssl3_free_digest_list(s); -#ifndef OPENSSL_NO_TLSEXT - if (s->s3->alpn_selected) - OPENSSL_free(s->s3->alpn_selected); -#endif - -#ifndef OPENSSL_NO_SRP - SSL_SRP_CTX_free(s); -#endif - OPENSSL_cleanse(s->s3, sizeof *s->s3); - OPENSSL_free(s->s3); - s->s3 = NULL; -} - -void ssl3_clear(SSL *s) -{ - unsigned char *rp, *wp; - size_t rlen, wlen; - int init_extra; - -#ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->client_opaque_prf_input != NULL) - OPENSSL_free(s->s3->client_opaque_prf_input); - s->s3->client_opaque_prf_input = NULL; - if (s->s3->server_opaque_prf_input != NULL) - OPENSSL_free(s->s3->server_opaque_prf_input); - s->s3->server_opaque_prf_input = NULL; -#endif - - ssl3_cleanup_key_block(s); - if (s->s3->tmp.ca_names != NULL) - sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); - - if (s->s3->rrec.comp != NULL) { - OPENSSL_free(s->s3->rrec.comp); - s->s3->rrec.comp = NULL; - } -#ifndef OPENSSL_NO_DH - if (s->s3->tmp.dh != NULL) { - DH_free(s->s3->tmp.dh); - s->s3->tmp.dh = NULL; - } -#endif -#ifndef OPENSSL_NO_ECDH - if (s->s3->tmp.ecdh != NULL) { - EC_KEY_free(s->s3->tmp.ecdh); - s->s3->tmp.ecdh = NULL; - } -#endif -#ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_EC - s->s3->is_probably_safari = 0; -# endif /* !OPENSSL_NO_EC */ -#endif /* !OPENSSL_NO_TLSEXT */ - - rp = s->s3->rbuf.buf; - wp = s->s3->wbuf.buf; - rlen = s->s3->rbuf.len; - wlen = s->s3->wbuf.len; - init_extra = s->s3->init_extra; - if (s->s3->handshake_buffer) { - BIO_free(s->s3->handshake_buffer); - s->s3->handshake_buffer = NULL; - } - if (s->s3->handshake_dgst) { - ssl3_free_digest_list(s); - } -#if !defined(OPENSSL_NO_TLSEXT) - if (s->s3->alpn_selected) { - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = NULL; - } -#endif - memset(s->s3, 0, sizeof *s->s3); - s->s3->rbuf.buf = rp; - s->s3->wbuf.buf = wp; - s->s3->rbuf.len = rlen; - s->s3->wbuf.len = wlen; - s->s3->init_extra = init_extra; - - ssl_free_wbio_buffer(s); - - s->packet_length = 0; - s->s3->renegotiate = 0; - s->s3->total_renegotiations = 0; - s->s3->num_renegotiations = 0; - s->s3->in_read_app_data = 0; - s->version = SSL3_VERSION; - -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) - if (s->next_proto_negotiated) { - OPENSSL_free(s->next_proto_negotiated); - s->next_proto_negotiated = NULL; - s->next_proto_negotiated_len = 0; - } -#endif -} - -#ifndef OPENSSL_NO_SRP -static char *MS_CALLBACK srp_password_from_info_cb(SSL *s, void *arg) -{ - return BUF_strdup(s->srp_ctx.info); -} -#endif - -static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, - size_t len); - -long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) -{ - int ret = 0; - -#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA) - if ( -# ifndef OPENSSL_NO_RSA - cmd == SSL_CTRL_SET_TMP_RSA || cmd == SSL_CTRL_SET_TMP_RSA_CB || -# endif -# ifndef OPENSSL_NO_DSA - cmd == SSL_CTRL_SET_TMP_DH || cmd == SSL_CTRL_SET_TMP_DH_CB || -# endif - 0) { - if (!ssl_cert_inst(&s->cert)) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE); - return (0); - } - } -#endif - - switch (cmd) { - case SSL_CTRL_GET_SESSION_REUSED: - ret = s->hit; - break; - case SSL_CTRL_GET_CLIENT_CERT_REQUEST: - break; - case SSL_CTRL_GET_NUM_RENEGOTIATIONS: - ret = s->s3->num_renegotiations; - break; - case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS: - ret = s->s3->num_renegotiations; - s->s3->num_renegotiations = 0; - break; - case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS: - ret = s->s3->total_renegotiations; - break; - case SSL_CTRL_GET_FLAGS: - ret = (int)(s->s3->flags); - break; -#ifndef OPENSSL_NO_RSA - case SSL_CTRL_NEED_TMP_RSA: - if ((s->cert != NULL) && (s->cert->rsa_tmp == NULL) && - ((s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) || - (EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) > - (512 / 8)))) - ret = 1; - break; - case SSL_CTRL_SET_TMP_RSA: - { - RSA *rsa = (RSA *)parg; - if (rsa == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return (ret); - } - if ((rsa = RSAPrivateKey_dup(rsa)) == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_RSA_LIB); - return (ret); - } - if (s->cert->rsa_tmp != NULL) - RSA_free(s->cert->rsa_tmp); - s->cert->rsa_tmp = rsa; - ret = 1; - } - break; - case SSL_CTRL_SET_TMP_RSA_CB: - { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (ret); - } - break; -#endif -#ifndef OPENSSL_NO_DH - case SSL_CTRL_SET_TMP_DH: - { - DH *dh = (DH *)parg; - if (dh == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return (ret); - } - if ((dh = DHparams_dup(dh)) == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB); - return (ret); - } - if (s->cert->dh_tmp != NULL) - DH_free(s->cert->dh_tmp); - s->cert->dh_tmp = dh; - ret = 1; - } - break; - case SSL_CTRL_SET_TMP_DH_CB: - { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (ret); - } - break; -#endif -#ifndef OPENSSL_NO_ECDH - case SSL_CTRL_SET_TMP_ECDH: - { - EC_KEY *ecdh = NULL; - - if (parg == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return (ret); - } - if (!EC_KEY_up_ref((EC_KEY *)parg)) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_ECDH_LIB); - return (ret); - } - ecdh = (EC_KEY *)parg; - if (!(s->options & SSL_OP_SINGLE_ECDH_USE)) { - if (!EC_KEY_generate_key(ecdh)) { - EC_KEY_free(ecdh); - SSLerr(SSL_F_SSL3_CTRL, ERR_R_ECDH_LIB); - return (ret); - } - } - if (s->cert->ecdh_tmp != NULL) - EC_KEY_free(s->cert->ecdh_tmp); - s->cert->ecdh_tmp = ecdh; - ret = 1; - } - break; - case SSL_CTRL_SET_TMP_ECDH_CB: - { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (ret); - } - break; -#endif /* !OPENSSL_NO_ECDH */ -#ifndef OPENSSL_NO_TLSEXT - case SSL_CTRL_SET_TLSEXT_HOSTNAME: - if (larg == TLSEXT_NAMETYPE_host_name) { - size_t len; - - if (s->tlsext_hostname != NULL) - OPENSSL_free(s->tlsext_hostname); - s->tlsext_hostname = NULL; - - ret = 1; - if (parg == NULL) - break; - len = strlen((char *)parg); - if (len == 0 || len > TLSEXT_MAXLEN_host_name) { - SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME); - return 0; - } - if ((s->tlsext_hostname = BUF_strdup((char *)parg)) == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR); - return 0; - } - } else { - SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE); - return 0; - } - break; - case SSL_CTRL_SET_TLSEXT_DEBUG_ARG: - s->tlsext_debug_arg = parg; - ret = 1; - break; - -# ifdef TLSEXT_TYPE_opaque_prf_input - case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT: - if (larg > 12288) { /* actual internal limit is 2^16 for the - * complete hello message * (including the - * cert chain and everything) */ - SSLerr(SSL_F_SSL3_CTRL, SSL_R_OPAQUE_PRF_INPUT_TOO_LONG); - break; - } - if (s->tlsext_opaque_prf_input != NULL) - OPENSSL_free(s->tlsext_opaque_prf_input); - if ((size_t)larg == 0) - s->tlsext_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte - * just to get - * non-NULL */ - else - s->tlsext_opaque_prf_input = BUF_memdup(parg, (size_t)larg); - if (s->tlsext_opaque_prf_input != NULL) { - s->tlsext_opaque_prf_input_len = (size_t)larg; - ret = 1; - } else - s->tlsext_opaque_prf_input_len = 0; - break; -# endif - - case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: - s->tlsext_status_type = larg; - ret = 1; - break; - - case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS: - *(STACK_OF(X509_EXTENSION) **)parg = s->tlsext_ocsp_exts; - ret = 1; - break; - - case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS: - s->tlsext_ocsp_exts = parg; - ret = 1; - break; - - case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS: - *(STACK_OF(OCSP_RESPID) **)parg = s->tlsext_ocsp_ids; - ret = 1; - break; - - case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS: - s->tlsext_ocsp_ids = parg; - ret = 1; - break; - - case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: - *(unsigned char **)parg = s->tlsext_ocsp_resp; - return s->tlsext_ocsp_resplen; - - case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: - if (s->tlsext_ocsp_resp) - OPENSSL_free(s->tlsext_ocsp_resp); - s->tlsext_ocsp_resp = parg; - s->tlsext_ocsp_resplen = larg; - ret = 1; - break; - -# ifndef OPENSSL_NO_HEARTBEATS - case SSL_CTRL_TLS_EXT_SEND_HEARTBEAT: - if (SSL_IS_DTLS(s)) - ret = dtls1_heartbeat(s); - else - ret = tls1_heartbeat(s); - break; - - case SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING: - ret = s->tlsext_hb_pending; - break; - - case SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS: - if (larg) - s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_RECV_REQUESTS; - else - s->tlsext_heartbeat &= ~SSL_TLSEXT_HB_DONT_RECV_REQUESTS; - ret = 1; - break; -# endif - -#endif /* !OPENSSL_NO_TLSEXT */ - - case SSL_CTRL_CHAIN: - if (larg) - return ssl_cert_set1_chain(s->cert, (STACK_OF(X509) *)parg); - else - return ssl_cert_set0_chain(s->cert, (STACK_OF(X509) *)parg); - - case SSL_CTRL_CHAIN_CERT: - if (larg) - return ssl_cert_add1_chain_cert(s->cert, (X509 *)parg); - else - return ssl_cert_add0_chain_cert(s->cert, (X509 *)parg); - - case SSL_CTRL_GET_CHAIN_CERTS: - *(STACK_OF(X509) **)parg = s->cert->key->chain; - break; - - case SSL_CTRL_SELECT_CURRENT_CERT: - return ssl_cert_select_current(s->cert, (X509 *)parg); - - case SSL_CTRL_SET_CURRENT_CERT: - if (larg == SSL_CERT_SET_SERVER) { - CERT_PKEY *cpk; - const SSL_CIPHER *cipher; - if (!s->server) - return 0; - cipher = s->s3->tmp.new_cipher; - if (!cipher) - return 0; - /* - * No certificate for unauthenticated ciphersuites or using SRP - * authentication - */ - if (cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) - return 2; - cpk = ssl_get_server_send_pkey(s); - if (!cpk) - return 0; - s->cert->key = cpk; - return 1; - } - return ssl_cert_set_current(s->cert, larg); - -#ifndef OPENSSL_NO_EC - case SSL_CTRL_GET_CURVES: - { - unsigned char *clist; - size_t clistlen; - if (!s->session) - return 0; - clist = s->session->tlsext_ellipticcurvelist; - clistlen = s->session->tlsext_ellipticcurvelist_length / 2; - if (parg) { - size_t i; - int *cptr = parg; - unsigned int cid, nid; - for (i = 0; i < clistlen; i++) { - n2s(clist, cid); - nid = tls1_ec_curve_id2nid(cid); - if (nid != 0) - cptr[i] = nid; - else - cptr[i] = TLSEXT_nid_unknown | cid; - } - } - return (int)clistlen; - } - - case SSL_CTRL_SET_CURVES: - return tls1_set_curves(&s->tlsext_ellipticcurvelist, - &s->tlsext_ellipticcurvelist_length, - parg, larg); - - case SSL_CTRL_SET_CURVES_LIST: - return tls1_set_curves_list(&s->tlsext_ellipticcurvelist, - &s->tlsext_ellipticcurvelist_length, - parg); - - case SSL_CTRL_GET_SHARED_CURVE: - return tls1_shared_curve(s, larg); - -# ifndef OPENSSL_NO_ECDH - case SSL_CTRL_SET_ECDH_AUTO: - s->cert->ecdh_tmp_auto = larg; - return 1; -# endif -#endif - case SSL_CTRL_SET_SIGALGS: - return tls1_set_sigalgs(s->cert, parg, larg, 0); - - case SSL_CTRL_SET_SIGALGS_LIST: - return tls1_set_sigalgs_list(s->cert, parg, 0); - - case SSL_CTRL_SET_CLIENT_SIGALGS: - return tls1_set_sigalgs(s->cert, parg, larg, 1); - - case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: - return tls1_set_sigalgs_list(s->cert, parg, 1); - - case SSL_CTRL_GET_CLIENT_CERT_TYPES: - { - const unsigned char **pctype = parg; - if (s->server || !s->s3->tmp.cert_req) - return 0; - if (s->cert->ctypes) { - if (pctype) - *pctype = s->cert->ctypes; - return (int)s->cert->ctype_num; - } - if (pctype) - *pctype = (unsigned char *)s->s3->tmp.ctype; - return s->s3->tmp.ctype_num; - } - - case SSL_CTRL_SET_CLIENT_CERT_TYPES: - if (!s->server) - return 0; - return ssl3_set_req_cert_type(s->cert, parg, larg); - - case SSL_CTRL_BUILD_CERT_CHAIN: - return ssl_build_cert_chain(s->cert, s->ctx->cert_store, larg); - - case SSL_CTRL_SET_VERIFY_CERT_STORE: - return ssl_cert_set_cert_store(s->cert, parg, 0, larg); - - case SSL_CTRL_SET_CHAIN_CERT_STORE: - return ssl_cert_set_cert_store(s->cert, parg, 1, larg); - - case SSL_CTRL_GET_PEER_SIGNATURE_NID: - if (SSL_USE_SIGALGS(s)) { - if (s->session && s->session->sess_cert) { - const EVP_MD *sig; - sig = s->session->sess_cert->peer_key->digest; - if (sig) { - *(int *)parg = EVP_MD_type(sig); - return 1; - } - } - return 0; - } - /* Might want to do something here for other versions */ - else - return 0; - - case SSL_CTRL_GET_SERVER_TMP_KEY: - if (s->server || !s->session || !s->session->sess_cert) - return 0; - else { - SESS_CERT *sc; - EVP_PKEY *ptmp; - int rv = 0; - sc = s->session->sess_cert; -#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDH) - if (!sc->peer_rsa_tmp && !sc->peer_dh_tmp && !sc->peer_ecdh_tmp) - return 0; -#endif - ptmp = EVP_PKEY_new(); - if (!ptmp) - return 0; - if (0) ; -#ifndef OPENSSL_NO_RSA - else if (sc->peer_rsa_tmp) - rv = EVP_PKEY_set1_RSA(ptmp, sc->peer_rsa_tmp); -#endif -#ifndef OPENSSL_NO_DH - else if (sc->peer_dh_tmp) - rv = EVP_PKEY_set1_DH(ptmp, sc->peer_dh_tmp); -#endif -#ifndef OPENSSL_NO_ECDH - else if (sc->peer_ecdh_tmp) - rv = EVP_PKEY_set1_EC_KEY(ptmp, sc->peer_ecdh_tmp); -#endif - if (rv) { - *(EVP_PKEY **)parg = ptmp; - return 1; - } - EVP_PKEY_free(ptmp); - return 0; - } -#ifndef OPENSSL_NO_EC - case SSL_CTRL_GET_EC_POINT_FORMATS: - { - SSL_SESSION *sess = s->session; - const unsigned char **pformat = parg; - if (!sess || !sess->tlsext_ecpointformatlist) - return 0; - *pformat = sess->tlsext_ecpointformatlist; - return (int)sess->tlsext_ecpointformatlist_length; - } -#endif - - case SSL_CTRL_CHECK_PROTO_VERSION: - /* - * For library-internal use; checks that the current protocol is the - * highest enabled version (according to s->ctx->method, as version - * negotiation may have changed s->method). - */ - if (s->version == s->ctx->method->version) - return 1; - /* - * Apparently we're using a version-flexible SSL_METHOD (not at its - * highest protocol version). - */ - if (s->ctx->method->version == SSLv23_method()->version) { -#if TLS_MAX_VERSION != TLS1_2_VERSION -# error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION. -#endif - if (!(s->options & SSL_OP_NO_TLSv1_2)) - return s->version == TLS1_2_VERSION; - if (!(s->options & SSL_OP_NO_TLSv1_1)) - return s->version == TLS1_1_VERSION; - if (!(s->options & SSL_OP_NO_TLSv1)) - return s->version == TLS1_VERSION; - if (!(s->options & SSL_OP_NO_SSLv3)) - return s->version == SSL3_VERSION; - if (!(s->options & SSL_OP_NO_SSLv2)) - return s->version == SSL2_VERSION; - } - return 0; /* Unexpected state; fail closed. */ - - default: - break; - } - return (ret); -} - -long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) -{ - int ret = 0; - -#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA) - if ( -# ifndef OPENSSL_NO_RSA - cmd == SSL_CTRL_SET_TMP_RSA_CB || -# endif -# ifndef OPENSSL_NO_DSA - cmd == SSL_CTRL_SET_TMP_DH_CB || -# endif - 0) { - if (!ssl_cert_inst(&s->cert)) { - SSLerr(SSL_F_SSL3_CALLBACK_CTRL, ERR_R_MALLOC_FAILURE); - return (0); - } - } -#endif - - switch (cmd) { -#ifndef OPENSSL_NO_RSA - case SSL_CTRL_SET_TMP_RSA_CB: - { - s->cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp; - } - break; -#endif -#ifndef OPENSSL_NO_DH - case SSL_CTRL_SET_TMP_DH_CB: - { - s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; - } - break; -#endif -#ifndef OPENSSL_NO_ECDH - case SSL_CTRL_SET_TMP_ECDH_CB: - { - s->cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp; - } - break; -#endif -#ifndef OPENSSL_NO_TLSEXT - case SSL_CTRL_SET_TLSEXT_DEBUG_CB: - s->tlsext_debug_cb = (void (*)(SSL *, int, int, - unsigned char *, int, void *))fp; - break; -#endif - default: - break; - } - return (ret); -} - -long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) -{ - CERT *cert; - - cert = ctx->cert; - - switch (cmd) { -#ifndef OPENSSL_NO_RSA - case SSL_CTRL_NEED_TMP_RSA: - if ((cert->rsa_tmp == NULL) && - ((cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) || - (EVP_PKEY_size(cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) > - (512 / 8))) - ) - return (1); - else - return (0); - /* break; */ - case SSL_CTRL_SET_TMP_RSA: - { - RSA *rsa; - int i; - - rsa = (RSA *)parg; - i = 1; - if (rsa == NULL) - i = 0; - else { - if ((rsa = RSAPrivateKey_dup(rsa)) == NULL) - i = 0; - } - if (!i) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_RSA_LIB); - return (0); - } else { - if (cert->rsa_tmp != NULL) - RSA_free(cert->rsa_tmp); - cert->rsa_tmp = rsa; - return (1); - } - } - /* break; */ - case SSL_CTRL_SET_TMP_RSA_CB: - { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (0); - } - break; -#endif -#ifndef OPENSSL_NO_DH - case SSL_CTRL_SET_TMP_DH: - { - DH *new = NULL, *dh; - - dh = (DH *)parg; - if ((new = DHparams_dup(dh)) == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_DH_LIB); - return 0; - } - if (cert->dh_tmp != NULL) - DH_free(cert->dh_tmp); - cert->dh_tmp = new; - return 1; - } - /* - * break; - */ - case SSL_CTRL_SET_TMP_DH_CB: - { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (0); - } - break; -#endif -#ifndef OPENSSL_NO_ECDH - case SSL_CTRL_SET_TMP_ECDH: - { - EC_KEY *ecdh = NULL; - - if (parg == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_ECDH_LIB); - return 0; - } - ecdh = EC_KEY_dup((EC_KEY *)parg); - if (ecdh == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_EC_LIB); - return 0; - } - if (!(ctx->options & SSL_OP_SINGLE_ECDH_USE)) { - if (!EC_KEY_generate_key(ecdh)) { - EC_KEY_free(ecdh); - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_ECDH_LIB); - return 0; - } - } - - if (cert->ecdh_tmp != NULL) { - EC_KEY_free(cert->ecdh_tmp); - } - cert->ecdh_tmp = ecdh; - return 1; - } - /* break; */ - case SSL_CTRL_SET_TMP_ECDH_CB: - { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (0); - } - break; -#endif /* !OPENSSL_NO_ECDH */ -#ifndef OPENSSL_NO_TLSEXT - case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG: - ctx->tlsext_servername_arg = parg; - break; - case SSL_CTRL_SET_TLSEXT_TICKET_KEYS: - case SSL_CTRL_GET_TLSEXT_TICKET_KEYS: - { - unsigned char *keys = parg; - if (!keys) - return 48; - if (larg != 48) { - SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_TICKET_KEYS_LENGTH); - return 0; - } - if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS) { - memcpy(ctx->tlsext_tick_key_name, keys, 16); - memcpy(ctx->tlsext_tick_hmac_key, keys + 16, 16); - memcpy(ctx->tlsext_tick_aes_key, keys + 32, 16); - } else { - memcpy(keys, ctx->tlsext_tick_key_name, 16); - memcpy(keys + 16, ctx->tlsext_tick_hmac_key, 16); - memcpy(keys + 32, ctx->tlsext_tick_aes_key, 16); - } - return 1; - } - -# ifdef TLSEXT_TYPE_opaque_prf_input - case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG: - ctx->tlsext_opaque_prf_input_callback_arg = parg; - return 1; -# endif - - case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG: - ctx->tlsext_status_arg = parg; - return 1; - break; - -# ifndef OPENSSL_NO_SRP - case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME: - ctx->srp_ctx.srp_Mask |= SSL_kSRP; - if (ctx->srp_ctx.login != NULL) - OPENSSL_free(ctx->srp_ctx.login); - ctx->srp_ctx.login = NULL; - if (parg == NULL) - break; - if (strlen((const char *)parg) > 255 - || strlen((const char *)parg) < 1) { - SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME); - return 0; - } - if ((ctx->srp_ctx.login = BUF_strdup((char *)parg)) == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR); - return 0; - } - break; - case SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD: - ctx->srp_ctx.SRP_give_srp_client_pwd_callback = - srp_password_from_info_cb; - ctx->srp_ctx.info = parg; - break; - case SSL_CTRL_SET_SRP_ARG: - ctx->srp_ctx.srp_Mask |= SSL_kSRP; - ctx->srp_ctx.SRP_cb_arg = parg; - break; - - case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH: - ctx->srp_ctx.strength = larg; - break; -# endif - -# ifndef OPENSSL_NO_EC - case SSL_CTRL_SET_CURVES: - return tls1_set_curves(&ctx->tlsext_ellipticcurvelist, - &ctx->tlsext_ellipticcurvelist_length, - parg, larg); - - case SSL_CTRL_SET_CURVES_LIST: - return tls1_set_curves_list(&ctx->tlsext_ellipticcurvelist, - &ctx->tlsext_ellipticcurvelist_length, - parg); -# ifndef OPENSSL_NO_ECDH - case SSL_CTRL_SET_ECDH_AUTO: - ctx->cert->ecdh_tmp_auto = larg; - return 1; -# endif -# endif - case SSL_CTRL_SET_SIGALGS: - return tls1_set_sigalgs(ctx->cert, parg, larg, 0); - - case SSL_CTRL_SET_SIGALGS_LIST: - return tls1_set_sigalgs_list(ctx->cert, parg, 0); - - case SSL_CTRL_SET_CLIENT_SIGALGS: - return tls1_set_sigalgs(ctx->cert, parg, larg, 1); - - case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: - return tls1_set_sigalgs_list(ctx->cert, parg, 1); - - case SSL_CTRL_SET_CLIENT_CERT_TYPES: - return ssl3_set_req_cert_type(ctx->cert, parg, larg); - - case SSL_CTRL_BUILD_CERT_CHAIN: - return ssl_build_cert_chain(ctx->cert, ctx->cert_store, larg); - - case SSL_CTRL_SET_VERIFY_CERT_STORE: - return ssl_cert_set_cert_store(ctx->cert, parg, 0, larg); - - case SSL_CTRL_SET_CHAIN_CERT_STORE: - return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg); - -#endif /* !OPENSSL_NO_TLSEXT */ - - /* A Thawte special :-) */ - case SSL_CTRL_EXTRA_CHAIN_CERT: - if (ctx->extra_certs == NULL) { - if ((ctx->extra_certs = sk_X509_new_null()) == NULL) - return (0); - } - sk_X509_push(ctx->extra_certs, (X509 *)parg); - break; - - case SSL_CTRL_GET_EXTRA_CHAIN_CERTS: - if (ctx->extra_certs == NULL && larg == 0) - *(STACK_OF(X509) **)parg = ctx->cert->key->chain; - else - *(STACK_OF(X509) **)parg = ctx->extra_certs; - break; - - case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS: - if (ctx->extra_certs) { - sk_X509_pop_free(ctx->extra_certs, X509_free); - ctx->extra_certs = NULL; - } - break; - - case SSL_CTRL_CHAIN: - if (larg) - return ssl_cert_set1_chain(ctx->cert, (STACK_OF(X509) *)parg); - else - return ssl_cert_set0_chain(ctx->cert, (STACK_OF(X509) *)parg); - - case SSL_CTRL_CHAIN_CERT: - if (larg) - return ssl_cert_add1_chain_cert(ctx->cert, (X509 *)parg); - else - return ssl_cert_add0_chain_cert(ctx->cert, (X509 *)parg); - - case SSL_CTRL_GET_CHAIN_CERTS: - *(STACK_OF(X509) **)parg = ctx->cert->key->chain; - break; - - case SSL_CTRL_SELECT_CURRENT_CERT: - return ssl_cert_select_current(ctx->cert, (X509 *)parg); - - case SSL_CTRL_SET_CURRENT_CERT: - return ssl_cert_set_current(ctx->cert, larg); - - default: - return (0); - } - return (1); -} - -long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) -{ - CERT *cert; - - cert = ctx->cert; - - switch (cmd) { -#ifndef OPENSSL_NO_RSA - case SSL_CTRL_SET_TMP_RSA_CB: - { - cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp; - } - break; -#endif -#ifndef OPENSSL_NO_DH - case SSL_CTRL_SET_TMP_DH_CB: - { - cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; - } - break; -#endif -#ifndef OPENSSL_NO_ECDH - case SSL_CTRL_SET_TMP_ECDH_CB: - { - cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp; - } - break; -#endif -#ifndef OPENSSL_NO_TLSEXT - case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB: - ctx->tlsext_servername_callback = (int (*)(SSL *, int *, void *))fp; - break; - -# ifdef TLSEXT_TYPE_opaque_prf_input - case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB: - ctx->tlsext_opaque_prf_input_callback = - (int (*)(SSL *, void *, size_t, void *))fp; - break; -# endif - - case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB: - ctx->tlsext_status_cb = (int (*)(SSL *, void *))fp; - break; - - case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB: - ctx->tlsext_ticket_key_cb = (int (*)(SSL *, unsigned char *, - unsigned char *, - EVP_CIPHER_CTX *, - HMAC_CTX *, int))fp; - break; - -# ifndef OPENSSL_NO_SRP - case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB: - ctx->srp_ctx.srp_Mask |= SSL_kSRP; - ctx->srp_ctx.SRP_verify_param_callback = (int (*)(SSL *, void *))fp; - break; - case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB: - ctx->srp_ctx.srp_Mask |= SSL_kSRP; - ctx->srp_ctx.TLS_ext_srp_username_callback = - (int (*)(SSL *, int *, void *))fp; - break; - case SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB: - ctx->srp_ctx.srp_Mask |= SSL_kSRP; - ctx->srp_ctx.SRP_give_srp_client_pwd_callback = - (char *(*)(SSL *, void *))fp; - break; -# endif -#endif - default: - return (0); - } - return (1); -} - -/* - * This function needs to check if the ciphers required are actually - * available - */ -const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p) -{ - SSL_CIPHER c; - const SSL_CIPHER *cp; - unsigned long id; - - id = 0x03000000L | ((unsigned long)p[0] << 8L) | (unsigned long)p[1]; - c.id = id; - cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS); -#ifdef DEBUG_PRINT_UNKNOWN_CIPHERSUITES - if (cp == NULL) - fprintf(stderr, "Unknown cipher ID %x\n", (p[0] << 8) | p[1]); -#endif - return cp; -} - -int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) -{ - long l; - - if (p != NULL) { - l = c->id; - if ((l & 0xff000000) != 0x03000000) - return (0); - p[0] = ((unsigned char)(l >> 8L)) & 0xFF; - p[1] = ((unsigned char)(l)) & 0xFF; - } - return (2); -} - -SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, - STACK_OF(SSL_CIPHER) *srvr) -{ - SSL_CIPHER *c, *ret = NULL; - STACK_OF(SSL_CIPHER) *prio, *allow; - int i, ii, ok; - CERT *cert; - unsigned long alg_k, alg_a, mask_k, mask_a, emask_k, emask_a; - - /* Let's see which ciphers we can support */ - cert = s->cert; - -#if 0 - /* - * Do not set the compare functions, because this may lead to a - * reordering by "id". We want to keep the original ordering. We may pay - * a price in performance during sk_SSL_CIPHER_find(), but would have to - * pay with the price of sk_SSL_CIPHER_dup(). - */ - sk_SSL_CIPHER_set_cmp_func(srvr, ssl_cipher_ptr_id_cmp); - sk_SSL_CIPHER_set_cmp_func(clnt, ssl_cipher_ptr_id_cmp); -#endif - -#ifdef CIPHER_DEBUG - fprintf(stderr, "Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), - (void *)srvr); - for (i = 0; i < sk_SSL_CIPHER_num(srvr); ++i) { - c = sk_SSL_CIPHER_value(srvr, i); - fprintf(stderr, "%p:%s\n", (void *)c, c->name); - } - fprintf(stderr, "Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), - (void *)clnt); - for (i = 0; i < sk_SSL_CIPHER_num(clnt); ++i) { - c = sk_SSL_CIPHER_value(clnt, i); - fprintf(stderr, "%p:%s\n", (void *)c, c->name); - } -#endif - - if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || tls1_suiteb(s)) { - prio = srvr; - allow = clnt; - } else { - prio = clnt; - allow = srvr; - } - - tls1_set_cert_validity(s); - - for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { - c = sk_SSL_CIPHER_value(prio, i); - - /* Skip TLS v1.2 only ciphersuites if not supported */ - if ((c->algorithm_ssl & SSL_TLSV1_2) && !SSL_USE_TLS1_2_CIPHERS(s)) - continue; - - ssl_set_cert_masks(cert, c); - mask_k = cert->mask_k; - mask_a = cert->mask_a; - emask_k = cert->export_mask_k; - emask_a = cert->export_mask_a; -#ifndef OPENSSL_NO_SRP - if (s->srp_ctx.srp_Mask & SSL_kSRP) { - mask_k |= SSL_kSRP; - emask_k |= SSL_kSRP; - mask_a |= SSL_aSRP; - emask_a |= SSL_aSRP; - } -#endif - -#ifdef KSSL_DEBUG - /* - * fprintf(stderr,"ssl3_choose_cipher %d alg= %lx\n", - * i,c->algorithms); - */ -#endif /* KSSL_DEBUG */ - - alg_k = c->algorithm_mkey; - alg_a = c->algorithm_auth; - -#ifndef OPENSSL_NO_KRB5 - if (alg_k & SSL_kKRB5) { - if (!kssl_keytab_is_available(s->kssl_ctx)) - continue; - } -#endif /* OPENSSL_NO_KRB5 */ -#ifndef OPENSSL_NO_PSK - /* with PSK there must be server callback set */ - if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL) - continue; -#endif /* OPENSSL_NO_PSK */ - - if (SSL_C_IS_EXPORT(c)) { - ok = (alg_k & emask_k) && (alg_a & emask_a); -#ifdef CIPHER_DEBUG - fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n", - ok, alg_k, alg_a, emask_k, emask_a, (void *)c, c->name); -#endif - } else { - ok = (alg_k & mask_k) && (alg_a & mask_a); -#ifdef CIPHER_DEBUG - fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", ok, alg_k, - alg_a, mask_k, mask_a, (void *)c, c->name); -#endif - } - -#ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_EC -# ifndef OPENSSL_NO_ECDH - /* - * if we are considering an ECC cipher suite that uses an ephemeral - * EC key check it - */ - if (alg_k & SSL_kEECDH) - ok = ok && tls1_check_ec_tmp_key(s, c->id); -# endif /* OPENSSL_NO_ECDH */ -# endif /* OPENSSL_NO_EC */ -#endif /* OPENSSL_NO_TLSEXT */ - - if (!ok) - continue; - ii = sk_SSL_CIPHER_find(allow, c); - if (ii >= 0) { -#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_TLSEXT) - if ((alg_k & SSL_kEECDH) && (alg_a & SSL_aECDSA) - && s->s3->is_probably_safari) { - if (!ret) - ret = sk_SSL_CIPHER_value(allow, ii); - continue; - } -#endif - ret = sk_SSL_CIPHER_value(allow, ii); - break; - } - } - return (ret); -} - -int ssl3_get_req_cert_type(SSL *s, unsigned char *p) -{ - int ret = 0; - const unsigned char *sig; - size_t i, siglen; - int have_rsa_sign = 0, have_dsa_sign = 0; -#ifndef OPENSSL_NO_ECDSA - int have_ecdsa_sign = 0; -#endif - int nostrict = 1; - unsigned long alg_k; - - /* If we have custom certificate types set, use them */ - if (s->cert->ctypes) { - memcpy(p, s->cert->ctypes, s->cert->ctype_num); - return (int)s->cert->ctype_num; - } - /* get configured sigalgs */ - siglen = tls12_get_psigalgs(s, 1, &sig); - if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) - nostrict = 0; - for (i = 0; i < siglen; i += 2, sig += 2) { - switch (sig[1]) { - case TLSEXT_signature_rsa: - have_rsa_sign = 1; - break; - - case TLSEXT_signature_dsa: - have_dsa_sign = 1; - break; -#ifndef OPENSSL_NO_ECDSA - case TLSEXT_signature_ecdsa: - have_ecdsa_sign = 1; - break; -#endif - } - } - - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - -#ifndef OPENSSL_NO_GOST - if (s->version >= TLS1_VERSION) { - if (alg_k & SSL_kGOST) { - p[ret++] = TLS_CT_GOST94_SIGN; - p[ret++] = TLS_CT_GOST01_SIGN; - return (ret); - } - } -#endif - -#ifndef OPENSSL_NO_DH - if (alg_k & (SSL_kDHr | SSL_kEDH)) { -# ifndef OPENSSL_NO_RSA - /* - * Since this refers to a certificate signed with an RSA algorithm, - * only check for rsa signing in strict mode. - */ - if (nostrict || have_rsa_sign) - p[ret++] = SSL3_CT_RSA_FIXED_DH; -# endif -# ifndef OPENSSL_NO_DSA - if (nostrict || have_dsa_sign) - p[ret++] = SSL3_CT_DSS_FIXED_DH; -# endif - } - if ((s->version == SSL3_VERSION) && - (alg_k & (SSL_kEDH | SSL_kDHd | SSL_kDHr))) { -# ifndef OPENSSL_NO_RSA - p[ret++] = SSL3_CT_RSA_EPHEMERAL_DH; -# endif -# ifndef OPENSSL_NO_DSA - p[ret++] = SSL3_CT_DSS_EPHEMERAL_DH; -# endif - } -#endif /* !OPENSSL_NO_DH */ -#ifndef OPENSSL_NO_RSA - if (have_rsa_sign) - p[ret++] = SSL3_CT_RSA_SIGN; -#endif -#ifndef OPENSSL_NO_DSA - if (have_dsa_sign) - p[ret++] = SSL3_CT_DSS_SIGN; -#endif -#ifndef OPENSSL_NO_ECDH - if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->version >= TLS1_VERSION)) { - if (nostrict || have_rsa_sign) - p[ret++] = TLS_CT_RSA_FIXED_ECDH; - if (nostrict || have_ecdsa_sign) - p[ret++] = TLS_CT_ECDSA_FIXED_ECDH; - } -#endif - -#ifndef OPENSSL_NO_ECDSA - /* - * ECDSA certs can be used with RSA cipher suites as well so we don't - * need to check for SSL_kECDH or SSL_kEECDH - */ - if (s->version >= TLS1_VERSION) { - if (have_ecdsa_sign) - p[ret++] = TLS_CT_ECDSA_SIGN; - } -#endif - return (ret); -} - -static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, size_t len) -{ - if (c->ctypes) { - OPENSSL_free(c->ctypes); - c->ctypes = NULL; - } - if (!p || !len) - return 1; - if (len > 0xff) - return 0; - c->ctypes = OPENSSL_malloc(len); - if (!c->ctypes) - return 0; - memcpy(c->ctypes, p, len); - c->ctype_num = len; - return 1; -} - -int ssl3_shutdown(SSL *s) -{ - int ret; - - /* - * Don't do anything much if we have not done the handshake or we don't - * want to send messages :-) - */ - if ((s->quiet_shutdown) || (s->state == SSL_ST_BEFORE)) { - s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); - return (1); - } - - if (!(s->shutdown & SSL_SENT_SHUTDOWN)) { - s->shutdown |= SSL_SENT_SHUTDOWN; -#if 1 - ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY); -#endif - /* - * our shutdown alert has been sent now, and if it still needs to be - * written, s->s3->alert_dispatch will be true - */ - if (s->s3->alert_dispatch) - return (-1); /* return WANT_WRITE */ - } else if (s->s3->alert_dispatch) { - /* resend it if not sent */ -#if 1 - ret = s->method->ssl_dispatch_alert(s); - if (ret == -1) { - /* - * we only get to return -1 here the 2nd/Nth invocation, we must - * have already signalled return 0 upon a previous invoation, - * return WANT_WRITE - */ - return (ret); - } -#endif - } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { - /* - * If we are waiting for a close from our peer, we are closed - */ - s->method->ssl_read_bytes(s, 0, NULL, 0, 0); - if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { - return (-1); /* return WANT_READ */ - } - } - - if ((s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) && - !s->s3->alert_dispatch) - return (1); - else - return (0); -} - -int ssl3_write(SSL *s, const void *buf, int len) -{ - int ret, n; - -#if 0 - if (s->shutdown & SSL_SEND_SHUTDOWN) { - s->rwstate = SSL_NOTHING; - return (0); - } -#endif - clear_sys_error(); - if (s->s3->renegotiate) - ssl3_renegotiate_check(s); - - /* - * This is an experimental flag that sends the last handshake message in - * the same packet as the first use data - used to see if it helps the - * TCP protocol during session-id reuse - */ - /* The second test is because the buffer may have been removed */ - if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio)) { - /* First time through, we write into the buffer */ - if (s->s3->delay_buf_pop_ret == 0) { - ret = ssl3_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len); - if (ret <= 0) - return (ret); - - s->s3->delay_buf_pop_ret = ret; - } - - s->rwstate = SSL_WRITING; - n = BIO_flush(s->wbio); - if (n <= 0) - return (n); - s->rwstate = SSL_NOTHING; - - /* We have flushed the buffer, so remove it */ - ssl_free_wbio_buffer(s); - s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; - - ret = s->s3->delay_buf_pop_ret; - s->s3->delay_buf_pop_ret = 0; - } else { - ret = s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, - buf, len); - if (ret <= 0) - return (ret); - } - - return (ret); -} - -static int ssl3_read_internal(SSL *s, void *buf, int len, int peek) -{ - int ret; - - clear_sys_error(); - if (s->s3->renegotiate) - ssl3_renegotiate_check(s); - s->s3->in_read_app_data = 1; - ret = - s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, - peek); - if ((ret == -1) && (s->s3->in_read_app_data == 2)) { - /* - * ssl3_read_bytes decided to call s->handshake_func, which called - * ssl3_read_bytes to read handshake data. However, ssl3_read_bytes - * actually found application data and thinks that application data - * makes sense here; so disable handshake processing and try to read - * application data again. - */ - s->in_handshake++; - ret = - s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, - peek); - s->in_handshake--; - } else - s->s3->in_read_app_data = 0; - - return (ret); -} - -int ssl3_read(SSL *s, void *buf, int len) -{ - return ssl3_read_internal(s, buf, len, 0); -} - -int ssl3_peek(SSL *s, void *buf, int len) -{ - return ssl3_read_internal(s, buf, len, 1); -} - -int ssl3_renegotiate(SSL *s) -{ - if (s->handshake_func == NULL) - return (1); - - if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) - return (0); - - s->s3->renegotiate = 1; - return (1); -} - -int ssl3_renegotiate_check(SSL *s) -{ - int ret = 0; - - if (s->s3->renegotiate) { - if ((s->s3->rbuf.left == 0) && - (s->s3->wbuf.left == 0) && !SSL_in_init(s)) { - /* - * if we are the server, and we have sent a 'RENEGOTIATE' - * message, we need to go to SSL_ST_ACCEPT. - */ - /* SSL_ST_ACCEPT */ - s->state = SSL_ST_RENEGOTIATE; - s->s3->renegotiate = 0; - s->s3->num_renegotiations++; - s->s3->total_renegotiations++; - ret = 1; - } - } - return (ret); -} - -/* - * If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and - * handshake macs if required. - */ -long ssl_get_algorithm2(SSL *s) -{ - long alg2; - if (s->s3 == NULL || s->s3->tmp.new_cipher == NULL) - return -1; - alg2 = s->s3->tmp.new_cipher->algorithm2; - if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF - && alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF)) - return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; - return alg2; -} diff --git a/thirdparty/openssl/ssl/s3_meth.c b/thirdparty/openssl/ssl/s3_meth.c deleted file mode 100644 index e5a52993fc..0000000000 --- a/thirdparty/openssl/ssl/s3_meth.c +++ /dev/null @@ -1,74 +0,0 @@ -/* ssl/s3_meth.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include <openssl/objects.h> -#include "ssl_locl.h" - -#ifndef OPENSSL_NO_SSL3_METHOD -static const SSL_METHOD *ssl3_get_method(int ver) -{ - if (ver == SSL3_VERSION) - return (SSLv3_method()); - else - return (NULL); -} - -IMPLEMENT_ssl3_meth_func(SSLv3_method, - ssl3_accept, ssl3_connect, ssl3_get_method) -#endif diff --git a/thirdparty/openssl/ssl/s3_pkt.c b/thirdparty/openssl/ssl/s3_pkt.c deleted file mode 100644 index 0290c991d8..0000000000 --- a/thirdparty/openssl/ssl/s3_pkt.c +++ /dev/null @@ -1,1767 +0,0 @@ -/* ssl/s3_pkt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2002 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 - * openssl-core@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). - * - */ - -#include <stdio.h> -#include <limits.h> -#include <errno.h> -#define USE_SOCKETS -#include "ssl_locl.h" -#include <openssl/evp.h> -#include <openssl/buffer.h> -#include <openssl/rand.h> - -#ifndef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK -# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 -#endif - -#if defined(OPENSSL_SMALL_FOOTPRINT) || \ - !( defined(AES_ASM) && ( \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64) || \ - defined(__INTEL__) ) \ - ) -# undef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK -# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 -#endif - -static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, - unsigned int len, int create_empty_fragment); -static int ssl3_get_record(SSL *s); - -/* - * Return values are as per SSL_read() - */ -int ssl3_read_n(SSL *s, int n, int max, int extend) -{ - /* - * If extend == 0, obtain new n-byte packet; if extend == 1, increase - * packet by another n bytes. The packet will be in the sub-array of - * s->s3->rbuf.buf specified by s->packet and s->packet_length. (If - * s->read_ahead is set, 'max' bytes may be stored in rbuf [plus - * s->packet_length bytes if extend == 1].) - */ - int i, len, left; - long align = 0; - unsigned char *pkt; - SSL3_BUFFER *rb; - - if (n <= 0) - return n; - - rb = &(s->s3->rbuf); - if (rb->buf == NULL) - if (!ssl3_setup_read_buffer(s)) - return -1; - - left = rb->left; -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - align = (long)rb->buf + SSL3_RT_HEADER_LENGTH; - align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); -#endif - - if (!extend) { - /* start with empty packet ... */ - if (left == 0) - rb->offset = align; - else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) { - /* - * check if next packet length is large enough to justify payload - * alignment... - */ - pkt = rb->buf + rb->offset; - if (pkt[0] == SSL3_RT_APPLICATION_DATA - && (pkt[3] << 8 | pkt[4]) >= 128) { - /* - * Note that even if packet is corrupted and its length field - * is insane, we can only be led to wrong decision about - * whether memmove will occur or not. Header values has no - * effect on memmove arguments and therefore no buffer - * overrun can be triggered. - */ - memmove(rb->buf + align, pkt, left); - rb->offset = align; - } - } - s->packet = rb->buf + rb->offset; - s->packet_length = 0; - /* ... now we can act as if 'extend' was set */ - } - - /* - * For DTLS/UDP reads should not span multiple packets because the read - * operation returns the whole packet at once (as long as it fits into - * the buffer). - */ - if (SSL_IS_DTLS(s)) { - if (left == 0 && extend) - return 0; - if (left > 0 && n > left) - n = left; - } - - /* if there is enough in the buffer from a previous read, take some */ - if (left >= n) { - s->packet_length += n; - rb->left = left - n; - rb->offset += n; - return (n); - } - - /* else we need to read more data */ - - len = s->packet_length; - pkt = rb->buf + align; - /* - * Move any available bytes to front of buffer: 'len' bytes already - * pointed to by 'packet', 'left' extra ones at the end - */ - if (s->packet != pkt) { /* len > 0 */ - memmove(pkt, s->packet, len + left); - s->packet = pkt; - rb->offset = len + align; - } - - if (n > (int)(rb->len - rb->offset)) { /* does not happen */ - SSLerr(SSL_F_SSL3_READ_N, ERR_R_INTERNAL_ERROR); - return -1; - } - - /* We always act like read_ahead is set for DTLS */ - if (!s->read_ahead && !SSL_IS_DTLS(s)) - /* ignore max parameter */ - max = n; - else { - if (max < n) - max = n; - if (max > (int)(rb->len - rb->offset)) - max = rb->len - rb->offset; - } - - while (left < n) { - /* - * Now we have len+left bytes at the front of s->s3->rbuf.buf and - * need to read in more until we have len+n (up to len+max if - * possible) - */ - - clear_sys_error(); - if (s->rbio != NULL) { - s->rwstate = SSL_READING; - i = BIO_read(s->rbio, pkt + len + left, max - left); - } else { - SSLerr(SSL_F_SSL3_READ_N, SSL_R_READ_BIO_NOT_SET); - i = -1; - } - - if (i <= 0) { - rb->left = left; - if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s)) - if (len + left == 0) - ssl3_release_read_buffer(s); - return (i); - } - left += i; - /* - * reads should *never* span multiple packets for DTLS because the - * underlying transport protocol is message oriented as opposed to - * byte oriented as in the TLS case. - */ - if (SSL_IS_DTLS(s)) { - if (n > left) - n = left; /* makes the while condition false */ - } - } - - /* done reading, now the book-keeping */ - rb->offset += n; - rb->left = left - n; - s->packet_length += n; - s->rwstate = SSL_NOTHING; - return (n); -} - -/* - * MAX_EMPTY_RECORDS defines the number of consecutive, empty records that - * will be processed per call to ssl3_get_record. Without this limit an - * attacker could send empty records at a faster rate than we can process and - * cause ssl3_get_record to loop forever. - */ -#define MAX_EMPTY_RECORDS 32 - -/*- - * Call this to get a new input record. - * It will return <= 0 if more data is needed, normally due to an error - * or non-blocking IO. - * When it finishes, one packet has been decoded and can be found in - * ssl->s3->rrec.type - is the type of record - * ssl->s3->rrec.data, - data - * ssl->s3->rrec.length, - number of bytes - */ -/* used only by ssl3_read_bytes */ -static int ssl3_get_record(SSL *s) -{ - int ssl_major, ssl_minor, al; - int enc_err, n, i, ret = -1; - SSL3_RECORD *rr; - SSL_SESSION *sess; - unsigned char *p; - unsigned char md[EVP_MAX_MD_SIZE]; - short version; - unsigned mac_size, orig_len; - size_t extra; - unsigned empty_record_count = 0; - - rr = &(s->s3->rrec); - sess = s->session; - - if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) - extra = SSL3_RT_MAX_EXTRA; - else - extra = 0; - if (extra && !s->s3->init_extra) { - /* - * An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER set after - * ssl3_setup_buffers() was done - */ - SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR); - return -1; - } - - again: - /* check if we have the header */ - if ((s->rstate != SSL_ST_READ_BODY) || - (s->packet_length < SSL3_RT_HEADER_LENGTH)) { - n = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); - if (n <= 0) - return (n); /* error or non-blocking */ - s->rstate = SSL_ST_READ_BODY; - - p = s->packet; - if (s->msg_callback) - s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, - s->msg_callback_arg); - - /* Pull apart the header into the SSL3_RECORD */ - rr->type = *(p++); - ssl_major = *(p++); - ssl_minor = *(p++); - version = (ssl_major << 8) | ssl_minor; - n2s(p, rr->length); -#if 0 - fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length); -#endif - - /* Lets check version */ - if (!s->first_packet) { - if (version != s->version) { - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); - if ((s->version & 0xFF00) == (version & 0xFF00) - && !s->enc_write_ctx && !s->write_hash) { - if (rr->type == SSL3_RT_ALERT) { - /* - * The record is using an incorrect version number, but - * what we've got appears to be an alert. We haven't - * read the body yet to check whether its a fatal or - * not - but chances are it is. We probably shouldn't - * send a fatal alert back. We'll just end. - */ - goto err; - } - /* - * Send back error using their minor version number :-) - */ - s->version = (unsigned short)version; - } - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } - } - - if ((version >> 8) != SSL3_VERSION_MAJOR) { - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); - goto err; - } - - if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG); - goto f_err; - } - - /* now s->rstate == SSL_ST_READ_BODY */ - } - - /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ - - if (rr->length > s->packet_length - SSL3_RT_HEADER_LENGTH) { - /* now s->packet_length == SSL3_RT_HEADER_LENGTH */ - i = rr->length; - n = ssl3_read_n(s, i, i, 1); - if (n <= 0) - return (n); /* error or non-blocking io */ - /* - * now n == rr->length, and s->packet_length == SSL3_RT_HEADER_LENGTH - * + rr->length - */ - } - - s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ - - /* - * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, - * and we have that many bytes in s->packet - */ - rr->input = &(s->packet[SSL3_RT_HEADER_LENGTH]); - - /* - * ok, we can now read from 's->packet' data into 'rr' rr->input points - * at rr->length bytes, which need to be copied into rr->data by either - * the decryption or by the decompression When the data is 'copied' into - * the rr->data buffer, rr->input will be pointed at the new buffer - */ - - /* - * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length - * bytes of encrypted compressed stuff. - */ - - /* check is not needed I believe */ - if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH + extra) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); - goto f_err; - } - - /* decrypt in place in 'rr->input' */ - rr->data = rr->input; - - enc_err = s->method->ssl3_enc->enc(s, 0); - /*- - * enc_err is: - * 0: (in non-constant time) if the record is publically invalid. - * 1: if the padding is valid - * -1: if the padding is invalid - */ - if (enc_err == 0) { - al = SSL_AD_DECRYPTION_FAILED; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); - goto f_err; - } -#ifdef TLS_DEBUG - printf("dec %d\n", rr->length); - { - unsigned int z; - for (z = 0; z < rr->length; z++) - printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n'); - } - printf("\n"); -#endif - - /* r->length is now the compressed data plus mac */ - if ((sess != NULL) && - (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) { - /* s->read_hash != NULL => mac_size != -1 */ - unsigned char *mac = NULL; - unsigned char mac_tmp[EVP_MAX_MD_SIZE]; - mac_size = EVP_MD_CTX_size(s->read_hash); - OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); - - /* - * kludge: *_cbc_remove_padding passes padding length in rr->type - */ - orig_len = rr->length + ((unsigned int)rr->type >> 8); - - /* - * orig_len is the length of the record before any padding was - * removed. This is public information, as is the MAC in use, - * therefore we can safely process the record in a different amount - * of time if it's too short to possibly contain a MAC. - */ - if (orig_len < mac_size || - /* CBC records must have a padding length byte too. */ - (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && - orig_len < mac_size + 1)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { - /* - * We update the length so that the TLS header bytes can be - * constructed correctly but we need to extract the MAC in - * constant time from within the record, without leaking the - * contents of the padding bytes. - */ - mac = mac_tmp; - ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); - rr->length -= mac_size; - } else { - /* - * In this case there's no padding, so |orig_len| equals - * |rec->length| and we checked that there's enough bytes for - * |mac_size| above. - */ - rr->length -= mac_size; - mac = &rr->data[rr->length]; - } - - i = s->method->ssl3_enc->mac(s, md, 0 /* not send */ ); - if (i < 0 || mac == NULL - || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) - enc_err = -1; - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + extra + mac_size) - enc_err = -1; - } - - if (enc_err < 0) { - /* - * A separate 'decryption_failed' alert was introduced with TLS 1.0, - * SSL 3.0 only has 'bad_record_mac'. But unless a decryption - * failure is directly visible from the ciphertext anyway, we should - * not reveal which kind of error occured -- this might become - * visible to an attacker (e.g. via a logfile) - */ - al = SSL_AD_BAD_RECORD_MAC; - SSLerr(SSL_F_SSL3_GET_RECORD, - SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); - goto f_err; - } - - /* r->length is now just compressed */ - if (s->expand != NULL) { - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + extra) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_COMPRESSED_LENGTH_TOO_LONG); - goto f_err; - } - if (!ssl3_do_uncompress(s)) { - al = SSL_AD_DECOMPRESSION_FAILURE; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BAD_DECOMPRESSION); - goto f_err; - } - } - - if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH + extra) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_DATA_LENGTH_TOO_LONG); - goto f_err; - } - - rr->off = 0; - /*- - * So at this point the following is true - * ssl->s3->rrec.type is the type of record - * ssl->s3->rrec.length == number of bytes in record - * ssl->s3->rrec.off == offset to first valid byte - * ssl->s3->rrec.data == where to take bytes from, increment - * after use :-). - */ - - /* we have pulled in a full packet so zero things */ - s->packet_length = 0; - - /* just read a 0 length packet */ - if (rr->length == 0) { - empty_record_count++; - if (empty_record_count > MAX_EMPTY_RECORDS) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_RECORD_TOO_SMALL); - goto f_err; - } - goto again; - } -#if 0 - fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, - rr->length); -#endif - - return (1); - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - return (ret); -} - -int ssl3_do_uncompress(SSL *ssl) -{ -#ifndef OPENSSL_NO_COMP - int i; - SSL3_RECORD *rr; - - rr = &(ssl->s3->rrec); - i = COMP_expand_block(ssl->expand, rr->comp, - SSL3_RT_MAX_PLAIN_LENGTH, rr->data, - (int)rr->length); - if (i < 0) - return (0); - else - rr->length = i; - rr->data = rr->comp; -#endif - return (1); -} - -int ssl3_do_compress(SSL *ssl) -{ -#ifndef OPENSSL_NO_COMP - int i; - SSL3_RECORD *wr; - - wr = &(ssl->s3->wrec); - i = COMP_compress_block(ssl->compress, wr->data, - SSL3_RT_MAX_COMPRESSED_LENGTH, - wr->input, (int)wr->length); - if (i < 0) - return (0); - else - wr->length = i; - - wr->input = wr->data; -#endif - return (1); -} - -/* - * Call this to write data in records of type 'type' It will return <= 0 if - * not all data has been sent or non-blocking IO. - */ -int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) -{ - const unsigned char *buf = buf_; - int tot; - unsigned int n, nw; -#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK - unsigned int max_send_fragment; -#endif - SSL3_BUFFER *wb = &(s->s3->wbuf); - int i; - - s->rwstate = SSL_NOTHING; - OPENSSL_assert(s->s3->wnum <= INT_MAX); - tot = s->s3->wnum; - s->s3->wnum = 0; - - if (SSL_in_init(s) && !s->in_handshake) { - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); - return -1; - } - } - - /* - * ensure that if we end up with a smaller value of data to write out - * than the the original len from a write which didn't complete for - * non-blocking I/O and also somehow ended up avoiding the check for - * this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be - * possible to end up with (len-tot) as a large number that will then - * promptly send beyond the end of the users buffer ... so we trap and - * report the error in a way the user will notice - */ - if ((len < tot) || ((wb->left != 0) && (len < (tot + s->s3->wpend_tot)))) { - SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH); - return (-1); - } - - /* - * first check if there is a SSL3_BUFFER still being written out. This - * will happen with non blocking IO - */ - if (wb->left != 0) { - i = ssl3_write_pending(s, type, &buf[tot], s->s3->wpend_tot); - if (i <= 0) { - /* XXX should we ssl3_release_write_buffer if i<0? */ - s->s3->wnum = tot; - return i; - } - tot += i; /* this might be last fragment */ - } -#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK - /* - * Depending on platform multi-block can deliver several *times* - * better performance. Downside is that it has to allocate - * jumbo buffer to accomodate up to 8 records, but the - * compromise is considered worthy. - */ - if (type == SSL3_RT_APPLICATION_DATA && - len >= 4 * (int)(max_send_fragment = s->max_send_fragment) && - s->compress == NULL && s->msg_callback == NULL && - SSL_USE_EXPLICIT_IV(s) && - s->enc_write_ctx != NULL && - EVP_CIPHER_flags(s->enc_write_ctx->cipher) & - EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) { - unsigned char aad[13]; - EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param; - int packlen; - - /* minimize address aliasing conflicts */ - if ((max_send_fragment & 0xfff) == 0) - max_send_fragment -= 512; - - if (tot == 0 || wb->buf == NULL) { /* allocate jumbo buffer */ - ssl3_release_write_buffer(s); - - packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, - EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE, - max_send_fragment, NULL); - - if (len >= 8 * (int)max_send_fragment) - packlen *= 8; - else - packlen *= 4; - - wb->buf = OPENSSL_malloc(packlen); - if (!wb->buf) { - SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_MALLOC_FAILURE); - return -1; - } - wb->len = packlen; - } else if (tot == len) { /* done? */ - OPENSSL_free(wb->buf); /* free jumbo buffer */ - wb->buf = NULL; - return tot; - } - - n = (len - tot); - for (;;) { - if (n < 4 * max_send_fragment) { - OPENSSL_free(wb->buf); /* free jumbo buffer */ - wb->buf = NULL; - break; - } - - if (s->s3->alert_dispatch) { - i = s->method->ssl_dispatch_alert(s); - if (i <= 0) { - s->s3->wnum = tot; - return i; - } - } - - if (n >= 8 * max_send_fragment) - nw = max_send_fragment * (mb_param.interleave = 8); - else - nw = max_send_fragment * (mb_param.interleave = 4); - - memcpy(aad, s->s3->write_sequence, 8); - aad[8] = type; - aad[9] = (unsigned char)(s->version >> 8); - aad[10] = (unsigned char)(s->version); - aad[11] = 0; - aad[12] = 0; - mb_param.out = NULL; - mb_param.inp = aad; - mb_param.len = nw; - - packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, - EVP_CTRL_TLS1_1_MULTIBLOCK_AAD, - sizeof(mb_param), &mb_param); - - if (packlen <= 0 || packlen > (int)wb->len) { /* never happens */ - OPENSSL_free(wb->buf); /* free jumbo buffer */ - wb->buf = NULL; - break; - } - - mb_param.out = wb->buf; - mb_param.inp = &buf[tot]; - mb_param.len = nw; - - if (EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, - EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT, - sizeof(mb_param), &mb_param) <= 0) - return -1; - - s->s3->write_sequence[7] += mb_param.interleave; - if (s->s3->write_sequence[7] < mb_param.interleave) { - int j = 6; - while (j >= 0 && (++s->s3->write_sequence[j--]) == 0) ; - } - - wb->offset = 0; - wb->left = packlen; - - s->s3->wpend_tot = nw; - s->s3->wpend_buf = &buf[tot]; - s->s3->wpend_type = type; - s->s3->wpend_ret = nw; - - i = ssl3_write_pending(s, type, &buf[tot], nw); - if (i <= 0) { - if (i < 0 && (!s->wbio || !BIO_should_retry(s->wbio))) { - OPENSSL_free(wb->buf); - wb->buf = NULL; - } - s->s3->wnum = tot; - return i; - } - if (i == (int)n) { - OPENSSL_free(wb->buf); /* free jumbo buffer */ - wb->buf = NULL; - return tot + i; - } - n -= i; - tot += i; - } - } else -#endif - if (tot == len) { /* done? */ - if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s)) - ssl3_release_write_buffer(s); - - return tot; - } - - n = (len - tot); - for (;;) { - if (n > s->max_send_fragment) - nw = s->max_send_fragment; - else - nw = n; - - i = do_ssl3_write(s, type, &(buf[tot]), nw, 0); - if (i <= 0) { - /* XXX should we ssl3_release_write_buffer if i<0? */ - s->s3->wnum = tot; - return i; - } - - if ((i == (int)n) || - (type == SSL3_RT_APPLICATION_DATA && - (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) { - /* - * next chunk of data should get another prepended empty fragment - * in ciphersuites with known-IV weakness: - */ - s->s3->empty_fragment_done = 0; - - if ((i == (int)n) && s->mode & SSL_MODE_RELEASE_BUFFERS && - !SSL_IS_DTLS(s)) - ssl3_release_write_buffer(s); - - return tot + i; - } - - n -= i; - tot += i; - } -} - -static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, - unsigned int len, int create_empty_fragment) -{ - unsigned char *p, *plen; - int i, mac_size, clear = 0; - int prefix_len = 0; - int eivlen; - long align = 0; - SSL3_RECORD *wr; - SSL3_BUFFER *wb = &(s->s3->wbuf); - SSL_SESSION *sess; - - /* - * first check if there is a SSL3_BUFFER still being written out. This - * will happen with non blocking IO - */ - if (wb->left != 0) - return (ssl3_write_pending(s, type, buf, len)); - - /* If we have an alert to send, lets send it */ - if (s->s3->alert_dispatch) { - i = s->method->ssl_dispatch_alert(s); - if (i <= 0) - return (i); - /* if it went, fall through and send more stuff */ - } - - if (wb->buf == NULL) - if (!ssl3_setup_write_buffer(s)) - return -1; - - if (len == 0 && !create_empty_fragment) - return 0; - - wr = &(s->s3->wrec); - sess = s->session; - - if ((sess == NULL) || - (s->enc_write_ctx == NULL) || - (EVP_MD_CTX_md(s->write_hash) == NULL)) { -#if 1 - clear = s->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */ -#else - clear = 1; -#endif - mac_size = 0; - } else { - mac_size = EVP_MD_CTX_size(s->write_hash); - if (mac_size < 0) - goto err; - } - - /* - * 'create_empty_fragment' is true only when this function calls itself - */ - if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) { - /* - * countermeasure against known-IV weakness in CBC ciphersuites (see - * http://www.openssl.org/~bodo/tls-cbc.txt) - */ - - if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) { - /* - * recursive function call with 'create_empty_fragment' set; this - * prepares and buffers the data for an empty fragment (these - * 'prefix_len' bytes are sent out later together with the actual - * payload) - */ - prefix_len = do_ssl3_write(s, type, buf, 0, 1); - if (prefix_len <= 0) - goto err; - - if (prefix_len > - (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) - { - /* insufficient space */ - SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - s->s3->empty_fragment_done = 1; - } - - if (create_empty_fragment) { -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - /* - * extra fragment would be couple of cipher blocks, which would be - * multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real - * payload, then we can just pretent we simply have two headers. - */ - align = (long)wb->buf + 2 * SSL3_RT_HEADER_LENGTH; - align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); -#endif - p = wb->buf + align; - wb->offset = align; - } else if (prefix_len) { - p = wb->buf + wb->offset + prefix_len; - } else { -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - align = (long)wb->buf + SSL3_RT_HEADER_LENGTH; - align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); -#endif - p = wb->buf + align; - wb->offset = align; - } - - /* write the header */ - - *(p++) = type & 0xff; - wr->type = type; - - *(p++) = (s->version >> 8); - /* - * Some servers hang if iniatial client hello is larger than 256 bytes - * and record version number > TLS 1.0 - */ - if (s->state == SSL3_ST_CW_CLNT_HELLO_B - && !s->renegotiate && TLS1_get_version(s) > TLS1_VERSION) - *(p++) = 0x1; - else - *(p++) = s->version & 0xff; - - /* field where we are to write out packet length */ - plen = p; - p += 2; - /* Explicit IV length, block ciphers appropriate version flag */ - if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) { - int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); - if (mode == EVP_CIPH_CBC_MODE) { - eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); - if (eivlen <= 1) - eivlen = 0; - } - /* Need explicit part of IV for GCM mode */ - else if (mode == EVP_CIPH_GCM_MODE) - eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; - else - eivlen = 0; - } else - eivlen = 0; - - /* lets setup the record stuff. */ - wr->data = p + eivlen; - wr->length = (int)len; - wr->input = (unsigned char *)buf; - - /* - * we now 'read' from wr->input, wr->length bytes into wr->data - */ - - /* first we compress */ - if (s->compress != NULL) { - if (!ssl3_do_compress(s)) { - SSLerr(SSL_F_DO_SSL3_WRITE, SSL_R_COMPRESSION_FAILURE); - goto err; - } - } else { - memcpy(wr->data, wr->input, wr->length); - wr->input = wr->data; - } - - /* - * we should still have the output to wr->data and the input from - * wr->input. Length should be wr->length. wr->data still points in the - * wb->buf - */ - - if (mac_size != 0) { - if (s->method->ssl3_enc->mac(s, &(p[wr->length + eivlen]), 1) < 0) - goto err; - wr->length += mac_size; - } - - wr->input = p; - wr->data = p; - - if (eivlen) { - /* - * if (RAND_pseudo_bytes(p, eivlen) <= 0) goto err; - */ - wr->length += eivlen; - } - - if (s->method->ssl3_enc->enc(s, 1) < 1) - goto err; - - /* record length after mac and block padding */ - s2n(wr->length, plen); - - if (s->msg_callback) - s->msg_callback(1, 0, SSL3_RT_HEADER, plen - 5, 5, s, - s->msg_callback_arg); - - /* - * we should now have wr->data pointing to the encrypted data, which is - * wr->length long - */ - wr->type = type; /* not needed but helps for debugging */ - wr->length += SSL3_RT_HEADER_LENGTH; - - if (create_empty_fragment) { - /* - * we are in a recursive call; just return the length, don't write - * out anything here - */ - return wr->length; - } - - /* now let's set up wb */ - wb->left = prefix_len + wr->length; - - /* - * memorize arguments so that ssl3_write_pending can detect bad write - * retries later - */ - s->s3->wpend_tot = len; - s->s3->wpend_buf = buf; - s->s3->wpend_type = type; - s->s3->wpend_ret = len; - - /* we now just need to write the buffer */ - return ssl3_write_pending(s, type, buf, len); - err: - return -1; -} - -/* if s->s3->wbuf.left != 0, we need to call this - * - * Return values are as per SSL_write(), i.e. - */ -int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, - unsigned int len) -{ - int i; - SSL3_BUFFER *wb = &(s->s3->wbuf); - -/* XXXX */ - if ((s->s3->wpend_tot > (int)len) - || ((s->s3->wpend_buf != buf) && - !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) - || (s->s3->wpend_type != type)) { - SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY); - return (-1); - } - - for (;;) { - clear_sys_error(); - if (s->wbio != NULL) { - s->rwstate = SSL_WRITING; - i = BIO_write(s->wbio, - (char *)&(wb->buf[wb->offset]), - (unsigned int)wb->left); - } else { - SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BIO_NOT_SET); - i = -1; - } - if (i == wb->left) { - wb->left = 0; - wb->offset += i; - s->rwstate = SSL_NOTHING; - return (s->s3->wpend_ret); - } else if (i <= 0) { - if (SSL_IS_DTLS(s)) { - /* - * For DTLS, just drop it. That's kind of the whole point in - * using a datagram service - */ - wb->left = 0; - } - return i; - } - wb->offset += i; - wb->left -= i; - } -} - -/*- - * Return up to 'len' payload bytes received in 'type' records. - * 'type' is one of the following: - * - * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) - * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) - * - 0 (during a shutdown, no data has to be returned) - * - * If we don't have stored data to work from, read a SSL/TLS record first - * (possibly multiple records if we still don't have anything to return). - * - * This function must handle any surprises the peer may have for us, such as - * Alert records (e.g. close_notify), ChangeCipherSpec records (not really - * a surprise, but handled as if it were), or renegotiation requests. - * Also if record payloads contain fragments too small to process, we store - * them until there is enough for the respective protocol (the record protocol - * may use arbitrary fragmentation and even interleaving): - * Change cipher spec protocol - * just 1 byte needed, no need for keeping anything stored - * Alert protocol - * 2 bytes needed (AlertLevel, AlertDescription) - * Handshake protocol - * 4 bytes needed (HandshakeType, uint24 length) -- we just have - * to detect unexpected Client Hello and Hello Request messages - * here, anything else is handled by higher layers - * Application data protocol - * none of our business - */ -int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) -{ - int al, i, j, ret; - unsigned int n; - SSL3_RECORD *rr; - void (*cb) (const SSL *ssl, int type2, int val) = NULL; - - if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ - if (!ssl3_setup_read_buffer(s)) - return (-1); - - if ((type && (type != SSL3_RT_APPLICATION_DATA) - && (type != SSL3_RT_HANDSHAKE)) || (peek - && (type != - SSL3_RT_APPLICATION_DATA))) { - SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); - return -1; - } - - if ((type == SSL3_RT_HANDSHAKE) && (s->s3->handshake_fragment_len > 0)) - /* (partially) satisfy request from storage */ - { - unsigned char *src = s->s3->handshake_fragment; - unsigned char *dst = buf; - unsigned int k; - - /* peek == 0 */ - n = 0; - while ((len > 0) && (s->s3->handshake_fragment_len > 0)) { - *dst++ = *src++; - len--; - s->s3->handshake_fragment_len--; - n++; - } - /* move any remaining fragment bytes: */ - for (k = 0; k < s->s3->handshake_fragment_len; k++) - s->s3->handshake_fragment[k] = *src++; - return n; - } - - /* - * Now s->s3->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. - */ - - if (!s->in_handshake && SSL_in_init(s)) { - /* type == SSL3_RT_APPLICATION_DATA */ - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - } - start: - s->rwstate = SSL_NOTHING; - - /*- - * s->s3->rrec.type - is the type of record - * s->s3->rrec.data, - data - * s->s3->rrec.off, - offset into 'data' for next read - * s->s3->rrec.length, - number of bytes. - */ - rr = &(s->s3->rrec); - - /* get new packet if necessary */ - if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) { - ret = ssl3_get_record(s); - if (ret <= 0) - return (ret); - } - - /* - * Reset the count of consecutive warning alerts if we've got a non-empty - * record that isn't an alert. - */ - if (rr->type != SSL3_RT_ALERT && rr->length != 0) - s->cert->alert_count = 0; - - /* we now have a packet which can be read and processed */ - - if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, - * reset by ssl3_get_finished */ - && (rr->type != SSL3_RT_HANDSHAKE)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); - goto f_err; - } - - /* - * If the other end has shut down, throw anything we read away (even in - * 'peek' mode) - */ - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - rr->length = 0; - s->rwstate = SSL_NOTHING; - return (0); - } - - if (type == rr->type) { /* SSL3_RT_APPLICATION_DATA or - * SSL3_RT_HANDSHAKE */ - /* - * make sure that we are not getting application data when we are - * doing a handshake for the first time - */ - if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && - (s->enc_read_ctx == NULL)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE); - goto f_err; - } - - if (len <= 0) - return (len); - - if ((unsigned int)len > rr->length) - n = rr->length; - else - n = (unsigned int)len; - - memcpy(buf, &(rr->data[rr->off]), n); - if (!peek) { - rr->length -= n; - rr->off += n; - if (rr->length == 0) { - s->rstate = SSL_ST_READ_HEADER; - rr->off = 0; - if (s->mode & SSL_MODE_RELEASE_BUFFERS - && s->s3->rbuf.left == 0) - ssl3_release_read_buffer(s); - } - } - return (n); - } - - /* - * If we get here, then type != rr->type; if we have a handshake message, - * then it was unexpected (Hello Request or Client Hello). - */ - - /* - * In case of record types for which we have 'fragment' storage, fill - * that so that we can process the data at a fixed place. - */ - { - unsigned int dest_maxlen = 0; - unsigned char *dest = NULL; - unsigned int *dest_len = NULL; - - if (rr->type == SSL3_RT_HANDSHAKE) { - dest_maxlen = sizeof s->s3->handshake_fragment; - dest = s->s3->handshake_fragment; - dest_len = &s->s3->handshake_fragment_len; - } else if (rr->type == SSL3_RT_ALERT) { - dest_maxlen = sizeof s->s3->alert_fragment; - dest = s->s3->alert_fragment; - dest_len = &s->s3->alert_fragment_len; - } -#ifndef OPENSSL_NO_HEARTBEATS - else if (rr->type == TLS1_RT_HEARTBEAT) { - tls1_process_heartbeat(s); - - /* Exit and notify application to read again */ - rr->length = 0; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - return (-1); - } -#endif - - if (dest_maxlen > 0) { - n = dest_maxlen - *dest_len; /* available space in 'dest' */ - if (rr->length < n) - n = rr->length; /* available bytes */ - - /* now move 'n' bytes: */ - while (n-- > 0) { - dest[(*dest_len)++] = rr->data[rr->off++]; - rr->length--; - } - - if (*dest_len < dest_maxlen) - goto start; /* fragment was too small */ - } - } - - /*- - * s->s3->handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE; - * s->s3->alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT. - * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) - */ - - /* If we are a client, check for an incoming 'Hello Request': */ - if ((!s->server) && - (s->s3->handshake_fragment_len >= 4) && - (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && - (s->session != NULL) && (s->session->cipher != NULL)) { - s->s3->handshake_fragment_len = 0; - - if ((s->s3->handshake_fragment[1] != 0) || - (s->s3->handshake_fragment[2] != 0) || - (s->s3->handshake_fragment[3] != 0)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_HELLO_REQUEST); - goto f_err; - } - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - s->s3->handshake_fragment, 4, s, - s->msg_callback_arg); - - if (SSL_is_init_finished(s) && - !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && - !s->s3->renegotiate) { - ssl3_renegotiate(s); - if (ssl3_renegotiate_check(s)) { - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_SSL3_READ_BYTES, - SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - - if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ - BIO *bio; - /* - * In the case where we try to read application data, - * but we trigger an SSL handshake, we return -1 with - * the retry option set. Otherwise renegotiation may - * cause nasty problems in the blocking world - */ - s->rwstate = SSL_READING; - bio = SSL_get_rbio(s); - BIO_clear_retry_flags(bio); - BIO_set_retry_read(bio); - return (-1); - } - } - } - } - /* - * we either finished a handshake or ignored the request, now try - * again to obtain the (application) data we were asked for - */ - goto start; - } - /* - * If we are a server and get a client hello when renegotiation isn't - * allowed send back a no renegotiation alert and carry on. WARNING: - * experimental code, needs reviewing (steve) - */ - if (s->server && - SSL_is_init_finished(s) && - !s->s3->send_connection_binding && - (s->version > SSL3_VERSION) && - (s->s3->handshake_fragment_len >= 4) && - (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) && - (s->session != NULL) && (s->session->cipher != NULL) && - !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { - /* - * s->s3->handshake_fragment_len = 0; - */ - rr->length = 0; - ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); - goto start; - } - if (s->s3->alert_fragment_len >= 2) { - int alert_level = s->s3->alert_fragment[0]; - int alert_descr = s->s3->alert_fragment[1]; - - s->s3->alert_fragment_len = 0; - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_ALERT, - s->s3->alert_fragment, 2, s, s->msg_callback_arg); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - if (cb != NULL) { - j = (alert_level << 8) | alert_descr; - cb(s, SSL_CB_READ_ALERT, j); - } - - if (alert_level == SSL3_AL_WARNING) { - s->s3->warn_alert = alert_descr; - - s->cert->alert_count++; - if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS); - goto f_err; - } - - if (alert_descr == SSL_AD_CLOSE_NOTIFY) { - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - return (0); - } - /* - * This is a warning but we receive it if we requested - * renegotiation and the peer denied it. Terminate with a fatal - * alert because if application tried to renegotiatie it - * presumably had a good reason and expects it to succeed. In - * future we might have a renegotiation where we don't care if - * the peer refused it where we carry on. - */ - else if (alert_descr == SSL_AD_NO_RENEGOTIATION) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_NO_RENEGOTIATION); - goto f_err; - } -#ifdef SSL_AD_MISSING_SRP_USERNAME - else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME) - return (0); -#endif - } else if (alert_level == SSL3_AL_FATAL) { - char tmp[16]; - - s->rwstate = SSL_NOTHING; - s->s3->fatal_alert = alert_descr; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr); - BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); - ERR_add_error_data(2, "SSL alert number ", tmp); - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL_CTX_remove_session(s->session_ctx, s->session); - return (0); - } else { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE); - goto f_err; - } - - goto start; - } - - if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a - * shutdown */ - s->rwstate = SSL_NOTHING; - rr->length = 0; - return (0); - } - - if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { - /* - * 'Change Cipher Spec' is just a single byte, so we know exactly - * what the record payload has to look like - */ - if ((rr->length != 1) || (rr->off != 0) || - (rr->data[0] != SSL3_MT_CCS)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto f_err; - } - - /* Check we have a cipher to change to */ - if (s->s3->tmp.new_cipher == NULL) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY); - goto f_err; - } - - if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY); - goto f_err; - } - - s->s3->flags &= ~SSL3_FLAGS_CCS_OK; - - rr->length = 0; - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, - rr->data, 1, s, s->msg_callback_arg); - - s->s3->change_cipher_spec = 1; - if (!ssl3_do_change_cipher_spec(s)) - goto err; - else - goto start; - } - - /* - * Unexpected handshake message (Client Hello, or protocol violation) - */ - if ((s->s3->handshake_fragment_len >= 4) && !s->in_handshake) { - if (((s->state & SSL_ST_MASK) == SSL_ST_OK) && - !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { -#if 0 /* worked only because C operator preferences - * are not as expected (and because this is - * not really needed for clients except for - * detecting protocol violations): */ - s->state = SSL_ST_BEFORE | (s->server) - ? SSL_ST_ACCEPT : SSL_ST_CONNECT; -#else - s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; -#endif - s->renegotiate = 1; - s->new_session = 1; - } - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - - if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ - BIO *bio; - /* - * In the case where we try to read application data, but we - * trigger an SSL handshake, we return -1 with the retry - * option set. Otherwise renegotiation may cause nasty - * problems in the blocking world - */ - s->rwstate = SSL_READING; - bio = SSL_get_rbio(s); - BIO_clear_retry_flags(bio); - BIO_set_retry_read(bio); - return (-1); - } - } - goto start; - } - - switch (rr->type) { - default: - /* - * TLS 1.0 and 1.1 say you SHOULD ignore unrecognised record types, but - * TLS 1.2 says you MUST send an unexpected message alert. We use the - * TLS 1.2 behaviour for all protocol versions to prevent issues where - * no progress is being made and the peer continually sends unrecognised - * record types, using up resources processing them. - */ - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD); - goto f_err; - case SSL3_RT_CHANGE_CIPHER_SPEC: - case SSL3_RT_ALERT: - case SSL3_RT_HANDSHAKE: - /* - * we already handled all of these, with the possible exception of - * SSL3_RT_HANDSHAKE when s->in_handshake is set, but that should not - * happen when type != rr->type - */ - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); - goto f_err; - case SSL3_RT_APPLICATION_DATA: - /* - * At this point, we were expecting handshake data, but have - * application data. If the library was running inside ssl3_read() - * (i.e. in_read_app_data is set) and it makes sense to read - * application data at this point (session renegotiation not yet - * started), we will indulge it. - */ - if (s->s3->in_read_app_data && - (s->s3->total_renegotiations != 0) && - (((s->state & SSL_ST_CONNECT) && - (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && - (s->state <= SSL3_ST_CR_SRVR_HELLO_A) - ) || ((s->state & SSL_ST_ACCEPT) && - (s->state <= SSL3_ST_SW_HELLO_REQ_A) && - (s->state >= SSL3_ST_SR_CLNT_HELLO_A) - ) - )) { - s->s3->in_read_app_data = 2; - return (-1); - } else { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD); - goto f_err; - } - } - /* not reached */ - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - return (-1); -} - -int ssl3_do_change_cipher_spec(SSL *s) -{ - int i; - const char *sender; - int slen; - - if (s->state & SSL_ST_ACCEPT) - i = SSL3_CHANGE_CIPHER_SERVER_READ; - else - i = SSL3_CHANGE_CIPHER_CLIENT_READ; - - if (s->s3->tmp.key_block == NULL) { - if (s->session == NULL || s->session->master_key_length == 0) { - /* might happen if dtls1_read_bytes() calls this */ - SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, - SSL_R_CCS_RECEIVED_EARLY); - return (0); - } - - s->session->cipher = s->s3->tmp.new_cipher; - if (!s->method->ssl3_enc->setup_key_block(s)) - return (0); - } - - if (!s->method->ssl3_enc->change_cipher_state(s, i)) - return (0); - - /* - * we have to record the message digest at this point so we can get it - * before we read the finished message - */ - if (s->state & SSL_ST_CONNECT) { - sender = s->method->ssl3_enc->server_finished_label; - slen = s->method->ssl3_enc->server_finished_label_len; - } else { - sender = s->method->ssl3_enc->client_finished_label; - slen = s->method->ssl3_enc->client_finished_label_len; - } - - i = s->method->ssl3_enc->final_finish_mac(s, - sender, slen, - s->s3->tmp.peer_finish_md); - if (i == 0) { - SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); - return 0; - } - s->s3->tmp.peer_finish_md_len = i; - - return (1); -} - -int ssl3_send_alert(SSL *s, int level, int desc) -{ - /* Map tls/ssl alert value to correct one */ - desc = s->method->ssl3_enc->alert_value(desc); - if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION) - desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have - * protocol_version alerts */ - if (desc < 0) - return -1; - /* If a fatal one, remove from cache */ - if ((level == 2) && (s->session != NULL)) - SSL_CTX_remove_session(s->session_ctx, s->session); - - s->s3->alert_dispatch = 1; - s->s3->send_alert[0] = level; - s->s3->send_alert[1] = desc; - if (s->s3->wbuf.left == 0) /* data still being written out? */ - return s->method->ssl_dispatch_alert(s); - /* - * else data is still being written out, we will get written some time in - * the future - */ - return -1; -} - -int ssl3_dispatch_alert(SSL *s) -{ - int i, j; - void (*cb) (const SSL *ssl, int type, int val) = NULL; - - s->s3->alert_dispatch = 0; - i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0); - if (i <= 0) { - s->s3->alert_dispatch = 1; - } else { - /* - * Alert sent to BIO. If it is important, flush it now. If the - * message does not get sent due to non-blocking IO, we will not - * worry too much. - */ - if (s->s3->send_alert[0] == SSL3_AL_FATAL) - (void)BIO_flush(s->wbio); - - if (s->msg_callback) - s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, - 2, s, s->msg_callback_arg); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - if (cb != NULL) { - j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; - cb(s, SSL_CB_WRITE_ALERT, j); - } - } - return (i); -} diff --git a/thirdparty/openssl/ssl/s3_srvr.c b/thirdparty/openssl/ssl/s3_srvr.c deleted file mode 100644 index ba17f1b562..0000000000 --- a/thirdparty/openssl/ssl/s3_srvr.c +++ /dev/null @@ -1,3677 +0,0 @@ -/* ssl/s3_srvr.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 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 - * openssl-core@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). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the OpenSSL open source - * license provided above. - * - * ECC cipher suite support in OpenSSL originally written by - * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#define REUSE_CIPHER_BUG -#define NETSCAPE_HANG_BUG - -#include <stdio.h> -#include "ssl_locl.h" -#include "kssl_lcl.h" -#include "../crypto/constant_time_locl.h" -#include <openssl/buffer.h> -#include <openssl/rand.h> -#include <openssl/objects.h> -#include <openssl/evp.h> -#include <openssl/hmac.h> -#include <openssl/x509.h> -#ifndef OPENSSL_NO_DH -# include <openssl/dh.h> -#endif -#include <openssl/bn.h> -#ifndef OPENSSL_NO_KRB5 -# include <openssl/krb5_asn.h> -#endif -#include <openssl/md5.h> - -#ifndef OPENSSL_NO_SSL3_METHOD -static const SSL_METHOD *ssl3_get_server_method(int ver); - -static const SSL_METHOD *ssl3_get_server_method(int ver) -{ - if (ver == SSL3_VERSION) - return (SSLv3_server_method()); - else - return (NULL); -} - -IMPLEMENT_ssl3_meth_func(SSLv3_server_method, - ssl3_accept, - ssl_undefined_function, ssl3_get_server_method) -#endif -#ifndef OPENSSL_NO_SRP -static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) -{ - int ret = SSL_ERROR_NONE; - - *al = SSL_AD_UNRECOGNIZED_NAME; - - if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) && - (s->srp_ctx.TLS_ext_srp_username_callback != NULL)) { - if (s->srp_ctx.login == NULL) { - /* - * RFC 5054 says SHOULD reject, we do so if There is no srp - * login name - */ - ret = SSL3_AL_FATAL; - *al = SSL_AD_UNKNOWN_PSK_IDENTITY; - } else { - ret = SSL_srp_server_param_with_username(s, al); - } - } - return ret; -} -#endif - -int ssl3_accept(SSL *s) -{ - BUF_MEM *buf; - unsigned long alg_k, Time = (unsigned long)time(NULL); - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int ret = -1; - int new_state, state, skip = 0; - - RAND_add(&Time, sizeof(Time), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - /* init things to blank */ - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - if (s->cert == NULL) { - SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_NO_CERTIFICATE_SET); - return (-1); - } -#ifndef OPENSSL_NO_HEARTBEATS - /* - * If we're awaiting a HeartbeatResponse, pretend we already got and - * don't await it anymore, because Heartbeats don't make sense during - * handshakes anyway. - */ - if (s->tlsext_hb_pending) { - s->tlsext_hb_pending = 0; - s->tlsext_hb_seq++; - } -#endif - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_RENEGOTIATE: - s->renegotiate = 1; - /* s->state=SSL_ST_ACCEPT; */ - - case SSL_ST_BEFORE: - case SSL_ST_ACCEPT: - case SSL_ST_BEFORE | SSL_ST_ACCEPT: - case SSL_ST_OK | SSL_ST_ACCEPT: - - s->server = 1; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - if ((s->version >> 8) != 3) { - SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return -1; - } - s->type = SSL_ST_ACCEPT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - BUF_MEM_free(buf); - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - s->init_buf = buf; - } - - if (!ssl3_setup_buffers(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - s->init_num = 0; - s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY; - s->s3->flags &= ~SSL3_FLAGS_CCS_OK; - /* - * Should have been reset by ssl3_get_finished, too. - */ - s->s3->change_cipher_spec = 0; - - if (s->state != SSL_ST_RENEGOTIATE) { - /* - * Ok, we now need to push on a buffering BIO so that the - * output is sent in a way that TCP likes :-) - */ - if (!ssl_init_wbio_buffer(s, 1)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - s->state = SSL3_ST_SR_CLNT_HELLO_A; - s->ctx->stats.sess_accept++; - } else if (!s->s3->send_connection_binding && - !(s->options & - SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { - /* - * Server attempting to renegotiate with client that doesn't - * support secure renegotiation. - */ - SSLerr(SSL_F_SSL3_ACCEPT, - SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } else { - /* - * s->state == SSL_ST_RENEGOTIATE, we will just send a - * HelloRequest - */ - s->ctx->stats.sess_accept_renegotiate++; - s->state = SSL3_ST_SW_HELLO_REQ_A; - } - break; - - case SSL3_ST_SW_HELLO_REQ_A: - case SSL3_ST_SW_HELLO_REQ_B: - - s->shutdown = 0; - ret = ssl3_send_hello_request(s); - if (ret <= 0) - goto end; - s->s3->tmp.next_state = SSL3_ST_SW_HELLO_REQ_C; - s->state = SSL3_ST_SW_FLUSH; - s->init_num = 0; - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - break; - - case SSL3_ST_SW_HELLO_REQ_C: - s->state = SSL_ST_OK; - break; - - case SSL3_ST_SR_CLNT_HELLO_A: - case SSL3_ST_SR_CLNT_HELLO_B: - case SSL3_ST_SR_CLNT_HELLO_C: - - s->shutdown = 0; - ret = ssl3_get_client_hello(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_SRP - s->state = SSL3_ST_SR_CLNT_HELLO_D; - case SSL3_ST_SR_CLNT_HELLO_D: - { - int al; - if ((ret = ssl_check_srp_ext_ClientHello(s, &al)) < 0) { - /* - * callback indicates firther work to be done - */ - s->rwstate = SSL_X509_LOOKUP; - goto end; - } - if (ret != SSL_ERROR_NONE) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - /* - * This is not really an error but the only means to for - * a client to detect whether srp is supported. - */ - if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY) - SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_CLIENTHELLO_TLSEXT); - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - } -#endif - - s->renegotiate = 2; - s->state = SSL3_ST_SW_SRVR_HELLO_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_SRVR_HELLO_A: - case SSL3_ST_SW_SRVR_HELLO_B: - ret = ssl3_send_server_hello(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_TLSEXT - if (s->hit) { - if (s->tlsext_ticket_expected) - s->state = SSL3_ST_SW_SESSION_TICKET_A; - else - s->state = SSL3_ST_SW_CHANGE_A; - } -#else - if (s->hit) - s->state = SSL3_ST_SW_CHANGE_A; -#endif - else - s->state = SSL3_ST_SW_CERT_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_CERT_A: - case SSL3_ST_SW_CERT_B: - /* Check if it is anon DH or anon ECDH, */ - /* normal PSK or KRB5 or SRP */ - if (! - (s->s3->tmp. - new_cipher->algorithm_auth & (SSL_aNULL | SSL_aKRB5 | - SSL_aSRP)) -&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - ret = ssl3_send_server_certificate(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_status_expected) - s->state = SSL3_ST_SW_CERT_STATUS_A; - else - s->state = SSL3_ST_SW_KEY_EXCH_A; - } else { - skip = 1; - s->state = SSL3_ST_SW_KEY_EXCH_A; - } -#else - } else - skip = 1; - - s->state = SSL3_ST_SW_KEY_EXCH_A; -#endif - s->init_num = 0; - break; - - case SSL3_ST_SW_KEY_EXCH_A: - case SSL3_ST_SW_KEY_EXCH_B: - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - - /* - * clear this, it may get reset by - * send_server_key_exchange - */ - s->s3->tmp.use_rsa_tmp = 0; - - /* - * only send if a DH key exchange, fortezza or RSA but we have a - * sign only certificate PSK: may send PSK identity hints For - * ECC ciphersuites, we send a serverKeyExchange message only if - * the cipher suite is either ECDH-anon or ECDHE. In other cases, - * the server certificate contains the server's public key for - * key exchange. - */ - if (0 - /* - * PSK: send ServerKeyExchange if PSK identity hint if - * provided - */ -#ifndef OPENSSL_NO_PSK - || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) -#endif -#ifndef OPENSSL_NO_SRP - /* SRP: send ServerKeyExchange */ - || (alg_k & SSL_kSRP) -#endif - || (alg_k & SSL_kEDH) - || (alg_k & SSL_kEECDH) - || ((alg_k & SSL_kRSA) - && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL - || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) - && EVP_PKEY_size(s->cert->pkeys - [SSL_PKEY_RSA_ENC].privatekey) * - 8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) - ) - ) - ) - ) { - ret = ssl3_send_server_key_exchange(s); - if (ret <= 0) - goto end; - } else - skip = 1; - - s->state = SSL3_ST_SW_CERT_REQ_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_CERT_REQ_A: - case SSL3_ST_SW_CERT_REQ_B: - if ( /* don't request cert unless asked for it: */ - !(s->verify_mode & SSL_VERIFY_PEER) || - /* - * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert - * during re-negotiation: - */ - (s->s3->tmp.finish_md_len != 0 && - (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || - /* - * never request cert in anonymous ciphersuites (see - * section "Certificate request" in SSL 3 drafts and in - * RFC 2246): - */ - ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && - /* - * ... except when the application insists on - * verification (against the specs, but s3_clnt.c accepts - * this for SSL 3) - */ - !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || - /* - * never request cert in Kerberos ciphersuites - */ - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) || - /* don't request certificate for SRP auth */ - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP) - /* - * With normal PSK Certificates and Certificate Requests - * are omitted - */ - || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - /* no cert request */ - skip = 1; - s->s3->tmp.cert_request = 0; - s->state = SSL3_ST_SW_SRVR_DONE_A; - if (s->s3->handshake_buffer) { - if (!ssl3_digest_cached_records(s)) { - s->state = SSL_ST_ERR; - return -1; - } - } - } else { - s->s3->tmp.cert_request = 1; - ret = ssl3_send_certificate_request(s); - if (ret <= 0) - goto end; -#ifndef NETSCAPE_HANG_BUG - s->state = SSL3_ST_SW_SRVR_DONE_A; -#else - s->state = SSL3_ST_SW_FLUSH; - s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; -#endif - s->init_num = 0; - } - break; - - case SSL3_ST_SW_SRVR_DONE_A: - case SSL3_ST_SW_SRVR_DONE_B: - ret = ssl3_send_server_done(s); - if (ret <= 0) - goto end; - s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; - s->state = SSL3_ST_SW_FLUSH; - s->init_num = 0; - break; - - case SSL3_ST_SW_FLUSH: - - /* - * This code originally checked to see if any data was pending - * using BIO_CTRL_INFO and then flushed. This caused problems as - * documented in PR#1939. The proposed fix doesn't completely - * resolve this issue as buggy implementations of - * BIO_CTRL_PENDING still exist. So instead we just flush - * unconditionally. - */ - - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { - ret = -1; - goto end; - } - s->rwstate = SSL_NOTHING; - - s->state = s->s3->tmp.next_state; - break; - - case SSL3_ST_SR_CERT_A: - case SSL3_ST_SR_CERT_B: - if (s->s3->tmp.cert_request) { - ret = ssl3_get_client_certificate(s); - if (ret <= 0) - goto end; - } - s->init_num = 0; - s->state = SSL3_ST_SR_KEY_EXCH_A; - break; - - case SSL3_ST_SR_KEY_EXCH_A: - case SSL3_ST_SR_KEY_EXCH_B: - ret = ssl3_get_client_key_exchange(s); - if (ret <= 0) - goto end; - if (ret == 2) { - /* - * For the ECDH ciphersuites when the client sends its ECDH - * pub key in a certificate, the CertificateVerify message is - * not sent. Also for GOST ciphersuites when the client uses - * its key from the certificate for key exchange. - */ -#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) - s->state = SSL3_ST_SR_FINISHED_A; -#else - if (s->s3->next_proto_neg_seen) - s->state = SSL3_ST_SR_NEXT_PROTO_A; - else - s->state = SSL3_ST_SR_FINISHED_A; -#endif - s->init_num = 0; - } else if (SSL_USE_SIGALGS(s)) { - s->state = SSL3_ST_SR_CERT_VRFY_A; - s->init_num = 0; - if (!s->session->peer) - break; - /* - * For sigalgs freeze the handshake buffer at this point and - * digest cached records. - */ - if (!s->s3->handshake_buffer) { - SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return -1; - } - s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; - if (!ssl3_digest_cached_records(s)) { - s->state = SSL_ST_ERR; - return -1; - } - } else { - int offset = 0; - int dgst_num; - - s->state = SSL3_ST_SR_CERT_VRFY_A; - s->init_num = 0; - - /* - * We need to get hashes here so if there is a client cert, - * it can be verified FIXME - digest processing for - * CertificateVerify should be generalized. But it is next - * step - */ - if (s->s3->handshake_buffer) { - if (!ssl3_digest_cached_records(s)) { - s->state = SSL_ST_ERR; - return -1; - } - } - for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++) - if (s->s3->handshake_dgst[dgst_num]) { - int dgst_size; - - s->method->ssl3_enc->cert_verify_mac(s, - EVP_MD_CTX_type - (s-> - s3->handshake_dgst - [dgst_num]), - &(s->s3-> - tmp.cert_verify_md - [offset])); - dgst_size = - EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]); - if (dgst_size < 0) { - s->state = SSL_ST_ERR; - ret = -1; - goto end; - } - offset += dgst_size; - } - } - break; - - case SSL3_ST_SR_CERT_VRFY_A: - case SSL3_ST_SR_CERT_VRFY_B: - ret = ssl3_get_cert_verify(s); - if (ret <= 0) - goto end; - -#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) - s->state = SSL3_ST_SR_FINISHED_A; -#else - if (s->s3->next_proto_neg_seen) - s->state = SSL3_ST_SR_NEXT_PROTO_A; - else - s->state = SSL3_ST_SR_FINISHED_A; -#endif - s->init_num = 0; - break; - -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) - case SSL3_ST_SR_NEXT_PROTO_A: - case SSL3_ST_SR_NEXT_PROTO_B: - /* - * Enable CCS for NPN. Receiving a CCS clears the flag, so make - * sure not to re-enable it to ban duplicates. This *should* be the - * first time we have received one - but we check anyway to be - * cautious. - * s->s3->change_cipher_spec is set when a CCS is - * processed in s3_pkt.c, and remains set until - * the client's Finished message is read. - */ - if (!s->s3->change_cipher_spec) - s->s3->flags |= SSL3_FLAGS_CCS_OK; - - ret = ssl3_get_next_proto(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL3_ST_SR_FINISHED_A; - break; -#endif - - case SSL3_ST_SR_FINISHED_A: - case SSL3_ST_SR_FINISHED_B: - /* - * Enable CCS for handshakes without NPN. In NPN the CCS flag has - * already been set. Receiving a CCS clears the flag, so make - * sure not to re-enable it to ban duplicates. - * s->s3->change_cipher_spec is set when a CCS is - * processed in s3_pkt.c, and remains set until - * the client's Finished message is read. - */ - if (!s->s3->change_cipher_spec) - s->s3->flags |= SSL3_FLAGS_CCS_OK; - ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, - SSL3_ST_SR_FINISHED_B); - if (ret <= 0) - goto end; - if (s->hit) - s->state = SSL_ST_OK; -#ifndef OPENSSL_NO_TLSEXT - else if (s->tlsext_ticket_expected) - s->state = SSL3_ST_SW_SESSION_TICKET_A; -#endif - else - s->state = SSL3_ST_SW_CHANGE_A; - s->init_num = 0; - break; - -#ifndef OPENSSL_NO_TLSEXT - case SSL3_ST_SW_SESSION_TICKET_A: - case SSL3_ST_SW_SESSION_TICKET_B: - ret = ssl3_send_newsession_ticket(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_CHANGE_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_CERT_STATUS_A: - case SSL3_ST_SW_CERT_STATUS_B: - ret = ssl3_send_cert_status(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_KEY_EXCH_A; - s->init_num = 0; - break; - -#endif - - case SSL3_ST_SW_CHANGE_A: - case SSL3_ST_SW_CHANGE_B: - - s->session->cipher = s->s3->tmp.new_cipher; - if (!s->method->ssl3_enc->setup_key_block(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - ret = ssl3_send_change_cipher_spec(s, - SSL3_ST_SW_CHANGE_A, - SSL3_ST_SW_CHANGE_B); - - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_FINISHED_A; - s->init_num = 0; - - if (!s->method->ssl3_enc->change_cipher_state(s, - SSL3_CHANGE_CIPHER_SERVER_WRITE)) - { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - break; - - case SSL3_ST_SW_FINISHED_A: - case SSL3_ST_SW_FINISHED_B: - ret = ssl3_send_finished(s, - SSL3_ST_SW_FINISHED_A, - SSL3_ST_SW_FINISHED_B, - s->method-> - ssl3_enc->server_finished_label, - s->method-> - ssl3_enc->server_finished_label_len); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_FLUSH; - if (s->hit) { -#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) - s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; -#else - if (s->s3->next_proto_neg_seen) { - s->s3->tmp.next_state = SSL3_ST_SR_NEXT_PROTO_A; - } else - s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; -#endif - } else - s->s3->tmp.next_state = SSL_ST_OK; - s->init_num = 0; - break; - - case SSL_ST_OK: - /* clean a few things up */ - ssl3_cleanup_key_block(s); - - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - - /* remove buffering on output */ - ssl_free_wbio_buffer(s); - - s->init_num = 0; - - if (s->renegotiate == 2) { /* skipped if we just sent a - * HelloRequest */ - s->renegotiate = 0; - s->new_session = 0; - - ssl_update_cache(s, SSL_SESS_CACHE_SERVER); - - s->ctx->stats.sess_accept_good++; - /* s->server=1; */ - s->handshake_func = ssl3_accept; - - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - } - - ret = 1; - goto end; - /* break; */ - - case SSL_ST_ERR: - default: - SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* break; */ - } - - if (!s->s3->tmp.reuse_message && !skip) { - if (s->debug) { - if ((ret = BIO_flush(s->wbio)) <= 0) - goto end; - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_ACCEPT_LOOP, 1); - s->state = new_state; - } - } - skip = 0; - } - end: - /* BIO_flush(s->wbio); */ - - s->in_handshake--; - if (cb != NULL) - cb(s, SSL_CB_ACCEPT_EXIT, ret); - return (ret); -} - -int ssl3_send_hello_request(SSL *s) -{ - - if (s->state == SSL3_ST_SW_HELLO_REQ_A) { - ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0); - s->state = SSL3_ST_SW_HELLO_REQ_B; - } - - /* SSL3_ST_SW_HELLO_REQ_B */ - return ssl_do_write(s); -} - -int ssl3_get_client_hello(SSL *s) -{ - int i, j, ok, al = SSL_AD_INTERNAL_ERROR, ret = -1, cookie_valid = 0; - unsigned int cookie_len; - long n; - unsigned long id; - unsigned char *p, *d; - SSL_CIPHER *c; -#ifndef OPENSSL_NO_COMP - unsigned char *q; - SSL_COMP *comp = NULL; -#endif - STACK_OF(SSL_CIPHER) *ciphers = NULL; - - if (s->state == SSL3_ST_SR_CLNT_HELLO_C && !s->first_packet) - goto retry_cert; - - /* - * We do this so that we will respond with our native type. If we are - * TLSv1 and we get SSLv3, we will respond with TLSv1, This down - * switching should be handled by a different method. If we are SSLv3, we - * will respond with SSLv3, even if prompted with TLSv1. - */ - if (s->state == SSL3_ST_SR_CLNT_HELLO_A) { - s->state = SSL3_ST_SR_CLNT_HELLO_B; - } - s->first_packet = 1; - n = s->method->ssl_get_message(s, - SSL3_ST_SR_CLNT_HELLO_B, - SSL3_ST_SR_CLNT_HELLO_C, - SSL3_MT_CLIENT_HELLO, - SSL3_RT_MAX_PLAIN_LENGTH, &ok); - - if (!ok) - return ((int)n); - s->first_packet = 0; - d = p = (unsigned char *)s->init_msg; - - /* - * 2 bytes for client version, SSL3_RANDOM_SIZE bytes for random, 1 byte - * for session id length - */ - if (n < 2 + SSL3_RANDOM_SIZE + 1) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - /* - * use version from inside client hello, not from record header (may - * differ: see RFC 2246, Appendix E, second paragraph) - */ - s->client_version = (((int)p[0]) << 8) | (int)p[1]; - p += 2; - - if (SSL_IS_DTLS(s) ? (s->client_version > s->version && - s->method->version != DTLS_ANY_VERSION) - : (s->client_version < s->version)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); - if ((s->client_version >> 8) == SSL3_VERSION_MAJOR && - !s->enc_write_ctx && !s->write_hash) { - /* - * similar to ssl3_get_record, send alert using remote version - * number - */ - s->version = s->client_version; - } - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } - - /* - * If we require cookies and this ClientHello doesn't contain one, just - * return since we do not want to allocate any memory yet. So check - * cookie length... - */ - if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { - unsigned int session_length, cookie_length; - - session_length = *(p + SSL3_RANDOM_SIZE); - - if (SSL3_RANDOM_SIZE + session_length + 1 - >= (unsigned int)((d + n) - p)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1); - - if (cookie_length == 0) - return 1; - } - - /* load the client random */ - memcpy(s->s3->client_random, p, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; - - /* get the session-id */ - j = *(p++); - - if ((d + n) - p < j) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if ((j < 0) || (j > SSL_MAX_SSL_SESSION_ID_LENGTH)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - - s->hit = 0; - /* - * Versions before 0.9.7 always allow clients to resume sessions in - * renegotiation. 0.9.7 and later allow this by default, but optionally - * ignore resumption requests with flag - * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather - * than a change to default behavior so that applications relying on this - * for security won't even compile against older library versions). - * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to - * request renegotiation but not a new session (s->new_session remains - * unset): for servers, this essentially just means that the - * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be ignored. - */ - if ((s->new_session - && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { - if (!ssl_get_new_session(s, 1)) - goto err; - } else { - i = ssl_get_prev_session(s, p, j, d + n); - /* - * Only resume if the session's version matches the negotiated - * version. - * RFC 5246 does not provide much useful advice on resumption - * with a different protocol version. It doesn't forbid it but - * the sanity of such behaviour would be questionable. - * In practice, clients do not accept a version mismatch and - * will abort the handshake with an error. - */ - if (i == 1 && s->version == s->session->ssl_version) { /* previous - * session */ - s->hit = 1; - } else if (i == -1) - goto err; - else { /* i == 0 */ - - if (!ssl_get_new_session(s, 1)) - goto err; - } - } - - p += j; - - if (SSL_IS_DTLS(s)) { - /* cookie stuff */ - if ((d + n) - p < 1) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - cookie_len = *(p++); - - if ((unsigned int)((d + n ) - p) < cookie_len) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - /* - * The ClientHello may contain a cookie even if the - * HelloVerify message has not been sent--make sure that it - * does not cause an overflow. - */ - if (cookie_len > sizeof(s->d1->rcvd_cookie)) { - /* too much data */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); - goto f_err; - } - - /* verify the cookie if appropriate option is set. */ - if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && cookie_len > 0) { - memcpy(s->d1->rcvd_cookie, p, cookie_len); - - if (s->ctx->app_verify_cookie_cb != NULL) { - if (s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie, - cookie_len) == 0) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_COOKIE_MISMATCH); - goto f_err; - } - /* else cookie verification succeeded */ - } - /* default verification */ - else if (memcmp(s->d1->rcvd_cookie, s->d1->cookie, - s->d1->cookie_len) != 0) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); - goto f_err; - } - cookie_valid = 1; - } - - p += cookie_len; - if (s->method->version == DTLS_ANY_VERSION) { - /* Select version to use */ - if (s->client_version <= DTLS1_2_VERSION && - !(s->options & SSL_OP_NO_DTLSv1_2)) { - s->version = DTLS1_2_VERSION; - s->method = DTLSv1_2_server_method(); - } else if (tls1_suiteb(s)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); - s->version = s->client_version; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } else if (s->client_version <= DTLS1_VERSION && - !(s->options & SSL_OP_NO_DTLSv1)) { - s->version = DTLS1_VERSION; - s->method = DTLSv1_server_method(); - } else { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_WRONG_VERSION_NUMBER); - s->version = s->client_version; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } - s->session->ssl_version = s->version; - } - } - - if ((d + n ) - p < 2) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p, i); - - if (i == 0) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED); - goto f_err; - } - - /* i bytes of cipher data + 1 byte for compression length later */ - if ((d + n) - p < i + 1) { - /* not enough data */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - if (ssl_bytes_to_cipher_list(s, p, i, &(ciphers)) == NULL) { - goto err; - } - p += i; - - /* If it is a hit, check that the cipher is in the list */ - if (s->hit) { - j = 0; - id = s->session->cipher->id; - -#ifdef CIPHER_DEBUG - fprintf(stderr, "client sent %d ciphers\n", - sk_SSL_CIPHER_num(ciphers)); -#endif - for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { - c = sk_SSL_CIPHER_value(ciphers, i); -#ifdef CIPHER_DEBUG - fprintf(stderr, "client [%2d of %2d]:%s\n", - i, sk_SSL_CIPHER_num(ciphers), SSL_CIPHER_get_name(c)); -#endif - if (c->id == id) { - j = 1; - break; - } - } - /* - * Disabled because it can be used in a ciphersuite downgrade attack: - * CVE-2010-4180. - */ -#if 0 - if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) - && (sk_SSL_CIPHER_num(ciphers) == 1)) { - /* - * Special case as client bug workaround: the previously used - * cipher may not be in the current list, the client instead - * might be trying to continue using a cipher that before wasn't - * chosen due to server preferences. We'll have to reject the - * connection if the cipher is not enabled, though. - */ - c = sk_SSL_CIPHER_value(ciphers, 0); - if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0) { - s->session->cipher = c; - j = 1; - } - } -#endif - if (j == 0) { - /* - * we need to have the cipher in the cipher list if we are asked - * to reuse it - */ - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_REQUIRED_CIPHER_MISSING); - goto f_err; - } - } - - /* compression */ - i = *(p++); - if ((d + n) - p < i) { - /* not enough data */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); - goto f_err; - } -#ifndef OPENSSL_NO_COMP - q = p; -#endif - for (j = 0; j < i; j++) { - if (p[j] == 0) - break; - } - - p += i; - if (j >= i) { - /* no compress */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED); - goto f_err; - } -#ifndef OPENSSL_NO_TLSEXT - /* TLS extensions */ - if (s->version >= SSL3_VERSION) { - if (!ssl_parse_clienthello_tlsext(s, &p, d + n)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT); - goto err; - } - } - - /* - * Check if we want to use external pre-shared secret for this handshake - * for not reused session only. We need to generate server_random before - * calling tls_session_secret_cb in order to allow SessionTicket - * processing to use it in key derivation. - */ - { - unsigned char *pos; - pos = s->s3->server_random; - if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0) { - goto f_err; - } - } - - if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb) { - SSL_CIPHER *pref_cipher = NULL; - - s->session->master_key_length = sizeof(s->session->master_key); - if (s->tls_session_secret_cb(s, s->session->master_key, - &s->session->master_key_length, ciphers, - &pref_cipher, - s->tls_session_secret_cb_arg)) { - s->hit = 1; - s->session->ciphers = ciphers; - s->session->verify_result = X509_V_OK; - - ciphers = NULL; - - /* check if some cipher was preferred by call back */ - pref_cipher = - pref_cipher ? pref_cipher : ssl3_choose_cipher(s, - s-> - session->ciphers, - SSL_get_ciphers - (s)); - if (pref_cipher == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER); - goto f_err; - } - - s->session->cipher = pref_cipher; - - if (s->cipher_list) - sk_SSL_CIPHER_free(s->cipher_list); - - if (s->cipher_list_by_id) - sk_SSL_CIPHER_free(s->cipher_list_by_id); - - s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers); - s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers); - } - } -#endif - - /* - * Worst case, we will use the NULL compression, but if we have other - * options, we will now look for them. We have i-1 compression - * algorithms from the client, starting at q. - */ - s->s3->tmp.new_compression = NULL; -#ifndef OPENSSL_NO_COMP - /* This only happens if we have a cache hit */ - if (s->session->compress_meth != 0) { - int m, comp_id = s->session->compress_meth; - /* Perform sanity checks on resumed compression algorithm */ - /* Can't disable compression */ - if (s->options & SSL_OP_NO_COMPRESSION) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_INCONSISTENT_COMPRESSION); - goto f_err; - } - /* Look for resumed compression method */ - for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++) { - comp = sk_SSL_COMP_value(s->ctx->comp_methods, m); - if (comp_id == comp->id) { - s->s3->tmp.new_compression = comp; - break; - } - } - if (s->s3->tmp.new_compression == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_INVALID_COMPRESSION_ALGORITHM); - goto f_err; - } - /* Look for resumed method in compression list */ - for (m = 0; m < i; m++) { - if (q[m] == comp_id) - break; - } - if (m >= i) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING); - goto f_err; - } - } else if (s->hit) - comp = NULL; - else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods) { - /* See if we have a match */ - int m, nn, o, v, done = 0; - - nn = sk_SSL_COMP_num(s->ctx->comp_methods); - for (m = 0; m < nn; m++) { - comp = sk_SSL_COMP_value(s->ctx->comp_methods, m); - v = comp->id; - for (o = 0; o < i; o++) { - if (v == q[o]) { - done = 1; - break; - } - } - if (done) - break; - } - if (done) - s->s3->tmp.new_compression = comp; - else - comp = NULL; - } -#else - /* - * If compression is disabled we'd better not try to resume a session - * using compression. - */ - if (s->session->compress_meth != 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_INCONSISTENT_COMPRESSION); - goto f_err; - } -#endif - - /* - * Given s->session->ciphers and SSL_get_ciphers, we must pick a cipher - */ - - if (!s->hit) { -#ifdef OPENSSL_NO_COMP - s->session->compress_meth = 0; -#else - s->session->compress_meth = (comp == NULL) ? 0 : comp->id; -#endif - if (s->session->ciphers != NULL) - sk_SSL_CIPHER_free(s->session->ciphers); - s->session->ciphers = ciphers; - if (ciphers == NULL) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto f_err; - } - ciphers = NULL; - if (!tls1_set_server_sigalgs(s)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); - goto err; - } - /* Let cert callback update server certificates if required */ - retry_cert: - if (s->cert->cert_cb) { - int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg); - if (rv == 0) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CERT_CB_ERROR); - goto f_err; - } - if (rv < 0) { - s->rwstate = SSL_X509_LOOKUP; - return -1; - } - s->rwstate = SSL_NOTHING; - } - c = ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s)); - - if (c == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER); - goto f_err; - } - s->s3->tmp.new_cipher = c; - } else { - /* Session-id reuse */ -#ifdef REUSE_CIPHER_BUG - STACK_OF(SSL_CIPHER) *sk; - SSL_CIPHER *nc = NULL; - SSL_CIPHER *ec = NULL; - - if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) { - sk = s->session->ciphers; - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { - c = sk_SSL_CIPHER_value(sk, i); - if (c->algorithm_enc & SSL_eNULL) - nc = c; - if (SSL_C_IS_EXPORT(c)) - ec = c; - } - if (nc != NULL) - s->s3->tmp.new_cipher = nc; - else if (ec != NULL) - s->s3->tmp.new_cipher = ec; - else - s->s3->tmp.new_cipher = s->session->cipher; - } else -#endif - s->s3->tmp.new_cipher = s->session->cipher; - } - - if (!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) { - if (!ssl3_digest_cached_records(s)) - goto f_err; - } - - /*- - * we now have the following setup. - * client_random - * cipher_list - our prefered list of ciphers - * ciphers - the clients prefered list of ciphers - * compression - basically ignored right now - * ssl version is set - sslv3 - * s->session - The ssl session has been setup. - * s->hit - session reuse flag - * s->tmp.new_cipher - the new cipher to use. - */ - - /* Handles TLS extensions that we couldn't check earlier */ - if (s->version >= SSL3_VERSION) { - if (!ssl_check_clienthello_tlsext_late(s, &al)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); - goto f_err; - } - } - - ret = cookie_valid ? 2 : 1; - if (0) { - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - s->state = SSL_ST_ERR; - } - - if (ciphers != NULL) - sk_SSL_CIPHER_free(ciphers); - return ret; -} - -int ssl3_send_server_hello(SSL *s) -{ - unsigned char *buf; - unsigned char *p, *d; - int i, sl; - int al = 0; - unsigned long l; - - if (s->state == SSL3_ST_SW_SRVR_HELLO_A) { - buf = (unsigned char *)s->init_buf->data; -#ifdef OPENSSL_NO_TLSEXT - p = s->s3->server_random; - if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0) { - s->state = SSL_ST_ERR; - return -1; - } -#endif - /* Do the message type and length last */ - d = p = ssl_handshake_start(s); - - *(p++) = s->version >> 8; - *(p++) = s->version & 0xff; - - /* Random stuff */ - memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; - - /*- - * There are several cases for the session ID to send - * back in the server hello: - * - For session reuse from the session cache, - * we send back the old session ID. - * - If stateless session reuse (using a session ticket) - * is successful, we send back the client's "session ID" - * (which doesn't actually identify the session). - * - If it is a new session, we send back the new - * session ID. - * - However, if we want the new session to be single-use, - * we send back a 0-length session ID. - * s->hit is non-zero in either case of session reuse, - * so the following won't overwrite an ID that we're supposed - * to send back. - */ - if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) - && !s->hit) - s->session->session_id_length = 0; - - sl = s->session->session_id_length; - if (sl > (int)sizeof(s->session->session_id)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return -1; - } - *(p++) = sl; - memcpy(p, s->session->session_id, sl); - p += sl; - - /* put the cipher */ - i = ssl3_put_cipher_by_char(s->s3->tmp.new_cipher, p); - p += i; - - /* put the compression method */ -#ifdef OPENSSL_NO_COMP - *(p++) = 0; -#else - if (s->s3->tmp.new_compression == NULL) - *(p++) = 0; - else - *(p++) = s->s3->tmp.new_compression->id; -#endif -#ifndef OPENSSL_NO_TLSEXT - if (ssl_prepare_serverhello_tlsext(s) <= 0) { - SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT); - s->state = SSL_ST_ERR; - return -1; - } - if ((p = - ssl_add_serverhello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH, - &al)) == NULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return -1; - } -#endif - /* do the header */ - l = (p - d); - ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l); - s->state = SSL3_ST_SW_SRVR_HELLO_B; - } - - /* SSL3_ST_SW_SRVR_HELLO_B */ - return ssl_do_write(s); -} - -int ssl3_send_server_done(SSL *s) -{ - - if (s->state == SSL3_ST_SW_SRVR_DONE_A) { - ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0); - s->state = SSL3_ST_SW_SRVR_DONE_B; - } - - /* SSL3_ST_SW_SRVR_DONE_B */ - return ssl_do_write(s); -} - -int ssl3_send_server_key_exchange(SSL *s) -{ -#ifndef OPENSSL_NO_RSA - unsigned char *q; - int j, num; - RSA *rsa; - unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; - unsigned int u; -#endif -#ifndef OPENSSL_NO_DH -# ifdef OPENSSL_NO_RSA - int j; -# endif - DH *dh = NULL, *dhp; -#endif -#ifndef OPENSSL_NO_ECDH - EC_KEY *ecdh = NULL, *ecdhp; - unsigned char *encodedPoint = NULL; - int encodedlen = 0; - int curve_id = 0; - BN_CTX *bn_ctx = NULL; -#endif - EVP_PKEY *pkey; - const EVP_MD *md = NULL; - unsigned char *p, *d; - int al, i; - unsigned long type; - int n; - CERT *cert; - BIGNUM *r[4]; - int nr[4], kn; - BUF_MEM *buf; - EVP_MD_CTX md_ctx; - - EVP_MD_CTX_init(&md_ctx); - if (s->state == SSL3_ST_SW_KEY_EXCH_A) { - type = s->s3->tmp.new_cipher->algorithm_mkey; - cert = s->cert; - - buf = s->init_buf; - - r[0] = r[1] = r[2] = r[3] = NULL; - n = 0; -#ifndef OPENSSL_NO_RSA - if (type & SSL_kRSA) { - rsa = cert->rsa_tmp; - if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) { - rsa = s->cert->rsa_tmp_cb(s, - SSL_C_IS_EXPORT(s->s3-> - tmp.new_cipher), - SSL_C_EXPORT_PKEYLENGTH(s->s3-> - tmp.new_cipher)); - if (rsa == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_ERROR_GENERATING_TMP_RSA_KEY); - goto f_err; - } - RSA_up_ref(rsa); - cert->rsa_tmp = rsa; - } - if (rsa == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_MISSING_TMP_RSA_KEY); - goto f_err; - } - r[0] = rsa->n; - r[1] = rsa->e; - s->s3->tmp.use_rsa_tmp = 1; - } else -#endif -#ifndef OPENSSL_NO_DH - if (type & SSL_kEDH) { - dhp = cert->dh_tmp; - if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) - dhp = s->cert->dh_tmp_cb(s, - SSL_C_IS_EXPORT(s->s3-> - tmp.new_cipher), - SSL_C_EXPORT_PKEYLENGTH(s->s3-> - tmp.new_cipher)); - if (dhp == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_MISSING_TMP_DH_KEY); - goto f_err; - } - - if (s->s3->tmp.dh != NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - if ((dh = DHparams_dup(dhp)) == NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); - goto err; - } - - s->s3->tmp.dh = dh; - if (!DH_generate_key(dh)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); - goto err; - } - r[0] = dh->p; - r[1] = dh->g; - r[2] = dh->pub_key; - } else -#endif -#ifndef OPENSSL_NO_ECDH - if (type & SSL_kEECDH) { - const EC_GROUP *group; - - if (s->s3->tmp.ecdh != NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - ecdhp = cert->ecdh_tmp; - if (s->cert->ecdh_tmp_auto) { - /* Get NID of appropriate shared curve */ - int nid = tls1_shared_curve(s, -2); - if (nid != NID_undef) - ecdhp = EC_KEY_new_by_curve_name(nid); - } else if ((ecdhp == NULL) && s->cert->ecdh_tmp_cb) { - ecdhp = s->cert->ecdh_tmp_cb(s, - SSL_C_IS_EXPORT(s->s3-> - tmp.new_cipher), - SSL_C_EXPORT_PKEYLENGTH(s-> - s3->tmp.new_cipher)); - } - if (ecdhp == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_MISSING_TMP_ECDH_KEY); - goto f_err; - } - - /* Duplicate the ECDH structure. */ - if (s->cert->ecdh_tmp_auto) - ecdh = ecdhp; - else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - - s->s3->tmp.ecdh = ecdh; - if ((EC_KEY_get0_public_key(ecdh) == NULL) || - (EC_KEY_get0_private_key(ecdh) == NULL) || - (s->options & SSL_OP_SINGLE_ECDH_USE)) { - if (!EC_KEY_generate_key(ecdh)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_ECDH_LIB); - goto err; - } - } - - if (((group = EC_KEY_get0_group(ecdh)) == NULL) || - (EC_KEY_get0_public_key(ecdh) == NULL) || - (EC_KEY_get0_private_key(ecdh) == NULL)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - - if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - (EC_GROUP_get_degree(group) > 163)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); - goto err; - } - - /* - * XXX: For now, we only support ephemeral ECDH keys over named - * (not generic) curves. For supported named curves, curve_id is - * non-zero. - */ - if ((curve_id = - tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group))) - == 0) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); - goto err; - } - - /* - * Encode the public key. First check the size of encoding and - * allocate memory accordingly. - */ - encodedlen = EC_POINT_point2oct(group, - EC_KEY_get0_public_key(ecdh), - POINT_CONVERSION_UNCOMPRESSED, - NULL, 0, NULL); - - encodedPoint = (unsigned char *) - OPENSSL_malloc(encodedlen * sizeof(unsigned char)); - bn_ctx = BN_CTX_new(); - if ((encodedPoint == NULL) || (bn_ctx == NULL)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - encodedlen = EC_POINT_point2oct(group, - EC_KEY_get0_public_key(ecdh), - POINT_CONVERSION_UNCOMPRESSED, - encodedPoint, encodedlen, bn_ctx); - - if (encodedlen == 0) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - - BN_CTX_free(bn_ctx); - bn_ctx = NULL; - - /* - * XXX: For now, we only support named (not generic) curves in - * ECDH ephemeral key exchanges. In this situation, we need four - * additional bytes to encode the entire ServerECDHParams - * structure. - */ - n = 4 + encodedlen; - - /* - * We'll generate the serverKeyExchange message explicitly so we - * can set these to NULLs - */ - r[0] = NULL; - r[1] = NULL; - r[2] = NULL; - r[3] = NULL; - } else -#endif /* !OPENSSL_NO_ECDH */ -#ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) { - /* - * reserve size for record length and PSK identity hint - */ - n += 2 + strlen(s->ctx->psk_identity_hint); - } else -#endif /* !OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_SRP - if (type & SSL_kSRP) { - if ((s->srp_ctx.N == NULL) || - (s->srp_ctx.g == NULL) || - (s->srp_ctx.s == NULL) || (s->srp_ctx.B == NULL)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_MISSING_SRP_PARAM); - goto err; - } - r[0] = s->srp_ctx.N; - r[1] = s->srp_ctx.g; - r[2] = s->srp_ctx.s; - r[3] = s->srp_ctx.B; - } else -#endif - { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); - goto f_err; - } - for (i = 0; i < 4 && r[i] != NULL; i++) { - nr[i] = BN_num_bytes(r[i]); -#ifndef OPENSSL_NO_SRP - if ((i == 2) && (type & SSL_kSRP)) - n += 1 + nr[i]; - else -#endif -#ifndef OPENSSL_NO_DH - /* - * for interoperability with some versions of the Microsoft TLS - * stack, we need to zero pad the DHE pub key to the same length - * as the prime, so use the length of the prime here - */ - if ((i == 2) && (type & (SSL_kEDH))) - n += 2 + nr[0]; - else -#endif - n += 2 + nr[i]; - } - - if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - if ((pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher, &md)) - == NULL) { - al = SSL_AD_DECODE_ERROR; - goto f_err; - } - kn = EVP_PKEY_size(pkey); - /* Allow space for signature algorithm */ - if (SSL_USE_SIGALGS(s)) - kn += 2; - /* Allow space for signature length */ - kn += 2; - } else { - pkey = NULL; - kn = 0; - } - - if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + kn)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_BUF); - goto err; - } - d = p = ssl_handshake_start(s); - - for (i = 0; i < 4 && r[i] != NULL; i++) { -#ifndef OPENSSL_NO_SRP - if ((i == 2) && (type & SSL_kSRP)) { - *p = nr[i]; - p++; - } else -#endif -#ifndef OPENSSL_NO_DH - /* - * for interoperability with some versions of the Microsoft TLS - * stack, we need to zero pad the DHE pub key to the same length - * as the prime - */ - if ((i == 2) && (type & (SSL_kEDH))) { - s2n(nr[0], p); - for (j = 0; j < (nr[0] - nr[2]); ++j) { - *p = 0; - ++p; - } - } else -#endif - s2n(nr[i], p); - BN_bn2bin(r[i], p); - p += nr[i]; - } - -#ifndef OPENSSL_NO_ECDH - if (type & SSL_kEECDH) { - /* - * XXX: For now, we only support named (not generic) curves. In - * this situation, the serverKeyExchange message has: [1 byte - * CurveType], [2 byte CurveName] [1 byte length of encoded - * point], followed by the actual encoded point itself - */ - *p = NAMED_CURVE_TYPE; - p += 1; - *p = 0; - p += 1; - *p = curve_id; - p += 1; - *p = encodedlen; - p += 1; - memcpy((unsigned char *)p, - (unsigned char *)encodedPoint, encodedlen); - OPENSSL_free(encodedPoint); - encodedPoint = NULL; - p += encodedlen; - } -#endif - -#ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) { - /* copy PSK identity hint */ - s2n(strlen(s->ctx->psk_identity_hint), p); - strncpy((char *)p, s->ctx->psk_identity_hint, - strlen(s->ctx->psk_identity_hint)); - p += strlen(s->ctx->psk_identity_hint); - } -#endif - - /* not anonymous */ - if (pkey != NULL) { - /* - * n is the length of the params, they start at &(d[4]) and p - * points to the space at the end. - */ -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { - q = md_buf; - j = 0; - for (num = 2; num > 0; num--) { - EVP_MD_CTX_set_flags(&md_ctx, - EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - if (EVP_DigestInit_ex(&md_ctx, - (num == 2) ? s->ctx->md5 - : s->ctx->sha1, - NULL) <= 0 - || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(&md_ctx, d, n) <= 0 - || EVP_DigestFinal_ex(&md_ctx, q, - (unsigned int *)&i) <= 0) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_LIB_EVP); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - q += i; - j += i; - } - if (RSA_sign(NID_md5_sha1, md_buf, j, - &(p[2]), &u, pkey->pkey.rsa) <= 0) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_RSA); - goto err; - } - s2n(u, p); - n += u + 2; - } else -#endif - if (md) { - /* send signature algorithm */ - if (SSL_USE_SIGALGS(s)) { - if (!tls12_get_sigandhash(p, pkey, md)) { - /* Should never happen */ - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto f_err; - } - p += 2; - } -#ifdef SSL_DEBUG - fprintf(stderr, "Using hash %s\n", EVP_MD_name(md)); -#endif - if (EVP_SignInit_ex(&md_ctx, md, NULL) <= 0 - || EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_SignUpdate(&md_ctx, d, n) <= 0 - || EVP_SignFinal(&md_ctx, &(p[2]), - (unsigned int *)&i, pkey) <= 0) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_EVP); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - s2n(i, p); - n += i + 2; - if (SSL_USE_SIGALGS(s)) - n += 2; - } else { - /* Is this error check actually needed? */ - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_UNKNOWN_PKEY_TYPE); - goto f_err; - } - } - - ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n); - } - - s->state = SSL3_ST_SW_KEY_EXCH_B; - EVP_MD_CTX_cleanup(&md_ctx); - return ssl_do_write(s); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: -#ifndef OPENSSL_NO_ECDH - if (encodedPoint != NULL) - OPENSSL_free(encodedPoint); - BN_CTX_free(bn_ctx); -#endif - EVP_MD_CTX_cleanup(&md_ctx); - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_send_certificate_request(SSL *s) -{ - unsigned char *p, *d; - int i, j, nl, off, n; - STACK_OF(X509_NAME) *sk = NULL; - X509_NAME *name; - BUF_MEM *buf; - - if (s->state == SSL3_ST_SW_CERT_REQ_A) { - buf = s->init_buf; - - d = p = ssl_handshake_start(s); - - /* get the list of acceptable cert types */ - p++; - n = ssl3_get_req_cert_type(s, p); - d[0] = n; - p += n; - n++; - - if (SSL_USE_SIGALGS(s)) { - const unsigned char *psigs; - nl = tls12_get_psigalgs(s, 1, &psigs); - s2n(nl, p); - memcpy(p, psigs, nl); - p += nl; - n += nl + 2; - } - - off = n; - p += 2; - n += 2; - - sk = SSL_get_client_CA_list(s); - nl = 0; - if (sk != NULL) { - for (i = 0; i < sk_X509_NAME_num(sk); i++) { - name = sk_X509_NAME_value(sk, i); - j = i2d_X509_NAME(name, NULL); - if (!BUF_MEM_grow_clean - (buf, SSL_HM_HEADER_LENGTH(s) + n + j + 2)) { - SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, - ERR_R_BUF_LIB); - goto err; - } - p = ssl_handshake_start(s) + n; - if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) { - s2n(j, p); - i2d_X509_NAME(name, &p); - n += 2 + j; - nl += 2 + j; - } else { - d = p; - i2d_X509_NAME(name, &p); - j -= 2; - s2n(j, d); - j += 2; - n += j; - nl += j; - } - } - } - /* else no CA names */ - p = ssl_handshake_start(s) + off; - s2n(nl, p); - - ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n); - -#ifdef NETSCAPE_HANG_BUG - if (!SSL_IS_DTLS(s)) { - if (!BUF_MEM_grow_clean(buf, s->init_num + 4)) { - SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, ERR_R_BUF_LIB); - goto err; - } - p = (unsigned char *)s->init_buf->data + s->init_num; - /* do the header */ - *(p++) = SSL3_MT_SERVER_DONE; - *(p++) = 0; - *(p++) = 0; - *(p++) = 0; - s->init_num += 4; - } -#endif - - s->state = SSL3_ST_SW_CERT_REQ_B; - } - - /* SSL3_ST_SW_CERT_REQ_B */ - return ssl_do_write(s); - err: - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_get_client_key_exchange(SSL *s) -{ - int i, al, ok; - long n; - unsigned long alg_k; - unsigned char *p; -#ifndef OPENSSL_NO_RSA - RSA *rsa = NULL; - EVP_PKEY *pkey = NULL; -#endif -#ifndef OPENSSL_NO_DH - BIGNUM *pub = NULL; - DH *dh_srvr, *dh_clnt = NULL; -#endif -#ifndef OPENSSL_NO_KRB5 - KSSL_ERR kssl_err; -#endif /* OPENSSL_NO_KRB5 */ - -#ifndef OPENSSL_NO_ECDH - EC_KEY *srvr_ecdh = NULL; - EVP_PKEY *clnt_pub_pkey = NULL; - EC_POINT *clnt_ecpoint = NULL; - BN_CTX *bn_ctx = NULL; -#endif - - n = s->method->ssl_get_message(s, - SSL3_ST_SR_KEY_EXCH_A, - SSL3_ST_SR_KEY_EXCH_B, - SSL3_MT_CLIENT_KEY_EXCHANGE, 2048, &ok); - - if (!ok) - return ((int)n); - p = (unsigned char *)s->init_msg; - - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - -#ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { - unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; - int decrypt_len; - unsigned char decrypt_good, version_good; - size_t j; - - /* FIX THIS UP EAY EAY EAY EAY */ - if (s->s3->tmp.use_rsa_tmp) { - if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL)) - rsa = s->cert->rsa_tmp; - /* - * Don't do a callback because rsa_tmp should be sent already - */ - if (rsa == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_TMP_RSA_PKEY); - goto f_err; - - } - } else { - pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey; - if ((pkey == NULL) || - (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_RSA_CERTIFICATE); - goto f_err; - } - rsa = pkey->pkey.rsa; - } - - /* TLS and [incidentally] DTLS{0xFEFF} */ - if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER) { - n2s(p, i); - if (n != i + 2) { - if (!(s->options & SSL_OP_TLS_D5_BUG)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); - goto f_err; - } else - p -= 2; - } else - n = i; - } - - /* - * Reject overly short RSA ciphertext because we want to be sure - * that the buffer size makes it safe to iterate over the entire - * size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The - * actual expected size is larger due to RSA padding, but the - * bound is sufficient to be safe. - */ - if (n < SSL_MAX_MASTER_KEY_LENGTH) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); - goto f_err; - } - - /* - * We must not leak whether a decryption failure occurs because of - * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, - * section 7.4.7.1). The code follows that advice of the TLS RFC and - * generates a random premaster secret for the case that the decrypt - * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 - */ - - if (RAND_bytes(rand_premaster_secret, - sizeof(rand_premaster_secret)) <= 0) - goto err; - decrypt_len = - RSA_private_decrypt((int)n, p, p, rsa, RSA_PKCS1_PADDING); - ERR_clear_error(); - - /* - * decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH. decrypt_good will - * be 0xff if so and zero otherwise. - */ - decrypt_good = - constant_time_eq_int_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH); - - /* - * If the version in the decrypted pre-master secret is correct then - * version_good will be 0xff, otherwise it'll be zero. The - * Klima-Pokorny-Rosa extension of Bleichenbacher's attack - * (http://eprint.iacr.org/2003/052/) exploits the version number - * check as a "bad version oracle". Thus version checks are done in - * constant time and are treated like any other decryption error. - */ - version_good = - constant_time_eq_8(p[0], (unsigned)(s->client_version >> 8)); - version_good &= - constant_time_eq_8(p[1], (unsigned)(s->client_version & 0xff)); - - /* - * The premaster secret must contain the same version number as the - * ClientHello to detect version rollback attacks (strangely, the - * protocol does not offer such protection for DH ciphersuites). - * However, buggy clients exist that send the negotiated protocol - * version instead if the server does not support the requested - * protocol version. If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such - * clients. - */ - if (s->options & SSL_OP_TLS_ROLLBACK_BUG) { - unsigned char workaround_good; - workaround_good = - constant_time_eq_8(p[0], (unsigned)(s->version >> 8)); - workaround_good &= - constant_time_eq_8(p[1], (unsigned)(s->version & 0xff)); - version_good |= workaround_good; - } - - /* - * Both decryption and version must be good for decrypt_good to - * remain non-zero (0xff). - */ - decrypt_good &= version_good; - - /* - * Now copy rand_premaster_secret over from p using - * decrypt_good_mask. If decryption failed, then p does not - * contain valid plaintext, however, a check above guarantees - * it is still sufficiently large to read from. - */ - for (j = 0; j < sizeof(rand_premaster_secret); j++) { - p[j] = constant_time_select_8(decrypt_good, p[j], - rand_premaster_secret[j]); - } - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, - sizeof - (rand_premaster_secret)); - OPENSSL_cleanse(p, sizeof(rand_premaster_secret)); - } else -#endif -#ifndef OPENSSL_NO_DH - if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) { - int idx = -1; - EVP_PKEY *skey = NULL; - if (n > 1) { - n2s(p, i); - } else { - if (alg_k & SSL_kDHE) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); - goto f_err; - } - i = 0; - } - if (n && n != i + 2) { - if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); - al = SSL_AD_HANDSHAKE_FAILURE; - goto f_err; - } else { - p -= 2; - i = (int)n; - } - } - if (alg_k & SSL_kDHr) - idx = SSL_PKEY_DH_RSA; - else if (alg_k & SSL_kDHd) - idx = SSL_PKEY_DH_DSA; - if (idx >= 0) { - skey = s->cert->pkeys[idx].privatekey; - if ((skey == NULL) || - (skey->type != EVP_PKEY_DH) || (skey->pkey.dh == NULL)) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_RSA_CERTIFICATE); - goto f_err; - } - dh_srvr = skey->pkey.dh; - } else if (s->s3->tmp.dh == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_TMP_DH_KEY); - goto f_err; - } else - dh_srvr = s->s3->tmp.dh; - - if (n == 0L) { - /* Get pubkey from cert */ - EVP_PKEY *clkey = X509_get_pubkey(s->session->peer); - if (clkey) { - if (EVP_PKEY_cmp_parameters(clkey, skey) == 1) - dh_clnt = EVP_PKEY_get1_DH(clkey); - } - if (dh_clnt == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_TMP_DH_KEY); - goto f_err; - } - EVP_PKEY_free(clkey); - pub = dh_clnt->pub_key; - } else - pub = BN_bin2bn(p, i, NULL); - if (pub == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB); - goto err; - } - - i = DH_compute_key(p, pub, dh_srvr); - - if (i <= 0) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); - BN_clear_free(pub); - goto f_err; - } - - DH_free(s->s3->tmp.dh); - s->s3->tmp.dh = NULL; - if (dh_clnt) - DH_free(dh_clnt); - else - BN_clear_free(pub); - pub = NULL; - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, i); - OPENSSL_cleanse(p, i); - if (dh_clnt) - return 2; - } else -#endif -#ifndef OPENSSL_NO_KRB5 - if (alg_k & SSL_kKRB5) { - krb5_error_code krb5rc; - krb5_data enc_ticket; - krb5_data authenticator; - krb5_data enc_pms; - KSSL_CTX *kssl_ctx = s->kssl_ctx; - EVP_CIPHER_CTX ciph_ctx; - const EVP_CIPHER *enc = NULL; - unsigned char iv[EVP_MAX_IV_LENGTH]; - unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_BLOCK_LENGTH]; - int padl, outl; - krb5_timestamp authtime = 0; - krb5_ticket_times ttimes; - int kerr = 0; - - EVP_CIPHER_CTX_init(&ciph_ctx); - - if (!kssl_ctx) - kssl_ctx = kssl_ctx_new(); - - n2s(p, i); - enc_ticket.length = i; - - if (n < (long)(enc_ticket.length + 6)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - - enc_ticket.data = (char *)p; - p += enc_ticket.length; - - n2s(p, i); - authenticator.length = i; - - if (n < (long)(enc_ticket.length + authenticator.length + 6)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - - authenticator.data = (char *)p; - p += authenticator.length; - - n2s(p, i); - enc_pms.length = i; - enc_pms.data = (char *)p; - p += enc_pms.length; - - /* - * Note that the length is checked again below, ** after decryption - */ - if (enc_pms.length > sizeof pms) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - - if (n != (long)(enc_ticket.length + authenticator.length + - enc_pms.length + 6)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - - if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes, - &kssl_err)) != 0) { -# ifdef KSSL_DEBUG - fprintf(stderr, "kssl_sget_tkt rtn %d [%d]\n", - krb5rc, kssl_err.reason); - if (kssl_err.text) - fprintf(stderr, "kssl_err text= %s\n", kssl_err.text); -# endif /* KSSL_DEBUG */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); - goto err; - } - - /* - * Note: no authenticator is not considered an error, ** but will - * return authtime == 0. - */ - if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator, - &authtime, &kssl_err)) != 0) { -# ifdef KSSL_DEBUG - fprintf(stderr, "kssl_check_authent rtn %d [%d]\n", - krb5rc, kssl_err.reason); - if (kssl_err.text) - fprintf(stderr, "kssl_err text= %s\n", kssl_err.text); -# endif /* KSSL_DEBUG */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); - goto err; - } - - if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc); - goto err; - } -# ifdef KSSL_DEBUG - kssl_ctx_show(kssl_ctx); -# endif /* KSSL_DEBUG */ - - enc = kssl_map_enc(kssl_ctx->enctype); - if (enc == NULL) - goto err; - - memset(iv, 0, sizeof iv); /* per RFC 1510 */ - - if (!EVP_DecryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - goto err; - } - if (!EVP_DecryptUpdate(&ciph_ctx, pms, &outl, - (unsigned char *)enc_pms.data, enc_pms.length)) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - kerr = 1; - goto kclean; - } - if (outl > SSL_MAX_MASTER_KEY_LENGTH) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - kerr = 1; - goto kclean; - } - if (!EVP_DecryptFinal_ex(&ciph_ctx, &(pms[outl]), &padl)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - kerr = 1; - goto kclean; - } - outl += padl; - if (outl > SSL_MAX_MASTER_KEY_LENGTH) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - kerr = 1; - goto kclean; - } - if (!((pms[0] == (s->client_version >> 8)) - && (pms[1] == (s->client_version & 0xff)))) { - /* - * The premaster secret must contain the same version number as - * the ClientHello to detect version rollback attacks (strangely, - * the protocol does not offer such protection for DH - * ciphersuites). However, buggy clients exist that send random - * bytes instead of the protocol version. If - * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. - * (Perhaps we should have a separate BUG value for the Kerberos - * cipher) - */ - if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_AD_DECODE_ERROR); - kerr = 1; - goto kclean; - } - } - - EVP_CIPHER_CTX_cleanup(&ciph_ctx); - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - pms, outl); - - if (kssl_ctx->client_princ) { - size_t len = strlen(kssl_ctx->client_princ); - if (len < SSL_MAX_KRB5_PRINCIPAL_LENGTH) { - s->session->krb5_client_princ_len = len; - memcpy(s->session->krb5_client_princ, kssl_ctx->client_princ, - len); - } - } - - /*- Was doing kssl_ctx_free() here, - * but it caused problems for apache. - * kssl_ctx = kssl_ctx_free(kssl_ctx); - * if (s->kssl_ctx) s->kssl_ctx = NULL; - */ - - kclean: - OPENSSL_cleanse(pms, sizeof(pms)); - if (kerr) - goto err; - } else -#endif /* OPENSSL_NO_KRB5 */ - -#ifndef OPENSSL_NO_ECDH - if (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) { - int ret = 1; - int field_size = 0; - const EC_KEY *tkey; - const EC_GROUP *group; - const BIGNUM *priv_key; - - /* initialize structures for server's ECDH key pair */ - if ((srvr_ecdh = EC_KEY_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Let's get server private key and group information */ - if (alg_k & (SSL_kECDHr | SSL_kECDHe)) { - /* use the certificate */ - tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec; - } else { - /* - * use the ephermeral values we saved when generating the - * ServerKeyExchange msg. - */ - tkey = s->s3->tmp.ecdh; - } - - group = EC_KEY_get0_group(tkey); - priv_key = EC_KEY_get0_private_key(tkey); - - if (!EC_KEY_set_group(srvr_ecdh, group) || - !EC_KEY_set_private_key(srvr_ecdh, priv_key)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - - /* Let's get client's public key */ - if ((clnt_ecpoint = EC_POINT_new(group)) == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (n == 0L) { - /* Client Publickey was in Client Certificate */ - - if (alg_k & SSL_kEECDH) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_TMP_ECDH_KEY); - goto f_err; - } - if (((clnt_pub_pkey = X509_get_pubkey(s->session->peer)) - == NULL) || (clnt_pub_pkey->type != EVP_PKEY_EC)) { - /* - * XXX: For now, we do not support client authentication - * using ECDH certificates so this branch (n == 0L) of the - * code is never executed. When that support is added, we - * ought to ensure the key received in the certificate is - * authorized for key agreement. ECDH_compute_key implicitly - * checks that the two ECDH shares are for the same group. - */ - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_UNABLE_TO_DECODE_ECDH_CERTS); - goto f_err; - } - - if (EC_POINT_copy(clnt_ecpoint, - EC_KEY_get0_public_key(clnt_pub_pkey-> - pkey.ec)) == 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - ret = 2; /* Skip certificate verify processing */ - } else { - /* - * Get client's public key from encoded point in the - * ClientKeyExchange message. - */ - if ((bn_ctx = BN_CTX_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Get encoded point length */ - i = *p; - p += 1; - if (n != 1 + i) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); - al = SSL_AD_DECODE_ERROR; - goto f_err; - } - if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - al = SSL_AD_HANDSHAKE_FAILURE; - goto f_err; - } - /* - * p is pointing to somewhere in the buffer currently, so set it - * to the start - */ - p = (unsigned char *)s->init_buf->data; - } - - /* Compute the shared pre-master secret */ - field_size = EC_GROUP_get_degree(group); - if (field_size <= 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - i = ECDH_compute_key(p, (field_size + 7) / 8, clnt_ecpoint, srvr_ecdh, - NULL); - if (i <= 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - - EVP_PKEY_free(clnt_pub_pkey); - EC_POINT_free(clnt_ecpoint); - EC_KEY_free(srvr_ecdh); - BN_CTX_free(bn_ctx); - EC_KEY_free(s->s3->tmp.ecdh); - s->s3->tmp.ecdh = NULL; - - /* Compute the master secret */ - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, i); - - OPENSSL_cleanse(p, i); - return (ret); - } else -#endif -#ifndef OPENSSL_NO_PSK - if (alg_k & SSL_kPSK) { - unsigned char *t = NULL; - unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4]; - unsigned int pre_ms_len = 0, psk_len = 0; - int psk_err = 1; - char tmp_id[PSK_MAX_IDENTITY_LEN + 1]; - - al = SSL_AD_HANDSHAKE_FAILURE; - - n2s(p, i); - if (n != i + 2) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); - goto psk_err; - } - if (i > PSK_MAX_IDENTITY_LEN) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto psk_err; - } - if (s->psk_server_callback == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_NO_SERVER_CB); - goto psk_err; - } - - /* - * Create guaranteed NULL-terminated identity string for the callback - */ - memcpy(tmp_id, p, i); - memset(tmp_id + i, 0, PSK_MAX_IDENTITY_LEN + 1 - i); - psk_len = s->psk_server_callback(s, tmp_id, - psk_or_pre_ms, - sizeof(psk_or_pre_ms)); - OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN + 1); - - if (psk_len > PSK_MAX_PSK_LEN) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto psk_err; - } else if (psk_len == 0) { - /* - * PSK related to the given identity not found - */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_IDENTITY_NOT_FOUND); - al = SSL_AD_UNKNOWN_PSK_IDENTITY; - goto psk_err; - } - - /* create PSK pre_master_secret */ - pre_ms_len = 2 + psk_len + 2 + psk_len; - t = psk_or_pre_ms; - memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len); - s2n(psk_len, t); - memset(t, 0, psk_len); - t += psk_len; - s2n(psk_len, t); - - if (s->session->psk_identity != NULL) - OPENSSL_free(s->session->psk_identity); - s->session->psk_identity = BUF_strndup((char *)p, i); - if (s->session->psk_identity == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto psk_err; - } - - if (s->session->psk_identity_hint != NULL) - OPENSSL_free(s->session->psk_identity_hint); - s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); - if (s->ctx->psk_identity_hint != NULL && - s->session->psk_identity_hint == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto psk_err; - } - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - psk_or_pre_ms, - pre_ms_len); - psk_err = 0; - psk_err: - OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); - if (psk_err != 0) - goto f_err; - } else -#endif -#ifndef OPENSSL_NO_SRP - if (alg_k & SSL_kSRP) { - int param_len; - - n2s(p, i); - param_len = i + 2; - if (param_len > n) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_BAD_SRP_A_LENGTH); - goto f_err; - } - if (!(s->srp_ctx.A = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - if (BN_ucmp(s->srp_ctx.A, s->srp_ctx.N) >= 0 - || BN_is_zero(s->srp_ctx.A)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_BAD_SRP_PARAMETERS); - goto f_err; - } - if (s->session->srp_username != NULL) - OPENSSL_free(s->session->srp_username); - s->session->srp_username = BUF_strdup(s->srp_ctx.login); - if (s->session->srp_username == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - if ((s->session->master_key_length = - SRP_generate_server_master_secret(s, - s->session->master_key)) < 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - - p += i; - } else -#endif /* OPENSSL_NO_SRP */ - if (alg_k & SSL_kGOST) { - int ret = 0; - EVP_PKEY_CTX *pkey_ctx; - EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; - unsigned char premaster_secret[32], *start; - size_t outlen = 32, inlen; - unsigned long alg_a; - int Ttag, Tclass; - long Tlen; - - /* Get our certificate private key */ - alg_a = s->s3->tmp.new_cipher->algorithm_auth; - if (alg_a & SSL_aGOST94) - pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey; - else if (alg_a & SSL_aGOST01) - pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; - - pkey_ctx = EVP_PKEY_CTX_new(pk, NULL); - if (pkey_ctx == NULL) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto f_err; - } - if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto gerr; - } - /* - * If client certificate is present and is of the same type, maybe - * use it for key exchange. Don't mind errors from - * EVP_PKEY_derive_set_peer, because it is completely valid to use a - * client certificate for authorization only. - */ - client_pub_pkey = X509_get_pubkey(s->session->peer); - if (client_pub_pkey) { - if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0) - ERR_clear_error(); - } - /* Decrypt session key */ - if (ASN1_get_object - ((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, - n) != V_ASN1_CONSTRUCTED || Ttag != V_ASN1_SEQUENCE - || Tclass != V_ASN1_UNIVERSAL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - goto gerr; - } - start = p; - inlen = Tlen; - if (EVP_PKEY_decrypt - (pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - goto gerr; - } - /* Generate master secret */ - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - premaster_secret, 32); - OPENSSL_cleanse(premaster_secret, sizeof(premaster_secret)); - /* Check if pubkey from client certificate was used */ - if (EVP_PKEY_CTX_ctrl - (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) - ret = 2; - else - ret = 1; - gerr: - EVP_PKEY_free(client_pub_pkey); - EVP_PKEY_CTX_free(pkey_ctx); - if (ret) - return ret; - else - goto err; - } else { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE); - goto f_err; - } - - return (1); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP) - err: -#endif -#ifndef OPENSSL_NO_ECDH - EVP_PKEY_free(clnt_pub_pkey); - EC_POINT_free(clnt_ecpoint); - if (srvr_ecdh != NULL) - EC_KEY_free(srvr_ecdh); - BN_CTX_free(bn_ctx); -#endif - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_get_cert_verify(SSL *s) -{ - EVP_PKEY *pkey = NULL; - unsigned char *p; - int al, ok, ret = 0; - long n; - int type = 0, i, j; - X509 *peer; - const EVP_MD *md = NULL; - EVP_MD_CTX mctx; - EVP_MD_CTX_init(&mctx); - - /* - * We should only process a CertificateVerify message if we have received - * a Certificate from the client. If so then |s->session->peer| will be non - * NULL. In some instances a CertificateVerify message is not required even - * if the peer has sent a Certificate (e.g. such as in the case of static - * DH). In that case the ClientKeyExchange processing will skip the - * CertificateVerify state so we should not arrive here. - */ - if (s->session->peer == NULL) { - ret = 1; - goto end; - } - - n = s->method->ssl_get_message(s, - SSL3_ST_SR_CERT_VRFY_A, - SSL3_ST_SR_CERT_VRFY_B, - SSL3_MT_CERTIFICATE_VERIFY, - SSL3_RT_MAX_PLAIN_LENGTH, &ok); - - if (!ok) - return ((int)n); - - peer = s->session->peer; - pkey = X509_get_pubkey(peer); - if (pkey == NULL) { - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - - type = X509_certificate_type(peer, pkey); - - if (!(type & EVP_PKT_SIGN)) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, - SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE); - al = SSL_AD_ILLEGAL_PARAMETER; - goto f_err; - } - - /* we now have a signature that we need to verify */ - p = (unsigned char *)s->init_msg; - /* Check for broken implementations of GOST ciphersuites */ - /* - * If key is GOST and n is exactly 64, it is bare signature without - * length field - */ - if (n == 64 && (pkey->type == NID_id_GostR3410_94 || - pkey->type == NID_id_GostR3410_2001)) { - i = 64; - } else { - if (SSL_USE_SIGALGS(s)) { - int rv = tls12_check_peer_sigalg(&md, s, p, pkey); - if (rv == -1) { - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } else if (rv == 0) { - al = SSL_AD_DECODE_ERROR; - goto f_err; - } -#ifdef SSL_DEBUG - fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); -#endif - p += 2; - n -= 2; - } - n2s(p, i); - n -= 2; - if (i > n) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_LENGTH_MISMATCH); - al = SSL_AD_DECODE_ERROR; - goto f_err; - } - } - j = EVP_PKEY_size(pkey); - if ((i > j) || (n > j) || (n <= 0)) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE); - al = SSL_AD_DECODE_ERROR; - goto f_err; - } - - if (SSL_USE_SIGALGS(s)) { - long hdatalen = 0; - void *hdata; - hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); - if (hdatalen <= 0) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } -#ifdef SSL_DEBUG - fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n", - EVP_MD_name(md)); -#endif - if (!EVP_VerifyInit_ex(&mctx, md, NULL) - || !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_EVP_LIB); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - - if (EVP_VerifyFinal(&mctx, p, i, pkey) <= 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_SIGNATURE); - goto f_err; - } - } else -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) { - i = RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md, - MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, p, i, - pkey->pkey.rsa); - if (i < 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_RSA_DECRYPT); - goto f_err; - } - if (i == 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_RSA_SIGNATURE); - goto f_err; - } - } else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) { - j = DSA_verify(pkey->save_type, - &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, p, i, pkey->pkey.dsa); - if (j <= 0) { - /* bad signature */ - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_DSA_SIGNATURE); - goto f_err; - } - } else -#endif -#ifndef OPENSSL_NO_ECDSA - if (pkey->type == EVP_PKEY_EC) { - j = ECDSA_verify(pkey->save_type, - &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, p, i, pkey->pkey.ec); - if (j <= 0) { - /* bad signature */ - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE); - goto f_err; - } - } else -#endif - if (pkey->type == NID_id_GostR3410_94 - || pkey->type == NID_id_GostR3410_2001) { - unsigned char signature[64]; - int idx; - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (pctx == NULL) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_MALLOC_FAILURE); - goto f_err; - } - if (EVP_PKEY_verify_init(pctx) <= 0) { - EVP_PKEY_CTX_free(pctx); - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); - goto f_err; - } - if (i != 64) { -#ifdef SSL_DEBUG - fprintf(stderr, "GOST signature length is %d", i); -#endif - } - for (idx = 0; idx < 64; idx++) { - signature[63 - idx] = p[idx]; - } - j = EVP_PKEY_verify(pctx, signature, 64, s->s3->tmp.cert_verify_md, - 32); - EVP_PKEY_CTX_free(pctx); - if (j <= 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE); - goto f_err; - } - } else { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); - al = SSL_AD_UNSUPPORTED_CERTIFICATE; - goto f_err; - } - - ret = 1; - if (0) { - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - s->state = SSL_ST_ERR; - } - end: - if (s->s3->handshake_buffer) { - BIO_free(s->s3->handshake_buffer); - s->s3->handshake_buffer = NULL; - s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE; - } - EVP_MD_CTX_cleanup(&mctx); - EVP_PKEY_free(pkey); - return (ret); -} - -int ssl3_get_client_certificate(SSL *s) -{ - int i, ok, al, ret = -1; - X509 *x = NULL; - unsigned long l, nc, llen, n; - const unsigned char *p, *q; - unsigned char *d; - STACK_OF(X509) *sk = NULL; - - n = s->method->ssl_get_message(s, - SSL3_ST_SR_CERT_A, - SSL3_ST_SR_CERT_B, - -1, s->max_cert_list, &ok); - - if (!ok) - return ((int)n); - - if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) { - if ((s->verify_mode & SSL_VERIFY_PEER) && - (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - al = SSL_AD_HANDSHAKE_FAILURE; - goto f_err; - } - /* - * If tls asked for a client cert, the client must return a 0 list - */ - if ((s->version > SSL3_VERSION) && s->s3->tmp.cert_request) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); - al = SSL_AD_UNEXPECTED_MESSAGE; - goto f_err; - } - s->s3->tmp.reuse_message = 1; - return (1); - } - - if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_WRONG_MESSAGE_TYPE); - goto f_err; - } - p = d = (unsigned char *)s->init_msg; - - if ((sk = sk_X509_new_null()) == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - - n2l3(p, llen); - if (llen + 3 != n) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - for (nc = 0; nc < llen;) { - if (nc + 3 > llen) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - n2l3(p, l); - if ((l + nc + 3) > llen) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - - q = p; - x = d2i_X509(NULL, &p, l); - if (x == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB); - goto err; - } - if (p != (q + l)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - if (!sk_X509_push(sk, x)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - x = NULL; - nc += l + 3; - } - - if (sk_X509_num(sk) <= 0) { - /* TLS does not mind 0 certs returned */ - if (s->version == SSL3_VERSION) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_NO_CERTIFICATES_RETURNED); - goto f_err; - } - /* Fail for TLS only if we required a certificate */ - else if ((s->verify_mode & SSL_VERIFY_PEER) && - (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - al = SSL_AD_HANDSHAKE_FAILURE; - goto f_err; - } - /* No client certificate so digest cached records */ - if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s)) { - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - } else { - i = ssl_verify_cert_chain(s, sk); - if (i <= 0) { - al = ssl_verify_alarm_type(s->verify_result); - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_CERTIFICATE_VERIFY_FAILED); - goto f_err; - } - } - - if (s->session->peer != NULL) /* This should not be needed */ - X509_free(s->session->peer); - s->session->peer = sk_X509_shift(sk); - s->session->verify_result = s->verify_result; - - /* - * With the current implementation, sess_cert will always be NULL when we - * arrive here. - */ - if (s->session->sess_cert == NULL) { - s->session->sess_cert = ssl_sess_cert_new(); - if (s->session->sess_cert == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - } - if (s->session->sess_cert->cert_chain != NULL) - sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free); - s->session->sess_cert->cert_chain = sk; - /* - * Inconsistency alert: cert_chain does *not* include the peer's own - * certificate, while we do include it in s3_clnt.c - */ - - sk = NULL; - - ret = 1; - if (0) { - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - s->state = SSL_ST_ERR; - } - - if (x != NULL) - X509_free(x); - if (sk != NULL) - sk_X509_pop_free(sk, X509_free); - return (ret); -} - -int ssl3_send_server_certificate(SSL *s) -{ - CERT_PKEY *cpk; - - if (s->state == SSL3_ST_SW_CERT_A) { - cpk = ssl_get_server_send_pkey(s); - if (cpk == NULL) { - /* VRS: allow null cert if auth == KRB5 */ - if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) || - (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, - ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return (0); - } - } - - if (!ssl3_output_cert_chain(s, cpk)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return (0); - } - s->state = SSL3_ST_SW_CERT_B; - } - - /* SSL3_ST_SW_CERT_B */ - return ssl_do_write(s); -} - -#ifndef OPENSSL_NO_TLSEXT -/* send a new session ticket (not necessarily for a new session) */ -int ssl3_send_newsession_ticket(SSL *s) -{ - unsigned char *senc = NULL; - EVP_CIPHER_CTX ctx; - HMAC_CTX hctx; - - if (s->state == SSL3_ST_SW_SESSION_TICKET_A) { - unsigned char *p, *macstart; - const unsigned char *const_p; - int len, slen_full, slen; - SSL_SESSION *sess; - unsigned int hlen; - SSL_CTX *tctx = s->initial_ctx; - unsigned char iv[EVP_MAX_IV_LENGTH]; - unsigned char key_name[16]; - - /* get session encoding length */ - slen_full = i2d_SSL_SESSION(s->session, NULL); - /* - * Some length values are 16 bits, so forget it if session is too - * long - */ - if (slen_full == 0 || slen_full > 0xFF00) { - s->state = SSL_ST_ERR; - return -1; - } - senc = OPENSSL_malloc(slen_full); - if (!senc) { - s->state = SSL_ST_ERR; - return -1; - } - - EVP_CIPHER_CTX_init(&ctx); - HMAC_CTX_init(&hctx); - - p = senc; - if (!i2d_SSL_SESSION(s->session, &p)) - goto err; - - /* - * create a fresh copy (not shared with other threads) to clean up - */ - const_p = senc; - sess = d2i_SSL_SESSION(NULL, &const_p, slen_full); - if (sess == NULL) - goto err; - sess->session_id_length = 0; /* ID is irrelevant for the ticket */ - - slen = i2d_SSL_SESSION(sess, NULL); - if (slen == 0 || slen > slen_full) { /* shouldn't ever happen */ - SSL_SESSION_free(sess); - goto err; - } - p = senc; - if (!i2d_SSL_SESSION(sess, &p)) { - SSL_SESSION_free(sess); - goto err; - } - SSL_SESSION_free(sess); - - /*- - * Grow buffer if need be: the length calculation is as - * follows handshake_header_length + - * 4 (ticket lifetime hint) + 2 (ticket length) + - * 16 (key name) + max_iv_len (iv length) + - * session_length + max_enc_block_size (max encrypted session - * length) + max_md_size (HMAC). - */ - if (!BUF_MEM_grow(s->init_buf, - SSL_HM_HEADER_LENGTH(s) + 22 + EVP_MAX_IV_LENGTH + - EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen)) - goto err; - - p = ssl_handshake_start(s); - /* - * Initialize HMAC and cipher contexts. If callback present it does - * all the work otherwise use generated values from parent ctx. - */ - if (tctx->tlsext_ticket_key_cb) { - /* if 0 is returned, write en empty ticket */ - int ret = tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, - &hctx, 1); - - if (ret == 0) { - l2n(0, p); /* timeout */ - s2n(0, p); /* length */ - ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, - p - ssl_handshake_start(s)); - s->state = SSL3_ST_SW_SESSION_TICKET_B; - OPENSSL_free(senc); - EVP_CIPHER_CTX_cleanup(&ctx); - HMAC_CTX_cleanup(&hctx); - return ssl_do_write(s); - } - if (ret < 0) - goto err; - } else { - if (RAND_bytes(iv, 16) <= 0) - goto err; - if (!EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, - tctx->tlsext_tick_aes_key, iv)) - goto err; - if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, - tlsext_tick_md(), NULL)) - goto err; - memcpy(key_name, tctx->tlsext_tick_key_name, 16); - } - - /* - * Ticket lifetime hint (advisory only): We leave this unspecified - * for resumed session (for simplicity), and guess that tickets for - * new sessions will live as long as their sessions. - */ - l2n(s->hit ? 0 : s->session->timeout, p); - - /* Skip ticket length for now */ - p += 2; - /* Output key name */ - macstart = p; - memcpy(p, key_name, 16); - p += 16; - /* output IV */ - memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); - p += EVP_CIPHER_CTX_iv_length(&ctx); - /* Encrypt session data */ - if (!EVP_EncryptUpdate(&ctx, p, &len, senc, slen)) - goto err; - p += len; - if (!EVP_EncryptFinal(&ctx, p, &len)) - goto err; - p += len; - - if (!HMAC_Update(&hctx, macstart, p - macstart)) - goto err; - if (!HMAC_Final(&hctx, p, &hlen)) - goto err; - - EVP_CIPHER_CTX_cleanup(&ctx); - HMAC_CTX_cleanup(&hctx); - - p += hlen; - /* Now write out lengths: p points to end of data written */ - /* Total length */ - len = p - ssl_handshake_start(s); - /* Skip ticket lifetime hint */ - p = ssl_handshake_start(s) + 4; - s2n(len - 6, p); - ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len); - s->state = SSL3_ST_SW_SESSION_TICKET_B; - OPENSSL_free(senc); - } - - /* SSL3_ST_SW_SESSION_TICKET_B */ - return ssl_do_write(s); - err: - if (senc) - OPENSSL_free(senc); - EVP_CIPHER_CTX_cleanup(&ctx); - HMAC_CTX_cleanup(&hctx); - s->state = SSL_ST_ERR; - return -1; -} - -int ssl3_send_cert_status(SSL *s) -{ - if (s->state == SSL3_ST_SW_CERT_STATUS_A) { - unsigned char *p; - size_t msglen; - - /*- - * Grow buffer if need be: the length calculation is as - * follows handshake_header_length + - * 1 (ocsp response type) + 3 (ocsp response length) - * + (ocsp response) - */ - msglen = 4 + s->tlsext_ocsp_resplen; - if (!BUF_MEM_grow(s->init_buf, SSL_HM_HEADER_LENGTH(s) + msglen)) { - s->state = SSL_ST_ERR; - return -1; - } - - p = ssl_handshake_start(s); - - /* status type */ - *(p++) = s->tlsext_status_type; - /* length of OCSP response */ - l2n3(s->tlsext_ocsp_resplen, p); - /* actual response */ - memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen); - - ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_STATUS, msglen); - } - - /* SSL3_ST_SW_CERT_STATUS_B */ - return (ssl_do_write(s)); -} - -# ifndef OPENSSL_NO_NEXTPROTONEG -/* - * ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. - * It sets the next_proto member in s if found - */ -int ssl3_get_next_proto(SSL *s) -{ - int ok; - int proto_len, padding_len; - long n; - const unsigned char *p; - - /* - * Clients cannot send a NextProtocol message if we didn't see the - * extension in their ClientHello - */ - if (!s->s3->next_proto_neg_seen) { - SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, - SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); - s->state = SSL_ST_ERR; - return -1; - } - - /* See the payload format below */ - n = s->method->ssl_get_message(s, - SSL3_ST_SR_NEXT_PROTO_A, - SSL3_ST_SR_NEXT_PROTO_B, - SSL3_MT_NEXT_PROTO, 514, &ok); - - if (!ok) - return ((int)n); - - /* - * s->state doesn't reflect whether ChangeCipherSpec has been received in - * this handshake, but s->s3->change_cipher_spec does (will be reset by - * ssl3_get_finished). - */ - if (!s->s3->change_cipher_spec) { - SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS); - s->state = SSL_ST_ERR; - return -1; - } - - if (n < 2) { - s->state = SSL_ST_ERR; - return 0; /* The body must be > 1 bytes long */ - } - - p = (unsigned char *)s->init_msg; - - /*- - * The payload looks like: - * uint8 proto_len; - * uint8 proto[proto_len]; - * uint8 padding_len; - * uint8 padding[padding_len]; - */ - proto_len = p[0]; - if (proto_len + 2 > s->init_num) { - s->state = SSL_ST_ERR; - return 0; - } - padding_len = p[proto_len + 1]; - if (proto_len + padding_len + 2 != s->init_num) { - s->state = SSL_ST_ERR; - return 0; - } - - s->next_proto_negotiated = OPENSSL_malloc(proto_len); - if (!s->next_proto_negotiated) { - SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE); - s->state = SSL_ST_ERR; - return 0; - } - memcpy(s->next_proto_negotiated, p + 1, proto_len); - s->next_proto_negotiated_len = proto_len; - - return 1; -} -# endif - -#endif diff --git a/thirdparty/openssl/ssl/ssl_algs.c b/thirdparty/openssl/ssl/ssl_algs.c deleted file mode 100644 index e6f515ff62..0000000000 --- a/thirdparty/openssl/ssl/ssl_algs.c +++ /dev/null @@ -1,155 +0,0 @@ -/* ssl/ssl_algs.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include <openssl/objects.h> -#include <openssl/lhash.h> -#include "ssl_locl.h" - -int SSL_library_init(void) -{ - -#ifndef OPENSSL_NO_DES - EVP_add_cipher(EVP_des_cbc()); - EVP_add_cipher(EVP_des_ede3_cbc()); -#endif -#ifndef OPENSSL_NO_IDEA - EVP_add_cipher(EVP_idea_cbc()); -#endif -#ifndef OPENSSL_NO_RC4 - EVP_add_cipher(EVP_rc4()); -# if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__)) - EVP_add_cipher(EVP_rc4_hmac_md5()); -# endif -#endif -#ifndef OPENSSL_NO_RC2 - EVP_add_cipher(EVP_rc2_cbc()); - /* - * Not actually used for SSL/TLS but this makes PKCS#12 work if an - * application only calls SSL_library_init(). - */ - EVP_add_cipher(EVP_rc2_40_cbc()); -#endif -#ifndef OPENSSL_NO_AES - EVP_add_cipher(EVP_aes_128_cbc()); - EVP_add_cipher(EVP_aes_192_cbc()); - EVP_add_cipher(EVP_aes_256_cbc()); - EVP_add_cipher(EVP_aes_128_gcm()); - EVP_add_cipher(EVP_aes_256_gcm()); -# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) - EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); - EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); -# endif -# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) - EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256()); - EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256()); -# endif - -#endif -#ifndef OPENSSL_NO_CAMELLIA - EVP_add_cipher(EVP_camellia_128_cbc()); - EVP_add_cipher(EVP_camellia_256_cbc()); -#endif - -#ifndef OPENSSL_NO_SEED - EVP_add_cipher(EVP_seed_cbc()); -#endif - -#ifndef OPENSSL_NO_MD5 - EVP_add_digest(EVP_md5()); - EVP_add_digest_alias(SN_md5, "ssl2-md5"); - EVP_add_digest_alias(SN_md5, "ssl3-md5"); -#endif -#ifndef OPENSSL_NO_SHA - EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ - EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); - EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); -#endif -#ifndef OPENSSL_NO_SHA256 - EVP_add_digest(EVP_sha224()); - EVP_add_digest(EVP_sha256()); -#endif -#ifndef OPENSSL_NO_SHA512 - EVP_add_digest(EVP_sha384()); - EVP_add_digest(EVP_sha512()); -#endif -#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA) - EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ - EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); - EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); - EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); -#endif -#ifndef OPENSSL_NO_ECDSA - EVP_add_digest(EVP_ecdsa()); -#endif - /* If you want support for phased out ciphers, add the following */ -#if 0 - EVP_add_digest(EVP_sha()); - EVP_add_digest(EVP_dss()); -#endif -#ifndef OPENSSL_NO_COMP - /* - * This will initialise the built-in compression algorithms. The value - * returned is a STACK_OF(SSL_COMP), but that can be discarded safely - */ - (void)SSL_COMP_get_compression_methods(); -#endif - /* initialize cipher/digest methods table */ - ssl_load_ciphers(); - return (1); -} diff --git a/thirdparty/openssl/ssl/ssl_asn1.c b/thirdparty/openssl/ssl/ssl_asn1.c deleted file mode 100644 index 499f0e85ad..0000000000 --- a/thirdparty/openssl/ssl/ssl_asn1.c +++ /dev/null @@ -1,639 +0,0 @@ -/* ssl/ssl_asn1.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include "ssl_locl.h" -#include <openssl/asn1_mac.h> -#include <openssl/objects.h> -#include <openssl/x509.h> - -typedef struct ssl_session_asn1_st { - ASN1_INTEGER version; - ASN1_INTEGER ssl_version; - ASN1_OCTET_STRING cipher; - ASN1_OCTET_STRING comp_id; - ASN1_OCTET_STRING master_key; - ASN1_OCTET_STRING session_id; - ASN1_OCTET_STRING session_id_context; - ASN1_OCTET_STRING key_arg; -#ifndef OPENSSL_NO_KRB5 - ASN1_OCTET_STRING krb5_princ; -#endif /* OPENSSL_NO_KRB5 */ - ASN1_INTEGER time; - ASN1_INTEGER timeout; - ASN1_INTEGER verify_result; -#ifndef OPENSSL_NO_TLSEXT - ASN1_OCTET_STRING tlsext_hostname; - ASN1_INTEGER tlsext_tick_lifetime; - ASN1_OCTET_STRING tlsext_tick; -#endif /* OPENSSL_NO_TLSEXT */ -#ifndef OPENSSL_NO_PSK - ASN1_OCTET_STRING psk_identity_hint; - ASN1_OCTET_STRING psk_identity; -#endif /* OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_SRP - ASN1_OCTET_STRING srp_username; -#endif /* OPENSSL_NO_SRP */ -} SSL_SESSION_ASN1; - -int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) -{ -#define LSIZE2 (sizeof(long)*2) - int v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0; - unsigned char buf[4], ibuf1[LSIZE2], ibuf2[LSIZE2]; - unsigned char ibuf3[LSIZE2], ibuf4[LSIZE2], ibuf5[LSIZE2]; -#ifndef OPENSSL_NO_TLSEXT - int v6 = 0, v9 = 0, v10 = 0; - unsigned char ibuf6[LSIZE2]; -#endif -#ifndef OPENSSL_NO_PSK - int v7 = 0, v8 = 0; -#endif -#ifndef OPENSSL_NO_COMP - unsigned char cbuf; - int v11 = 0; -#endif -#ifndef OPENSSL_NO_SRP - int v12 = 0; -#endif - long l; - SSL_SESSION_ASN1 a; - M_ASN1_I2D_vars(in); - - if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0))) - return (0); - - /* - * Note that I cheat in the following 2 assignments. I know that if the - * ASN1_INTEGER passed to ASN1_INTEGER_set is > sizeof(long)+1, the - * buffer will not be re-OPENSSL_malloc()ed. This is a bit evil but makes - * things simple, no dynamic allocation to clean up :-) - */ - a.version.length = LSIZE2; - a.version.type = V_ASN1_INTEGER; - a.version.data = ibuf1; - ASN1_INTEGER_set(&(a.version), SSL_SESSION_ASN1_VERSION); - - a.ssl_version.length = LSIZE2; - a.ssl_version.type = V_ASN1_INTEGER; - a.ssl_version.data = ibuf2; - ASN1_INTEGER_set(&(a.ssl_version), in->ssl_version); - - a.cipher.type = V_ASN1_OCTET_STRING; - a.cipher.data = buf; - - if (in->cipher == NULL) - l = in->cipher_id; - else - l = in->cipher->id; - if (in->ssl_version == SSL2_VERSION) { - a.cipher.length = 3; - buf[0] = ((unsigned char)(l >> 16L)) & 0xff; - buf[1] = ((unsigned char)(l >> 8L)) & 0xff; - buf[2] = ((unsigned char)(l)) & 0xff; - } else { - a.cipher.length = 2; - buf[0] = ((unsigned char)(l >> 8L)) & 0xff; - buf[1] = ((unsigned char)(l)) & 0xff; - } - -#ifndef OPENSSL_NO_COMP - if (in->compress_meth) { - cbuf = (unsigned char)in->compress_meth; - a.comp_id.length = 1; - a.comp_id.type = V_ASN1_OCTET_STRING; - a.comp_id.data = &cbuf; - } -#endif - - a.master_key.length = in->master_key_length; - a.master_key.type = V_ASN1_OCTET_STRING; - a.master_key.data = in->master_key; - - a.session_id.length = in->session_id_length; - a.session_id.type = V_ASN1_OCTET_STRING; - a.session_id.data = in->session_id; - - a.session_id_context.length = in->sid_ctx_length; - a.session_id_context.type = V_ASN1_OCTET_STRING; - a.session_id_context.data = in->sid_ctx; - - a.key_arg.length = in->key_arg_length; - a.key_arg.type = V_ASN1_OCTET_STRING; - a.key_arg.data = in->key_arg; - -#ifndef OPENSSL_NO_KRB5 - if (in->krb5_client_princ_len) { - a.krb5_princ.length = in->krb5_client_princ_len; - a.krb5_princ.type = V_ASN1_OCTET_STRING; - a.krb5_princ.data = in->krb5_client_princ; - } -#endif /* OPENSSL_NO_KRB5 */ - - if (in->time != 0L) { - a.time.length = LSIZE2; - a.time.type = V_ASN1_INTEGER; - a.time.data = ibuf3; - ASN1_INTEGER_set(&(a.time), in->time); - } - - if (in->timeout != 0L) { - a.timeout.length = LSIZE2; - a.timeout.type = V_ASN1_INTEGER; - a.timeout.data = ibuf4; - ASN1_INTEGER_set(&(a.timeout), in->timeout); - } - - if (in->verify_result != X509_V_OK) { - a.verify_result.length = LSIZE2; - a.verify_result.type = V_ASN1_INTEGER; - a.verify_result.data = ibuf5; - ASN1_INTEGER_set(&a.verify_result, in->verify_result); - } -#ifndef OPENSSL_NO_TLSEXT - if (in->tlsext_hostname) { - a.tlsext_hostname.length = strlen(in->tlsext_hostname); - a.tlsext_hostname.type = V_ASN1_OCTET_STRING; - a.tlsext_hostname.data = (unsigned char *)in->tlsext_hostname; - } - if (in->tlsext_tick) { - a.tlsext_tick.length = in->tlsext_ticklen; - a.tlsext_tick.type = V_ASN1_OCTET_STRING; - a.tlsext_tick.data = (unsigned char *)in->tlsext_tick; - } - if (in->tlsext_tick_lifetime_hint > 0) { - a.tlsext_tick_lifetime.length = LSIZE2; - a.tlsext_tick_lifetime.type = V_ASN1_INTEGER; - a.tlsext_tick_lifetime.data = ibuf6; - ASN1_INTEGER_set(&a.tlsext_tick_lifetime, - in->tlsext_tick_lifetime_hint); - } -#endif /* OPENSSL_NO_TLSEXT */ -#ifndef OPENSSL_NO_PSK - if (in->psk_identity_hint) { - a.psk_identity_hint.length = strlen(in->psk_identity_hint); - a.psk_identity_hint.type = V_ASN1_OCTET_STRING; - a.psk_identity_hint.data = (unsigned char *)(in->psk_identity_hint); - } - if (in->psk_identity) { - a.psk_identity.length = strlen(in->psk_identity); - a.psk_identity.type = V_ASN1_OCTET_STRING; - a.psk_identity.data = (unsigned char *)(in->psk_identity); - } -#endif /* OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_SRP - if (in->srp_username) { - a.srp_username.length = strlen(in->srp_username); - a.srp_username.type = V_ASN1_OCTET_STRING; - a.srp_username.data = (unsigned char *)(in->srp_username); - } -#endif /* OPENSSL_NO_SRP */ - - M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER); - M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER); - M_ASN1_I2D_len(&(a.cipher), i2d_ASN1_OCTET_STRING); - M_ASN1_I2D_len(&(a.session_id), i2d_ASN1_OCTET_STRING); - M_ASN1_I2D_len(&(a.master_key), i2d_ASN1_OCTET_STRING); -#ifndef OPENSSL_NO_KRB5 - if (in->krb5_client_princ_len) - M_ASN1_I2D_len(&(a.krb5_princ), i2d_ASN1_OCTET_STRING); -#endif /* OPENSSL_NO_KRB5 */ - if (in->key_arg_length > 0) - M_ASN1_I2D_len_IMP_opt(&(a.key_arg), i2d_ASN1_OCTET_STRING); - if (in->time != 0L) - M_ASN1_I2D_len_EXP_opt(&(a.time), i2d_ASN1_INTEGER, 1, v1); - if (in->timeout != 0L) - M_ASN1_I2D_len_EXP_opt(&(a.timeout), i2d_ASN1_INTEGER, 2, v2); - if (in->peer != NULL) - M_ASN1_I2D_len_EXP_opt(in->peer, i2d_X509, 3, v3); - M_ASN1_I2D_len_EXP_opt(&a.session_id_context, i2d_ASN1_OCTET_STRING, 4, - v4); - if (in->verify_result != X509_V_OK) - M_ASN1_I2D_len_EXP_opt(&(a.verify_result), i2d_ASN1_INTEGER, 5, v5); - -#ifndef OPENSSL_NO_TLSEXT - if (in->tlsext_tick_lifetime_hint > 0) - M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER, 9, - v9); - if (in->tlsext_tick) - M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING, 10, - v10); - if (in->tlsext_hostname) - M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING, 6, - v6); -# ifndef OPENSSL_NO_COMP - if (in->compress_meth) - M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING, 11, v11); -# endif -#endif /* OPENSSL_NO_TLSEXT */ -#ifndef OPENSSL_NO_PSK - if (in->psk_identity_hint) - M_ASN1_I2D_len_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING, - 7, v7); - if (in->psk_identity) - M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING, 8, - v8); -#endif /* OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_SRP - if (in->srp_username) - M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING, 12, - v12); -#endif /* OPENSSL_NO_SRP */ - - M_ASN1_I2D_seq_total(); - - M_ASN1_I2D_put(&(a.version), i2d_ASN1_INTEGER); - M_ASN1_I2D_put(&(a.ssl_version), i2d_ASN1_INTEGER); - M_ASN1_I2D_put(&(a.cipher), i2d_ASN1_OCTET_STRING); - M_ASN1_I2D_put(&(a.session_id), i2d_ASN1_OCTET_STRING); - M_ASN1_I2D_put(&(a.master_key), i2d_ASN1_OCTET_STRING); -#ifndef OPENSSL_NO_KRB5 - if (in->krb5_client_princ_len) - M_ASN1_I2D_put(&(a.krb5_princ), i2d_ASN1_OCTET_STRING); -#endif /* OPENSSL_NO_KRB5 */ - if (in->key_arg_length > 0) - M_ASN1_I2D_put_IMP_opt(&(a.key_arg), i2d_ASN1_OCTET_STRING, 0); - if (in->time != 0L) - M_ASN1_I2D_put_EXP_opt(&(a.time), i2d_ASN1_INTEGER, 1, v1); - if (in->timeout != 0L) - M_ASN1_I2D_put_EXP_opt(&(a.timeout), i2d_ASN1_INTEGER, 2, v2); - if (in->peer != NULL) - M_ASN1_I2D_put_EXP_opt(in->peer, i2d_X509, 3, v3); - M_ASN1_I2D_put_EXP_opt(&a.session_id_context, i2d_ASN1_OCTET_STRING, 4, - v4); - if (in->verify_result != X509_V_OK) - M_ASN1_I2D_put_EXP_opt(&a.verify_result, i2d_ASN1_INTEGER, 5, v5); -#ifndef OPENSSL_NO_TLSEXT - if (in->tlsext_hostname) - M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING, 6, - v6); -#endif /* OPENSSL_NO_TLSEXT */ -#ifndef OPENSSL_NO_PSK - if (in->psk_identity_hint) - M_ASN1_I2D_put_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING, - 7, v7); - if (in->psk_identity) - M_ASN1_I2D_put_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING, 8, - v8); -#endif /* OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_TLSEXT - if (in->tlsext_tick_lifetime_hint > 0) - M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER, 9, - v9); - if (in->tlsext_tick) - M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING, 10, - v10); -#endif /* OPENSSL_NO_TLSEXT */ -#ifndef OPENSSL_NO_COMP - if (in->compress_meth) - M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING, 11, v11); -#endif -#ifndef OPENSSL_NO_SRP - if (in->srp_username) - M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING, 12, - v12); -#endif /* OPENSSL_NO_SRP */ - M_ASN1_I2D_finish(); -} - -SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, - long length) -{ - int ssl_version = 0, i; - long id; - ASN1_INTEGER ai, *aip; - ASN1_OCTET_STRING os, *osp; - M_ASN1_D2I_vars(a, SSL_SESSION *, SSL_SESSION_new); - - aip = &ai; - osp = &os; - - M_ASN1_D2I_Init(); - M_ASN1_D2I_start_sequence(); - - ai.data = NULL; - ai.length = 0; - M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER); - if (ai.data != NULL) { - OPENSSL_free(ai.data); - ai.data = NULL; - ai.length = 0; - } - - /* we don't care about the version right now :-) */ - M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER); - ssl_version = (int)ASN1_INTEGER_get(aip); - ret->ssl_version = ssl_version; - if (ai.data != NULL) { - OPENSSL_free(ai.data); - ai.data = NULL; - ai.length = 0; - } - - os.data = NULL; - os.length = 0; - M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING); - if (ssl_version == SSL2_VERSION) { - if (os.length != 3) { - c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH; - c.line = __LINE__; - goto err; - } - id = 0x02000000L | - ((unsigned long)os.data[0] << 16L) | - ((unsigned long)os.data[1] << 8L) | (unsigned long)os.data[2]; - } else if ((ssl_version >> 8) == SSL3_VERSION_MAJOR - || (ssl_version >> 8) == DTLS1_VERSION_MAJOR - || ssl_version == DTLS1_BAD_VER) { - if (os.length != 2) { - c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH; - c.line = __LINE__; - goto err; - } - id = 0x03000000L | - ((unsigned long)os.data[0] << 8L) | (unsigned long)os.data[1]; - } else { - c.error = SSL_R_UNKNOWN_SSL_VERSION; - c.line = __LINE__; - goto err; - } - - ret->cipher = NULL; - ret->cipher_id = id; - - M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING); - if ((ssl_version >> 8) >= SSL3_VERSION_MAJOR) - i = SSL3_MAX_SSL_SESSION_ID_LENGTH; - else /* if (ssl_version>>8 == SSL2_VERSION_MAJOR) */ - i = SSL2_MAX_SSL_SESSION_ID_LENGTH; - - if (os.length > i) - os.length = i; - if (os.length > (int)sizeof(ret->session_id)) /* can't happen */ - os.length = sizeof(ret->session_id); - - ret->session_id_length = os.length; - OPENSSL_assert(os.length <= (int)sizeof(ret->session_id)); - memcpy(ret->session_id, os.data, os.length); - - M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING); - if (os.length > SSL_MAX_MASTER_KEY_LENGTH) - ret->master_key_length = SSL_MAX_MASTER_KEY_LENGTH; - else - ret->master_key_length = os.length; - memcpy(ret->master_key, os.data, ret->master_key_length); - - os.length = 0; - -#ifndef OPENSSL_NO_KRB5 - os.length = 0; - M_ASN1_D2I_get_opt(osp, d2i_ASN1_OCTET_STRING, V_ASN1_OCTET_STRING); - if (os.data) { - if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH) - ret->krb5_client_princ_len = 0; - else - ret->krb5_client_princ_len = os.length; - memcpy(ret->krb5_client_princ, os.data, ret->krb5_client_princ_len); - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - } else - ret->krb5_client_princ_len = 0; -#endif /* OPENSSL_NO_KRB5 */ - - M_ASN1_D2I_get_IMP_opt(osp, d2i_ASN1_OCTET_STRING, 0, - V_ASN1_OCTET_STRING); - if (os.length > SSL_MAX_KEY_ARG_LENGTH) - ret->key_arg_length = SSL_MAX_KEY_ARG_LENGTH; - else - ret->key_arg_length = os.length; - memcpy(ret->key_arg, os.data, ret->key_arg_length); - if (os.data != NULL) - OPENSSL_free(os.data); - - ai.length = 0; - M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 1); - if (ai.data != NULL) { - ret->time = ASN1_INTEGER_get(aip); - OPENSSL_free(ai.data); - ai.data = NULL; - ai.length = 0; - } else - ret->time = (unsigned long)time(NULL); - - ai.length = 0; - M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 2); - if (ai.data != NULL) { - ret->timeout = ASN1_INTEGER_get(aip); - OPENSSL_free(ai.data); - ai.data = NULL; - ai.length = 0; - } else - ret->timeout = 3; - - if (ret->peer != NULL) { - X509_free(ret->peer); - ret->peer = NULL; - } - M_ASN1_D2I_get_EXP_opt(ret->peer, d2i_X509, 3); - - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 4); - - if (os.data != NULL) { - if (os.length > SSL_MAX_SID_CTX_LENGTH) { - c.error = SSL_R_BAD_LENGTH; - c.line = __LINE__; - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - goto err; - } else { - ret->sid_ctx_length = os.length; - memcpy(ret->sid_ctx, os.data, os.length); - } - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - } else - ret->sid_ctx_length = 0; - - ai.length = 0; - M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 5); - if (ai.data != NULL) { - ret->verify_result = ASN1_INTEGER_get(aip); - OPENSSL_free(ai.data); - ai.data = NULL; - ai.length = 0; - } else - ret->verify_result = X509_V_OK; - -#ifndef OPENSSL_NO_TLSEXT - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 6); - if (os.data) { - ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length); - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - } else - ret->tlsext_hostname = NULL; -#endif /* OPENSSL_NO_TLSEXT */ - -#ifndef OPENSSL_NO_PSK - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 7); - if (os.data) { - ret->psk_identity_hint = BUF_strndup((char *)os.data, os.length); - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - } else - ret->psk_identity_hint = NULL; - - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 8); - if (os.data) { - ret->psk_identity = BUF_strndup((char *)os.data, os.length); - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - } else - ret->psk_identity = NULL; -#endif /* OPENSSL_NO_PSK */ - -#ifndef OPENSSL_NO_TLSEXT - ai.length = 0; - M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 9); - if (ai.data != NULL) { - ret->tlsext_tick_lifetime_hint = ASN1_INTEGER_get(aip); - OPENSSL_free(ai.data); - ai.data = NULL; - ai.length = 0; - } else if (ret->tlsext_ticklen && ret->session_id_length) - ret->tlsext_tick_lifetime_hint = -1; - else - ret->tlsext_tick_lifetime_hint = 0; - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 10); - if (os.data) { - ret->tlsext_tick = os.data; - ret->tlsext_ticklen = os.length; - os.data = NULL; - os.length = 0; - } else - ret->tlsext_tick = NULL; -#endif /* OPENSSL_NO_TLSEXT */ -#ifndef OPENSSL_NO_COMP - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 11); - if (os.data) { - ret->compress_meth = os.data[0]; - OPENSSL_free(os.data); - os.data = NULL; - } -#endif - -#ifndef OPENSSL_NO_SRP - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 12); - if (os.data) { - ret->srp_username = BUF_strndup((char *)os.data, os.length); - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - } else - ret->srp_username = NULL; -#endif /* OPENSSL_NO_SRP */ - - M_ASN1_D2I_Finish(a, SSL_SESSION_free, SSL_F_D2I_SSL_SESSION); -} diff --git a/thirdparty/openssl/ssl/ssl_cert.c b/thirdparty/openssl/ssl/ssl_cert.c deleted file mode 100644 index 155728d037..0000000000 --- a/thirdparty/openssl/ssl/ssl_cert.c +++ /dev/null @@ -1,1263 +0,0 @@ -/* - * ! \file ssl/ssl_cert.c - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 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 - * openssl-core@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). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#include <stdio.h> - -#include "e_os.h" -#ifndef NO_SYS_TYPES_H -# include <sys/types.h> -#endif - -#include "o_dir.h" -#include <openssl/objects.h> -#include <openssl/bio.h> -#include <openssl/pem.h> -#include <openssl/x509v3.h> -#ifndef OPENSSL_NO_DH -# include <openssl/dh.h> -#endif -#include <openssl/bn.h> -#include "ssl_locl.h" - -int SSL_get_ex_data_X509_STORE_CTX_idx(void) -{ - static volatile int ssl_x509_store_ctx_idx = -1; - int got_write_lock = 0; - - if (((size_t)&ssl_x509_store_ctx_idx & - (sizeof(ssl_x509_store_ctx_idx) - 1)) - == 0) { /* check alignment, practically always true */ - int ret; - - if ((ret = ssl_x509_store_ctx_idx) < 0) { - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - if ((ret = ssl_x509_store_ctx_idx) < 0) { - ret = ssl_x509_store_ctx_idx = - X509_STORE_CTX_get_ex_new_index(0, - "SSL for verify callback", - NULL, NULL, NULL); - } - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - } - - return ret; - } else { /* commonly eliminated */ - - CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); - - if (ssl_x509_store_ctx_idx < 0) { - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - got_write_lock = 1; - - if (ssl_x509_store_ctx_idx < 0) { - ssl_x509_store_ctx_idx = - X509_STORE_CTX_get_ex_new_index(0, - "SSL for verify callback", - NULL, NULL, NULL); - } - } - - if (got_write_lock) - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - else - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); - - return ssl_x509_store_ctx_idx; - } -} - -void ssl_cert_set_default_md(CERT *cert) -{ - /* Set digest values to defaults */ -#ifndef OPENSSL_NO_DSA - cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); -#endif -#ifndef OPENSSL_NO_RSA - cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); - cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); -#endif -#ifndef OPENSSL_NO_ECDSA - cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); -#endif -} - -CERT *ssl_cert_new(void) -{ - CERT *ret; - - ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); - if (ret == NULL) { - SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); - } - memset(ret, 0, sizeof(CERT)); - - ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]); - ret->references = 1; - ssl_cert_set_default_md(ret); - return (ret); -} - -CERT *ssl_cert_dup(CERT *cert) -{ - CERT *ret; - int i; - - ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); - if (ret == NULL) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); - return (NULL); - } - - memset(ret, 0, sizeof(CERT)); - - ret->references = 1; - ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; - /* - * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that - * more readable - */ - - ret->valid = cert->valid; - ret->mask_k = cert->mask_k; - ret->mask_a = cert->mask_a; - ret->export_mask_k = cert->export_mask_k; - ret->export_mask_a = cert->export_mask_a; - -#ifndef OPENSSL_NO_RSA - if (cert->rsa_tmp != NULL) { - RSA_up_ref(cert->rsa_tmp); - ret->rsa_tmp = cert->rsa_tmp; - } - ret->rsa_tmp_cb = cert->rsa_tmp_cb; -#endif - -#ifndef OPENSSL_NO_DH - if (cert->dh_tmp != NULL) { - ret->dh_tmp = DHparams_dup(cert->dh_tmp); - if (ret->dh_tmp == NULL) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); - goto err; - } - if (cert->dh_tmp->priv_key) { - BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); - if (!b) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); - goto err; - } - ret->dh_tmp->priv_key = b; - } - if (cert->dh_tmp->pub_key) { - BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); - if (!b) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); - goto err; - } - ret->dh_tmp->pub_key = b; - } - } - ret->dh_tmp_cb = cert->dh_tmp_cb; -#endif - -#ifndef OPENSSL_NO_ECDH - if (cert->ecdh_tmp) { - ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); - if (ret->ecdh_tmp == NULL) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB); - goto err; - } - } - ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; - ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; -#endif - - for (i = 0; i < SSL_PKEY_NUM; i++) { - CERT_PKEY *cpk = cert->pkeys + i; - CERT_PKEY *rpk = ret->pkeys + i; - if (cpk->x509 != NULL) { - rpk->x509 = cpk->x509; - CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509); - } - - if (cpk->privatekey != NULL) { - rpk->privatekey = cpk->privatekey; - CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY); - } - - if (cpk->chain) { - rpk->chain = X509_chain_up_ref(cpk->chain); - if (!rpk->chain) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); - goto err; - } - } - rpk->valid_flags = 0; -#ifndef OPENSSL_NO_TLSEXT - if (cert->pkeys[i].serverinfo != NULL) { - /* Just copy everything. */ - ret->pkeys[i].serverinfo = - OPENSSL_malloc(cert->pkeys[i].serverinfo_length); - if (ret->pkeys[i].serverinfo == NULL) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); - goto err; - } - ret->pkeys[i].serverinfo_length = - cert->pkeys[i].serverinfo_length; - memcpy(ret->pkeys[i].serverinfo, - cert->pkeys[i].serverinfo, - cert->pkeys[i].serverinfo_length); - } -#endif - } - - /* - * Set digests to defaults. NB: we don't copy existing values as they - * will be set during handshake. - */ - ssl_cert_set_default_md(ret); - /* Peer sigalgs set to NULL as we get these from handshake too */ - ret->peer_sigalgs = NULL; - ret->peer_sigalgslen = 0; - /* Configured sigalgs however we copy across */ - - if (cert->conf_sigalgs) { - ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen); - if (!ret->conf_sigalgs) - goto err; - memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen); - ret->conf_sigalgslen = cert->conf_sigalgslen; - } else - ret->conf_sigalgs = NULL; - - if (cert->client_sigalgs) { - ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen); - if (!ret->client_sigalgs) - goto err; - memcpy(ret->client_sigalgs, cert->client_sigalgs, - cert->client_sigalgslen); - ret->client_sigalgslen = cert->client_sigalgslen; - } else - ret->client_sigalgs = NULL; - /* Shared sigalgs also NULL */ - ret->shared_sigalgs = NULL; - /* Copy any custom client certificate types */ - if (cert->ctypes) { - ret->ctypes = OPENSSL_malloc(cert->ctype_num); - if (!ret->ctypes) - goto err; - memcpy(ret->ctypes, cert->ctypes, cert->ctype_num); - ret->ctype_num = cert->ctype_num; - } - - ret->cert_flags = cert->cert_flags; - - ret->cert_cb = cert->cert_cb; - ret->cert_cb_arg = cert->cert_cb_arg; - - if (cert->verify_store) { - CRYPTO_add(&cert->verify_store->references, 1, - CRYPTO_LOCK_X509_STORE); - ret->verify_store = cert->verify_store; - } - - if (cert->chain_store) { - CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE); - ret->chain_store = cert->chain_store; - } - - ret->ciphers_raw = NULL; - -#ifndef OPENSSL_NO_TLSEXT - if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext)) - goto err; - if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext)) - goto err; -#endif - - return (ret); - - err: -#ifndef OPENSSL_NO_RSA - if (ret->rsa_tmp != NULL) - RSA_free(ret->rsa_tmp); -#endif -#ifndef OPENSSL_NO_DH - if (ret->dh_tmp != NULL) - DH_free(ret->dh_tmp); -#endif -#ifndef OPENSSL_NO_ECDH - if (ret->ecdh_tmp != NULL) - EC_KEY_free(ret->ecdh_tmp); -#endif - -#ifndef OPENSSL_NO_TLSEXT - custom_exts_free(&ret->cli_ext); - custom_exts_free(&ret->srv_ext); -#endif - - ssl_cert_clear_certs(ret); - OPENSSL_free(ret); - - return NULL; -} - -/* Free up and clear all certificates and chains */ - -void ssl_cert_clear_certs(CERT *c) -{ - int i; - if (c == NULL) - return; - for (i = 0; i < SSL_PKEY_NUM; i++) { - CERT_PKEY *cpk = c->pkeys + i; - if (cpk->x509) { - X509_free(cpk->x509); - cpk->x509 = NULL; - } - if (cpk->privatekey) { - EVP_PKEY_free(cpk->privatekey); - cpk->privatekey = NULL; - } - if (cpk->chain) { - sk_X509_pop_free(cpk->chain, X509_free); - cpk->chain = NULL; - } -#ifndef OPENSSL_NO_TLSEXT - if (cpk->serverinfo) { - OPENSSL_free(cpk->serverinfo); - cpk->serverinfo = NULL; - cpk->serverinfo_length = 0; - } -#endif - /* Clear all flags apart from explicit sign */ - cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN; - } -} - -void ssl_cert_free(CERT *c) -{ - int i; - - if (c == NULL) - return; - - i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT); -#ifdef REF_PRINT - REF_PRINT("CERT", c); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "ssl_cert_free, bad reference count\n"); - abort(); /* ok */ - } -#endif - -#ifndef OPENSSL_NO_RSA - if (c->rsa_tmp) - RSA_free(c->rsa_tmp); -#endif -#ifndef OPENSSL_NO_DH - if (c->dh_tmp) - DH_free(c->dh_tmp); -#endif -#ifndef OPENSSL_NO_ECDH - if (c->ecdh_tmp) - EC_KEY_free(c->ecdh_tmp); -#endif - - ssl_cert_clear_certs(c); - if (c->peer_sigalgs) - OPENSSL_free(c->peer_sigalgs); - if (c->conf_sigalgs) - OPENSSL_free(c->conf_sigalgs); - if (c->client_sigalgs) - OPENSSL_free(c->client_sigalgs); - if (c->shared_sigalgs) - OPENSSL_free(c->shared_sigalgs); - if (c->ctypes) - OPENSSL_free(c->ctypes); - if (c->verify_store) - X509_STORE_free(c->verify_store); - if (c->chain_store) - X509_STORE_free(c->chain_store); - if (c->ciphers_raw) - OPENSSL_free(c->ciphers_raw); -#ifndef OPENSSL_NO_TLSEXT - custom_exts_free(&c->cli_ext); - custom_exts_free(&c->srv_ext); - if (c->alpn_proposed) - OPENSSL_free(c->alpn_proposed); -#endif - OPENSSL_free(c); -} - -int ssl_cert_inst(CERT **o) -{ - /* - * Create a CERT if there isn't already one (which cannot really happen, - * as it is initially created in SSL_CTX_new; but the earlier code - * usually allows for that one being non-existant, so we follow that - * behaviour, as it might turn out that there actually is a reason for it - * -- but I'm not sure that *all* of the existing code could cope with - * s->cert being NULL, otherwise we could do without the initialization - * in SSL_CTX_new). - */ - - if (o == NULL) { - SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (*o == NULL) { - if ((*o = ssl_cert_new()) == NULL) { - SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE); - return (0); - } - } - return (1); -} - -int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain) -{ - CERT_PKEY *cpk = c->key; - if (!cpk) - return 0; - if (cpk->chain) - sk_X509_pop_free(cpk->chain, X509_free); - cpk->chain = chain; - return 1; -} - -int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain) -{ - STACK_OF(X509) *dchain; - if (!chain) - return ssl_cert_set0_chain(c, NULL); - dchain = X509_chain_up_ref(chain); - if (!dchain) - return 0; - if (!ssl_cert_set0_chain(c, dchain)) { - sk_X509_pop_free(dchain, X509_free); - return 0; - } - return 1; -} - -int ssl_cert_add0_chain_cert(CERT *c, X509 *x) -{ - CERT_PKEY *cpk = c->key; - if (!cpk) - return 0; - if (!cpk->chain) - cpk->chain = sk_X509_new_null(); - if (!cpk->chain || !sk_X509_push(cpk->chain, x)) - return 0; - return 1; -} - -int ssl_cert_add1_chain_cert(CERT *c, X509 *x) -{ - if (!ssl_cert_add0_chain_cert(c, x)) - return 0; - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); - return 1; -} - -int ssl_cert_select_current(CERT *c, X509 *x) -{ - int i; - if (x == NULL) - return 0; - for (i = 0; i < SSL_PKEY_NUM; i++) { - CERT_PKEY *cpk = c->pkeys + i; - if (cpk->x509 == x && cpk->privatekey) { - c->key = cpk; - return 1; - } - } - - for (i = 0; i < SSL_PKEY_NUM; i++) { - CERT_PKEY *cpk = c->pkeys + i; - if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) { - c->key = cpk; - return 1; - } - } - return 0; -} - -int ssl_cert_set_current(CERT *c, long op) -{ - int i, idx; - if (!c) - return 0; - if (op == SSL_CERT_SET_FIRST) - idx = 0; - else if (op == SSL_CERT_SET_NEXT) { - idx = (int)(c->key - c->pkeys + 1); - if (idx >= SSL_PKEY_NUM) - return 0; - } else - return 0; - for (i = idx; i < SSL_PKEY_NUM; i++) { - CERT_PKEY *cpk = c->pkeys + i; - if (cpk->x509 && cpk->privatekey) { - c->key = cpk; - return 1; - } - } - return 0; -} - -void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg) -{ - c->cert_cb = cb; - c->cert_cb_arg = arg; -} - -SESS_CERT *ssl_sess_cert_new(void) -{ - SESS_CERT *ret; - - ret = OPENSSL_malloc(sizeof *ret); - if (ret == NULL) { - SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - - memset(ret, 0, sizeof *ret); - ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]); - ret->references = 1; - - return ret; -} - -void ssl_sess_cert_free(SESS_CERT *sc) -{ - int i; - - if (sc == NULL) - return; - - i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT); -#ifdef REF_PRINT - REF_PRINT("SESS_CERT", sc); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "ssl_sess_cert_free, bad reference count\n"); - abort(); /* ok */ - } -#endif - - /* i == 0 */ - if (sc->cert_chain != NULL) - sk_X509_pop_free(sc->cert_chain, X509_free); - for (i = 0; i < SSL_PKEY_NUM; i++) { - if (sc->peer_pkeys[i].x509 != NULL) - X509_free(sc->peer_pkeys[i].x509); -#if 0 /* We don't have the peer's private key. - * These lines are just * here as a reminder - * that we're still using a - * not-quite-appropriate * data structure. */ - if (sc->peer_pkeys[i].privatekey != NULL) - EVP_PKEY_free(sc->peer_pkeys[i].privatekey); -#endif - } - -#ifndef OPENSSL_NO_RSA - if (sc->peer_rsa_tmp != NULL) - RSA_free(sc->peer_rsa_tmp); -#endif -#ifndef OPENSSL_NO_DH - if (sc->peer_dh_tmp != NULL) - DH_free(sc->peer_dh_tmp); -#endif -#ifndef OPENSSL_NO_ECDH - if (sc->peer_ecdh_tmp != NULL) - EC_KEY_free(sc->peer_ecdh_tmp); -#endif - - OPENSSL_free(sc); -} - -int ssl_set_peer_cert_type(SESS_CERT *sc, int type) -{ - sc->peer_cert_type = type; - return (1); -} - -int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) -{ - X509 *x; - int i; - X509_STORE *verify_store; - X509_STORE_CTX ctx; - - if (s->cert->verify_store) - verify_store = s->cert->verify_store; - else - verify_store = s->ctx->cert_store; - - if ((sk == NULL) || (sk_X509_num(sk) == 0)) - return (0); - - x = sk_X509_value(sk, 0); - if (!X509_STORE_CTX_init(&ctx, verify_store, x, sk)) { - SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB); - return (0); - } - /* Set suite B flags if needed */ - X509_STORE_CTX_set_flags(&ctx, tls1_suiteb(s)); -#if 0 - if (SSL_get_verify_depth(s) >= 0) - X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); -#endif - X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s); - - /* - * 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 - * vice versa. - */ - - X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server"); - /* - * Anything non-default in "param" should overwrite anything in the ctx. - */ - X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param); - - if (s->verify_callback) - X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); - - if (s->ctx->app_verify_callback != NULL) -#if 1 /* new with OpenSSL 0.9.7 */ - i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); -#else - i = s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */ -#endif - else { -#ifndef OPENSSL_NO_X509_VERIFY - i = X509_verify_cert(&ctx); -#else - i = 0; - ctx.error = X509_V_ERR_APPLICATION_VERIFICATION; - SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_NO_VERIFY_CALLBACK); -#endif - } - - s->verify_result = ctx.error; - X509_STORE_CTX_cleanup(&ctx); - - return (i); -} - -static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list, - STACK_OF(X509_NAME) *name_list) -{ - if (*ca_list != NULL) - sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); - - *ca_list = name_list; -} - -STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) -{ - int i; - STACK_OF(X509_NAME) *ret; - X509_NAME *name; - - ret = sk_X509_NAME_new_null(); - for (i = 0; i < sk_X509_NAME_num(sk); i++) { - name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); - if ((name == NULL) || !sk_X509_NAME_push(ret, name)) { - sk_X509_NAME_pop_free(ret, X509_NAME_free); - return (NULL); - } - } - return (ret); -} - -void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) -{ - set_client_CA_list(&(s->client_CA), name_list); -} - -void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) -{ - set_client_CA_list(&(ctx->client_CA), name_list); -} - -STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) -{ - return (ctx->client_CA); -} - -STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) -{ - if (s->type == SSL_ST_CONNECT) { /* we are in the client */ - if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL)) - return (s->s3->tmp.ca_names); - else - return (NULL); - } else { - if (s->client_CA != NULL) - return (s->client_CA); - else - return (s->ctx->client_CA); - } -} - -static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) -{ - X509_NAME *name; - - if (x == NULL) - return (0); - if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL)) - return (0); - - if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) - return (0); - - if (!sk_X509_NAME_push(*sk, name)) { - X509_NAME_free(name); - return (0); - } - return (1); -} - -int SSL_add_client_CA(SSL *ssl, X509 *x) -{ - return (add_client_CA(&(ssl->client_CA), x)); -} - -int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) -{ - return (add_client_CA(&(ctx->client_CA), x)); -} - -static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) -{ - return (X509_NAME_cmp(*a, *b)); -} - -#ifndef OPENSSL_NO_STDIO -/** - * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; - * it doesn't really have anything to do with clients (except that a common use - * for a stack of CAs is to send it to the client). Actually, it doesn't have - * much to do with CAs, either, since it will load any old cert. - * \param file the file containing one or more certs. - * \return a ::STACK containing the certs. - */ -STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) -{ - BIO *in; - X509 *x = NULL; - X509_NAME *xn = NULL; - STACK_OF(X509_NAME) *ret = NULL, *sk; - - sk = sk_X509_NAME_new(xname_cmp); - - in = BIO_new(BIO_s_file_internal()); - - if ((sk == NULL) || (in == NULL)) { - SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!BIO_read_filename(in, file)) - goto err; - - for (;;) { - if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) - break; - if (ret == NULL) { - ret = sk_X509_NAME_new_null(); - if (ret == NULL) { - SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); - goto err; - } - } - if ((xn = X509_get_subject_name(x)) == NULL) - goto err; - /* check for duplicates */ - xn = X509_NAME_dup(xn); - if (xn == NULL) - goto err; - if (sk_X509_NAME_find(sk, xn) >= 0) - X509_NAME_free(xn); - else { - sk_X509_NAME_push(sk, xn); - sk_X509_NAME_push(ret, xn); - } - } - - if (0) { - err: - if (ret != NULL) - sk_X509_NAME_pop_free(ret, X509_NAME_free); - ret = NULL; - } - if (sk != NULL) - sk_X509_NAME_free(sk); - if (in != NULL) - BIO_free(in); - if (x != NULL) - X509_free(x); - if (ret != NULL) - ERR_clear_error(); - return (ret); -} -#endif - -/** - * Add a file of certs to a stack. - * \param stack the stack to add to. - * \param file the file to add from. All certs in this file that are not - * already in the stack will be added. - * \return 1 for success, 0 for failure. Note that in the case of failure some - * certs may have been added to \c stack. - */ - -int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, - const char *file) -{ - BIO *in; - X509 *x = NULL; - X509_NAME *xn = NULL; - int ret = 1; - int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b); - - oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); - - in = BIO_new(BIO_s_file_internal()); - - if (in == NULL) { - SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, - ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!BIO_read_filename(in, file)) - goto err; - - for (;;) { - if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) - break; - if ((xn = X509_get_subject_name(x)) == NULL) - goto err; - xn = X509_NAME_dup(xn); - if (xn == NULL) - goto err; - if (sk_X509_NAME_find(stack, xn) >= 0) - X509_NAME_free(xn); - else - sk_X509_NAME_push(stack, xn); - } - - ERR_clear_error(); - - if (0) { - err: - ret = 0; - } - if (in != NULL) - BIO_free(in); - if (x != NULL) - X509_free(x); - - (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); - - return ret; -} - -/** - * Add a directory of certs to a stack. - * \param stack the stack to append to. - * \param dir the directory to append from. All files in this directory will be - * examined as potential certs. Any that are acceptable to - * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be - * included. - * \return 1 for success, 0 for failure. Note that in the case of failure some - * certs may have been added to \c stack. - */ - -int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, - const char *dir) -{ - OPENSSL_DIR_CTX *d = NULL; - const char *filename; - int ret = 0; - - CRYPTO_w_lock(CRYPTO_LOCK_READDIR); - - /* Note that a side effect is that the CAs will be sorted by name */ - - while ((filename = OPENSSL_DIR_read(&d, dir))) { - char buf[1024]; - int r; - - if (strlen(dir) + strlen(filename) + 2 > sizeof buf) { - SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, - SSL_R_PATH_TOO_LONG); - goto err; - } -#ifdef OPENSSL_SYS_VMS - r = BIO_snprintf(buf, sizeof buf, "%s%s", dir, filename); -#else - r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename); -#endif - if (r <= 0 || r >= (int)sizeof(buf)) - goto err; - if (!SSL_add_file_cert_subjects_to_stack(stack, buf)) - goto err; - } - - if (errno) { - SYSerr(SYS_F_OPENDIR, get_last_sys_error()); - ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')"); - SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); - goto err; - } - - ret = 1; - - err: - if (d) - OPENSSL_DIR_end(&d); - CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); - return ret; -} - -/* Add a certificate to a BUF_MEM structure */ - -static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) -{ - int n; - unsigned char *p; - - n = i2d_X509(x, NULL); - if (n < 0 || !BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) { - SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); - return 0; - } - p = (unsigned char *)&(buf->data[*l]); - l2n3(n, p); - n = i2d_X509(x, &p); - if (n < 0) { - /* Shouldn't happen */ - SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); - return 0; - } - *l += n + 3; - - return 1; -} - -/* Add certificate chain to internal SSL BUF_MEM strcuture */ -int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) -{ - BUF_MEM *buf = s->init_buf; - int no_chain; - int i; - - X509 *x; - STACK_OF(X509) *extra_certs; - X509_STORE *chain_store; - - if (cpk) - x = cpk->x509; - else - x = NULL; - - if (s->cert->chain_store) - chain_store = s->cert->chain_store; - else - chain_store = s->ctx->cert_store; - - /* - * If we have a certificate specific chain use it, else use parent ctx. - */ - if (cpk && cpk->chain) - extra_certs = cpk->chain; - else - extra_certs = s->ctx->extra_certs; - - if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs) - no_chain = 1; - else - no_chain = 0; - - /* TLSv1 sends a chain with nothing in it, instead of an alert */ - if (!BUF_MEM_grow_clean(buf, 10)) { - SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_BUF_LIB); - return 0; - } - if (x != NULL) { - if (no_chain) { - if (!ssl_add_cert_to_buf(buf, l, x)) - return 0; - } else { - X509_STORE_CTX xs_ctx; - - if (!X509_STORE_CTX_init(&xs_ctx, chain_store, x, NULL)) { - SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_X509_LIB); - return (0); - } - X509_verify_cert(&xs_ctx); - /* Don't leave errors in the queue */ - ERR_clear_error(); - for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) { - x = sk_X509_value(xs_ctx.chain, i); - - if (!ssl_add_cert_to_buf(buf, l, x)) { - X509_STORE_CTX_cleanup(&xs_ctx); - return 0; - } - } - X509_STORE_CTX_cleanup(&xs_ctx); - } - } - for (i = 0; i < sk_X509_num(extra_certs); i++) { - x = sk_X509_value(extra_certs, i); - if (!ssl_add_cert_to_buf(buf, l, x)) - return 0; - } - - return 1; -} - -/* Build a certificate chain for current certificate */ -int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) -{ - CERT_PKEY *cpk = c->key; - X509_STORE_CTX xs_ctx; - STACK_OF(X509) *chain = NULL, *untrusted = NULL; - X509 *x; - int i, rv = 0; - unsigned long error; - - if (!cpk->x509) { - SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_NO_CERTIFICATE_SET); - goto err; - } - /* Rearranging and check the chain: add everything to a store */ - if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) { - chain_store = X509_STORE_new(); - if (!chain_store) - goto err; - for (i = 0; i < sk_X509_num(cpk->chain); i++) { - x = sk_X509_value(cpk->chain, i); - if (!X509_STORE_add_cert(chain_store, x)) { - error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) != ERR_LIB_X509 || - ERR_GET_REASON(error) != - X509_R_CERT_ALREADY_IN_HASH_TABLE) - goto err; - ERR_clear_error(); - } - } - /* Add EE cert too: it might be self signed */ - if (!X509_STORE_add_cert(chain_store, cpk->x509)) { - error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) != ERR_LIB_X509 || - ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) - goto err; - ERR_clear_error(); - } - } else { - if (c->chain_store) - chain_store = c->chain_store; - - if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED) - untrusted = cpk->chain; - } - - if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted)) { - SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_X509_LIB); - goto err; - } - /* Set suite B flags if needed */ - X509_STORE_CTX_set_flags(&xs_ctx, - c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS); - - i = X509_verify_cert(&xs_ctx); - if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) { - if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR) - ERR_clear_error(); - i = 1; - rv = 2; - } - if (i > 0) - chain = X509_STORE_CTX_get1_chain(&xs_ctx); - if (i <= 0) { - SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_CERTIFICATE_VERIFY_FAILED); - i = X509_STORE_CTX_get_error(&xs_ctx); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(i)); - - X509_STORE_CTX_cleanup(&xs_ctx); - goto err; - } - X509_STORE_CTX_cleanup(&xs_ctx); - if (cpk->chain) - sk_X509_pop_free(cpk->chain, X509_free); - /* Remove EE certificate from chain */ - x = sk_X509_shift(chain); - X509_free(x); - if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT) { - if (sk_X509_num(chain) > 0) { - /* See if last cert is self signed */ - x = sk_X509_value(chain, sk_X509_num(chain) - 1); - X509_check_purpose(x, -1, 0); - if (x->ex_flags & EXFLAG_SS) { - x = sk_X509_pop(chain); - X509_free(x); - } - } - } - cpk->chain = chain; - if (rv == 0) - rv = 1; - err: - if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) - X509_STORE_free(chain_store); - - return rv; -} - -int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref) -{ - X509_STORE **pstore; - if (chain) - pstore = &c->chain_store; - else - pstore = &c->verify_store; - if (*pstore) - X509_STORE_free(*pstore); - *pstore = store; - if (ref && store) - CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); - return 1; -} diff --git a/thirdparty/openssl/ssl/ssl_ciph.c b/thirdparty/openssl/ssl/ssl_ciph.c deleted file mode 100644 index 40021329a9..0000000000 --- a/thirdparty/openssl/ssl/ssl_ciph.c +++ /dev/null @@ -1,2093 +0,0 @@ -/* ssl/ssl_ciph.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 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 - * openssl-core@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). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include <stdio.h> -#include <openssl/objects.h> -#ifndef OPENSSL_NO_COMP -# include <openssl/comp.h> -#endif -#ifndef OPENSSL_NO_ENGINE -# include <openssl/engine.h> -#endif -#include "ssl_locl.h" - -#define SSL_ENC_DES_IDX 0 -#define SSL_ENC_3DES_IDX 1 -#define SSL_ENC_RC4_IDX 2 -#define SSL_ENC_RC2_IDX 3 -#define SSL_ENC_IDEA_IDX 4 -#define SSL_ENC_NULL_IDX 5 -#define SSL_ENC_AES128_IDX 6 -#define SSL_ENC_AES256_IDX 7 -#define SSL_ENC_CAMELLIA128_IDX 8 -#define SSL_ENC_CAMELLIA256_IDX 9 -#define SSL_ENC_GOST89_IDX 10 -#define SSL_ENC_SEED_IDX 11 -#define SSL_ENC_AES128GCM_IDX 12 -#define SSL_ENC_AES256GCM_IDX 13 -#define SSL_ENC_NUM_IDX 14 - -static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL -}; - -#define SSL_COMP_NULL_IDX 0 -#define SSL_COMP_ZLIB_IDX 1 -#define SSL_COMP_NUM_IDX 2 - -static STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; - -#define SSL_MD_MD5_IDX 0 -#define SSL_MD_SHA1_IDX 1 -#define SSL_MD_GOST94_IDX 2 -#define SSL_MD_GOST89MAC_IDX 3 -#define SSL_MD_SHA256_IDX 4 -#define SSL_MD_SHA384_IDX 5 -/* - * Constant SSL_MAX_DIGEST equal to size of digests array should be defined - * in the ssl_locl.h - */ -#define SSL_MD_NUM_IDX SSL_MAX_DIGEST -static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { - NULL, NULL, NULL, NULL, NULL, NULL -}; - -/* - * PKEY_TYPE for GOST89MAC is known in advance, but, because implementation - * is engine-provided, we'll fill it only if corresponding EVP_PKEY_METHOD is - * found - */ -static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { - EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef, - EVP_PKEY_HMAC, EVP_PKEY_HMAC -}; - -static int ssl_mac_secret_size[SSL_MD_NUM_IDX] = { - 0, 0, 0, 0, 0, 0 -}; - -static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX] = { - SSL_HANDSHAKE_MAC_MD5, SSL_HANDSHAKE_MAC_SHA, - SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256, - SSL_HANDSHAKE_MAC_SHA384 -}; - -#define CIPHER_ADD 1 -#define CIPHER_KILL 2 -#define CIPHER_DEL 3 -#define CIPHER_ORD 4 -#define CIPHER_SPECIAL 5 - -typedef struct cipher_order_st { - const SSL_CIPHER *cipher; - int active; - int dead; - struct cipher_order_st *next, *prev; -} CIPHER_ORDER; - -static const SSL_CIPHER cipher_aliases[] = { - /* "ALL" doesn't include eNULL (must be specifically enabled) */ - {0, SSL_TXT_ALL, 0, 0, 0, ~SSL_eNULL, 0, 0, 0, 0, 0, 0}, - /* "COMPLEMENTOFALL" */ - {0, SSL_TXT_CMPALL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, - - /* - * "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in - * ALL!) - */ - {0, SSL_TXT_CMPDEF, 0, 0, 0, 0, 0, 0, SSL_NOT_DEFAULT, 0, 0, 0}, - - /* - * key exchange aliases (some of those using only a single bit here - * combine multiple key exchange algs according to the RFCs, e.g. kEDH - * combines DHE_DSS and DHE_RSA) - */ - {0, SSL_TXT_kRSA, 0, SSL_kRSA, 0, 0, 0, 0, 0, 0, 0, 0}, - - {0, SSL_TXT_kDHr, 0, SSL_kDHr, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kDHd, 0, SSL_kDHd, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kDH, 0, SSL_kDHr | SSL_kDHd, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kEDH, 0, SSL_kEDH, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kDHE, 0, SSL_kEDH, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_DH, 0, SSL_kDHr | SSL_kDHd | SSL_kEDH, 0, 0, 0, 0, 0, 0, 0, - 0}, - - {0, SSL_TXT_kKRB5, 0, SSL_kKRB5, 0, 0, 0, 0, 0, 0, 0, 0}, - - {0, SSL_TXT_kECDHr, 0, SSL_kECDHr, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kECDHe, 0, SSL_kECDHe, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kECDH, 0, SSL_kECDHr | SSL_kECDHe, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kEECDH, 0, SSL_kEECDH, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kECDHE, 0, SSL_kEECDH, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_ECDH, 0, SSL_kECDHr | SSL_kECDHe | SSL_kEECDH, 0, 0, 0, 0, 0, - 0, 0, 0}, - - {0, SSL_TXT_kPSK, 0, SSL_kPSK, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kSRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kGOST, 0, SSL_kGOST, 0, 0, 0, 0, 0, 0, 0, 0}, - - /* server authentication aliases */ - {0, SSL_TXT_aRSA, 0, 0, SSL_aRSA, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aDSS, 0, 0, SSL_aDSS, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_DSS, 0, 0, SSL_aDSS, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aKRB5, 0, 0, SSL_aKRB5, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aNULL, 0, 0, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - /* no such ciphersuites supported! */ - {0, SSL_TXT_aDH, 0, 0, SSL_aDH, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aECDH, 0, 0, SSL_aECDH, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_ECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aPSK, 0, 0, SSL_aPSK, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aGOST94, 0, 0, SSL_aGOST94, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aGOST01, 0, 0, SSL_aGOST01, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aGOST, 0, 0, SSL_aGOST94 | SSL_aGOST01, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aSRP, 0, 0, SSL_aSRP, 0, 0, 0, 0, 0, 0, 0}, - - /* aliases combining key exchange and server authentication */ - {0, SSL_TXT_EDH, 0, SSL_kEDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_DHE, 0, SSL_kEDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_EECDH, 0, SSL_kEECDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_ECDHE, 0, SSL_kEECDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_NULL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_KRB5, 0, SSL_kKRB5, SSL_aKRB5, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_RSA, 0, SSL_kRSA, SSL_aRSA, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_ADH, 0, SSL_kEDH, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_AECDH, 0, SSL_kEECDH, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_PSK, 0, SSL_kPSK, SSL_aPSK, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_SRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0}, - - /* symmetric encryption aliases */ - {0, SSL_TXT_DES, 0, 0, 0, SSL_DES, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_3DES, 0, 0, 0, SSL_3DES, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_RC4, 0, 0, 0, SSL_RC4, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_RC2, 0, 0, 0, SSL_RC2, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_IDEA, 0, 0, 0, SSL_IDEA, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_SEED, 0, 0, 0, SSL_SEED, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_eNULL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_AES128, 0, 0, 0, SSL_AES128 | SSL_AES128GCM, 0, 0, 0, 0, 0, - 0}, - {0, SSL_TXT_AES256, 0, 0, 0, SSL_AES256 | SSL_AES256GCM, 0, 0, 0, 0, 0, - 0}, - {0, SSL_TXT_AES, 0, 0, 0, SSL_AES, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_AES_GCM, 0, 0, 0, SSL_AES128GCM | SSL_AES256GCM, 0, 0, 0, 0, - 0, 0}, - {0, SSL_TXT_CAMELLIA128, 0, 0, 0, SSL_CAMELLIA128, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_CAMELLIA256, 0, 0, 0, SSL_CAMELLIA256, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_CAMELLIA, 0, 0, 0, SSL_CAMELLIA128 | SSL_CAMELLIA256, 0, 0, 0, - 0, 0, 0}, - - /* MAC aliases */ - {0, SSL_TXT_MD5, 0, 0, 0, 0, SSL_MD5, 0, 0, 0, 0, 0}, - {0, SSL_TXT_SHA1, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0}, - {0, SSL_TXT_SHA, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0}, - {0, SSL_TXT_GOST94, 0, 0, 0, 0, SSL_GOST94, 0, 0, 0, 0, 0}, - {0, SSL_TXT_GOST89MAC, 0, 0, 0, 0, SSL_GOST89MAC, 0, 0, 0, 0, 0}, - {0, SSL_TXT_SHA256, 0, 0, 0, 0, SSL_SHA256, 0, 0, 0, 0, 0}, - {0, SSL_TXT_SHA384, 0, 0, 0, 0, SSL_SHA384, 0, 0, 0, 0, 0}, - - /* protocol version aliases */ - {0, SSL_TXT_SSLV2, 0, 0, 0, 0, 0, SSL_SSLV2, 0, 0, 0, 0}, - {0, SSL_TXT_SSLV3, 0, 0, 0, 0, 0, SSL_SSLV3, 0, 0, 0, 0}, - {0, SSL_TXT_TLSV1, 0, 0, 0, 0, 0, SSL_TLSV1, 0, 0, 0, 0}, - {0, SSL_TXT_TLSV1_2, 0, 0, 0, 0, 0, SSL_TLSV1_2, 0, 0, 0, 0}, - - /* export flag */ - {0, SSL_TXT_EXP, 0, 0, 0, 0, 0, 0, SSL_EXPORT, 0, 0, 0}, - {0, SSL_TXT_EXPORT, 0, 0, 0, 0, 0, 0, SSL_EXPORT, 0, 0, 0}, - - /* strength classes */ - {0, SSL_TXT_EXP40, 0, 0, 0, 0, 0, 0, SSL_EXP40, 0, 0, 0}, - {0, SSL_TXT_EXP56, 0, 0, 0, 0, 0, 0, SSL_EXP56, 0, 0, 0}, - {0, SSL_TXT_LOW, 0, 0, 0, 0, 0, 0, SSL_LOW, 0, 0, 0}, - {0, SSL_TXT_MEDIUM, 0, 0, 0, 0, 0, 0, SSL_MEDIUM, 0, 0, 0}, - {0, SSL_TXT_HIGH, 0, 0, 0, 0, 0, 0, SSL_HIGH, 0, 0, 0}, - /* FIPS 140-2 approved ciphersuite */ - {0, SSL_TXT_FIPS, 0, 0, 0, ~SSL_eNULL, 0, 0, SSL_FIPS, 0, 0, 0}, - /* "DHE-" aliases to "EDH-" labels (for forward compatibility) */ - {0, SSL3_TXT_DHE_DSS_DES_40_CBC_SHA, 0, - SSL_kDHE, SSL_aDSS, SSL_DES, SSL_SHA1, SSL_SSLV3, SSL_EXPORT | SSL_EXP40, - 0, 0, 0,}, - {0, SSL3_TXT_DHE_DSS_DES_64_CBC_SHA, 0, - SSL_kDHE, SSL_aDSS, SSL_DES, SSL_SHA1, SSL_SSLV3, SSL_NOT_EXP | SSL_LOW, - 0, 0, 0,}, - {0, SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA, 0, - SSL_kDHE, SSL_aDSS, SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, 0, 0, 0,}, - {0, SSL3_TXT_DHE_RSA_DES_40_CBC_SHA, 0, - SSL_kDHE, SSL_aRSA, SSL_DES, SSL_SHA1, SSL_SSLV3, SSL_EXPORT | SSL_EXP40, - 0, 0, 0,}, - {0, SSL3_TXT_DHE_RSA_DES_64_CBC_SHA, 0, - SSL_kDHE, SSL_aRSA, SSL_DES, SSL_SHA1, SSL_SSLV3, SSL_NOT_EXP | SSL_LOW, - 0, 0, 0,}, - {0, SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA, 0, - SSL_kDHE, SSL_aRSA, SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, 0, 0, 0,}, -}; - -/* - * Search for public key algorithm with given name and return its pkey_id if - * it is available. Otherwise return 0 - */ -#ifdef OPENSSL_NO_ENGINE - -static int get_optional_pkey_id(const char *pkey_name) -{ - const EVP_PKEY_ASN1_METHOD *ameth; - int pkey_id = 0; - ameth = EVP_PKEY_asn1_find_str(NULL, pkey_name, -1); - if (ameth && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, - ameth) > 0) { - return pkey_id; - } - return 0; -} - -#else - -static int get_optional_pkey_id(const char *pkey_name) -{ - const EVP_PKEY_ASN1_METHOD *ameth; - ENGINE *tmpeng = NULL; - int pkey_id = 0; - ameth = EVP_PKEY_asn1_find_str(&tmpeng, pkey_name, -1); - if (ameth) { - if (EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, - ameth) <= 0) - pkey_id = 0; - } - if (tmpeng) - ENGINE_finish(tmpeng); - return pkey_id; -} - -#endif - -void ssl_load_ciphers(void) -{ - ssl_cipher_methods[SSL_ENC_DES_IDX] = EVP_get_cipherbyname(SN_des_cbc); - ssl_cipher_methods[SSL_ENC_3DES_IDX] = - EVP_get_cipherbyname(SN_des_ede3_cbc); - ssl_cipher_methods[SSL_ENC_RC4_IDX] = EVP_get_cipherbyname(SN_rc4); - ssl_cipher_methods[SSL_ENC_RC2_IDX] = EVP_get_cipherbyname(SN_rc2_cbc); -#ifndef OPENSSL_NO_IDEA - ssl_cipher_methods[SSL_ENC_IDEA_IDX] = EVP_get_cipherbyname(SN_idea_cbc); -#else - ssl_cipher_methods[SSL_ENC_IDEA_IDX] = NULL; -#endif - ssl_cipher_methods[SSL_ENC_AES128_IDX] = - EVP_get_cipherbyname(SN_aes_128_cbc); - ssl_cipher_methods[SSL_ENC_AES256_IDX] = - EVP_get_cipherbyname(SN_aes_256_cbc); - ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] = - EVP_get_cipherbyname(SN_camellia_128_cbc); - ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] = - EVP_get_cipherbyname(SN_camellia_256_cbc); - ssl_cipher_methods[SSL_ENC_GOST89_IDX] = - EVP_get_cipherbyname(SN_gost89_cnt); - ssl_cipher_methods[SSL_ENC_SEED_IDX] = EVP_get_cipherbyname(SN_seed_cbc); - - ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] = - EVP_get_cipherbyname(SN_aes_128_gcm); - ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] = - EVP_get_cipherbyname(SN_aes_256_gcm); - - ssl_digest_methods[SSL_MD_MD5_IDX] = EVP_get_digestbyname(SN_md5); - ssl_mac_secret_size[SSL_MD_MD5_IDX] = - EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]); - OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0); - ssl_digest_methods[SSL_MD_SHA1_IDX] = EVP_get_digestbyname(SN_sha1); - ssl_mac_secret_size[SSL_MD_SHA1_IDX] = - EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]); - OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0); - ssl_digest_methods[SSL_MD_GOST94_IDX] = - EVP_get_digestbyname(SN_id_GostR3411_94); - if (ssl_digest_methods[SSL_MD_GOST94_IDX]) { - ssl_mac_secret_size[SSL_MD_GOST94_IDX] = - EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]); - OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0); - } - ssl_digest_methods[SSL_MD_GOST89MAC_IDX] = - EVP_get_digestbyname(SN_id_Gost28147_89_MAC); - ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac"); - if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) { - ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32; - } - - ssl_digest_methods[SSL_MD_SHA256_IDX] = EVP_get_digestbyname(SN_sha256); - ssl_mac_secret_size[SSL_MD_SHA256_IDX] = - EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]); - ssl_digest_methods[SSL_MD_SHA384_IDX] = EVP_get_digestbyname(SN_sha384); - ssl_mac_secret_size[SSL_MD_SHA384_IDX] = - EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]); -} - -#ifndef OPENSSL_NO_COMP - -static int sk_comp_cmp(const SSL_COMP *const *a, const SSL_COMP *const *b) -{ - return ((*a)->id - (*b)->id); -} - -static void load_builtin_compressions(void) -{ - int got_write_lock = 0; - - CRYPTO_r_lock(CRYPTO_LOCK_SSL); - if (ssl_comp_methods == NULL) { - CRYPTO_r_unlock(CRYPTO_LOCK_SSL); - CRYPTO_w_lock(CRYPTO_LOCK_SSL); - got_write_lock = 1; - - if (ssl_comp_methods == NULL) { - SSL_COMP *comp = NULL; - - MemCheck_off(); - ssl_comp_methods = sk_SSL_COMP_new(sk_comp_cmp); - if (ssl_comp_methods != NULL) { - comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); - if (comp != NULL) { - comp->method = COMP_zlib(); - if (comp->method && comp->method->type == NID_undef) - OPENSSL_free(comp); - else { - comp->id = SSL_COMP_ZLIB_IDX; - comp->name = comp->method->name; - sk_SSL_COMP_push(ssl_comp_methods, comp); - } - } - sk_SSL_COMP_sort(ssl_comp_methods); - } - MemCheck_on(); - } - } - - if (got_write_lock) - CRYPTO_w_unlock(CRYPTO_LOCK_SSL); - else - CRYPTO_r_unlock(CRYPTO_LOCK_SSL); -} -#endif - -int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, - const EVP_MD **md, int *mac_pkey_type, - int *mac_secret_size, SSL_COMP **comp) -{ - int i; - const SSL_CIPHER *c; - - c = s->cipher; - if (c == NULL) - return (0); - if (comp != NULL) { - SSL_COMP ctmp; -#ifndef OPENSSL_NO_COMP - load_builtin_compressions(); -#endif - - *comp = NULL; - ctmp.id = s->compress_meth; - if (ssl_comp_methods != NULL) { - i = sk_SSL_COMP_find(ssl_comp_methods, &ctmp); - if (i >= 0) - *comp = sk_SSL_COMP_value(ssl_comp_methods, i); - else - *comp = NULL; - } - } - - if ((enc == NULL) || (md == NULL)) - return (0); - - switch (c->algorithm_enc) { - case SSL_DES: - i = SSL_ENC_DES_IDX; - break; - case SSL_3DES: - i = SSL_ENC_3DES_IDX; - break; - case SSL_RC4: - i = SSL_ENC_RC4_IDX; - break; - case SSL_RC2: - i = SSL_ENC_RC2_IDX; - break; - case SSL_IDEA: - i = SSL_ENC_IDEA_IDX; - break; - case SSL_eNULL: - i = SSL_ENC_NULL_IDX; - break; - case SSL_AES128: - i = SSL_ENC_AES128_IDX; - break; - case SSL_AES256: - i = SSL_ENC_AES256_IDX; - break; - case SSL_CAMELLIA128: - i = SSL_ENC_CAMELLIA128_IDX; - break; - case SSL_CAMELLIA256: - i = SSL_ENC_CAMELLIA256_IDX; - break; - case SSL_eGOST2814789CNT: - i = SSL_ENC_GOST89_IDX; - break; - case SSL_SEED: - i = SSL_ENC_SEED_IDX; - break; - case SSL_AES128GCM: - i = SSL_ENC_AES128GCM_IDX; - break; - case SSL_AES256GCM: - i = SSL_ENC_AES256GCM_IDX; - break; - default: - i = -1; - break; - } - - if ((i < 0) || (i >= SSL_ENC_NUM_IDX)) - *enc = NULL; - else { - if (i == SSL_ENC_NULL_IDX) - *enc = EVP_enc_null(); - else - *enc = ssl_cipher_methods[i]; - } - - switch (c->algorithm_mac) { - case SSL_MD5: - i = SSL_MD_MD5_IDX; - break; - case SSL_SHA1: - i = SSL_MD_SHA1_IDX; - break; - case SSL_SHA256: - i = SSL_MD_SHA256_IDX; - break; - case SSL_SHA384: - i = SSL_MD_SHA384_IDX; - break; - case SSL_GOST94: - i = SSL_MD_GOST94_IDX; - break; - case SSL_GOST89MAC: - i = SSL_MD_GOST89MAC_IDX; - break; - default: - i = -1; - break; - } - if ((i < 0) || (i >= SSL_MD_NUM_IDX)) { - *md = NULL; - if (mac_pkey_type != NULL) - *mac_pkey_type = NID_undef; - if (mac_secret_size != NULL) - *mac_secret_size = 0; - if (c->algorithm_mac == SSL_AEAD) - mac_pkey_type = NULL; - } else { - *md = ssl_digest_methods[i]; - if (mac_pkey_type != NULL) - *mac_pkey_type = ssl_mac_pkey_id[i]; - if (mac_secret_size != NULL) - *mac_secret_size = ssl_mac_secret_size[i]; - } - - if ((*enc != NULL) && - (*md != NULL || (EVP_CIPHER_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER)) - && (!mac_pkey_type || *mac_pkey_type != NID_undef)) { - const EVP_CIPHER *evp; - - if (s->ssl_version >> 8 != TLS1_VERSION_MAJOR || - s->ssl_version < TLS1_VERSION) - return 1; - -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return 1; -#endif - - if (c->algorithm_enc == SSL_RC4 && - c->algorithm_mac == SSL_MD5 && - (evp = EVP_get_cipherbyname("RC4-HMAC-MD5"))) - *enc = evp, *md = NULL; - else if (c->algorithm_enc == SSL_AES128 && - c->algorithm_mac == SSL_SHA1 && - (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1"))) - *enc = evp, *md = NULL; - else if (c->algorithm_enc == SSL_AES256 && - c->algorithm_mac == SSL_SHA1 && - (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1"))) - *enc = evp, *md = NULL; - else if (c->algorithm_enc == SSL_AES128 && - c->algorithm_mac == SSL_SHA256 && - (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA256"))) - *enc = evp, *md = NULL; - else if (c->algorithm_enc == SSL_AES256 && - c->algorithm_mac == SSL_SHA256 && - (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA256"))) - *enc = evp, *md = NULL; - return (1); - } else - return (0); -} - -int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) -{ - if (idx < 0 || idx >= SSL_MD_NUM_IDX) { - return 0; - } - *mask = ssl_handshake_digest_flag[idx]; - if (*mask) - *md = ssl_digest_methods[idx]; - else - *md = NULL; - return 1; -} - -#define ITEM_SEP(a) \ - (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) - -static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, - CIPHER_ORDER **tail) -{ - if (curr == *tail) - return; - if (curr == *head) - *head = curr->next; - if (curr->prev != NULL) - curr->prev->next = curr->next; - if (curr->next != NULL) - curr->next->prev = curr->prev; - (*tail)->next = curr; - curr->prev = *tail; - curr->next = NULL; - *tail = curr; -} - -static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr, - CIPHER_ORDER **tail) -{ - if (curr == *head) - return; - if (curr == *tail) - *tail = curr->prev; - if (curr->next != NULL) - curr->next->prev = curr->prev; - if (curr->prev != NULL) - curr->prev->next = curr->next; - (*head)->prev = curr; - curr->next = *head; - curr->prev = NULL; - *head = curr; -} - -static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, - unsigned long *enc, unsigned long *mac, - unsigned long *ssl) -{ - *mkey = 0; - *auth = 0; - *enc = 0; - *mac = 0; - *ssl = 0; - -#ifdef OPENSSL_NO_RSA - *mkey |= SSL_kRSA; - *auth |= SSL_aRSA; -#endif -#ifdef OPENSSL_NO_DSA - *auth |= SSL_aDSS; -#endif -#ifdef OPENSSL_NO_DH - *mkey |= SSL_kDHr | SSL_kDHd | SSL_kEDH; - *auth |= SSL_aDH; -#endif -#ifdef OPENSSL_NO_KRB5 - *mkey |= SSL_kKRB5; - *auth |= SSL_aKRB5; -#endif -#ifdef OPENSSL_NO_ECDSA - *auth |= SSL_aECDSA; -#endif -#ifdef OPENSSL_NO_ECDH - *mkey |= SSL_kECDHe | SSL_kECDHr; - *auth |= SSL_aECDH; -#endif -#ifdef OPENSSL_NO_PSK - *mkey |= SSL_kPSK; - *auth |= SSL_aPSK; -#endif -#ifdef OPENSSL_NO_SRP - *mkey |= SSL_kSRP; -#endif - /* - * Check for presence of GOST 34.10 algorithms, and if they do not - * present, disable appropriate auth and key exchange - */ - if (!get_optional_pkey_id("gost94")) { - *auth |= SSL_aGOST94; - } - if (!get_optional_pkey_id("gost2001")) { - *auth |= SSL_aGOST01; - } - /* - * Disable GOST key exchange if no GOST signature algs are available * - */ - if ((*auth & (SSL_aGOST94 | SSL_aGOST01)) == (SSL_aGOST94 | SSL_aGOST01)) { - *mkey |= SSL_kGOST; - } -#ifdef SSL_FORBID_ENULL - *enc |= SSL_eNULL; -#endif - - *enc |= (ssl_cipher_methods[SSL_ENC_DES_IDX] == NULL) ? SSL_DES : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_RC4_IDX] == NULL) ? SSL_RC4 : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_RC2_IDX] == NULL) ? SSL_RC2 : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128 : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256 : 0; - *enc |= - (ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] == - NULL) ? SSL_AES128GCM : 0; - *enc |= - (ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] == - NULL) ? SSL_AES256GCM : 0; - *enc |= - (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == - NULL) ? SSL_CAMELLIA128 : 0; - *enc |= - (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == - NULL) ? SSL_CAMELLIA256 : 0; - *enc |= - (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == - NULL) ? SSL_eGOST2814789CNT : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED : 0; - - *mac |= (ssl_digest_methods[SSL_MD_MD5_IDX] == NULL) ? SSL_MD5 : 0; - *mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1 : 0; - *mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256 : 0; - *mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384 : 0; - *mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94 : 0; - *mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL - || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] == - NID_undef) ? SSL_GOST89MAC : 0; - -} - -static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, - int num_of_ciphers, - unsigned long disabled_mkey, - unsigned long disabled_auth, - unsigned long disabled_enc, - unsigned long disabled_mac, - unsigned long disabled_ssl, - CIPHER_ORDER *co_list, - CIPHER_ORDER **head_p, - CIPHER_ORDER **tail_p) -{ - int i, co_list_num; - const SSL_CIPHER *c; - - /* - * We have num_of_ciphers descriptions compiled in, depending on the - * method selected (SSLv2 and/or SSLv3, TLSv1 etc). - * These will later be sorted in a linked list with at most num - * entries. - */ - - /* Get the initial list of ciphers */ - co_list_num = 0; /* actual count of ciphers */ - for (i = 0; i < num_of_ciphers; i++) { - c = ssl_method->get_cipher(i); - /* drop those that use any of that is not available */ - if ((c != NULL) && c->valid && -#ifdef OPENSSL_FIPS - (!FIPS_mode() || (c->algo_strength & SSL_FIPS)) && -#endif - !(c->algorithm_mkey & disabled_mkey) && - !(c->algorithm_auth & disabled_auth) && - !(c->algorithm_enc & disabled_enc) && - !(c->algorithm_mac & disabled_mac) && - !(c->algorithm_ssl & disabled_ssl)) { - co_list[co_list_num].cipher = c; - co_list[co_list_num].next = NULL; - co_list[co_list_num].prev = NULL; - co_list[co_list_num].active = 0; - co_list_num++; -#ifdef KSSL_DEBUG - fprintf(stderr, "\t%d: %s %lx %lx %lx\n", i, c->name, c->id, - c->algorithm_mkey, c->algorithm_auth); -#endif /* KSSL_DEBUG */ - /* - * if (!sk_push(ca_list,(char *)c)) goto err; - */ - } - } - - /* - * Prepare linked list from list entries - */ - if (co_list_num > 0) { - co_list[0].prev = NULL; - - if (co_list_num > 1) { - co_list[0].next = &co_list[1]; - - for (i = 1; i < co_list_num - 1; i++) { - co_list[i].prev = &co_list[i - 1]; - co_list[i].next = &co_list[i + 1]; - } - - co_list[co_list_num - 1].prev = &co_list[co_list_num - 2]; - } - - co_list[co_list_num - 1].next = NULL; - - *head_p = &co_list[0]; - *tail_p = &co_list[co_list_num - 1]; - } -} - -static void ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list, - int num_of_group_aliases, - unsigned long disabled_mkey, - unsigned long disabled_auth, - unsigned long disabled_enc, - unsigned long disabled_mac, - unsigned long disabled_ssl, - CIPHER_ORDER *head) -{ - CIPHER_ORDER *ciph_curr; - const SSL_CIPHER **ca_curr; - int i; - unsigned long mask_mkey = ~disabled_mkey; - unsigned long mask_auth = ~disabled_auth; - unsigned long mask_enc = ~disabled_enc; - unsigned long mask_mac = ~disabled_mac; - unsigned long mask_ssl = ~disabled_ssl; - - /* - * First, add the real ciphers as already collected - */ - ciph_curr = head; - ca_curr = ca_list; - while (ciph_curr != NULL) { - *ca_curr = ciph_curr->cipher; - ca_curr++; - ciph_curr = ciph_curr->next; - } - - /* - * Now we add the available ones from the cipher_aliases[] table. - * They represent either one or more algorithms, some of which - * in any affected category must be supported (set in enabled_mask), - * or represent a cipher strength value (will be added in any case because algorithms=0). - */ - for (i = 0; i < num_of_group_aliases; i++) { - unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey; - unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth; - unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc; - unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac; - unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl; - - if (algorithm_mkey) - if ((algorithm_mkey & mask_mkey) == 0) - continue; - - if (algorithm_auth) - if ((algorithm_auth & mask_auth) == 0) - continue; - - if (algorithm_enc) - if ((algorithm_enc & mask_enc) == 0) - continue; - - if (algorithm_mac) - if ((algorithm_mac & mask_mac) == 0) - continue; - - if (algorithm_ssl) - if ((algorithm_ssl & mask_ssl) == 0) - continue; - - *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); - ca_curr++; - } - - *ca_curr = NULL; /* end of list */ -} - -static void ssl_cipher_apply_rule(unsigned long cipher_id, - unsigned long alg_mkey, - unsigned long alg_auth, - unsigned long alg_enc, - unsigned long alg_mac, - unsigned long alg_ssl, - unsigned long algo_strength, int rule, - int strength_bits, CIPHER_ORDER **head_p, - CIPHER_ORDER **tail_p) -{ - CIPHER_ORDER *head, *tail, *curr, *next, *last; - const SSL_CIPHER *cp; - int reverse = 0; - -#ifdef CIPHER_DEBUG - fprintf(stderr, - "Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n", - rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, - algo_strength, strength_bits); -#endif - - if (rule == CIPHER_DEL) - reverse = 1; /* needed to maintain sorting between - * currently deleted ciphers */ - - head = *head_p; - tail = *tail_p; - - if (reverse) { - next = tail; - last = head; - } else { - next = head; - last = tail; - } - - curr = NULL; - for (;;) { - if (curr == last) - break; - - curr = next; - - if (curr == NULL) - break; - - next = reverse ? curr->prev : curr->next; - - cp = curr->cipher; - - /* - * Selection criteria is either the value of strength_bits - * or the algorithms used. - */ - if (strength_bits >= 0) { - if (strength_bits != cp->strength_bits) - continue; - } else { -#ifdef CIPHER_DEBUG - fprintf(stderr, - "\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", - cp->name, cp->algorithm_mkey, cp->algorithm_auth, - cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, - cp->algo_strength); -#endif -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - if (cipher_id && cipher_id != cp->id) - continue; -#endif - if (alg_mkey && !(alg_mkey & cp->algorithm_mkey)) - continue; - if (alg_auth && !(alg_auth & cp->algorithm_auth)) - continue; - if (alg_enc && !(alg_enc & cp->algorithm_enc)) - continue; - if (alg_mac && !(alg_mac & cp->algorithm_mac)) - continue; - if (alg_ssl && !(alg_ssl & cp->algorithm_ssl)) - continue; - if ((algo_strength & SSL_EXP_MASK) - && !(algo_strength & SSL_EXP_MASK & cp->algo_strength)) - continue; - if ((algo_strength & SSL_STRONG_MASK) - && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength)) - continue; - if ((algo_strength & SSL_NOT_DEFAULT) - && !(cp->algo_strength & SSL_NOT_DEFAULT)) - continue; - } - -#ifdef CIPHER_DEBUG - fprintf(stderr, "Action = %d\n", rule); -#endif - - /* add the cipher if it has not been added yet. */ - if (rule == CIPHER_ADD) { - /* reverse == 0 */ - if (!curr->active) { - ll_append_tail(&head, curr, &tail); - curr->active = 1; - } - } - /* Move the added cipher to this location */ - else if (rule == CIPHER_ORD) { - /* reverse == 0 */ - if (curr->active) { - ll_append_tail(&head, curr, &tail); - } - } else if (rule == CIPHER_DEL) { - /* reverse == 1 */ - if (curr->active) { - /* - * most recently deleted ciphersuites get best positions for - * any future CIPHER_ADD (note that the CIPHER_DEL loop works - * in reverse to maintain the order) - */ - ll_append_head(&head, curr, &tail); - curr->active = 0; - } - } else if (rule == CIPHER_KILL) { - /* reverse == 0 */ - if (head == curr) - head = curr->next; - else - curr->prev->next = curr->next; - if (tail == curr) - tail = curr->prev; - curr->active = 0; - if (curr->next != NULL) - curr->next->prev = curr->prev; - if (curr->prev != NULL) - curr->prev->next = curr->next; - curr->next = NULL; - curr->prev = NULL; - } - } - - *head_p = head; - *tail_p = tail; -} - -static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, - CIPHER_ORDER **tail_p) -{ - int max_strength_bits, i, *number_uses; - CIPHER_ORDER *curr; - - /* - * This routine sorts the ciphers with descending strength. The sorting - * must keep the pre-sorted sequence, so we apply the normal sorting - * routine as '+' movement to the end of the list. - */ - max_strength_bits = 0; - curr = *head_p; - while (curr != NULL) { - if (curr->active && (curr->cipher->strength_bits > max_strength_bits)) - max_strength_bits = curr->cipher->strength_bits; - curr = curr->next; - } - - number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int)); - if (!number_uses) { - SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT, ERR_R_MALLOC_FAILURE); - return (0); - } - memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int)); - - /* - * Now find the strength_bits values actually used - */ - curr = *head_p; - while (curr != NULL) { - if (curr->active) - number_uses[curr->cipher->strength_bits]++; - curr = curr->next; - } - /* - * Go through the list of used strength_bits values in descending - * order. - */ - for (i = max_strength_bits; i >= 0; i--) - if (number_uses[i] > 0) - ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, - tail_p); - - OPENSSL_free(number_uses); - return (1); -} - -static int ssl_cipher_process_rulestr(const char *rule_str, - CIPHER_ORDER **head_p, - CIPHER_ORDER **tail_p, - const SSL_CIPHER **ca_list) -{ - unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, - algo_strength; - const char *l, *buf; - int j, multi, found, rule, retval, ok, buflen; - unsigned long cipher_id = 0; - char ch; - - retval = 1; - l = rule_str; - for (;;) { - ch = *l; - - if (ch == '\0') - break; /* done */ - if (ch == '-') { - rule = CIPHER_DEL; - l++; - } else if (ch == '+') { - rule = CIPHER_ORD; - l++; - } else if (ch == '!') { - rule = CIPHER_KILL; - l++; - } else if (ch == '@') { - rule = CIPHER_SPECIAL; - l++; - } else { - rule = CIPHER_ADD; - } - - if (ITEM_SEP(ch)) { - l++; - continue; - } - - alg_mkey = 0; - alg_auth = 0; - alg_enc = 0; - alg_mac = 0; - alg_ssl = 0; - algo_strength = 0; - - for (;;) { - ch = *l; - buf = l; - buflen = 0; -#ifndef CHARSET_EBCDIC - while (((ch >= 'A') && (ch <= 'Z')) || - ((ch >= '0') && (ch <= '9')) || - ((ch >= 'a') && (ch <= 'z')) || (ch == '-') || (ch == '.')) -#else - while (isalnum(ch) || (ch == '-') || (ch == '.')) -#endif - { - ch = *(++l); - buflen++; - } - - if (buflen == 0) { - /* - * We hit something we cannot deal with, - * it is no command or separator nor - * alphanumeric, so we call this an error. - */ - SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, - SSL_R_INVALID_COMMAND); - retval = found = 0; - l++; - break; - } - - if (rule == CIPHER_SPECIAL) { - found = 0; /* unused -- avoid compiler warning */ - break; /* special treatment */ - } - - /* check for multi-part specification */ - if (ch == '+') { - multi = 1; - l++; - } else - multi = 0; - - /* - * Now search for the cipher alias in the ca_list. Be careful - * with the strncmp, because the "buflen" limitation - * will make the rule "ADH:SOME" and the cipher - * "ADH-MY-CIPHER" look like a match for buflen=3. - * So additionally check whether the cipher name found - * has the correct length. We can save a strlen() call: - * just checking for the '\0' at the right place is - * sufficient, we have to strncmp() anyway. (We cannot - * use strcmp(), because buf is not '\0' terminated.) - */ - j = found = 0; - cipher_id = 0; - while (ca_list[j]) { - if (!strncmp(buf, ca_list[j]->name, buflen) && - (ca_list[j]->name[buflen] == '\0')) { - found = 1; - break; - } else - j++; - } - - if (!found) - break; /* ignore this entry */ - - if (ca_list[j]->algorithm_mkey) { - if (alg_mkey) { - alg_mkey &= ca_list[j]->algorithm_mkey; - if (!alg_mkey) { - found = 0; - break; - } - } else - alg_mkey = ca_list[j]->algorithm_mkey; - } - - if (ca_list[j]->algorithm_auth) { - if (alg_auth) { - alg_auth &= ca_list[j]->algorithm_auth; - if (!alg_auth) { - found = 0; - break; - } - } else - alg_auth = ca_list[j]->algorithm_auth; - } - - if (ca_list[j]->algorithm_enc) { - if (alg_enc) { - alg_enc &= ca_list[j]->algorithm_enc; - if (!alg_enc) { - found = 0; - break; - } - } else - alg_enc = ca_list[j]->algorithm_enc; - } - - if (ca_list[j]->algorithm_mac) { - if (alg_mac) { - alg_mac &= ca_list[j]->algorithm_mac; - if (!alg_mac) { - found = 0; - break; - } - } else - alg_mac = ca_list[j]->algorithm_mac; - } - - if (ca_list[j]->algo_strength & SSL_EXP_MASK) { - if (algo_strength & SSL_EXP_MASK) { - algo_strength &= - (ca_list[j]->algo_strength & SSL_EXP_MASK) | - ~SSL_EXP_MASK; - if (!(algo_strength & SSL_EXP_MASK)) { - found = 0; - break; - } - } else - algo_strength |= ca_list[j]->algo_strength & SSL_EXP_MASK; - } - - if (ca_list[j]->algo_strength & SSL_STRONG_MASK) { - if (algo_strength & SSL_STRONG_MASK) { - algo_strength &= - (ca_list[j]->algo_strength & SSL_STRONG_MASK) | - ~SSL_STRONG_MASK; - if (!(algo_strength & SSL_STRONG_MASK)) { - found = 0; - break; - } - } else - algo_strength |= - ca_list[j]->algo_strength & SSL_STRONG_MASK; - } - - if (ca_list[j]->algo_strength & SSL_NOT_DEFAULT) { - algo_strength |= SSL_NOT_DEFAULT; - } - - if (ca_list[j]->valid) { - /* - * explicit ciphersuite found; its protocol version does not - * become part of the search pattern! - */ - - cipher_id = ca_list[j]->id; - } else { - /* - * not an explicit ciphersuite; only in this case, the - * protocol version is considered part of the search pattern - */ - - if (ca_list[j]->algorithm_ssl) { - if (alg_ssl) { - alg_ssl &= ca_list[j]->algorithm_ssl; - if (!alg_ssl) { - found = 0; - break; - } - } else - alg_ssl = ca_list[j]->algorithm_ssl; - } - } - - if (!multi) - break; - } - - /* - * Ok, we have the rule, now apply it - */ - if (rule == CIPHER_SPECIAL) { /* special command */ - ok = 0; - if ((buflen == 8) && !strncmp(buf, "STRENGTH", 8)) - ok = ssl_cipher_strength_sort(head_p, tail_p); - else - SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, - SSL_R_INVALID_COMMAND); - if (ok == 0) - retval = 0; - /* - * We do not support any "multi" options - * together with "@", so throw away the - * rest of the command, if any left, until - * end or ':' is found. - */ - while ((*l != '\0') && !ITEM_SEP(*l)) - l++; - } else if (found) { - ssl_cipher_apply_rule(cipher_id, - alg_mkey, alg_auth, alg_enc, alg_mac, - alg_ssl, algo_strength, rule, -1, head_p, - tail_p); - } else { - while ((*l != '\0') && !ITEM_SEP(*l)) - l++; - } - if (*l == '\0') - break; /* done */ - } - - return (retval); -} - -#ifndef OPENSSL_NO_EC -static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c, - const char **prule_str) -{ - unsigned int suiteb_flags = 0, suiteb_comb2 = 0; - if (strncmp(*prule_str, "SUITEB128ONLY", 13) == 0) { - suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY; - } else if (strncmp(*prule_str, "SUITEB128C2", 11) == 0) { - suiteb_comb2 = 1; - suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS; - } else if (strncmp(*prule_str, "SUITEB128", 9) == 0) { - suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS; - } else if (strncmp(*prule_str, "SUITEB192", 9) == 0) { - suiteb_flags = SSL_CERT_FLAG_SUITEB_192_LOS; - } - - if (suiteb_flags) { - c->cert_flags &= ~SSL_CERT_FLAG_SUITEB_128_LOS; - c->cert_flags |= suiteb_flags; - } else - suiteb_flags = c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS; - - if (!suiteb_flags) - return 1; - /* Check version: if TLS 1.2 ciphers allowed we can use Suite B */ - - if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)) { - if (meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) - SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, - SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); - else - SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, - SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); - return 0; - } -# ifndef OPENSSL_NO_ECDH - switch (suiteb_flags) { - case SSL_CERT_FLAG_SUITEB_128_LOS: - if (suiteb_comb2) - *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384"; - else - *prule_str = - "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384"; - break; - case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: - *prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256"; - break; - case SSL_CERT_FLAG_SUITEB_192_LOS: - *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384"; - break; - } - /* Set auto ECDH parameter determination */ - c->ecdh_tmp_auto = 1; - return 1; -# else - SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, - SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE); - return 0; -# endif -} -#endif - -STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, STACK_OF(SSL_CIPHER) - **cipher_list, STACK_OF(SSL_CIPHER) - **cipher_list_by_id, - const char *rule_str, CERT *c) -{ - int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; - unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, - disabled_ssl; - STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list; - const char *rule_p; - CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; - const SSL_CIPHER **ca_list = NULL; - - /* - * Return with error if nothing to do. - */ - if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL) - return NULL; -#ifndef OPENSSL_NO_EC - if (!check_suiteb_cipher_list(ssl_method, c, &rule_str)) - return NULL; -#endif - - /* - * To reduce the work to do we only want to process the compiled - * in algorithms, so we first get the mask of disabled ciphers. - */ - ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, - &disabled_mac, &disabled_ssl); - - /* - * Now we have to collect the available ciphers from the compiled - * in ciphers. We cannot get more than the number compiled in, so - * it is used for allocation. - */ - num_of_ciphers = ssl_method->num_ciphers(); -#ifdef KSSL_DEBUG - fprintf(stderr, "ssl_create_cipher_list() for %d ciphers\n", - num_of_ciphers); -#endif /* KSSL_DEBUG */ - co_list = - (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers); - if (co_list == NULL) { - SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - return (NULL); /* Failure */ - } - - ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, - disabled_mkey, disabled_auth, disabled_enc, - disabled_mac, disabled_ssl, co_list, &head, - &tail); - - /* Now arrange all ciphers by preference: */ - - /* - * Everything else being equal, prefer ephemeral ECDH over other key - * exchange mechanisms - */ - ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, - &tail); - ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, - &tail); - - /* AES is our preferred symmetric cipher */ - ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, &head, - &tail); - - /* Temporarily enable everything else for sorting */ - ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); - - /* Low priority for MD5 */ - ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, - &tail); - - /* - * Move anonymous ciphers to the end. Usually, these will remain - * disabled. (For applications that allow them, they aren't too bad, but - * we prefer authenticated ciphers.) - */ - ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, - &tail); - - /* Move ciphers without forward secrecy to the end */ - ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, - &tail); - /* - * ssl_cipher_apply_rule(0, 0, SSL_aDH, 0, 0, 0, 0, CIPHER_ORD, -1, - * &head, &tail); - */ - ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, - &tail); - ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, - &tail); - ssl_cipher_apply_rule(0, SSL_kKRB5, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, - &tail); - - /* RC4 is sort-of broken -- move the the end */ - ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, - &tail); - - /* - * Now sort by symmetric encryption strength. The above ordering remains - * in force within each class - */ - if (!ssl_cipher_strength_sort(&head, &tail)) { - OPENSSL_free(co_list); - return NULL; - } - - /* Now disable everything (maintaining the ordering!) */ - ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); - - /* - * We also need cipher aliases for selecting based on the rule_str. - * There might be two types of entries in the rule_str: 1) names - * of ciphers themselves 2) aliases for groups of ciphers. - * For 1) we need the available ciphers and for 2) the cipher - * groups of cipher_aliases added together in one list (otherwise - * we would be happy with just the cipher_aliases table). - */ - num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); - num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; - ca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max); - if (ca_list == NULL) { - OPENSSL_free(co_list); - SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - return (NULL); /* Failure */ - } - ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, - disabled_mkey, disabled_auth, disabled_enc, - disabled_mac, disabled_ssl, head); - - /* - * If the rule_string begins with DEFAULT, apply the default rule - * before using the (possibly available) additional rules. - */ - ok = 1; - rule_p = rule_str; - if (strncmp(rule_str, "DEFAULT", 7) == 0) { - ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, - &head, &tail, ca_list); - rule_p += 7; - if (*rule_p == ':') - rule_p++; - } - - if (ok && (strlen(rule_p) > 0)) - ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list); - - OPENSSL_free((void *)ca_list); /* Not needed anymore */ - - if (!ok) { /* Rule processing failure */ - OPENSSL_free(co_list); - return (NULL); - } - - /* - * Allocate new "cipherstack" for the result, return with error - * if we cannot get one. - */ - if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) { - OPENSSL_free(co_list); - return (NULL); - } - - /* - * The cipher selection for the list is done. The ciphers are added - * to the resulting precedence to the STACK_OF(SSL_CIPHER). - */ - for (curr = head; curr != NULL; curr = curr->next) { -#ifdef OPENSSL_FIPS - if (curr->active - && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS)) -#else - if (curr->active) -#endif - { - sk_SSL_CIPHER_push(cipherstack, curr->cipher); -#ifdef CIPHER_DEBUG - fprintf(stderr, "<%s>\n", curr->cipher->name); -#endif - } - } - OPENSSL_free(co_list); /* Not needed any longer */ - - tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack); - if (tmp_cipher_list == NULL) { - sk_SSL_CIPHER_free(cipherstack); - return NULL; - } - if (*cipher_list != NULL) - sk_SSL_CIPHER_free(*cipher_list); - *cipher_list = cipherstack; - if (*cipher_list_by_id != NULL) - sk_SSL_CIPHER_free(*cipher_list_by_id); - *cipher_list_by_id = tmp_cipher_list; - (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id, - ssl_cipher_ptr_id_cmp); - - sk_SSL_CIPHER_sort(*cipher_list_by_id); - return (cipherstack); -} - -char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) -{ - int is_export, pkl, kl; - const char *ver, *exp_str; - const char *kx, *au, *enc, *mac; - unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, alg2; -#ifdef KSSL_DEBUG - static const char *format = - "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx/%lx/%lx/%lx/%lx\n"; -#else - static const char *format = - "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n"; -#endif /* KSSL_DEBUG */ - - alg_mkey = cipher->algorithm_mkey; - alg_auth = cipher->algorithm_auth; - alg_enc = cipher->algorithm_enc; - alg_mac = cipher->algorithm_mac; - alg_ssl = cipher->algorithm_ssl; - - alg2 = cipher->algorithm2; - - is_export = SSL_C_IS_EXPORT(cipher); - pkl = SSL_C_EXPORT_PKEYLENGTH(cipher); - kl = SSL_C_EXPORT_KEYLENGTH(cipher); - exp_str = is_export ? " export" : ""; - - if (alg_ssl & SSL_SSLV2) - ver = "SSLv2"; - else if (alg_ssl & SSL_SSLV3) - ver = "SSLv3"; - else if (alg_ssl & SSL_TLSV1_2) - ver = "TLSv1.2"; - else - ver = "unknown"; - - switch (alg_mkey) { - case SSL_kRSA: - kx = is_export ? (pkl == 512 ? "RSA(512)" : "RSA(1024)") : "RSA"; - break; - case SSL_kDHr: - kx = "DH/RSA"; - break; - case SSL_kDHd: - kx = "DH/DSS"; - break; - case SSL_kKRB5: - kx = "KRB5"; - break; - case SSL_kEDH: - kx = is_export ? (pkl == 512 ? "DH(512)" : "DH(1024)") : "DH"; - break; - case SSL_kECDHr: - kx = "ECDH/RSA"; - break; - case SSL_kECDHe: - kx = "ECDH/ECDSA"; - break; - case SSL_kEECDH: - kx = "ECDH"; - break; - case SSL_kPSK: - kx = "PSK"; - break; - case SSL_kSRP: - kx = "SRP"; - break; - case SSL_kGOST: - kx = "GOST"; - break; - default: - kx = "unknown"; - } - - switch (alg_auth) { - case SSL_aRSA: - au = "RSA"; - break; - case SSL_aDSS: - au = "DSS"; - break; - case SSL_aDH: - au = "DH"; - break; - case SSL_aKRB5: - au = "KRB5"; - break; - case SSL_aECDH: - au = "ECDH"; - break; - case SSL_aNULL: - au = "None"; - break; - case SSL_aECDSA: - au = "ECDSA"; - break; - case SSL_aPSK: - au = "PSK"; - break; - case SSL_aSRP: - au = "SRP"; - break; - case SSL_aGOST94: - au = "GOST94"; - break; - case SSL_aGOST01: - au = "GOST01"; - break; - default: - au = "unknown"; - break; - } - - switch (alg_enc) { - case SSL_DES: - enc = (is_export && kl == 5) ? "DES(40)" : "DES(56)"; - break; - case SSL_3DES: - enc = "3DES(168)"; - break; - case SSL_RC4: - enc = is_export ? (kl == 5 ? "RC4(40)" : "RC4(56)") - : ((alg2 & SSL2_CF_8_BYTE_ENC) ? "RC4(64)" : "RC4(128)"); - break; - case SSL_RC2: - enc = is_export ? (kl == 5 ? "RC2(40)" : "RC2(56)") : "RC2(128)"; - break; - case SSL_IDEA: - enc = "IDEA(128)"; - break; - case SSL_eNULL: - enc = "None"; - break; - case SSL_AES128: - enc = "AES(128)"; - break; - case SSL_AES256: - enc = "AES(256)"; - break; - case SSL_AES128GCM: - enc = "AESGCM(128)"; - break; - case SSL_AES256GCM: - enc = "AESGCM(256)"; - break; - case SSL_CAMELLIA128: - enc = "Camellia(128)"; - break; - case SSL_CAMELLIA256: - enc = "Camellia(256)"; - break; - case SSL_SEED: - enc = "SEED(128)"; - break; - case SSL_eGOST2814789CNT: - enc = "GOST89(256)"; - break; - default: - enc = "unknown"; - break; - } - - switch (alg_mac) { - case SSL_MD5: - mac = "MD5"; - break; - case SSL_SHA1: - mac = "SHA1"; - break; - case SSL_SHA256: - mac = "SHA256"; - break; - case SSL_SHA384: - mac = "SHA384"; - break; - case SSL_AEAD: - mac = "AEAD"; - break; - case SSL_GOST89MAC: - mac = "GOST89"; - break; - case SSL_GOST94: - mac = "GOST94"; - break; - default: - mac = "unknown"; - break; - } - - if (buf == NULL) { - len = 128; - buf = OPENSSL_malloc(len); - if (buf == NULL) - return ("OPENSSL_malloc Error"); - } else if (len < 128) - return ("Buffer too small"); - -#ifdef KSSL_DEBUG - BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac, - exp_str, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl); -#else - BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac, - exp_str); -#endif /* KSSL_DEBUG */ - return (buf); -} - -char *SSL_CIPHER_get_version(const SSL_CIPHER *c) -{ - int i; - - if (c == NULL) - return ("(NONE)"); - i = (int)(c->id >> 24L); - if (i == 3) - return ("TLSv1/SSLv3"); - else if (i == 2) - return ("SSLv2"); - else - return ("unknown"); -} - -/* return the actual cipher being used */ -const char *SSL_CIPHER_get_name(const SSL_CIPHER *c) -{ - if (c != NULL) - return (c->name); - return ("(NONE)"); -} - -/* number of bits for symmetric cipher */ -int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits) -{ - int ret = 0; - - if (c != NULL) { - if (alg_bits != NULL) - *alg_bits = c->alg_bits; - ret = c->strength_bits; - } - return (ret); -} - -unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c) -{ - return c->id; -} - -SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) -{ - SSL_COMP *ctmp; - int i, nn; - - if ((n == 0) || (sk == NULL)) - return (NULL); - nn = sk_SSL_COMP_num(sk); - for (i = 0; i < nn; i++) { - ctmp = sk_SSL_COMP_value(sk, i); - if (ctmp->id == n) - return (ctmp); - } - return (NULL); -} - -#ifdef OPENSSL_NO_COMP -STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) -{ - return NULL; -} - -STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) - *meths) -{ - return NULL; -} - -void SSL_COMP_free_compression_methods(void) -{ -} - -int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) -{ - return 1; -} - -const char *SSL_COMP_get_name(const COMP_METHOD *comp) -{ - return NULL; -} -#else -STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) -{ - load_builtin_compressions(); - return (ssl_comp_methods); -} - -STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) - *meths) -{ - STACK_OF(SSL_COMP) *old_meths = ssl_comp_methods; - ssl_comp_methods = meths; - return old_meths; -} - -static void cmeth_free(SSL_COMP *cm) -{ - OPENSSL_free(cm); -} - -void SSL_COMP_free_compression_methods(void) -{ - STACK_OF(SSL_COMP) *old_meths = ssl_comp_methods; - ssl_comp_methods = NULL; - sk_SSL_COMP_pop_free(old_meths, cmeth_free); -} - -int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) -{ - SSL_COMP *comp; - - if (cm == NULL || cm->type == NID_undef) - return 1; - - /*- - * According to draft-ietf-tls-compression-04.txt, the - * compression number ranges should be the following: - * - * 0 to 63: methods defined by the IETF - * 64 to 192: external party methods assigned by IANA - * 193 to 255: reserved for private use - */ - if (id < 193 || id > 255) { - SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, - SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE); - return 1; - } - - MemCheck_off(); - comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); - if (comp == NULL) { - MemCheck_on(); - SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE); - return 1; - } - comp->id = id; - comp->method = cm; - comp->name = cm->name; - load_builtin_compressions(); - if (ssl_comp_methods && sk_SSL_COMP_find(ssl_comp_methods, comp) >= 0) { - OPENSSL_free(comp); - MemCheck_on(); - SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, - SSL_R_DUPLICATE_COMPRESSION_ID); - return (1); - } else if ((ssl_comp_methods == NULL) - || !sk_SSL_COMP_push(ssl_comp_methods, comp)) { - OPENSSL_free(comp); - MemCheck_on(); - SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE); - return (1); - } else { - MemCheck_on(); - return (0); - } -} - -const char *SSL_COMP_get_name(const COMP_METHOD *comp) -{ - if (comp) - return comp->name; - return NULL; -} -#endif -/* For a cipher return the index corresponding to the certificate type */ -int ssl_cipher_get_cert_index(const SSL_CIPHER *c) -{ - unsigned long alg_k, alg_a; - - alg_k = c->algorithm_mkey; - alg_a = c->algorithm_auth; - - if (alg_k & (SSL_kECDHr | SSL_kECDHe)) { - /* - * we don't need to look at SSL_kEECDH since no certificate is needed - * for anon ECDH and for authenticated EECDH, the check for the auth - * algorithm will set i correctly NOTE: For ECDH-RSA, we need an ECC - * not an RSA cert but for EECDH-RSA we need an RSA cert. Placing the - * checks for SSL_kECDH before RSA checks ensures the correct cert is - * chosen. - */ - return SSL_PKEY_ECC; - } else if (alg_a & SSL_aECDSA) - return SSL_PKEY_ECC; - else if (alg_k & SSL_kDHr) - return SSL_PKEY_DH_RSA; - else if (alg_k & SSL_kDHd) - return SSL_PKEY_DH_DSA; - else if (alg_a & SSL_aDSS) - return SSL_PKEY_DSA_SIGN; - else if (alg_a & SSL_aRSA) - return SSL_PKEY_RSA_ENC; - else if (alg_a & SSL_aKRB5) - /* VRS something else here? */ - return -1; - else if (alg_a & SSL_aGOST94) - return SSL_PKEY_GOST94; - else if (alg_a & SSL_aGOST01) - return SSL_PKEY_GOST01; - return -1; -} - -const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr) -{ - const SSL_CIPHER *c; - c = ssl->method->get_cipher_by_char(ptr); - if (c == NULL || c->valid == 0) - return NULL; - return c; -} - -const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr) -{ - return ssl->method->get_cipher_by_char(ptr); -} diff --git a/thirdparty/openssl/ssl/ssl_conf.c b/thirdparty/openssl/ssl/ssl_conf.c deleted file mode 100644 index 8d3709d2b6..0000000000 --- a/thirdparty/openssl/ssl/ssl_conf.c +++ /dev/null @@ -1,691 +0,0 @@ -/* - * ! \file ssl/ssl_conf.c \brief SSL configuration functions - */ -/* ==================================================================== - * Copyright (c) 2012 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 - * openssl-core@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). - * - */ - -#ifdef REF_CHECK -# include <assert.h> -#endif -#include <stdio.h> -#include "ssl_locl.h" -#include <openssl/conf.h> -#include <openssl/objects.h> -#ifndef OPENSSL_NO_DH -# include <openssl/dh.h> -#endif - -/* - * structure holding name tables. This is used for pemitted elements in lists - * such as TLSv1 and single command line switches such as no_tls1 - */ - -typedef struct { - const char *name; - int namelen; - unsigned int name_flags; - unsigned long option_value; -} ssl_flag_tbl; - -/* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */ -#define SSL_TFLAG_INV 0x1 -/* Flags refers to cert_flags not options */ -#define SSL_TFLAG_CERT 0x2 -/* Option can only be used for clients */ -#define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT -/* Option can only be used for servers */ -#define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER -#define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER) - -#define SSL_FLAG_TBL(str, flag) \ - {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag} -#define SSL_FLAG_TBL_SRV(str, flag) \ - {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag} -#define SSL_FLAG_TBL_CLI(str, flag) \ - {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag} -#define SSL_FLAG_TBL_INV(str, flag) \ - {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag} -#define SSL_FLAG_TBL_SRV_INV(str, flag) \ - {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag} -#define SSL_FLAG_TBL_CERT(str, flag) \ - {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag} - -/* - * Opaque structure containing SSL configuration context. - */ - -struct ssl_conf_ctx_st { - /* - * Various flags indicating (among other things) which options we will - * recognise. - */ - unsigned int flags; - /* Prefix and length of commands */ - char *prefix; - size_t prefixlen; - /* SSL_CTX or SSL structure to perform operations on */ - SSL_CTX *ctx; - SSL *ssl; - /* Pointer to SSL or SSL_CTX options field or NULL if none */ - unsigned long *poptions; - /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */ - unsigned int *pcert_flags; - /* Current flag table being worked on */ - const ssl_flag_tbl *tbl; - /* Size of table */ - size_t ntbl; -}; - -static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl, - const char *name, int namelen, int onoff) -{ - /* If name not relevant for context skip */ - if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH)) - return 0; - if (namelen == -1) { - if (strcmp(tbl->name, name)) - return 0; - } else if (tbl->namelen != namelen - || strncasecmp(tbl->name, name, namelen)) - return 0; - if (cctx->poptions) { - if (tbl->name_flags & SSL_TFLAG_INV) - onoff ^= 1; - if (tbl->name_flags & SSL_TFLAG_CERT) { - if (onoff) - *cctx->pcert_flags |= tbl->option_value; - else - *cctx->pcert_flags &= ~tbl->option_value; - } else { - if (onoff) - *cctx->poptions |= tbl->option_value; - else - *cctx->poptions &= ~tbl->option_value; - } - } - return 1; -} - -static int ssl_set_option_list(const char *elem, int len, void *usr) -{ - SSL_CONF_CTX *cctx = usr; - size_t i; - const ssl_flag_tbl *tbl; - int onoff = 1; - /* - * len == -1 indicates not being called in list context, just for single - * command line switches, so don't allow +, -. - */ - if (elem == NULL) - return 0; - if (len != -1) { - if (*elem == '+') { - elem++; - len--; - onoff = 1; - } else if (*elem == '-') { - elem++; - len--; - onoff = 0; - } - } - for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) { - if (ssl_match_option(cctx, tbl, elem, len, onoff)) - return 1; - } - return 0; -} - -/* Single command line switches with no argument e.g. -no_ssl3 */ -static int ctrl_str_option(SSL_CONF_CTX *cctx, const char *cmd) -{ - static const ssl_flag_tbl ssl_option_single[] = { - SSL_FLAG_TBL("no_ssl2", SSL_OP_NO_SSLv2), - SSL_FLAG_TBL("no_ssl3", SSL_OP_NO_SSLv3), - SSL_FLAG_TBL("no_tls1", SSL_OP_NO_TLSv1), - SSL_FLAG_TBL("no_tls1_1", SSL_OP_NO_TLSv1_1), - SSL_FLAG_TBL("no_tls1_2", SSL_OP_NO_TLSv1_2), - SSL_FLAG_TBL("bugs", SSL_OP_ALL), - SSL_FLAG_TBL("no_comp", SSL_OP_NO_COMPRESSION), - SSL_FLAG_TBL_SRV("ecdh_single", SSL_OP_SINGLE_ECDH_USE), -#ifndef OPENSSL_NO_TLSEXT - SSL_FLAG_TBL("no_ticket", SSL_OP_NO_TICKET), -#endif - SSL_FLAG_TBL_SRV("serverpref", SSL_OP_CIPHER_SERVER_PREFERENCE), - SSL_FLAG_TBL("legacy_renegotiation", - SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), - SSL_FLAG_TBL_SRV("legacy_server_connect", - SSL_OP_LEGACY_SERVER_CONNECT), - SSL_FLAG_TBL_SRV("no_resumption_on_reneg", - SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION), - SSL_FLAG_TBL_SRV_INV("no_legacy_server_connect", - SSL_OP_LEGACY_SERVER_CONNECT), - SSL_FLAG_TBL_CERT("strict", SSL_CERT_FLAG_TLS_STRICT), -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - SSL_FLAG_TBL_CERT("debug_broken_protocol", - SSL_CERT_FLAG_BROKEN_PROTOCOL), -#endif - }; - cctx->tbl = ssl_option_single; - cctx->ntbl = sizeof(ssl_option_single) / sizeof(ssl_flag_tbl); - return ssl_set_option_list(cmd, -1, cctx); -} - -/* Set supported signature algorithms */ -static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value) -{ - int rv; - if (cctx->ssl) - rv = SSL_set1_sigalgs_list(cctx->ssl, value); - /* NB: ctx == NULL performs syntax checking only */ - else - rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value); - return rv > 0; -} - -/* Set supported client signature algorithms */ -static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx, - const char *value) -{ - int rv; - if (cctx->ssl) - rv = SSL_set1_client_sigalgs_list(cctx->ssl, value); - /* NB: ctx == NULL performs syntax checking only */ - else - rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value); - return rv > 0; -} - -static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value) -{ - int rv; - if (cctx->ssl) - rv = SSL_set1_curves_list(cctx->ssl, value); - /* NB: ctx == NULL performs syntax checking only */ - else - rv = SSL_CTX_set1_curves_list(cctx->ctx, value); - return rv > 0; -} - -#ifndef OPENSSL_NO_ECDH -/* ECDH temporary parameters */ -static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value) -{ - int onoff = -1, rv = 1; - if (!(cctx->flags & SSL_CONF_FLAG_SERVER)) - return -2; - if (cctx->flags & SSL_CONF_FLAG_FILE) { - if (*value == '+') { - onoff = 1; - value++; - } - if (*value == '-') { - onoff = 0; - value++; - } - if (!strcasecmp(value, "automatic")) { - if (onoff == -1) - onoff = 1; - } else if (onoff != -1) - return 0; - } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { - if (!strcmp(value, "auto")) - onoff = 1; - } - - if (onoff != -1) { - if (cctx->ctx) - rv = SSL_CTX_set_ecdh_auto(cctx->ctx, onoff); - else if (cctx->ssl) - rv = SSL_set_ecdh_auto(cctx->ssl, onoff); - } else { - EC_KEY *ecdh; - int nid; - nid = EC_curve_nist2nid(value); - if (nid == NID_undef) - nid = OBJ_sn2nid(value); - if (nid == 0) - return 0; - ecdh = EC_KEY_new_by_curve_name(nid); - if (!ecdh) - return 0; - if (cctx->ctx) - rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh); - else if (cctx->ssl) - rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh); - EC_KEY_free(ecdh); - } - - return rv > 0; -} -#endif -static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value) -{ - int rv = 1; - if (cctx->ctx) - rv = SSL_CTX_set_cipher_list(cctx->ctx, value); - if (cctx->ssl) - rv = SSL_set_cipher_list(cctx->ssl, value); - return rv > 0; -} - -static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value) -{ - static const ssl_flag_tbl ssl_protocol_list[] = { - SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK), - SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2), - SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3), - SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1), - SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1), - SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2) - }; - int ret; - int sslv2off; - - if (!(cctx->flags & SSL_CONF_FLAG_FILE)) - return -2; - cctx->tbl = ssl_protocol_list; - cctx->ntbl = sizeof(ssl_protocol_list) / sizeof(ssl_flag_tbl); - - sslv2off = *cctx->poptions & SSL_OP_NO_SSLv2; - ret = CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); - /* Never turn on SSLv2 through configuration */ - *cctx->poptions |= sslv2off; - return ret; -} - -static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) -{ - static const ssl_flag_tbl ssl_option_list[] = { - SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET), - SSL_FLAG_TBL_INV("EmptyFragments", - SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS), - SSL_FLAG_TBL("Bugs", SSL_OP_ALL), - SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION), - SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE), - SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation", - SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION), - SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE), - SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE), - SSL_FLAG_TBL("UnsafeLegacyRenegotiation", - SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), - }; - if (!(cctx->flags & SSL_CONF_FLAG_FILE)) - return -2; - if (value == NULL) - return -3; - cctx->tbl = ssl_option_list; - cctx->ntbl = sizeof(ssl_option_list) / sizeof(ssl_flag_tbl); - return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); -} - -static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value) -{ - int rv = 1; - if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) - return -2; - if (cctx->ctx) - rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value); - if (cctx->ssl) - rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM); - return rv > 0; -} - -static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value) -{ - int rv = 1; - if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) - return -2; - if (cctx->ctx) - rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM); - if (cctx->ssl) - rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM); - return rv > 0; -} - -static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value) -{ - int rv = 1; - if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) - return -2; - if (!(cctx->flags & SSL_CONF_FLAG_SERVER)) - return -2; - if (cctx->ctx) - rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value); - return rv > 0; -} - -#ifndef OPENSSL_NO_DH -static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value) -{ - int rv = 0; - DH *dh = NULL; - BIO *in = NULL; - if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) - return -2; - if (cctx->ctx || cctx->ssl) { - in = BIO_new(BIO_s_file_internal()); - if (!in) - goto end; - if (BIO_read_filename(in, value) <= 0) - goto end; - dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); - if (!dh) - goto end; - } else - return 1; - if (cctx->ctx) - rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh); - if (cctx->ssl) - rv = SSL_set_tmp_dh(cctx->ssl, dh); - end: - if (dh) - DH_free(dh); - if (in) - BIO_free(in); - return rv > 0; -} -#endif -typedef struct { - int (*cmd) (SSL_CONF_CTX *cctx, const char *value); - const char *str_file; - const char *str_cmdline; - unsigned int value_type; -} ssl_conf_cmd_tbl; - -/* Table of supported parameters */ - -#define SSL_CONF_CMD(name, cmdopt, type) \ - {cmd_##name, #name, cmdopt, type} - -#define SSL_CONF_CMD_STRING(name, cmdopt) \ - SSL_CONF_CMD(name, cmdopt, SSL_CONF_TYPE_STRING) - -static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { - SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs"), - SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs"), - SSL_CONF_CMD_STRING(Curves, "curves"), -#ifndef OPENSSL_NO_ECDH - SSL_CONF_CMD_STRING(ECDHParameters, "named_curve"), -#endif - SSL_CONF_CMD_STRING(CipherString, "cipher"), - SSL_CONF_CMD_STRING(Protocol, NULL), - SSL_CONF_CMD_STRING(Options, NULL), - SSL_CONF_CMD(Certificate, "cert", SSL_CONF_TYPE_FILE), - SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_TYPE_FILE), - SSL_CONF_CMD(ServerInfoFile, NULL, SSL_CONF_TYPE_FILE), -#ifndef OPENSSL_NO_DH - SSL_CONF_CMD(DHParameters, "dhparam", SSL_CONF_TYPE_FILE) -#endif -}; - -static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd) -{ - if (!pcmd || !*pcmd) - return 0; - /* If a prefix is set, check and skip */ - if (cctx->prefix) { - if (strlen(*pcmd) <= cctx->prefixlen) - return 0; - if (cctx->flags & SSL_CONF_FLAG_CMDLINE && - strncmp(*pcmd, cctx->prefix, cctx->prefixlen)) - return 0; - if (cctx->flags & SSL_CONF_FLAG_FILE && - strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen)) - return 0; - *pcmd += cctx->prefixlen; - } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { - if (**pcmd != '-' || !(*pcmd)[1]) - return 0; - *pcmd += 1; - } - return 1; -} - -static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx, - const char *cmd) -{ - const ssl_conf_cmd_tbl *t; - size_t i; - if (cmd == NULL) - return NULL; - - /* Look for matching parameter name in table */ - for (i = 0, t = ssl_conf_cmds; - i < sizeof(ssl_conf_cmds) / sizeof(ssl_conf_cmd_tbl); i++, t++) { - if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { - if (t->str_cmdline && !strcmp(t->str_cmdline, cmd)) - return t; - } - if (cctx->flags & SSL_CONF_FLAG_FILE) { - if (t->str_file && !strcasecmp(t->str_file, cmd)) - return t; - } - } - return NULL; -} - -int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value) -{ - const ssl_conf_cmd_tbl *runcmd; - if (cmd == NULL) { - SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME); - return 0; - } - - if (!ssl_conf_cmd_skip_prefix(cctx, &cmd)) - return -2; - - runcmd = ssl_conf_cmd_lookup(cctx, cmd); - - if (runcmd) { - int rv; - if (value == NULL) - return -3; - rv = runcmd->cmd(cctx, value); - if (rv > 0) - return 2; - if (rv == -2) - return -2; - if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) { - SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE); - ERR_add_error_data(4, "cmd=", cmd, ", value=", value); - } - return 0; - } - - if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { - if (ctrl_str_option(cctx, cmd)) - return 1; - } - - if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) { - SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME); - ERR_add_error_data(2, "cmd=", cmd); - } - - return -2; -} - -int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv) -{ - int rv; - const char *arg = NULL, *argn; - if (pargc && *pargc == 0) - return 0; - if (!pargc || *pargc > 0) - arg = **pargv; - if (arg == NULL) - return 0; - if (!pargc || *pargc > 1) - argn = (*pargv)[1]; - else - argn = NULL; - cctx->flags &= ~SSL_CONF_FLAG_FILE; - cctx->flags |= SSL_CONF_FLAG_CMDLINE; - rv = SSL_CONF_cmd(cctx, arg, argn); - if (rv > 0) { - /* Success: update pargc, pargv */ - (*pargv) += rv; - if (pargc) - (*pargc) -= rv; - return rv; - } - /* Unknown switch: indicate no arguments processed */ - if (rv == -2) - return 0; - /* Some error occurred processing command, return fatal error */ - if (rv == 0) - return -1; - return rv; -} - -int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd) -{ - if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) { - const ssl_conf_cmd_tbl *runcmd; - runcmd = ssl_conf_cmd_lookup(cctx, cmd); - if (runcmd) - return runcmd->value_type; - } - return SSL_CONF_TYPE_UNKNOWN; -} - -SSL_CONF_CTX *SSL_CONF_CTX_new(void) -{ - SSL_CONF_CTX *ret; - ret = OPENSSL_malloc(sizeof(SSL_CONF_CTX)); - if (ret) { - ret->flags = 0; - ret->prefix = NULL; - ret->prefixlen = 0; - ret->ssl = NULL; - ret->ctx = NULL; - ret->poptions = NULL; - ret->pcert_flags = NULL; - ret->tbl = NULL; - ret->ntbl = 0; - } - return ret; -} - -int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx) -{ - return 1; -} - -void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx) -{ - if (cctx) { - if (cctx->prefix) - OPENSSL_free(cctx->prefix); - OPENSSL_free(cctx); - } -} - -unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags) -{ - cctx->flags |= flags; - return cctx->flags; -} - -unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags) -{ - cctx->flags &= ~flags; - return cctx->flags; -} - -int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre) -{ - char *tmp = NULL; - if (pre) { - tmp = BUF_strdup(pre); - if (tmp == NULL) - return 0; - } - if (cctx->prefix) - OPENSSL_free(cctx->prefix); - cctx->prefix = tmp; - if (tmp) - cctx->prefixlen = strlen(tmp); - else - cctx->prefixlen = 0; - return 1; -} - -void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl) -{ - cctx->ssl = ssl; - cctx->ctx = NULL; - if (ssl) { - cctx->poptions = &ssl->options; - cctx->pcert_flags = &ssl->cert->cert_flags; - } else { - cctx->poptions = NULL; - cctx->pcert_flags = NULL; - } -} - -void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx) -{ - cctx->ctx = ctx; - cctx->ssl = NULL; - if (ctx) { - cctx->poptions = &ctx->options; - cctx->pcert_flags = &ctx->cert->cert_flags; - } else { - cctx->poptions = NULL; - cctx->pcert_flags = NULL; - } -} diff --git a/thirdparty/openssl/ssl/ssl_err.c b/thirdparty/openssl/ssl/ssl_err.c deleted file mode 100644 index a4c17a6bf3..0000000000 --- a/thirdparty/openssl/ssl/ssl_err.c +++ /dev/null @@ -1,840 +0,0 @@ -/* ssl/ssl_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2016 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 - * openssl-core@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). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include <stdio.h> -#include <openssl/err.h> -#include <openssl/ssl.h> - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_SSL,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_SSL,0,reason) - -static ERR_STRING_DATA SSL_str_functs[] = { - {ERR_FUNC(SSL_F_CHECK_SUITEB_CIPHER_LIST), "CHECK_SUITEB_CIPHER_LIST"}, - {ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"}, - {ERR_FUNC(SSL_F_CLIENT_FINISHED), "CLIENT_FINISHED"}, - {ERR_FUNC(SSL_F_CLIENT_HELLO), "CLIENT_HELLO"}, - {ERR_FUNC(SSL_F_CLIENT_MASTER_KEY), "CLIENT_MASTER_KEY"}, - {ERR_FUNC(SSL_F_D2I_SSL_SESSION), "d2i_SSL_SESSION"}, - {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"}, - {ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF), "DTLS1_ADD_CERT_TO_BUF"}, - {ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD), "DTLS1_BUFFER_RECORD"}, - {ERR_FUNC(SSL_F_DTLS1_CHECK_TIMEOUT_NUM), "dtls1_check_timeout_num"}, - {ERR_FUNC(SSL_F_DTLS1_CLIENT_HELLO), "dtls1_client_hello"}, - {ERR_FUNC(SSL_F_DTLS1_CONNECT), "dtls1_connect"}, - {ERR_FUNC(SSL_F_DTLS1_GET_HELLO_VERIFY), "DTLS1_GET_HELLO_VERIFY"}, - {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE), "dtls1_get_message"}, - {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT), - "DTLS1_GET_MESSAGE_FRAGMENT"}, - {ERR_FUNC(SSL_F_DTLS1_GET_RECORD), "dtls1_get_record"}, - {ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT), "dtls1_handle_timeout"}, - {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "dtls1_heartbeat"}, - {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "dtls1_output_cert_chain"}, - {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"}, - {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS), - "DTLS1_PROCESS_BUFFERED_RECORDS"}, - {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), - "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, - {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, - {ERR_FUNC(SSL_F_DTLS1_READ_BYTES), "dtls1_read_bytes"}, - {ERR_FUNC(SSL_F_DTLS1_READ_FAILED), "dtls1_read_failed"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST), - "dtls1_send_certificate_request"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE), - "dtls1_send_client_certificate"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE), - "dtls1_send_client_key_exchange"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_VERIFY), "dtls1_send_client_verify"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST), - "DTLS1_SEND_HELLO_VERIFY_REQUEST"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE), - "dtls1_send_server_certificate"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_HELLO), "dtls1_send_server_hello"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE), - "dtls1_send_server_key_exchange"}, - {ERR_FUNC(SSL_F_DTLS1_WRITE_APP_DATA_BYTES), - "dtls1_write_app_data_bytes"}, - {ERR_FUNC(SSL_F_GET_CLIENT_FINISHED), "GET_CLIENT_FINISHED"}, - {ERR_FUNC(SSL_F_GET_CLIENT_HELLO), "GET_CLIENT_HELLO"}, - {ERR_FUNC(SSL_F_GET_CLIENT_MASTER_KEY), "GET_CLIENT_MASTER_KEY"}, - {ERR_FUNC(SSL_F_GET_SERVER_FINISHED), "GET_SERVER_FINISHED"}, - {ERR_FUNC(SSL_F_GET_SERVER_HELLO), "GET_SERVER_HELLO"}, - {ERR_FUNC(SSL_F_GET_SERVER_STATIC_DH_KEY), "GET_SERVER_STATIC_DH_KEY"}, - {ERR_FUNC(SSL_F_GET_SERVER_VERIFY), "GET_SERVER_VERIFY"}, - {ERR_FUNC(SSL_F_I2D_SSL_SESSION), "i2d_SSL_SESSION"}, - {ERR_FUNC(SSL_F_READ_N), "READ_N"}, - {ERR_FUNC(SSL_F_REQUEST_CERTIFICATE), "REQUEST_CERTIFICATE"}, - {ERR_FUNC(SSL_F_SERVER_FINISH), "SERVER_FINISH"}, - {ERR_FUNC(SSL_F_SERVER_HELLO), "SERVER_HELLO"}, - {ERR_FUNC(SSL_F_SERVER_VERIFY), "SERVER_VERIFY"}, - {ERR_FUNC(SSL_F_SSL23_ACCEPT), "ssl23_accept"}, - {ERR_FUNC(SSL_F_SSL23_CLIENT_HELLO), "SSL23_CLIENT_HELLO"}, - {ERR_FUNC(SSL_F_SSL23_CONNECT), "ssl23_connect"}, - {ERR_FUNC(SSL_F_SSL23_GET_CLIENT_HELLO), "SSL23_GET_CLIENT_HELLO"}, - {ERR_FUNC(SSL_F_SSL23_GET_SERVER_HELLO), "SSL23_GET_SERVER_HELLO"}, - {ERR_FUNC(SSL_F_SSL23_PEEK), "ssl23_peek"}, - {ERR_FUNC(SSL_F_SSL23_READ), "ssl23_read"}, - {ERR_FUNC(SSL_F_SSL23_WRITE), "ssl23_write"}, - {ERR_FUNC(SSL_F_SSL2_ACCEPT), "ssl2_accept"}, - {ERR_FUNC(SSL_F_SSL2_CONNECT), "ssl2_connect"}, - {ERR_FUNC(SSL_F_SSL2_ENC_INIT), "ssl2_enc_init"}, - {ERR_FUNC(SSL_F_SSL2_GENERATE_KEY_MATERIAL), - "ssl2_generate_key_material"}, - {ERR_FUNC(SSL_F_SSL2_PEEK), "ssl2_peek"}, - {ERR_FUNC(SSL_F_SSL2_READ), "ssl2_read"}, - {ERR_FUNC(SSL_F_SSL2_READ_INTERNAL), "SSL2_READ_INTERNAL"}, - {ERR_FUNC(SSL_F_SSL2_SET_CERTIFICATE), "ssl2_set_certificate"}, - {ERR_FUNC(SSL_F_SSL2_WRITE), "ssl2_write"}, - {ERR_FUNC(SSL_F_SSL3_ACCEPT), "ssl3_accept"}, - {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"}, - {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "ssl3_callback_ctrl"}, - {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "ssl3_change_cipher_state"}, - {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), - "ssl3_check_cert_and_algorithm"}, - {ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "ssl3_check_client_hello"}, - {ERR_FUNC(SSL_F_SSL3_CHECK_FINISHED), "SSL3_CHECK_FINISHED"}, - {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "ssl3_client_hello"}, - {ERR_FUNC(SSL_F_SSL3_CONNECT), "ssl3_connect"}, - {ERR_FUNC(SSL_F_SSL3_CTRL), "ssl3_ctrl"}, - {ERR_FUNC(SSL_F_SSL3_CTX_CTRL), "ssl3_ctx_ctrl"}, - {ERR_FUNC(SSL_F_SSL3_DIGEST_CACHED_RECORDS), - "ssl3_digest_cached_records"}, - {ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC), - "ssl3_do_change_cipher_spec"}, - {ERR_FUNC(SSL_F_SSL3_ENC), "ssl3_enc"}, - {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"}, - {ERR_FUNC(SSL_F_SSL3_GENERATE_MASTER_SECRET), - "ssl3_generate_master_secret"}, - {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST), - "ssl3_get_certificate_request"}, - {ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS), "ssl3_get_cert_status"}, - {ERR_FUNC(SSL_F_SSL3_GET_CERT_VERIFY), "ssl3_get_cert_verify"}, - {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_CERTIFICATE), - "ssl3_get_client_certificate"}, - {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_HELLO), "ssl3_get_client_hello"}, - {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE), - "ssl3_get_client_key_exchange"}, - {ERR_FUNC(SSL_F_SSL3_GET_FINISHED), "ssl3_get_finished"}, - {ERR_FUNC(SSL_F_SSL3_GET_KEY_EXCHANGE), "ssl3_get_key_exchange"}, - {ERR_FUNC(SSL_F_SSL3_GET_MESSAGE), "ssl3_get_message"}, - {ERR_FUNC(SSL_F_SSL3_GET_NEW_SESSION_TICKET), - "ssl3_get_new_session_ticket"}, - {ERR_FUNC(SSL_F_SSL3_GET_NEXT_PROTO), "ssl3_get_next_proto"}, - {ERR_FUNC(SSL_F_SSL3_GET_RECORD), "SSL3_GET_RECORD"}, - {ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE), - "ssl3_get_server_certificate"}, - {ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE), "ssl3_get_server_done"}, - {ERR_FUNC(SSL_F_SSL3_GET_SERVER_HELLO), "ssl3_get_server_hello"}, - {ERR_FUNC(SSL_F_SSL3_HANDSHAKE_MAC), "ssl3_handshake_mac"}, - {ERR_FUNC(SSL_F_SSL3_NEW_SESSION_TICKET), "SSL3_NEW_SESSION_TICKET"}, - {ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN), "ssl3_output_cert_chain"}, - {ERR_FUNC(SSL_F_SSL3_PEEK), "ssl3_peek"}, - {ERR_FUNC(SSL_F_SSL3_READ_BYTES), "ssl3_read_bytes"}, - {ERR_FUNC(SSL_F_SSL3_READ_N), "ssl3_read_n"}, - {ERR_FUNC(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST), - "ssl3_send_certificate_request"}, - {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE), - "ssl3_send_client_certificate"}, - {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE), - "ssl3_send_client_key_exchange"}, - {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_VERIFY), "ssl3_send_client_verify"}, - {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_CERTIFICATE), - "ssl3_send_server_certificate"}, - {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_HELLO), "ssl3_send_server_hello"}, - {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE), - "ssl3_send_server_key_exchange"}, - {ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK), "ssl3_setup_key_block"}, - {ERR_FUNC(SSL_F_SSL3_SETUP_READ_BUFFER), "ssl3_setup_read_buffer"}, - {ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER), "ssl3_setup_write_buffer"}, - {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "ssl3_write_bytes"}, - {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "ssl3_write_pending"}, - {ERR_FUNC(SSL_F_SSL_ADD_CERT_CHAIN), "ssl_add_cert_chain"}, - {ERR_FUNC(SSL_F_SSL_ADD_CERT_TO_BUF), "SSL_ADD_CERT_TO_BUF"}, - {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT), - "ssl_add_clienthello_renegotiate_ext"}, - {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT), - "ssl_add_clienthello_tlsext"}, - {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT), - "ssl_add_clienthello_use_srtp_ext"}, - {ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK), - "SSL_add_dir_cert_subjects_to_stack"}, - {ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK), - "SSL_add_file_cert_subjects_to_stack"}, - {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT), - "ssl_add_serverhello_renegotiate_ext"}, - {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT), - "ssl_add_serverhello_tlsext"}, - {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT), - "ssl_add_serverhello_use_srtp_ext"}, - {ERR_FUNC(SSL_F_SSL_BAD_METHOD), "ssl_bad_method"}, - {ERR_FUNC(SSL_F_SSL_BUILD_CERT_CHAIN), "ssl_build_cert_chain"}, - {ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "ssl_bytes_to_cipher_list"}, - {ERR_FUNC(SSL_F_SSL_CERT_DUP), "ssl_cert_dup"}, - {ERR_FUNC(SSL_F_SSL_CERT_INST), "ssl_cert_inst"}, - {ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE), "SSL_CERT_INSTANTIATE"}, - {ERR_FUNC(SSL_F_SSL_CERT_NEW), "ssl_cert_new"}, - {ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY), "SSL_check_private_key"}, - {ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT), - "SSL_CHECK_SERVERHELLO_TLSEXT"}, - {ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG), - "ssl_check_srvr_ecc_cert_and_alg"}, - {ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR), - "SSL_CIPHER_PROCESS_RULESTR"}, - {ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT), "SSL_CIPHER_STRENGTH_SORT"}, - {ERR_FUNC(SSL_F_SSL_CLEAR), "SSL_clear"}, - {ERR_FUNC(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD), - "SSL_COMP_add_compression_method"}, - {ERR_FUNC(SSL_F_SSL_CONF_CMD), "SSL_CONF_cmd"}, - {ERR_FUNC(SSL_F_SSL_CREATE_CIPHER_LIST), "ssl_create_cipher_list"}, - {ERR_FUNC(SSL_F_SSL_CTRL), "SSL_ctrl"}, - {ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY), "SSL_CTX_check_private_key"}, - {ERR_FUNC(SSL_F_SSL_CTX_MAKE_PROFILES), "SSL_CTX_MAKE_PROFILES"}, - {ERR_FUNC(SSL_F_SSL_CTX_NEW), "SSL_CTX_new"}, - {ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST), "SSL_CTX_set_cipher_list"}, - {ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE), - "SSL_CTX_set_client_cert_engine"}, - {ERR_FUNC(SSL_F_SSL_CTX_SET_PURPOSE), "SSL_CTX_set_purpose"}, - {ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT), - "SSL_CTX_set_session_id_context"}, - {ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION), "SSL_CTX_set_ssl_version"}, - {ERR_FUNC(SSL_F_SSL_CTX_SET_TRUST), "SSL_CTX_set_trust"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE), "SSL_CTX_use_certificate"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1), - "SSL_CTX_use_certificate_ASN1"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE), - "SSL_CTX_use_certificate_chain_file"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE), - "SSL_CTX_use_certificate_file"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY), "SSL_CTX_use_PrivateKey"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1), - "SSL_CTX_use_PrivateKey_ASN1"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE), - "SSL_CTX_use_PrivateKey_file"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT), - "SSL_CTX_use_psk_identity_hint"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY), "SSL_CTX_use_RSAPrivateKey"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1), - "SSL_CTX_use_RSAPrivateKey_ASN1"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE), - "SSL_CTX_use_RSAPrivateKey_file"}, - {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_DO_HANDSHAKE), "SSL_do_handshake"}, - {ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION), "ssl_get_new_session"}, - {ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "ssl_get_prev_session"}, - {ERR_FUNC(SSL_F_SSL_GET_SERVER_CERT_INDEX), "SSL_GET_SERVER_CERT_INDEX"}, - {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT), "SSL_GET_SERVER_SEND_CERT"}, - {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY), "ssl_get_server_send_pkey"}, - {ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "ssl_get_sign_pkey"}, - {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "ssl_init_wbio_buffer"}, - {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"}, - {ERR_FUNC(SSL_F_SSL_NEW), "SSL_new"}, - {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT), - "ssl_parse_clienthello_renegotiate_ext"}, - {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT), - "ssl_parse_clienthello_tlsext"}, - {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT), - "ssl_parse_clienthello_use_srtp_ext"}, - {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT), - "ssl_parse_serverhello_renegotiate_ext"}, - {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT), - "ssl_parse_serverhello_tlsext"}, - {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT), - "ssl_parse_serverhello_use_srtp_ext"}, - {ERR_FUNC(SSL_F_SSL_PEEK), "SSL_peek"}, - {ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT), - "ssl_prepare_clienthello_tlsext"}, - {ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT), - "ssl_prepare_serverhello_tlsext"}, - {ERR_FUNC(SSL_F_SSL_READ), "SSL_read"}, - {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"}, - {ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"}, - {ERR_FUNC(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT), - "SSL_SCAN_CLIENTHELLO_TLSEXT"}, - {ERR_FUNC(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT), - "SSL_SCAN_SERVERHELLO_TLSEXT"}, - {ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"}, - {ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"}, - {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"}, - {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), - "SSL_SESSION_set1_id_context"}, - {ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "ssl_sess_cert_new"}, - {ERR_FUNC(SSL_F_SSL_SET_CERT), "SSL_SET_CERT"}, - {ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"}, - {ERR_FUNC(SSL_F_SSL_SET_FD), "SSL_set_fd"}, - {ERR_FUNC(SSL_F_SSL_SET_PKEY), "SSL_SET_PKEY"}, - {ERR_FUNC(SSL_F_SSL_SET_PURPOSE), "SSL_set_purpose"}, - {ERR_FUNC(SSL_F_SSL_SET_RFD), "SSL_set_rfd"}, - {ERR_FUNC(SSL_F_SSL_SET_SESSION), "SSL_set_session"}, - {ERR_FUNC(SSL_F_SSL_SET_SESSION_ID_CONTEXT), - "SSL_set_session_id_context"}, - {ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), - "SSL_set_session_ticket_ext"}, - {ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"}, - {ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"}, - {ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"}, - {ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_init"}, - {ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), - "ssl_undefined_const_function"}, - {ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "ssl_undefined_function"}, - {ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), - "ssl_undefined_void_function"}, - {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE), "SSL_use_certificate"}, - {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1), "SSL_use_certificate_ASN1"}, - {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE), "SSL_use_certificate_file"}, - {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY), "SSL_use_PrivateKey"}, - {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_ASN1), "SSL_use_PrivateKey_ASN1"}, - {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_FILE), "SSL_use_PrivateKey_file"}, - {ERR_FUNC(SSL_F_SSL_USE_PSK_IDENTITY_HINT), "SSL_use_psk_identity_hint"}, - {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY), "SSL_use_RSAPrivateKey"}, - {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1), - "SSL_use_RSAPrivateKey_ASN1"}, - {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE), - "SSL_use_RSAPrivateKey_file"}, - {ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "ssl_verify_cert_chain"}, - {ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"}, - {ERR_FUNC(SSL_F_TLS12_CHECK_PEER_SIGALG), "tls12_check_peer_sigalg"}, - {ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC), "tls1_cert_verify_mac"}, - {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE), "tls1_change_cipher_state"}, - {ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT), - "TLS1_CHECK_SERVERHELLO_TLSEXT"}, - {ERR_FUNC(SSL_F_TLS1_ENC), "tls1_enc"}, - {ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), - "tls1_export_keying_material"}, - {ERR_FUNC(SSL_F_TLS1_GET_CURVELIST), "TLS1_GET_CURVELIST"}, - {ERR_FUNC(SSL_F_TLS1_HEARTBEAT), "tls1_heartbeat"}, - {ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT), - "TLS1_PREPARE_CLIENTHELLO_TLSEXT"}, - {ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT), - "TLS1_PREPARE_SERVERHELLO_TLSEXT"}, - {ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"}, - {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "tls1_setup_key_block"}, - {ERR_FUNC(SSL_F_TLS1_SET_SERVER_SIGALGS), "tls1_set_server_sigalgs"}, - {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"}, - {0, NULL} -}; - -static ERR_STRING_DATA SSL_str_reasons[] = { - {ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE), "app data in handshake"}, - {ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT), - "attempt to reuse session in different context"}, - {ERR_REASON(SSL_R_BAD_ALERT_RECORD), "bad alert record"}, - {ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE), "bad authentication type"}, - {ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC), "bad change cipher spec"}, - {ERR_REASON(SSL_R_BAD_CHECKSUM), "bad checksum"}, - {ERR_REASON(SSL_R_BAD_DATA), "bad data"}, - {ERR_REASON(SSL_R_BAD_DATA_RETURNED_BY_CALLBACK), - "bad data returned by callback"}, - {ERR_REASON(SSL_R_BAD_DECOMPRESSION), "bad decompression"}, - {ERR_REASON(SSL_R_BAD_DH_G_LENGTH), "bad dh g length"}, - {ERR_REASON(SSL_R_BAD_DH_G_VALUE), "bad dh g value"}, - {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH), "bad dh pub key length"}, - {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_VALUE), "bad dh pub key value"}, - {ERR_REASON(SSL_R_BAD_DH_P_LENGTH), "bad dh p length"}, - {ERR_REASON(SSL_R_BAD_DH_P_VALUE), "bad dh p value"}, - {ERR_REASON(SSL_R_BAD_DIGEST_LENGTH), "bad digest length"}, - {ERR_REASON(SSL_R_BAD_DSA_SIGNATURE), "bad dsa signature"}, - {ERR_REASON(SSL_R_BAD_ECC_CERT), "bad ecc cert"}, - {ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE), "bad ecdsa signature"}, - {ERR_REASON(SSL_R_BAD_ECPOINT), "bad ecpoint"}, - {ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH), "bad handshake length"}, - {ERR_REASON(SSL_R_BAD_HELLO_REQUEST), "bad hello request"}, - {ERR_REASON(SSL_R_BAD_LENGTH), "bad length"}, - {ERR_REASON(SSL_R_BAD_MAC_DECODE), "bad mac decode"}, - {ERR_REASON(SSL_R_BAD_MAC_LENGTH), "bad mac length"}, - {ERR_REASON(SSL_R_BAD_MESSAGE_TYPE), "bad message type"}, - {ERR_REASON(SSL_R_BAD_PACKET_LENGTH), "bad packet length"}, - {ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER), - "bad protocol version number"}, - {ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH), - "bad psk identity hint length"}, - {ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT), "bad response argument"}, - {ERR_REASON(SSL_R_BAD_RSA_DECRYPT), "bad rsa decrypt"}, - {ERR_REASON(SSL_R_BAD_RSA_ENCRYPT), "bad rsa encrypt"}, - {ERR_REASON(SSL_R_BAD_RSA_E_LENGTH), "bad rsa e length"}, - {ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH), "bad rsa modulus length"}, - {ERR_REASON(SSL_R_BAD_RSA_SIGNATURE), "bad rsa signature"}, - {ERR_REASON(SSL_R_BAD_SIGNATURE), "bad signature"}, - {ERR_REASON(SSL_R_BAD_SRP_A_LENGTH), "bad srp a length"}, - {ERR_REASON(SSL_R_BAD_SRP_B_LENGTH), "bad srp b length"}, - {ERR_REASON(SSL_R_BAD_SRP_G_LENGTH), "bad srp g length"}, - {ERR_REASON(SSL_R_BAD_SRP_N_LENGTH), "bad srp n length"}, - {ERR_REASON(SSL_R_BAD_SRP_PARAMETERS), "bad srp parameters"}, - {ERR_REASON(SSL_R_BAD_SRP_S_LENGTH), "bad srp s length"}, - {ERR_REASON(SSL_R_BAD_SRTP_MKI_VALUE), "bad srtp mki value"}, - {ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST), - "bad srtp protection profile list"}, - {ERR_REASON(SSL_R_BAD_SSL_FILETYPE), "bad ssl filetype"}, - {ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH), - "bad ssl session id length"}, - {ERR_REASON(SSL_R_BAD_STATE), "bad state"}, - {ERR_REASON(SSL_R_BAD_VALUE), "bad value"}, - {ERR_REASON(SSL_R_BAD_WRITE_RETRY), "bad write retry"}, - {ERR_REASON(SSL_R_BIO_NOT_SET), "bio not set"}, - {ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG), - "block cipher pad is wrong"}, - {ERR_REASON(SSL_R_BN_LIB), "bn lib"}, - {ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH), "ca dn length mismatch"}, - {ERR_REASON(SSL_R_CA_DN_TOO_LONG), "ca dn too long"}, - {ERR_REASON(SSL_R_CCS_RECEIVED_EARLY), "ccs received early"}, - {ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED), - "certificate verify failed"}, - {ERR_REASON(SSL_R_CERT_CB_ERROR), "cert cb error"}, - {ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH), "cert length mismatch"}, - {ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT), "challenge is different"}, - {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH), "cipher code wrong length"}, - {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE), - "cipher or hash unavailable"}, - {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR), "cipher table src error"}, - {ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT), "clienthello tlsext"}, - {ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG), - "compressed length too long"}, - {ERR_REASON(SSL_R_COMPRESSION_DISABLED), "compression disabled"}, - {ERR_REASON(SSL_R_COMPRESSION_FAILURE), "compression failure"}, - {ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE), - "compression id not within private range"}, - {ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR), - "compression library error"}, - {ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT), - "connection id is different"}, - {ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET), "connection type not set"}, - {ERR_REASON(SSL_R_COOKIE_MISMATCH), "cookie mismatch"}, - {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"}, - {ERR_REASON(SSL_R_DECRYPTION_FAILED), "decryption failed"}, - {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC), - "decryption failed or bad record mac"}, - {ERR_REASON(SSL_R_DH_KEY_TOO_SMALL), "dh key too small"}, - {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG), - "dh public value length is wrong"}, - {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED), "digest check failed"}, - {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG), "dtls message too big"}, - {ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID), "duplicate compression id"}, - {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT), - "ecc cert not for key agreement"}, - {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING), "ecc cert not for signing"}, - {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE), - "ecc cert should have rsa signature"}, - {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE), - "ecc cert should have sha1 signature"}, - {ERR_REASON(SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE), - "ecdh required for suiteb mode"}, - {ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER), - "ecgroup too large for cipher"}, - {ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST), - "empty srtp protection profile list"}, - {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG), - "encrypted length too long"}, - {ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY), - "error generating tmp rsa key"}, - {ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST), - "error in received cipher list"}, - {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_GOT_A_FIN_BEFORE_A_CCS), "got a fin before a ccs"}, - {ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS), - "got next proto before a ccs"}, - {ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION), - "got next proto without seeing extension"}, - {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST), "https proxy request"}, - {ERR_REASON(SSL_R_HTTP_REQUEST), "http request"}, - {ERR_REASON(SSL_R_ILLEGAL_PADDING), "illegal padding"}, - {ERR_REASON(SSL_R_ILLEGAL_SUITEB_DIGEST), "illegal Suite B digest"}, - {ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"}, - {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"}, - {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"}, - {ERR_REASON(SSL_R_INVALID_COMMAND), "invalid command"}, - {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM), - "invalid compression algorithm"}, - {ERR_REASON(SSL_R_INVALID_NULL_CMD_NAME), "invalid null cmd name"}, - {ERR_REASON(SSL_R_INVALID_PURPOSE), "invalid purpose"}, - {ERR_REASON(SSL_R_INVALID_SERVERINFO_DATA), "invalid serverinfo data"}, - {ERR_REASON(SSL_R_INVALID_SRP_USERNAME), "invalid srp username"}, - {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE), "invalid status response"}, - {ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH), - "invalid ticket keys length"}, - {ERR_REASON(SSL_R_INVALID_TRUST), "invalid trust"}, - {ERR_REASON(SSL_R_KEY_ARG_TOO_LONG), "key arg too long"}, - {ERR_REASON(SSL_R_KRB5), "krb5"}, - {ERR_REASON(SSL_R_KRB5_C_CC_PRINC), "krb5 client cc principal (no tkt?)"}, - {ERR_REASON(SSL_R_KRB5_C_GET_CRED), "krb5 client get cred"}, - {ERR_REASON(SSL_R_KRB5_C_INIT), "krb5 client init"}, - {ERR_REASON(SSL_R_KRB5_C_MK_REQ), "krb5 client mk_req (expired tkt?)"}, - {ERR_REASON(SSL_R_KRB5_S_BAD_TICKET), "krb5 server bad ticket"}, - {ERR_REASON(SSL_R_KRB5_S_INIT), "krb5 server init"}, - {ERR_REASON(SSL_R_KRB5_S_RD_REQ), "krb5 server rd_req (keytab perms?)"}, - {ERR_REASON(SSL_R_KRB5_S_TKT_EXPIRED), "krb5 server tkt expired"}, - {ERR_REASON(SSL_R_KRB5_S_TKT_NYV), "krb5 server tkt not yet valid"}, - {ERR_REASON(SSL_R_KRB5_S_TKT_SKEW), "krb5 server tkt skew"}, - {ERR_REASON(SSL_R_LENGTH_MISMATCH), "length mismatch"}, - {ERR_REASON(SSL_R_LENGTH_TOO_SHORT), "length too short"}, - {ERR_REASON(SSL_R_LIBRARY_BUG), "library bug"}, - {ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"}, - {ERR_REASON(SSL_R_MESSAGE_TOO_LONG), "message too long"}, - {ERR_REASON(SSL_R_MISSING_DH_DSA_CERT), "missing dh dsa cert"}, - {ERR_REASON(SSL_R_MISSING_DH_KEY), "missing dh key"}, - {ERR_REASON(SSL_R_MISSING_DH_RSA_CERT), "missing dh rsa cert"}, - {ERR_REASON(SSL_R_MISSING_DSA_SIGNING_CERT), "missing dsa signing cert"}, - {ERR_REASON(SSL_R_MISSING_ECDH_CERT), "missing ecdh cert"}, - {ERR_REASON(SSL_R_MISSING_ECDSA_SIGNING_CERT), - "missing ecdsa signing cert"}, - {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_DH_KEY), - "missing export tmp dh key"}, - {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_RSA_KEY), - "missing export tmp rsa key"}, - {ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE), "missing rsa certificate"}, - {ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT), - "missing rsa encrypting cert"}, - {ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT), "missing rsa signing cert"}, - {ERR_REASON(SSL_R_MISSING_SRP_PARAM), "can't find SRP server param"}, - {ERR_REASON(SSL_R_MISSING_TMP_DH_KEY), "missing tmp dh key"}, - {ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY), "missing tmp ecdh key"}, - {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY), "missing tmp rsa key"}, - {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY), "missing tmp rsa pkey"}, - {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE), "missing verify message"}, - {ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS), "multiple sgc restarts"}, - {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET), "non sslv2 initial packet"}, - {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED), "no certificates returned"}, - {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED), "no certificate assigned"}, - {ERR_REASON(SSL_R_NO_CERTIFICATE_RETURNED), "no certificate returned"}, - {ERR_REASON(SSL_R_NO_CERTIFICATE_SET), "no certificate set"}, - {ERR_REASON(SSL_R_NO_CERTIFICATE_SPECIFIED), "no certificate specified"}, - {ERR_REASON(SSL_R_NO_CIPHERS_AVAILABLE), "no ciphers available"}, - {ERR_REASON(SSL_R_NO_CIPHERS_PASSED), "no ciphers passed"}, - {ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED), "no ciphers specified"}, - {ERR_REASON(SSL_R_NO_CIPHER_LIST), "no cipher list"}, - {ERR_REASON(SSL_R_NO_CIPHER_MATCH), "no cipher match"}, - {ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD), "no client cert method"}, - {ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED), "no client cert received"}, - {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED), "no compression specified"}, - {ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER), - "Peer haven't sent GOST certificate, required for selected ciphersuite"}, - {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED), "no method specified"}, - {ERR_REASON(SSL_R_NO_PEM_EXTENSIONS), "no pem extensions"}, - {ERR_REASON(SSL_R_NO_PRIVATEKEY), "no privatekey"}, - {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED), "no private key assigned"}, - {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE), "no protocols available"}, - {ERR_REASON(SSL_R_NO_PUBLICKEY), "no publickey"}, - {ERR_REASON(SSL_R_NO_RENEGOTIATION), "no renegotiation"}, - {ERR_REASON(SSL_R_NO_REQUIRED_DIGEST), - "digest requred for handshake isn't computed"}, - {ERR_REASON(SSL_R_NO_SHARED_CIPHER), "no shared cipher"}, - {ERR_REASON(SSL_R_NO_SHARED_SIGATURE_ALGORITHMS), - "no shared sigature algorithms"}, - {ERR_REASON(SSL_R_NO_SRTP_PROFILES), "no srtp profiles"}, - {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK), "no verify callback"}, - {ERR_REASON(SSL_R_NULL_SSL_CTX), "null ssl ctx"}, - {ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED), "null ssl method passed"}, - {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED), - "old session cipher not returned"}, - {ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED), - "old session compression algorithm not returned"}, - {ERR_REASON(SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE), - "only DTLS 1.2 allowed in Suite B mode"}, - {ERR_REASON(SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE), - "only TLS 1.2 allowed in Suite B mode"}, - {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE), - "only tls allowed in fips mode"}, - {ERR_REASON(SSL_R_OPAQUE_PRF_INPUT_TOO_LONG), - "opaque PRF input too long"}, - {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG), "packet length too long"}, - {ERR_REASON(SSL_R_PARSE_TLSEXT), "parse tlsext"}, - {ERR_REASON(SSL_R_PATH_TOO_LONG), "path too long"}, - {ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE), - "peer did not return a certificate"}, - {ERR_REASON(SSL_R_PEER_ERROR), "peer error"}, - {ERR_REASON(SSL_R_PEER_ERROR_CERTIFICATE), "peer error certificate"}, - {ERR_REASON(SSL_R_PEER_ERROR_NO_CERTIFICATE), - "peer error no certificate"}, - {ERR_REASON(SSL_R_PEER_ERROR_NO_CIPHER), "peer error no cipher"}, - {ERR_REASON(SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE), - "peer error unsupported certificate type"}, - {ERR_REASON(SSL_R_PEM_NAME_BAD_PREFIX), "pem name bad prefix"}, - {ERR_REASON(SSL_R_PEM_NAME_TOO_SHORT), "pem name too short"}, - {ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG), "pre mac length too long"}, - {ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS), - "problems mapping cipher functions"}, - {ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN), "protocol is shutdown"}, - {ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND), "psk identity not found"}, - {ERR_REASON(SSL_R_PSK_NO_CLIENT_CB), "psk no client cb"}, - {ERR_REASON(SSL_R_PSK_NO_SERVER_CB), "psk no server cb"}, - {ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR), "public key encrypt error"}, - {ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA), "public key is not rsa"}, - {ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"}, - {ERR_REASON(SSL_R_READ_BIO_NOT_SET), "read bio not set"}, - {ERR_REASON(SSL_R_READ_TIMEOUT_EXPIRED), "read timeout expired"}, - {ERR_REASON(SSL_R_READ_WRONG_PACKET_TYPE), "read wrong packet type"}, - {ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH), "record length mismatch"}, - {ERR_REASON(SSL_R_RECORD_TOO_LARGE), "record too large"}, - {ERR_REASON(SSL_R_RECORD_TOO_SMALL), "record too small"}, - {ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG), "renegotiate ext too long"}, - {ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR), - "renegotiation encoding err"}, - {ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH), "renegotiation mismatch"}, - {ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING), "required cipher missing"}, - {ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING), - "required compresssion algorithm missing"}, - {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO), - "reuse cert length not zero"}, - {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO), "reuse cert type not zero"}, - {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO), - "reuse cipher list not zero"}, - {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING), - "scsv received when renegotiating"}, - {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT), "serverhello tlsext"}, - {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED), - "session id context uninitialized"}, - {ERR_REASON(SSL_R_SHORT_READ), "short read"}, - {ERR_REASON(SSL_R_SHUTDOWN_WHILE_IN_INIT), "shutdown while in init"}, - {ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR), - "signature algorithms error"}, - {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE), - "signature for non signing certificate"}, - {ERR_REASON(SSL_R_SRP_A_CALC), "error with the srp params"}, - {ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES), - "srtp could not allocate profiles"}, - {ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG), - "srtp protection profile list too long"}, - {ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE), - "srtp unknown protection profile"}, - {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE), - "ssl23 doing session id reuse"}, - {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG), - "ssl2 connection id too long"}, - {ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT), - "ssl3 ext invalid ecpointformat"}, - {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME), - "ssl3 ext invalid servername"}, - {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE), - "ssl3 ext invalid servername type"}, - {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG), "ssl3 session id too long"}, - {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT), - "ssl3 session id too short"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE), - "sslv3 alert bad certificate"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_RECORD_MAC), - "sslv3 alert bad record mac"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED), - "sslv3 alert certificate expired"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED), - "sslv3 alert certificate revoked"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN), - "sslv3 alert certificate unknown"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE), - "sslv3 alert decompression failure"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE), - "sslv3 alert handshake failure"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER), - "sslv3 alert illegal parameter"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_NO_CERTIFICATE), - "sslv3 alert no certificate"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE), - "sslv3 alert unexpected message"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE), - "sslv3 alert unsupported certificate"}, - {ERR_REASON(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION), - "ssl ctx has no default ssl version"}, - {ERR_REASON(SSL_R_SSL_HANDSHAKE_FAILURE), "ssl handshake failure"}, - {ERR_REASON(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS), - "ssl library has no ciphers"}, - {ERR_REASON(SSL_R_SSL_SESSION_ID_CALLBACK_FAILED), - "ssl session id callback failed"}, - {ERR_REASON(SSL_R_SSL_SESSION_ID_CONFLICT), "ssl session id conflict"}, - {ERR_REASON(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG), - "ssl session id context too long"}, - {ERR_REASON(SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH), - "ssl session id has bad length"}, - {ERR_REASON(SSL_R_SSL_SESSION_ID_IS_DIFFERENT), - "ssl session id is different"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED), - "tlsv1 alert access denied"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR), "tlsv1 alert decode error"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), - "tlsv1 alert decryption failed"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR), - "tlsv1 alert decrypt error"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), - "tlsv1 alert export restriction"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK), - "tlsv1 alert inappropriate fallback"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), - "tlsv1 alert insufficient security"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR), - "tlsv1 alert internal error"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), - "tlsv1 alert no renegotiation"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_PROTOCOL_VERSION), - "tlsv1 alert protocol version"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW), - "tlsv1 alert record overflow"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA), "tlsv1 alert unknown ca"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED), - "tlsv1 alert user cancelled"}, - {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE), - "tlsv1 bad certificate hash value"}, - {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE), - "tlsv1 bad certificate status response"}, - {ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE), - "tlsv1 certificate unobtainable"}, - {ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME), "tlsv1 unrecognized name"}, - {ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION), - "tlsv1 unsupported extension"}, - {ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER), - "tls client cert req with anon cipher"}, - {ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT), - "peer does not accept heartbeats"}, - {ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING), - "heartbeat request already pending"}, - {ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL), - "tls illegal exporter label"}, - {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST), - "tls invalid ecpointformat list"}, - {ERR_REASON(SSL_R_TOO_MANY_WARN_ALERTS), "too many warn alerts"}, - {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST), - "tls peer did not respond with certificate list"}, - {ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG), - "tls rsa encrypted value length is wrong"}, - {ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER), - "tried to use unsupported cipher"}, - {ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS), - "unable to decode dh certs"}, - {ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS), - "unable to decode ecdh certs"}, - {ERR_REASON(SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY), - "unable to extract public key"}, - {ERR_REASON(SSL_R_UNABLE_TO_FIND_DH_PARAMETERS), - "unable to find dh parameters"}, - {ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS), - "unable to find ecdh parameters"}, - {ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS), - "unable to find public key parameters"}, - {ERR_REASON(SSL_R_UNABLE_TO_FIND_SSL_METHOD), - "unable to find ssl method"}, - {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES), - "unable to load ssl2 md5 routines"}, - {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES), - "unable to load ssl3 md5 routines"}, - {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES), - "unable to load ssl3 sha1 routines"}, - {ERR_REASON(SSL_R_UNEXPECTED_MESSAGE), "unexpected message"}, - {ERR_REASON(SSL_R_UNEXPECTED_RECORD), "unexpected record"}, - {ERR_REASON(SSL_R_UNINITIALIZED), "uninitialized"}, - {ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE), "unknown alert type"}, - {ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE), "unknown certificate type"}, - {ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED), "unknown cipher returned"}, - {ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE), "unknown cipher type"}, - {ERR_REASON(SSL_R_UNKNOWN_CMD_NAME), "unknown cmd name"}, - {ERR_REASON(SSL_R_UNKNOWN_DIGEST), "unknown digest"}, - {ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE), - "unknown key exchange type"}, - {ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE), "unknown pkey type"}, - {ERR_REASON(SSL_R_UNKNOWN_PROTOCOL), "unknown protocol"}, - {ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE), - "unknown remote error type"}, - {ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION), "unknown ssl version"}, - {ERR_REASON(SSL_R_UNKNOWN_STATE), "unknown state"}, - {ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED), - "unsafe legacy renegotiation disabled"}, - {ERR_REASON(SSL_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, - {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM), - "unsupported compression algorithm"}, - {ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE), "unsupported digest type"}, - {ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE), - "unsupported elliptic curve"}, - {ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL), "unsupported protocol"}, - {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION), "unsupported ssl version"}, - {ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE), "unsupported status type"}, - {ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"}, - {ERR_REASON(SSL_R_WRITE_BIO_NOT_SET), "write bio not set"}, - {ERR_REASON(SSL_R_WRONG_CERTIFICATE_TYPE), "wrong certificate type"}, - {ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED), "wrong cipher returned"}, - {ERR_REASON(SSL_R_WRONG_CURVE), "wrong curve"}, - {ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE), "wrong message type"}, - {ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS), "wrong number of key bits"}, - {ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"}, - {ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE), "wrong signature size"}, - {ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE), "wrong signature type"}, - {ERR_REASON(SSL_R_WRONG_SSL_VERSION), "wrong ssl version"}, - {ERR_REASON(SSL_R_WRONG_VERSION_NUMBER), "wrong version number"}, - {ERR_REASON(SSL_R_X509_LIB), "x509 lib"}, - {ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS), - "x509 verification setup problems"}, - {0, NULL} -}; - -#endif - -void ERR_load_SSL_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) { - ERR_load_strings(0, SSL_str_functs); - ERR_load_strings(0, SSL_str_reasons); - } -#endif -} diff --git a/thirdparty/openssl/ssl/ssl_err2.c b/thirdparty/openssl/ssl/ssl_err2.c deleted file mode 100644 index 14e48221f4..0000000000 --- a/thirdparty/openssl/ssl/ssl_err2.c +++ /dev/null @@ -1,69 +0,0 @@ -/* ssl/ssl_err2.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include <openssl/err.h> -#include <openssl/ssl.h> - -void SSL_load_error_strings(void) -{ -#ifndef OPENSSL_NO_ERR - ERR_load_crypto_strings(); - ERR_load_SSL_strings(); -#endif -} diff --git a/thirdparty/openssl/ssl/ssl_lib.c b/thirdparty/openssl/ssl/ssl_lib.c deleted file mode 100644 index 24be376c9f..0000000000 --- a/thirdparty/openssl/ssl/ssl_lib.c +++ /dev/null @@ -1,3580 +0,0 @@ -/* - * ! \file ssl/ssl_lib.c \brief Version independent SSL functions. - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 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 - * openssl-core@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). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#ifdef REF_CHECK -# include <assert.h> -#endif -#include <stdio.h> -#include "ssl_locl.h" -#include "kssl_lcl.h" -#include <openssl/objects.h> -#include <openssl/lhash.h> -#include <openssl/x509v3.h> -#include <openssl/rand.h> -#include <openssl/ocsp.h> -#ifndef OPENSSL_NO_DH -# include <openssl/dh.h> -#endif -#ifndef OPENSSL_NO_ENGINE -# include <openssl/engine.h> -#endif - -const char *SSL_version_str = OPENSSL_VERSION_TEXT; - -SSL3_ENC_METHOD ssl3_undef_enc_method = { - /* - * evil casts, but these functions are only called if there's a library - * bug - */ - (int (*)(SSL *, int))ssl_undefined_function, - (int (*)(SSL *, unsigned char *, int))ssl_undefined_function, - ssl_undefined_function, - (int (*)(SSL *, unsigned char *, unsigned char *, int)) - ssl_undefined_function, - (int (*)(SSL *, int))ssl_undefined_function, - (int (*)(SSL *, const char *, int, unsigned char *)) - ssl_undefined_function, - 0, /* finish_mac_length */ - (int (*)(SSL *, int, unsigned char *))ssl_undefined_function, - NULL, /* client_finished_label */ - 0, /* client_finished_label_len */ - NULL, /* server_finished_label */ - 0, /* server_finished_label_len */ - (int (*)(int))ssl_undefined_function, - (int (*)(SSL *, unsigned char *, size_t, const char *, - size_t, const unsigned char *, size_t, - int use_context))ssl_undefined_function, -}; - -int SSL_clear(SSL *s) -{ - - if (s->method == NULL) { - SSLerr(SSL_F_SSL_CLEAR, SSL_R_NO_METHOD_SPECIFIED); - return (0); - } - - if (ssl_clear_bad_session(s)) { - SSL_SESSION_free(s->session); - s->session = NULL; - } - - s->error = 0; - s->hit = 0; - s->shutdown = 0; - -#if 0 - /* - * Disabled since version 1.10 of this file (early return not - * needed because SSL_clear is not called when doing renegotiation) - */ - /* - * This is set if we are doing dynamic renegotiation so keep - * the old cipher. It is sort of a SSL_clear_lite :-) - */ - if (s->renegotiate) - return (1); -#else - if (s->renegotiate) { - SSLerr(SSL_F_SSL_CLEAR, ERR_R_INTERNAL_ERROR); - return 0; - } -#endif - - s->type = 0; - - s->state = SSL_ST_BEFORE | ((s->server) ? SSL_ST_ACCEPT : SSL_ST_CONNECT); - - s->version = s->method->version; - s->client_version = s->version; - s->rwstate = SSL_NOTHING; - s->rstate = SSL_ST_READ_HEADER; -#if 0 - s->read_ahead = s->ctx->read_ahead; -#endif - - if (s->init_buf != NULL) { - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - } - - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); - - s->first_packet = 0; -#ifndef OPENSSL_NO_TLSEXT - if (s->cert != NULL) { - if (s->cert->alpn_proposed) { - OPENSSL_free(s->cert->alpn_proposed); - s->cert->alpn_proposed = NULL; - } - s->cert->alpn_proposed_len = 0; - s->cert->alpn_sent = 0; - } -#endif -#if 1 - /* - * Check to see if we were changed into a different method, if so, revert - * back if we are not doing session-id reuse. - */ - if (!s->in_handshake && (s->session == NULL) - && (s->method != s->ctx->method)) { - s->method->ssl_free(s); - s->method = s->ctx->method; - if (!s->method->ssl_new(s)) - return (0); - } else -#endif - s->method->ssl_clear(s); - return (1); -} - -/** Used to change an SSL_CTXs default SSL method type */ -int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) -{ - STACK_OF(SSL_CIPHER) *sk; - - ctx->method = meth; - - sk = ssl_create_cipher_list(ctx->method, &(ctx->cipher_list), - &(ctx->cipher_list_by_id), - meth->version == - SSL2_VERSION ? "SSLv2" : - SSL_DEFAULT_CIPHER_LIST, ctx->cert); - if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) { - SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION, - SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); - return (0); - } - return (1); -} - -SSL *SSL_new(SSL_CTX *ctx) -{ - SSL *s; - - if (ctx == NULL) { - SSLerr(SSL_F_SSL_NEW, SSL_R_NULL_SSL_CTX); - return (NULL); - } - if (ctx->method == NULL) { - SSLerr(SSL_F_SSL_NEW, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION); - return (NULL); - } - - s = (SSL *)OPENSSL_malloc(sizeof(SSL)); - if (s == NULL) - goto err; - memset(s, 0, sizeof(SSL)); - -#ifndef OPENSSL_NO_KRB5 - s->kssl_ctx = kssl_ctx_new(); -#endif /* OPENSSL_NO_KRB5 */ - - s->options = ctx->options; - s->mode = ctx->mode; - s->max_cert_list = ctx->max_cert_list; - s->references = 1; - - if (ctx->cert != NULL) { - /* - * Earlier library versions used to copy the pointer to the CERT, not - * its contents; only when setting new parameters for the per-SSL - * copy, ssl_cert_new would be called (and the direct reference to - * the per-SSL_CTX settings would be lost, but those still were - * indirectly accessed for various purposes, and for that reason they - * used to be known as s->ctx->default_cert). Now we don't look at the - * SSL_CTX's CERT after having duplicated it once. - */ - - s->cert = ssl_cert_dup(ctx->cert); - if (s->cert == NULL) - goto err; - } else - s->cert = NULL; /* Cannot really happen (see SSL_CTX_new) */ - - s->read_ahead = ctx->read_ahead; - s->msg_callback = ctx->msg_callback; - s->msg_callback_arg = ctx->msg_callback_arg; - s->verify_mode = ctx->verify_mode; -#if 0 - s->verify_depth = ctx->verify_depth; -#endif - s->sid_ctx_length = ctx->sid_ctx_length; - OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx); - memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx)); - s->verify_callback = ctx->default_verify_callback; - s->generate_session_id = ctx->generate_session_id; - - s->param = X509_VERIFY_PARAM_new(); - if (!s->param) - goto err; - X509_VERIFY_PARAM_inherit(s->param, ctx->param); -#if 0 - s->purpose = ctx->purpose; - s->trust = ctx->trust; -#endif - s->quiet_shutdown = ctx->quiet_shutdown; - s->max_send_fragment = ctx->max_send_fragment; - - CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); - s->ctx = ctx; -#ifndef OPENSSL_NO_TLSEXT - s->tlsext_debug_cb = 0; - s->tlsext_debug_arg = NULL; - s->tlsext_ticket_expected = 0; - s->tlsext_status_type = -1; - s->tlsext_status_expected = 0; - s->tlsext_ocsp_ids = NULL; - s->tlsext_ocsp_exts = NULL; - s->tlsext_ocsp_resp = NULL; - s->tlsext_ocsp_resplen = -1; - CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); - s->initial_ctx = ctx; -# ifndef OPENSSL_NO_EC - if (ctx->tlsext_ecpointformatlist) { - s->tlsext_ecpointformatlist = - BUF_memdup(ctx->tlsext_ecpointformatlist, - ctx->tlsext_ecpointformatlist_length); - if (!s->tlsext_ecpointformatlist) - goto err; - s->tlsext_ecpointformatlist_length = - ctx->tlsext_ecpointformatlist_length; - } - if (ctx->tlsext_ellipticcurvelist) { - s->tlsext_ellipticcurvelist = - BUF_memdup(ctx->tlsext_ellipticcurvelist, - ctx->tlsext_ellipticcurvelist_length); - if (!s->tlsext_ellipticcurvelist) - goto err; - s->tlsext_ellipticcurvelist_length = - ctx->tlsext_ellipticcurvelist_length; - } -# endif -# ifndef OPENSSL_NO_NEXTPROTONEG - s->next_proto_negotiated = NULL; -# endif - - if (s->ctx->alpn_client_proto_list) { - s->alpn_client_proto_list = - OPENSSL_malloc(s->ctx->alpn_client_proto_list_len); - if (s->alpn_client_proto_list == NULL) - goto err; - memcpy(s->alpn_client_proto_list, s->ctx->alpn_client_proto_list, - s->ctx->alpn_client_proto_list_len); - s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len; - } -#endif - - s->verify_result = X509_V_OK; - - s->method = ctx->method; - - if (!s->method->ssl_new(s)) - goto err; - - s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1; - - SSL_clear(s); - - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); - -#ifndef OPENSSL_NO_PSK - s->psk_client_callback = ctx->psk_client_callback; - s->psk_server_callback = ctx->psk_server_callback; -#endif - - return (s); - err: - if (s != NULL) - SSL_free(s); - SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); -} - -int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, - unsigned int sid_ctx_len) -{ - if (sid_ctx_len > sizeof ctx->sid_ctx) { - SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT, - SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); - return 0; - } - ctx->sid_ctx_length = sid_ctx_len; - memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len); - - return 1; -} - -int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, - unsigned int sid_ctx_len) -{ - if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { - SSLerr(SSL_F_SSL_SET_SESSION_ID_CONTEXT, - SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); - return 0; - } - ssl->sid_ctx_length = sid_ctx_len; - memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len); - - return 1; -} - -int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) -{ - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - ctx->generate_session_id = cb; - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - return 1; -} - -int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) -{ - CRYPTO_w_lock(CRYPTO_LOCK_SSL); - ssl->generate_session_id = cb; - CRYPTO_w_unlock(CRYPTO_LOCK_SSL); - return 1; -} - -int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, - unsigned int id_len) -{ - /* - * A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how - * we can "construct" a session to give us the desired check - ie. to - * find if there's a session in the hash table that would conflict with - * any new session built out of this id/id_len and the ssl_version in use - * by this SSL. - */ - SSL_SESSION r, *p; - - if (id_len > sizeof r.session_id) - return 0; - - r.ssl_version = ssl->version; - r.session_id_length = id_len; - memcpy(r.session_id, id, id_len); - /* - * NB: SSLv2 always uses a fixed 16-byte session ID, so even if a - * callback is calling us to check the uniqueness of a shorter ID, it - * must be compared as a padded-out ID because that is what it will be - * converted to when the callback has finished choosing it. - */ - if ((r.ssl_version == SSL2_VERSION) && - (id_len < SSL2_SSL_SESSION_ID_LENGTH)) { - memset(r.session_id + id_len, 0, SSL2_SSL_SESSION_ID_LENGTH - id_len); - r.session_id_length = SSL2_SSL_SESSION_ID_LENGTH; - } - - CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); - p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r); - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); - return (p != NULL); -} - -int SSL_CTX_set_purpose(SSL_CTX *s, int purpose) -{ - return X509_VERIFY_PARAM_set_purpose(s->param, purpose); -} - -int SSL_set_purpose(SSL *s, int purpose) -{ - return X509_VERIFY_PARAM_set_purpose(s->param, purpose); -} - -int SSL_CTX_set_trust(SSL_CTX *s, int trust) -{ - return X509_VERIFY_PARAM_set_trust(s->param, trust); -} - -int SSL_set_trust(SSL *s, int trust) -{ - return X509_VERIFY_PARAM_set_trust(s->param, trust); -} - -int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) -{ - return X509_VERIFY_PARAM_set1(ctx->param, vpm); -} - -int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) -{ - return X509_VERIFY_PARAM_set1(ssl->param, vpm); -} - -X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) -{ - return ctx->param; -} - -X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) -{ - return ssl->param; -} - -void SSL_certs_clear(SSL *s) -{ - ssl_cert_clear_certs(s->cert); -} - -void SSL_free(SSL *s) -{ - int i; - - if (s == NULL) - return; - - i = CRYPTO_add(&s->references, -1, CRYPTO_LOCK_SSL); -#ifdef REF_PRINT - REF_PRINT("SSL", s); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "SSL_free, bad reference count\n"); - abort(); /* ok */ - } -#endif - - if (s->param) - X509_VERIFY_PARAM_free(s->param); - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); - - if (s->bbio != NULL) { - /* If the buffering BIO is in place, pop it off */ - if (s->bbio == s->wbio) { - s->wbio = BIO_pop(s->wbio); - } - BIO_free(s->bbio); - s->bbio = NULL; - } - if (s->rbio != NULL) - BIO_free_all(s->rbio); - if ((s->wbio != NULL) && (s->wbio != s->rbio)) - BIO_free_all(s->wbio); - - if (s->init_buf != NULL) - BUF_MEM_free(s->init_buf); - - /* add extra stuff */ - if (s->cipher_list != NULL) - sk_SSL_CIPHER_free(s->cipher_list); - if (s->cipher_list_by_id != NULL) - sk_SSL_CIPHER_free(s->cipher_list_by_id); - - /* Make the next call work :-) */ - if (s->session != NULL) { - ssl_clear_bad_session(s); - SSL_SESSION_free(s->session); - } - - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); - - if (s->cert != NULL) - ssl_cert_free(s->cert); - /* Free up if allocated */ - -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_hostname) - OPENSSL_free(s->tlsext_hostname); - if (s->initial_ctx) - SSL_CTX_free(s->initial_ctx); -# ifndef OPENSSL_NO_EC - if (s->tlsext_ecpointformatlist) - OPENSSL_free(s->tlsext_ecpointformatlist); - if (s->tlsext_ellipticcurvelist) - OPENSSL_free(s->tlsext_ellipticcurvelist); -# endif /* OPENSSL_NO_EC */ - if (s->tlsext_opaque_prf_input) - OPENSSL_free(s->tlsext_opaque_prf_input); - if (s->tlsext_ocsp_exts) - sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free); - if (s->tlsext_ocsp_ids) - sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); - if (s->tlsext_ocsp_resp) - OPENSSL_free(s->tlsext_ocsp_resp); - if (s->alpn_client_proto_list) - OPENSSL_free(s->alpn_client_proto_list); -#endif - - if (s->client_CA != NULL) - sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free); - - if (s->method != NULL) - s->method->ssl_free(s); - - if (s->ctx) - SSL_CTX_free(s->ctx); - -#ifndef OPENSSL_NO_KRB5 - if (s->kssl_ctx != NULL) - kssl_ctx_free(s->kssl_ctx); -#endif /* OPENSSL_NO_KRB5 */ - -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) - if (s->next_proto_negotiated) - OPENSSL_free(s->next_proto_negotiated); -#endif - -#ifndef OPENSSL_NO_SRTP - if (s->srtp_profiles) - sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); -#endif - - OPENSSL_free(s); -} - -void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) -{ - /* - * If the output buffering BIO is still in place, remove it - */ - if (s->bbio != NULL) { - if (s->wbio == s->bbio) { - s->wbio = s->wbio->next_bio; - s->bbio->next_bio = NULL; - } - } - if ((s->rbio != NULL) && (s->rbio != rbio)) - BIO_free_all(s->rbio); - if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio)) - BIO_free_all(s->wbio); - s->rbio = rbio; - s->wbio = wbio; -} - -BIO *SSL_get_rbio(const SSL *s) -{ - return (s->rbio); -} - -BIO *SSL_get_wbio(const SSL *s) -{ - return (s->wbio); -} - -int SSL_get_fd(const SSL *s) -{ - return (SSL_get_rfd(s)); -} - -int SSL_get_rfd(const SSL *s) -{ - int ret = -1; - BIO *b, *r; - - b = SSL_get_rbio(s); - r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR); - if (r != NULL) - BIO_get_fd(r, &ret); - return (ret); -} - -int SSL_get_wfd(const SSL *s) -{ - int ret = -1; - BIO *b, *r; - - b = SSL_get_wbio(s); - r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR); - if (r != NULL) - BIO_get_fd(r, &ret); - return (ret); -} - -#ifndef OPENSSL_NO_SOCK -int SSL_set_fd(SSL *s, int fd) -{ - int ret = 0; - BIO *bio = NULL; - - bio = BIO_new(BIO_s_socket()); - - if (bio == NULL) { - SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB); - goto err; - } - BIO_set_fd(bio, fd, BIO_NOCLOSE); - SSL_set_bio(s, bio, bio); - ret = 1; - err: - return (ret); -} - -int SSL_set_wfd(SSL *s, int fd) -{ - int ret = 0; - BIO *bio = NULL; - - if ((s->rbio == NULL) || (BIO_method_type(s->rbio) != BIO_TYPE_SOCKET) - || ((int)BIO_get_fd(s->rbio, NULL) != fd)) { - bio = BIO_new(BIO_s_socket()); - - if (bio == NULL) { - SSLerr(SSL_F_SSL_SET_WFD, ERR_R_BUF_LIB); - goto err; - } - BIO_set_fd(bio, fd, BIO_NOCLOSE); - SSL_set_bio(s, SSL_get_rbio(s), bio); - } else - SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s)); - ret = 1; - err: - return (ret); -} - -int SSL_set_rfd(SSL *s, int fd) -{ - int ret = 0; - BIO *bio = NULL; - - if ((s->wbio == NULL) || (BIO_method_type(s->wbio) != BIO_TYPE_SOCKET) - || ((int)BIO_get_fd(s->wbio, NULL) != fd)) { - bio = BIO_new(BIO_s_socket()); - - if (bio == NULL) { - SSLerr(SSL_F_SSL_SET_RFD, ERR_R_BUF_LIB); - goto err; - } - BIO_set_fd(bio, fd, BIO_NOCLOSE); - SSL_set_bio(s, bio, SSL_get_wbio(s)); - } else - SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s)); - ret = 1; - err: - return (ret); -} -#endif - -/* return length of latest Finished message we sent, copy to 'buf' */ -size_t SSL_get_finished(const SSL *s, void *buf, size_t count) -{ - size_t ret = 0; - - if (s->s3 != NULL) { - ret = s->s3->tmp.finish_md_len; - if (count > ret) - count = ret; - memcpy(buf, s->s3->tmp.finish_md, count); - } - return ret; -} - -/* return length of latest Finished message we expected, copy to 'buf' */ -size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count) -{ - size_t ret = 0; - - if (s->s3 != NULL) { - ret = s->s3->tmp.peer_finish_md_len; - if (count > ret) - count = ret; - memcpy(buf, s->s3->tmp.peer_finish_md, count); - } - return ret; -} - -int SSL_get_verify_mode(const SSL *s) -{ - return (s->verify_mode); -} - -int SSL_get_verify_depth(const SSL *s) -{ - return X509_VERIFY_PARAM_get_depth(s->param); -} - -int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *) { - return (s->verify_callback); -} - -int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) -{ - return (ctx->verify_mode); -} - -int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) -{ - return X509_VERIFY_PARAM_get_depth(ctx->param); -} - -int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int, X509_STORE_CTX *) { - return (ctx->default_verify_callback); -} - -void SSL_set_verify(SSL *s, int mode, - int (*callback) (int ok, X509_STORE_CTX *ctx)) -{ - s->verify_mode = mode; - if (callback != NULL) - s->verify_callback = callback; -} - -void SSL_set_verify_depth(SSL *s, int depth) -{ - X509_VERIFY_PARAM_set_depth(s->param, depth); -} - -void SSL_set_read_ahead(SSL *s, int yes) -{ - s->read_ahead = yes; -} - -int SSL_get_read_ahead(const SSL *s) -{ - return (s->read_ahead); -} - -int SSL_pending(const SSL *s) -{ - /* - * SSL_pending cannot work properly if read-ahead is enabled - * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), and it is - * impossible to fix since SSL_pending cannot report errors that may be - * observed while scanning the new data. (Note that SSL_pending() is - * often used as a boolean value, so we'd better not return -1.) - */ - return (s->method->ssl_pending(s)); -} - -X509 *SSL_get_peer_certificate(const SSL *s) -{ - X509 *r; - - if ((s == NULL) || (s->session == NULL)) - r = NULL; - else - r = s->session->peer; - - if (r == NULL) - return (r); - - CRYPTO_add(&r->references, 1, CRYPTO_LOCK_X509); - - return (r); -} - -STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) -{ - STACK_OF(X509) *r; - - if ((s == NULL) || (s->session == NULL) - || (s->session->sess_cert == NULL)) - r = NULL; - else - r = s->session->sess_cert->cert_chain; - - /* - * If we are a client, cert_chain includes the peer's own certificate; if - * we are a server, it does not. - */ - - return (r); -} - -/* - * Now in theory, since the calling process own 't' it should be safe to - * modify. We need to be able to read f without being hassled - */ -void SSL_copy_session_id(SSL *t, const SSL *f) -{ - CERT *tmp; - - /* Do we need to to SSL locking? */ - SSL_set_session(t, SSL_get_session(f)); - - /* - * what if we are setup as SSLv2 but want to talk SSLv3 or vice-versa - */ - 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 */ - } - - tmp = t->cert; - if (f->cert != NULL) { - CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT); - t->cert = f->cert; - } else - t->cert = NULL; - if (tmp != NULL) - ssl_cert_free(tmp); - SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length); -} - -/* Fix this so it checks all the valid key/cert options */ -int SSL_CTX_check_private_key(const SSL_CTX *ctx) -{ - if ((ctx == NULL) || - (ctx->cert == NULL) || (ctx->cert->key->x509 == NULL)) { - SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, - SSL_R_NO_CERTIFICATE_ASSIGNED); - return (0); - } - if (ctx->cert->key->privatekey == NULL) { - SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, - SSL_R_NO_PRIVATE_KEY_ASSIGNED); - return (0); - } - return (X509_check_private_key - (ctx->cert->key->x509, ctx->cert->key->privatekey)); -} - -/* Fix this function so that it takes an optional type parameter */ -int SSL_check_private_key(const SSL *ssl) -{ - if (ssl == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (ssl->cert == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); - return 0; - } - if (ssl->cert->key->x509 == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); - return (0); - } - if (ssl->cert->key->privatekey == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_PRIVATE_KEY_ASSIGNED); - return (0); - } - return (X509_check_private_key(ssl->cert->key->x509, - ssl->cert->key->privatekey)); -} - -int SSL_accept(SSL *s) -{ - if (s->handshake_func == 0) - /* Not properly initialized yet */ - SSL_set_accept_state(s); - - return (s->method->ssl_accept(s)); -} - -int SSL_connect(SSL *s) -{ - if (s->handshake_func == 0) - /* Not properly initialized yet */ - SSL_set_connect_state(s); - - return (s->method->ssl_connect(s)); -} - -long SSL_get_default_timeout(const SSL *s) -{ - return (s->method->get_timeout()); -} - -int SSL_read(SSL *s, void *buf, int num) -{ - if (s->handshake_func == 0) { - SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED); - return -1; - } - - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - s->rwstate = SSL_NOTHING; - return (0); - } - return (s->method->ssl_read(s, buf, num)); -} - -int SSL_peek(SSL *s, void *buf, int num) -{ - if (s->handshake_func == 0) { - SSLerr(SSL_F_SSL_PEEK, SSL_R_UNINITIALIZED); - return -1; - } - - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - return (0); - } - return (s->method->ssl_peek(s, buf, num)); -} - -int SSL_write(SSL *s, const void *buf, int num) -{ - if (s->handshake_func == 0) { - SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED); - return -1; - } - - if (s->shutdown & SSL_SENT_SHUTDOWN) { - s->rwstate = SSL_NOTHING; - SSLerr(SSL_F_SSL_WRITE, SSL_R_PROTOCOL_IS_SHUTDOWN); - return (-1); - } - return (s->method->ssl_write(s, buf, num)); -} - -int SSL_shutdown(SSL *s) -{ - /* - * Note that this function behaves differently from what one might - * expect. Return values are 0 for no success (yet), 1 for success; but - * calling it once is usually not enough, even if blocking I/O is used - * (see ssl3_shutdown). - */ - - if (s->handshake_func == 0) { - SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_UNINITIALIZED); - return -1; - } - - if (!SSL_in_init(s)) { - return s->method->ssl_shutdown(s); - } else { - SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_SHUTDOWN_WHILE_IN_INIT); - return -1; - } -} - -int SSL_renegotiate(SSL *s) -{ - if (s->renegotiate == 0) - s->renegotiate = 1; - - s->new_session = 1; - - return (s->method->ssl_renegotiate(s)); -} - -int SSL_renegotiate_abbreviated(SSL *s) -{ - if (s->renegotiate == 0) - s->renegotiate = 1; - - s->new_session = 0; - - return (s->method->ssl_renegotiate(s)); -} - -int SSL_renegotiate_pending(SSL *s) -{ - /* - * becomes true when negotiation is requested; false again once a - * handshake has finished - */ - return (s->renegotiate != 0); -} - -long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) -{ - long l; - - switch (cmd) { - case SSL_CTRL_GET_READ_AHEAD: - return (s->read_ahead); - case SSL_CTRL_SET_READ_AHEAD: - l = s->read_ahead; - s->read_ahead = larg; - return (l); - - case SSL_CTRL_SET_MSG_CALLBACK_ARG: - s->msg_callback_arg = parg; - return 1; - - case SSL_CTRL_OPTIONS: - return (s->options |= larg); - case SSL_CTRL_CLEAR_OPTIONS: - return (s->options &= ~larg); - case SSL_CTRL_MODE: - return (s->mode |= larg); - case SSL_CTRL_CLEAR_MODE: - return (s->mode &= ~larg); - case SSL_CTRL_GET_MAX_CERT_LIST: - return (s->max_cert_list); - case SSL_CTRL_SET_MAX_CERT_LIST: - l = s->max_cert_list; - s->max_cert_list = larg; - return (l); - case SSL_CTRL_SET_MAX_SEND_FRAGMENT: - if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) - return 0; - s->max_send_fragment = larg; - return 1; - case SSL_CTRL_GET_RI_SUPPORT: - if (s->s3) - return s->s3->send_connection_binding; - else - return 0; - case SSL_CTRL_CERT_FLAGS: - return (s->cert->cert_flags |= larg); - case SSL_CTRL_CLEAR_CERT_FLAGS: - return (s->cert->cert_flags &= ~larg); - - case SSL_CTRL_GET_RAW_CIPHERLIST: - if (parg) { - if (s->cert->ciphers_raw == NULL) - return 0; - *(unsigned char **)parg = s->cert->ciphers_raw; - return (int)s->cert->ciphers_rawlen; - } else - return ssl_put_cipher_by_char(s, NULL, NULL); - default: - return (s->method->ssl_ctrl(s, cmd, larg, parg)); - } -} - -long SSL_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) -{ - switch (cmd) { - case SSL_CTRL_SET_MSG_CALLBACK: - s->msg_callback = (void (*) - (int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, - void *arg))(fp); - return 1; - - default: - return (s->method->ssl_callback_ctrl(s, cmd, fp)); - } -} - -LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) -{ - return ctx->sessions; -} - -long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) -{ - long l; - /* For some cases with ctx == NULL perform syntax checks */ - if (ctx == NULL) { - switch (cmd) { -#ifndef OPENSSL_NO_EC - case SSL_CTRL_SET_CURVES_LIST: - return tls1_set_curves_list(NULL, NULL, parg); -#endif - case SSL_CTRL_SET_SIGALGS_LIST: - case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: - return tls1_set_sigalgs_list(NULL, parg, 0); - default: - return 0; - } - } - - switch (cmd) { - case SSL_CTRL_GET_READ_AHEAD: - return (ctx->read_ahead); - case SSL_CTRL_SET_READ_AHEAD: - l = ctx->read_ahead; - ctx->read_ahead = larg; - return (l); - - case SSL_CTRL_SET_MSG_CALLBACK_ARG: - ctx->msg_callback_arg = parg; - return 1; - - case SSL_CTRL_GET_MAX_CERT_LIST: - return (ctx->max_cert_list); - case SSL_CTRL_SET_MAX_CERT_LIST: - l = ctx->max_cert_list; - ctx->max_cert_list = larg; - return (l); - - case SSL_CTRL_SET_SESS_CACHE_SIZE: - l = ctx->session_cache_size; - ctx->session_cache_size = larg; - return (l); - case SSL_CTRL_GET_SESS_CACHE_SIZE: - return (ctx->session_cache_size); - case SSL_CTRL_SET_SESS_CACHE_MODE: - l = ctx->session_cache_mode; - ctx->session_cache_mode = larg; - return (l); - case SSL_CTRL_GET_SESS_CACHE_MODE: - return (ctx->session_cache_mode); - - case SSL_CTRL_SESS_NUMBER: - return (lh_SSL_SESSION_num_items(ctx->sessions)); - case SSL_CTRL_SESS_CONNECT: - return (ctx->stats.sess_connect); - case SSL_CTRL_SESS_CONNECT_GOOD: - return (ctx->stats.sess_connect_good); - case SSL_CTRL_SESS_CONNECT_RENEGOTIATE: - return (ctx->stats.sess_connect_renegotiate); - case SSL_CTRL_SESS_ACCEPT: - return (ctx->stats.sess_accept); - case SSL_CTRL_SESS_ACCEPT_GOOD: - return (ctx->stats.sess_accept_good); - case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE: - return (ctx->stats.sess_accept_renegotiate); - case SSL_CTRL_SESS_HIT: - return (ctx->stats.sess_hit); - case SSL_CTRL_SESS_CB_HIT: - return (ctx->stats.sess_cb_hit); - case SSL_CTRL_SESS_MISSES: - return (ctx->stats.sess_miss); - case SSL_CTRL_SESS_TIMEOUTS: - return (ctx->stats.sess_timeout); - case SSL_CTRL_SESS_CACHE_FULL: - return (ctx->stats.sess_cache_full); - case SSL_CTRL_OPTIONS: - return (ctx->options |= larg); - case SSL_CTRL_CLEAR_OPTIONS: - return (ctx->options &= ~larg); - case SSL_CTRL_MODE: - return (ctx->mode |= larg); - case SSL_CTRL_CLEAR_MODE: - return (ctx->mode &= ~larg); - case SSL_CTRL_SET_MAX_SEND_FRAGMENT: - if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) - return 0; - ctx->max_send_fragment = larg; - return 1; - case SSL_CTRL_CERT_FLAGS: - return (ctx->cert->cert_flags |= larg); - case SSL_CTRL_CLEAR_CERT_FLAGS: - return (ctx->cert->cert_flags &= ~larg); - default: - return (ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg)); - } -} - -long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) -{ - switch (cmd) { - case SSL_CTRL_SET_MSG_CALLBACK: - ctx->msg_callback = (void (*) - (int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, - void *arg))(fp); - return 1; - - default: - return (ctx->method->ssl_ctx_callback_ctrl(ctx, cmd, fp)); - } -} - -int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b) -{ - long l; - - l = a->id - b->id; - if (l == 0L) - return (0); - else - return ((l > 0) ? 1 : -1); -} - -int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, - const SSL_CIPHER *const *bp) -{ - long l; - - l = (*ap)->id - (*bp)->id; - if (l == 0L) - return (0); - else - return ((l > 0) ? 1 : -1); -} - -/** return a STACK of the ciphers available for the SSL and in order of - * preference */ -STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) -{ - if (s != NULL) { - if (s->cipher_list != NULL) { - return (s->cipher_list); - } else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) { - return (s->ctx->cipher_list); - } - } - return (NULL); -} - -/** return a STACK of the ciphers available for the SSL and in order of - * algorithm id */ -STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s) -{ - if (s != NULL) { - if (s->cipher_list_by_id != NULL) { - return (s->cipher_list_by_id); - } else if ((s->ctx != NULL) && (s->ctx->cipher_list_by_id != NULL)) { - return (s->ctx->cipher_list_by_id); - } - } - return (NULL); -} - -/** The old interface to get the same thing as SSL_get_ciphers() */ -const char *SSL_get_cipher_list(const SSL *s, int n) -{ - SSL_CIPHER *c; - STACK_OF(SSL_CIPHER) *sk; - - if (s == NULL) - return (NULL); - sk = SSL_get_ciphers(s); - if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= n)) - return (NULL); - c = sk_SSL_CIPHER_value(sk, n); - if (c == NULL) - return (NULL); - return (c->name); -} - -/** specify the ciphers to be used by default by the SSL_CTX */ -int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) -{ - STACK_OF(SSL_CIPHER) *sk; - - sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list, - &ctx->cipher_list_by_id, str, ctx->cert); - /* - * ssl_create_cipher_list may return an empty stack if it was unable to - * find a cipher matching the given rule string (for example if the rule - * string specifies a cipher which has been disabled). This is not an - * error as far as ssl_create_cipher_list is concerned, and hence - * ctx->cipher_list and ctx->cipher_list_by_id has been updated. - */ - if (sk == NULL) - return 0; - else if (sk_SSL_CIPHER_num(sk) == 0) { - SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); - return 0; - } - return 1; -} - -/** specify the ciphers to be used by the SSL */ -int SSL_set_cipher_list(SSL *s, const char *str) -{ - STACK_OF(SSL_CIPHER) *sk; - - sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list, - &s->cipher_list_by_id, str, s->cert); - /* see comment in SSL_CTX_set_cipher_list */ - if (sk == NULL) - return 0; - else if (sk_SSL_CIPHER_num(sk) == 0) { - SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); - return 0; - } - return 1; -} - -/* works well for SSLv2, not so good for SSLv3 */ -char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len) -{ - char *p; - STACK_OF(SSL_CIPHER) *sk; - SSL_CIPHER *c; - int i; - - if ((s->session == NULL) || (s->session->ciphers == NULL) || (len < 2)) - return (NULL); - - p = buf; - sk = s->session->ciphers; - - if (sk_SSL_CIPHER_num(sk) == 0) - return NULL; - - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { - int n; - - c = sk_SSL_CIPHER_value(sk, i); - n = strlen(c->name); - if (n + 1 > len) { - if (p != buf) - --p; - *p = '\0'; - return buf; - } - strcpy(p, c->name); - p += n; - *(p++) = ':'; - len -= n + 1; - } - p[-1] = '\0'; - return (buf); -} - -int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, - unsigned char *p, - int (*put_cb) (const SSL_CIPHER *, - unsigned char *)) -{ - int i, j = 0; - SSL_CIPHER *c; - CERT *ct = s->cert; - unsigned char *q; - int empty_reneg_info_scsv = !s->renegotiate; - /* Set disabled masks for this session */ - ssl_set_client_disabled(s); - - if (sk == NULL) - return (0); - q = p; - if (put_cb == NULL) - put_cb = s->method->put_cipher_by_char; - - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { - c = sk_SSL_CIPHER_value(sk, i); - /* Skip disabled ciphers */ - if (c->algorithm_ssl & ct->mask_ssl || - c->algorithm_mkey & ct->mask_k || c->algorithm_auth & ct->mask_a) - continue; -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - if (c->id == SSL3_CK_SCSV) { - if (!empty_reneg_info_scsv) - continue; - else - empty_reneg_info_scsv = 0; - } -#endif - j = put_cb(c, p); - p += j; - } - /* - * If p == q, no ciphers; caller indicates an error. Otherwise, add - * applicable SCSVs. - */ - if (p != q) { - if (empty_reneg_info_scsv) { - static SSL_CIPHER scsv = { - 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - j = put_cb(&scsv, p); - p += j; -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, - "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n"); -#endif - } - if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) { - static SSL_CIPHER scsv = { - 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - j = put_cb(&scsv, p); - p += j; - } - } - - return (p - q); -} - -STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, - int num, - STACK_OF(SSL_CIPHER) **skp) -{ - const SSL_CIPHER *c; - STACK_OF(SSL_CIPHER) *sk; - int i, n; - - if (s->s3) - s->s3->send_connection_binding = 0; - - n = ssl_put_cipher_by_char(s, NULL, NULL); - if (n == 0 || (num % n) != 0) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); - return (NULL); - } - if ((skp == NULL) || (*skp == NULL)) { - sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */ - if(sk == NULL) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - return NULL; - } - } else { - sk = *skp; - sk_SSL_CIPHER_zero(sk); - } - - if (s->cert->ciphers_raw) - OPENSSL_free(s->cert->ciphers_raw); - s->cert->ciphers_raw = BUF_memdup(p, num); - if (s->cert->ciphers_raw == NULL) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - goto err; - } - s->cert->ciphers_rawlen = (size_t)num; - - for (i = 0; i < num; i += n) { - /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ - if (s->s3 && (n != 3 || !p[0]) && - (p[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) && - (p[n - 1] == (SSL3_CK_SCSV & 0xff))) { - /* SCSV fatal if renegotiating */ - if (s->renegotiate) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - goto err; - } - s->s3->send_connection_binding = 1; - p += n; -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "SCSV received by server\n"); -#endif - continue; - } - - /* Check for TLS_FALLBACK_SCSV */ - if ((n != 3 || !p[0]) && - (p[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) && - (p[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) { - /* - * The SCSV indicates that the client previously tried a higher - * version. Fail if the current version is an unexpected - * downgrade. - */ - if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_INAPPROPRIATE_FALLBACK); - if (s->s3) - ssl3_send_alert(s, SSL3_AL_FATAL, - SSL_AD_INAPPROPRIATE_FALLBACK); - goto err; - } - p += n; - continue; - } - - c = ssl_get_cipher_by_char(s, p); - p += n; - if (c != NULL) { - if (!sk_SSL_CIPHER_push(sk, c)) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - goto err; - } - } - } - - if (skp != NULL) - *skp = sk; - return (sk); - err: - if ((skp == NULL) || (*skp == NULL)) - sk_SSL_CIPHER_free(sk); - return (NULL); -} - -#ifndef OPENSSL_NO_TLSEXT -/** return a servername extension value if provided in Client Hello, or NULL. - * So far, only host_name types are defined (RFC 3546). - */ - -const char *SSL_get_servername(const SSL *s, const int type) -{ - if (type != TLSEXT_NAMETYPE_host_name) - return NULL; - - return s->session && !s->tlsext_hostname ? - s->session->tlsext_hostname : s->tlsext_hostname; -} - -int SSL_get_servername_type(const SSL *s) -{ - if (s->session - && (!s->tlsext_hostname ? s->session-> - tlsext_hostname : s->tlsext_hostname)) - return TLSEXT_NAMETYPE_host_name; - return -1; -} - -/* - * SSL_select_next_proto implements the standard protocol selection. It is - * expected that this function is called from the callback set by - * SSL_CTX_set_next_proto_select_cb. The protocol data is assumed to be a - * vector of 8-bit, length prefixed byte strings. The length byte itself is - * not included in the length. A byte string of length 0 is invalid. No byte - * string may be truncated. The current, but experimental algorithm for - * selecting the protocol is: 1) If the server doesn't support NPN then this - * is indicated to the callback. In this case, the client application has to - * abort the connection or have a default application level protocol. 2) If - * the server supports NPN, but advertises an empty list then the client - * selects the first protcol in its list, but indicates via the API that this - * fallback case was enacted. 3) Otherwise, the client finds the first - * protocol in the server's list that it supports and selects this protocol. - * This is because it's assumed that the server has better information about - * which protocol a client should use. 4) If the client doesn't support any - * of the server's advertised protocols, then this is treated the same as - * case 2. It returns either OPENSSL_NPN_NEGOTIATED if a common protocol was - * found, or OPENSSL_NPN_NO_OVERLAP if the fallback case was reached. - */ -int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, - const unsigned char *server, - unsigned int server_len, - const unsigned char *client, - unsigned int client_len) -{ - unsigned int i, j; - const unsigned char *result; - int status = OPENSSL_NPN_UNSUPPORTED; - - /* - * For each protocol in server preference order, see if we support it. - */ - for (i = 0; i < server_len;) { - for (j = 0; j < client_len;) { - if (server[i] == client[j] && - memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) { - /* We found a match */ - result = &server[i]; - status = OPENSSL_NPN_NEGOTIATED; - goto found; - } - j += client[j]; - j++; - } - i += server[i]; - i++; - } - - /* There's no overlap between our protocols and the server's list. */ - result = client; - status = OPENSSL_NPN_NO_OVERLAP; - - found: - *out = (unsigned char *)result + 1; - *outlen = result[0]; - return status; -} - -# ifndef OPENSSL_NO_NEXTPROTONEG -/* - * SSL_get0_next_proto_negotiated sets *data and *len to point to the - * client's requested protocol for this connection and returns 0. If the - * client didn't request any protocol, then *data is set to NULL. Note that - * the client can request any protocol it chooses. The value returned from - * this function need not be a member of the list of supported protocols - * provided by the callback. - */ -void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, - unsigned *len) -{ - *data = s->next_proto_negotiated; - if (!*data) { - *len = 0; - } else { - *len = s->next_proto_negotiated_len; - } -} - -/* - * SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when - * a TLS server needs a list of supported protocols for Next Protocol - * Negotiation. The returned list must be in wire format. The list is - * returned by setting |out| to point to it and |outlen| to its length. This - * memory will not be modified, but one should assume that the SSL* keeps a - * reference to it. The callback should return SSL_TLSEXT_ERR_OK if it - * wishes to advertise. Otherwise, no such extension will be included in the - * ServerHello. - */ -void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, - const unsigned char - **out, - unsigned int *outlen, - void *arg), void *arg) -{ - ctx->next_protos_advertised_cb = cb; - ctx->next_protos_advertised_cb_arg = arg; -} - -/* - * SSL_CTX_set_next_proto_select_cb sets a callback that is called when a - * client needs to select a protocol from the server's provided list. |out| - * must be set to point to the selected protocol (which may be within |in|). - * The length of the protocol name must be written into |outlen|. The - * server's advertised protocols are provided in |in| and |inlen|. The - * callback can assume that |in| is syntactically valid. The client must - * select a protocol. It is fatal to the connection if this callback returns - * a value other than SSL_TLSEXT_ERR_OK. - */ -void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, - int (*cb) (SSL *s, unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg), void *arg) -{ - ctx->next_proto_select_cb = cb; - ctx->next_proto_select_cb_arg = arg; -} -# endif - -/* - * SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|. - * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit - * length-prefixed strings). Returns 0 on success. - */ -int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, - unsigned protos_len) -{ - if (ctx->alpn_client_proto_list) - OPENSSL_free(ctx->alpn_client_proto_list); - - ctx->alpn_client_proto_list = OPENSSL_malloc(protos_len); - if (!ctx->alpn_client_proto_list) - return 1; - memcpy(ctx->alpn_client_proto_list, protos, protos_len); - ctx->alpn_client_proto_list_len = protos_len; - - return 0; -} - -/* - * SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|. - * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit - * length-prefixed strings). Returns 0 on success. - */ -int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, - unsigned protos_len) -{ - if (ssl->alpn_client_proto_list) - OPENSSL_free(ssl->alpn_client_proto_list); - - ssl->alpn_client_proto_list = OPENSSL_malloc(protos_len); - if (!ssl->alpn_client_proto_list) - return 1; - memcpy(ssl->alpn_client_proto_list, protos, protos_len); - ssl->alpn_client_proto_list_len = protos_len; - - return 0; -} - -/* - * SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is - * called during ClientHello processing in order to select an ALPN protocol - * from the client's list of offered protocols. - */ -void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, - const unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg), void *arg) -{ - ctx->alpn_select_cb = cb; - ctx->alpn_select_cb_arg = arg; -} - -/* - * SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from - * |ssl|. On return it sets |*data| to point to |*len| bytes of protocol name - * (not including the leading length-prefix byte). If the server didn't - * respond with a negotiated protocol then |*len| will be zero. - */ -void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, - unsigned *len) -{ - *data = NULL; - if (ssl->s3) - *data = ssl->s3->alpn_selected; - if (*data == NULL) - *len = 0; - else - *len = ssl->s3->alpn_selected_len; -} - -#endif /* !OPENSSL_NO_TLSEXT */ - -int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, - const char *label, size_t llen, - const unsigned char *p, size_t plen, - int use_context) -{ - if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER) - return -1; - - return s->method->ssl3_enc->export_keying_material(s, out, olen, label, - llen, p, plen, - use_context); -} - -static unsigned long ssl_session_hash(const SSL_SESSION *a) -{ - const unsigned char *session_id = a->session_id; - unsigned long l; - unsigned char tmp_storage[4]; - - if (a->session_id_length < sizeof(tmp_storage)) { - memset(tmp_storage, 0, sizeof(tmp_storage)); - memcpy(tmp_storage, a->session_id, a->session_id_length); - session_id = tmp_storage; - } - - l = (unsigned long) - ((unsigned long)session_id[0]) | - ((unsigned long)session_id[1] << 8L) | - ((unsigned long)session_id[2] << 16L) | - ((unsigned long)session_id[3] << 24L); - return (l); -} - -/* - * NB: If this function (or indeed the hash function which uses a sort of - * coarser function than this one) is changed, ensure - * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on - * being able to construct an SSL_SESSION that will collide with any existing - * session with a matching session ID. - */ -static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) -{ - if (a->ssl_version != b->ssl_version) - return (1); - if (a->session_id_length != b->session_id_length) - return (1); - return (memcmp(a->session_id, b->session_id, a->session_id_length)); -} - -/* - * These wrapper functions should remain rather than redeclaring - * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each - * variable. The reason is that the functions aren't static, they're exposed - * via ssl.h. - */ -static IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION) -static IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION) - -SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) -{ - SSL_CTX *ret = NULL; - - if (meth == NULL) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_NULL_SSL_METHOD_PASSED); - return (NULL); - } -#ifdef OPENSSL_FIPS - if (FIPS_mode() && (meth->version < TLS1_VERSION)) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - return NULL; - } -#endif - - if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); - goto err; - } - ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX)); - if (ret == NULL) - goto err; - - memset(ret, 0, sizeof(SSL_CTX)); - - ret->method = meth; - - ret->cert_store = NULL; - ret->session_cache_mode = SSL_SESS_CACHE_SERVER; - ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; - ret->session_cache_head = NULL; - ret->session_cache_tail = NULL; - - /* We take the system default */ - ret->session_timeout = meth->get_timeout(); - - ret->new_session_cb = 0; - ret->remove_session_cb = 0; - ret->get_session_cb = 0; - ret->generate_session_id = 0; - - memset((char *)&ret->stats, 0, sizeof(ret->stats)); - - ret->references = 1; - ret->quiet_shutdown = 0; - -/* ret->cipher=NULL;*/ -/*- - ret->s2->challenge=NULL; - ret->master_key=NULL; - ret->key_arg=NULL; - ret->s2->conn_id=NULL; */ - - ret->info_callback = NULL; - - ret->app_verify_callback = 0; - ret->app_verify_arg = NULL; - - ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; - ret->read_ahead = 0; - ret->msg_callback = 0; - ret->msg_callback_arg = NULL; - ret->verify_mode = SSL_VERIFY_NONE; -#if 0 - ret->verify_depth = -1; /* Don't impose a limit (but x509_lu.c does) */ -#endif - ret->sid_ctx_length = 0; - ret->default_verify_callback = NULL; - if ((ret->cert = ssl_cert_new()) == NULL) - goto err; - - ret->default_passwd_callback = 0; - ret->default_passwd_callback_userdata = NULL; - ret->client_cert_cb = 0; - ret->app_gen_cookie_cb = 0; - ret->app_verify_cookie_cb = 0; - - ret->sessions = lh_SSL_SESSION_new(); - if (ret->sessions == NULL) - goto err; - ret->cert_store = X509_STORE_new(); - if (ret->cert_store == NULL) - goto err; - - ssl_create_cipher_list(ret->method, - &ret->cipher_list, &ret->cipher_list_by_id, - meth->version == - SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST, - ret->cert); - if (ret->cipher_list == NULL || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_LIBRARY_HAS_NO_CIPHERS); - goto err2; - } - - ret->param = X509_VERIFY_PARAM_new(); - if (!ret->param) - goto err; - - if ((ret->rsa_md5 = EVP_get_digestbyname("ssl2-md5")) == NULL) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES); - goto err2; - } - if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES); - goto err2; - } - if ((ret->sha1 = EVP_get_digestbyname("ssl3-sha1")) == NULL) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES); - goto err2; - } - - if ((ret->client_CA = sk_X509_NAME_new_null()) == NULL) - goto err; - - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data); - - ret->extra_certs = NULL; - /* No compression for DTLS */ - if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)) - ret->comp_methods = SSL_COMP_get_compression_methods(); - - ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; - -#ifndef OPENSSL_NO_TLSEXT - ret->tlsext_servername_callback = 0; - ret->tlsext_servername_arg = NULL; - /* Setup RFC4507 ticket keys */ - if ((RAND_bytes(ret->tlsext_tick_key_name, 16) <= 0) - || (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0) - || (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0)) - ret->options |= SSL_OP_NO_TICKET; - - ret->tlsext_status_cb = 0; - ret->tlsext_status_arg = NULL; - -# ifndef OPENSSL_NO_NEXTPROTONEG - ret->next_protos_advertised_cb = 0; - ret->next_proto_select_cb = 0; -# endif -#endif -#ifndef OPENSSL_NO_PSK - ret->psk_identity_hint = NULL; - ret->psk_client_callback = NULL; - ret->psk_server_callback = NULL; -#endif -#ifndef OPENSSL_NO_SRP - SSL_CTX_SRP_CTX_init(ret); -#endif -#ifndef OPENSSL_NO_BUF_FREELISTS - ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT; - ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); - if (!ret->rbuf_freelist) - goto err; - ret->rbuf_freelist->chunklen = 0; - ret->rbuf_freelist->len = 0; - ret->rbuf_freelist->head = NULL; - ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); - if (!ret->wbuf_freelist) - goto err; - ret->wbuf_freelist->chunklen = 0; - ret->wbuf_freelist->len = 0; - ret->wbuf_freelist->head = NULL; -#endif -#ifndef OPENSSL_NO_ENGINE - ret->client_cert_engine = NULL; -# ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO -# define eng_strx(x) #x -# define eng_str(x) eng_strx(x) - /* Use specific client engine automatically... ignore errors */ - { - ENGINE *eng; - eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); - if (!eng) { - ERR_clear_error(); - ENGINE_load_builtin_engines(); - eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); - } - if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng)) - ERR_clear_error(); - } -# endif -#endif - /* - * Default is to connect to non-RI servers. When RI is more widely - * deployed might change this. - */ - ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; - - /* - * Disable SSLv2 by default, callers that want to enable SSLv2 will have to - * explicitly clear this option via either of SSL_CTX_clear_options() or - * SSL_clear_options(). - */ - ret->options |= SSL_OP_NO_SSLv2; - - return (ret); - err: - SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE); - err2: - if (ret != NULL) - SSL_CTX_free(ret); - return (NULL); -} - -#if 0 -static void SSL_COMP_free(SSL_COMP *comp) -{ - OPENSSL_free(comp); -} -#endif - -#ifndef OPENSSL_NO_BUF_FREELISTS -static void ssl_buf_freelist_free(SSL3_BUF_FREELIST *list) -{ - SSL3_BUF_FREELIST_ENTRY *ent, *next; - for (ent = list->head; ent; ent = next) { - next = ent->next; - OPENSSL_free(ent); - } - OPENSSL_free(list); -} -#endif - -void SSL_CTX_free(SSL_CTX *a) -{ - int i; - - if (a == NULL) - return; - - i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_SSL_CTX); -#ifdef REF_PRINT - REF_PRINT("SSL_CTX", a); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "SSL_CTX_free, bad reference count\n"); - abort(); /* ok */ - } -#endif - - if (a->param) - X509_VERIFY_PARAM_free(a->param); - - /* - * Free internal session cache. However: the remove_cb() may reference - * the ex_data of SSL_CTX, thus the ex_data store can only be removed - * after the sessions were flushed. - * As the ex_data handling routines might also touch the session cache, - * the most secure solution seems to be: empty (flush) the cache, then - * free ex_data, then finally free the cache. - * (See ticket [openssl.org #212].) - */ - if (a->sessions != NULL) - SSL_CTX_flush_sessions(a, 0); - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data); - - if (a->sessions != NULL) - lh_SSL_SESSION_free(a->sessions); - - if (a->cert_store != NULL) - X509_STORE_free(a->cert_store); - if (a->cipher_list != NULL) - sk_SSL_CIPHER_free(a->cipher_list); - if (a->cipher_list_by_id != NULL) - sk_SSL_CIPHER_free(a->cipher_list_by_id); - if (a->cert != NULL) - ssl_cert_free(a->cert); - if (a->client_CA != NULL) - sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free); - if (a->extra_certs != NULL) - sk_X509_pop_free(a->extra_certs, X509_free); -#if 0 /* This should never be done, since it - * removes a global database */ - if (a->comp_methods != NULL) - sk_SSL_COMP_pop_free(a->comp_methods, SSL_COMP_free); -#else - a->comp_methods = NULL; -#endif - -#ifndef OPENSSL_NO_SRTP - if (a->srtp_profiles) - sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); -#endif - -#ifndef OPENSSL_NO_PSK - if (a->psk_identity_hint) - OPENSSL_free(a->psk_identity_hint); -#endif -#ifndef OPENSSL_NO_SRP - SSL_CTX_SRP_CTX_free(a); -#endif -#ifndef OPENSSL_NO_ENGINE - if (a->client_cert_engine) - ENGINE_finish(a->client_cert_engine); -#endif - -#ifndef OPENSSL_NO_BUF_FREELISTS - if (a->wbuf_freelist) - ssl_buf_freelist_free(a->wbuf_freelist); - if (a->rbuf_freelist) - ssl_buf_freelist_free(a->rbuf_freelist); -#endif -#ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_EC - if (a->tlsext_ecpointformatlist) - OPENSSL_free(a->tlsext_ecpointformatlist); - if (a->tlsext_ellipticcurvelist) - OPENSSL_free(a->tlsext_ellipticcurvelist); -# endif /* OPENSSL_NO_EC */ - if (a->alpn_client_proto_list != NULL) - OPENSSL_free(a->alpn_client_proto_list); -#endif - - OPENSSL_free(a); -} - -void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) -{ - ctx->default_passwd_callback = cb; -} - -void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) -{ - ctx->default_passwd_callback_userdata = u; -} - -void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, - int (*cb) (X509_STORE_CTX *, void *), - void *arg) -{ - ctx->app_verify_callback = cb; - ctx->app_verify_arg = arg; -} - -void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, - int (*cb) (int, X509_STORE_CTX *)) -{ - ctx->verify_mode = mode; - ctx->default_verify_callback = cb; -} - -void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) -{ - X509_VERIFY_PARAM_set_depth(ctx->param, depth); -} - -void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), - void *arg) -{ - ssl_cert_set_cert_cb(c->cert, cb, arg); -} - -void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg) -{ - ssl_cert_set_cert_cb(s->cert, cb, arg); -} - -void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) -{ - CERT_PKEY *cpk; - int rsa_enc, rsa_tmp, rsa_sign, dh_tmp, dh_rsa, dh_dsa, dsa_sign; - int rsa_enc_export, dh_rsa_export, dh_dsa_export; - int rsa_tmp_export, dh_tmp_export, kl; - unsigned long mask_k, mask_a, emask_k, emask_a; -#ifndef OPENSSL_NO_ECDSA - int have_ecc_cert, ecdsa_ok, ecc_pkey_size; -#endif -#ifndef OPENSSL_NO_ECDH - int have_ecdh_tmp, ecdh_ok; -#endif -#ifndef OPENSSL_NO_EC - X509 *x = NULL; - EVP_PKEY *ecc_pkey = NULL; - int signature_nid = 0, pk_nid = 0, md_nid = 0; -#endif - if (c == NULL) - return; - - kl = SSL_C_EXPORT_PKEYLENGTH(cipher); - -#ifndef OPENSSL_NO_RSA - rsa_tmp = (c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL); - rsa_tmp_export = (c->rsa_tmp_cb != NULL || - (rsa_tmp && RSA_size(c->rsa_tmp) * 8 <= kl)); -#else - rsa_tmp = rsa_tmp_export = 0; -#endif -#ifndef OPENSSL_NO_DH - dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL); - dh_tmp_export = (c->dh_tmp_cb != NULL || - (dh_tmp && DH_size(c->dh_tmp) * 8 <= kl)); -#else - dh_tmp = dh_tmp_export = 0; -#endif - -#ifndef OPENSSL_NO_ECDH - have_ecdh_tmp = (c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto); -#endif - cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]); - rsa_enc = cpk->valid_flags & CERT_PKEY_VALID; - rsa_enc_export = (rsa_enc && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); - cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]); - rsa_sign = cpk->valid_flags & CERT_PKEY_SIGN; - cpk = &(c->pkeys[SSL_PKEY_DSA_SIGN]); - dsa_sign = cpk->valid_flags & CERT_PKEY_SIGN; - cpk = &(c->pkeys[SSL_PKEY_DH_RSA]); - dh_rsa = cpk->valid_flags & CERT_PKEY_VALID; - dh_rsa_export = (dh_rsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); - cpk = &(c->pkeys[SSL_PKEY_DH_DSA]); -/* FIX THIS EAY EAY EAY */ - dh_dsa = cpk->valid_flags & CERT_PKEY_VALID; - dh_dsa_export = (dh_dsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); - cpk = &(c->pkeys[SSL_PKEY_ECC]); -#ifndef OPENSSL_NO_EC - have_ecc_cert = cpk->valid_flags & CERT_PKEY_VALID; -#endif - mask_k = 0; - mask_a = 0; - emask_k = 0; - emask_a = 0; - -#ifdef CIPHER_DEBUG - fprintf(stderr, - "rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n", - rsa_tmp, rsa_tmp_export, dh_tmp, have_ecdh_tmp, rsa_enc, - rsa_enc_export, rsa_sign, dsa_sign, dh_rsa, dh_dsa); -#endif - - cpk = &(c->pkeys[SSL_PKEY_GOST01]); - if (cpk->x509 != NULL && cpk->privatekey != NULL) { - mask_k |= SSL_kGOST; - mask_a |= SSL_aGOST01; - } - cpk = &(c->pkeys[SSL_PKEY_GOST94]); - if (cpk->x509 != NULL && cpk->privatekey != NULL) { - mask_k |= SSL_kGOST; - mask_a |= SSL_aGOST94; - } - - if (rsa_enc || (rsa_tmp && rsa_sign)) - mask_k |= SSL_kRSA; - if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc))) - emask_k |= SSL_kRSA; - -#if 0 - /* The match needs to be both kEDH and aRSA or aDSA, so don't worry */ - if ((dh_tmp || dh_rsa || dh_dsa) && (rsa_enc || rsa_sign || dsa_sign)) - mask_k |= SSL_kEDH; - if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) && - (rsa_enc || rsa_sign || dsa_sign)) - emask_k |= SSL_kEDH; -#endif - - if (dh_tmp_export) - emask_k |= SSL_kEDH; - - if (dh_tmp) - mask_k |= SSL_kEDH; - - if (dh_rsa) - mask_k |= SSL_kDHr; - if (dh_rsa_export) - emask_k |= SSL_kDHr; - - if (dh_dsa) - mask_k |= SSL_kDHd; - if (dh_dsa_export) - emask_k |= SSL_kDHd; - - if (mask_k & (SSL_kDHr | SSL_kDHd)) - mask_a |= SSL_aDH; - - if (rsa_enc || rsa_sign) { - mask_a |= SSL_aRSA; - emask_a |= SSL_aRSA; - } - - if (dsa_sign) { - mask_a |= SSL_aDSS; - emask_a |= SSL_aDSS; - } - - mask_a |= SSL_aNULL; - emask_a |= SSL_aNULL; - -#ifndef OPENSSL_NO_KRB5 - mask_k |= SSL_kKRB5; - mask_a |= SSL_aKRB5; - emask_k |= SSL_kKRB5; - emask_a |= SSL_aKRB5; -#endif - - /* - * An ECC certificate may be usable for ECDH and/or ECDSA cipher suites - * depending on the key usage extension. - */ -#ifndef OPENSSL_NO_EC - if (have_ecc_cert) { - cpk = &c->pkeys[SSL_PKEY_ECC]; - x = cpk->x509; - /* This call populates extension flags (ex_flags) */ - X509_check_purpose(x, -1, 0); -# ifndef OPENSSL_NO_ECDH - ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ? - (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1; -# endif - ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ? - (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1; - if (!(cpk->valid_flags & CERT_PKEY_SIGN)) - ecdsa_ok = 0; - ecc_pkey = X509_get_pubkey(x); - ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0; - EVP_PKEY_free(ecc_pkey); - if ((x->sig_alg) && (x->sig_alg->algorithm)) { - signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); - OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); - } -# ifndef OPENSSL_NO_ECDH - if (ecdh_ok) { - - if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) { - mask_k |= SSL_kECDHr; - mask_a |= SSL_aECDH; - if (ecc_pkey_size <= 163) { - emask_k |= SSL_kECDHr; - emask_a |= SSL_aECDH; - } - } - - if (pk_nid == NID_X9_62_id_ecPublicKey) { - mask_k |= SSL_kECDHe; - mask_a |= SSL_aECDH; - if (ecc_pkey_size <= 163) { - emask_k |= SSL_kECDHe; - emask_a |= SSL_aECDH; - } - } - } -# endif -# ifndef OPENSSL_NO_ECDSA - if (ecdsa_ok) { - mask_a |= SSL_aECDSA; - emask_a |= SSL_aECDSA; - } -# endif - } -#endif - -#ifndef OPENSSL_NO_ECDH - if (have_ecdh_tmp) { - mask_k |= SSL_kEECDH; - emask_k |= SSL_kEECDH; - } -#endif - -#ifndef OPENSSL_NO_PSK - mask_k |= SSL_kPSK; - mask_a |= SSL_aPSK; - emask_k |= SSL_kPSK; - emask_a |= SSL_aPSK; -#endif - - c->mask_k = mask_k; - c->mask_a = mask_a; - c->export_mask_k = emask_k; - c->export_mask_a = emask_a; - c->valid = 1; -} - -/* This handy macro borrowed from crypto/x509v3/v3_purp.c */ -#define ku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) - -#ifndef OPENSSL_NO_EC - -int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) -{ - unsigned long alg_k, alg_a; - EVP_PKEY *pkey = NULL; - int keysize = 0; - int signature_nid = 0, md_nid = 0, pk_nid = 0; - const SSL_CIPHER *cs = s->s3->tmp.new_cipher; - - alg_k = cs->algorithm_mkey; - alg_a = cs->algorithm_auth; - - if (SSL_C_IS_EXPORT(cs)) { - /* ECDH key length in export ciphers must be <= 163 bits */ - pkey = X509_get_pubkey(x); - if (pkey == NULL) - return 0; - keysize = EVP_PKEY_bits(pkey); - EVP_PKEY_free(pkey); - if (keysize > 163) - return 0; - } - - /* This call populates the ex_flags field correctly */ - X509_check_purpose(x, -1, 0); - if ((x->sig_alg) && (x->sig_alg->algorithm)) { - signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); - OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); - } - if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr) { - /* key usage, if present, must allow key agreement */ - if (ku_reject(x, X509v3_KU_KEY_AGREEMENT)) { - SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, - SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT); - return 0; - } - if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION) { - /* signature alg must be ECDSA */ - if (pk_nid != NID_X9_62_id_ecPublicKey) { - SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, - SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE); - return 0; - } - } - if ((alg_k & SSL_kECDHr) && TLS1_get_version(s) < TLS1_2_VERSION) { - /* signature alg must be RSA */ - - if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa) { - SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, - SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE); - return 0; - } - } - } - if (alg_a & SSL_aECDSA) { - /* key usage, if present, must allow signing */ - if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) { - SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, - SSL_R_ECC_CERT_NOT_FOR_SIGNING); - return 0; - } - } - - return 1; /* all checks are ok */ -} - -#endif - -static int ssl_get_server_cert_index(const SSL *s) -{ - int idx; - idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher); - if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509) - idx = SSL_PKEY_RSA_SIGN; - if (idx == -1) - SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX, ERR_R_INTERNAL_ERROR); - return idx; -} - -CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) -{ - CERT *c; - int i; - - c = s->cert; - if (!s->s3 || !s->s3->tmp.new_cipher) - return NULL; - ssl_set_cert_masks(c, s->s3->tmp.new_cipher); - -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - /* - * Broken protocol test: return last used certificate: which may mismatch - * the one expected. - */ - if (c->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) - return c->key; -#endif - - i = ssl_get_server_cert_index(s); - - /* This may or may not be an error. */ - if (i < 0) - return NULL; - - /* May be NULL. */ - return &c->pkeys[i]; -} - -EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, - const EVP_MD **pmd) -{ - unsigned long alg_a; - CERT *c; - int idx = -1; - - alg_a = cipher->algorithm_auth; - c = s->cert; - -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - /* - * Broken protocol test: use last key: which may mismatch the one - * expected. - */ - if (c->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) - idx = c->key - c->pkeys; - else -#endif - - if ((alg_a & SSL_aDSS) && - (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) - idx = SSL_PKEY_DSA_SIGN; - else if (alg_a & SSL_aRSA) { - if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) - idx = SSL_PKEY_RSA_SIGN; - else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) - idx = SSL_PKEY_RSA_ENC; - } else if ((alg_a & SSL_aECDSA) && - (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) - idx = SSL_PKEY_ECC; - if (idx == -1) { - SSLerr(SSL_F_SSL_GET_SIGN_PKEY, ERR_R_INTERNAL_ERROR); - return (NULL); - } - if (pmd) - *pmd = c->pkeys[idx].digest; - return c->pkeys[idx].privatekey; -} - -#ifndef OPENSSL_NO_TLSEXT -int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, - size_t *serverinfo_length) -{ - CERT *c = NULL; - int i = 0; - *serverinfo_length = 0; - - c = s->cert; - i = ssl_get_server_cert_index(s); - - if (i == -1) - return 0; - if (c->pkeys[i].serverinfo == NULL) - return 0; - - *serverinfo = c->pkeys[i].serverinfo; - *serverinfo_length = c->pkeys[i].serverinfo_length; - return 1; -} -#endif - -void ssl_update_cache(SSL *s, int mode) -{ - int i; - - /* - * If the session_id_length is 0, we are not supposed to cache it, and it - * would be rather hard to do anyway :-) - */ - if (s->session->session_id_length == 0) - return; - - i = s->session_ctx->session_cache_mode; - if ((i & mode) && (!s->hit) - && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) - || SSL_CTX_add_session(s->session_ctx, s->session)) - && (s->session_ctx->new_session_cb != NULL)) { - CRYPTO_add(&s->session->references, 1, CRYPTO_LOCK_SSL_SESSION); - if (!s->session_ctx->new_session_cb(s, s->session)) - SSL_SESSION_free(s->session); - } - - /* auto flush every 255 connections */ - if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) { - if ((((mode & SSL_SESS_CACHE_CLIENT) - ? s->session_ctx->stats.sess_connect_good - : s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff) { - SSL_CTX_flush_sessions(s->session_ctx, (unsigned long)time(NULL)); - } - } -} - -const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx) -{ - return ctx->method; -} - -const SSL_METHOD *SSL_get_ssl_method(SSL *s) -{ - return (s->method); -} - -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); - - if (s->method->version == meth->version) - s->method = meth; - else { - s->method->ssl_free(s); - s->method = meth; - ret = s->method->ssl_new(s); - } - - if (conn == 1) - s->handshake_func = meth->ssl_connect; - else if (conn == 0) - s->handshake_func = meth->ssl_accept; - } - return (ret); -} - -int SSL_get_error(const SSL *s, int i) -{ - int reason; - unsigned long l; - BIO *bio; - - if (i > 0) - return (SSL_ERROR_NONE); - - /* - * Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc, - * where we do encode the error - */ - if ((l = ERR_peek_error()) != 0) { - if (ERR_GET_LIB(l) == ERR_LIB_SYS) - return (SSL_ERROR_SYSCALL); - else - return (SSL_ERROR_SSL); - } - - if ((i < 0) && SSL_want_read(s)) { - bio = SSL_get_rbio(s); - if (BIO_should_read(bio)) - return (SSL_ERROR_WANT_READ); - else if (BIO_should_write(bio)) - /* - * This one doesn't make too much sense ... We never try to write - * to the rbio, and an application program where rbio and wbio - * are separate couldn't even know what it should wait for. - * However if we ever set s->rwstate incorrectly (so that we have - * SSL_want_read(s) instead of SSL_want_write(s)) and rbio and - * wbio *are* the same, this test works around that bug; so it - * might be safer to keep it. - */ - return (SSL_ERROR_WANT_WRITE); - else if (BIO_should_io_special(bio)) { - reason = BIO_get_retry_reason(bio); - if (reason == BIO_RR_CONNECT) - return (SSL_ERROR_WANT_CONNECT); - else if (reason == BIO_RR_ACCEPT) - return (SSL_ERROR_WANT_ACCEPT); - else - return (SSL_ERROR_SYSCALL); /* unknown */ - } - } - - if ((i < 0) && SSL_want_write(s)) { - bio = SSL_get_wbio(s); - if (BIO_should_write(bio)) - return (SSL_ERROR_WANT_WRITE); - else if (BIO_should_read(bio)) - /* - * See above (SSL_want_read(s) with BIO_should_write(bio)) - */ - return (SSL_ERROR_WANT_READ); - else if (BIO_should_io_special(bio)) { - reason = BIO_get_retry_reason(bio); - if (reason == BIO_RR_CONNECT) - return (SSL_ERROR_WANT_CONNECT); - else if (reason == BIO_RR_ACCEPT) - return (SSL_ERROR_WANT_ACCEPT); - else - return (SSL_ERROR_SYSCALL); - } - } - if ((i < 0) && SSL_want_x509_lookup(s)) { - return (SSL_ERROR_WANT_X509_LOOKUP); - } - - if (i == 0) { - if (s->version == SSL2_VERSION) { - /* assume it is the socket being closed */ - return (SSL_ERROR_ZERO_RETURN); - } else { - if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) && - (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) - return (SSL_ERROR_ZERO_RETURN); - } - } - return (SSL_ERROR_SYSCALL); -} - -int SSL_do_handshake(SSL *s) -{ - int ret = 1; - - if (s->handshake_func == NULL) { - SSLerr(SSL_F_SSL_DO_HANDSHAKE, SSL_R_CONNECTION_TYPE_NOT_SET); - return (-1); - } - - s->method->ssl_renegotiate_check(s); - - if (SSL_in_init(s) || SSL_in_before(s)) { - ret = s->handshake_func(s); - } - return (ret); -} - -/* - * For the next 2 functions, SSL_clear() sets shutdown and so one of these - * calls will reset it - */ -void SSL_set_accept_state(SSL *s) -{ - s->server = 1; - s->shutdown = 0; - s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE; - s->handshake_func = s->method->ssl_accept; - /* clear the current cipher */ - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); -} - -void SSL_set_connect_state(SSL *s) -{ - s->server = 0; - s->shutdown = 0; - s->state = SSL_ST_CONNECT | SSL_ST_BEFORE; - s->handshake_func = s->method->ssl_connect; - /* clear the current cipher */ - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); -} - -int ssl_undefined_function(SSL *s) -{ - SSLerr(SSL_F_SSL_UNDEFINED_FUNCTION, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (0); -} - -int ssl_undefined_void_function(void) -{ - SSLerr(SSL_F_SSL_UNDEFINED_VOID_FUNCTION, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (0); -} - -int ssl_undefined_const_function(const SSL *s) -{ - SSLerr(SSL_F_SSL_UNDEFINED_CONST_FUNCTION, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (0); -} - -SSL_METHOD *ssl_bad_method(int ver) -{ - SSLerr(SSL_F_SSL_BAD_METHOD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (NULL); -} - -const char *SSL_get_version(const SSL *s) -{ - if (s->version == TLS1_2_VERSION) - return ("TLSv1.2"); - else if (s->version == TLS1_1_VERSION) - return ("TLSv1.1"); - else if (s->version == TLS1_VERSION) - return ("TLSv1"); - else if (s->version == SSL3_VERSION) - return ("SSLv3"); - else if (s->version == SSL2_VERSION) - return ("SSLv2"); - else if (s->version == DTLS1_BAD_VER) - return ("DTLSv0.9"); - else if (s->version == DTLS1_VERSION) - return ("DTLSv1"); - else if (s->version == DTLS1_2_VERSION) - return ("DTLSv1.2"); - else - return ("unknown"); -} - -SSL *SSL_dup(SSL *s) -{ - STACK_OF(X509_NAME) *sk; - X509_NAME *xn; - SSL *ret; - int i; - - if ((ret = SSL_new(SSL_get_SSL_CTX(s))) == NULL) - return (NULL); - - ret->version = s->version; - ret->type = s->type; - ret->method = s->method; - - if (s->session != NULL) { - /* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */ - SSL_copy_session_id(ret, s); - } else { - /* - * No session has been established yet, so we have to expect that - * s->cert or ret->cert will be changed later -- they should not both - * 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 (s->cert != NULL) { - if (ret->cert != NULL) { - ssl_cert_free(ret->cert); - } - ret->cert = ssl_cert_dup(s->cert); - if (ret->cert == NULL) - goto err; - } - - SSL_set_session_id_context(ret, s->sid_ctx, s->sid_ctx_length); - } - - ret->options = s->options; - ret->mode = s->mode; - SSL_set_max_cert_list(ret, SSL_get_max_cert_list(s)); - SSL_set_read_ahead(ret, SSL_get_read_ahead(s)); - ret->msg_callback = s->msg_callback; - ret->msg_callback_arg = s->msg_callback_arg; - SSL_set_verify(ret, SSL_get_verify_mode(s), SSL_get_verify_callback(s)); - SSL_set_verify_depth(ret, SSL_get_verify_depth(s)); - ret->generate_session_id = s->generate_session_id; - - SSL_set_info_callback(ret, SSL_get_info_callback(s)); - - ret->debug = s->debug; - - /* copy app data, a little dangerous perhaps */ - if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data)) - goto err; - - /* setup rbio, and wbio */ - if (s->rbio != NULL) { - if (!BIO_dup_state(s->rbio, (char *)&ret->rbio)) - goto err; - } - if (s->wbio != NULL) { - if (s->wbio != s->rbio) { - if (!BIO_dup_state(s->wbio, (char *)&ret->wbio)) - goto err; - } else - ret->wbio = ret->rbio; - } - ret->rwstate = s->rwstate; - ret->in_handshake = s->in_handshake; - 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; - ret->shutdown = s->shutdown; - ret->state = s->state; /* SSL_dup does not really work at any state, - * though */ - ret->rstate = s->rstate; - ret->init_num = 0; /* would have to copy ret->init_buf, - * ret->init_msg, ret->init_num, - * ret->init_off */ - ret->hit = s->hit; - - X509_VERIFY_PARAM_inherit(ret->param, s->param); - - /* dup the cipher_list and cipher_list_by_id stacks */ - if (s->cipher_list != NULL) { - if ((ret->cipher_list = sk_SSL_CIPHER_dup(s->cipher_list)) == NULL) - goto err; - } - if (s->cipher_list_by_id != NULL) - if ((ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id)) - == NULL) - goto err; - - /* Dup the client_CA list */ - if (s->client_CA != NULL) { - if ((sk = sk_X509_NAME_dup(s->client_CA)) == NULL) - goto err; - ret->client_CA = sk; - for (i = 0; i < sk_X509_NAME_num(sk); i++) { - xn = sk_X509_NAME_value(sk, i); - if (sk_X509_NAME_set(sk, i, X509_NAME_dup(xn)) == NULL) { - X509_NAME_free(xn); - goto err; - } - } - } - - if (0) { - err: - if (ret != NULL) - SSL_free(ret); - ret = NULL; - } - return (ret); -} - -void ssl_clear_cipher_ctx(SSL *s) -{ - if (s->enc_read_ctx != NULL) { - EVP_CIPHER_CTX_cleanup(s->enc_read_ctx); - OPENSSL_free(s->enc_read_ctx); - s->enc_read_ctx = NULL; - } - if (s->enc_write_ctx != NULL) { - EVP_CIPHER_CTX_cleanup(s->enc_write_ctx); - OPENSSL_free(s->enc_write_ctx); - s->enc_write_ctx = NULL; - } -#ifndef OPENSSL_NO_COMP - if (s->expand != NULL) { - COMP_CTX_free(s->expand); - s->expand = NULL; - } - if (s->compress != NULL) { - COMP_CTX_free(s->compress); - s->compress = NULL; - } -#endif -} - -X509 *SSL_get_certificate(const SSL *s) -{ - if (s->cert != NULL) - return (s->cert->key->x509); - else - return (NULL); -} - -EVP_PKEY *SSL_get_privatekey(const SSL *s) -{ - if (s->cert != NULL) - return (s->cert->key->privatekey); - else - return (NULL); -} - -X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) -{ - if (ctx->cert != NULL) - return ctx->cert->key->x509; - else - return NULL; -} - -EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) -{ - if (ctx->cert != NULL) - return ctx->cert->key->privatekey; - else - return NULL; -} - -const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) -{ - if ((s->session != NULL) && (s->session->cipher != NULL)) - return (s->session->cipher); - return (NULL); -} - -#ifdef OPENSSL_NO_COMP -const COMP_METHOD *SSL_get_current_compression(SSL *s) -{ - return NULL; -} - -const COMP_METHOD *SSL_get_current_expansion(SSL *s) -{ - return NULL; -} -#else - -const COMP_METHOD *SSL_get_current_compression(SSL *s) -{ - if (s->compress != NULL) - return (s->compress->meth); - return (NULL); -} - -const COMP_METHOD *SSL_get_current_expansion(SSL *s) -{ - if (s->expand != NULL) - return (s->expand->meth); - return (NULL); -} -#endif - -int ssl_init_wbio_buffer(SSL *s, int push) -{ - BIO *bbio; - - if (s->bbio == NULL) { - bbio = BIO_new(BIO_f_buffer()); - if (bbio == NULL) - return (0); - s->bbio = bbio; - } else { - bbio = s->bbio; - if (s->bbio == s->wbio) - s->wbio = BIO_pop(s->wbio); - } - (void)BIO_reset(bbio); -/* if (!BIO_set_write_buffer_size(bbio,16*1024)) */ - if (!BIO_set_read_buffer_size(bbio, 1)) { - SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER, ERR_R_BUF_LIB); - return (0); - } - if (push) { - if (s->wbio != bbio) - s->wbio = BIO_push(bbio, s->wbio); - } else { - if (s->wbio == bbio) - s->wbio = BIO_pop(bbio); - } - return (1); -} - -void ssl_free_wbio_buffer(SSL *s) -{ - if (s->bbio == NULL) - return; - - if (s->bbio == s->wbio) { - /* remove buffering */ - s->wbio = BIO_pop(s->wbio); -#ifdef REF_CHECK /* not the usual REF_CHECK, but this avoids - * adding one more preprocessor symbol */ - assert(s->wbio != NULL); -#endif - } - BIO_free(s->bbio); - s->bbio = NULL; -} - -void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) -{ - ctx->quiet_shutdown = mode; -} - -int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) -{ - return (ctx->quiet_shutdown); -} - -void SSL_set_quiet_shutdown(SSL *s, int mode) -{ - s->quiet_shutdown = mode; -} - -int SSL_get_quiet_shutdown(const SSL *s) -{ - return (s->quiet_shutdown); -} - -void SSL_set_shutdown(SSL *s, int mode) -{ - s->shutdown = mode; -} - -int SSL_get_shutdown(const SSL *s) -{ - return (s->shutdown); -} - -int SSL_version(const SSL *s) -{ - return (s->version); -} - -SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) -{ - return (ssl->ctx); -} - -SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) -{ - CERT *ocert = ssl->cert; - if (ssl->ctx == ctx) - return ssl->ctx; -#ifndef OPENSSL_NO_TLSEXT - if (ctx == NULL) - ctx = ssl->initial_ctx; -#endif - ssl->cert = ssl_cert_dup(ctx->cert); - if (ocert) { - /* Preserve any already negotiated parameters */ - if (ssl->server) { - ssl->cert->peer_sigalgs = ocert->peer_sigalgs; - ssl->cert->peer_sigalgslen = ocert->peer_sigalgslen; - ocert->peer_sigalgs = NULL; - ssl->cert->ciphers_raw = ocert->ciphers_raw; - ssl->cert->ciphers_rawlen = ocert->ciphers_rawlen; - ocert->ciphers_raw = NULL; - } -#ifndef OPENSSL_NO_TLSEXT - ssl->cert->alpn_proposed = ocert->alpn_proposed; - ssl->cert->alpn_proposed_len = ocert->alpn_proposed_len; - ocert->alpn_proposed = NULL; - ssl->cert->alpn_sent = ocert->alpn_sent; - - if (!custom_exts_copy_flags(&ssl->cert->srv_ext, &ocert->srv_ext)) - return NULL; -#endif - ssl_cert_free(ocert); - } - - /* - * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH), - * so setter APIs must prevent invalid lengths from entering the system. - */ - OPENSSL_assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx)); - - /* - * If the session ID context matches that of the parent SSL_CTX, - * inherit it from the new SSL_CTX as well. If however the context does - * not match (i.e., it was set per-ssl with SSL_set_session_id_context), - * leave it unchanged. - */ - if ((ssl->ctx != NULL) && - (ssl->sid_ctx_length == ssl->ctx->sid_ctx_length) && - (memcmp(ssl->sid_ctx, ssl->ctx->sid_ctx, ssl->sid_ctx_length) == 0)) { - ssl->sid_ctx_length = ctx->sid_ctx_length; - memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx)); - } - - CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); - if (ssl->ctx != NULL) - SSL_CTX_free(ssl->ctx); /* decrement reference count */ - ssl->ctx = ctx; - - return (ssl->ctx); -} - -#ifndef OPENSSL_NO_STDIO -int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) -{ - return (X509_STORE_set_default_paths(ctx->cert_store)); -} - -int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, - const char *CApath) -{ - return (X509_STORE_load_locations(ctx->cert_store, CAfile, CApath)); -} -#endif - -void SSL_set_info_callback(SSL *ssl, - void (*cb) (const SSL *ssl, int type, int val)) -{ - ssl->info_callback = cb; -} - -/* - * One compiler (Diab DCC) doesn't like argument names in returned function - * pointer. - */ -void (*SSL_get_info_callback(const SSL *ssl)) (const SSL * /* ssl */ , - int /* type */ , - int /* val */ ) { - return ssl->info_callback; -} - -int SSL_state(const SSL *ssl) -{ - return (ssl->state); -} - -void SSL_set_state(SSL *ssl, int state) -{ - ssl->state = state; -} - -void SSL_set_verify_result(SSL *ssl, long arg) -{ - ssl->verify_result = arg; -} - -long SSL_get_verify_result(const SSL *ssl) -{ - return (ssl->verify_result); -} - -int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp, - new_func, dup_func, free_func); -} - -int SSL_set_ex_data(SSL *s, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); -} - -void *SSL_get_ex_data(const SSL *s, int idx) -{ - return (CRYPTO_get_ex_data(&s->ex_data, idx)); -} - -int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp, - new_func, dup_func, free_func); -} - -int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); -} - -void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) -{ - return (CRYPTO_get_ex_data(&s->ex_data, idx)); -} - -int ssl_ok(SSL *s) -{ - return (1); -} - -X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) -{ - return (ctx->cert_store); -} - -void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) -{ - if (ctx->cert_store != NULL) - X509_STORE_free(ctx->cert_store); - ctx->cert_store = store; -} - -int SSL_want(const SSL *s) -{ - return (s->rwstate); -} - -/** - * \brief Set the callback for generating temporary RSA keys. - * \param ctx the SSL context. - * \param cb the callback - */ - -#ifndef OPENSSL_NO_RSA -void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, RSA *(*cb) (SSL *ssl, - int is_export, - int keylength)) -{ - SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb); -} - -void SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb) (SSL *ssl, - int is_export, - int keylength)) -{ - SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb); -} -#endif - -#ifdef DOXYGEN -/** - * \brief The RSA temporary key callback function. - * \param ssl the SSL session. - * \param is_export \c TRUE if the temp RSA key is for an export ciphersuite. - * \param keylength if \c is_export is \c TRUE, then \c keylength is the size - * of the required key in bits. - * \return the temporary RSA key. - * \sa SSL_CTX_set_tmp_rsa_callback, SSL_set_tmp_rsa_callback - */ - -RSA *cb(SSL *ssl, int is_export, int keylength) -{ -} -#endif - -/** - * \brief Set the callback for generating temporary DH keys. - * \param ctx the SSL context. - * \param dh the callback - */ - -#ifndef OPENSSL_NO_DH -void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, - DH *(*dh) (SSL *ssl, int is_export, - int keylength)) -{ - SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh); -} - -void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh) (SSL *ssl, int is_export, - int keylength)) -{ - SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh); -} -#endif - -#ifndef OPENSSL_NO_ECDH -void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, - EC_KEY *(*ecdh) (SSL *ssl, int is_export, - int keylength)) -{ - SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH_CB, - (void (*)(void))ecdh); -} - -void SSL_set_tmp_ecdh_callback(SSL *ssl, - EC_KEY *(*ecdh) (SSL *ssl, int is_export, - int keylength)) -{ - SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_ECDH_CB, (void (*)(void))ecdh); -} -#endif - -#ifndef OPENSSL_NO_PSK -int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) -{ - if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { - SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT, - SSL_R_DATA_LENGTH_TOO_LONG); - return 0; - } - if (ctx->psk_identity_hint != NULL) - OPENSSL_free(ctx->psk_identity_hint); - if (identity_hint != NULL) { - ctx->psk_identity_hint = BUF_strdup(identity_hint); - if (ctx->psk_identity_hint == NULL) - return 0; - } else - ctx->psk_identity_hint = NULL; - return 1; -} - -int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) -{ - if (s == NULL) - return 0; - - if (s->session == NULL) - return 1; /* session not created yet, ignored */ - - if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { - SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG); - return 0; - } - if (s->session->psk_identity_hint != NULL) - OPENSSL_free(s->session->psk_identity_hint); - if (identity_hint != NULL) { - s->session->psk_identity_hint = BUF_strdup(identity_hint); - if (s->session->psk_identity_hint == NULL) - return 0; - } else - s->session->psk_identity_hint = NULL; - return 1; -} - -const char *SSL_get_psk_identity_hint(const SSL *s) -{ - if (s == NULL || s->session == NULL) - return NULL; - return (s->session->psk_identity_hint); -} - -const char *SSL_get_psk_identity(const SSL *s) -{ - if (s == NULL || s->session == NULL) - return NULL; - return (s->session->psk_identity); -} - -void SSL_set_psk_client_callback(SSL *s, - unsigned int (*cb) (SSL *ssl, - const char *hint, - char *identity, - unsigned int - max_identity_len, - unsigned char *psk, - unsigned int - max_psk_len)) -{ - s->psk_client_callback = cb; -} - -void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, - unsigned int (*cb) (SSL *ssl, - const char *hint, - char *identity, - unsigned int - max_identity_len, - unsigned char *psk, - unsigned int - max_psk_len)) -{ - ctx->psk_client_callback = cb; -} - -void SSL_set_psk_server_callback(SSL *s, - unsigned int (*cb) (SSL *ssl, - const char *identity, - unsigned char *psk, - unsigned int - max_psk_len)) -{ - s->psk_server_callback = cb; -} - -void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, - unsigned int (*cb) (SSL *ssl, - const char *identity, - unsigned char *psk, - unsigned int - max_psk_len)) -{ - ctx->psk_server_callback = cb; -} -#endif - -void SSL_CTX_set_msg_callback(SSL_CTX *ctx, - void (*cb) (int write_p, int version, - int content_type, const void *buf, - size_t len, SSL *ssl, void *arg)) -{ - SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); -} - -void SSL_set_msg_callback(SSL *ssl, - void (*cb) (int write_p, int version, - int content_type, const void *buf, - size_t len, SSL *ssl, void *arg)) -{ - SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); -} - -/* - * Allocates new EVP_MD_CTX and sets pointer to it into given pointer - * vairable, freeing EVP_MD_CTX previously stored in that variable, if any. - * If EVP_MD pointer is passed, initializes ctx with this md Returns newly - * allocated ctx; - */ - -EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md) -{ - ssl_clear_hash_ctx(hash); - *hash = EVP_MD_CTX_create(); - if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) { - EVP_MD_CTX_destroy(*hash); - *hash = NULL; - return NULL; - } - return *hash; -} - -void ssl_clear_hash_ctx(EVP_MD_CTX **hash) -{ - - if (*hash) - EVP_MD_CTX_destroy(*hash); - *hash = NULL; -} - -void SSL_set_debug(SSL *s, int debug) -{ - s->debug = debug; -} - -int SSL_cache_hit(SSL *s) -{ - return s->hit; -} - -int SSL_is_server(SSL *s) -{ - return s->server; -} - -#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16) -# include "../crypto/bio/bss_file.c" -#endif - -IMPLEMENT_STACK_OF(SSL_CIPHER) -IMPLEMENT_STACK_OF(SSL_COMP) -IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); diff --git a/thirdparty/openssl/ssl/ssl_locl.h b/thirdparty/openssl/ssl/ssl_locl.h deleted file mode 100644 index aeffc00634..0000000000 --- a/thirdparty/openssl/ssl/ssl_locl.h +++ /dev/null @@ -1,1497 +0,0 @@ -/* ssl/ssl_locl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 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 - * openssl-core@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). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#ifndef HEADER_SSL_LOCL_H -# define HEADER_SSL_LOCL_H -# include <stdlib.h> -# include <time.h> -# include <string.h> -# include <errno.h> - -# include "e_os.h" - -# include <openssl/buffer.h> -# ifndef OPENSSL_NO_COMP -# include <openssl/comp.h> -# endif -# include <openssl/bio.h> -# include <openssl/stack.h> -# ifndef OPENSSL_NO_RSA -# include <openssl/rsa.h> -# endif -# ifndef OPENSSL_NO_DSA -# include <openssl/dsa.h> -# endif -# include <openssl/err.h> -# include <openssl/ssl.h> -# include <openssl/symhacks.h> - -# ifdef OPENSSL_BUILD_SHLIBSSL -# undef OPENSSL_EXTERN -# define OPENSSL_EXTERN OPENSSL_EXPORT -# endif - -# undef PKCS1_CHECK - -# define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \ - l|=(((unsigned long)(*((c)++)))<< 8), \ - l|=(((unsigned long)(*((c)++)))<<16), \ - l|=(((unsigned long)(*((c)++)))<<24)) - -/* NOTE - c is not incremented as per c2l */ -# define c2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c))))<<24; \ - case 7: l2|=((unsigned long)(*(--(c))))<<16; \ - case 6: l2|=((unsigned long)(*(--(c))))<< 8; \ - case 5: l2|=((unsigned long)(*(--(c)))); \ - case 4: l1 =((unsigned long)(*(--(c))))<<24; \ - case 3: l1|=((unsigned long)(*(--(c))))<<16; \ - case 2: l1|=((unsigned long)(*(--(c))))<< 8; \ - case 1: l1|=((unsigned long)(*(--(c)))); \ - } \ - } - -# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff)) - -# define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24, \ - l|=((unsigned long)(*((c)++)))<<16, \ - l|=((unsigned long)(*((c)++)))<< 8, \ - l|=((unsigned long)(*((c)++)))) - -# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -# define l2n6(l,c) (*((c)++)=(unsigned char)(((l)>>40)&0xff), \ - *((c)++)=(unsigned char)(((l)>>32)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -# define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ - *((c)++)=(unsigned char)(((l)>>48)&0xff), \ - *((c)++)=(unsigned char)(((l)>>40)&0xff), \ - *((c)++)=(unsigned char)(((l)>>32)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -# define n2l6(c,l) (l =((BN_ULLONG)(*((c)++)))<<40, \ - l|=((BN_ULLONG)(*((c)++)))<<32, \ - l|=((BN_ULLONG)(*((c)++)))<<24, \ - l|=((BN_ULLONG)(*((c)++)))<<16, \ - l|=((BN_ULLONG)(*((c)++)))<< 8, \ - l|=((BN_ULLONG)(*((c)++)))) - -/* NOTE - c is not incremented as per l2c */ -# define l2cn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ - } \ - } - -# define n2s(c,s) ((s=(((unsigned int)(c[0]))<< 8)| \ - (((unsigned int)(c[1])) )),c+=2) -# define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), \ - c[1]=(unsigned char)(((s) )&0xff)),c+=2) - -# define n2l3(c,l) ((l =(((unsigned long)(c[0]))<<16)| \ - (((unsigned long)(c[1]))<< 8)| \ - (((unsigned long)(c[2])) )),c+=3) - -# define l2n3(l,c) ((c[0]=(unsigned char)(((l)>>16)&0xff), \ - c[1]=(unsigned char)(((l)>> 8)&0xff), \ - c[2]=(unsigned char)(((l) )&0xff)),c+=3) - -/* LOCAL STUFF */ - -# define SSL_DECRYPT 0 -# define SSL_ENCRYPT 1 - -# define TWO_BYTE_BIT 0x80 -# define SEC_ESC_BIT 0x40 -# define TWO_BYTE_MASK 0x7fff -# define THREE_BYTE_MASK 0x3fff - -# define INC32(a) ((a)=((a)+1)&0xffffffffL) -# define DEC32(a) ((a)=((a)-1)&0xffffffffL) -# define MAX_MAC_SIZE 20 /* up from 16 for SSLv3 */ - -/* - * Define the Bitmasks for SSL_CIPHER.algorithms. - * This bits are used packed as dense as possible. If new methods/ciphers - * etc will be added, the bits a likely to change, so this information - * is for internal library use only, even though SSL_CIPHER.algorithms - * can be publicly accessed. - * Use the according functions for cipher management instead. - * - * The bit mask handling in the selection and sorting scheme in - * ssl_create_cipher_list() has only limited capabilities, reflecting - * that the different entities within are mutually exclusive: - * ONLY ONE BIT PER MASK CAN BE SET AT A TIME. - */ - -/* Bits for algorithm_mkey (key exchange algorithm) */ -/* RSA key exchange */ -# define SSL_kRSA 0x00000001L -/* DH cert, RSA CA cert */ -# define SSL_kDHr 0x00000002L -/* DH cert, DSA CA cert */ -# define SSL_kDHd 0x00000004L -/* tmp DH key no DH cert */ -# define SSL_kEDH 0x00000008L -/* forward-compatible synonym */ -# define SSL_kDHE SSL_kEDH -/* Kerberos5 key exchange */ -# define SSL_kKRB5 0x00000010L -/* ECDH cert, RSA CA cert */ -# define SSL_kECDHr 0x00000020L -/* ECDH cert, ECDSA CA cert */ -# define SSL_kECDHe 0x00000040L -/* ephemeral ECDH */ -# define SSL_kEECDH 0x00000080L -/* forward-compatible synonym */ -# define SSL_kECDHE SSL_kEECDH -/* PSK */ -# define SSL_kPSK 0x00000100L -/* GOST key exchange */ -# define SSL_kGOST 0x00000200L -/* SRP */ -# define SSL_kSRP 0x00000400L - -/* Bits for algorithm_auth (server authentication) */ -/* RSA auth */ -# define SSL_aRSA 0x00000001L -/* DSS auth */ -# define SSL_aDSS 0x00000002L -/* no auth (i.e. use ADH or AECDH) */ -# define SSL_aNULL 0x00000004L -/* Fixed DH auth (kDHd or kDHr) */ -# define SSL_aDH 0x00000008L -/* Fixed ECDH auth (kECDHe or kECDHr) */ -# define SSL_aECDH 0x00000010L -/* KRB5 auth */ -# define SSL_aKRB5 0x00000020L -/* ECDSA auth*/ -# define SSL_aECDSA 0x00000040L -/* PSK auth */ -# define SSL_aPSK 0x00000080L -/* GOST R 34.10-94 signature auth */ -# define SSL_aGOST94 0x00000100L -/* GOST R 34.10-2001 signature auth */ -# define SSL_aGOST01 0x00000200L -/* SRP auth */ -# define SSL_aSRP 0x00000400L - -/* Bits for algorithm_enc (symmetric encryption) */ -# define SSL_DES 0x00000001L -# define SSL_3DES 0x00000002L -# define SSL_RC4 0x00000004L -# define SSL_RC2 0x00000008L -# define SSL_IDEA 0x00000010L -# define SSL_eNULL 0x00000020L -# define SSL_AES128 0x00000040L -# define SSL_AES256 0x00000080L -# define SSL_CAMELLIA128 0x00000100L -# define SSL_CAMELLIA256 0x00000200L -# define SSL_eGOST2814789CNT 0x00000400L -# define SSL_SEED 0x00000800L -# define SSL_AES128GCM 0x00001000L -# define SSL_AES256GCM 0x00002000L - -# define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM) -# define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256) - -/* Bits for algorithm_mac (symmetric authentication) */ - -# define SSL_MD5 0x00000001L -# define SSL_SHA1 0x00000002L -# define SSL_GOST94 0x00000004L -# define SSL_GOST89MAC 0x00000008L -# define SSL_SHA256 0x00000010L -# define SSL_SHA384 0x00000020L -/* Not a real MAC, just an indication it is part of cipher */ -# define SSL_AEAD 0x00000040L - -/* Bits for algorithm_ssl (protocol version) */ -# define SSL_SSLV2 0x00000001UL -# define SSL_SSLV3 0x00000002UL -# define SSL_TLSV1 SSL_SSLV3/* for now */ -# define SSL_TLSV1_2 0x00000004UL - -/* Bits for algorithm2 (handshake digests and other extra flags) */ - -# define SSL_HANDSHAKE_MAC_MD5 0x10 -# define SSL_HANDSHAKE_MAC_SHA 0x20 -# define SSL_HANDSHAKE_MAC_GOST94 0x40 -# define SSL_HANDSHAKE_MAC_SHA256 0x80 -# define SSL_HANDSHAKE_MAC_SHA384 0x100 -# define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA) - -/* - * When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX make - * sure to update this constant too - */ -# define SSL_MAX_DIGEST 6 - -# define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT) - -# define TLS1_PRF_DGST_SHIFT 10 -# define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT) -# define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT) -# define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT) -# define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT) -# define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT) -# define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1) - -/* - * Stream MAC for GOST ciphersuites from cryptopro draft (currently this also - * goes into algorithm2) - */ -# define TLS1_STREAM_MAC 0x04 - -/* - * Export and cipher strength information. For each cipher we have to decide - * whether it is exportable or not. This information is likely to change - * over time, since the export control rules are no static technical issue. - * - * Independent of the export flag the cipher strength is sorted into classes. - * SSL_EXP40 was denoting the 40bit US export limit of past times, which now - * is at 56bit (SSL_EXP56). If the exportable cipher class is going to change - * again (eg. to 64bit) the use of "SSL_EXP*" becomes blurred even more, - * since SSL_EXP64 could be similar to SSL_LOW. - * For this reason SSL_MICRO and SSL_MINI macros are included to widen the - * namespace of SSL_LOW-SSL_HIGH to lower values. As development of speed - * and ciphers goes, another extension to SSL_SUPER and/or SSL_ULTRA would - * be possible. - */ -# define SSL_EXP_MASK 0x00000003L -# define SSL_STRONG_MASK 0x000001fcL - -# define SSL_NOT_EXP 0x00000001L -# define SSL_EXPORT 0x00000002L - -# define SSL_STRONG_NONE 0x00000004L -# define SSL_EXP40 0x00000008L -# define SSL_MICRO (SSL_EXP40) -# define SSL_EXP56 0x00000010L -# define SSL_MINI (SSL_EXP56) -# define SSL_LOW 0x00000020L -# define SSL_MEDIUM 0x00000040L -# define SSL_HIGH 0x00000080L -# define SSL_FIPS 0x00000100L -# define SSL_NOT_DEFAULT 0x00000200L - -/* we have used 000003ff - 22 bits left to go */ - -/*- - * Macros to check the export status and cipher strength for export ciphers. - * Even though the macros for EXPORT and EXPORT40/56 have similar names, - * their meaning is different: - * *_EXPORT macros check the 'exportable' status. - * *_EXPORT40/56 macros are used to check whether a certain cipher strength - * is given. - * Since the SSL_IS_EXPORT* and SSL_EXPORT* macros depend on the correct - * algorithm structure element to be passed (algorithms, algo_strength) and no - * typechecking can be done as they are all of type unsigned long, their - * direct usage is discouraged. - * Use the SSL_C_* macros instead. - */ -# define SSL_IS_EXPORT(a) ((a)&SSL_EXPORT) -# define SSL_IS_EXPORT56(a) ((a)&SSL_EXP56) -# define SSL_IS_EXPORT40(a) ((a)&SSL_EXP40) -# define SSL_C_IS_EXPORT(c) SSL_IS_EXPORT((c)->algo_strength) -# define SSL_C_IS_EXPORT56(c) SSL_IS_EXPORT56((c)->algo_strength) -# define SSL_C_IS_EXPORT40(c) SSL_IS_EXPORT40((c)->algo_strength) - -# define SSL_EXPORT_KEYLENGTH(a,s) (SSL_IS_EXPORT40(s) ? 5 : \ - (a) == SSL_DES ? 8 : 7) -# define SSL_EXPORT_PKEYLENGTH(a) (SSL_IS_EXPORT40(a) ? 512 : 1024) -# define SSL_C_EXPORT_KEYLENGTH(c) SSL_EXPORT_KEYLENGTH((c)->algorithm_enc, \ - (c)->algo_strength) -# define SSL_C_EXPORT_PKEYLENGTH(c) SSL_EXPORT_PKEYLENGTH((c)->algo_strength) - -/* Check if an SSL structure is using DTLS */ -# define SSL_IS_DTLS(s) (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) -/* See if we need explicit IV */ -# define SSL_USE_EXPLICIT_IV(s) \ - (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV) -/* - * See if we use signature algorithms extension and signature algorithm - * before signatures. - */ -# define SSL_USE_SIGALGS(s) \ - (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SIGALGS) -/* - * Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: may - * apply to others in future. - */ -# define SSL_USE_TLS1_2_CIPHERS(s) \ - (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS) -/* - * Determine if a client can use TLS 1.2 ciphersuites: can't rely on method - * flags because it may not be set to correct version yet. - */ -# define SSL_CLIENT_USE_TLS1_2_CIPHERS(s) \ - ((SSL_IS_DTLS(s) && s->client_version <= DTLS1_2_VERSION) || \ - (!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION)) -/* - * Determine if a client should send signature algorithms extension: - * as with TLS1.2 cipher we can't rely on method flags. - */ -# define SSL_CLIENT_USE_SIGALGS(s) \ - SSL_CLIENT_USE_TLS1_2_CIPHERS(s) - -/* Mostly for SSLv3 */ -# define SSL_PKEY_RSA_ENC 0 -# define SSL_PKEY_RSA_SIGN 1 -# define SSL_PKEY_DSA_SIGN 2 -# define SSL_PKEY_DH_RSA 3 -# define SSL_PKEY_DH_DSA 4 -# define SSL_PKEY_ECC 5 -# define SSL_PKEY_GOST94 6 -# define SSL_PKEY_GOST01 7 -# define SSL_PKEY_NUM 8 - -/*- - * SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) | - * <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN) - * SSL_kDH <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN) - * SSL_kEDH <- RSA_ENC | RSA_SIGN | DSA_SIGN - * SSL_aRSA <- RSA_ENC | RSA_SIGN - * SSL_aDSS <- DSA_SIGN - */ - -/*- -#define CERT_INVALID 0 -#define CERT_PUBLIC_KEY 1 -#define CERT_PRIVATE_KEY 2 -*/ - -# ifndef OPENSSL_NO_EC -/* - * From ECC-TLS draft, used in encoding the curve type in ECParameters - */ -# define EXPLICIT_PRIME_CURVE_TYPE 1 -# define EXPLICIT_CHAR2_CURVE_TYPE 2 -# define NAMED_CURVE_TYPE 3 -# endif /* OPENSSL_NO_EC */ - -typedef struct cert_pkey_st { - X509 *x509; - EVP_PKEY *privatekey; - /* Digest to use when signing */ - const EVP_MD *digest; - /* Chain for this certificate */ - STACK_OF(X509) *chain; -# ifndef OPENSSL_NO_TLSEXT - /*- - * serverinfo data for this certificate. The data is in TLS Extension - * wire format, specifically it's a series of records like: - * uint16_t extension_type; // (RFC 5246, 7.4.1.4, Extension) - * uint16_t length; - * uint8_t data[length]; - */ - unsigned char *serverinfo; - size_t serverinfo_length; -# endif - /* - * Set if CERT_PKEY can be used with current SSL session: e.g. - * appropriate curve, signature algorithms etc. If zero it can't be used - * at all. - */ - int valid_flags; -} CERT_PKEY; -/* Retrieve Suite B flags */ -# define tls1_suiteb(s) (s->cert->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS) -/* Uses to check strict mode: suite B modes are always strict */ -# define SSL_CERT_FLAGS_CHECK_TLS_STRICT \ - (SSL_CERT_FLAG_SUITEB_128_LOS|SSL_CERT_FLAG_TLS_STRICT) - -typedef struct { - unsigned short ext_type; - /* - * Per-connection flags relating to this extension type: not used if - * part of an SSL_CTX structure. - */ - unsigned short ext_flags; - custom_ext_add_cb add_cb; - custom_ext_free_cb free_cb; - void *add_arg; - custom_ext_parse_cb parse_cb; - void *parse_arg; -} custom_ext_method; - -/* ext_flags values */ - -/* - * Indicates an extension has been received. Used to check for unsolicited or - * duplicate extensions. - */ -# define SSL_EXT_FLAG_RECEIVED 0x1 -/* - * Indicates an extension has been sent: used to enable sending of - * corresponding ServerHello extension. - */ -# define SSL_EXT_FLAG_SENT 0x2 - -# define MAX_WARN_ALERT_COUNT 5 - -typedef struct { - custom_ext_method *meths; - size_t meths_count; -} custom_ext_methods; - -typedef struct cert_st { - /* Current active set */ - /* - * ALWAYS points to an element of the pkeys array - * Probably it would make more sense to store - * an index, not a pointer. - */ - CERT_PKEY *key; - /* - * For servers the following masks are for the key and auth algorithms - * that are supported by the certs below. For clients they are masks of - * *disabled* algorithms based on the current session. - */ - int valid; - unsigned long mask_k; - unsigned long mask_a; - unsigned long export_mask_k; - unsigned long export_mask_a; - /* Client only */ - unsigned long mask_ssl; -# ifndef OPENSSL_NO_RSA - RSA *rsa_tmp; - RSA *(*rsa_tmp_cb) (SSL *ssl, int is_export, int keysize); -# endif -# ifndef OPENSSL_NO_DH - DH *dh_tmp; - DH *(*dh_tmp_cb) (SSL *ssl, int is_export, int keysize); -# endif -# ifndef OPENSSL_NO_ECDH - EC_KEY *ecdh_tmp; - /* Callback for generating ephemeral ECDH keys */ - EC_KEY *(*ecdh_tmp_cb) (SSL *ssl, int is_export, int keysize); - /* Select ECDH parameters automatically */ - int ecdh_tmp_auto; -# endif - /* Flags related to certificates */ - unsigned int cert_flags; - CERT_PKEY pkeys[SSL_PKEY_NUM]; - /* - * Certificate types (received or sent) in certificate request message. - * On receive this is only set if number of certificate types exceeds - * SSL3_CT_NUMBER. - */ - unsigned char *ctypes; - size_t ctype_num; - /* - * signature algorithms peer reports: e.g. supported signature algorithms - * extension for server or as part of a certificate request for client. - */ - unsigned char *peer_sigalgs; - /* Size of above array */ - size_t peer_sigalgslen; - /* - * suppported signature algorithms. When set on a client this is sent in - * the client hello as the supported signature algorithms extension. For - * servers it represents the signature algorithms we are willing to use. - */ - unsigned char *conf_sigalgs; - /* Size of above array */ - size_t conf_sigalgslen; - /* - * Client authentication signature algorithms, if not set then uses - * conf_sigalgs. On servers these will be the signature algorithms sent - * to the client in a cerificate request for TLS 1.2. On a client this - * represents the signature algortithms we are willing to use for client - * authentication. - */ - unsigned char *client_sigalgs; - /* Size of above array */ - size_t client_sigalgslen; - /* - * Signature algorithms shared by client and server: cached because these - * are used most often. - */ - TLS_SIGALGS *shared_sigalgs; - size_t shared_sigalgslen; - /* - * Certificate setup callback: if set is called whenever a certificate - * may be required (client or server). the callback can then examine any - * appropriate parameters and setup any certificates required. This - * allows advanced applications to select certificates on the fly: for - * example based on supported signature algorithms or curves. - */ - int (*cert_cb) (SSL *ssl, void *arg); - void *cert_cb_arg; - /* - * Optional X509_STORE for chain building or certificate validation If - * NULL the parent SSL_CTX store is used instead. - */ - X509_STORE *chain_store; - X509_STORE *verify_store; - /* Raw values of the cipher list from a client */ - unsigned char *ciphers_raw; - size_t ciphers_rawlen; - /* Custom extension methods for server and client */ - custom_ext_methods cli_ext; - custom_ext_methods srv_ext; - int references; /* >1 only if SSL_copy_session_id is used */ - /* non-optimal, but here due to compatibility */ - unsigned char *alpn_proposed; /* server */ - unsigned int alpn_proposed_len; - int alpn_sent; /* client */ - /* Count of the number of consecutive warning alerts received */ - unsigned int alert_count; -} CERT; - -typedef struct sess_cert_st { - STACK_OF(X509) *cert_chain; /* as received from peer (not for SSL2) */ - /* The 'peer_...' members are used only by clients. */ - int peer_cert_type; - CERT_PKEY *peer_key; /* points to an element of peer_pkeys (never - * NULL!) */ - CERT_PKEY peer_pkeys[SSL_PKEY_NUM]; - /* - * Obviously we don't have the private keys of these, so maybe we - * shouldn't even use the CERT_PKEY type here. - */ -# ifndef OPENSSL_NO_RSA - RSA *peer_rsa_tmp; /* not used for SSL 2 */ -# endif -# ifndef OPENSSL_NO_DH - DH *peer_dh_tmp; /* not used for SSL 2 */ -# endif -# ifndef OPENSSL_NO_ECDH - EC_KEY *peer_ecdh_tmp; -# endif - int references; /* actually always 1 at the moment */ -} SESS_CERT; -/* Structure containing decoded values of signature algorithms extension */ -struct tls_sigalgs_st { - /* NID of hash algorithm */ - int hash_nid; - /* NID of signature algorithm */ - int sign_nid; - /* Combined hash and signature NID */ - int signandhash_nid; - /* Raw values used in extension */ - unsigned char rsign; - unsigned char rhash; -}; - -/* - * #define MAC_DEBUG - */ - -/* - * #define ERR_DEBUG - */ -/* - * #define ABORT_DEBUG - */ -/* - * #define PKT_DEBUG 1 - */ -/* - * #define DES_DEBUG - */ -/* - * #define DES_OFB_DEBUG - */ -/* - * #define SSL_DEBUG - */ -/* - * #define RSA_DEBUG - */ -/* - * #define IDEA_DEBUG - */ - -# define FP_ICC (int (*)(const void *,const void *)) -# define ssl_put_cipher_by_char(ssl,ciph,ptr) \ - ((ssl)->method->put_cipher_by_char((ciph),(ptr))) - -/* - * This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff It is a bit - * of a mess of functions, but hell, think of it as an opaque structure :-) - */ -typedef struct ssl3_enc_method { - int (*enc) (SSL *, int); - int (*mac) (SSL *, unsigned char *, int); - int (*setup_key_block) (SSL *); - int (*generate_master_secret) (SSL *, unsigned char *, unsigned char *, - int); - int (*change_cipher_state) (SSL *, int); - int (*final_finish_mac) (SSL *, const char *, int, unsigned char *); - int finish_mac_length; - int (*cert_verify_mac) (SSL *, int, unsigned char *); - const char *client_finished_label; - int client_finished_label_len; - const char *server_finished_label; - int server_finished_label_len; - int (*alert_value) (int); - int (*export_keying_material) (SSL *, unsigned char *, size_t, - const char *, size_t, - const unsigned char *, size_t, - int use_context); - /* Various flags indicating protocol version requirements */ - unsigned int enc_flags; - /* Handshake header length */ - unsigned int hhlen; - /* Set the handshake header */ - void (*set_handshake_header) (SSL *s, int type, unsigned long len); - /* Write out handshake message */ - int (*do_write) (SSL *s); -} SSL3_ENC_METHOD; - -# define SSL_HM_HEADER_LENGTH(s) s->method->ssl3_enc->hhlen -# define ssl_handshake_start(s) \ - (((unsigned char *)s->init_buf->data) + s->method->ssl3_enc->hhlen) -# define ssl_set_handshake_header(s, htype, len) \ - s->method->ssl3_enc->set_handshake_header(s, htype, len) -# define ssl_do_write(s) s->method->ssl3_enc->do_write(s) - -/* Values for enc_flags */ - -/* Uses explicit IV for CBC mode */ -# define SSL_ENC_FLAG_EXPLICIT_IV 0x1 -/* Uses signature algorithms extension */ -# define SSL_ENC_FLAG_SIGALGS 0x2 -/* Uses SHA256 default PRF */ -# define SSL_ENC_FLAG_SHA256_PRF 0x4 -/* Is DTLS */ -# define SSL_ENC_FLAG_DTLS 0x8 -/* - * Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: may - * apply to others in future. - */ -# define SSL_ENC_FLAG_TLS1_2_CIPHERS 0x10 - -# ifndef OPENSSL_NO_COMP -/* Used for holding the relevant compression methods loaded into SSL_CTX */ -typedef struct ssl3_comp_st { - int comp_id; /* The identifier byte for this compression - * type */ - char *name; /* Text name used for the compression type */ - COMP_METHOD *method; /* The method :-) */ -} SSL3_COMP; -# endif - -# ifndef OPENSSL_NO_BUF_FREELISTS -typedef struct ssl3_buf_freelist_st { - size_t chunklen; - unsigned int len; - struct ssl3_buf_freelist_entry_st *head; -} SSL3_BUF_FREELIST; - -typedef struct ssl3_buf_freelist_entry_st { - struct ssl3_buf_freelist_entry_st *next; -} SSL3_BUF_FREELIST_ENTRY; -# endif - -extern SSL3_ENC_METHOD ssl3_undef_enc_method; -OPENSSL_EXTERN const SSL_CIPHER ssl2_ciphers[]; -OPENSSL_EXTERN SSL_CIPHER ssl3_ciphers[]; - -SSL_METHOD *ssl_bad_method(int ver); - -extern SSL3_ENC_METHOD TLSv1_enc_data; -extern SSL3_ENC_METHOD TLSv1_1_enc_data; -extern SSL3_ENC_METHOD TLSv1_2_enc_data; -extern SSL3_ENC_METHOD SSLv3_enc_data; -extern SSL3_ENC_METHOD DTLSv1_enc_data; -extern SSL3_ENC_METHOD DTLSv1_2_enc_data; - -# define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \ - s_get_meth, enc_data) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - version, \ - tls1_new, \ - tls1_clear, \ - tls1_free, \ - s_accept, \ - s_connect, \ - ssl3_read, \ - ssl3_peek, \ - ssl3_write, \ - ssl3_shutdown, \ - ssl3_renegotiate, \ - ssl3_renegotiate_check, \ - ssl3_get_message, \ - ssl3_read_bytes, \ - ssl3_write_bytes, \ - ssl3_dispatch_alert, \ - ssl3_ctrl, \ - ssl3_ctx_ctrl, \ - ssl3_get_cipher_by_char, \ - ssl3_put_cipher_by_char, \ - ssl3_pending, \ - ssl3_num_ciphers, \ - ssl3_get_cipher, \ - s_get_meth, \ - tls1_default_timeout, \ - &enc_data, \ - ssl_undefined_void_function, \ - ssl3_callback_ctrl, \ - ssl3_ctx_callback_ctrl, \ - }; \ - return &func_name##_data; \ - } - -# define IMPLEMENT_ssl3_meth_func(func_name, s_accept, s_connect, s_get_meth) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - SSL3_VERSION, \ - ssl3_new, \ - ssl3_clear, \ - ssl3_free, \ - s_accept, \ - s_connect, \ - ssl3_read, \ - ssl3_peek, \ - ssl3_write, \ - ssl3_shutdown, \ - ssl3_renegotiate, \ - ssl3_renegotiate_check, \ - ssl3_get_message, \ - ssl3_read_bytes, \ - ssl3_write_bytes, \ - ssl3_dispatch_alert, \ - ssl3_ctrl, \ - ssl3_ctx_ctrl, \ - ssl3_get_cipher_by_char, \ - ssl3_put_cipher_by_char, \ - ssl3_pending, \ - ssl3_num_ciphers, \ - ssl3_get_cipher, \ - s_get_meth, \ - ssl3_default_timeout, \ - &SSLv3_enc_data, \ - ssl_undefined_void_function, \ - ssl3_callback_ctrl, \ - ssl3_ctx_callback_ctrl, \ - }; \ - return &func_name##_data; \ - } - -# define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect, s_get_meth) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - TLS1_2_VERSION, \ - tls1_new, \ - tls1_clear, \ - tls1_free, \ - s_accept, \ - s_connect, \ - ssl23_read, \ - ssl23_peek, \ - ssl23_write, \ - ssl_undefined_function, \ - ssl_undefined_function, \ - ssl_ok, \ - ssl3_get_message, \ - ssl3_read_bytes, \ - ssl3_write_bytes, \ - ssl3_dispatch_alert, \ - ssl3_ctrl, \ - ssl3_ctx_ctrl, \ - ssl23_get_cipher_by_char, \ - ssl23_put_cipher_by_char, \ - ssl_undefined_const_function, \ - ssl23_num_ciphers, \ - ssl23_get_cipher, \ - s_get_meth, \ - ssl23_default_timeout, \ - &TLSv1_2_enc_data, \ - ssl_undefined_void_function, \ - ssl3_callback_ctrl, \ - ssl3_ctx_callback_ctrl, \ - }; \ - return &func_name##_data; \ - } - -# define IMPLEMENT_ssl2_meth_func(func_name, s_accept, s_connect, s_get_meth) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - SSL2_VERSION, \ - ssl2_new, /* local */ \ - ssl2_clear, /* local */ \ - ssl2_free, /* local */ \ - s_accept, \ - s_connect, \ - ssl2_read, \ - ssl2_peek, \ - ssl2_write, \ - ssl2_shutdown, \ - ssl_ok, /* NULL - renegotiate */ \ - ssl_ok, /* NULL - check renegotiate */ \ - NULL, /* NULL - ssl_get_message */ \ - NULL, /* NULL - ssl_get_record */ \ - NULL, /* NULL - ssl_write_bytes */ \ - NULL, /* NULL - dispatch_alert */ \ - ssl2_ctrl, /* local */ \ - ssl2_ctx_ctrl, /* local */ \ - ssl2_get_cipher_by_char, \ - ssl2_put_cipher_by_char, \ - ssl2_pending, \ - ssl2_num_ciphers, \ - ssl2_get_cipher, \ - s_get_meth, \ - ssl2_default_timeout, \ - &ssl3_undef_enc_method, \ - ssl_undefined_void_function, \ - ssl2_callback_ctrl, /* local */ \ - ssl2_ctx_callback_ctrl, /* local */ \ - }; \ - return &func_name##_data; \ - } - -# define IMPLEMENT_dtls1_meth_func(version, func_name, s_accept, s_connect, \ - s_get_meth, enc_data) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - version, \ - dtls1_new, \ - dtls1_clear, \ - dtls1_free, \ - s_accept, \ - s_connect, \ - ssl3_read, \ - ssl3_peek, \ - ssl3_write, \ - dtls1_shutdown, \ - ssl3_renegotiate, \ - ssl3_renegotiate_check, \ - dtls1_get_message, \ - dtls1_read_bytes, \ - dtls1_write_app_data_bytes, \ - dtls1_dispatch_alert, \ - dtls1_ctrl, \ - ssl3_ctx_ctrl, \ - ssl3_get_cipher_by_char, \ - ssl3_put_cipher_by_char, \ - ssl3_pending, \ - ssl3_num_ciphers, \ - dtls1_get_cipher, \ - s_get_meth, \ - dtls1_default_timeout, \ - &enc_data, \ - ssl_undefined_void_function, \ - ssl3_callback_ctrl, \ - ssl3_ctx_callback_ctrl, \ - }; \ - return &func_name##_data; \ - } - -struct openssl_ssl_test_functions { - int (*p_ssl_init_wbio_buffer) (SSL *s, int push); - int (*p_ssl3_setup_buffers) (SSL *s); - int (*p_tls1_process_heartbeat) (SSL *s); - int (*p_dtls1_process_heartbeat) (SSL *s); -}; - -# ifndef OPENSSL_UNIT_TEST - -void ssl_clear_cipher_ctx(SSL *s); -int ssl_clear_bad_session(SSL *s); -CERT *ssl_cert_new(void); -CERT *ssl_cert_dup(CERT *cert); -void ssl_cert_set_default_md(CERT *cert); -int ssl_cert_inst(CERT **o); -void ssl_cert_clear_certs(CERT *c); -void ssl_cert_free(CERT *c); -SESS_CERT *ssl_sess_cert_new(void); -void ssl_sess_cert_free(SESS_CERT *sc); -int ssl_set_peer_cert_type(SESS_CERT *c, int type); -int ssl_get_new_session(SSL *s, int session); -int ssl_get_prev_session(SSL *s, unsigned char *session, int len, - const unsigned char *limit); -SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket); -int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b); -DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); -int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, - const SSL_CIPHER *const *bp); -STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, - int num, - STACK_OF(SSL_CIPHER) **skp); -int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, - unsigned char *p, - int (*put_cb) (const SSL_CIPHER *, - unsigned char *)); -STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth, - STACK_OF(SSL_CIPHER) **pref, - STACK_OF(SSL_CIPHER) **sorted, - const char *rule_str, CERT *c); -void ssl_update_cache(SSL *s, int mode); -int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, - const EVP_MD **md, int *mac_pkey_type, - int *mac_secret_size, SSL_COMP **comp); -int ssl_get_handshake_digest(int i, long *mask, const EVP_MD **md); -int ssl_cipher_get_cert_index(const SSL_CIPHER *c); -const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr); -int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain); -int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain); -int ssl_cert_add0_chain_cert(CERT *c, X509 *x); -int ssl_cert_add1_chain_cert(CERT *c, X509 *x); -int ssl_cert_select_current(CERT *c, X509 *x); -int ssl_cert_set_current(CERT *c, long arg); -X509 *ssl_cert_get0_next_certificate(CERT *c, int first); -void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), - void *arg); - -int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk); -int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l); -int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags); -int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref); -int ssl_undefined_function(SSL *s); -int ssl_undefined_void_function(void); -int ssl_undefined_const_function(const SSL *s); -CERT_PKEY *ssl_get_server_send_pkey(const SSL *s); -# ifndef OPENSSL_NO_TLSEXT -int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, - size_t *serverinfo_length); -# endif -EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd); -int ssl_cert_type(X509 *x, EVP_PKEY *pkey); -void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher); -STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s); -int ssl_verify_alarm_type(long type); -void ssl_load_ciphers(void); -int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, int len); - -int ssl2_enc_init(SSL *s, int client); -int ssl2_generate_key_material(SSL *s); -int ssl2_enc(SSL *s, int send_data); -void ssl2_mac(SSL *s, unsigned char *mac, int send_data); -const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p); -int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); -int ssl2_part_read(SSL *s, unsigned long f, int i); -int ssl2_do_write(SSL *s); -int ssl2_set_certificate(SSL *s, int type, int len, - const unsigned char *data); -void ssl2_return_error(SSL *s, int reason); -void ssl2_write_error(SSL *s); -int ssl2_num_ciphers(void); -const SSL_CIPHER *ssl2_get_cipher(unsigned int u); -int ssl2_new(SSL *s); -void ssl2_free(SSL *s); -int ssl2_accept(SSL *s); -int ssl2_connect(SSL *s); -int ssl2_read(SSL *s, void *buf, int len); -int ssl2_peek(SSL *s, void *buf, int len); -int ssl2_write(SSL *s, const void *buf, int len); -int ssl2_shutdown(SSL *s); -void ssl2_clear(SSL *s); -long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg); -long ssl2_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg); -long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); -long ssl2_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void)); -int ssl2_pending(const SSL *s); -long ssl2_default_timeout(void); - -const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); -int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); -int ssl3_init_finished_mac(SSL *s); -int ssl3_send_server_certificate(SSL *s); -int ssl3_send_newsession_ticket(SSL *s); -int ssl3_send_cert_status(SSL *s); -int ssl3_get_finished(SSL *s, int state_a, int state_b); -int ssl3_setup_key_block(SSL *s); -int ssl3_send_change_cipher_spec(SSL *s, int state_a, int state_b); -int ssl3_change_cipher_state(SSL *s, int which); -void ssl3_cleanup_key_block(SSL *s); -int ssl3_do_write(SSL *s, int type); -int ssl3_send_alert(SSL *s, int level, int desc); -int ssl3_generate_master_secret(SSL *s, unsigned char *out, - unsigned char *p, int len); -int ssl3_get_req_cert_type(SSL *s, unsigned char *p); -long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); -int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen); -int ssl3_num_ciphers(void); -const SSL_CIPHER *ssl3_get_cipher(unsigned int u); -int ssl3_renegotiate(SSL *ssl); -int ssl3_renegotiate_check(SSL *ssl); -int ssl3_dispatch_alert(SSL *s); -int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); -int ssl3_write_bytes(SSL *s, int type, const void *buf, int len); -int ssl3_final_finish_mac(SSL *s, const char *sender, int slen, - unsigned char *p); -int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p); -void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len); -int ssl3_enc(SSL *s, int send_data); -int n_ssl3_mac(SSL *ssl, unsigned char *md, int send_data); -void ssl3_free_digest_list(SSL *s); -unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk); -SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, STACK_OF(SSL_CIPHER) *clnt, - STACK_OF(SSL_CIPHER) *srvr); -int ssl3_setup_buffers(SSL *s); -int ssl3_setup_read_buffer(SSL *s); -int ssl3_setup_write_buffer(SSL *s); -int ssl3_release_read_buffer(SSL *s); -int ssl3_release_write_buffer(SSL *s); -int ssl3_digest_cached_records(SSL *s); -int ssl3_new(SSL *s); -void ssl3_free(SSL *s); -int ssl3_accept(SSL *s); -int ssl3_connect(SSL *s); -int ssl3_read(SSL *s, void *buf, int len); -int ssl3_peek(SSL *s, void *buf, int len); -int ssl3_write(SSL *s, const void *buf, int len); -int ssl3_shutdown(SSL *s); -void ssl3_clear(SSL *s); -long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg); -long ssl3_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg); -long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); -long ssl3_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void)); -int ssl3_pending(const SSL *s); - -void ssl3_record_sequence_update(unsigned char *seq); -int ssl3_do_change_cipher_spec(SSL *ssl); -long ssl3_default_timeout(void); - -void ssl3_set_handshake_header(SSL *s, int htype, unsigned long len); -int ssl3_handshake_write(SSL *s); - -int ssl23_num_ciphers(void); -const SSL_CIPHER *ssl23_get_cipher(unsigned int u); -int ssl23_read(SSL *s, void *buf, int len); -int ssl23_peek(SSL *s, void *buf, int len); -int ssl23_write(SSL *s, const void *buf, int len); -int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); -const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p); -long ssl23_default_timeout(void); - -long tls1_default_timeout(void); -int dtls1_do_write(SSL *s, int type); -int ssl3_read_n(SSL *s, int n, int max, int extend); -int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); -int ssl3_do_compress(SSL *ssl); -int ssl3_do_uncompress(SSL *ssl); -int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, - unsigned int len); -unsigned char *dtls1_set_message_header(SSL *s, - unsigned char *p, unsigned char mt, - unsigned long len, - unsigned long frag_off, - unsigned long frag_len); - -int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len); -int dtls1_write_bytes(SSL *s, int type, const void *buf, int len); - -int dtls1_send_change_cipher_spec(SSL *s, int a, int b); -int dtls1_read_failed(SSL *s, int code); -int dtls1_buffer_message(SSL *s, int ccs); -int dtls1_retransmit_message(SSL *s, unsigned short seq, - unsigned long frag_off, int *found); -int dtls1_get_queue_priority(unsigned short seq, int is_ccs); -int dtls1_retransmit_buffered_messages(SSL *s); -void dtls1_clear_received_buffer(SSL *s); -void dtls1_clear_sent_buffer(SSL *s); -void dtls1_get_message_header(unsigned char *data, - struct hm_header_st *msg_hdr); -void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); -void dtls1_reset_seq_numbers(SSL *s, int rw); -long dtls1_default_timeout(void); -struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft); -int dtls1_check_timeout_num(SSL *s); -int dtls1_handle_timeout(SSL *s); -const SSL_CIPHER *dtls1_get_cipher(unsigned int u); -void dtls1_start_timer(SSL *s); -void dtls1_stop_timer(SSL *s); -int dtls1_is_timer_expired(SSL *s); -void dtls1_double_timeout(SSL *s); -int dtls1_send_newsession_ticket(SSL *s); -unsigned int dtls1_min_mtu(SSL *s); -unsigned int dtls1_link_min_mtu(void); -void dtls1_hm_fragment_free(hm_fragment *frag); - -/* some client-only functions */ -int ssl3_client_hello(SSL *s); -int ssl3_get_server_hello(SSL *s); -int ssl3_get_certificate_request(SSL *s); -int ssl3_get_new_session_ticket(SSL *s); -int ssl3_get_cert_status(SSL *s); -int ssl3_get_server_done(SSL *s); -int ssl3_send_client_verify(SSL *s); -int ssl3_send_client_certificate(SSL *s); -int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); -int ssl3_send_client_key_exchange(SSL *s); -int ssl3_get_key_exchange(SSL *s); -int ssl3_get_server_certificate(SSL *s); -int ssl3_check_cert_and_algorithm(SSL *s); -# ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_NEXTPROTONEG -int ssl3_send_next_proto(SSL *s); -# endif -# endif - -int dtls1_client_hello(SSL *s); - -/* some server-only functions */ -int ssl3_get_client_hello(SSL *s); -int ssl3_send_server_hello(SSL *s); -int ssl3_send_hello_request(SSL *s); -int ssl3_send_server_key_exchange(SSL *s); -int ssl3_send_certificate_request(SSL *s); -int ssl3_send_server_done(SSL *s); -int ssl3_get_client_certificate(SSL *s); -int ssl3_get_client_key_exchange(SSL *s); -int ssl3_get_cert_verify(SSL *s); -# ifndef OPENSSL_NO_NEXTPROTONEG -int ssl3_get_next_proto(SSL *s); -# endif - -int ssl23_accept(SSL *s); -int ssl23_connect(SSL *s); -int ssl23_read_bytes(SSL *s, int n); -int ssl23_write_bytes(SSL *s); - -int tls1_new(SSL *s); -void tls1_free(SSL *s); -void tls1_clear(SSL *s); -long tls1_ctrl(SSL *s, int cmd, long larg, void *parg); -long tls1_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); - -int dtls1_new(SSL *s); -int dtls1_accept(SSL *s); -int dtls1_connect(SSL *s); -void dtls1_free(SSL *s); -void dtls1_clear(SSL *s); -long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg); -int dtls1_shutdown(SSL *s); - -long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); -int dtls1_get_record(SSL *s); -int do_dtls1_write(SSL *s, int type, const unsigned char *buf, - unsigned int len, int create_empty_fragement); -int dtls1_dispatch_alert(SSL *s); - -int ssl_init_wbio_buffer(SSL *s, int push); -void ssl_free_wbio_buffer(SSL *s); - -int tls1_change_cipher_state(SSL *s, int which); -int tls1_setup_key_block(SSL *s); -int tls1_enc(SSL *s, int snd); -int tls1_final_finish_mac(SSL *s, - const char *str, int slen, unsigned char *p); -int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p); -int tls1_mac(SSL *ssl, unsigned char *md, int snd); -int tls1_generate_master_secret(SSL *s, unsigned char *out, - unsigned char *p, int len); -int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, - const char *label, size_t llen, - const unsigned char *p, size_t plen, - int use_context); -int tls1_alert_code(int code); -int ssl3_alert_code(int code); -int ssl_ok(SSL *s); - -# ifndef OPENSSL_NO_ECDH -int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s); -# endif - -SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); - -# ifndef OPENSSL_NO_EC -int tls1_ec_curve_id2nid(int curve_id); -int tls1_ec_nid2curve_id(int nid); -int tls1_check_curve(SSL *s, const unsigned char *p, size_t len); -int tls1_shared_curve(SSL *s, int nmatch); -int tls1_set_curves(unsigned char **pext, size_t *pextlen, - int *curves, size_t ncurves); -int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, - const char *str); -# ifndef OPENSSL_NO_ECDH -int tls1_check_ec_tmp_key(SSL *s, unsigned long id); -# endif /* OPENSSL_NO_ECDH */ -# endif /* OPENSSL_NO_EC */ - -# ifndef OPENSSL_NO_TLSEXT -int tls1_shared_list(SSL *s, - const unsigned char *l1, size_t l1len, - const unsigned char *l2, size_t l2len, int nmatch); -unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, - unsigned char *limit, int *al); -unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, - unsigned char *limit, int *al); -int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, - unsigned char *limit); -int tls1_set_server_sigalgs(SSL *s); -int ssl_check_clienthello_tlsext_late(SSL *s, int *al); -int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, - unsigned char *d, int n); -int ssl_prepare_clienthello_tlsext(SSL *s); -int ssl_prepare_serverhello_tlsext(SSL *s); - -# ifndef OPENSSL_NO_HEARTBEATS -int tls1_heartbeat(SSL *s); -int dtls1_heartbeat(SSL *s); -int tls1_process_heartbeat(SSL *s); -int dtls1_process_heartbeat(SSL *s); -# endif - -# ifdef OPENSSL_NO_SHA256 -# define tlsext_tick_md EVP_sha1 -# else -# define tlsext_tick_md EVP_sha256 -# endif -int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, - const unsigned char *limit, SSL_SESSION **ret); - -int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, - const EVP_MD *md); -int tls12_get_sigid(const EVP_PKEY *pk); -const EVP_MD *tls12_get_hash(unsigned char hash_alg); - -int tls1_set_sigalgs_list(CERT *c, const char *str, int client); -int tls1_set_sigalgs(CERT *c, const int *salg, size_t salglen, int client); -int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, - int idx); -void tls1_set_cert_validity(SSL *s); - -# endif -EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md); -void ssl_clear_hash_ctx(EVP_MD_CTX **hash); -int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, - int maxlen); -int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, - int *al); -int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, - int maxlen); -int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, - int *al); -long ssl_get_algorithm2(SSL *s); -int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize); -int tls1_process_sigalgs(SSL *s); -size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs); -int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, - const unsigned char *sig, EVP_PKEY *pkey); -void ssl_set_client_disabled(SSL *s); - -int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, - int maxlen); -int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len, - int *al); -int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, - int maxlen); -int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len, - int *al); - -/* s3_cbc.c */ -void ssl3_cbc_copy_mac(unsigned char *out, - const SSL3_RECORD *rec, - unsigned md_size, unsigned orig_len); -int ssl3_cbc_remove_padding(const SSL *s, - SSL3_RECORD *rec, - unsigned block_size, unsigned mac_size); -int tls1_cbc_remove_padding(const SSL *s, - SSL3_RECORD *rec, - unsigned block_size, unsigned mac_size); -char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); -int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, - unsigned char *md_out, - size_t *md_out_size, - const unsigned char header[13], - const unsigned char *data, - size_t data_plus_mac_size, - size_t data_plus_mac_plus_padding_size, - const unsigned char *mac_secret, - unsigned mac_secret_length, char is_sslv3); - -void tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx, - EVP_MD_CTX *mac_ctx, const unsigned char *data, - size_t data_len, size_t orig_len); - -int srp_verify_server_param(SSL *s, int *al); - -/* t1_ext.c */ - -void custom_ext_init(custom_ext_methods *meths); - -int custom_ext_parse(SSL *s, int server, - unsigned int ext_type, - const unsigned char *ext_data, size_t ext_size, int *al); -int custom_ext_add(SSL *s, int server, - unsigned char **pret, unsigned char *limit, int *al); - -int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src); -int custom_exts_copy_flags(custom_ext_methods *dst, - const custom_ext_methods *src); -void custom_exts_free(custom_ext_methods *exts); - -# else - -# define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer -# define ssl3_setup_buffers SSL_test_functions()->p_ssl3_setup_buffers -# define tls1_process_heartbeat SSL_test_functions()->p_tls1_process_heartbeat -# define dtls1_process_heartbeat SSL_test_functions()->p_dtls1_process_heartbeat - -# endif -#endif diff --git a/thirdparty/openssl/ssl/ssl_rsa.c b/thirdparty/openssl/ssl/ssl_rsa.c deleted file mode 100644 index af03d45c2e..0000000000 --- a/thirdparty/openssl/ssl/ssl_rsa.c +++ /dev/null @@ -1,1048 +0,0 @@ -/* ssl/ssl_rsa.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include "ssl_locl.h" -#include <openssl/bio.h> -#include <openssl/objects.h> -#include <openssl/evp.h> -#include <openssl/x509.h> -#include <openssl/pem.h> - -static int ssl_set_cert(CERT *c, X509 *x509); -static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); -int SSL_use_certificate(SSL *ssl, X509 *x) -{ - if (x == NULL) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (!ssl_cert_inst(&ssl->cert)) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); - return (0); - } - return (ssl_set_cert(ssl->cert, x)); -} - -#ifndef OPENSSL_NO_STDIO -int SSL_use_certificate_file(SSL *ssl, const char *file, int type) -{ - int j; - BIO *in; - int ret = 0; - X509 *x = NULL; - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - x = d2i_X509_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, - ssl->ctx->default_passwd_callback_userdata); - } else { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - - if (x == NULL) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j); - goto end; - } - - ret = SSL_use_certificate(ssl, x); - end: - if (x != NULL) - X509_free(x); - if (in != NULL) - BIO_free(in); - return (ret); -} -#endif - -int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) -{ - X509 *x; - int ret; - - x = d2i_X509(NULL, &d, (long)len); - if (x == NULL) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); - return (0); - } - - ret = SSL_use_certificate(ssl, x); - X509_free(x); - return (ret); -} - -#ifndef OPENSSL_NO_RSA -int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) -{ - EVP_PKEY *pkey; - int ret; - - if (rsa == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (!ssl_cert_inst(&ssl->cert)) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); - return (0); - } - if ((pkey = EVP_PKEY_new()) == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); - return (0); - } - - RSA_up_ref(rsa); - if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { - RSA_free(rsa); - return 0; - } - - ret = ssl_set_pkey(ssl->cert, pkey); - EVP_PKEY_free(pkey); - return (ret); -} -#endif - -static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) -{ - int i; - /* - * Special case for DH: check two DH certificate types for a match. This - * means for DH certificates we must set the certificate first. - */ - if (pkey->type == EVP_PKEY_DH) { - X509 *x; - i = -1; - x = c->pkeys[SSL_PKEY_DH_RSA].x509; - if (x && X509_check_private_key(x, pkey)) - i = SSL_PKEY_DH_RSA; - x = c->pkeys[SSL_PKEY_DH_DSA].x509; - if (i == -1 && x && X509_check_private_key(x, pkey)) - i = SSL_PKEY_DH_DSA; - ERR_clear_error(); - } else - i = ssl_cert_type(NULL, pkey); - if (i < 0) { - SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); - return (0); - } - - if (c->pkeys[i].x509 != NULL) { - EVP_PKEY *pktmp; - pktmp = X509_get_pubkey(c->pkeys[i].x509); - if (pktmp == NULL) { - SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE); - EVP_PKEY_free(pktmp); - return 0; - } - /* - * The return code from EVP_PKEY_copy_parameters is deliberately - * ignored. Some EVP_PKEY types cannot do this. - */ - EVP_PKEY_copy_parameters(pktmp, pkey); - EVP_PKEY_free(pktmp); - ERR_clear_error(); - -#ifndef OPENSSL_NO_RSA - /* - * Don't check the public/private key, this is mostly for smart - * cards. - */ - if ((pkey->type == EVP_PKEY_RSA) && - (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) ; - else -#endif - if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { - X509_free(c->pkeys[i].x509); - c->pkeys[i].x509 = NULL; - return 0; - } - } - - if (c->pkeys[i].privatekey != NULL) - EVP_PKEY_free(c->pkeys[i].privatekey); - CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); - c->pkeys[i].privatekey = pkey; - c->key = &(c->pkeys[i]); - - c->valid = 0; - return (1); -} - -#ifndef OPENSSL_NO_RSA -# ifndef OPENSSL_NO_STDIO -int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) -{ - int j, ret = 0; - BIO *in; - RSA *rsa = NULL; - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - rsa = d2i_RSAPrivateKey_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - rsa = PEM_read_bio_RSAPrivateKey(in, NULL, - ssl->ctx->default_passwd_callback, - ssl-> - ctx->default_passwd_callback_userdata); - } else { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - if (rsa == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j); - goto end; - } - ret = SSL_use_RSAPrivateKey(ssl, rsa); - RSA_free(rsa); - end: - if (in != NULL) - BIO_free(in); - return (ret); -} -# endif - -int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len) -{ - int ret; - const unsigned char *p; - RSA *rsa; - - p = d; - if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); - return (0); - } - - ret = SSL_use_RSAPrivateKey(ssl, rsa); - RSA_free(rsa); - return (ret); -} -#endif /* !OPENSSL_NO_RSA */ - -int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) -{ - int ret; - - if (pkey == NULL) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (!ssl_cert_inst(&ssl->cert)) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); - return (0); - } - ret = ssl_set_pkey(ssl->cert, pkey); - return (ret); -} - -#ifndef OPENSSL_NO_STDIO -int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) -{ - int j, ret = 0; - BIO *in; - EVP_PKEY *pkey = NULL; - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - pkey = PEM_read_bio_PrivateKey(in, NULL, - ssl->ctx->default_passwd_callback, - ssl-> - ctx->default_passwd_callback_userdata); - } else if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - pkey = d2i_PrivateKey_bio(in, NULL); - } else { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - if (pkey == NULL) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j); - goto end; - } - ret = SSL_use_PrivateKey(ssl, pkey); - EVP_PKEY_free(pkey); - end: - if (in != NULL) - BIO_free(in); - return (ret); -} -#endif - -int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, - long len) -{ - int ret; - const unsigned char *p; - EVP_PKEY *pkey; - - p = d; - if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); - return (0); - } - - ret = SSL_use_PrivateKey(ssl, pkey); - EVP_PKEY_free(pkey); - return (ret); -} - -int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) -{ - if (x == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (!ssl_cert_inst(&ctx->cert)) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); - return (0); - } - return (ssl_set_cert(ctx->cert, x)); -} - -static int ssl_set_cert(CERT *c, X509 *x) -{ - EVP_PKEY *pkey; - int i; - - pkey = X509_get_pubkey(x); - if (pkey == NULL) { - SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); - return (0); - } - - i = ssl_cert_type(x, pkey); - if (i < 0) { - SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); - EVP_PKEY_free(pkey); - return (0); - } - - if (c->pkeys[i].privatekey != NULL) { - /* - * The return code from EVP_PKEY_copy_parameters is deliberately - * ignored. Some EVP_PKEY types cannot do this. - */ - EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); - ERR_clear_error(); - -#ifndef OPENSSL_NO_RSA - /* - * Don't check the public/private key, this is mostly for smart - * cards. - */ - if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) && - (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) & - RSA_METHOD_FLAG_NO_CHECK)) ; - else -#endif /* OPENSSL_NO_RSA */ - if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { - /* - * don't fail for a cert/key mismatch, just free current private - * key (when switching to a different cert & key, first this - * function should be used, then ssl_set_pkey - */ - EVP_PKEY_free(c->pkeys[i].privatekey); - c->pkeys[i].privatekey = NULL; - /* clear error queue */ - ERR_clear_error(); - } - } - - EVP_PKEY_free(pkey); - - if (c->pkeys[i].x509 != NULL) - X509_free(c->pkeys[i].x509); - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); - c->pkeys[i].x509 = x; - c->key = &(c->pkeys[i]); - - c->valid = 0; - return (1); -} - -#ifndef OPENSSL_NO_STDIO -int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) -{ - int j; - BIO *in; - int ret = 0; - X509 *x = NULL; - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - x = d2i_X509_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - } else { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - - if (x == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j); - goto end; - } - - ret = SSL_CTX_use_certificate(ctx, x); - end: - if (x != NULL) - X509_free(x); - if (in != NULL) - BIO_free(in); - return (ret); -} -#endif - -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, - const unsigned char *d) -{ - X509 *x; - int ret; - - x = d2i_X509(NULL, &d, (long)len); - if (x == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); - return (0); - } - - ret = SSL_CTX_use_certificate(ctx, x); - X509_free(x); - return (ret); -} - -#ifndef OPENSSL_NO_RSA -int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) -{ - int ret; - EVP_PKEY *pkey; - - if (rsa == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (!ssl_cert_inst(&ctx->cert)) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); - return (0); - } - if ((pkey = EVP_PKEY_new()) == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); - return (0); - } - - RSA_up_ref(rsa); - if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { - RSA_free(rsa); - return 0; - } - - ret = ssl_set_pkey(ctx->cert, pkey); - EVP_PKEY_free(pkey); - return (ret); -} - -# ifndef OPENSSL_NO_STDIO -int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) -{ - int j, ret = 0; - BIO *in; - RSA *rsa = NULL; - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - rsa = d2i_RSAPrivateKey_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - rsa = PEM_read_bio_RSAPrivateKey(in, NULL, - ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - } else { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - if (rsa == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j); - goto end; - } - ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); - RSA_free(rsa); - end: - if (in != NULL) - BIO_free(in); - return (ret); -} -# endif - -int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, - long len) -{ - int ret; - const unsigned char *p; - RSA *rsa; - - p = d; - if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); - return (0); - } - - ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); - RSA_free(rsa); - return (ret); -} -#endif /* !OPENSSL_NO_RSA */ - -int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) -{ - if (pkey == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (!ssl_cert_inst(&ctx->cert)) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); - return (0); - } - return (ssl_set_pkey(ctx->cert, pkey)); -} - -#ifndef OPENSSL_NO_STDIO -int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) -{ - int j, ret = 0; - BIO *in; - EVP_PKEY *pkey = NULL; - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - pkey = PEM_read_bio_PrivateKey(in, NULL, - ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - } else if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - pkey = d2i_PrivateKey_bio(in, NULL); - } else { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - if (pkey == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j); - goto end; - } - ret = SSL_CTX_use_PrivateKey(ctx, pkey); - EVP_PKEY_free(pkey); - end: - if (in != NULL) - BIO_free(in); - return (ret); -} -#endif - -int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, - const unsigned char *d, long len) -{ - int ret; - const unsigned char *p; - EVP_PKEY *pkey; - - p = d; - if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); - return (0); - } - - ret = SSL_CTX_use_PrivateKey(ctx, pkey); - EVP_PKEY_free(pkey); - return (ret); -} - -#ifndef OPENSSL_NO_STDIO -/* - * Read a file that contains our certificate in "PEM" format, possibly - * followed by a sequence of CA certificates that should be sent to the peer - * in the Certificate message. - */ -int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) -{ - BIO *in; - int ret = 0; - X509 *x = NULL; - - ERR_clear_error(); /* clear error stack for - * SSL_CTX_use_certificate() */ - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB); - goto end; - } - - x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - if (x == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); - goto end; - } - - ret = SSL_CTX_use_certificate(ctx, x); - - if (ERR_peek_error() != 0) - ret = 0; /* Key/certificate mismatch doesn't imply - * ret==0 ... */ - if (ret) { - /* - * If we could set up our certificate, now proceed to the CA - * certificates. - */ - X509 *ca; - int r; - unsigned long err; - - SSL_CTX_clear_chain_certs(ctx); - - while ((ca = PEM_read_bio_X509(in, NULL, - ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata)) - != NULL) { - r = SSL_CTX_add0_chain_cert(ctx, ca); - if (!r) { - X509_free(ca); - ret = 0; - goto end; - } - /* - * Note that we must not free r if it was successfully added to - * the chain (while we must free the main certificate, since its - * reference count is increased by SSL_CTX_use_certificate). - */ - } - /* When the while loop ends, it's usually just EOF. */ - err = ERR_peek_last_error(); - if (ERR_GET_LIB(err) == ERR_LIB_PEM - && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) - ERR_clear_error(); - else - ret = 0; /* some real error */ - } - - end: - if (x != NULL) - X509_free(x); - if (in != NULL) - BIO_free(in); - return (ret); -} -#endif - -#ifndef OPENSSL_NO_TLSEXT -static int serverinfo_find_extension(const unsigned char *serverinfo, - size_t serverinfo_length, - unsigned int extension_type, - const unsigned char **extension_data, - size_t *extension_length) -{ - *extension_data = NULL; - *extension_length = 0; - if (serverinfo == NULL || serverinfo_length == 0) - return -1; - for (;;) { - unsigned int type = 0; - size_t len = 0; - - /* end of serverinfo */ - if (serverinfo_length == 0) - return 0; /* Extension not found */ - - /* read 2-byte type field */ - if (serverinfo_length < 2) - return -1; /* Error */ - type = (serverinfo[0] << 8) + serverinfo[1]; - serverinfo += 2; - serverinfo_length -= 2; - - /* read 2-byte len field */ - if (serverinfo_length < 2) - return -1; /* Error */ - len = (serverinfo[0] << 8) + serverinfo[1]; - serverinfo += 2; - serverinfo_length -= 2; - - if (len > serverinfo_length) - return -1; /* Error */ - - if (type == extension_type) { - *extension_data = serverinfo; - *extension_length = len; - return 1; /* Success */ - } - - serverinfo += len; - serverinfo_length -= len; - } - return 0; /* Error */ -} - -static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type, - const unsigned char *in, - size_t inlen, int *al, void *arg) -{ - - if (inlen != 0) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - return 1; -} - -static int serverinfo_srv_add_cb(SSL *s, unsigned int ext_type, - const unsigned char **out, size_t *outlen, - int *al, void *arg) -{ - const unsigned char *serverinfo = NULL; - size_t serverinfo_length = 0; - - /* Is there serverinfo data for the chosen server cert? */ - if ((ssl_get_server_cert_serverinfo(s, &serverinfo, - &serverinfo_length)) != 0) { - /* Find the relevant extension from the serverinfo */ - int retval = serverinfo_find_extension(serverinfo, serverinfo_length, - ext_type, out, outlen); - if (retval == -1) { - *al = SSL_AD_DECODE_ERROR; - return -1; /* Error */ - } - if (retval == 0) - return 0; /* No extension found, don't send extension */ - return 1; /* Send extension */ - } - return 0; /* No serverinfo data found, don't send - * extension */ -} - -/* - * With a NULL context, this function just checks that the serverinfo data - * parses correctly. With a non-NULL context, it registers callbacks for - * the included extensions. - */ -static int serverinfo_process_buffer(const unsigned char *serverinfo, - size_t serverinfo_length, SSL_CTX *ctx) -{ - if (serverinfo == NULL || serverinfo_length == 0) - return 0; - for (;;) { - unsigned int ext_type = 0; - size_t len = 0; - - /* end of serverinfo */ - if (serverinfo_length == 0) - return 1; - - /* read 2-byte type field */ - if (serverinfo_length < 2) - return 0; - /* FIXME: check for types we understand explicitly? */ - - /* Register callbacks for extensions */ - ext_type = (serverinfo[0] << 8) + serverinfo[1]; - if (ctx) { - int have_ext_cbs = 0; - size_t i; - custom_ext_methods *exts = &ctx->cert->srv_ext; - custom_ext_method *meth = exts->meths; - - for (i = 0; i < exts->meths_count; i++, meth++) { - if (ext_type == meth->ext_type) { - have_ext_cbs = 1; - break; - } - } - - if (!have_ext_cbs && !SSL_CTX_add_server_custom_ext(ctx, ext_type, - serverinfo_srv_add_cb, - NULL, NULL, - serverinfo_srv_parse_cb, - NULL)) - return 0; - } - - serverinfo += 2; - serverinfo_length -= 2; - - /* read 2-byte len field */ - if (serverinfo_length < 2) - return 0; - len = (serverinfo[0] << 8) + serverinfo[1]; - serverinfo += 2; - serverinfo_length -= 2; - - if (len > serverinfo_length) - return 0; - - serverinfo += len; - serverinfo_length -= len; - } -} - -int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, - size_t serverinfo_length) -{ - unsigned char *new_serverinfo; - - if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (!serverinfo_process_buffer(serverinfo, serverinfo_length, NULL)) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA); - return 0; - } - if (!ssl_cert_inst(&ctx->cert)) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE); - return 0; - } - if (ctx->cert->key == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_INTERNAL_ERROR); - return 0; - } - new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo, - serverinfo_length); - if (new_serverinfo == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE); - return 0; - } - ctx->cert->key->serverinfo = new_serverinfo; - memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length); - ctx->cert->key->serverinfo_length = serverinfo_length; - - /* - * Now that the serverinfo is validated and stored, go ahead and - * register callbacks. - */ - if (!serverinfo_process_buffer(serverinfo, serverinfo_length, ctx)) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA); - return 0; - } - return 1; -} - -# ifndef OPENSSL_NO_STDIO -int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) -{ - unsigned char *serverinfo = NULL; - size_t serverinfo_length = 0; - unsigned char *extension = 0; - long extension_length = 0; - char *name = NULL; - char *header = NULL; - char namePrefix[] = "SERVERINFO FOR "; - int ret = 0; - BIO *bin = NULL; - size_t num_extensions = 0; - unsigned char *new_serverinfo; - - if (ctx == NULL || file == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, - ERR_R_PASSED_NULL_PARAMETER); - goto end; - } - - bin = BIO_new(BIO_s_file_internal()); - if (bin == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB); - goto end; - } - if (BIO_read_filename(bin, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB); - goto end; - } - - for (num_extensions = 0;; num_extensions++) { - if (PEM_read_bio(bin, &name, &header, &extension, &extension_length) - == 0) { - /* - * There must be at least one extension in this file - */ - if (num_extensions == 0) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, - SSL_R_NO_PEM_EXTENSIONS); - goto end; - } else /* End of file, we're done */ - break; - } - /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */ - if (strlen(name) < strlen(namePrefix)) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, - SSL_R_PEM_NAME_TOO_SHORT); - goto end; - } - if (strncmp(name, namePrefix, strlen(namePrefix)) != 0) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, - SSL_R_PEM_NAME_BAD_PREFIX); - goto end; - } - /* - * Check that the decoded PEM data is plausible (valid length field) - */ - if (extension_length < 4 - || (extension[2] << 8) + extension[3] != extension_length - 4) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA); - goto end; - } - /* Append the decoded extension to the serverinfo buffer */ - new_serverinfo = - OPENSSL_realloc(serverinfo, serverinfo_length + extension_length); - if (new_serverinfo == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE); - goto end; - } - serverinfo = new_serverinfo; - memcpy(serverinfo + serverinfo_length, extension, extension_length); - serverinfo_length += extension_length; - - OPENSSL_free(name); - name = NULL; - OPENSSL_free(header); - header = NULL; - OPENSSL_free(extension); - extension = NULL; - } - - ret = SSL_CTX_use_serverinfo(ctx, serverinfo, serverinfo_length); - end: - /* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */ - OPENSSL_free(name); - OPENSSL_free(header); - OPENSSL_free(extension); - OPENSSL_free(serverinfo); - if (bin != NULL) - BIO_free(bin); - return ret; -} -# endif /* OPENSSL_NO_STDIO */ -#endif /* OPENSSL_NO_TLSEXT */ diff --git a/thirdparty/openssl/ssl/ssl_sess.c b/thirdparty/openssl/ssl/ssl_sess.c deleted file mode 100644 index f50f514212..0000000000 --- a/thirdparty/openssl/ssl/ssl_sess.c +++ /dev/null @@ -1,1287 +0,0 @@ -/* ssl/ssl_sess.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 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 - * openssl-core@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). - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include <stdio.h> -#include <openssl/lhash.h> -#include <openssl/rand.h> -#ifndef OPENSSL_NO_ENGINE -# include <openssl/engine.h> -#endif -#include "ssl_locl.h" - -static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); -static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s); -static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); - -SSL_SESSION *SSL_get_session(const SSL *ssl) -/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */ -{ - return (ssl->session); -} - -SSL_SESSION *SSL_get1_session(SSL *ssl) -/* variant of SSL_get_session: caller really gets something */ -{ - SSL_SESSION *sess; - /* - * Need to lock this all up rather than just use CRYPTO_add so that - * somebody doesn't free ssl->session between when we check it's non-null - * and when we up the reference count. - */ - CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION); - sess = ssl->session; - if (sess) - sess->references++; - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION); - return (sess); -} - -int SSL_SESSION_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp, - new_func, dup_func, free_func); -} - -int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); -} - -void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx) -{ - return (CRYPTO_get_ex_data(&s->ex_data, idx)); -} - -SSL_SESSION *SSL_SESSION_new(void) -{ - SSL_SESSION *ss; - - ss = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION)); - if (ss == NULL) { - SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE); - return (0); - } - memset(ss, 0, sizeof(SSL_SESSION)); - - ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */ - ss->references = 1; - ss->timeout = 60 * 5 + 4; /* 5 minute timeout by default */ - ss->time = (unsigned long)time(NULL); - ss->prev = NULL; - ss->next = NULL; - ss->compress_meth = 0; -#ifndef OPENSSL_NO_TLSEXT - ss->tlsext_hostname = NULL; -# ifndef OPENSSL_NO_EC - ss->tlsext_ecpointformatlist_length = 0; - ss->tlsext_ecpointformatlist = NULL; - ss->tlsext_ellipticcurvelist_length = 0; - ss->tlsext_ellipticcurvelist = NULL; -# endif -#endif - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); -#ifndef OPENSSL_NO_PSK - ss->psk_identity_hint = NULL; - ss->psk_identity = NULL; -#endif -#ifndef OPENSSL_NO_SRP - ss->srp_username = NULL; -#endif - return (ss); -} - -/* - * Create a new SSL_SESSION and duplicate the contents of |src| into it. If - * ticket == 0 then no ticket information is duplicated, otherwise it is. - */ -SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) -{ - SSL_SESSION *dest; - - dest = OPENSSL_malloc(sizeof(*src)); - if (dest == NULL) { - goto err; - } - memcpy(dest, src, sizeof(*dest)); - - /* - * Set the various pointers to NULL so that we can call SSL_SESSION_free in - * the case of an error whilst halfway through constructing dest - */ -#ifndef OPENSSL_NO_PSK - dest->psk_identity_hint = NULL; - dest->psk_identity = NULL; -#endif - dest->ciphers = NULL; -#ifndef OPENSSL_NO_TLSEXT - dest->tlsext_hostname = NULL; -# ifndef OPENSSL_NO_EC - dest->tlsext_ecpointformatlist = NULL; - dest->tlsext_ellipticcurvelist = NULL; -# endif - dest->tlsext_tick = NULL; -#endif -#ifndef OPENSSL_NO_SRP - dest->srp_username = NULL; -#endif - memset(&dest->ex_data, 0, sizeof(dest->ex_data)); - - /* We deliberately don't copy the prev and next pointers */ - dest->prev = NULL; - dest->next = NULL; - - dest->references = 1; - - if (src->sess_cert != NULL) - CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT); - - if (src->peer != NULL) - CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509); - -#ifndef OPENSSL_NO_PSK - if (src->psk_identity_hint) { - dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint); - if (dest->psk_identity_hint == NULL) { - goto err; - } - } - if (src->psk_identity) { - dest->psk_identity = BUF_strdup(src->psk_identity); - if (dest->psk_identity == NULL) { - goto err; - } - } -#endif - - if(src->ciphers != NULL) { - dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers); - if (dest->ciphers == NULL) - goto err; - } - - if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, - &dest->ex_data, &src->ex_data)) { - goto err; - } - -#ifndef OPENSSL_NO_TLSEXT - if (src->tlsext_hostname) { - dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname); - if (dest->tlsext_hostname == NULL) { - goto err; - } - } -# ifndef OPENSSL_NO_EC - if (src->tlsext_ecpointformatlist) { - dest->tlsext_ecpointformatlist = - BUF_memdup(src->tlsext_ecpointformatlist, - src->tlsext_ecpointformatlist_length); - if (dest->tlsext_ecpointformatlist == NULL) - goto err; - } - if (src->tlsext_ellipticcurvelist) { - dest->tlsext_ellipticcurvelist = - BUF_memdup(src->tlsext_ellipticcurvelist, - src->tlsext_ellipticcurvelist_length); - if (dest->tlsext_ellipticcurvelist == NULL) - goto err; - } -# endif - - if (ticket != 0) { - dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen); - if(dest->tlsext_tick == NULL) - goto err; - } else { - dest->tlsext_tick_lifetime_hint = 0; - dest->tlsext_ticklen = 0; - } -#endif - -#ifndef OPENSSL_NO_SRP - if (src->srp_username) { - dest->srp_username = BUF_strdup(src->srp_username); - if (dest->srp_username == NULL) { - goto err; - } - } -#endif - - return dest; -err: - SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE); - SSL_SESSION_free(dest); - return NULL; -} - -const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, - unsigned int *len) -{ - if (len) - *len = s->session_id_length; - return s->session_id; -} - -unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s) -{ - return s->compress_meth; -} - -/* - * Even with SSLv2, we have 16 bytes (128 bits) of session ID space. - * SSLv3/TLSv1 has 32 bytes (256 bits). As such, filling the ID with random - * gunk repeatedly until we have no conflict is going to complete in one - * iteration pretty much "most" of the time (btw: understatement). So, if it - * takes us 10 iterations and we still can't avoid a conflict - well that's a - * reasonable point to call it quits. Either the RAND code is broken or - * someone is trying to open roughly very close to 2^128 (or 2^256) SSL - * sessions to our server. How you might store that many sessions is perhaps - * a more interesting question ... - */ - -#define MAX_SESS_ID_ATTEMPTS 10 -static int def_generate_session_id(const SSL *ssl, unsigned char *id, - unsigned int *id_len) -{ - unsigned int retry = 0; - do - if (RAND_bytes(id, *id_len) <= 0) - return 0; - while (SSL_has_matching_session_id(ssl, id, *id_len) && - (++retry < MAX_SESS_ID_ATTEMPTS)) ; - if (retry < MAX_SESS_ID_ATTEMPTS) - return 1; - /* else - woops a session_id match */ - /* - * XXX We should also check the external cache -- but the probability of - * a collision is negligible, and we could not prevent the concurrent - * creation of sessions with identical IDs since we currently don't have - * means to atomically check whether a session ID already exists and make - * a reservation for it if it does not (this problem applies to the - * internal cache as well). - */ - return 0; -} - -int ssl_get_new_session(SSL *s, int session) -{ - /* This gets used by clients and servers. */ - - unsigned int tmp; - SSL_SESSION *ss = NULL; - GEN_SESSION_CB cb = def_generate_session_id; - - if ((ss = SSL_SESSION_new()) == NULL) - return (0); - - /* If the context has a default timeout, use it */ - if (s->session_ctx->session_timeout == 0) - ss->timeout = SSL_get_default_timeout(s); - else - ss->timeout = s->session_ctx->session_timeout; - - if (s->session != NULL) { - SSL_SESSION_free(s->session); - s->session = NULL; - } - - if (session) { - if (s->version == SSL2_VERSION) { - ss->ssl_version = SSL2_VERSION; - ss->session_id_length = SSL2_SSL_SESSION_ID_LENGTH; - } else if (s->version == SSL3_VERSION) { - ss->ssl_version = SSL3_VERSION; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else if (s->version == TLS1_VERSION) { - ss->ssl_version = TLS1_VERSION; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else if (s->version == TLS1_1_VERSION) { - ss->ssl_version = TLS1_1_VERSION; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else if (s->version == TLS1_2_VERSION) { - ss->ssl_version = TLS1_2_VERSION; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else if (s->version == DTLS1_BAD_VER) { - ss->ssl_version = DTLS1_BAD_VER; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else if (s->version == DTLS1_VERSION) { - ss->ssl_version = DTLS1_VERSION; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else if (s->version == DTLS1_2_VERSION) { - ss->ssl_version = DTLS1_2_VERSION; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else { - SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION); - SSL_SESSION_free(ss); - return (0); - } -#ifndef OPENSSL_NO_TLSEXT - /*- - * If RFC5077 ticket, use empty session ID (as server). - * Note that: - * (a) ssl_get_prev_session() does lookahead into the - * ClientHello extensions to find the session ticket. - * When ssl_get_prev_session() fails, s3_srvr.c calls - * ssl_get_new_session() in ssl3_get_client_hello(). - * At that point, it has not yet parsed the extensions, - * however, because of the lookahead, it already knows - * whether a ticket is expected or not. - * - * (b) s3_clnt.c calls ssl_get_new_session() before parsing - * ServerHello extensions, and before recording the session - * ID received from the server, so this block is a noop. - */ - if (s->tlsext_ticket_expected) { - ss->session_id_length = 0; - goto sess_id_done; - } -#endif - /* Choose which callback will set the session ID */ - CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); - if (s->generate_session_id) - cb = s->generate_session_id; - else if (s->session_ctx->generate_session_id) - cb = s->session_ctx->generate_session_id; - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); - /* Choose a session ID */ - tmp = ss->session_id_length; - if (!cb(s, ss->session_id, &tmp)) { - /* The callback failed */ - SSLerr(SSL_F_SSL_GET_NEW_SESSION, - SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); - SSL_SESSION_free(ss); - return (0); - } - /* - * Don't allow the callback to set the session length to zero. nor - * set it higher than it was. - */ - if (!tmp || (tmp > ss->session_id_length)) { - /* The callback set an illegal length */ - SSLerr(SSL_F_SSL_GET_NEW_SESSION, - SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH); - SSL_SESSION_free(ss); - return (0); - } - /* If the session length was shrunk and we're SSLv2, pad it */ - if ((tmp < ss->session_id_length) && (s->version == SSL2_VERSION)) - memset(ss->session_id + tmp, 0, ss->session_id_length - tmp); - else - ss->session_id_length = tmp; - /* Finally, check for a conflict */ - if (SSL_has_matching_session_id(s, ss->session_id, - ss->session_id_length)) { - SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_SSL_SESSION_ID_CONFLICT); - SSL_SESSION_free(ss); - return (0); - } -#ifndef OPENSSL_NO_TLSEXT - sess_id_done: - if (s->tlsext_hostname) { - ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname); - if (ss->tlsext_hostname == NULL) { - SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); - SSL_SESSION_free(ss); - return 0; - } - } -#endif - } else { - ss->session_id_length = 0; - } - - if (s->sid_ctx_length > sizeof ss->sid_ctx) { - SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); - SSL_SESSION_free(ss); - return 0; - } - memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length); - ss->sid_ctx_length = s->sid_ctx_length; - s->session = ss; - ss->ssl_version = s->version; - ss->verify_result = X509_V_OK; - - return (1); -} - -/*- - * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this - * connection. It is only called by servers. - * - * session_id: points at the session ID in the ClientHello. This code will - * read past the end of this in order to parse out the session ticket - * extension, if any. - * len: the length of the session ID. - * limit: a pointer to the first byte after the ClientHello. - * - * Returns: - * -1: error - * 0: a session may have been found. - * - * Side effects: - * - If a session is found then s->session is pointed at it (after freeing an - * existing session if need be) and s->verify_result is set from the session. - * - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1 - * if the server should issue a new session ticket (to 0 otherwise). - */ -int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, - const unsigned char *limit) -{ - /* This is used only by servers. */ - - SSL_SESSION *ret = NULL; - int fatal = 0; - int try_session_cache = 1; -#ifndef OPENSSL_NO_TLSEXT - int r; -#endif - - if (limit - session_id < len) { - fatal = 1; - goto err; - } - - if (len == 0) - try_session_cache = 0; - -#ifndef OPENSSL_NO_TLSEXT - /* sets s->tlsext_ticket_expected */ - r = tls1_process_ticket(s, session_id, len, limit, &ret); - switch (r) { - case -1: /* Error during processing */ - fatal = 1; - goto err; - case 0: /* No ticket found */ - case 1: /* Zero length ticket found */ - break; /* Ok to carry on processing session id. */ - case 2: /* Ticket found but not decrypted. */ - case 3: /* Ticket decrypted, *ret has been set. */ - try_session_cache = 0; - break; - default: - abort(); - } -#endif - - if (try_session_cache && - ret == NULL && - !(s->session_ctx->session_cache_mode & - SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { - SSL_SESSION data; - data.ssl_version = s->version; - data.session_id_length = len; - if (len == 0) - return 0; - memcpy(data.session_id, session_id, len); - CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); - ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); - if (ret != NULL) { - /* don't allow other threads to steal it: */ - CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); - } - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); - if (ret == NULL) - s->session_ctx->stats.sess_miss++; - } - - if (try_session_cache && - ret == NULL && s->session_ctx->get_session_cb != NULL) { - int copy = 1; - - if ((ret = s->session_ctx->get_session_cb(s, session_id, len, ©))) { - s->session_ctx->stats.sess_cb_hit++; - - /* - * Increment reference count now if the session callback asks us - * to do so (note that if the session structures returned by the - * callback are shared between threads, it must handle the - * reference count itself [i.e. copy == 0], or things won't be - * thread-safe). - */ - if (copy) - CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); - - /* - * Add the externally cached session to the internal cache as - * well if and only if we are supposed to. - */ - if (! - (s->session_ctx->session_cache_mode & - SSL_SESS_CACHE_NO_INTERNAL_STORE)) - /* - * The following should not return 1, otherwise, things are - * very strange - */ - SSL_CTX_add_session(s->session_ctx, ret); - } - } - - if (ret == NULL) - goto err; - - /* Now ret is non-NULL and we own one of its reference counts. */ - - if (ret->sid_ctx_length != s->sid_ctx_length - || memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) { - /* - * We have the session requested by the client, but we don't want to - * use it in this context. - */ - goto err; /* treat like cache miss */ - } - - if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) { - /* - * We can't be sure if this session is being used out of context, - * which is especially important for SSL_VERIFY_PEER. The application - * should have used SSL[_CTX]_set_session_id_context. For this error - * case, we generate an error instead of treating the event like a - * cache miss (otherwise it would be easy for applications to - * effectively disable the session cache by accident without anyone - * noticing). - */ - - SSLerr(SSL_F_SSL_GET_PREV_SESSION, - SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); - fatal = 1; - goto err; - } - - if (ret->cipher == NULL) { - unsigned char buf[5], *p; - unsigned long l; - - p = buf; - l = ret->cipher_id; - l2n(l, p); - if ((ret->ssl_version >> 8) >= SSL3_VERSION_MAJOR) - ret->cipher = ssl_get_cipher_by_char(s, &(buf[2])); - else - ret->cipher = ssl_get_cipher_by_char(s, &(buf[1])); - if (ret->cipher == NULL) - goto err; - } - - if (ret->timeout < (long)(time(NULL) - ret->time)) { /* timeout */ - s->session_ctx->stats.sess_timeout++; - if (try_session_cache) { - /* session was from the cache, so remove it */ - SSL_CTX_remove_session(s->session_ctx, ret); - } - goto err; - } - - s->session_ctx->stats.sess_hit++; - - if (s->session != NULL) - SSL_SESSION_free(s->session); - s->session = ret; - s->verify_result = s->session->verify_result; - return 1; - - err: - if (ret != NULL) { - SSL_SESSION_free(ret); -#ifndef OPENSSL_NO_TLSEXT - if (!try_session_cache) { - /* - * The session was from a ticket, so we should issue a ticket for - * the new session - */ - s->tlsext_ticket_expected = 1; - } -#endif - } - if (fatal) - return -1; - else - return 0; -} - -int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) -{ - int ret = 0; - SSL_SESSION *s; - - /* - * add just 1 reference count for the SSL_CTX's session cache even though - * it has two ways of access: each session is in a doubly linked list and - * an lhash - */ - CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION); - /* - * if session c is in already in cache, we take back the increment later - */ - - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - s = lh_SSL_SESSION_insert(ctx->sessions, c); - - /* - * s != NULL iff we already had a session with the given PID. In this - * case, s == c should hold (then we did not really modify - * ctx->sessions), or we're in trouble. - */ - if (s != NULL && s != c) { - /* We *are* in trouble ... */ - SSL_SESSION_list_remove(ctx, s); - SSL_SESSION_free(s); - /* - * ... so pretend the other session did not exist in cache (we cannot - * handle two SSL_SESSION structures with identical session ID in the - * same cache, which could happen e.g. when two threads concurrently - * obtain the same session from an external cache) - */ - s = NULL; - } else if (s == NULL && - lh_SSL_SESSION_retrieve(ctx->sessions, c) == NULL) { - /* s == NULL can also mean OOM error in lh_SSL_SESSION_insert ... */ - - /* - * ... so take back the extra reference and also don't add - * the session to the SSL_SESSION_list at this time - */ - s = c; - } - - /* Put at the head of the queue unless it is already in the cache */ - if (s == NULL) - SSL_SESSION_list_add(ctx, c); - - if (s != NULL) { - /* - * existing cache entry -- decrement previously incremented reference - * count because it already takes into account the cache - */ - - SSL_SESSION_free(s); /* s == c */ - ret = 0; - } else { - /* - * new cache entry -- remove old ones if cache has become too large - */ - - ret = 1; - - if (SSL_CTX_sess_get_cache_size(ctx) > 0) { - while (SSL_CTX_sess_number(ctx) > - SSL_CTX_sess_get_cache_size(ctx)) { - if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) - break; - else - ctx->stats.sess_cache_full++; - } - } - } - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - return (ret); -} - -int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) -{ - return remove_session_lock(ctx, c, 1); -} - -static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) -{ - SSL_SESSION *r; - int ret = 0; - - if ((c != NULL) && (c->session_id_length != 0)) { - if (lck) - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) { - ret = 1; - r = lh_SSL_SESSION_delete(ctx->sessions, c); - SSL_SESSION_list_remove(ctx, c); - } - - if (lck) - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - - if (ret) { - r->not_resumable = 1; - if (ctx->remove_session_cb != NULL) - ctx->remove_session_cb(ctx, r); - SSL_SESSION_free(r); - } - } else - ret = 0; - return (ret); -} - -void SSL_SESSION_free(SSL_SESSION *ss) -{ - int i; - - if (ss == NULL) - return; - - i = CRYPTO_add(&ss->references, -1, CRYPTO_LOCK_SSL_SESSION); -#ifdef REF_PRINT - REF_PRINT("SSL_SESSION", ss); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "SSL_SESSION_free, bad reference count\n"); - abort(); /* ok */ - } -#endif - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); - - OPENSSL_cleanse(ss->key_arg, sizeof ss->key_arg); - OPENSSL_cleanse(ss->master_key, sizeof ss->master_key); - OPENSSL_cleanse(ss->session_id, sizeof ss->session_id); - if (ss->sess_cert != NULL) - ssl_sess_cert_free(ss->sess_cert); - if (ss->peer != NULL) - X509_free(ss->peer); - if (ss->ciphers != NULL) - sk_SSL_CIPHER_free(ss->ciphers); -#ifndef OPENSSL_NO_TLSEXT - if (ss->tlsext_hostname != NULL) - OPENSSL_free(ss->tlsext_hostname); - if (ss->tlsext_tick != NULL) - OPENSSL_free(ss->tlsext_tick); -# ifndef OPENSSL_NO_EC - ss->tlsext_ecpointformatlist_length = 0; - if (ss->tlsext_ecpointformatlist != NULL) - OPENSSL_free(ss->tlsext_ecpointformatlist); - ss->tlsext_ellipticcurvelist_length = 0; - if (ss->tlsext_ellipticcurvelist != NULL) - OPENSSL_free(ss->tlsext_ellipticcurvelist); -# endif /* OPENSSL_NO_EC */ -#endif -#ifndef OPENSSL_NO_PSK - if (ss->psk_identity_hint != NULL) - OPENSSL_free(ss->psk_identity_hint); - if (ss->psk_identity != NULL) - OPENSSL_free(ss->psk_identity); -#endif -#ifndef OPENSSL_NO_SRP - if (ss->srp_username != NULL) - OPENSSL_free(ss->srp_username); -#endif - OPENSSL_cleanse(ss, sizeof(*ss)); - OPENSSL_free(ss); -} - -int SSL_set_session(SSL *s, SSL_SESSION *session) -{ - int ret = 0; - const SSL_METHOD *meth; - - if (session != NULL) { - meth = s->ctx->method->get_ssl_method(session->ssl_version); - if (meth == NULL) - meth = s->method->get_ssl_method(session->ssl_version); - if (meth == NULL) { - SSLerr(SSL_F_SSL_SET_SESSION, SSL_R_UNABLE_TO_FIND_SSL_METHOD); - return (0); - } - - if (meth != s->method) { - if (!SSL_set_ssl_method(s, meth)) - return (0); - } -#ifndef OPENSSL_NO_KRB5 - if (s->kssl_ctx && !s->kssl_ctx->client_princ && - session->krb5_client_princ_len > 0) { - s->kssl_ctx->client_princ = - (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1); - if (s->kssl_ctx->client_princ == NULL) { - SSLerr(SSL_F_SSL_SET_SESSION, ERR_R_MALLOC_FAILURE); - return 0; - } - memcpy(s->kssl_ctx->client_princ, session->krb5_client_princ, - session->krb5_client_princ_len); - s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0'; - } -#endif /* OPENSSL_NO_KRB5 */ - - /* CRYPTO_w_lock(CRYPTO_LOCK_SSL); */ - CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION); - if (s->session != NULL) - SSL_SESSION_free(s->session); - s->session = session; - s->verify_result = s->session->verify_result; - /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL); */ - ret = 1; - } else { - if (s->session != NULL) { - SSL_SESSION_free(s->session); - s->session = NULL; - } - - meth = s->ctx->method; - if (meth != s->method) { - if (!SSL_set_ssl_method(s, meth)) - return (0); - } - ret = 1; - } - return (ret); -} - -long SSL_SESSION_set_timeout(SSL_SESSION *s, long t) -{ - if (s == NULL) - return (0); - s->timeout = t; - return (1); -} - -long SSL_SESSION_get_timeout(const SSL_SESSION *s) -{ - if (s == NULL) - return (0); - return (s->timeout); -} - -long SSL_SESSION_get_time(const SSL_SESSION *s) -{ - if (s == NULL) - return (0); - return (s->time); -} - -long SSL_SESSION_set_time(SSL_SESSION *s, long t) -{ - if (s == NULL) - return (0); - s->time = t; - return (t); -} - -X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) -{ - return s->peer; -} - -int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, - unsigned int sid_ctx_len) -{ - if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { - SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT, - SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); - return 0; - } - s->sid_ctx_length = sid_ctx_len; - if (s->sid_ctx != sid_ctx) - memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); - - return 1; -} - -long SSL_CTX_set_timeout(SSL_CTX *s, long t) -{ - long l; - if (s == NULL) - return (0); - l = s->session_timeout; - s->session_timeout = t; - return (l); -} - -long SSL_CTX_get_timeout(const SSL_CTX *s) -{ - if (s == NULL) - return (0); - return (s->session_timeout); -} - -#ifndef OPENSSL_NO_TLSEXT -int SSL_set_session_secret_cb(SSL *s, - int (*tls_session_secret_cb) (SSL *s, - void *secret, - int *secret_len, - STACK_OF(SSL_CIPHER) - *peer_ciphers, - SSL_CIPHER - **cipher, - void *arg), - void *arg) -{ - if (s == NULL) - return (0); - s->tls_session_secret_cb = tls_session_secret_cb; - s->tls_session_secret_cb_arg = arg; - return (1); -} - -int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, - void *arg) -{ - if (s == NULL) - return (0); - s->tls_session_ticket_ext_cb = cb; - s->tls_session_ticket_ext_cb_arg = arg; - return (1); -} - -int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) -{ - if (s->version >= TLS1_VERSION) { - if (s->tlsext_session_ticket) { - OPENSSL_free(s->tlsext_session_ticket); - s->tlsext_session_ticket = NULL; - } - - s->tlsext_session_ticket = - OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); - if (!s->tlsext_session_ticket) { - SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE); - return 0; - } - - if (ext_data) { - s->tlsext_session_ticket->length = ext_len; - s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1; - memcpy(s->tlsext_session_ticket->data, ext_data, ext_len); - } else { - s->tlsext_session_ticket->length = 0; - s->tlsext_session_ticket->data = NULL; - } - - return 1; - } - - return 0; -} -#endif /* OPENSSL_NO_TLSEXT */ - -typedef struct timeout_param_st { - SSL_CTX *ctx; - long time; - LHASH_OF(SSL_SESSION) *cache; -} TIMEOUT_PARAM; - -static void timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p) -{ - if ((p->time == 0) || (p->time > (s->time + s->timeout))) { /* timeout */ - /* - * The reason we don't call SSL_CTX_remove_session() is to save on - * locking overhead - */ - (void)lh_SSL_SESSION_delete(p->cache, s); - SSL_SESSION_list_remove(p->ctx, s); - s->not_resumable = 1; - if (p->ctx->remove_session_cb != NULL) - p->ctx->remove_session_cb(p->ctx, s); - SSL_SESSION_free(s); - } -} - -static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM) - -void SSL_CTX_flush_sessions(SSL_CTX *s, long t) -{ - unsigned long i; - TIMEOUT_PARAM tp; - - tp.ctx = s; - tp.cache = s->sessions; - if (tp.cache == NULL) - return; - tp.time = t; - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - i = CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; - CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = 0; - lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), - TIMEOUT_PARAM, &tp); - CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = i; - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); -} - -int ssl_clear_bad_session(SSL *s) -{ - if ((s->session != NULL) && - !(s->shutdown & SSL_SENT_SHUTDOWN) && - !(SSL_in_init(s) || SSL_in_before(s))) { - SSL_CTX_remove_session(s->session_ctx, s->session); - return (1); - } else - return (0); -} - -/* locked by SSL_CTX in the calling function */ -static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) -{ - if ((s->next == NULL) || (s->prev == NULL)) - return; - - if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) { - /* last element in list */ - if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { - /* only one element in list */ - ctx->session_cache_head = NULL; - ctx->session_cache_tail = NULL; - } else { - ctx->session_cache_tail = s->prev; - s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail); - } - } else { - if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { - /* first element in list */ - ctx->session_cache_head = s->next; - s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head); - } else { - /* middle of list */ - s->next->prev = s->prev; - s->prev->next = s->next; - } - } - s->prev = s->next = NULL; -} - -static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) -{ - if ((s->next != NULL) && (s->prev != NULL)) - SSL_SESSION_list_remove(ctx, s); - - if (ctx->session_cache_head == NULL) { - ctx->session_cache_head = s; - ctx->session_cache_tail = s; - s->prev = (SSL_SESSION *)&(ctx->session_cache_head); - s->next = (SSL_SESSION *)&(ctx->session_cache_tail); - } else { - s->next = ctx->session_cache_head; - s->next->prev = s; - s->prev = (SSL_SESSION *)&(ctx->session_cache_head); - ctx->session_cache_head = s; - } -} - -void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, - int (*cb) (struct ssl_st *ssl, - SSL_SESSION *sess)) -{ - ctx->new_session_cb = cb; -} - -int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (SSL *ssl, SSL_SESSION *sess) { - return ctx->new_session_cb; -} - -void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, - void (*cb) (SSL_CTX *ctx, SSL_SESSION *sess)) -{ - ctx->remove_session_cb = cb; -} - -void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (SSL_CTX *ctx, - SSL_SESSION *sess) { - return ctx->remove_session_cb; -} - -void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, - SSL_SESSION *(*cb) (struct ssl_st *ssl, - unsigned char *data, int len, - int *copy)) -{ - ctx->get_session_cb = cb; -} - -SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (SSL *ssl, - unsigned char *data, - int len, int *copy) { - return ctx->get_session_cb; -} - -void SSL_CTX_set_info_callback(SSL_CTX *ctx, - void (*cb) (const SSL *ssl, int type, int val)) -{ - ctx->info_callback = cb; -} - -void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, - int val) { - return ctx->info_callback; -} - -void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, X509 **x509, - EVP_PKEY **pkey)) -{ - ctx->client_cert_cb = cb; -} - -int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, - EVP_PKEY **pkey) { - return ctx->client_cert_cb; -} - -#ifndef OPENSSL_NO_ENGINE -int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e) -{ - if (!ENGINE_init(e)) { - SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB); - return 0; - } - if (!ENGINE_get_ssl_client_cert_function(e)) { - SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, - SSL_R_NO_CLIENT_CERT_METHOD); - ENGINE_finish(e); - return 0; - } - ctx->client_cert_engine = e; - return 1; -} -#endif - -void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, - unsigned char *cookie, - unsigned int *cookie_len)) -{ - ctx->app_gen_cookie_cb = cb; -} - -void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, unsigned char *cookie, - unsigned int cookie_len)) -{ - ctx->app_verify_cookie_cb = cb; -} - -IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, - SSL_SESSION) diff --git a/thirdparty/openssl/ssl/ssl_stat.c b/thirdparty/openssl/ssl/ssl_stat.c deleted file mode 100644 index 1b9069f978..0000000000 --- a/thirdparty/openssl/ssl/ssl_stat.c +++ /dev/null @@ -1,1078 +0,0 @@ -/* ssl/ssl_stat.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include <stdio.h> -#include "ssl_locl.h" - -const char *SSL_state_string_long(const SSL *s) -{ - const char *str; - - switch (s->state) { - case SSL_ST_BEFORE: - str = "before SSL initialization"; - break; - case SSL_ST_ACCEPT: - str = "before accept initialization"; - break; - case SSL_ST_CONNECT: - str = "before connect initialization"; - break; - case SSL_ST_OK: - str = "SSL negotiation finished successfully"; - break; - case SSL_ST_RENEGOTIATE: - str = "SSL renegotiate ciphers"; - break; - case SSL_ST_BEFORE | SSL_ST_CONNECT: - str = "before/connect initialization"; - break; - case SSL_ST_OK | SSL_ST_CONNECT: - str = "ok/connect SSL initialization"; - break; - case SSL_ST_BEFORE | SSL_ST_ACCEPT: - str = "before/accept initialization"; - break; - case SSL_ST_OK | SSL_ST_ACCEPT: - str = "ok/accept SSL initialization"; - break; - case SSL_ST_ERR: - str = "error"; - break; -#ifndef OPENSSL_NO_SSL2 - case SSL2_ST_CLIENT_START_ENCRYPTION: - str = "SSLv2 client start encryption"; - break; - case SSL2_ST_SERVER_START_ENCRYPTION: - str = "SSLv2 server start encryption"; - break; - case SSL2_ST_SEND_CLIENT_HELLO_A: - str = "SSLv2 write client hello A"; - break; - case SSL2_ST_SEND_CLIENT_HELLO_B: - str = "SSLv2 write client hello B"; - break; - case SSL2_ST_GET_SERVER_HELLO_A: - str = "SSLv2 read server hello A"; - break; - case SSL2_ST_GET_SERVER_HELLO_B: - str = "SSLv2 read server hello B"; - break; - case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: - str = "SSLv2 write client master key A"; - break; - case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: - str = "SSLv2 write client master key B"; - break; - case SSL2_ST_SEND_CLIENT_FINISHED_A: - str = "SSLv2 write client finished A"; - break; - case SSL2_ST_SEND_CLIENT_FINISHED_B: - str = "SSLv2 write client finished B"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: - str = "SSLv2 write client certificate A"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: - str = "SSLv2 write client certificate B"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: - str = "SSLv2 write client certificate C"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: - str = "SSLv2 write client certificate D"; - break; - case SSL2_ST_GET_SERVER_VERIFY_A: - str = "SSLv2 read server verify A"; - break; - case SSL2_ST_GET_SERVER_VERIFY_B: - str = "SSLv2 read server verify B"; - break; - case SSL2_ST_GET_SERVER_FINISHED_A: - str = "SSLv2 read server finished A"; - break; - case SSL2_ST_GET_SERVER_FINISHED_B: - str = "SSLv2 read server finished B"; - break; - case SSL2_ST_GET_CLIENT_HELLO_A: - str = "SSLv2 read client hello A"; - break; - case SSL2_ST_GET_CLIENT_HELLO_B: - str = "SSLv2 read client hello B"; - break; - case SSL2_ST_GET_CLIENT_HELLO_C: - str = "SSLv2 read client hello C"; - break; - case SSL2_ST_SEND_SERVER_HELLO_A: - str = "SSLv2 write server hello A"; - break; - case SSL2_ST_SEND_SERVER_HELLO_B: - str = "SSLv2 write server hello B"; - break; - case SSL2_ST_GET_CLIENT_MASTER_KEY_A: - str = "SSLv2 read client master key A"; - break; - case SSL2_ST_GET_CLIENT_MASTER_KEY_B: - str = "SSLv2 read client master key B"; - break; - case SSL2_ST_SEND_SERVER_VERIFY_A: - str = "SSLv2 write server verify A"; - break; - case SSL2_ST_SEND_SERVER_VERIFY_B: - str = "SSLv2 write server verify B"; - break; - case SSL2_ST_SEND_SERVER_VERIFY_C: - str = "SSLv2 write server verify C"; - break; - case SSL2_ST_GET_CLIENT_FINISHED_A: - str = "SSLv2 read client finished A"; - break; - case SSL2_ST_GET_CLIENT_FINISHED_B: - str = "SSLv2 read client finished B"; - break; - case SSL2_ST_SEND_SERVER_FINISHED_A: - str = "SSLv2 write server finished A"; - break; - case SSL2_ST_SEND_SERVER_FINISHED_B: - str = "SSLv2 write server finished B"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: - str = "SSLv2 write request certificate A"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: - str = "SSLv2 write request certificate B"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: - str = "SSLv2 write request certificate C"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: - str = "SSLv2 write request certificate D"; - break; - case SSL2_ST_X509_GET_SERVER_CERTIFICATE: - str = "SSLv2 X509 read server certificate"; - break; - case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: - str = "SSLv2 X509 read client certificate"; - break; -#endif - -#ifndef OPENSSL_NO_SSL3 -/* SSLv3 additions */ - case SSL3_ST_CW_CLNT_HELLO_A: - str = "SSLv3 write client hello A"; - break; - case SSL3_ST_CW_CLNT_HELLO_B: - str = "SSLv3 write client hello B"; - break; - case SSL3_ST_CR_SRVR_HELLO_A: - str = "SSLv3 read server hello A"; - break; - case SSL3_ST_CR_SRVR_HELLO_B: - str = "SSLv3 read server hello B"; - break; - case SSL3_ST_CR_CERT_A: - str = "SSLv3 read server certificate A"; - break; - case SSL3_ST_CR_CERT_B: - str = "SSLv3 read server certificate B"; - break; - case SSL3_ST_CR_KEY_EXCH_A: - str = "SSLv3 read server key exchange A"; - break; - case SSL3_ST_CR_KEY_EXCH_B: - str = "SSLv3 read server key exchange B"; - break; - case SSL3_ST_CR_CERT_REQ_A: - str = "SSLv3 read server certificate request A"; - break; - case SSL3_ST_CR_CERT_REQ_B: - str = "SSLv3 read server certificate request B"; - break; - case SSL3_ST_CR_SESSION_TICKET_A: - str = "SSLv3 read server session ticket A"; - break; - case SSL3_ST_CR_SESSION_TICKET_B: - str = "SSLv3 read server session ticket B"; - break; - case SSL3_ST_CR_SRVR_DONE_A: - str = "SSLv3 read server done A"; - break; - case SSL3_ST_CR_SRVR_DONE_B: - str = "SSLv3 read server done B"; - break; - case SSL3_ST_CW_CERT_A: - str = "SSLv3 write client certificate A"; - break; - case SSL3_ST_CW_CERT_B: - str = "SSLv3 write client certificate B"; - break; - case SSL3_ST_CW_CERT_C: - str = "SSLv3 write client certificate C"; - break; - case SSL3_ST_CW_CERT_D: - str = "SSLv3 write client certificate D"; - break; - case SSL3_ST_CW_KEY_EXCH_A: - str = "SSLv3 write client key exchange A"; - break; - case SSL3_ST_CW_KEY_EXCH_B: - str = "SSLv3 write client key exchange B"; - break; - case SSL3_ST_CW_CERT_VRFY_A: - str = "SSLv3 write certificate verify A"; - break; - case SSL3_ST_CW_CERT_VRFY_B: - str = "SSLv3 write certificate verify B"; - break; - - case SSL3_ST_CW_CHANGE_A: - case SSL3_ST_SW_CHANGE_A: - str = "SSLv3 write change cipher spec A"; - break; - case SSL3_ST_CW_CHANGE_B: - case SSL3_ST_SW_CHANGE_B: - str = "SSLv3 write change cipher spec B"; - break; - case SSL3_ST_CW_FINISHED_A: - case SSL3_ST_SW_FINISHED_A: - str = "SSLv3 write finished A"; - break; - case SSL3_ST_CW_FINISHED_B: - case SSL3_ST_SW_FINISHED_B: - str = "SSLv3 write finished B"; - break; - case SSL3_ST_CR_CHANGE_A: - case SSL3_ST_SR_CHANGE_A: - str = "SSLv3 read change cipher spec A"; - break; - case SSL3_ST_CR_CHANGE_B: - case SSL3_ST_SR_CHANGE_B: - str = "SSLv3 read change cipher spec B"; - break; - case SSL3_ST_CR_FINISHED_A: - case SSL3_ST_SR_FINISHED_A: - str = "SSLv3 read finished A"; - break; - case SSL3_ST_CR_FINISHED_B: - case SSL3_ST_SR_FINISHED_B: - str = "SSLv3 read finished B"; - break; - - case SSL3_ST_CW_FLUSH: - case SSL3_ST_SW_FLUSH: - str = "SSLv3 flush data"; - break; - - case SSL3_ST_SR_CLNT_HELLO_A: - str = "SSLv3 read client hello A"; - break; - case SSL3_ST_SR_CLNT_HELLO_B: - str = "SSLv3 read client hello B"; - break; - case SSL3_ST_SR_CLNT_HELLO_C: - str = "SSLv3 read client hello C"; - break; - case SSL3_ST_SW_HELLO_REQ_A: - str = "SSLv3 write hello request A"; - break; - case SSL3_ST_SW_HELLO_REQ_B: - str = "SSLv3 write hello request B"; - break; - case SSL3_ST_SW_HELLO_REQ_C: - str = "SSLv3 write hello request C"; - break; - case SSL3_ST_SW_SRVR_HELLO_A: - str = "SSLv3 write server hello A"; - break; - case SSL3_ST_SW_SRVR_HELLO_B: - str = "SSLv3 write server hello B"; - break; - case SSL3_ST_SW_CERT_A: - str = "SSLv3 write certificate A"; - break; - case SSL3_ST_SW_CERT_B: - str = "SSLv3 write certificate B"; - break; - case SSL3_ST_SW_KEY_EXCH_A: - str = "SSLv3 write key exchange A"; - break; - case SSL3_ST_SW_KEY_EXCH_B: - str = "SSLv3 write key exchange B"; - break; - case SSL3_ST_SW_CERT_REQ_A: - str = "SSLv3 write certificate request A"; - break; - case SSL3_ST_SW_CERT_REQ_B: - str = "SSLv3 write certificate request B"; - break; - case SSL3_ST_SW_SESSION_TICKET_A: - str = "SSLv3 write session ticket A"; - break; - case SSL3_ST_SW_SESSION_TICKET_B: - str = "SSLv3 write session ticket B"; - break; - case SSL3_ST_SW_SRVR_DONE_A: - str = "SSLv3 write server done A"; - break; - case SSL3_ST_SW_SRVR_DONE_B: - str = "SSLv3 write server done B"; - break; - case SSL3_ST_SR_CERT_A: - str = "SSLv3 read client certificate A"; - break; - case SSL3_ST_SR_CERT_B: - str = "SSLv3 read client certificate B"; - break; - case SSL3_ST_SR_KEY_EXCH_A: - str = "SSLv3 read client key exchange A"; - break; - case SSL3_ST_SR_KEY_EXCH_B: - str = "SSLv3 read client key exchange B"; - break; - case SSL3_ST_SR_CERT_VRFY_A: - str = "SSLv3 read certificate verify A"; - break; - case SSL3_ST_SR_CERT_VRFY_B: - str = "SSLv3 read certificate verify B"; - break; -#endif - -/* SSLv2/v3 compatibility states */ -/* client */ - case SSL23_ST_CW_CLNT_HELLO_A: - str = "SSLv2/v3 write client hello A"; - break; - case SSL23_ST_CW_CLNT_HELLO_B: - str = "SSLv2/v3 write client hello B"; - break; - case SSL23_ST_CR_SRVR_HELLO_A: - str = "SSLv2/v3 read server hello A"; - break; - case SSL23_ST_CR_SRVR_HELLO_B: - str = "SSLv2/v3 read server hello B"; - break; -/* server */ - case SSL23_ST_SR_CLNT_HELLO_A: - str = "SSLv2/v3 read client hello A"; - break; - case SSL23_ST_SR_CLNT_HELLO_B: - str = "SSLv2/v3 read client hello B"; - break; - -/* DTLS */ - case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: - str = "DTLS1 read hello verify request A"; - break; - case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: - str = "DTLS1 read hello verify request B"; - break; - case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: - str = "DTLS1 write hello verify request A"; - break; - case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: - str = "DTLS1 write hello verify request B"; - break; - - default: - str = "unknown state"; - break; - } - return (str); -} - -const char *SSL_rstate_string_long(const SSL *s) -{ - const char *str; - - switch (s->rstate) { - case SSL_ST_READ_HEADER: - str = "read header"; - break; - case SSL_ST_READ_BODY: - str = "read body"; - break; - case SSL_ST_READ_DONE: - str = "read done"; - break; - default: - str = "unknown"; - break; - } - return (str); -} - -const char *SSL_state_string(const SSL *s) -{ - const char *str; - - switch (s->state) { - case SSL_ST_BEFORE: - str = "PINIT "; - break; - case SSL_ST_ACCEPT: - str = "AINIT "; - break; - case SSL_ST_CONNECT: - str = "CINIT "; - break; - case SSL_ST_OK: - str = "SSLOK "; - break; - case SSL_ST_ERR: - str = "SSLERR"; - break; -#ifndef OPENSSL_NO_SSL2 - case SSL2_ST_CLIENT_START_ENCRYPTION: - str = "2CSENC"; - break; - case SSL2_ST_SERVER_START_ENCRYPTION: - str = "2SSENC"; - break; - case SSL2_ST_SEND_CLIENT_HELLO_A: - str = "2SCH_A"; - break; - case SSL2_ST_SEND_CLIENT_HELLO_B: - str = "2SCH_B"; - break; - case SSL2_ST_GET_SERVER_HELLO_A: - str = "2GSH_A"; - break; - case SSL2_ST_GET_SERVER_HELLO_B: - str = "2GSH_B"; - break; - case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: - str = "2SCMKA"; - break; - case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: - str = "2SCMKB"; - break; - case SSL2_ST_SEND_CLIENT_FINISHED_A: - str = "2SCF_A"; - break; - case SSL2_ST_SEND_CLIENT_FINISHED_B: - str = "2SCF_B"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: - str = "2SCC_A"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: - str = "2SCC_B"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: - str = "2SCC_C"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: - str = "2SCC_D"; - break; - case SSL2_ST_GET_SERVER_VERIFY_A: - str = "2GSV_A"; - break; - case SSL2_ST_GET_SERVER_VERIFY_B: - str = "2GSV_B"; - break; - case SSL2_ST_GET_SERVER_FINISHED_A: - str = "2GSF_A"; - break; - case SSL2_ST_GET_SERVER_FINISHED_B: - str = "2GSF_B"; - break; - case SSL2_ST_GET_CLIENT_HELLO_A: - str = "2GCH_A"; - break; - case SSL2_ST_GET_CLIENT_HELLO_B: - str = "2GCH_B"; - break; - case SSL2_ST_GET_CLIENT_HELLO_C: - str = "2GCH_C"; - break; - case SSL2_ST_SEND_SERVER_HELLO_A: - str = "2SSH_A"; - break; - case SSL2_ST_SEND_SERVER_HELLO_B: - str = "2SSH_B"; - break; - case SSL2_ST_GET_CLIENT_MASTER_KEY_A: - str = "2GCMKA"; - break; - case SSL2_ST_GET_CLIENT_MASTER_KEY_B: - str = "2GCMKA"; - break; - case SSL2_ST_SEND_SERVER_VERIFY_A: - str = "2SSV_A"; - break; - case SSL2_ST_SEND_SERVER_VERIFY_B: - str = "2SSV_B"; - break; - case SSL2_ST_SEND_SERVER_VERIFY_C: - str = "2SSV_C"; - break; - case SSL2_ST_GET_CLIENT_FINISHED_A: - str = "2GCF_A"; - break; - case SSL2_ST_GET_CLIENT_FINISHED_B: - str = "2GCF_B"; - break; - case SSL2_ST_SEND_SERVER_FINISHED_A: - str = "2SSF_A"; - break; - case SSL2_ST_SEND_SERVER_FINISHED_B: - str = "2SSF_B"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: - str = "2SRC_A"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: - str = "2SRC_B"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: - str = "2SRC_C"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: - str = "2SRC_D"; - break; - case SSL2_ST_X509_GET_SERVER_CERTIFICATE: - str = "2X9GSC"; - break; - case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: - str = "2X9GCC"; - break; -#endif - -#ifndef OPENSSL_NO_SSL3 -/* SSLv3 additions */ - case SSL3_ST_SW_FLUSH: - case SSL3_ST_CW_FLUSH: - str = "3FLUSH"; - break; - case SSL3_ST_CW_CLNT_HELLO_A: - str = "3WCH_A"; - break; - case SSL3_ST_CW_CLNT_HELLO_B: - str = "3WCH_B"; - break; - case SSL3_ST_CR_SRVR_HELLO_A: - str = "3RSH_A"; - break; - case SSL3_ST_CR_SRVR_HELLO_B: - str = "3RSH_B"; - break; - case SSL3_ST_CR_CERT_A: - str = "3RSC_A"; - break; - case SSL3_ST_CR_CERT_B: - str = "3RSC_B"; - break; - case SSL3_ST_CR_KEY_EXCH_A: - str = "3RSKEA"; - break; - case SSL3_ST_CR_KEY_EXCH_B: - str = "3RSKEB"; - break; - case SSL3_ST_CR_CERT_REQ_A: - str = "3RCR_A"; - break; - case SSL3_ST_CR_CERT_REQ_B: - str = "3RCR_B"; - break; - case SSL3_ST_CR_SRVR_DONE_A: - str = "3RSD_A"; - break; - case SSL3_ST_CR_SRVR_DONE_B: - str = "3RSD_B"; - break; - case SSL3_ST_CW_CERT_A: - str = "3WCC_A"; - break; - case SSL3_ST_CW_CERT_B: - str = "3WCC_B"; - break; - case SSL3_ST_CW_CERT_C: - str = "3WCC_C"; - break; - case SSL3_ST_CW_CERT_D: - str = "3WCC_D"; - break; - case SSL3_ST_CW_KEY_EXCH_A: - str = "3WCKEA"; - break; - case SSL3_ST_CW_KEY_EXCH_B: - str = "3WCKEB"; - break; - case SSL3_ST_CW_CERT_VRFY_A: - str = "3WCV_A"; - break; - case SSL3_ST_CW_CERT_VRFY_B: - str = "3WCV_B"; - break; - - case SSL3_ST_SW_CHANGE_A: - case SSL3_ST_CW_CHANGE_A: - str = "3WCCSA"; - break; - case SSL3_ST_SW_CHANGE_B: - case SSL3_ST_CW_CHANGE_B: - str = "3WCCSB"; - break; - case SSL3_ST_SW_FINISHED_A: - case SSL3_ST_CW_FINISHED_A: - str = "3WFINA"; - break; - case SSL3_ST_SW_FINISHED_B: - case SSL3_ST_CW_FINISHED_B: - str = "3WFINB"; - break; - case SSL3_ST_SR_CHANGE_A: - case SSL3_ST_CR_CHANGE_A: - str = "3RCCSA"; - break; - case SSL3_ST_SR_CHANGE_B: - case SSL3_ST_CR_CHANGE_B: - str = "3RCCSB"; - break; - case SSL3_ST_SR_FINISHED_A: - case SSL3_ST_CR_FINISHED_A: - str = "3RFINA"; - break; - case SSL3_ST_SR_FINISHED_B: - case SSL3_ST_CR_FINISHED_B: - str = "3RFINB"; - break; - - case SSL3_ST_SW_HELLO_REQ_A: - str = "3WHR_A"; - break; - case SSL3_ST_SW_HELLO_REQ_B: - str = "3WHR_B"; - break; - case SSL3_ST_SW_HELLO_REQ_C: - str = "3WHR_C"; - break; - case SSL3_ST_SR_CLNT_HELLO_A: - str = "3RCH_A"; - break; - case SSL3_ST_SR_CLNT_HELLO_B: - str = "3RCH_B"; - break; - case SSL3_ST_SR_CLNT_HELLO_C: - str = "3RCH_C"; - break; - case SSL3_ST_SW_SRVR_HELLO_A: - str = "3WSH_A"; - break; - case SSL3_ST_SW_SRVR_HELLO_B: - str = "3WSH_B"; - break; - case SSL3_ST_SW_CERT_A: - str = "3WSC_A"; - break; - case SSL3_ST_SW_CERT_B: - str = "3WSC_B"; - break; - case SSL3_ST_SW_KEY_EXCH_A: - str = "3WSKEA"; - break; - case SSL3_ST_SW_KEY_EXCH_B: - str = "3WSKEB"; - break; - case SSL3_ST_SW_CERT_REQ_A: - str = "3WCR_A"; - break; - case SSL3_ST_SW_CERT_REQ_B: - str = "3WCR_B"; - break; - case SSL3_ST_SW_SRVR_DONE_A: - str = "3WSD_A"; - break; - case SSL3_ST_SW_SRVR_DONE_B: - str = "3WSD_B"; - break; - case SSL3_ST_SR_CERT_A: - str = "3RCC_A"; - break; - case SSL3_ST_SR_CERT_B: - str = "3RCC_B"; - break; - case SSL3_ST_SR_KEY_EXCH_A: - str = "3RCKEA"; - break; - case SSL3_ST_SR_KEY_EXCH_B: - str = "3RCKEB"; - break; - case SSL3_ST_SR_CERT_VRFY_A: - str = "3RCV_A"; - break; - case SSL3_ST_SR_CERT_VRFY_B: - str = "3RCV_B"; - break; -#endif - -/* SSLv2/v3 compatibility states */ -/* client */ - case SSL23_ST_CW_CLNT_HELLO_A: - str = "23WCHA"; - break; - case SSL23_ST_CW_CLNT_HELLO_B: - str = "23WCHB"; - break; - case SSL23_ST_CR_SRVR_HELLO_A: - str = "23RSHA"; - break; - case SSL23_ST_CR_SRVR_HELLO_B: - str = "23RSHA"; - break; -/* server */ - case SSL23_ST_SR_CLNT_HELLO_A: - str = "23RCHA"; - break; - case SSL23_ST_SR_CLNT_HELLO_B: - str = "23RCHB"; - break; - -/* DTLS */ - case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: - str = "DRCHVA"; - break; - case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: - str = "DRCHVB"; - break; - case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: - str = "DWCHVA"; - break; - case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: - str = "DWCHVB"; - break; - - default: - str = "UNKWN "; - break; - } - return (str); -} - -const char *SSL_alert_type_string_long(int value) -{ - value >>= 8; - if (value == SSL3_AL_WARNING) - return ("warning"); - else if (value == SSL3_AL_FATAL) - return ("fatal"); - else - return ("unknown"); -} - -const char *SSL_alert_type_string(int value) -{ - value >>= 8; - if (value == SSL3_AL_WARNING) - return ("W"); - else if (value == SSL3_AL_FATAL) - return ("F"); - else - return ("U"); -} - -const char *SSL_alert_desc_string(int value) -{ - const char *str; - - switch (value & 0xff) { - case SSL3_AD_CLOSE_NOTIFY: - str = "CN"; - break; - case SSL3_AD_UNEXPECTED_MESSAGE: - str = "UM"; - break; - case SSL3_AD_BAD_RECORD_MAC: - str = "BM"; - break; - case SSL3_AD_DECOMPRESSION_FAILURE: - str = "DF"; - break; - case SSL3_AD_HANDSHAKE_FAILURE: - str = "HF"; - break; - case SSL3_AD_NO_CERTIFICATE: - str = "NC"; - break; - case SSL3_AD_BAD_CERTIFICATE: - str = "BC"; - break; - case SSL3_AD_UNSUPPORTED_CERTIFICATE: - str = "UC"; - break; - case SSL3_AD_CERTIFICATE_REVOKED: - str = "CR"; - break; - case SSL3_AD_CERTIFICATE_EXPIRED: - str = "CE"; - break; - case SSL3_AD_CERTIFICATE_UNKNOWN: - str = "CU"; - break; - case SSL3_AD_ILLEGAL_PARAMETER: - str = "IP"; - break; - case TLS1_AD_DECRYPTION_FAILED: - str = "DC"; - break; - case TLS1_AD_RECORD_OVERFLOW: - str = "RO"; - break; - case TLS1_AD_UNKNOWN_CA: - str = "CA"; - break; - case TLS1_AD_ACCESS_DENIED: - str = "AD"; - break; - case TLS1_AD_DECODE_ERROR: - str = "DE"; - break; - case TLS1_AD_DECRYPT_ERROR: - str = "CY"; - break; - case TLS1_AD_EXPORT_RESTRICTION: - str = "ER"; - break; - case TLS1_AD_PROTOCOL_VERSION: - str = "PV"; - break; - case TLS1_AD_INSUFFICIENT_SECURITY: - str = "IS"; - break; - case TLS1_AD_INTERNAL_ERROR: - str = "IE"; - break; - case TLS1_AD_USER_CANCELLED: - str = "US"; - break; - case TLS1_AD_NO_RENEGOTIATION: - str = "NR"; - break; - case TLS1_AD_UNSUPPORTED_EXTENSION: - str = "UE"; - break; - case TLS1_AD_CERTIFICATE_UNOBTAINABLE: - str = "CO"; - break; - case TLS1_AD_UNRECOGNIZED_NAME: - str = "UN"; - break; - case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: - str = "BR"; - break; - case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: - str = "BH"; - break; - case TLS1_AD_UNKNOWN_PSK_IDENTITY: - str = "UP"; - break; - default: - str = "UK"; - break; - } - return (str); -} - -const char *SSL_alert_desc_string_long(int value) -{ - const char *str; - - switch (value & 0xff) { - case SSL3_AD_CLOSE_NOTIFY: - str = "close notify"; - break; - case SSL3_AD_UNEXPECTED_MESSAGE: - str = "unexpected_message"; - break; - case SSL3_AD_BAD_RECORD_MAC: - str = "bad record mac"; - break; - case SSL3_AD_DECOMPRESSION_FAILURE: - str = "decompression failure"; - break; - case SSL3_AD_HANDSHAKE_FAILURE: - str = "handshake failure"; - break; - case SSL3_AD_NO_CERTIFICATE: - str = "no certificate"; - break; - case SSL3_AD_BAD_CERTIFICATE: - str = "bad certificate"; - break; - case SSL3_AD_UNSUPPORTED_CERTIFICATE: - str = "unsupported certificate"; - break; - case SSL3_AD_CERTIFICATE_REVOKED: - str = "certificate revoked"; - break; - case SSL3_AD_CERTIFICATE_EXPIRED: - str = "certificate expired"; - break; - case SSL3_AD_CERTIFICATE_UNKNOWN: - str = "certificate unknown"; - break; - case SSL3_AD_ILLEGAL_PARAMETER: - str = "illegal parameter"; - break; - case TLS1_AD_DECRYPTION_FAILED: - str = "decryption failed"; - break; - case TLS1_AD_RECORD_OVERFLOW: - str = "record overflow"; - break; - case TLS1_AD_UNKNOWN_CA: - str = "unknown CA"; - break; - case TLS1_AD_ACCESS_DENIED: - str = "access denied"; - break; - case TLS1_AD_DECODE_ERROR: - str = "decode error"; - break; - case TLS1_AD_DECRYPT_ERROR: - str = "decrypt error"; - break; - case TLS1_AD_EXPORT_RESTRICTION: - str = "export restriction"; - break; - case TLS1_AD_PROTOCOL_VERSION: - str = "protocol version"; - break; - case TLS1_AD_INSUFFICIENT_SECURITY: - str = "insufficient security"; - break; - case TLS1_AD_INTERNAL_ERROR: - str = "internal error"; - break; - case TLS1_AD_USER_CANCELLED: - str = "user canceled"; - break; - case TLS1_AD_NO_RENEGOTIATION: - str = "no renegotiation"; - break; - case TLS1_AD_UNSUPPORTED_EXTENSION: - str = "unsupported extension"; - break; - case TLS1_AD_CERTIFICATE_UNOBTAINABLE: - str = "certificate unobtainable"; - break; - case TLS1_AD_UNRECOGNIZED_NAME: - str = "unrecognized name"; - break; - case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: - str = "bad certificate status response"; - break; - case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: - str = "bad certificate hash value"; - break; - case TLS1_AD_UNKNOWN_PSK_IDENTITY: - str = "unknown PSK identity"; - break; - default: - str = "unknown"; - break; - } - return (str); -} - -const char *SSL_rstate_string(const SSL *s) -{ - const char *str; - - switch (s->rstate) { - case SSL_ST_READ_HEADER: - str = "RH"; - break; - case SSL_ST_READ_BODY: - str = "RB"; - break; - case SSL_ST_READ_DONE: - str = "RD"; - break; - default: - str = "unknown"; - break; - } - return (str); -} diff --git a/thirdparty/openssl/ssl/ssl_task.c b/thirdparty/openssl/ssl/ssl_task.c deleted file mode 100644 index fb770753e2..0000000000 --- a/thirdparty/openssl/ssl/ssl_task.c +++ /dev/null @@ -1,397 +0,0 @@ -/* ssl/ssl_task.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* VMS */ -/*- - * DECnet object for servicing SSL. We accept the inbound and speak a - * simple protocol for multiplexing the 2 data streams (application and - * ssl data) over this logical link. - * - * Logical names: - * SSL_CIPHER Defines a list of cipher specifications the server - * will support in order of preference. - * SSL_SERVER_CERTIFICATE - * Points to PEM (privacy enhanced mail) file that - * contains the server certificate and private password. - * SYS$NET Logical created by netserver.exe as hook for completing - * DECnet logical link. - * - * Each NSP message sent over the DECnet link has the following structure: - * struct rpc_msg { - * char channel; - * char function; - * short length; - * char data[MAX_DATA]; - * } msg; - * - * The channel field designates the virtual data stream this message applies - * to and is one of: - * A - Application data (payload). - * R - Remote client connection that initiated the SSL connection. Encrypted - * data is sent over this connection. - * G - General data, reserved for future use. - * - * The data streams are half-duplex read/write and have following functions: - * G - Get, requests that up to msg.length bytes of data be returned. The - * data is returned in the next 'C' function response that matches the - * requesting channel. - * P - Put, requests that the first msg.length bytes of msg.data be appended - * to the designated stream. - * C - Confirms a get or put. Every get and put will get a confirm response, - * you cannot initiate another function on a channel until the previous - * operation has been confirmed. - * - * The 2 channels may interleave their operations, for example: - * Server msg Client msg - * A, Get, 4092 ----> - * <---- R, get, 4092 - * R, Confirm, {hello} ----> - * <---- R, put, {srv hello} - * R, Confirm, 0 ----> - * . (SSL handshake completed) - * . (read first app data). - * <---- A, confirm, {http data} - * A, Put, {http data} ----> - * <---- A, confirm, 0 - * - * The length field is not permitted to be larger that 4092 bytes. - * - * Author: Dave Jones - * Date: 22-JUL-1996 - */ -#include <stdlib.h> -#include <stdio.h> -#include <iodef.h> /* VMS IO$_ definitions */ -#include <descrip.h> /* VMS string descriptors */ -extern int SYS$QIOW(), SYS$ASSIGN(); -int LIB$INIT_TIMER(), LIB$SHOW_TIMER(); - -#include <string.h> /* from ssltest.c */ -#include <errno.h> - -#include "e_os.h" - -#include <openssl/buffer.h> -#include <openssl/x509.h> -#include <openssl/ssl.h> -#include <openssl/err.h> - -int MS_CALLBACK verify_callback(int ok, X509 *xs, X509 *xi, int depth, - int error); -BIO *bio_err = NULL; -BIO *bio_stdout = NULL; -BIO_METHOD *BIO_s_rtcp(); - -static char *cipher = NULL; -int verbose = 1; -#ifdef FIONBIO -static int s_nbio = 0; -#endif -#define TEST_SERVER_CERT "SSL_SERVER_CERTIFICATE" -/*************************************************************************/ -/* Should have member alignment inhibited */ -struct rpc_msg { - /* 'A'-app data. 'R'-remote client 'G'-global */ - char channel; - /* 'G'-get, 'P'-put, 'C'-confirm, 'X'-close */ - char function; - /* Amount of data returned or max to return */ - unsigned short int length; - /* variable data */ - char data[4092]; -}; -#define RPC_HDR_SIZE (sizeof(struct rpc_msg) - 4092) - -static $DESCRIPTOR(sysnet, "SYS$NET"); -typedef unsigned short io_channel; - -struct io_status { - unsigned short status; - unsigned short count; - unsigned long stsval; -}; -int doit(io_channel chan, SSL_CTX *s_ctx); -/*****************************************************************************/ -/* - * Decnet I/O routines. - */ -static int get(io_channel chan, char *buffer, int maxlen, int *length) -{ - int status; - struct io_status iosb; - status = SYS$QIOW(0, chan, IO$_READVBLK, &iosb, 0, 0, - buffer, maxlen, 0, 0, 0, 0); - if ((status & 1) == 1) - status = iosb.status; - if ((status & 1) == 1) - *length = iosb.count; - return status; -} - -static int put(io_channel chan, char *buffer, int length) -{ - int status; - struct io_status iosb; - status = SYS$QIOW(0, chan, IO$_WRITEVBLK, &iosb, 0, 0, - buffer, length, 0, 0, 0, 0); - if ((status & 1) == 1) - status = iosb.status; - return status; -} - -/***************************************************************************/ -/* - * Handle operations on the 'G' channel. - */ -static int general_request(io_channel chan, struct rpc_msg *msg, int length) -{ - return 48; -} - -/***************************************************************************/ -int main(int argc, char **argv) -{ - int status, length; - io_channel chan; - struct rpc_msg msg; - - char *CApath = NULL, *CAfile = NULL; - int badop = 0; - int ret = 1; - int client_auth = 0; - int server_auth = 0; - SSL_CTX *s_ctx = NULL; - /* - * Confirm logical link with initiating client. - */ - LIB$INIT_TIMER(); - status = SYS$ASSIGN(&sysnet, &chan, 0, 0, 0); - printf("status of assign to SYS$NET: %d\n", status); - /* - * Initialize standard out and error files. - */ - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE); - if (bio_stdout == NULL) - if ((bio_stdout = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_stdout, stdout, BIO_NOCLOSE); - /* - * get the preferred cipher list and other initialization - */ - if (cipher == NULL) - cipher = getenv("SSL_CIPHER"); - printf("cipher list: %s\n", cipher ? cipher : "{undefined}"); - - SSL_load_error_strings(); - OpenSSL_add_all_algorithms(); - - /* - * DRM, this was the original, but there is no such thing as SSLv2() - * s_ctx=SSL_CTX_new(SSLv2()); - */ - s_ctx = SSL_CTX_new(SSLv2_server_method()); - - if (s_ctx == NULL) - goto end; - - SSL_CTX_use_certificate_file(s_ctx, TEST_SERVER_CERT, SSL_FILETYPE_PEM); - SSL_CTX_use_RSAPrivateKey_file(s_ctx, TEST_SERVER_CERT, SSL_FILETYPE_PEM); - printf("Loaded server certificate: '%s'\n", TEST_SERVER_CERT); - - /* - * Take commands from client until bad status. - */ - LIB$SHOW_TIMER(); - status = doit(chan, s_ctx); - LIB$SHOW_TIMER(); - /* - * do final cleanup and exit. - */ - end: - if (s_ctx != NULL) - SSL_CTX_free(s_ctx); - LIB$SHOW_TIMER(); - return 1; -} - -int doit(io_channel chan, SSL_CTX *s_ctx) -{ - int status, length, link_state; - struct rpc_msg msg; - - SSL *s_ssl = NULL; - BIO *c_to_s = NULL; - BIO *s_to_c = NULL; - BIO *c_bio = NULL; - BIO *s_bio = NULL; - int i; - int done = 0; - - s_ssl = SSL_new(s_ctx); - if (s_ssl == NULL) - goto err; - - c_to_s = BIO_new(BIO_s_rtcp()); - s_to_c = BIO_new(BIO_s_rtcp()); - if ((s_to_c == NULL) || (c_to_s == NULL)) - goto err; -/*- original, DRM 24-SEP-1997 - BIO_set_fd ( c_to_s, "", chan ); - BIO_set_fd ( s_to_c, "", chan ); -*/ - BIO_set_fd(c_to_s, 0, chan); - BIO_set_fd(s_to_c, 0, chan); - - c_bio = BIO_new(BIO_f_ssl()); - s_bio = BIO_new(BIO_f_ssl()); - if ((c_bio == NULL) || (s_bio == NULL)) - goto err; - - SSL_set_accept_state(s_ssl); - SSL_set_bio(s_ssl, c_to_s, s_to_c); - BIO_set_ssl(s_bio, s_ssl, BIO_CLOSE); - - /* We can always do writes */ - printf("Begin doit main loop\n"); - /* - * Link states: 0-idle, 1-read pending, 2-write pending, 3-closed. - */ - for (link_state = 0; link_state < 3;) { - /* - * Wait for remote end to request data action on A channel. - */ - while (link_state == 0) { - status = get(chan, (char *)&msg, sizeof(msg), &length); - if ((status & 1) == 0) { - printf("Error in main loop get: %d\n", status); - link_state = 3; - break; - } - if (length < RPC_HDR_SIZE) { - printf("Error in main loop get size: %d\n", length); - break; - link_state = 3; - } - if (msg.channel != 'A') { - printf("Error in main loop, unexpected channel: %c\n", - msg.channel); - break; - link_state = 3; - } - if (msg.function == 'G') { - link_state = 1; - } else if (msg.function == 'P') { - link_state = 2; /* write pending */ - } else if (msg.function == 'X') { - link_state = 3; - } else { - link_state = 3; - } - } - if (link_state == 1) { - i = BIO_read(s_bio, msg.data, msg.length); - if (i < 0) - link_state = 3; - else { - msg.channel = 'A'; - msg.function = 'C'; /* confirm */ - msg.length = i; - status = put(chan, (char *)&msg, i + RPC_HDR_SIZE); - if ((status & 1) == 0) - break; - link_state = 0; - } - } else if (link_state == 2) { - i = BIO_write(s_bio, msg.data, msg.length); - if (i < 0) - link_state = 3; - else { - msg.channel = 'A'; - msg.function = 'C'; /* confirm */ - msg.length = 0; - status = put(chan, (char *)&msg, RPC_HDR_SIZE); - if ((status & 1) == 0) - break; - link_state = 0; - } - } - } - fprintf(stdout, "DONE\n"); - err: - /* - * We have to set the BIO's to NULL otherwise they will be free()ed - * twice. Once when th s_ssl is SSL_free()ed and again when c_ssl is - * SSL_free()ed. This is a hack required because s_ssl and c_ssl are - * sharing the same BIO structure and SSL_set_bio() and SSL_free() - * automatically BIO_free non NULL entries. You should not normally do - * this or be required to do this - */ - s_ssl->rbio = NULL; - s_ssl->wbio = NULL; - - if (c_to_s != NULL) - BIO_free(c_to_s); - if (s_to_c != NULL) - BIO_free(s_to_c); - if (c_bio != NULL) - BIO_free(c_bio); - if (s_bio != NULL) - BIO_free(s_bio); - return (0); -} diff --git a/thirdparty/openssl/ssl/ssl_txt.c b/thirdparty/openssl/ssl/ssl_txt.c deleted file mode 100644 index 45308d8b65..0000000000 --- a/thirdparty/openssl/ssl/ssl_txt.c +++ /dev/null @@ -1,262 +0,0 @@ -/* ssl/ssl_txt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include <stdio.h> -#include <openssl/buffer.h> -#include "ssl_locl.h" - -#ifndef OPENSSL_NO_FP_API -int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file_internal())) == NULL) { - SSLerr(SSL_F_SSL_SESSION_PRINT_FP, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = SSL_SESSION_print(b, x); - BIO_free(b); - return (ret); -} -#endif - -int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) -{ - unsigned int i; - const char *s; - - if (x == NULL) - goto err; - if (BIO_puts(bp, "SSL-Session:\n") <= 0) - goto err; - if (x->ssl_version == SSL2_VERSION) - s = "SSLv2"; - else if (x->ssl_version == SSL3_VERSION) - s = "SSLv3"; - else if (x->ssl_version == TLS1_2_VERSION) - s = "TLSv1.2"; - else if (x->ssl_version == TLS1_1_VERSION) - s = "TLSv1.1"; - else if (x->ssl_version == TLS1_VERSION) - s = "TLSv1"; - else if (x->ssl_version == DTLS1_VERSION) - s = "DTLSv1"; - else if (x->ssl_version == DTLS1_2_VERSION) - s = "DTLSv1.2"; - else if (x->ssl_version == DTLS1_BAD_VER) - s = "DTLSv1-bad"; - else - s = "unknown"; - if (BIO_printf(bp, " Protocol : %s\n", s) <= 0) - goto err; - - if (x->cipher == NULL) { - if (((x->cipher_id) & 0xff000000) == 0x02000000) { - if (BIO_printf - (bp, " Cipher : %06lX\n", x->cipher_id & 0xffffff) <= 0) - goto err; - } else { - if (BIO_printf - (bp, " Cipher : %04lX\n", x->cipher_id & 0xffff) <= 0) - goto err; - } - } else { - if (BIO_printf - (bp, " Cipher : %s\n", - ((x->cipher == NULL) ? "unknown" : x->cipher->name)) <= 0) - goto err; - } - if (BIO_puts(bp, " Session-ID: ") <= 0) - goto err; - for (i = 0; i < x->session_id_length; i++) { - if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0) - goto err; - } - if (BIO_puts(bp, "\n Session-ID-ctx: ") <= 0) - goto err; - for (i = 0; i < x->sid_ctx_length; i++) { - if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0) - goto err; - } - if (BIO_puts(bp, "\n Master-Key: ") <= 0) - goto err; - for (i = 0; i < (unsigned int)x->master_key_length; i++) { - if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0) - goto err; - } - if (BIO_puts(bp, "\n Key-Arg : ") <= 0) - goto err; - if (x->key_arg_length == 0) { - if (BIO_puts(bp, "None") <= 0) - goto err; - } else - for (i = 0; i < x->key_arg_length; i++) { - if (BIO_printf(bp, "%02X", x->key_arg[i]) <= 0) - goto err; - } -#ifndef OPENSSL_NO_KRB5 - if (BIO_puts(bp, "\n Krb5 Principal: ") <= 0) - goto err; - if (x->krb5_client_princ_len == 0) { - if (BIO_puts(bp, "None") <= 0) - goto err; - } else - for (i = 0; i < x->krb5_client_princ_len; i++) { - if (BIO_printf(bp, "%02X", x->krb5_client_princ[i]) <= 0) - goto err; - } -#endif /* OPENSSL_NO_KRB5 */ -#ifndef OPENSSL_NO_PSK - if (BIO_puts(bp, "\n PSK identity: ") <= 0) - goto err; - if (BIO_printf(bp, "%s", x->psk_identity ? x->psk_identity : "None") <= 0) - goto err; - if (BIO_puts(bp, "\n PSK identity hint: ") <= 0) - goto err; - if (BIO_printf - (bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0) - goto err; -#endif -#ifndef OPENSSL_NO_SRP - if (BIO_puts(bp, "\n SRP username: ") <= 0) - goto err; - if (BIO_printf(bp, "%s", x->srp_username ? x->srp_username : "None") <= 0) - goto err; -#endif -#ifndef OPENSSL_NO_TLSEXT - if (x->tlsext_tick_lifetime_hint) { - if (BIO_printf(bp, - "\n TLS session ticket lifetime hint: %ld (seconds)", - x->tlsext_tick_lifetime_hint) <= 0) - goto err; - } - if (x->tlsext_tick) { - if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0) - goto err; - if (BIO_dump_indent(bp, (char *)x->tlsext_tick, x->tlsext_ticklen, 4) - <= 0) - goto err; - } -#endif - -#ifndef OPENSSL_NO_COMP - if (x->compress_meth != 0) { - SSL_COMP *comp = NULL; - - ssl_cipher_get_evp(x, NULL, NULL, NULL, NULL, &comp); - if (comp == NULL) { - if (BIO_printf(bp, "\n Compression: %d", x->compress_meth) <= - 0) - goto err; - } else { - if (BIO_printf - (bp, "\n Compression: %d (%s)", comp->id, - comp->method->name) <= 0) - goto err; - } - } -#endif - if (x->time != 0L) { - if (BIO_printf(bp, "\n Start Time: %ld", x->time) <= 0) - goto err; - } - if (x->timeout != 0L) { - if (BIO_printf(bp, "\n Timeout : %ld (sec)", x->timeout) <= 0) - goto err; - } - if (BIO_puts(bp, "\n") <= 0) - goto err; - - if (BIO_puts(bp, " Verify return code: ") <= 0) - goto err; - if (BIO_printf(bp, "%ld (%s)\n", x->verify_result, - X509_verify_cert_error_string(x->verify_result)) <= 0) - goto err; - - return (1); - err: - return (0); -} diff --git a/thirdparty/openssl/ssl/ssl_utst.c b/thirdparty/openssl/ssl/ssl_utst.c deleted file mode 100644 index 53bdde330d..0000000000 --- a/thirdparty/openssl/ssl/ssl_utst.c +++ /dev/null @@ -1,72 +0,0 @@ -/* ssl_utst.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2014 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 - * openssl-core@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. - * ==================================================================== - * - */ - -#include "ssl_locl.h" - -#ifndef OPENSSL_NO_UNIT_TEST - -static const struct openssl_ssl_test_functions ssl_test_functions = { - ssl_init_wbio_buffer, - ssl3_setup_buffers, - tls1_process_heartbeat, - dtls1_process_heartbeat -}; - -const struct openssl_ssl_test_functions *SSL_test_functions(void) -{ - return &ssl_test_functions; -} - -#endif diff --git a/thirdparty/openssl/ssl/t1_clnt.c b/thirdparty/openssl/ssl/t1_clnt.c deleted file mode 100644 index 746b4e6b7a..0000000000 --- a/thirdparty/openssl/ssl/t1_clnt.c +++ /dev/null @@ -1,90 +0,0 @@ -/* ssl/t1_clnt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include "ssl_locl.h" -#include <openssl/buffer.h> -#include <openssl/rand.h> -#include <openssl/objects.h> -#include <openssl/evp.h> - -static const SSL_METHOD *tls1_get_client_method(int ver); -static const SSL_METHOD *tls1_get_client_method(int ver) -{ - if (ver == TLS1_2_VERSION) - return TLSv1_2_client_method(); - if (ver == TLS1_1_VERSION) - return TLSv1_1_client_method(); - if (ver == TLS1_VERSION) - return TLSv1_client_method(); - return NULL; -} - -IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_client_method, - ssl_undefined_function, - ssl3_connect, - tls1_get_client_method, TLSv1_2_enc_data) - - IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_client_method, - ssl_undefined_function, - ssl3_connect, - tls1_get_client_method, TLSv1_1_enc_data) - - IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_client_method, - ssl_undefined_function, - ssl3_connect, tls1_get_client_method, TLSv1_enc_data) diff --git a/thirdparty/openssl/ssl/t1_enc.c b/thirdparty/openssl/ssl/t1_enc.c deleted file mode 100644 index b6d1ee95a5..0000000000 --- a/thirdparty/openssl/ssl/t1_enc.c +++ /dev/null @@ -1,1376 +0,0 @@ -/* ssl/t1_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 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 - * openssl-core@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). - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include <stdio.h> -#include "ssl_locl.h" -#ifndef OPENSSL_NO_COMP -# include <openssl/comp.h> -#endif -#include <openssl/evp.h> -#include <openssl/hmac.h> -#include <openssl/md5.h> -#include <openssl/rand.h> -#ifdef KSSL_DEBUG -# include <openssl/des.h> -#endif - -/* seed1 through seed5 are virtually concatenated */ -static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec, - int sec_len, - const void *seed1, int seed1_len, - const void *seed2, int seed2_len, - const void *seed3, int seed3_len, - const void *seed4, int seed4_len, - const void *seed5, int seed5_len, - unsigned char *out, int olen) -{ - int chunk; - size_t j; - EVP_MD_CTX ctx, ctx_tmp, ctx_init; - EVP_PKEY *mac_key; - unsigned char A1[EVP_MAX_MD_SIZE]; - size_t A1_len; - int ret = 0; - - chunk = EVP_MD_size(md); - OPENSSL_assert(chunk >= 0); - - EVP_MD_CTX_init(&ctx); - EVP_MD_CTX_init(&ctx_tmp); - EVP_MD_CTX_init(&ctx_init); - EVP_MD_CTX_set_flags(&ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len); - if (!mac_key) - goto err; - if (!EVP_DigestSignInit(&ctx_init, NULL, md, NULL, mac_key)) - goto err; - if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init)) - goto err; - if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) - goto err; - if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) - goto err; - if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) - goto err; - if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len)) - goto err; - if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) - goto err; - if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) - goto err; - - for (;;) { - /* Reinit mac contexts */ - if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init)) - goto err; - if (!EVP_DigestSignUpdate(&ctx, A1, A1_len)) - goto err; - if (olen > chunk && !EVP_MD_CTX_copy_ex(&ctx_tmp, &ctx)) - goto err; - if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) - goto err; - if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) - goto err; - if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) - goto err; - if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len)) - goto err; - if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) - goto err; - - if (olen > chunk) { - if (!EVP_DigestSignFinal(&ctx, out, &j)) - goto err; - out += j; - olen -= j; - /* calc the next A1 value */ - if (!EVP_DigestSignFinal(&ctx_tmp, A1, &A1_len)) - goto err; - } else { /* last one */ - - if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) - goto err; - memcpy(out, A1, olen); - break; - } - } - ret = 1; - err: - EVP_PKEY_free(mac_key); - EVP_MD_CTX_cleanup(&ctx); - EVP_MD_CTX_cleanup(&ctx_tmp); - EVP_MD_CTX_cleanup(&ctx_init); - OPENSSL_cleanse(A1, sizeof(A1)); - return ret; -} - -/* seed1 through seed5 are virtually concatenated */ -static int tls1_PRF(long digest_mask, - const void *seed1, int seed1_len, - const void *seed2, int seed2_len, - const void *seed3, int seed3_len, - const void *seed4, int seed4_len, - const void *seed5, int seed5_len, - const unsigned char *sec, int slen, - unsigned char *out1, unsigned char *out2, int olen) -{ - int len, i, idx, count; - const unsigned char *S1; - long m; - const EVP_MD *md; - int ret = 0; - - /* Count number of digests and partition sec evenly */ - count = 0; - for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { - if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) - count++; - } - if (!count) { - /* Should never happen */ - SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR); - goto err; - } - len = slen / count; - if (count == 1) - slen = 0; - S1 = sec; - memset(out1, 0, olen); - for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { - if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) { - if (!md) { - SSLerr(SSL_F_TLS1_PRF, SSL_R_UNSUPPORTED_DIGEST_TYPE); - goto err; - } - if (!tls1_P_hash(md, S1, len + (slen & 1), - seed1, seed1_len, seed2, seed2_len, seed3, - seed3_len, seed4, seed4_len, seed5, seed5_len, - out2, olen)) - goto err; - S1 += len; - for (i = 0; i < olen; i++) { - out1[i] ^= out2[i]; - } - } - } - ret = 1; - err: - return ret; -} - -static int tls1_generate_key_block(SSL *s, unsigned char *km, - unsigned char *tmp, int num) -{ - int ret; - ret = tls1_PRF(ssl_get_algorithm2(s), - TLS_MD_KEY_EXPANSION_CONST, - TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3->server_random, - SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE, - NULL, 0, NULL, 0, s->session->master_key, - s->session->master_key_length, km, tmp, num); -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_generate_key_block() ==> %d byte master_key =\n\t", - s->session->master_key_length); - { - int i; - for (i = 0; i < s->session->master_key_length; i++) { - fprintf(stderr, "%02X", s->session->master_key[i]); - } - fprintf(stderr, "\n"); - } -#endif /* KSSL_DEBUG */ - return ret; -} - -int tls1_change_cipher_state(SSL *s, int which) -{ - static const unsigned char empty[] = ""; - unsigned char *p, *mac_secret; - unsigned char *exp_label; - unsigned char tmp1[EVP_MAX_KEY_LENGTH]; - unsigned char tmp2[EVP_MAX_KEY_LENGTH]; - unsigned char iv1[EVP_MAX_IV_LENGTH * 2]; - unsigned char iv2[EVP_MAX_IV_LENGTH * 2]; - unsigned char *ms, *key, *iv; - int client_write; - EVP_CIPHER_CTX *dd; - const EVP_CIPHER *c; -#ifndef OPENSSL_NO_COMP - const SSL_COMP *comp; -#endif - const EVP_MD *m; - int mac_type; - int *mac_secret_size; - EVP_MD_CTX *mac_ctx; - EVP_PKEY *mac_key; - int is_export, n, i, j, k, exp_label_len, cl; - int reuse_dd = 0; - - is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); - c = s->s3->tmp.new_sym_enc; - m = s->s3->tmp.new_hash; - mac_type = s->s3->tmp.new_mac_pkey_type; -#ifndef OPENSSL_NO_COMP - comp = s->s3->tmp.new_compression; -#endif - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_change_cipher_state(which= %d) w/\n", which); - fprintf(stderr, "\talg= %ld/%ld, comp= %p\n", - s->s3->tmp.new_cipher->algorithm_mkey, - s->s3->tmp.new_cipher->algorithm_auth, comp); - fprintf(stderr, "\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c); - fprintf(stderr, "\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n", - c->nid, c->block_size, c->key_len, c->iv_len); - fprintf(stderr, "\tkey_block: len= %d, data= ", - s->s3->tmp.key_block_length); - { - int i; - for (i = 0; i < s->s3->tmp.key_block_length; i++) - fprintf(stderr, "%02x", s->s3->tmp.key_block[i]); - fprintf(stderr, "\n"); - } -#endif /* KSSL_DEBUG */ - - if (which & SSL3_CC_READ) { - if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) - s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; - else - s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; - - if (s->enc_read_ctx != NULL) - reuse_dd = 1; - else if ((s->enc_read_ctx = - OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) - goto err; - else - /* - * make sure it's intialized in case we exit later with an error - */ - EVP_CIPHER_CTX_init(s->enc_read_ctx); - dd = s->enc_read_ctx; - mac_ctx = ssl_replace_hash(&s->read_hash, NULL); - if (mac_ctx == NULL) - goto err; -#ifndef OPENSSL_NO_COMP - if (s->expand != NULL) { - COMP_CTX_free(s->expand); - s->expand = NULL; - } - if (comp != NULL) { - s->expand = COMP_CTX_new(comp->method); - if (s->expand == NULL) { - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, - SSL_R_COMPRESSION_LIBRARY_ERROR); - goto err2; - } - if (s->s3->rrec.comp == NULL) - s->s3->rrec.comp = (unsigned char *) - OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH); - if (s->s3->rrec.comp == NULL) - goto err; - } -#endif - /* - * this is done by dtls1_reset_seq_numbers for DTLS - */ - if (!SSL_IS_DTLS(s)) - memset(&(s->s3->read_sequence[0]), 0, 8); - mac_secret = &(s->s3->read_mac_secret[0]); - mac_secret_size = &(s->s3->read_mac_secret_size); - } else { - if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) - s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; - else - s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; - if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) - reuse_dd = 1; - else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) - goto err; - dd = s->enc_write_ctx; - if (SSL_IS_DTLS(s)) { - mac_ctx = EVP_MD_CTX_create(); - if (mac_ctx == NULL) - goto err; - s->write_hash = mac_ctx; - } else { - mac_ctx = ssl_replace_hash(&s->write_hash, NULL); - if (mac_ctx == NULL) - goto err; - } -#ifndef OPENSSL_NO_COMP - if (s->compress != NULL) { - COMP_CTX_free(s->compress); - s->compress = NULL; - } - if (comp != NULL) { - s->compress = COMP_CTX_new(comp->method); - if (s->compress == NULL) { - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, - SSL_R_COMPRESSION_LIBRARY_ERROR); - goto err2; - } - } -#endif - /* - * this is done by dtls1_reset_seq_numbers for DTLS - */ - if (!SSL_IS_DTLS(s)) - memset(&(s->s3->write_sequence[0]), 0, 8); - mac_secret = &(s->s3->write_mac_secret[0]); - mac_secret_size = &(s->s3->write_mac_secret_size); - } - - if (reuse_dd) - EVP_CIPHER_CTX_cleanup(dd); - - p = s->s3->tmp.key_block; - i = *mac_secret_size = s->s3->tmp.new_mac_secret_size; - - cl = EVP_CIPHER_key_length(c); - j = is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? - cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; - /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ - /* If GCM mode only part of IV comes from PRF */ - if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) - k = EVP_GCM_TLS_FIXED_IV_LEN; - else - k = EVP_CIPHER_iv_length(c); - if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || - (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { - ms = &(p[0]); - n = i + i; - key = &(p[n]); - n += j + j; - iv = &(p[n]); - n += k + k; - exp_label = (unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST; - exp_label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; - client_write = 1; - } else { - n = i; - ms = &(p[n]); - n += i + j; - key = &(p[n]); - n += j + k; - iv = &(p[n]); - n += k; - exp_label = (unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST; - exp_label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; - client_write = 0; - } - - if (n > s->s3->tmp.key_block_length) { - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } - - memcpy(mac_secret, ms, i); - - if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) { - mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, - mac_secret, *mac_secret_size); - if (mac_key == NULL - || EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key) <= 0) { - EVP_PKEY_free(mac_key); - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } - EVP_PKEY_free(mac_key); - } -#ifdef TLS_DEBUG - printf("which = %04X\nmac key=", which); - { - int z; - for (z = 0; z < i; z++) - printf("%02X%c", ms[z], ((z + 1) % 16) ? ' ' : '\n'); - } -#endif - if (is_export) { - /* - * In here I set both the read and write key/iv to the same value - * since only the correct one will be used :-). - */ - if (!tls1_PRF(ssl_get_algorithm2(s), - exp_label, exp_label_len, - s->s3->client_random, SSL3_RANDOM_SIZE, - s->s3->server_random, SSL3_RANDOM_SIZE, - NULL, 0, NULL, 0, - key, j, tmp1, tmp2, EVP_CIPHER_key_length(c))) - goto err2; - key = tmp1; - - if (k > 0) { - if (!tls1_PRF(ssl_get_algorithm2(s), - TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE, - s->s3->client_random, SSL3_RANDOM_SIZE, - s->s3->server_random, SSL3_RANDOM_SIZE, - NULL, 0, NULL, 0, empty, 0, iv1, iv2, k * 2)) - goto err2; - if (client_write) - iv = iv1; - else - iv = &(iv1[k]); - } - } - - s->session->key_arg_length = 0; -#ifdef KSSL_DEBUG - { - int i; - fprintf(stderr, "EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); - fprintf(stderr, "\tkey= "); - for (i = 0; i < c->key_len; i++) - fprintf(stderr, "%02x", key[i]); - fprintf(stderr, "\n"); - fprintf(stderr, "\t iv= "); - for (i = 0; i < c->iv_len; i++) - fprintf(stderr, "%02x", iv[i]); - fprintf(stderr, "\n"); - } -#endif /* KSSL_DEBUG */ - - if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { - if (!EVP_CipherInit_ex(dd, c, NULL, key, NULL, (which & SSL3_CC_WRITE)) - || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv)) { - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } - } else { - if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } - } - /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ - if ((EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size - && !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_MAC_KEY, - *mac_secret_size, mac_secret)) { - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } -#ifdef OPENSSL_SSL_TRACE_CRYPTO - if (s->msg_callback) { - int wh = which & SSL3_CC_WRITE ? TLS1_RT_CRYPTO_WRITE : 0; - if (*mac_secret_size) - s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC, - mac_secret, *mac_secret_size, - s, s->msg_callback_arg); - if (c->key_len) - s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY, - key, c->key_len, s, s->msg_callback_arg); - if (k) { - if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) - wh |= TLS1_RT_CRYPTO_FIXED_IV; - else - wh |= TLS1_RT_CRYPTO_IV; - s->msg_callback(2, s->version, wh, iv, k, s, s->msg_callback_arg); - } - } -#endif - -#ifdef TLS_DEBUG - printf("which = %04X\nkey=", which); - { - int z; - for (z = 0; z < EVP_CIPHER_key_length(c); z++) - printf("%02X%c", key[z], ((z + 1) % 16) ? ' ' : '\n'); - } - printf("\niv="); - { - int z; - for (z = 0; z < k; z++) - printf("%02X%c", iv[z], ((z + 1) % 16) ? ' ' : '\n'); - } - printf("\n"); -#endif - - OPENSSL_cleanse(tmp1, sizeof(tmp1)); - OPENSSL_cleanse(tmp2, sizeof(tmp1)); - OPENSSL_cleanse(iv1, sizeof(iv1)); - OPENSSL_cleanse(iv2, sizeof(iv2)); - return (1); - err: - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); - err2: - return (0); -} - -int tls1_setup_key_block(SSL *s) -{ - unsigned char *p1, *p2 = NULL; - const EVP_CIPHER *c; - const EVP_MD *hash; - int num; - SSL_COMP *comp; - int mac_type = NID_undef, mac_secret_size = 0; - int ret = 0; - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_setup_key_block()\n"); -#endif /* KSSL_DEBUG */ - - if (s->s3->tmp.key_block_length != 0) - return (1); - - if (!ssl_cipher_get_evp - (s->session, &c, &hash, &mac_type, &mac_secret_size, &comp)) { - SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); - return (0); - } - - s->s3->tmp.new_sym_enc = c; - s->s3->tmp.new_hash = hash; - s->s3->tmp.new_mac_pkey_type = mac_type; - s->s3->tmp.new_mac_secret_size = mac_secret_size; - num = - EVP_CIPHER_key_length(c) + mac_secret_size + EVP_CIPHER_iv_length(c); - num *= 2; - - ssl3_cleanup_key_block(s); - - if ((p1 = (unsigned char *)OPENSSL_malloc(num)) == NULL) { - SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); - goto err; - } - - s->s3->tmp.key_block_length = num; - s->s3->tmp.key_block = p1; - - if ((p2 = (unsigned char *)OPENSSL_malloc(num)) == NULL) { - SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); - goto err; - } -#ifdef TLS_DEBUG - printf("client random\n"); - { - int z; - for (z = 0; z < SSL3_RANDOM_SIZE; z++) - printf("%02X%c", s->s3->client_random[z], - ((z + 1) % 16) ? ' ' : '\n'); - } - printf("server random\n"); - { - int z; - for (z = 0; z < SSL3_RANDOM_SIZE; z++) - printf("%02X%c", s->s3->server_random[z], - ((z + 1) % 16) ? ' ' : '\n'); - } - printf("pre-master\n"); - { - int z; - for (z = 0; z < s->session->master_key_length; z++) - printf("%02X%c", s->session->master_key[z], - ((z + 1) % 16) ? ' ' : '\n'); - } -#endif - if (!tls1_generate_key_block(s, p1, p2, num)) - goto err; -#ifdef TLS_DEBUG - printf("\nkey block\n"); - { - int z; - for (z = 0; z < num; z++) - printf("%02X%c", p1[z], ((z + 1) % 16) ? ' ' : '\n'); - } -#endif - - if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) - && s->method->version <= TLS1_VERSION) { - /* - * enable vulnerability countermeasure for CBC ciphers with known-IV - * problem (http://www.openssl.org/~bodo/tls-cbc.txt) - */ - s->s3->need_empty_fragments = 1; - - if (s->session->cipher != NULL) { - if (s->session->cipher->algorithm_enc == SSL_eNULL) - s->s3->need_empty_fragments = 0; - -#ifndef OPENSSL_NO_RC4 - if (s->session->cipher->algorithm_enc == SSL_RC4) - s->s3->need_empty_fragments = 0; -#endif - } - } - - ret = 1; - err: - if (p2) { - OPENSSL_cleanse(p2, num); - OPENSSL_free(p2); - } - return (ret); -} - -/*- - * tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. - * - * Returns: - * 0: (in non-constant time) if the record is publically invalid (i.e. too - * short etc). - * 1: if the record's padding is valid / the encryption was successful. - * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, - * an internal error occured. - */ -int tls1_enc(SSL *s, int send) -{ - SSL3_RECORD *rec; - EVP_CIPHER_CTX *ds; - unsigned long l; - int bs, i, j, k, pad = 0, ret, mac_size = 0; - const EVP_CIPHER *enc; - - if (send) { - if (EVP_MD_CTX_md(s->write_hash)) { - int n = EVP_MD_CTX_size(s->write_hash); - OPENSSL_assert(n >= 0); - } - ds = s->enc_write_ctx; - rec = &(s->s3->wrec); - if (s->enc_write_ctx == NULL) - enc = NULL; - else { - int ivlen; - enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); - /* For TLSv1.1 and later explicit IV */ - if (SSL_USE_EXPLICIT_IV(s) - && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) - ivlen = EVP_CIPHER_iv_length(enc); - else - ivlen = 0; - if (ivlen > 1) { - if (rec->data != rec->input) - /* - * we can't write into the input stream: Can this ever - * happen?? (steve) - */ - fprintf(stderr, - "%s:%d: rec->data != rec->input\n", - __FILE__, __LINE__); - else if (RAND_bytes(rec->input, ivlen) <= 0) - return -1; - } - } - } else { - if (EVP_MD_CTX_md(s->read_hash)) { - int n = EVP_MD_CTX_size(s->read_hash); - OPENSSL_assert(n >= 0); - } - ds = s->enc_read_ctx; - rec = &(s->s3->rrec); - if (s->enc_read_ctx == NULL) - enc = NULL; - else - enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); - } - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_enc(%d)\n", send); -#endif /* KSSL_DEBUG */ - - if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { - memmove(rec->data, rec->input, rec->length); - rec->input = rec->data; - ret = 1; - } else { - l = rec->length; - bs = EVP_CIPHER_block_size(ds->cipher); - - if (EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { - unsigned char buf[EVP_AEAD_TLS1_AAD_LEN], *seq; - - seq = send ? s->s3->write_sequence : s->s3->read_sequence; - - if (SSL_IS_DTLS(s)) { - unsigned char dtlsseq[9], *p = dtlsseq; - - s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p); - memcpy(p, &seq[2], 6); - memcpy(buf, dtlsseq, 8); - } else { - memcpy(buf, seq, 8); - for (i = 7; i >= 0; i--) { /* increment */ - ++seq[i]; - if (seq[i] != 0) - break; - } - } - - buf[8] = rec->type; - buf[9] = (unsigned char)(s->version >> 8); - buf[10] = (unsigned char)(s->version); - buf[11] = rec->length >> 8; - buf[12] = rec->length & 0xff; - pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, - EVP_AEAD_TLS1_AAD_LEN, buf); - if (pad <= 0) - return -1; - if (send) { - l += pad; - rec->length += pad; - } - } else if ((bs != 1) && send) { - i = bs - ((int)l % bs); - - /* Add weird padding of upto 256 bytes */ - - /* we need to add 'i' padding bytes of value j */ - j = i - 1; - if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) { - if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) - j++; - } - for (k = (int)l; k < (int)(l + i); k++) - rec->input[k] = j; - l += i; - rec->length += i; - } -#ifdef KSSL_DEBUG - { - unsigned long ui; - fprintf(stderr, - "EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", - ds, rec->data, rec->input, l); - fprintf(stderr, - "\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%lu %lu], %d iv_len\n", - ds->buf_len, ds->cipher->key_len, DES_KEY_SZ, - DES_SCHEDULE_SZ, ds->cipher->iv_len); - fprintf(stderr, "\t\tIV: "); - for (i = 0; i < ds->cipher->iv_len; i++) - fprintf(stderr, "%02X", ds->iv[i]); - fprintf(stderr, "\n"); - fprintf(stderr, "\trec->input="); - for (ui = 0; ui < l; ui++) - fprintf(stderr, " %02x", rec->input[ui]); - fprintf(stderr, "\n"); - } -#endif /* KSSL_DEBUG */ - - if (!send) { - if (l == 0 || l % bs != 0) - return 0; - } - - i = EVP_Cipher(ds, rec->data, rec->input, l); - if ((EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_CUSTOM_CIPHER) - ? (i < 0) - : (i == 0)) - return -1; /* AEAD can fail to verify MAC */ - if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send) { - rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN; - rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN; - rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; - } -#ifdef KSSL_DEBUG - { - unsigned long i; - fprintf(stderr, "\trec->data="); - for (i = 0; i < l; i++) - fprintf(stderr, " %02x", rec->data[i]); - fprintf(stderr, "\n"); - } -#endif /* KSSL_DEBUG */ - - ret = 1; - if (EVP_MD_CTX_md(s->read_hash) != NULL) - mac_size = EVP_MD_CTX_size(s->read_hash); - if ((bs != 1) && !send) - ret = tls1_cbc_remove_padding(s, rec, bs, mac_size); - if (pad && !send) - rec->length -= pad; - } - return ret; -} - -int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out) -{ - unsigned int ret; - EVP_MD_CTX ctx, *d = NULL; - int i; - - if (s->s3->handshake_buffer) - if (!ssl3_digest_cached_records(s)) - return 0; - - for (i = 0; i < SSL_MAX_DIGEST; i++) { - if (s->s3->handshake_dgst[i] - && EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) { - d = s->s3->handshake_dgst[i]; - break; - } - } - if (!d) { - SSLerr(SSL_F_TLS1_CERT_VERIFY_MAC, SSL_R_NO_REQUIRED_DIGEST); - return 0; - } - - EVP_MD_CTX_init(&ctx); - if (EVP_MD_CTX_copy_ex(&ctx, d) <=0 - || EVP_DigestFinal_ex(&ctx, out, &ret) <= 0) - ret = 0; - EVP_MD_CTX_cleanup(&ctx); - return ((int)ret); -} - -int tls1_final_finish_mac(SSL *s, - const char *str, int slen, unsigned char *out) -{ - unsigned int i; - EVP_MD_CTX ctx; - unsigned char buf[2 * EVP_MAX_MD_SIZE]; - unsigned char *q, buf2[12]; - int idx; - long mask; - int err = 0; - const EVP_MD *md; - - q = buf; - - if (s->s3->handshake_buffer) - if (!ssl3_digest_cached_records(s)) - return 0; - - EVP_MD_CTX_init(&ctx); - - for (idx = 0; ssl_get_handshake_digest(idx, &mask, &md); idx++) { - if (mask & ssl_get_algorithm2(s)) { - int hashsize = EVP_MD_size(md); - EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx]; - if (!hdgst || hashsize < 0 - || hashsize > (int)(sizeof buf - (size_t)(q - buf))) { - /* - * internal error: 'buf' is too small for this cipersuite! - */ - err = 1; - } else { - if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) || - !EVP_DigestFinal_ex(&ctx, q, &i) || - (i != (unsigned int)hashsize)) - err = 1; - q += hashsize; - } - } - } - - if (!tls1_PRF(ssl_get_algorithm2(s), - str, slen, buf, (int)(q - buf), NULL, 0, NULL, 0, NULL, 0, - s->session->master_key, s->session->master_key_length, - out, buf2, sizeof buf2)) - err = 1; - EVP_MD_CTX_cleanup(&ctx); - - OPENSSL_cleanse(buf, (int)(q - buf)); - OPENSSL_cleanse(buf2, sizeof(buf2)); - if (err) - return 0; - else - return sizeof buf2; -} - -int tls1_mac(SSL *ssl, unsigned char *md, int send) -{ - SSL3_RECORD *rec; - unsigned char *seq; - EVP_MD_CTX *hash; - size_t md_size, orig_len; - int i; - EVP_MD_CTX hmac, *mac_ctx; - unsigned char header[13]; - int stream_mac = (send ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) - : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM)); - int t; - - if (send) { - rec = &(ssl->s3->wrec); - seq = &(ssl->s3->write_sequence[0]); - hash = ssl->write_hash; - } else { - rec = &(ssl->s3->rrec); - seq = &(ssl->s3->read_sequence[0]); - hash = ssl->read_hash; - } - - t = EVP_MD_CTX_size(hash); - OPENSSL_assert(t >= 0); - md_size = t; - - /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ - if (stream_mac) { - mac_ctx = hash; - } else { - if (!EVP_MD_CTX_copy(&hmac, hash)) - return -1; - mac_ctx = &hmac; - } - - if (SSL_IS_DTLS(ssl)) { - unsigned char dtlsseq[8], *p = dtlsseq; - - s2n(send ? ssl->d1->w_epoch : ssl->d1->r_epoch, p); - memcpy(p, &seq[2], 6); - - memcpy(header, dtlsseq, 8); - } else - memcpy(header, seq, 8); - - /* - * kludge: tls1_cbc_remove_padding passes padding length in rec->type - */ - orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8); - rec->type &= 0xff; - - header[8] = rec->type; - header[9] = (unsigned char)(ssl->version >> 8); - header[10] = (unsigned char)(ssl->version); - header[11] = (rec->length) >> 8; - header[12] = (rec->length) & 0xff; - - if (!send && - EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && - ssl3_cbc_record_digest_supported(mac_ctx)) { - /* - * This is a CBC-encrypted record. We must avoid leaking any - * timing-side channel information about how many blocks of data we - * are hashing because that gives an attacker a timing-oracle. - */ - /* Final param == not SSLv3 */ - if (ssl3_cbc_digest_record(mac_ctx, - md, &md_size, - header, rec->input, - rec->length + md_size, orig_len, - ssl->s3->read_mac_secret, - ssl->s3->read_mac_secret_size, 0) <= 0) { - if (!stream_mac) - EVP_MD_CTX_cleanup(&hmac); - return -1; - } - } else { - if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0 - || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0 - || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) { - if (!stream_mac) - EVP_MD_CTX_cleanup(&hmac); - return -1; - } -#ifdef OPENSSL_FIPS - if (!send && FIPS_mode()) - tls_fips_digest_extra(ssl->enc_read_ctx, - mac_ctx, rec->input, rec->length, orig_len); -#endif - } - - if (!stream_mac) - EVP_MD_CTX_cleanup(&hmac); -#ifdef TLS_DEBUG - fprintf(stderr, "seq="); - { - int z; - for (z = 0; z < 8; z++) - fprintf(stderr, "%02X ", seq[z]); - fprintf(stderr, "\n"); - } - fprintf(stderr, "rec="); - { - unsigned int z; - for (z = 0; z < rec->length; z++) - fprintf(stderr, "%02X ", rec->data[z]); - fprintf(stderr, "\n"); - } -#endif - - if (!SSL_IS_DTLS(ssl)) { - for (i = 7; i >= 0; i--) { - ++seq[i]; - if (seq[i] != 0) - break; - } - } -#ifdef TLS_DEBUG - { - unsigned int z; - for (z = 0; z < md_size; z++) - fprintf(stderr, "%02X ", md[z]); - fprintf(stderr, "\n"); - } -#endif - return (md_size); -} - -int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, - int len) -{ - unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH]; - const void *co = NULL, *so = NULL; - int col = 0, sol = 0; - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_generate_master_secret(%p,%p, %p, %d)\n", s, out, p, - len); -#endif /* KSSL_DEBUG */ - -#ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->client_opaque_prf_input != NULL - && s->s3->server_opaque_prf_input != NULL - && s->s3->client_opaque_prf_input_len > 0 - && s->s3->client_opaque_prf_input_len == - s->s3->server_opaque_prf_input_len) { - co = s->s3->client_opaque_prf_input; - col = s->s3->server_opaque_prf_input_len; - so = s->s3->server_opaque_prf_input; - /* - * must be same as col (see - * draft-rescorla-tls-opaque-prf-input-00.txt, section 3.1) - */ - sol = s->s3->client_opaque_prf_input_len; - } -#endif - - tls1_PRF(ssl_get_algorithm2(s), - TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, - s->s3->client_random, SSL3_RANDOM_SIZE, - co, col, - s->s3->server_random, SSL3_RANDOM_SIZE, - so, sol, p, len, s->session->master_key, buff, sizeof buff); - OPENSSL_cleanse(buff, sizeof buff); -#ifdef SSL_DEBUG - fprintf(stderr, "Premaster Secret:\n"); - BIO_dump_fp(stderr, (char *)p, len); - fprintf(stderr, "Client Random:\n"); - BIO_dump_fp(stderr, (char *)s->s3->client_random, SSL3_RANDOM_SIZE); - fprintf(stderr, "Server Random:\n"); - BIO_dump_fp(stderr, (char *)s->s3->server_random, SSL3_RANDOM_SIZE); - fprintf(stderr, "Master Secret:\n"); - BIO_dump_fp(stderr, (char *)s->session->master_key, - SSL3_MASTER_SECRET_SIZE); -#endif - -#ifdef OPENSSL_SSL_TRACE_CRYPTO - if (s->msg_callback) { - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER, - p, len, s, s->msg_callback_arg); - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM, - s->s3->client_random, SSL3_RANDOM_SIZE, - s, s->msg_callback_arg); - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM, - s->s3->server_random, SSL3_RANDOM_SIZE, - s, s->msg_callback_arg); - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER, - s->session->master_key, - SSL3_MASTER_SECRET_SIZE, s, s->msg_callback_arg); - } -#endif - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_generate_master_secret() complete\n"); -#endif /* KSSL_DEBUG */ - return (SSL3_MASTER_SECRET_SIZE); -} - -int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, - const char *label, size_t llen, - const unsigned char *context, - size_t contextlen, int use_context) -{ - unsigned char *buff; - unsigned char *val = NULL; - size_t vallen, currentvalpos; - int rv; - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_export_keying_material(%p,%p,%lu,%s,%lu,%p,%lu)\n", - s, out, olen, label, llen, context, contextlen); -#endif /* KSSL_DEBUG */ - - buff = OPENSSL_malloc(olen); - if (buff == NULL) - goto err2; - - /* - * construct PRF arguments we construct the PRF argument ourself rather - * than passing separate values into the TLS PRF to ensure that the - * concatenation of values does not create a prohibited label. - */ - vallen = llen + SSL3_RANDOM_SIZE * 2; - if (use_context) { - vallen += 2 + contextlen; - } - - val = OPENSSL_malloc(vallen); - if (val == NULL) - goto err2; - currentvalpos = 0; - memcpy(val + currentvalpos, (unsigned char *)label, llen); - currentvalpos += llen; - memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE); - currentvalpos += SSL3_RANDOM_SIZE; - memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE); - currentvalpos += SSL3_RANDOM_SIZE; - - if (use_context) { - val[currentvalpos] = (contextlen >> 8) & 0xff; - currentvalpos++; - val[currentvalpos] = contextlen & 0xff; - currentvalpos++; - if ((contextlen > 0) || (context != NULL)) { - memcpy(val + currentvalpos, context, contextlen); - } - } - - /* - * disallow prohibited labels note that SSL3_RANDOM_SIZE > max(prohibited - * label len) = 15, so size of val > max(prohibited label len) = 15 and - * the comparisons won't have buffer overflow - */ - if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST, - TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) - goto err1; - if (memcmp(val, TLS_MD_SERVER_FINISH_CONST, - TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) - goto err1; - if (memcmp(val, TLS_MD_MASTER_SECRET_CONST, - TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) - goto err1; - if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST, - TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) - goto err1; - - rv = tls1_PRF(ssl_get_algorithm2(s), - val, vallen, - NULL, 0, - NULL, 0, - NULL, 0, - NULL, 0, - s->session->master_key, s->session->master_key_length, - out, buff, olen); - OPENSSL_cleanse(val, vallen); - OPENSSL_cleanse(buff, olen); - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_export_keying_material() complete\n"); -#endif /* KSSL_DEBUG */ - goto ret; - err1: - SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, - SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); - rv = 0; - goto ret; - err2: - SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE); - rv = 0; - ret: - if (buff != NULL) - OPENSSL_free(buff); - if (val != NULL) - OPENSSL_free(val); - return (rv); -} - -int tls1_alert_code(int code) -{ - switch (code) { - case SSL_AD_CLOSE_NOTIFY: - return (SSL3_AD_CLOSE_NOTIFY); - case SSL_AD_UNEXPECTED_MESSAGE: - return (SSL3_AD_UNEXPECTED_MESSAGE); - case SSL_AD_BAD_RECORD_MAC: - return (SSL3_AD_BAD_RECORD_MAC); - case SSL_AD_DECRYPTION_FAILED: - return (TLS1_AD_DECRYPTION_FAILED); - case SSL_AD_RECORD_OVERFLOW: - return (TLS1_AD_RECORD_OVERFLOW); - case SSL_AD_DECOMPRESSION_FAILURE: - return (SSL3_AD_DECOMPRESSION_FAILURE); - case SSL_AD_HANDSHAKE_FAILURE: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_NO_CERTIFICATE: - return (-1); - case SSL_AD_BAD_CERTIFICATE: - return (SSL3_AD_BAD_CERTIFICATE); - case SSL_AD_UNSUPPORTED_CERTIFICATE: - return (SSL3_AD_UNSUPPORTED_CERTIFICATE); - case SSL_AD_CERTIFICATE_REVOKED: - return (SSL3_AD_CERTIFICATE_REVOKED); - case SSL_AD_CERTIFICATE_EXPIRED: - return (SSL3_AD_CERTIFICATE_EXPIRED); - case SSL_AD_CERTIFICATE_UNKNOWN: - return (SSL3_AD_CERTIFICATE_UNKNOWN); - case SSL_AD_ILLEGAL_PARAMETER: - return (SSL3_AD_ILLEGAL_PARAMETER); - case SSL_AD_UNKNOWN_CA: - return (TLS1_AD_UNKNOWN_CA); - case SSL_AD_ACCESS_DENIED: - return (TLS1_AD_ACCESS_DENIED); - case SSL_AD_DECODE_ERROR: - return (TLS1_AD_DECODE_ERROR); - case SSL_AD_DECRYPT_ERROR: - return (TLS1_AD_DECRYPT_ERROR); - case SSL_AD_EXPORT_RESTRICTION: - return (TLS1_AD_EXPORT_RESTRICTION); - case SSL_AD_PROTOCOL_VERSION: - return (TLS1_AD_PROTOCOL_VERSION); - case SSL_AD_INSUFFICIENT_SECURITY: - return (TLS1_AD_INSUFFICIENT_SECURITY); - case SSL_AD_INTERNAL_ERROR: - return (TLS1_AD_INTERNAL_ERROR); - case SSL_AD_USER_CANCELLED: - return (TLS1_AD_USER_CANCELLED); - case SSL_AD_NO_RENEGOTIATION: - return (TLS1_AD_NO_RENEGOTIATION); - case SSL_AD_UNSUPPORTED_EXTENSION: - return (TLS1_AD_UNSUPPORTED_EXTENSION); - case SSL_AD_CERTIFICATE_UNOBTAINABLE: - return (TLS1_AD_CERTIFICATE_UNOBTAINABLE); - case SSL_AD_UNRECOGNIZED_NAME: - return (TLS1_AD_UNRECOGNIZED_NAME); - case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: - return (TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE); - case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: - return (TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); - case SSL_AD_UNKNOWN_PSK_IDENTITY: - return (TLS1_AD_UNKNOWN_PSK_IDENTITY); - case SSL_AD_INAPPROPRIATE_FALLBACK: - return (TLS1_AD_INAPPROPRIATE_FALLBACK); -#if 0 - /* not appropriate for TLS, not used for DTLS */ - case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: - return (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); -#endif - default: - return (-1); - } -} diff --git a/thirdparty/openssl/ssl/t1_ext.c b/thirdparty/openssl/ssl/t1_ext.c deleted file mode 100644 index 0f4aba0226..0000000000 --- a/thirdparty/openssl/ssl/t1_ext.c +++ /dev/null @@ -1,317 +0,0 @@ -/* ssl/t1_ext.c */ -/* ==================================================================== - * Copyright (c) 2014 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 - * openssl-core@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). - * - */ - -/* Custom extension utility functions */ - -#include "ssl_locl.h" - -#ifndef OPENSSL_NO_TLSEXT - -/* Find a custom extension from the list. */ -static custom_ext_method *custom_ext_find(custom_ext_methods *exts, - unsigned int ext_type) -{ - size_t i; - custom_ext_method *meth = exts->meths; - for (i = 0; i < exts->meths_count; i++, meth++) { - if (ext_type == meth->ext_type) - return meth; - } - return NULL; -} - -/* - * Initialise custom extensions flags to indicate neither sent nor received. - */ -void custom_ext_init(custom_ext_methods *exts) -{ - size_t i; - custom_ext_method *meth = exts->meths; - for (i = 0; i < exts->meths_count; i++, meth++) - meth->ext_flags = 0; -} - -/* Pass received custom extension data to the application for parsing. */ -int custom_ext_parse(SSL *s, int server, - unsigned int ext_type, - const unsigned char *ext_data, size_t ext_size, int *al) -{ - custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext; - custom_ext_method *meth; - meth = custom_ext_find(exts, ext_type); - /* If not found return success */ - if (!meth) - return 1; - if (!server) { - /* - * If it's ServerHello we can't have any extensions not sent in - * ClientHello. - */ - if (!(meth->ext_flags & SSL_EXT_FLAG_SENT)) { - *al = TLS1_AD_UNSUPPORTED_EXTENSION; - return 0; - } - } - /* If already present it's a duplicate */ - if (meth->ext_flags & SSL_EXT_FLAG_RECEIVED) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - meth->ext_flags |= SSL_EXT_FLAG_RECEIVED; - /* If no parse function set return success */ - if (!meth->parse_cb) - return 1; - - return meth->parse_cb(s, ext_type, ext_data, ext_size, al, - meth->parse_arg); -} - -/* - * Request custom extension data from the application and add to the return - * buffer. - */ -int custom_ext_add(SSL *s, int server, - unsigned char **pret, unsigned char *limit, int *al) -{ - custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext; - custom_ext_method *meth; - unsigned char *ret = *pret; - size_t i; - - for (i = 0; i < exts->meths_count; i++) { - const unsigned char *out = NULL; - size_t outlen = 0; - meth = exts->meths + i; - - if (server) { - /* - * For ServerHello only send extensions present in ClientHello. - */ - if (!(meth->ext_flags & SSL_EXT_FLAG_RECEIVED)) - continue; - /* If callback absent for server skip it */ - if (!meth->add_cb) - continue; - } - if (meth->add_cb) { - int cb_retval = 0; - cb_retval = meth->add_cb(s, meth->ext_type, - &out, &outlen, al, meth->add_arg); - if (cb_retval < 0) - return 0; /* error */ - if (cb_retval == 0) - continue; /* skip this extension */ - } - if (4 > limit - ret || outlen > (size_t)(limit - ret - 4)) - return 0; - s2n(meth->ext_type, ret); - s2n(outlen, ret); - if (outlen) { - memcpy(ret, out, outlen); - ret += outlen; - } - /* - * We can't send duplicates: code logic should prevent this. - */ - OPENSSL_assert(!(meth->ext_flags & SSL_EXT_FLAG_SENT)); - /* - * Indicate extension has been sent: this is both a sanity check to - * ensure we don't send duplicate extensions and indicates that it is - * not an error if the extension is present in ServerHello. - */ - meth->ext_flags |= SSL_EXT_FLAG_SENT; - if (meth->free_cb) - meth->free_cb(s, meth->ext_type, out, meth->add_arg); - } - *pret = ret; - return 1; -} - -/* Copy the flags from src to dst for any extensions that exist in both */ -int custom_exts_copy_flags(custom_ext_methods *dst, - const custom_ext_methods *src) -{ - size_t i; - custom_ext_method *methsrc = src->meths; - - for (i = 0; i < src->meths_count; i++, methsrc++) { - custom_ext_method *methdst = custom_ext_find(dst, methsrc->ext_type); - - if (methdst == NULL) - continue; - - methdst->ext_flags = methsrc->ext_flags; - } - - return 1; -} - -/* Copy table of custom extensions */ -int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src) -{ - if (src->meths_count) { - dst->meths = - BUF_memdup(src->meths, - sizeof(custom_ext_method) * src->meths_count); - if (dst->meths == NULL) - return 0; - dst->meths_count = src->meths_count; - } - return 1; -} - -void custom_exts_free(custom_ext_methods *exts) -{ - if (exts->meths) - OPENSSL_free(exts->meths); -} - -/* Set callbacks for a custom extension. */ -static int custom_ext_meth_add(custom_ext_methods *exts, - unsigned int ext_type, - custom_ext_add_cb add_cb, - custom_ext_free_cb free_cb, - void *add_arg, - custom_ext_parse_cb parse_cb, void *parse_arg) -{ - custom_ext_method *meth; - /* - * Check application error: if add_cb is not set free_cb will never be - * called. - */ - if (!add_cb && free_cb) - return 0; - /* Don't add if extension supported internally. */ - if (SSL_extension_supported(ext_type)) - return 0; - /* Extension type must fit in 16 bits */ - if (ext_type > 0xffff) - return 0; - /* Search for duplicate */ - if (custom_ext_find(exts, ext_type)) - return 0; - meth = OPENSSL_realloc(exts->meths, - (exts->meths_count + 1) - * sizeof(custom_ext_method)); - if (meth == NULL) - return 0; - - exts->meths = meth; - meth += exts->meths_count; - memset(meth, 0, sizeof(custom_ext_method)); - meth->parse_cb = parse_cb; - meth->add_cb = add_cb; - meth->free_cb = free_cb; - meth->ext_type = ext_type; - meth->add_arg = add_arg; - meth->parse_arg = parse_arg; - exts->meths_count++; - return 1; -} - -/* Application level functions to add custom extension callbacks */ -int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type, - custom_ext_add_cb add_cb, - custom_ext_free_cb free_cb, - void *add_arg, - custom_ext_parse_cb parse_cb, - void *parse_arg) -{ - return custom_ext_meth_add(&ctx->cert->cli_ext, ext_type, - add_cb, free_cb, add_arg, parse_cb, parse_arg); -} - -int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type, - custom_ext_add_cb add_cb, - custom_ext_free_cb free_cb, - void *add_arg, - custom_ext_parse_cb parse_cb, - void *parse_arg) -{ - return custom_ext_meth_add(&ctx->cert->srv_ext, ext_type, - add_cb, free_cb, add_arg, parse_cb, parse_arg); -} - -int SSL_extension_supported(unsigned int ext_type) -{ - switch (ext_type) { - /* Internally supported extensions. */ - case TLSEXT_TYPE_application_layer_protocol_negotiation: - case TLSEXT_TYPE_ec_point_formats: - case TLSEXT_TYPE_elliptic_curves: - case TLSEXT_TYPE_heartbeat: -# ifndef OPENSSL_NO_NEXTPROTONEG - case TLSEXT_TYPE_next_proto_neg: -# endif - case TLSEXT_TYPE_padding: - case TLSEXT_TYPE_renegotiate: - case TLSEXT_TYPE_server_name: - case TLSEXT_TYPE_session_ticket: - case TLSEXT_TYPE_signature_algorithms: - case TLSEXT_TYPE_srp: - case TLSEXT_TYPE_status_request: - case TLSEXT_TYPE_use_srtp: -# ifdef TLSEXT_TYPE_opaque_prf_input - case TLSEXT_TYPE_opaque_prf_input: -# endif -# ifdef TLSEXT_TYPE_encrypt_then_mac - case TLSEXT_TYPE_encrypt_then_mac: -# endif - return 1; - default: - return 0; - } -} -#endif diff --git a/thirdparty/openssl/ssl/t1_lib.c b/thirdparty/openssl/ssl/t1_lib.c deleted file mode 100644 index 6587e8bb68..0000000000 --- a/thirdparty/openssl/ssl/t1_lib.c +++ /dev/null @@ -1,4559 +0,0 @@ -/* ssl/t1_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 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 - * openssl-core@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). - * - */ - -#include <stdio.h> -#include <openssl/objects.h> -#include <openssl/evp.h> -#include <openssl/hmac.h> -#ifndef OPENSSL_NO_EC -#ifdef OPENSSL_NO_EC2M -# include <openssl/ec.h> -#endif -#endif -#include <openssl/ocsp.h> -#include <openssl/rand.h> -#include "ssl_locl.h" - -const char tls1_version_str[] = "TLSv1" OPENSSL_VERSION_PTEXT; - -#ifndef OPENSSL_NO_TLSEXT -static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, - const unsigned char *sess_id, int sesslen, - SSL_SESSION **psess); -static int ssl_check_clienthello_tlsext_early(SSL *s); -int ssl_check_serverhello_tlsext(SSL *s); -#endif - -#define CHECKLEN(curr, val, limit) \ - (((curr) >= (limit)) || (size_t)((limit) - (curr)) < (size_t)(val)) - -SSL3_ENC_METHOD TLSv1_enc_data = { - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - 0, - SSL3_HM_HEADER_LENGTH, - ssl3_set_handshake_header, - ssl3_handshake_write -}; - -SSL3_ENC_METHOD TLSv1_1_enc_data = { - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - SSL_ENC_FLAG_EXPLICIT_IV, - SSL3_HM_HEADER_LENGTH, - ssl3_set_handshake_header, - ssl3_handshake_write -}; - -SSL3_ENC_METHOD TLSv1_2_enc_data = { - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF - | SSL_ENC_FLAG_TLS1_2_CIPHERS, - SSL3_HM_HEADER_LENGTH, - ssl3_set_handshake_header, - ssl3_handshake_write -}; - -long tls1_default_timeout(void) -{ - /* - * 2 hours, the 24 hours mentioned in the TLSv1 spec is way too long for - * http, the cache would over fill - */ - return (60 * 60 * 2); -} - -int tls1_new(SSL *s) -{ - if (!ssl3_new(s)) - return (0); - s->method->ssl_clear(s); - return (1); -} - -void tls1_free(SSL *s) -{ -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_session_ticket) { - OPENSSL_free(s->tlsext_session_ticket); - } -#endif /* OPENSSL_NO_TLSEXT */ - ssl3_free(s); -} - -void tls1_clear(SSL *s) -{ - ssl3_clear(s); - s->version = s->method->version; -} - -#ifndef OPENSSL_NO_EC - -static int nid_list[] = { - NID_sect163k1, /* sect163k1 (1) */ - NID_sect163r1, /* sect163r1 (2) */ - NID_sect163r2, /* sect163r2 (3) */ - NID_sect193r1, /* sect193r1 (4) */ - NID_sect193r2, /* sect193r2 (5) */ - NID_sect233k1, /* sect233k1 (6) */ - NID_sect233r1, /* sect233r1 (7) */ - NID_sect239k1, /* sect239k1 (8) */ - NID_sect283k1, /* sect283k1 (9) */ - NID_sect283r1, /* sect283r1 (10) */ - NID_sect409k1, /* sect409k1 (11) */ - NID_sect409r1, /* sect409r1 (12) */ - NID_sect571k1, /* sect571k1 (13) */ - NID_sect571r1, /* sect571r1 (14) */ - NID_secp160k1, /* secp160k1 (15) */ - NID_secp160r1, /* secp160r1 (16) */ - NID_secp160r2, /* secp160r2 (17) */ - NID_secp192k1, /* secp192k1 (18) */ - NID_X9_62_prime192v1, /* secp192r1 (19) */ - NID_secp224k1, /* secp224k1 (20) */ - NID_secp224r1, /* secp224r1 (21) */ - NID_secp256k1, /* secp256k1 (22) */ - NID_X9_62_prime256v1, /* secp256r1 (23) */ - NID_secp384r1, /* secp384r1 (24) */ - NID_secp521r1, /* secp521r1 (25) */ - NID_brainpoolP256r1, /* brainpoolP256r1 (26) */ - NID_brainpoolP384r1, /* brainpoolP384r1 (27) */ - NID_brainpoolP512r1 /* brainpool512r1 (28) */ -}; - -static const unsigned char ecformats_default[] = { - TLSEXT_ECPOINTFORMAT_uncompressed, - TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, - TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 -}; - -/* The client's default curves / the server's 'auto' curves. */ -static const unsigned char eccurves_auto[] = { - /* Prefer P-256 which has the fastest and most secure implementations. */ - 0, 23, /* secp256r1 (23) */ - /* Other >= 256-bit prime curves. */ - 0, 25, /* secp521r1 (25) */ - 0, 28, /* brainpool512r1 (28) */ - 0, 27, /* brainpoolP384r1 (27) */ - 0, 24, /* secp384r1 (24) */ - 0, 26, /* brainpoolP256r1 (26) */ - 0, 22, /* secp256k1 (22) */ -# ifndef OPENSSL_NO_EC2M - /* >= 256-bit binary curves. */ - 0, 14, /* sect571r1 (14) */ - 0, 13, /* sect571k1 (13) */ - 0, 11, /* sect409k1 (11) */ - 0, 12, /* sect409r1 (12) */ - 0, 9, /* sect283k1 (9) */ - 0, 10, /* sect283r1 (10) */ -# endif -}; - -static const unsigned char eccurves_all[] = { - /* Prefer P-256 which has the fastest and most secure implementations. */ - 0, 23, /* secp256r1 (23) */ - /* Other >= 256-bit prime curves. */ - 0, 25, /* secp521r1 (25) */ - 0, 28, /* brainpool512r1 (28) */ - 0, 27, /* brainpoolP384r1 (27) */ - 0, 24, /* secp384r1 (24) */ - 0, 26, /* brainpoolP256r1 (26) */ - 0, 22, /* secp256k1 (22) */ -# ifndef OPENSSL_NO_EC2M - /* >= 256-bit binary curves. */ - 0, 14, /* sect571r1 (14) */ - 0, 13, /* sect571k1 (13) */ - 0, 11, /* sect409k1 (11) */ - 0, 12, /* sect409r1 (12) */ - 0, 9, /* sect283k1 (9) */ - 0, 10, /* sect283r1 (10) */ -# endif - /* - * Remaining curves disabled by default but still permitted if set - * via an explicit callback or parameters. - */ - 0, 20, /* secp224k1 (20) */ - 0, 21, /* secp224r1 (21) */ - 0, 18, /* secp192k1 (18) */ - 0, 19, /* secp192r1 (19) */ - 0, 15, /* secp160k1 (15) */ - 0, 16, /* secp160r1 (16) */ - 0, 17, /* secp160r2 (17) */ -# ifndef OPENSSL_NO_EC2M - 0, 8, /* sect239k1 (8) */ - 0, 6, /* sect233k1 (6) */ - 0, 7, /* sect233r1 (7) */ - 0, 4, /* sect193r1 (4) */ - 0, 5, /* sect193r2 (5) */ - 0, 1, /* sect163k1 (1) */ - 0, 2, /* sect163r1 (2) */ - 0, 3, /* sect163r2 (3) */ -# endif -}; - -static const unsigned char suiteb_curves[] = { - 0, TLSEXT_curve_P_256, - 0, TLSEXT_curve_P_384 -}; - -# ifdef OPENSSL_FIPS -/* Brainpool not allowed in FIPS mode */ -static const unsigned char fips_curves_default[] = { -# ifndef OPENSSL_NO_EC2M - 0, 14, /* sect571r1 (14) */ - 0, 13, /* sect571k1 (13) */ -# endif - 0, 25, /* secp521r1 (25) */ -# ifndef OPENSSL_NO_EC2M - 0, 11, /* sect409k1 (11) */ - 0, 12, /* sect409r1 (12) */ -# endif - 0, 24, /* secp384r1 (24) */ -# ifndef OPENSSL_NO_EC2M - 0, 9, /* sect283k1 (9) */ - 0, 10, /* sect283r1 (10) */ -# endif - 0, 22, /* secp256k1 (22) */ - 0, 23, /* secp256r1 (23) */ -# ifndef OPENSSL_NO_EC2M - 0, 8, /* sect239k1 (8) */ - 0, 6, /* sect233k1 (6) */ - 0, 7, /* sect233r1 (7) */ -# endif - 0, 20, /* secp224k1 (20) */ - 0, 21, /* secp224r1 (21) */ -# ifndef OPENSSL_NO_EC2M - 0, 4, /* sect193r1 (4) */ - 0, 5, /* sect193r2 (5) */ -# endif - 0, 18, /* secp192k1 (18) */ - 0, 19, /* secp192r1 (19) */ -# ifndef OPENSSL_NO_EC2M - 0, 1, /* sect163k1 (1) */ - 0, 2, /* sect163r1 (2) */ - 0, 3, /* sect163r2 (3) */ -# endif - 0, 15, /* secp160k1 (15) */ - 0, 16, /* secp160r1 (16) */ - 0, 17, /* secp160r2 (17) */ -}; -# endif - -int tls1_ec_curve_id2nid(int curve_id) -{ - /* ECC curves from RFC 4492 and RFC 7027 */ - if ((curve_id < 1) || ((unsigned int)curve_id > - sizeof(nid_list) / sizeof(nid_list[0]))) - return 0; - return nid_list[curve_id - 1]; -} - -int tls1_ec_nid2curve_id(int nid) -{ - /* ECC curves from RFC 4492 and RFC 7027 */ - switch (nid) { - case NID_sect163k1: /* sect163k1 (1) */ - return 1; - case NID_sect163r1: /* sect163r1 (2) */ - return 2; - case NID_sect163r2: /* sect163r2 (3) */ - return 3; - case NID_sect193r1: /* sect193r1 (4) */ - return 4; - case NID_sect193r2: /* sect193r2 (5) */ - return 5; - case NID_sect233k1: /* sect233k1 (6) */ - return 6; - case NID_sect233r1: /* sect233r1 (7) */ - return 7; - case NID_sect239k1: /* sect239k1 (8) */ - return 8; - case NID_sect283k1: /* sect283k1 (9) */ - return 9; - case NID_sect283r1: /* sect283r1 (10) */ - return 10; - case NID_sect409k1: /* sect409k1 (11) */ - return 11; - case NID_sect409r1: /* sect409r1 (12) */ - return 12; - case NID_sect571k1: /* sect571k1 (13) */ - return 13; - case NID_sect571r1: /* sect571r1 (14) */ - return 14; - case NID_secp160k1: /* secp160k1 (15) */ - return 15; - case NID_secp160r1: /* secp160r1 (16) */ - return 16; - case NID_secp160r2: /* secp160r2 (17) */ - return 17; - case NID_secp192k1: /* secp192k1 (18) */ - return 18; - case NID_X9_62_prime192v1: /* secp192r1 (19) */ - return 19; - case NID_secp224k1: /* secp224k1 (20) */ - return 20; - case NID_secp224r1: /* secp224r1 (21) */ - return 21; - case NID_secp256k1: /* secp256k1 (22) */ - return 22; - case NID_X9_62_prime256v1: /* secp256r1 (23) */ - return 23; - case NID_secp384r1: /* secp384r1 (24) */ - return 24; - case NID_secp521r1: /* secp521r1 (25) */ - return 25; - case NID_brainpoolP256r1: /* brainpoolP256r1 (26) */ - return 26; - case NID_brainpoolP384r1: /* brainpoolP384r1 (27) */ - return 27; - case NID_brainpoolP512r1: /* brainpool512r1 (28) */ - return 28; - default: - return 0; - } -} - -/* - * Get curves list, if "sess" is set return client curves otherwise - * preferred list. - * Sets |num_curves| to the number of curves in the list, i.e., - * the length of |pcurves| is 2 * num_curves. - * Returns 1 on success and 0 if the client curves list has invalid format. - * The latter indicates an internal error: we should not be accepting such - * lists in the first place. - * TODO(emilia): we should really be storing the curves list in explicitly - * parsed form instead. (However, this would affect binary compatibility - * so cannot happen in the 1.0.x series.) - */ -static int tls1_get_curvelist(SSL *s, int sess, - const unsigned char **pcurves, - size_t *num_curves) -{ - size_t pcurveslen = 0; - if (sess) { - *pcurves = s->session->tlsext_ellipticcurvelist; - pcurveslen = s->session->tlsext_ellipticcurvelist_length; - } else { - /* For Suite B mode only include P-256, P-384 */ - switch (tls1_suiteb(s)) { - case SSL_CERT_FLAG_SUITEB_128_LOS: - *pcurves = suiteb_curves; - pcurveslen = sizeof(suiteb_curves); - break; - - case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: - *pcurves = suiteb_curves; - pcurveslen = 2; - break; - - case SSL_CERT_FLAG_SUITEB_192_LOS: - *pcurves = suiteb_curves + 2; - pcurveslen = 2; - break; - default: - *pcurves = s->tlsext_ellipticcurvelist; - pcurveslen = s->tlsext_ellipticcurvelist_length; - } - if (!*pcurves) { -# ifdef OPENSSL_FIPS - if (FIPS_mode()) { - *pcurves = fips_curves_default; - pcurveslen = sizeof(fips_curves_default); - } else -# endif - { - if (!s->server || s->cert->ecdh_tmp_auto) { - *pcurves = eccurves_auto; - pcurveslen = sizeof(eccurves_auto); - } else { - *pcurves = eccurves_all; - pcurveslen = sizeof(eccurves_all); - } - } - } - } - /* We do not allow odd length arrays to enter the system. */ - if (pcurveslen & 1) { - SSLerr(SSL_F_TLS1_GET_CURVELIST, ERR_R_INTERNAL_ERROR); - *num_curves = 0; - return 0; - } else { - *num_curves = pcurveslen / 2; - return 1; - } -} - -/* Check a curve is one of our preferences */ -int tls1_check_curve(SSL *s, const unsigned char *p, size_t len) -{ - const unsigned char *curves; - size_t num_curves, i; - unsigned int suiteb_flags = tls1_suiteb(s); - if (len != 3 || p[0] != NAMED_CURVE_TYPE) - return 0; - /* Check curve matches Suite B preferences */ - if (suiteb_flags) { - unsigned long cid = s->s3->tmp.new_cipher->id; - if (p[1]) - return 0; - if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) { - if (p[2] != TLSEXT_curve_P_256) - return 0; - } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) { - if (p[2] != TLSEXT_curve_P_384) - return 0; - } else /* Should never happen */ - return 0; - } - if (!tls1_get_curvelist(s, 0, &curves, &num_curves)) - return 0; - for (i = 0; i < num_curves; i++, curves += 2) { - if (p[1] == curves[0] && p[2] == curves[1]) - return 1; - } - return 0; -} - -/*- - * Return |nmatch|th shared curve or NID_undef if there is no match. - * For nmatch == -1, return number of matches - * For nmatch == -2, return the NID of the curve to use for - * an EC tmp key, or NID_undef if there is no match. - */ -int tls1_shared_curve(SSL *s, int nmatch) -{ - const unsigned char *pref, *supp; - size_t num_pref, num_supp, i, j; - int k; - /* Can't do anything on client side */ - if (s->server == 0) - return -1; - if (nmatch == -2) { - if (tls1_suiteb(s)) { - /* - * For Suite B ciphersuite determines curve: we already know - * these are acceptable due to previous checks. - */ - unsigned long cid = s->s3->tmp.new_cipher->id; - if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - return NID_X9_62_prime256v1; /* P-256 */ - if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - return NID_secp384r1; /* P-384 */ - /* Should never happen */ - return NID_undef; - } - /* If not Suite B just return first preference shared curve */ - nmatch = 0; - } - /* - * Avoid truncation. tls1_get_curvelist takes an int - * but s->options is a long... - */ - if (!tls1_get_curvelist - (s, (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0, &supp, - &num_supp)) - /* In practice, NID_undef == 0 but let's be precise. */ - return nmatch == -1 ? 0 : NID_undef; - if (!tls1_get_curvelist - (s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &pref, - &num_pref)) - return nmatch == -1 ? 0 : NID_undef; - - /* - * If the client didn't send the elliptic_curves extension all of them - * are allowed. - */ - if (num_supp == 0 && (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0) { - supp = eccurves_all; - num_supp = sizeof(eccurves_all) / 2; - } else if (num_pref == 0 && - (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0) { - pref = eccurves_all; - num_pref = sizeof(eccurves_all) / 2; - } - - k = 0; - for (i = 0; i < num_pref; i++, pref += 2) { - const unsigned char *tsupp = supp; - for (j = 0; j < num_supp; j++, tsupp += 2) { - if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) { - if (nmatch == k) { - int id = (pref[0] << 8) | pref[1]; - return tls1_ec_curve_id2nid(id); - } - k++; - } - } - } - if (nmatch == -1) - return k; - /* Out of range (nmatch > k). */ - return NID_undef; -} - -int tls1_set_curves(unsigned char **pext, size_t *pextlen, - int *curves, size_t ncurves) -{ - unsigned char *clist, *p; - size_t i; - /* - * Bitmap of curves included to detect duplicates: only works while curve - * ids < 32 - */ - unsigned long dup_list = 0; -# ifdef OPENSSL_NO_EC2M - EC_GROUP *curve; -# endif - - clist = OPENSSL_malloc(ncurves * 2); - if (!clist) - return 0; - for (i = 0, p = clist; i < ncurves; i++) { - unsigned long idmask; - int id; - id = tls1_ec_nid2curve_id(curves[i]); -# ifdef OPENSSL_FIPS - /* NB: 25 is last curve ID supported by FIPS module */ - if (FIPS_mode() && id > 25) { - OPENSSL_free(clist); - return 0; - } -# endif -# ifdef OPENSSL_NO_EC2M - curve = EC_GROUP_new_by_curve_name(curves[i]); - if (!curve || EC_METHOD_get_field_type(EC_GROUP_method_of(curve)) - == NID_X9_62_characteristic_two_field) { - if (curve) - EC_GROUP_free(curve); - OPENSSL_free(clist); - return 0; - } else - EC_GROUP_free(curve); -# endif - idmask = 1L << id; - if (!id || (dup_list & idmask)) { - OPENSSL_free(clist); - return 0; - } - dup_list |= idmask; - s2n(id, p); - } - if (*pext) - OPENSSL_free(*pext); - *pext = clist; - *pextlen = ncurves * 2; - return 1; -} - -# define MAX_CURVELIST 28 - -typedef struct { - size_t nidcnt; - int nid_arr[MAX_CURVELIST]; -} nid_cb_st; - -static int nid_cb(const char *elem, int len, void *arg) -{ - nid_cb_st *narg = arg; - size_t i; - int nid; - char etmp[20]; - if (elem == NULL) - return 0; - if (narg->nidcnt == MAX_CURVELIST) - return 0; - if (len > (int)(sizeof(etmp) - 1)) - return 0; - memcpy(etmp, elem, len); - etmp[len] = 0; - nid = EC_curve_nist2nid(etmp); - if (nid == NID_undef) - nid = OBJ_sn2nid(etmp); - if (nid == NID_undef) - nid = OBJ_ln2nid(etmp); - if (nid == NID_undef) - return 0; - for (i = 0; i < narg->nidcnt; i++) - if (narg->nid_arr[i] == nid) - return 0; - narg->nid_arr[narg->nidcnt++] = nid; - return 1; -} - -/* Set curves based on a colon separate list */ -int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, - const char *str) -{ - nid_cb_st ncb; - ncb.nidcnt = 0; - if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb)) - return 0; - if (pext == NULL) - return 1; - return tls1_set_curves(pext, pextlen, ncb.nid_arr, ncb.nidcnt); -} - -/* For an EC key set TLS id and required compression based on parameters */ -static int tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, - EC_KEY *ec) -{ - int is_prime, id; - const EC_GROUP *grp; - const EC_METHOD *meth; - if (!ec) - return 0; - /* Determine if it is a prime field */ - grp = EC_KEY_get0_group(ec); - if (!grp) - return 0; - meth = EC_GROUP_method_of(grp); - if (!meth) - return 0; - if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field) - is_prime = 1; - else - is_prime = 0; - /* Determine curve ID */ - id = EC_GROUP_get_curve_name(grp); - id = tls1_ec_nid2curve_id(id); - /* If we have an ID set it, otherwise set arbitrary explicit curve */ - if (id) { - curve_id[0] = 0; - curve_id[1] = (unsigned char)id; - } else { - curve_id[0] = 0xff; - if (is_prime) - curve_id[1] = 0x01; - else - curve_id[1] = 0x02; - } - if (comp_id) { - if (EC_KEY_get0_public_key(ec) == NULL) - return 0; - if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) { - if (is_prime) - *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; - else - *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; - } else - *comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; - } - return 1; -} - -/* Check an EC key is compatible with extensions */ -static int tls1_check_ec_key(SSL *s, - unsigned char *curve_id, unsigned char *comp_id) -{ - const unsigned char *pformats, *pcurves; - size_t num_formats, num_curves, i; - int j; - /* - * If point formats extension present check it, otherwise everything is - * supported (see RFC4492). - */ - if (comp_id && s->session->tlsext_ecpointformatlist) { - pformats = s->session->tlsext_ecpointformatlist; - num_formats = s->session->tlsext_ecpointformatlist_length; - for (i = 0; i < num_formats; i++, pformats++) { - if (*comp_id == *pformats) - break; - } - if (i == num_formats) - return 0; - } - if (!curve_id) - return 1; - /* Check curve is consistent with client and server preferences */ - for (j = 0; j <= 1; j++) { - if (!tls1_get_curvelist(s, j, &pcurves, &num_curves)) - return 0; - if (j == 1 && num_curves == 0) { - /* - * If we've not received any curves then skip this check. - * RFC 4492 does not require the supported elliptic curves extension - * so if it is not sent we can just choose any curve. - * It is invalid to send an empty list in the elliptic curves - * extension, so num_curves == 0 always means no extension. - */ - break; - } - for (i = 0; i < num_curves; i++, pcurves += 2) { - if (pcurves[0] == curve_id[0] && pcurves[1] == curve_id[1]) - break; - } - if (i == num_curves) - return 0; - /* For clients can only check sent curve list */ - if (!s->server) - return 1; - } - return 1; -} - -static void tls1_get_formatlist(SSL *s, const unsigned char **pformats, - size_t *num_formats) -{ - /* - * If we have a custom point format list use it otherwise use default - */ - if (s->tlsext_ecpointformatlist) { - *pformats = s->tlsext_ecpointformatlist; - *num_formats = s->tlsext_ecpointformatlist_length; - } else { - *pformats = ecformats_default; - /* For Suite B we don't support char2 fields */ - if (tls1_suiteb(s)) - *num_formats = sizeof(ecformats_default) - 1; - else - *num_formats = sizeof(ecformats_default); - } -} - -/* - * Check cert parameters compatible with extensions: currently just checks EC - * certificates have compatible curves and compression. - */ -static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) -{ - unsigned char comp_id, curve_id[2]; - EVP_PKEY *pkey; - int rv; - pkey = X509_get_pubkey(x); - if (!pkey) - return 0; - /* If not EC nothing to do */ - if (pkey->type != EVP_PKEY_EC) { - EVP_PKEY_free(pkey); - return 1; - } - rv = tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec); - EVP_PKEY_free(pkey); - if (!rv) - return 0; - /* - * Can't check curve_id for client certs as we don't have a supported - * curves extension. - */ - rv = tls1_check_ec_key(s, s->server ? curve_id : NULL, &comp_id); - if (!rv) - return 0; - /* - * Special case for suite B. We *MUST* sign using SHA256+P-256 or - * SHA384+P-384, adjust digest if necessary. - */ - if (set_ee_md && tls1_suiteb(s)) { - int check_md; - size_t i; - CERT *c = s->cert; - if (curve_id[0]) - return 0; - /* Check to see we have necessary signing algorithm */ - if (curve_id[1] == TLSEXT_curve_P_256) - check_md = NID_ecdsa_with_SHA256; - else if (curve_id[1] == TLSEXT_curve_P_384) - check_md = NID_ecdsa_with_SHA384; - else - return 0; /* Should never happen */ - for (i = 0; i < c->shared_sigalgslen; i++) - if (check_md == c->shared_sigalgs[i].signandhash_nid) - break; - if (i == c->shared_sigalgslen) - return 0; - if (set_ee_md == 2) { - if (check_md == NID_ecdsa_with_SHA256) - c->pkeys[SSL_PKEY_ECC].digest = EVP_sha256(); - else - c->pkeys[SSL_PKEY_ECC].digest = EVP_sha384(); - } - } - return rv; -} - -# ifndef OPENSSL_NO_ECDH -/* Check EC temporary key is compatible with client extensions */ -int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) -{ - unsigned char curve_id[2]; - EC_KEY *ec = s->cert->ecdh_tmp; -# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - /* Allow any curve: not just those peer supports */ - if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) - return 1; -# endif - /* - * If Suite B, AES128 MUST use P-256 and AES256 MUST use P-384, no other - * curves permitted. - */ - if (tls1_suiteb(s)) { - /* Curve to check determined by ciphersuite */ - if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - curve_id[1] = TLSEXT_curve_P_256; - else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - curve_id[1] = TLSEXT_curve_P_384; - else - return 0; - curve_id[0] = 0; - /* Check this curve is acceptable */ - if (!tls1_check_ec_key(s, curve_id, NULL)) - return 0; - /* If auto or setting curve from callback assume OK */ - if (s->cert->ecdh_tmp_auto || s->cert->ecdh_tmp_cb) - return 1; - /* Otherwise check curve is acceptable */ - else { - unsigned char curve_tmp[2]; - if (!ec) - return 0; - if (!tls1_set_ec_id(curve_tmp, NULL, ec)) - return 0; - if (!curve_tmp[0] || curve_tmp[1] == curve_id[1]) - return 1; - return 0; - } - - } - if (s->cert->ecdh_tmp_auto) { - /* Need a shared curve */ - if (tls1_shared_curve(s, 0)) - return 1; - else - return 0; - } - if (!ec) { - if (s->cert->ecdh_tmp_cb) - return 1; - else - return 0; - } - if (!tls1_set_ec_id(curve_id, NULL, ec)) - return 0; -/* Set this to allow use of invalid curves for testing */ -# if 0 - return 1; -# else - return tls1_check_ec_key(s, curve_id, NULL); -# endif -} -# endif /* OPENSSL_NO_ECDH */ - -#else - -static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) -{ - return 1; -} - -#endif /* OPENSSL_NO_EC */ - -#ifndef OPENSSL_NO_TLSEXT - -/* - * List of supported signature algorithms and hashes. Should make this - * customisable at some point, for now include everything we support. - */ - -# ifdef OPENSSL_NO_RSA -# define tlsext_sigalg_rsa(md) /* */ -# else -# define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa, -# endif - -# ifdef OPENSSL_NO_DSA -# define tlsext_sigalg_dsa(md) /* */ -# else -# define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa, -# endif - -# ifdef OPENSSL_NO_ECDSA -# define tlsext_sigalg_ecdsa(md) - /* */ -# else -# define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa, -# endif - -# define tlsext_sigalg(md) \ - tlsext_sigalg_rsa(md) \ - tlsext_sigalg_dsa(md) \ - tlsext_sigalg_ecdsa(md) - -static unsigned char tls12_sigalgs[] = { -# ifndef OPENSSL_NO_SHA512 - tlsext_sigalg(TLSEXT_hash_sha512) - tlsext_sigalg(TLSEXT_hash_sha384) -# endif -# ifndef OPENSSL_NO_SHA256 - tlsext_sigalg(TLSEXT_hash_sha256) - tlsext_sigalg(TLSEXT_hash_sha224) -# endif -# ifndef OPENSSL_NO_SHA - tlsext_sigalg(TLSEXT_hash_sha1) -# endif -}; - -# ifndef OPENSSL_NO_ECDSA -static unsigned char suiteb_sigalgs[] = { - tlsext_sigalg_ecdsa(TLSEXT_hash_sha256) - tlsext_sigalg_ecdsa(TLSEXT_hash_sha384) -}; -# endif -size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs) -{ - /* - * If Suite B mode use Suite B sigalgs only, ignore any other - * preferences. - */ -# ifndef OPENSSL_NO_EC - switch (tls1_suiteb(s)) { - case SSL_CERT_FLAG_SUITEB_128_LOS: - *psigs = suiteb_sigalgs; - return sizeof(suiteb_sigalgs); - - case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: - *psigs = suiteb_sigalgs; - return 2; - - case SSL_CERT_FLAG_SUITEB_192_LOS: - *psigs = suiteb_sigalgs + 2; - return 2; - } -# endif - /* If server use client authentication sigalgs if not NULL */ - if (s->server == sent && s->cert->client_sigalgs) { - *psigs = s->cert->client_sigalgs; - return s->cert->client_sigalgslen; - } else if (s->cert->conf_sigalgs) { - *psigs = s->cert->conf_sigalgs; - return s->cert->conf_sigalgslen; - } else { - *psigs = tls12_sigalgs; - return sizeof(tls12_sigalgs); - } -} - -/* - * Check signature algorithm is consistent with sent supported signature - * algorithms and if so return relevant digest. - */ -int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, - const unsigned char *sig, EVP_PKEY *pkey) -{ - const unsigned char *sent_sigs; - size_t sent_sigslen, i; - int sigalg = tls12_get_sigid(pkey); - /* Should never happen */ - if (sigalg == -1) - return -1; - /* Check key type is consistent with signature */ - if (sigalg != (int)sig[1]) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); - return 0; - } -# ifndef OPENSSL_NO_EC - if (pkey->type == EVP_PKEY_EC) { - unsigned char curve_id[2], comp_id; - /* Check compression and curve matches extensions */ - if (!tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec)) - return 0; - if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE); - return 0; - } - /* If Suite B only P-384+SHA384 or P-256+SHA-256 allowed */ - if (tls1_suiteb(s)) { - if (curve_id[0]) - return 0; - if (curve_id[1] == TLSEXT_curve_P_256) { - if (sig[0] != TLSEXT_hash_sha256) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_ILLEGAL_SUITEB_DIGEST); - return 0; - } - } else if (curve_id[1] == TLSEXT_curve_P_384) { - if (sig[0] != TLSEXT_hash_sha384) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_ILLEGAL_SUITEB_DIGEST); - return 0; - } - } else - return 0; - } - } else if (tls1_suiteb(s)) - return 0; -# endif - - /* Check signature matches a type we sent */ - sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); - for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) { - if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1]) - break; - } - /* Allow fallback to SHA1 if not strict mode */ - if (i == sent_sigslen - && (sig[0] != TLSEXT_hash_sha1 - || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); - return 0; - } - *pmd = tls12_get_hash(sig[0]); - if (*pmd == NULL) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST); - return 0; - } - /* - * Store the digest used so applications can retrieve it if they wish. - */ - if (s->session && s->session->sess_cert) - s->session->sess_cert->peer_key->digest = *pmd; - return 1; -} - -/* - * Get a mask of disabled algorithms: an algorithm is disabled if it isn't - * supported or doesn't appear in supported signature algorithms. Unlike - * ssl_cipher_get_disabled this applies to a specific session and not global - * settings. - */ -void ssl_set_client_disabled(SSL *s) -{ - CERT *c = s->cert; - const unsigned char *sigalgs; - size_t i, sigalgslen; - int have_rsa = 0, have_dsa = 0, have_ecdsa = 0; - c->mask_a = 0; - c->mask_k = 0; - /* Don't allow TLS 1.2 only ciphers if we don't suppport them */ - if (!SSL_CLIENT_USE_TLS1_2_CIPHERS(s)) - c->mask_ssl = SSL_TLSV1_2; - else - c->mask_ssl = 0; - /* - * Now go through all signature algorithms seeing if we support any for - * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2. - */ - sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs); - for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) { - switch (sigalgs[1]) { -# ifndef OPENSSL_NO_RSA - case TLSEXT_signature_rsa: - have_rsa = 1; - break; -# endif -# ifndef OPENSSL_NO_DSA - case TLSEXT_signature_dsa: - have_dsa = 1; - break; -# endif -# ifndef OPENSSL_NO_ECDSA - case TLSEXT_signature_ecdsa: - have_ecdsa = 1; - break; -# endif - } - } - /* - * Disable auth and static DH if we don't include any appropriate - * signature algorithms. - */ - if (!have_rsa) { - c->mask_a |= SSL_aRSA; - c->mask_k |= SSL_kDHr | SSL_kECDHr; - } - if (!have_dsa) { - c->mask_a |= SSL_aDSS; - c->mask_k |= SSL_kDHd; - } - if (!have_ecdsa) { - c->mask_a |= SSL_aECDSA; - c->mask_k |= SSL_kECDHe; - } -# ifndef OPENSSL_NO_KRB5 - if (!kssl_tgt_is_available(s->kssl_ctx)) { - c->mask_a |= SSL_aKRB5; - c->mask_k |= SSL_kKRB5; - } -# endif -# ifndef OPENSSL_NO_PSK - /* with PSK there must be client callback set */ - if (!s->psk_client_callback) { - c->mask_a |= SSL_aPSK; - c->mask_k |= SSL_kPSK; - } -# endif /* OPENSSL_NO_PSK */ -# ifndef OPENSSL_NO_SRP - if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) { - c->mask_a |= SSL_aSRP; - c->mask_k |= SSL_kSRP; - } -# endif - c->valid = 1; -} - -unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, - unsigned char *limit, int *al) -{ - int extdatalen = 0; - unsigned char *orig = buf; - unsigned char *ret = buf; -# ifndef OPENSSL_NO_EC - /* See if we support any ECC ciphersuites */ - int using_ecc = 0; - if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) { - int i; - unsigned long alg_k, alg_a; - STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s); - - for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) { - SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i); - - alg_k = c->algorithm_mkey; - alg_a = c->algorithm_auth; - if ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe) - || (alg_a & SSL_aECDSA))) { - using_ecc = 1; - break; - } - } - } -# endif - - /* don't add extensions for SSLv3 unless doing secure renegotiation */ - if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding) - return orig; - - ret += 2; - - if (ret >= limit) - return NULL; /* this really never occurs, but ... */ - - if (s->tlsext_hostname != NULL) { - /* Add TLS extension servername to the Client Hello message */ - size_t size_str; - - /*- - * check for enough space. - * 4 for the servername type and entension length - * 2 for servernamelist length - * 1 for the hostname type - * 2 for hostname length - * + hostname length - */ - size_str = strlen(s->tlsext_hostname); - if (CHECKLEN(ret, 9 + size_str, limit)) - return NULL; - - /* extension type and length */ - s2n(TLSEXT_TYPE_server_name, ret); - s2n(size_str + 5, ret); - - /* length of servername list */ - s2n(size_str + 3, ret); - - /* hostname type, length and hostname */ - *(ret++) = (unsigned char)TLSEXT_NAMETYPE_host_name; - s2n(size_str, ret); - memcpy(ret, s->tlsext_hostname, size_str); - ret += size_str; - } - - /* Add RI if renegotiating */ - if (s->renegotiate) { - int el; - - if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - if ((limit - ret - 4 - el) < 0) - return NULL; - - s2n(TLSEXT_TYPE_renegotiate, ret); - s2n(el, ret); - - if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - ret += el; - } -# ifndef OPENSSL_NO_SRP - /* Add SRP username if there is one */ - if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the - * Client Hello message */ - - size_t login_len = strlen(s->srp_ctx.login); - if (login_len > 255 || login_len == 0) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - /*- - * check for enough space. - * 4 for the srp type type and entension length - * 1 for the srp user identity - * + srp user identity length - */ - if (CHECKLEN(ret, 5 + login_len, limit)) - return NULL; - - /* fill in the extension */ - s2n(TLSEXT_TYPE_srp, ret); - s2n(login_len + 1, ret); - (*ret++) = (unsigned char)login_len; - memcpy(ret, s->srp_ctx.login, login_len); - ret += login_len; - } -# endif - -# ifndef OPENSSL_NO_EC - if (using_ecc) { - /* - * Add TLS extension ECPointFormats to the ClientHello message - */ - const unsigned char *pcurves, *pformats; - size_t num_curves, num_formats, curves_list_len; - - tls1_get_formatlist(s, &pformats, &num_formats); - - if (num_formats > 255) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - /*- - * check for enough space. - * 4 bytes for the ec point formats type and extension length - * 1 byte for the length of the formats - * + formats length - */ - if (CHECKLEN(ret, 5 + num_formats, limit)) - return NULL; - - s2n(TLSEXT_TYPE_ec_point_formats, ret); - /* The point format list has 1-byte length. */ - s2n(num_formats + 1, ret); - *(ret++) = (unsigned char)num_formats; - memcpy(ret, pformats, num_formats); - ret += num_formats; - - /* - * Add TLS extension EllipticCurves to the ClientHello message - */ - pcurves = s->tlsext_ellipticcurvelist; - if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) - return NULL; - - if (num_curves > 65532 / 2) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - curves_list_len = 2 * num_curves; - /*- - * check for enough space. - * 4 bytes for the ec curves type and extension length - * 2 bytes for the curve list length - * + curve list length - */ - if (CHECKLEN(ret, 6 + curves_list_len, limit)) - return NULL; - - s2n(TLSEXT_TYPE_elliptic_curves, ret); - s2n(curves_list_len + 2, ret); - s2n(curves_list_len, ret); - memcpy(ret, pcurves, curves_list_len); - ret += curves_list_len; - } -# endif /* OPENSSL_NO_EC */ - - if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { - size_t ticklen; - if (!s->new_session && s->session && s->session->tlsext_tick) - ticklen = s->session->tlsext_ticklen; - else if (s->session && s->tlsext_session_ticket && - s->tlsext_session_ticket->data) { - ticklen = s->tlsext_session_ticket->length; - s->session->tlsext_tick = OPENSSL_malloc(ticklen); - if (!s->session->tlsext_tick) - return NULL; - memcpy(s->session->tlsext_tick, - s->tlsext_session_ticket->data, ticklen); - s->session->tlsext_ticklen = ticklen; - } else - ticklen = 0; - if (ticklen == 0 && s->tlsext_session_ticket && - s->tlsext_session_ticket->data == NULL) - goto skip_ext; - /* - * Check for enough room 2 for extension type, 2 for len rest for - * ticket - */ - if (CHECKLEN(ret, 4 + ticklen, limit)) - return NULL; - s2n(TLSEXT_TYPE_session_ticket, ret); - s2n(ticklen, ret); - if (ticklen > 0) { - memcpy(ret, s->session->tlsext_tick, ticklen); - ret += ticklen; - } - } - skip_ext: - - if (SSL_CLIENT_USE_SIGALGS(s)) { - size_t salglen; - const unsigned char *salg; - salglen = tls12_get_psigalgs(s, 1, &salg); - - /*- - * check for enough space. - * 4 bytes for the sigalgs type and extension length - * 2 bytes for the sigalg list length - * + sigalg list length - */ - if (CHECKLEN(ret, salglen + 6, limit)) - return NULL; - s2n(TLSEXT_TYPE_signature_algorithms, ret); - s2n(salglen + 2, ret); - s2n(salglen, ret); - memcpy(ret, salg, salglen); - ret += salglen; - } -# ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->client_opaque_prf_input != NULL) { - size_t col = s->s3->client_opaque_prf_input_len; - - if ((long)(limit - ret - 6 - col < 0)) - return NULL; - if (col > 0xFFFD) /* can't happen */ - return NULL; - - s2n(TLSEXT_TYPE_opaque_prf_input, ret); - s2n(col + 2, ret); - s2n(col, ret); - memcpy(ret, s->s3->client_opaque_prf_input, col); - ret += col; - } -# endif - - if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { - int i; - size_t extlen, idlen; - int lentmp; - OCSP_RESPID *id; - - idlen = 0; - for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { - id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); - lentmp = i2d_OCSP_RESPID(id, NULL); - if (lentmp <= 0) - return NULL; - idlen += (size_t)lentmp + 2; - } - - if (s->tlsext_ocsp_exts) { - lentmp = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL); - if (lentmp < 0) - return NULL; - extlen = (size_t)lentmp; - } else - extlen = 0; - - if (extlen + idlen > 0xFFF0) - return NULL; - /* - * 2 bytes for status request type - * 2 bytes for status request len - * 1 byte for OCSP request type - * 2 bytes for length of ids - * 2 bytes for length of extensions - * + length of ids - * + length of extensions - */ - if (CHECKLEN(ret, 9 + idlen + extlen, limit)) - return NULL; - - s2n(TLSEXT_TYPE_status_request, ret); - s2n(extlen + idlen + 5, ret); - *(ret++) = TLSEXT_STATUSTYPE_ocsp; - s2n(idlen, ret); - for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { - /* save position of id len */ - unsigned char *q = ret; - id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); - /* skip over id len */ - ret += 2; - lentmp = i2d_OCSP_RESPID(id, &ret); - /* write id len */ - s2n(lentmp, q); - } - s2n(extlen, ret); - if (extlen > 0) - i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret); - } -# ifndef OPENSSL_NO_HEARTBEATS - /* Add Heartbeat extension */ - - /*- - * check for enough space. - * 4 bytes for the heartbeat ext type and extension length - * 1 byte for the mode - */ - if (CHECKLEN(ret, 5, limit)) - return NULL; - - s2n(TLSEXT_TYPE_heartbeat, ret); - s2n(1, ret); - /*- - * Set mode: - * 1: peer may send requests - * 2: peer not allowed to send requests - */ - if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS) - *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS; - else - *(ret++) = SSL_TLSEXT_HB_ENABLED; -# endif - -# ifndef OPENSSL_NO_NEXTPROTONEG - if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) { - /* - * The client advertises an emtpy extension to indicate its support - * for Next Protocol Negotiation - */ - - /*- - * check for enough space. - * 4 bytes for the NPN ext type and extension length - */ - if (CHECKLEN(ret, 4, limit)) - return NULL; - s2n(TLSEXT_TYPE_next_proto_neg, ret); - s2n(0, ret); - } -# endif - - if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) { - /*- - * check for enough space. - * 4 bytes for the ALPN type and extension length - * 2 bytes for the ALPN protocol list length - * + ALPN protocol list length - */ - if (CHECKLEN(ret, 6 + s->alpn_client_proto_list_len, limit)) - return NULL; - s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); - s2n(2 + s->alpn_client_proto_list_len, ret); - s2n(s->alpn_client_proto_list_len, ret); - memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len); - ret += s->alpn_client_proto_list_len; - s->cert->alpn_sent = 1; - } -# ifndef OPENSSL_NO_SRTP - if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { - int el; - - ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0); - - /*- - * check for enough space. - * 4 bytes for the SRTP type and extension length - * + SRTP profiles length - */ - if (CHECKLEN(ret, 4 + el, limit)) - return NULL; - - s2n(TLSEXT_TYPE_use_srtp, ret); - s2n(el, ret); - - if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - ret += el; - } -# endif - custom_ext_init(&s->cert->cli_ext); - /* Add custom TLS Extensions to ClientHello */ - if (!custom_ext_add(s, 0, &ret, limit, al)) - return NULL; - - /* - * Add padding to workaround bugs in F5 terminators. See - * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this - * code works out the length of all existing extensions it MUST always - * appear last. - */ - if (s->options & SSL_OP_TLSEXT_PADDING) { - int hlen = ret - (unsigned char *)s->init_buf->data; - /* - * The code in s23_clnt.c to build ClientHello messages includes the - * 5-byte record header in the buffer, while the code in s3_clnt.c - * does not. - */ - if (s->state == SSL23_ST_CW_CLNT_HELLO_A) - hlen -= 5; - if (hlen > 0xff && hlen < 0x200) { - hlen = 0x200 - hlen; - if (hlen >= 4) - hlen -= 4; - else - hlen = 0; - - /*- - * check for enough space. Strictly speaking we know we've already - * got enough space because to get here the message size is < 0x200, - * but we know that we've allocated far more than that in the buffer - * - but for consistency and robustness we're going to check anyway. - * - * 4 bytes for the padding type and extension length - * + padding length - */ - if (CHECKLEN(ret, 4 + hlen, limit)) - return NULL; - s2n(TLSEXT_TYPE_padding, ret); - s2n(hlen, ret); - memset(ret, 0, hlen); - ret += hlen; - } - } - - if ((extdatalen = ret - orig - 2) == 0) - return orig; - - s2n(extdatalen, orig); - return ret; -} - -unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, - unsigned char *limit, int *al) -{ - int extdatalen = 0; - unsigned char *orig = buf; - unsigned char *ret = buf; -# ifndef OPENSSL_NO_NEXTPROTONEG - int next_proto_neg_seen; -# endif -# ifndef OPENSSL_NO_EC - unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; - int using_ecc = (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) - || (alg_a & SSL_aECDSA); - using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL); -# endif - /* - * don't add extensions for SSLv3, unless doing secure renegotiation - */ - if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) - return orig; - - ret += 2; - if (ret >= limit) - return NULL; /* this really never occurs, but ... */ - - if (!s->hit && s->servername_done == 1 - && s->session->tlsext_hostname != NULL) { - if ((long)(limit - ret - 4) < 0) - return NULL; - - s2n(TLSEXT_TYPE_server_name, ret); - s2n(0, ret); - } - - if (s->s3->send_connection_binding) { - int el; - - if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - /*- - * check for enough space. - * 4 bytes for the reneg type and extension length - * + reneg data length - */ - if (CHECKLEN(ret, 4 + el, limit)) - return NULL; - - s2n(TLSEXT_TYPE_renegotiate, ret); - s2n(el, ret); - - if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - ret += el; - } -# ifndef OPENSSL_NO_EC - if (using_ecc) { - const unsigned char *plist; - size_t plistlen; - /* - * Add TLS extension ECPointFormats to the ServerHello message - */ - - tls1_get_formatlist(s, &plist, &plistlen); - - if (plistlen > 255) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - /*- - * check for enough space. - * 4 bytes for the ec points format type and extension length - * 1 byte for the points format list length - * + length of points format list - */ - if (CHECKLEN(ret, 5 + plistlen, limit)) - return NULL; - - s2n(TLSEXT_TYPE_ec_point_formats, ret); - s2n(plistlen + 1, ret); - *(ret++) = (unsigned char)plistlen; - memcpy(ret, plist, plistlen); - ret += plistlen; - - } - /* - * Currently the server should not respond with a SupportedCurves - * extension - */ -# endif /* OPENSSL_NO_EC */ - - if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) { - /*- - * check for enough space. - * 4 bytes for the Ticket type and extension length - */ - if (CHECKLEN(ret, 4, limit)) - return NULL; - s2n(TLSEXT_TYPE_session_ticket, ret); - s2n(0, ret); - } else { - /* if we don't add the above TLSEXT, we can't add a session ticket later */ - s->tlsext_ticket_expected = 0; - } - - if (s->tlsext_status_expected) { - /*- - * check for enough space. - * 4 bytes for the Status request type and extension length - */ - if (CHECKLEN(ret, 4, limit)) - return NULL; - s2n(TLSEXT_TYPE_status_request, ret); - s2n(0, ret); - } -# ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->server_opaque_prf_input != NULL) { - size_t sol = s->s3->server_opaque_prf_input_len; - - if ((long)(limit - ret - 6 - sol) < 0) - return NULL; - if (sol > 0xFFFD) /* can't happen */ - return NULL; - - s2n(TLSEXT_TYPE_opaque_prf_input, ret); - s2n(sol + 2, ret); - s2n(sol, ret); - memcpy(ret, s->s3->server_opaque_prf_input, sol); - ret += sol; - } -# endif - -# ifndef OPENSSL_NO_SRTP - if (SSL_IS_DTLS(s) && s->srtp_profile) { - int el; - - ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0); - - /*- - * check for enough space. - * 4 bytes for the SRTP profiles type and extension length - * + length of the SRTP profiles list - */ - if (CHECKLEN(ret, 4 + el, limit)) - return NULL; - - s2n(TLSEXT_TYPE_use_srtp, ret); - s2n(el, ret); - - if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - ret += el; - } -# endif - - if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80 - || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81) - && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) { - const unsigned char cryptopro_ext[36] = { - 0xfd, 0xe8, /* 65000 */ - 0x00, 0x20, /* 32 bytes length */ - 0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, - 0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06, - 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, - 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17 - }; - - /* check for enough space. */ - if (CHECKLEN(ret, sizeof(cryptopro_ext), limit)) - return NULL; - memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext)); - ret += sizeof(cryptopro_ext); - - } -# ifndef OPENSSL_NO_HEARTBEATS - /* Add Heartbeat extension if we've received one */ - if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) { - /*- - * check for enough space. - * 4 bytes for the Heartbeat type and extension length - * 1 byte for the mode - */ - if (CHECKLEN(ret, 5, limit)) - return NULL; - s2n(TLSEXT_TYPE_heartbeat, ret); - s2n(1, ret); - /*- - * Set mode: - * 1: peer may send requests - * 2: peer not allowed to send requests - */ - if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS) - *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS; - else - *(ret++) = SSL_TLSEXT_HB_ENABLED; - - } -# endif - -# ifndef OPENSSL_NO_NEXTPROTONEG - next_proto_neg_seen = s->s3->next_proto_neg_seen; - s->s3->next_proto_neg_seen = 0; - if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) { - const unsigned char *npa; - unsigned int npalen; - int r; - - r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, - s-> - ctx->next_protos_advertised_cb_arg); - if (r == SSL_TLSEXT_ERR_OK) { - /*- - * check for enough space. - * 4 bytes for the NPN type and extension length - * + length of protocols list - */ - if (CHECKLEN(ret, 4 + npalen, limit)) - return NULL; - s2n(TLSEXT_TYPE_next_proto_neg, ret); - s2n(npalen, ret); - memcpy(ret, npa, npalen); - ret += npalen; - s->s3->next_proto_neg_seen = 1; - } - } -# endif - if (!custom_ext_add(s, 1, &ret, limit, al)) - return NULL; - - if (s->s3->alpn_selected) { - const unsigned char *selected = s->s3->alpn_selected; - size_t len = s->s3->alpn_selected_len; - - /*- - * check for enough space. - * 4 bytes for the ALPN type and extension length - * 2 bytes for ALPN data length - * 1 byte for selected protocol length - * + length of the selected protocol - */ - if (CHECKLEN(ret, 7 + len, limit)) - return NULL; - s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); - s2n(3 + len, ret); - s2n(1 + len, ret); - *ret++ = len; - memcpy(ret, selected, len); - ret += len; - } - - if ((extdatalen = ret - orig - 2) == 0) - return orig; - - s2n(extdatalen, orig); - return ret; -} - -# ifndef OPENSSL_NO_EC -/*- - * ssl_check_for_safari attempts to fingerprint Safari using OS X - * SecureTransport using the TLS extension block in |d|, of length |n|. - * Safari, since 10.6, sends exactly these extensions, in this order: - * SNI, - * elliptic_curves - * ec_point_formats - * - * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8, - * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them. - * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from - * 10.8..10.8.3 (which don't work). - */ -static void ssl_check_for_safari(SSL *s, const unsigned char *data, - const unsigned char *limit) -{ - unsigned short type, size; - static const unsigned char kSafariExtensionsBlock[] = { - 0x00, 0x0a, /* elliptic_curves extension */ - 0x00, 0x08, /* 8 bytes */ - 0x00, 0x06, /* 6 bytes of curve ids */ - 0x00, 0x17, /* P-256 */ - 0x00, 0x18, /* P-384 */ - 0x00, 0x19, /* P-521 */ - - 0x00, 0x0b, /* ec_point_formats */ - 0x00, 0x02, /* 2 bytes */ - 0x01, /* 1 point format */ - 0x00, /* uncompressed */ - }; - - /* The following is only present in TLS 1.2 */ - static const unsigned char kSafariTLS12ExtensionsBlock[] = { - 0x00, 0x0d, /* signature_algorithms */ - 0x00, 0x0c, /* 12 bytes */ - 0x00, 0x0a, /* 10 bytes */ - 0x05, 0x01, /* SHA-384/RSA */ - 0x04, 0x01, /* SHA-256/RSA */ - 0x02, 0x01, /* SHA-1/RSA */ - 0x04, 0x03, /* SHA-256/ECDSA */ - 0x02, 0x03, /* SHA-1/ECDSA */ - }; - - if (limit - data <= 2) - return; - data += 2; - - if (limit - data < 4) - return; - n2s(data, type); - n2s(data, size); - - if (type != TLSEXT_TYPE_server_name) - return; - - if (limit - data < size) - return; - data += size; - - if (TLS1_get_client_version(s) >= TLS1_2_VERSION) { - const size_t len1 = sizeof(kSafariExtensionsBlock); - const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock); - - if (limit - data != (int)(len1 + len2)) - return; - if (memcmp(data, kSafariExtensionsBlock, len1) != 0) - return; - if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0) - return; - } else { - const size_t len = sizeof(kSafariExtensionsBlock); - - if (limit - data != (int)(len)) - return; - if (memcmp(data, kSafariExtensionsBlock, len) != 0) - return; - } - - s->s3->is_probably_safari = 1; -} -# endif /* !OPENSSL_NO_EC */ - -/* - * tls1_alpn_handle_client_hello is called to save the ALPN extension in a - * ClientHello. data: the contents of the extension, not including the type - * and length. data_len: the number of bytes in |data| al: a pointer to the - * alert value to send in the event of a non-zero return. returns: 0 on - * success. - */ -static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data, - unsigned data_len, int *al) -{ - unsigned i; - unsigned proto_len; - - if (data_len < 2) - goto parse_error; - - /* - * data should contain a uint16 length followed by a series of 8-bit, - * length-prefixed strings. - */ - i = ((unsigned)data[0]) << 8 | ((unsigned)data[1]); - data_len -= 2; - data += 2; - if (data_len != i) - goto parse_error; - - if (data_len < 2) - goto parse_error; - - for (i = 0; i < data_len;) { - proto_len = data[i]; - i++; - - if (proto_len == 0) - goto parse_error; - - if (i + proto_len < i || i + proto_len > data_len) - goto parse_error; - - i += proto_len; - } - - if (s->cert->alpn_proposed != NULL) - OPENSSL_free(s->cert->alpn_proposed); - s->cert->alpn_proposed = OPENSSL_malloc(data_len); - if (s->cert->alpn_proposed == NULL) { - *al = SSL_AD_INTERNAL_ERROR; - return -1; - } - memcpy(s->cert->alpn_proposed, data, data_len); - s->cert->alpn_proposed_len = data_len; - return 0; - - parse_error: - *al = SSL_AD_DECODE_ERROR; - return -1; -} - -/* - * Process the ALPN extension in a ClientHello. - * al: a pointer to the alert value to send in the event of a failure. - * returns 1 on success, 0 on failure: al set only on failure - */ -static int tls1_alpn_handle_client_hello_late(SSL *s, int *al) -{ - const unsigned char *selected = NULL; - unsigned char selected_len = 0; - - if (s->ctx->alpn_select_cb != NULL && s->cert->alpn_proposed != NULL) { - int r = s->ctx->alpn_select_cb(s, &selected, &selected_len, - s->cert->alpn_proposed, - s->cert->alpn_proposed_len, - s->ctx->alpn_select_cb_arg); - - if (r == SSL_TLSEXT_ERR_OK) { - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = OPENSSL_malloc(selected_len); - if (s->s3->alpn_selected == NULL) { - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } - memcpy(s->s3->alpn_selected, selected, selected_len); - s->s3->alpn_selected_len = selected_len; -# ifndef OPENSSL_NO_NEXTPROTONEG - /* ALPN takes precedence over NPN. */ - s->s3->next_proto_neg_seen = 0; -# endif - } - } - - return 1; -} - -static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, - unsigned char *limit, int *al) -{ - unsigned short type; - unsigned short size; - unsigned short len; - unsigned char *data = *p; - int renegotiate_seen = 0; - - s->servername_done = 0; - s->tlsext_status_type = -1; -# ifndef OPENSSL_NO_NEXTPROTONEG - s->s3->next_proto_neg_seen = 0; -# endif - - if (s->s3->alpn_selected) { - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = NULL; - } - s->s3->alpn_selected_len = 0; - if (s->cert->alpn_proposed) { - OPENSSL_free(s->cert->alpn_proposed); - s->cert->alpn_proposed = NULL; - } - s->cert->alpn_proposed_len = 0; -# ifndef OPENSSL_NO_HEARTBEATS - s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED | - SSL_TLSEXT_HB_DONT_SEND_REQUESTS); -# endif - -# ifndef OPENSSL_NO_EC - if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) - ssl_check_for_safari(s, data, limit); -# endif /* !OPENSSL_NO_EC */ - - /* Clear any signature algorithms extension received */ - if (s->cert->peer_sigalgs) { - OPENSSL_free(s->cert->peer_sigalgs); - s->cert->peer_sigalgs = NULL; - } -# ifndef OPENSSL_NO_SRP - if (s->srp_ctx.login != NULL) { - OPENSSL_free(s->srp_ctx.login); - s->srp_ctx.login = NULL; - } -# endif - - s->srtp_profile = NULL; - - if (data == limit) - goto ri_check; - - if (limit - data < 2) - goto err; - - n2s(data, len); - - if (limit - data != len) - goto err; - - while (limit - data >= 4) { - n2s(data, type); - n2s(data, size); - - if (limit - data < size) - goto err; -# if 0 - fprintf(stderr, "Received extension type %d size %d\n", type, size); -# endif - if (s->tlsext_debug_cb) - s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg); -/*- - * The servername extension is treated as follows: - * - * - Only the hostname type is supported with a maximum length of 255. - * - The servername is rejected if too long or if it contains zeros, - * in which case an fatal alert is generated. - * - The servername field is maintained together with the session cache. - * - When a session is resumed, the servername call back invoked in order - * to allow the application to position itself to the right context. - * - The servername is acknowledged if it is new for a session or when - * it is identical to a previously used for the same session. - * Applications can control the behaviour. They can at any time - * set a 'desirable' servername for a new SSL object. This can be the - * case for example with HTTPS when a Host: header field is received and - * a renegotiation is requested. In this case, a possible servername - * presented in the new client hello is only acknowledged if it matches - * the value of the Host: field. - * - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION - * if they provide for changing an explicit servername context for the - * session, i.e. when the session has been established with a servername - * extension. - * - On session reconnect, the servername extension may be absent. - * - */ - - if (type == TLSEXT_TYPE_server_name) { - unsigned char *sdata; - int servname_type; - int dsize; - - if (size < 2) - goto err; - n2s(data, dsize); - size -= 2; - if (dsize > size) - goto err; - - sdata = data; - while (dsize > 3) { - servname_type = *(sdata++); - n2s(sdata, len); - dsize -= 3; - - if (len > dsize) - goto err; - - if (s->servername_done == 0) - switch (servname_type) { - case TLSEXT_NAMETYPE_host_name: - if (!s->hit) { - if (s->session->tlsext_hostname) - goto err; - - if (len > TLSEXT_MAXLEN_host_name) { - *al = TLS1_AD_UNRECOGNIZED_NAME; - return 0; - } - if ((s->session->tlsext_hostname = - OPENSSL_malloc(len + 1)) == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - memcpy(s->session->tlsext_hostname, sdata, len); - s->session->tlsext_hostname[len] = '\0'; - if (strlen(s->session->tlsext_hostname) != len) { - OPENSSL_free(s->session->tlsext_hostname); - s->session->tlsext_hostname = NULL; - *al = TLS1_AD_UNRECOGNIZED_NAME; - return 0; - } - s->servername_done = 1; - - } else - s->servername_done = s->session->tlsext_hostname - && strlen(s->session->tlsext_hostname) == len - && strncmp(s->session->tlsext_hostname, - (char *)sdata, len) == 0; - - break; - - default: - break; - } - - dsize -= len; - } - if (dsize != 0) - goto err; - - } -# ifndef OPENSSL_NO_SRP - else if (type == TLSEXT_TYPE_srp) { - if (size == 0 || ((len = data[0])) != (size - 1)) - goto err; - if (s->srp_ctx.login != NULL) - goto err; - if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL) - return -1; - memcpy(s->srp_ctx.login, &data[1], len); - s->srp_ctx.login[len] = '\0'; - - if (strlen(s->srp_ctx.login) != len) - goto err; - } -# endif - -# ifndef OPENSSL_NO_EC - else if (type == TLSEXT_TYPE_ec_point_formats) { - unsigned char *sdata = data; - int ecpointformatlist_length = *(sdata++); - - if (ecpointformatlist_length != size - 1 || - ecpointformatlist_length < 1) - goto err; - if (!s->hit) { - if (s->session->tlsext_ecpointformatlist) { - OPENSSL_free(s->session->tlsext_ecpointformatlist); - s->session->tlsext_ecpointformatlist = NULL; - } - s->session->tlsext_ecpointformatlist_length = 0; - if ((s->session->tlsext_ecpointformatlist = - OPENSSL_malloc(ecpointformatlist_length)) == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - s->session->tlsext_ecpointformatlist_length = - ecpointformatlist_length; - memcpy(s->session->tlsext_ecpointformatlist, sdata, - ecpointformatlist_length); - } -# if 0 - fprintf(stderr, - "ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", - s->session->tlsext_ecpointformatlist_length); - sdata = s->session->tlsext_ecpointformatlist; - for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) - fprintf(stderr, "%i ", *(sdata++)); - fprintf(stderr, "\n"); -# endif - } else if (type == TLSEXT_TYPE_elliptic_curves) { - unsigned char *sdata = data; - int ellipticcurvelist_length = (*(sdata++) << 8); - ellipticcurvelist_length += (*(sdata++)); - - if (ellipticcurvelist_length != size - 2 || - ellipticcurvelist_length < 1 || - /* Each NamedCurve is 2 bytes. */ - ellipticcurvelist_length & 1) - goto err; - - if (!s->hit) { - if (s->session->tlsext_ellipticcurvelist) - goto err; - - s->session->tlsext_ellipticcurvelist_length = 0; - if ((s->session->tlsext_ellipticcurvelist = - OPENSSL_malloc(ellipticcurvelist_length)) == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - s->session->tlsext_ellipticcurvelist_length = - ellipticcurvelist_length; - memcpy(s->session->tlsext_ellipticcurvelist, sdata, - ellipticcurvelist_length); - } -# if 0 - fprintf(stderr, - "ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", - s->session->tlsext_ellipticcurvelist_length); - sdata = s->session->tlsext_ellipticcurvelist; - for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++) - fprintf(stderr, "%i ", *(sdata++)); - fprintf(stderr, "\n"); -# endif - } -# endif /* OPENSSL_NO_EC */ -# ifdef TLSEXT_TYPE_opaque_prf_input - else if (type == TLSEXT_TYPE_opaque_prf_input) { - unsigned char *sdata = data; - - if (size < 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - n2s(sdata, s->s3->client_opaque_prf_input_len); - if (s->s3->client_opaque_prf_input_len != size - 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - if (s->s3->client_opaque_prf_input != NULL) { - /* shouldn't really happen */ - OPENSSL_free(s->s3->client_opaque_prf_input); - } - - /* dummy byte just to get non-NULL */ - if (s->s3->client_opaque_prf_input_len == 0) - s->s3->client_opaque_prf_input = OPENSSL_malloc(1); - else - s->s3->client_opaque_prf_input = - BUF_memdup(sdata, s->s3->client_opaque_prf_input_len); - if (s->s3->client_opaque_prf_input == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - } -# endif - else if (type == TLSEXT_TYPE_session_ticket) { - if (s->tls_session_ticket_ext_cb && - !s->tls_session_ticket_ext_cb(s, data, size, - s->tls_session_ticket_ext_cb_arg)) - { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - } else if (type == TLSEXT_TYPE_renegotiate) { - if (!ssl_parse_clienthello_renegotiate_ext(s, data, size, al)) - return 0; - renegotiate_seen = 1; - } else if (type == TLSEXT_TYPE_signature_algorithms) { - int dsize; - if (s->cert->peer_sigalgs || size < 2) - goto err; - n2s(data, dsize); - size -= 2; - if (dsize != size || dsize & 1 || !dsize) - goto err; - if (!tls1_save_sigalgs(s, data, dsize)) - goto err; - } else if (type == TLSEXT_TYPE_status_request) { - - if (size < 5) - goto err; - - s->tlsext_status_type = *data++; - size--; - if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { - const unsigned char *sdata; - int dsize; - /* Read in responder_id_list */ - n2s(data, dsize); - size -= 2; - if (dsize > size) - goto err; - - /* - * We remove any OCSP_RESPIDs from a previous handshake - * to prevent unbounded memory growth - CVE-2016-6304 - */ - sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, - OCSP_RESPID_free); - if (dsize > 0) { - s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null(); - if (s->tlsext_ocsp_ids == NULL) { - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } - } else { - s->tlsext_ocsp_ids = NULL; - } - - while (dsize > 0) { - OCSP_RESPID *id; - int idsize; - if (dsize < 4) - goto err; - n2s(data, idsize); - dsize -= 2 + idsize; - size -= 2 + idsize; - if (dsize < 0) - goto err; - sdata = data; - data += idsize; - id = d2i_OCSP_RESPID(NULL, &sdata, idsize); - if (!id) - goto err; - if (data != sdata) { - OCSP_RESPID_free(id); - goto err; - } - if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) { - OCSP_RESPID_free(id); - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } - } - - /* Read in request_extensions */ - if (size < 2) - goto err; - n2s(data, dsize); - size -= 2; - if (dsize != size) - goto err; - sdata = data; - if (dsize > 0) { - if (s->tlsext_ocsp_exts) { - sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, - X509_EXTENSION_free); - } - - s->tlsext_ocsp_exts = - d2i_X509_EXTENSIONS(NULL, &sdata, dsize); - if (!s->tlsext_ocsp_exts || (data + dsize != sdata)) - goto err; - } - } - /* - * We don't know what to do with any other type * so ignore it. - */ - else - s->tlsext_status_type = -1; - } -# ifndef OPENSSL_NO_HEARTBEATS - else if (type == TLSEXT_TYPE_heartbeat) { - switch (data[0]) { - case 0x01: /* Client allows us to send HB requests */ - s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; - break; - case 0x02: /* Client doesn't accept HB requests */ - s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; - s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS; - break; - default: - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - } -# endif -# ifndef OPENSSL_NO_NEXTPROTONEG - else if (type == TLSEXT_TYPE_next_proto_neg && - s->s3->tmp.finish_md_len == 0) { - /*- - * We shouldn't accept this extension on a - * renegotiation. - * - * s->new_session will be set on renegotiation, but we - * probably shouldn't rely that it couldn't be set on - * the initial renegotation too in certain cases (when - * there's some other reason to disallow resuming an - * earlier session -- the current code won't be doing - * anything like that, but this might change). - * - * A valid sign that there's been a previous handshake - * in this connection is if s->s3->tmp.finish_md_len > - * 0. (We are talking about a check that will happen - * in the Hello protocol round, well before a new - * Finished message could have been computed.) - */ - s->s3->next_proto_neg_seen = 1; - } -# endif - - else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation && - s->s3->tmp.finish_md_len == 0) { - if (tls1_alpn_handle_client_hello(s, data, size, al) != 0) - return 0; - } - - /* session ticket processed earlier */ -# ifndef OPENSSL_NO_SRTP - else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s) - && type == TLSEXT_TYPE_use_srtp) { - if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al)) - return 0; - } -# endif - - data += size; - } - - /* Spurious data on the end */ - if (data != limit) - goto err; - - *p = data; - - ri_check: - - /* Need RI if renegotiating */ - - if (!renegotiate_seen && s->renegotiate && - !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { - *al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, - SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); - return 0; - } - - return 1; -err: - *al = SSL_AD_DECODE_ERROR; - return 0; -} - -/* - * Parse any custom extensions found. "data" is the start of the extension data - * and "limit" is the end of the record. TODO: add strict syntax checking. - */ - -static int ssl_scan_clienthello_custom_tlsext(SSL *s, - const unsigned char *data, - const unsigned char *limit, - int *al) -{ - unsigned short type, size, len; - /* If resumed session or no custom extensions nothing to do */ - if (s->hit || s->cert->srv_ext.meths_count == 0) - return 1; - - if (limit - data <= 2) - return 1; - n2s(data, len); - - if (limit - data < len) - return 1; - - while (limit - data >= 4) { - n2s(data, type); - n2s(data, size); - - if (limit - data < size) - return 1; - if (custom_ext_parse(s, 1 /* server */ , type, data, size, al) <= 0) - return 0; - - data += size; - } - - return 1; -} - -int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, - unsigned char *limit) -{ - int al = -1; - unsigned char *ptmp = *p; - /* - * Internally supported extensions are parsed first so SNI can be handled - * before custom extensions. An application processing SNI will typically - * switch the parent context using SSL_set_SSL_CTX and custom extensions - * need to be handled by the new SSL_CTX structure. - */ - if (ssl_scan_clienthello_tlsext(s, p, limit, &al) <= 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return 0; - } - - if (ssl_check_clienthello_tlsext_early(s) <= 0) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_CLIENTHELLO_TLSEXT); - return 0; - } - - custom_ext_init(&s->cert->srv_ext); - if (ssl_scan_clienthello_custom_tlsext(s, ptmp, limit, &al) <= 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return 0; - } - - return 1; -} - -# ifndef OPENSSL_NO_NEXTPROTONEG -/* - * ssl_next_proto_validate validates a Next Protocol Negotiation block. No - * elements of zero length are allowed and the set of elements must exactly - * fill the length of the block. - */ -static char ssl_next_proto_validate(unsigned char *d, unsigned len) -{ - unsigned int off = 0; - - while (off < len) { - if (d[off] == 0) - return 0; - off += d[off]; - off++; - } - - return off == len; -} -# endif - -static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, - unsigned char *d, int n, int *al) -{ - unsigned short length; - unsigned short type; - unsigned short size; - unsigned char *data = *p; - int tlsext_servername = 0; - int renegotiate_seen = 0; - -# ifndef OPENSSL_NO_NEXTPROTONEG - s->s3->next_proto_neg_seen = 0; -# endif - s->tlsext_ticket_expected = 0; - - if (s->s3->alpn_selected) { - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = NULL; - } -# ifndef OPENSSL_NO_HEARTBEATS - s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED | - SSL_TLSEXT_HB_DONT_SEND_REQUESTS); -# endif - - if ((d + n) - data <= 2) - goto ri_check; - - n2s(data, length); - if ((d + n) - data != length) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - while ((d + n) - data >= 4) { - n2s(data, type); - n2s(data, size); - - if ((d + n) - data < size) - goto ri_check; - - if (s->tlsext_debug_cb) - s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg); - - if (type == TLSEXT_TYPE_server_name) { - if (s->tlsext_hostname == NULL || size > 0) { - *al = TLS1_AD_UNRECOGNIZED_NAME; - return 0; - } - tlsext_servername = 1; - } -# ifndef OPENSSL_NO_EC - else if (type == TLSEXT_TYPE_ec_point_formats) { - unsigned char *sdata = data; - int ecpointformatlist_length = *(sdata++); - - if (ecpointformatlist_length != size - 1) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - if (!s->hit) { - s->session->tlsext_ecpointformatlist_length = 0; - if (s->session->tlsext_ecpointformatlist != NULL) - OPENSSL_free(s->session->tlsext_ecpointformatlist); - if ((s->session->tlsext_ecpointformatlist = - OPENSSL_malloc(ecpointformatlist_length)) == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - s->session->tlsext_ecpointformatlist_length = - ecpointformatlist_length; - memcpy(s->session->tlsext_ecpointformatlist, sdata, - ecpointformatlist_length); - } -# if 0 - fprintf(stderr, - "ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist "); - sdata = s->session->tlsext_ecpointformatlist; - for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) - fprintf(stderr, "%i ", *(sdata++)); - fprintf(stderr, "\n"); -# endif - } -# endif /* OPENSSL_NO_EC */ - - else if (type == TLSEXT_TYPE_session_ticket) { - if (s->tls_session_ticket_ext_cb && - !s->tls_session_ticket_ext_cb(s, data, size, - s->tls_session_ticket_ext_cb_arg)) - { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - if ((SSL_get_options(s) & SSL_OP_NO_TICKET) - || (size > 0)) { - *al = TLS1_AD_UNSUPPORTED_EXTENSION; - return 0; - } - s->tlsext_ticket_expected = 1; - } -# ifdef TLSEXT_TYPE_opaque_prf_input - else if (type == TLSEXT_TYPE_opaque_prf_input) { - unsigned char *sdata = data; - - if (size < 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - n2s(sdata, s->s3->server_opaque_prf_input_len); - if (s->s3->server_opaque_prf_input_len != size - 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - if (s->s3->server_opaque_prf_input != NULL) { - /* shouldn't really happen */ - OPENSSL_free(s->s3->server_opaque_prf_input); - } - if (s->s3->server_opaque_prf_input_len == 0) { - /* dummy byte just to get non-NULL */ - s->s3->server_opaque_prf_input = OPENSSL_malloc(1); - } else { - s->s3->server_opaque_prf_input = - BUF_memdup(sdata, s->s3->server_opaque_prf_input_len); - } - - if (s->s3->server_opaque_prf_input == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - } -# endif - else if (type == TLSEXT_TYPE_status_request) { - /* - * MUST be empty and only sent if we've requested a status - * request message. - */ - if ((s->tlsext_status_type == -1) || (size > 0)) { - *al = TLS1_AD_UNSUPPORTED_EXTENSION; - return 0; - } - /* Set flag to expect CertificateStatus message */ - s->tlsext_status_expected = 1; - } -# ifndef OPENSSL_NO_NEXTPROTONEG - else if (type == TLSEXT_TYPE_next_proto_neg && - s->s3->tmp.finish_md_len == 0) { - unsigned char *selected; - unsigned char selected_len; - - /* We must have requested it. */ - if (s->ctx->next_proto_select_cb == NULL) { - *al = TLS1_AD_UNSUPPORTED_EXTENSION; - return 0; - } - /* The data must be valid */ - if (!ssl_next_proto_validate(data, size)) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - if (s-> - ctx->next_proto_select_cb(s, &selected, &selected_len, data, - size, - s->ctx->next_proto_select_cb_arg) != - SSL_TLSEXT_ERR_OK) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - /* - * Could be non-NULL if server has sent multiple NPN extensions in - * a single Serverhello - */ - OPENSSL_free(s->next_proto_negotiated); - s->next_proto_negotiated = OPENSSL_malloc(selected_len); - if (!s->next_proto_negotiated) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - memcpy(s->next_proto_negotiated, selected, selected_len); - s->next_proto_negotiated_len = selected_len; - s->s3->next_proto_neg_seen = 1; - } -# endif - - else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) { - unsigned len; - - /* We must have requested it. */ - if (!s->cert->alpn_sent) { - *al = TLS1_AD_UNSUPPORTED_EXTENSION; - return 0; - } - if (size < 4) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - /*- - * The extension data consists of: - * uint16 list_length - * uint8 proto_length; - * uint8 proto[proto_length]; - */ - len = data[0]; - len <<= 8; - len |= data[1]; - if (len != (unsigned)size - 2) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - len = data[2]; - if (len != (unsigned)size - 3) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - if (s->s3->alpn_selected) - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = OPENSSL_malloc(len); - if (!s->s3->alpn_selected) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - memcpy(s->s3->alpn_selected, data + 3, len); - s->s3->alpn_selected_len = len; - } - - else if (type == TLSEXT_TYPE_renegotiate) { - if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) - return 0; - renegotiate_seen = 1; - } -# ifndef OPENSSL_NO_HEARTBEATS - else if (type == TLSEXT_TYPE_heartbeat) { - switch (data[0]) { - case 0x01: /* Server allows us to send HB requests */ - s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; - break; - case 0x02: /* Server doesn't accept HB requests */ - s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; - s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS; - break; - default: - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - } -# endif -# ifndef OPENSSL_NO_SRTP - else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { - if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al)) - return 0; - } -# endif - /* - * If this extension type was not otherwise handled, but matches a - * custom_cli_ext_record, then send it to the c callback - */ - else if (custom_ext_parse(s, 0, type, data, size, al) <= 0) - return 0; - - data += size; - } - - if (data != d + n) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - if (!s->hit && tlsext_servername == 1) { - if (s->tlsext_hostname) { - if (s->session->tlsext_hostname == NULL) { - s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname); - if (!s->session->tlsext_hostname) { - *al = SSL_AD_UNRECOGNIZED_NAME; - return 0; - } - } else { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - } - } - - *p = data; - - ri_check: - - /* - * Determine if we need to see RI. Strictly speaking if we want to avoid - * an attack we should *always* see RI even on initial server hello - * because the client doesn't see any renegotiation during an attack. - * However this would mean we could not connect to any server which - * doesn't support RI so for the immediate future tolerate RI absence on - * initial connect only. - */ - if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT) - && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { - *al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, - SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); - return 0; - } - - return 1; -} - -int ssl_prepare_clienthello_tlsext(SSL *s) -{ - -# ifdef TLSEXT_TYPE_opaque_prf_input - { - int r = 1; - - if (s->ctx->tlsext_opaque_prf_input_callback != 0) { - r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, - s-> - ctx->tlsext_opaque_prf_input_callback_arg); - if (!r) - return -1; - } - - if (s->tlsext_opaque_prf_input != NULL) { - if (s->s3->client_opaque_prf_input != NULL) { - /* shouldn't really happen */ - OPENSSL_free(s->s3->client_opaque_prf_input); - } - - if (s->tlsext_opaque_prf_input_len == 0) { - /* dummy byte just to get non-NULL */ - s->s3->client_opaque_prf_input = OPENSSL_malloc(1); - } else { - s->s3->client_opaque_prf_input = - BUF_memdup(s->tlsext_opaque_prf_input, - s->tlsext_opaque_prf_input_len); - } - if (s->s3->client_opaque_prf_input == NULL) { - SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT, - ERR_R_MALLOC_FAILURE); - return -1; - } - s->s3->client_opaque_prf_input_len = - s->tlsext_opaque_prf_input_len; - } - - if (r == 2) - /* - * at callback's request, insist on receiving an appropriate - * server opaque PRF input - */ - s->s3->server_opaque_prf_input_len = - s->tlsext_opaque_prf_input_len; - } -# endif - - s->cert->alpn_sent = 0; - return 1; -} - -int ssl_prepare_serverhello_tlsext(SSL *s) -{ - return 1; -} - -static int ssl_check_clienthello_tlsext_early(SSL *s) -{ - int ret = SSL_TLSEXT_ERR_NOACK; - int al = SSL_AD_UNRECOGNIZED_NAME; - -# ifndef OPENSSL_NO_EC - /* - * The handling of the ECPointFormats extension is done elsewhere, namely - * in ssl3_choose_cipher in s3_lib.c. - */ - /* - * The handling of the EllipticCurves extension is done elsewhere, namely - * in ssl3_choose_cipher in s3_lib.c. - */ -# endif - - if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) - ret = - s->ctx->tlsext_servername_callback(s, &al, - s->ctx->tlsext_servername_arg); - else if (s->initial_ctx != NULL - && s->initial_ctx->tlsext_servername_callback != 0) - ret = - s->initial_ctx->tlsext_servername_callback(s, &al, - s-> - initial_ctx->tlsext_servername_arg); - -# ifdef TLSEXT_TYPE_opaque_prf_input - { - /* - * This sort of belongs into ssl_prepare_serverhello_tlsext(), but we - * might be sending an alert in response to the client hello, so this - * has to happen here in ssl_check_clienthello_tlsext_early(). - */ - - int r = 1; - - if (s->ctx->tlsext_opaque_prf_input_callback != 0) { - r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, - s-> - ctx->tlsext_opaque_prf_input_callback_arg); - if (!r) { - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_INTERNAL_ERROR; - goto err; - } - } - - if (s->s3->server_opaque_prf_input != NULL) { - /* shouldn't really happen */ - OPENSSL_free(s->s3->server_opaque_prf_input); - } - s->s3->server_opaque_prf_input = NULL; - - if (s->tlsext_opaque_prf_input != NULL) { - if (s->s3->client_opaque_prf_input != NULL && - s->s3->client_opaque_prf_input_len == - s->tlsext_opaque_prf_input_len) { - /* - * can only use this extension if we have a server opaque PRF - * input of the same length as the client opaque PRF input! - */ - - if (s->tlsext_opaque_prf_input_len == 0) { - /* dummy byte just to get non-NULL */ - s->s3->server_opaque_prf_input = OPENSSL_malloc(1); - } else { - s->s3->server_opaque_prf_input = - BUF_memdup(s->tlsext_opaque_prf_input, - s->tlsext_opaque_prf_input_len); - } - if (s->s3->server_opaque_prf_input == NULL) { - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_INTERNAL_ERROR; - goto err; - } - s->s3->server_opaque_prf_input_len = - s->tlsext_opaque_prf_input_len; - } - } - - if (r == 2 && s->s3->server_opaque_prf_input == NULL) { - /* - * The callback wants to enforce use of the extension, but we - * can't do that with the client opaque PRF input; abort the - * handshake. - */ - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_HANDSHAKE_FAILURE; - } - } - - err: -# endif - switch (ret) { - case SSL_TLSEXT_ERR_ALERT_FATAL: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return -1; - - case SSL_TLSEXT_ERR_ALERT_WARNING: - ssl3_send_alert(s, SSL3_AL_WARNING, al); - return 1; - - case SSL_TLSEXT_ERR_NOACK: - s->servername_done = 0; - default: - return 1; - } -} - -int tls1_set_server_sigalgs(SSL *s) -{ - int al; - size_t i; - /* Clear any shared sigtnature algorithms */ - if (s->cert->shared_sigalgs) { - OPENSSL_free(s->cert->shared_sigalgs); - s->cert->shared_sigalgs = NULL; - s->cert->shared_sigalgslen = 0; - } - /* Clear certificate digests and validity flags */ - for (i = 0; i < SSL_PKEY_NUM; i++) { - s->cert->pkeys[i].digest = NULL; - s->cert->pkeys[i].valid_flags = 0; - } - - /* If sigalgs received process it. */ - if (s->cert->peer_sigalgs) { - if (!tls1_process_sigalgs(s)) { - SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE); - al = SSL_AD_INTERNAL_ERROR; - goto err; - } - /* Fatal error is no shared signature algorithms */ - if (!s->cert->shared_sigalgs) { - SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, - SSL_R_NO_SHARED_SIGATURE_ALGORITHMS); - al = SSL_AD_ILLEGAL_PARAMETER; - goto err; - } - } else - ssl_cert_set_default_md(s->cert); - return 1; - err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return 0; -} - -/* - * Upon success, returns 1. - * Upon failure, returns 0 and sets |al| to the appropriate fatal alert. - */ -int ssl_check_clienthello_tlsext_late(SSL *s, int *al) -{ - - /* - * If status request then ask callback what to do. Note: this must be - * called after servername callbacks in case the certificate has changed, - * and must be called after the cipher has been chosen because this may - * influence which certificate is sent - */ - if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) { - int ret; - CERT_PKEY *certpkey; - certpkey = ssl_get_server_send_pkey(s); - /* If no certificate can't return certificate status */ - if (certpkey != NULL) { - /* - * Set current certificate to one we will use so SSL_get_certificate - * et al can pick it up. - */ - s->cert->key = certpkey; - ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); - switch (ret) { - /* We don't want to send a status request response */ - case SSL_TLSEXT_ERR_NOACK: - s->tlsext_status_expected = 0; - break; - /* status request response should be sent */ - case SSL_TLSEXT_ERR_OK: - if (s->tlsext_ocsp_resp) - s->tlsext_status_expected = 1; - break; - /* something bad happened */ - case SSL_TLSEXT_ERR_ALERT_FATAL: - default: - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } - } - } - - if (!tls1_alpn_handle_client_hello_late(s, al)) { - return 0; - } - - return 1; -} - -int ssl_check_serverhello_tlsext(SSL *s) -{ - int ret = SSL_TLSEXT_ERR_NOACK; - int al = SSL_AD_UNRECOGNIZED_NAME; - -# ifndef OPENSSL_NO_EC - /* - * If we are client and using an elliptic curve cryptography cipher - * suite, then if server returns an EC point formats lists extension it - * must contain uncompressed. - */ - unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; - if ((s->tlsext_ecpointformatlist != NULL) - && (s->tlsext_ecpointformatlist_length > 0) - && (s->session->tlsext_ecpointformatlist != NULL) - && (s->session->tlsext_ecpointformatlist_length > 0) - && ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) - || (alg_a & SSL_aECDSA))) { - /* we are using an ECC cipher */ - size_t i; - unsigned char *list; - int found_uncompressed = 0; - list = s->session->tlsext_ecpointformatlist; - for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) { - if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) { - found_uncompressed = 1; - break; - } - } - if (!found_uncompressed) { - SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT, - SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); - return -1; - } - } - ret = SSL_TLSEXT_ERR_OK; -# endif /* OPENSSL_NO_EC */ - - if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) - ret = - s->ctx->tlsext_servername_callback(s, &al, - s->ctx->tlsext_servername_arg); - else if (s->initial_ctx != NULL - && s->initial_ctx->tlsext_servername_callback != 0) - ret = - s->initial_ctx->tlsext_servername_callback(s, &al, - s-> - initial_ctx->tlsext_servername_arg); - -# ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->server_opaque_prf_input_len > 0) { - /* - * This case may indicate that we, as a client, want to insist on - * using opaque PRF inputs. So first verify that we really have a - * value from the server too. - */ - - if (s->s3->server_opaque_prf_input == NULL) { - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_HANDSHAKE_FAILURE; - } - - /* - * Anytime the server *has* sent an opaque PRF input, we need to - * check that we have a client opaque PRF input of the same size. - */ - if (s->s3->client_opaque_prf_input == NULL || - s->s3->client_opaque_prf_input_len != - s->s3->server_opaque_prf_input_len) { - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_ILLEGAL_PARAMETER; - } - } -# endif - - OPENSSL_free(s->tlsext_ocsp_resp); - s->tlsext_ocsp_resp = NULL; - s->tlsext_ocsp_resplen = -1; - /* - * If we've requested certificate status and we wont get one tell the - * callback - */ - if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected) - && !(s->hit) && s->ctx && s->ctx->tlsext_status_cb) { - int r; - /* - * Call callback with resp == NULL and resplen == -1 so callback - * knows there is no response - */ - r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); - if (r == 0) { - al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - } - if (r < 0) { - al = SSL_AD_INTERNAL_ERROR; - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - } - } - - switch (ret) { - case SSL_TLSEXT_ERR_ALERT_FATAL: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return -1; - - case SSL_TLSEXT_ERR_ALERT_WARNING: - ssl3_send_alert(s, SSL3_AL_WARNING, al); - return 1; - - case SSL_TLSEXT_ERR_NOACK: - s->servername_done = 0; - default: - return 1; - } -} - -int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, - int n) -{ - int al = -1; - if (s->version < SSL3_VERSION) - return 1; - if (ssl_scan_serverhello_tlsext(s, p, d, n, &al) <= 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return 0; - } - - if (ssl_check_serverhello_tlsext(s) <= 0) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_SERVERHELLO_TLSEXT); - return 0; - } - return 1; -} - -/*- - * Since the server cache lookup is done early on in the processing of the - * ClientHello, and other operations depend on the result, we need to handle - * any TLS session ticket extension at the same time. - * - * session_id: points at the session ID in the ClientHello. This code will - * read past the end of this in order to parse out the session ticket - * extension, if any. - * len: the length of the session ID. - * limit: a pointer to the first byte after the ClientHello. - * ret: (output) on return, if a ticket was decrypted, then this is set to - * point to the resulting session. - * - * If s->tls_session_secret_cb is set then we are expecting a pre-shared key - * ciphersuite, in which case we have no use for session tickets and one will - * never be decrypted, nor will s->tlsext_ticket_expected be set to 1. - * - * Returns: - * -1: fatal error, either from parsing or decrypting the ticket. - * 0: no ticket was found (or was ignored, based on settings). - * 1: a zero length extension was found, indicating that the client supports - * session tickets but doesn't currently have one to offer. - * 2: either s->tls_session_secret_cb was set, or a ticket was offered but - * couldn't be decrypted because of a non-fatal error. - * 3: a ticket was successfully decrypted and *ret was set. - * - * Side effects: - * Sets s->tlsext_ticket_expected to 1 if the server will have to issue - * a new session ticket to the client because the client indicated support - * (and s->tls_session_secret_cb is NULL) but the client either doesn't have - * a session ticket or we couldn't use the one it gave us, or if - * s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket. - * Otherwise, s->tlsext_ticket_expected is set to 0. - */ -int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, - const unsigned char *limit, SSL_SESSION **ret) -{ - /* Point after session ID in client hello */ - const unsigned char *p = session_id + len; - unsigned short i; - - *ret = NULL; - s->tlsext_ticket_expected = 0; - - /* - * If tickets disabled behave as if no ticket present to permit stateful - * resumption. - */ - if (SSL_get_options(s) & SSL_OP_NO_TICKET) - return 0; - if ((s->version <= SSL3_VERSION) || !limit) - return 0; - if (p >= limit) - return -1; - /* Skip past DTLS cookie */ - if (SSL_IS_DTLS(s)) { - i = *(p++); - - if (limit - p <= i) - return -1; - - p += i; - } - /* Skip past cipher list */ - n2s(p, i); - if (limit - p <= i) - return -1; - p += i; - - /* Skip past compression algorithm list */ - i = *(p++); - if (limit - p < i) - return -1; - p += i; - - /* Now at start of extensions */ - if (limit - p <= 2) - return 0; - n2s(p, i); - while (limit - p >= 4) { - unsigned short type, size; - n2s(p, type); - n2s(p, size); - if (limit - p < size) - return 0; - if (type == TLSEXT_TYPE_session_ticket) { - int r; - if (size == 0) { - /* - * The client will accept a ticket but doesn't currently have - * one. - */ - s->tlsext_ticket_expected = 1; - return 1; - } - if (s->tls_session_secret_cb) { - /* - * Indicate that the ticket couldn't be decrypted rather than - * generating the session from ticket now, trigger - * abbreviated handshake based on external mechanism to - * calculate the master secret later. - */ - return 2; - } - r = tls_decrypt_ticket(s, p, size, session_id, len, ret); - switch (r) { - case 2: /* ticket couldn't be decrypted */ - s->tlsext_ticket_expected = 1; - return 2; - case 3: /* ticket was decrypted */ - return r; - case 4: /* ticket decrypted but need to renew */ - s->tlsext_ticket_expected = 1; - return 3; - default: /* fatal error */ - return -1; - } - } - p += size; - } - return 0; -} - -/*- - * tls_decrypt_ticket attempts to decrypt a session ticket. - * - * etick: points to the body of the session ticket extension. - * eticklen: the length of the session tickets extenion. - * sess_id: points at the session ID. - * sesslen: the length of the session ID. - * psess: (output) on return, if a ticket was decrypted, then this is set to - * point to the resulting session. - * - * Returns: - * -1: fatal error, either from parsing or decrypting the ticket. - * 2: the ticket couldn't be decrypted. - * 3: a ticket was successfully decrypted and *psess was set. - * 4: same as 3, but the ticket needs to be renewed. - */ -static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, - int eticklen, const unsigned char *sess_id, - int sesslen, SSL_SESSION **psess) -{ - SSL_SESSION *sess; - unsigned char *sdec; - const unsigned char *p; - int slen, mlen, renew_ticket = 0; - unsigned char tick_hmac[EVP_MAX_MD_SIZE]; - HMAC_CTX hctx; - EVP_CIPHER_CTX ctx; - SSL_CTX *tctx = s->initial_ctx; - - /* Initialize session ticket encryption and HMAC contexts */ - HMAC_CTX_init(&hctx); - EVP_CIPHER_CTX_init(&ctx); - if (tctx->tlsext_ticket_key_cb) { - unsigned char *nctick = (unsigned char *)etick; - int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, - &ctx, &hctx, 0); - if (rv < 0) - return -1; - if (rv == 0) - return 2; - if (rv == 2) - renew_ticket = 1; - } else { - /* Check key name matches */ - if (memcmp(etick, tctx->tlsext_tick_key_name, 16)) - return 2; - if (HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, - tlsext_tick_md(), NULL) <= 0 - || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, - tctx->tlsext_tick_aes_key, - etick + 16) <= 0) { - goto err; - } - } - /* - * Attempt to process session ticket, first conduct sanity and integrity - * checks on ticket. - */ - mlen = HMAC_size(&hctx); - if (mlen < 0) { - goto err; - } - /* Sanity check ticket length: must exceed keyname + IV + HMAC */ - if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) { - HMAC_CTX_cleanup(&hctx); - EVP_CIPHER_CTX_cleanup(&ctx); - return 2; - } - - eticklen -= mlen; - /* Check HMAC of encrypted ticket */ - if (HMAC_Update(&hctx, etick, eticklen) <= 0 - || HMAC_Final(&hctx, tick_hmac, NULL) <= 0) { - goto err; - } - HMAC_CTX_cleanup(&hctx); - if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) { - EVP_CIPHER_CTX_cleanup(&ctx); - return 2; - } - /* Attempt to decrypt session data */ - /* Move p after IV to start of encrypted ticket, update length */ - p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); - eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx); - sdec = OPENSSL_malloc(eticklen); - if (sdec == NULL - || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) { - EVP_CIPHER_CTX_cleanup(&ctx); - OPENSSL_free(sdec); - return -1; - } - if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) { - EVP_CIPHER_CTX_cleanup(&ctx); - OPENSSL_free(sdec); - return 2; - } - slen += mlen; - EVP_CIPHER_CTX_cleanup(&ctx); - p = sdec; - - sess = d2i_SSL_SESSION(NULL, &p, slen); - slen -= p - sdec; - OPENSSL_free(sdec); - if (sess) { - /* Some additional consistency checks */ - if (slen != 0 || sess->session_id_length != 0) { - SSL_SESSION_free(sess); - return 2; - } - /* - * The session ID, if non-empty, is used by some clients to detect - * that the ticket has been accepted. So we copy it to the session - * structure. If it is empty set length to zero as required by - * standard. - */ - if (sesslen) - memcpy(sess->session_id, sess_id, sesslen); - sess->session_id_length = sesslen; - *psess = sess; - if (renew_ticket) - return 4; - else - return 3; - } - ERR_clear_error(); - /* - * For session parse failure, indicate that we need to send a new ticket. - */ - return 2; -err: - EVP_CIPHER_CTX_cleanup(&ctx); - HMAC_CTX_cleanup(&hctx); - return -1; -} - -/* Tables to translate from NIDs to TLS v1.2 ids */ - -typedef struct { - int nid; - int id; -} tls12_lookup; - -static tls12_lookup tls12_md[] = { - {NID_md5, TLSEXT_hash_md5}, - {NID_sha1, TLSEXT_hash_sha1}, - {NID_sha224, TLSEXT_hash_sha224}, - {NID_sha256, TLSEXT_hash_sha256}, - {NID_sha384, TLSEXT_hash_sha384}, - {NID_sha512, TLSEXT_hash_sha512} -}; - -static tls12_lookup tls12_sig[] = { - {EVP_PKEY_RSA, TLSEXT_signature_rsa}, - {EVP_PKEY_DSA, TLSEXT_signature_dsa}, - {EVP_PKEY_EC, TLSEXT_signature_ecdsa} -}; - -static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen) -{ - size_t i; - for (i = 0; i < tlen; i++) { - if (table[i].nid == nid) - return table[i].id; - } - return -1; -} - -static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen) -{ - size_t i; - for (i = 0; i < tlen; i++) { - if ((table[i].id) == id) - return table[i].nid; - } - return NID_undef; -} - -int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, - const EVP_MD *md) -{ - int sig_id, md_id; - if (!md) - return 0; - md_id = tls12_find_id(EVP_MD_type(md), tls12_md, - sizeof(tls12_md) / sizeof(tls12_lookup)); - if (md_id == -1) - return 0; - sig_id = tls12_get_sigid(pk); - if (sig_id == -1) - return 0; - p[0] = (unsigned char)md_id; - p[1] = (unsigned char)sig_id; - return 1; -} - -int tls12_get_sigid(const EVP_PKEY *pk) -{ - return tls12_find_id(pk->type, tls12_sig, - sizeof(tls12_sig) / sizeof(tls12_lookup)); -} - -const EVP_MD *tls12_get_hash(unsigned char hash_alg) -{ - switch (hash_alg) { -# ifndef OPENSSL_NO_MD5 - case TLSEXT_hash_md5: -# ifdef OPENSSL_FIPS - if (FIPS_mode()) - return NULL; -# endif - return EVP_md5(); -# endif -# ifndef OPENSSL_NO_SHA - case TLSEXT_hash_sha1: - return EVP_sha1(); -# endif -# ifndef OPENSSL_NO_SHA256 - case TLSEXT_hash_sha224: - return EVP_sha224(); - - case TLSEXT_hash_sha256: - return EVP_sha256(); -# endif -# ifndef OPENSSL_NO_SHA512 - case TLSEXT_hash_sha384: - return EVP_sha384(); - - case TLSEXT_hash_sha512: - return EVP_sha512(); -# endif - default: - return NULL; - - } -} - -static int tls12_get_pkey_idx(unsigned char sig_alg) -{ - switch (sig_alg) { -# ifndef OPENSSL_NO_RSA - case TLSEXT_signature_rsa: - return SSL_PKEY_RSA_SIGN; -# endif -# ifndef OPENSSL_NO_DSA - case TLSEXT_signature_dsa: - return SSL_PKEY_DSA_SIGN; -# endif -# ifndef OPENSSL_NO_ECDSA - case TLSEXT_signature_ecdsa: - return SSL_PKEY_ECC; -# endif - } - return -1; -} - -/* Convert TLS 1.2 signature algorithm extension values into NIDs */ -static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid, - int *psignhash_nid, const unsigned char *data) -{ - int sign_nid = NID_undef, hash_nid = NID_undef; - if (!phash_nid && !psign_nid && !psignhash_nid) - return; - if (phash_nid || psignhash_nid) { - hash_nid = tls12_find_nid(data[0], tls12_md, - sizeof(tls12_md) / sizeof(tls12_lookup)); - if (phash_nid) - *phash_nid = hash_nid; - } - if (psign_nid || psignhash_nid) { - sign_nid = tls12_find_nid(data[1], tls12_sig, - sizeof(tls12_sig) / sizeof(tls12_lookup)); - if (psign_nid) - *psign_nid = sign_nid; - } - if (psignhash_nid) { - if (sign_nid == NID_undef || hash_nid == NID_undef - || OBJ_find_sigid_by_algs(psignhash_nid, hash_nid, - sign_nid) <= 0) - *psignhash_nid = NID_undef; - } -} - -/* Given preference and allowed sigalgs set shared sigalgs */ -static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig, - const unsigned char *pref, size_t preflen, - const unsigned char *allow, - size_t allowlen) -{ - const unsigned char *ptmp, *atmp; - size_t i, j, nmatch = 0; - for (i = 0, ptmp = pref; i < preflen; i += 2, ptmp += 2) { - /* Skip disabled hashes or signature algorithms */ - if (tls12_get_hash(ptmp[0]) == NULL) - continue; - if (tls12_get_pkey_idx(ptmp[1]) == -1) - continue; - for (j = 0, atmp = allow; j < allowlen; j += 2, atmp += 2) { - if (ptmp[0] == atmp[0] && ptmp[1] == atmp[1]) { - nmatch++; - if (shsig) { - shsig->rhash = ptmp[0]; - shsig->rsign = ptmp[1]; - tls1_lookup_sigalg(&shsig->hash_nid, - &shsig->sign_nid, - &shsig->signandhash_nid, ptmp); - shsig++; - } - break; - } - } - } - return nmatch; -} - -/* Set shared signature algorithms for SSL structures */ -static int tls1_set_shared_sigalgs(SSL *s) -{ - const unsigned char *pref, *allow, *conf; - size_t preflen, allowlen, conflen; - size_t nmatch; - TLS_SIGALGS *salgs = NULL; - CERT *c = s->cert; - unsigned int is_suiteb = tls1_suiteb(s); - if (c->shared_sigalgs) { - OPENSSL_free(c->shared_sigalgs); - c->shared_sigalgs = NULL; - c->shared_sigalgslen = 0; - } - /* If client use client signature algorithms if not NULL */ - if (!s->server && c->client_sigalgs && !is_suiteb) { - conf = c->client_sigalgs; - conflen = c->client_sigalgslen; - } else if (c->conf_sigalgs && !is_suiteb) { - conf = c->conf_sigalgs; - conflen = c->conf_sigalgslen; - } else - conflen = tls12_get_psigalgs(s, 0, &conf); - if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) { - pref = conf; - preflen = conflen; - allow = c->peer_sigalgs; - allowlen = c->peer_sigalgslen; - } else { - allow = conf; - allowlen = conflen; - pref = c->peer_sigalgs; - preflen = c->peer_sigalgslen; - } - nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen); - if (nmatch) { - salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS)); - if (!salgs) - return 0; - nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen); - } else { - salgs = NULL; - } - c->shared_sigalgs = salgs; - c->shared_sigalgslen = nmatch; - return 1; -} - -/* Set preferred digest for each key type */ - -int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize) -{ - CERT *c = s->cert; - /* Extension ignored for inappropriate versions */ - if (!SSL_USE_SIGALGS(s)) - return 1; - /* Should never happen */ - if (!c) - return 0; - - if (c->peer_sigalgs) - OPENSSL_free(c->peer_sigalgs); - c->peer_sigalgs = OPENSSL_malloc(dsize); - if (!c->peer_sigalgs) - return 0; - c->peer_sigalgslen = dsize; - memcpy(c->peer_sigalgs, data, dsize); - return 1; -} - -int tls1_process_sigalgs(SSL *s) -{ - int idx; - size_t i; - const EVP_MD *md; - CERT *c = s->cert; - TLS_SIGALGS *sigptr; - if (!tls1_set_shared_sigalgs(s)) - return 0; - -# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) { - /* - * Use first set signature preference to force message digest, - * ignoring any peer preferences. - */ - const unsigned char *sigs = NULL; - if (s->server) - sigs = c->conf_sigalgs; - else - sigs = c->client_sigalgs; - if (sigs) { - idx = tls12_get_pkey_idx(sigs[1]); - md = tls12_get_hash(sigs[0]); - c->pkeys[idx].digest = md; - c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN; - if (idx == SSL_PKEY_RSA_SIGN) { - c->pkeys[SSL_PKEY_RSA_ENC].valid_flags = - CERT_PKEY_EXPLICIT_SIGN; - c->pkeys[SSL_PKEY_RSA_ENC].digest = md; - } - } - } -# endif - - for (i = 0, sigptr = c->shared_sigalgs; - i < c->shared_sigalgslen; i++, sigptr++) { - idx = tls12_get_pkey_idx(sigptr->rsign); - if (idx > 0 && c->pkeys[idx].digest == NULL) { - md = tls12_get_hash(sigptr->rhash); - c->pkeys[idx].digest = md; - c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN; - if (idx == SSL_PKEY_RSA_SIGN) { - c->pkeys[SSL_PKEY_RSA_ENC].valid_flags = - CERT_PKEY_EXPLICIT_SIGN; - c->pkeys[SSL_PKEY_RSA_ENC].digest = md; - } - } - - } - /* - * In strict mode leave unset digests as NULL to indicate we can't use - * the certificate for signing. - */ - if (!(s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) { - /* - * Set any remaining keys to default values. NOTE: if alg is not - * supported it stays as NULL. - */ -# ifndef OPENSSL_NO_DSA - if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest) - c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); -# endif -# ifndef OPENSSL_NO_RSA - if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) { - c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); - c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); - } -# endif -# ifndef OPENSSL_NO_ECDSA - if (!c->pkeys[SSL_PKEY_ECC].digest) - c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); -# endif - } - return 1; -} - -int SSL_get_sigalgs(SSL *s, int idx, - int *psign, int *phash, int *psignhash, - unsigned char *rsig, unsigned char *rhash) -{ - const unsigned char *psig = s->cert->peer_sigalgs; - if (psig == NULL) - return 0; - if (idx >= 0) { - idx <<= 1; - if (idx >= (int)s->cert->peer_sigalgslen) - return 0; - psig += idx; - if (rhash) - *rhash = psig[0]; - if (rsig) - *rsig = psig[1]; - tls1_lookup_sigalg(phash, psign, psignhash, psig); - } - return s->cert->peer_sigalgslen / 2; -} - -int SSL_get_shared_sigalgs(SSL *s, int idx, - int *psign, int *phash, int *psignhash, - unsigned char *rsig, unsigned char *rhash) -{ - TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs; - if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen) - return 0; - shsigalgs += idx; - if (phash) - *phash = shsigalgs->hash_nid; - if (psign) - *psign = shsigalgs->sign_nid; - if (psignhash) - *psignhash = shsigalgs->signandhash_nid; - if (rsig) - *rsig = shsigalgs->rsign; - if (rhash) - *rhash = shsigalgs->rhash; - return s->cert->shared_sigalgslen; -} - -# ifndef OPENSSL_NO_HEARTBEATS -int tls1_process_heartbeat(SSL *s) -{ - unsigned char *p = &s->s3->rrec.data[0], *pl; - unsigned short hbtype; - unsigned int payload; - unsigned int padding = 16; /* Use minimum padding */ - - if (s->msg_callback) - s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, - &s->s3->rrec.data[0], s->s3->rrec.length, - s, s->msg_callback_arg); - - /* Read type and payload length first */ - if (1 + 2 + 16 > s->s3->rrec.length) - return 0; /* silently discard */ - hbtype = *p++; - n2s(p, payload); - if (1 + 2 + payload + 16 > s->s3->rrec.length) - return 0; /* silently discard per RFC 6520 sec. 4 */ - pl = p; - - if (hbtype == TLS1_HB_REQUEST) { - unsigned char *buffer, *bp; - int r; - - /* - * Allocate memory for the response, size is 1 bytes message type, - * plus 2 bytes payload length, plus payload, plus padding - */ - buffer = OPENSSL_malloc(1 + 2 + payload + padding); - if (buffer == NULL) - return -1; - bp = buffer; - - /* Enter response type, length and copy payload */ - *bp++ = TLS1_HB_RESPONSE; - s2n(payload, bp); - memcpy(bp, pl, payload); - bp += payload; - /* Random padding */ - if (RAND_bytes(bp, padding) <= 0) { - OPENSSL_free(buffer); - return -1; - } - - r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, - 3 + payload + padding); - - if (r >= 0 && s->msg_callback) - s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, - buffer, 3 + payload + padding, - s, s->msg_callback_arg); - - OPENSSL_free(buffer); - - if (r < 0) - return r; - } else if (hbtype == TLS1_HB_RESPONSE) { - unsigned int seq; - - /* - * We only send sequence numbers (2 bytes unsigned int), and 16 - * random bytes, so we just try to read the sequence number - */ - n2s(pl, seq); - - if (payload == 18 && seq == s->tlsext_hb_seq) { - s->tlsext_hb_seq++; - s->tlsext_hb_pending = 0; - } - } - - return 0; -} - -int tls1_heartbeat(SSL *s) -{ - unsigned char *buf, *p; - int ret = -1; - unsigned int payload = 18; /* Sequence number + random bytes */ - unsigned int padding = 16; /* Use minimum padding */ - - /* Only send if peer supports and accepts HB requests... */ - if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || - s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) { - SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); - return -1; - } - - /* ...and there is none in flight yet... */ - if (s->tlsext_hb_pending) { - SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING); - return -1; - } - - /* ...and no handshake in progress. */ - if (SSL_in_init(s) || s->in_handshake) { - SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE); - return -1; - } - - /* - * Check if padding is too long, payload and padding must not exceed 2^14 - * - 3 = 16381 bytes in total. - */ - OPENSSL_assert(payload + padding <= 16381); - - /*- - * Create HeartBeat message, we just use a sequence number - * as payload to distuingish different messages and add - * some random stuff. - * - Message Type, 1 byte - * - Payload Length, 2 bytes (unsigned int) - * - Payload, the sequence number (2 bytes uint) - * - Payload, random bytes (16 bytes uint) - * - Padding - */ - buf = OPENSSL_malloc(1 + 2 + payload + padding); - if (buf == NULL) - return -1; - p = buf; - /* Message Type */ - *p++ = TLS1_HB_REQUEST; - /* Payload length (18 bytes here) */ - s2n(payload, p); - /* Sequence number */ - s2n(s->tlsext_hb_seq, p); - /* 16 random bytes */ - if (RAND_bytes(p, 16) <= 0) { - SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); - goto err; - } - p += 16; - /* Random padding */ - if (RAND_bytes(p, padding) <= 0) { - SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); - goto err; - } - - ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); - if (ret >= 0) { - if (s->msg_callback) - s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, - buf, 3 + payload + padding, - s, s->msg_callback_arg); - - s->tlsext_hb_pending = 1; - } - -err: - OPENSSL_free(buf); - - return ret; -} -# endif - -# define MAX_SIGALGLEN (TLSEXT_hash_num * TLSEXT_signature_num * 2) - -typedef struct { - size_t sigalgcnt; - int sigalgs[MAX_SIGALGLEN]; -} sig_cb_st; - -static int sig_cb(const char *elem, int len, void *arg) -{ - sig_cb_st *sarg = arg; - size_t i; - char etmp[20], *p; - int sig_alg, hash_alg; - if (elem == NULL) - return 0; - if (sarg->sigalgcnt == MAX_SIGALGLEN) - return 0; - if (len > (int)(sizeof(etmp) - 1)) - return 0; - memcpy(etmp, elem, len); - etmp[len] = 0; - p = strchr(etmp, '+'); - if (!p) - return 0; - *p = 0; - p++; - if (!*p) - return 0; - - if (!strcmp(etmp, "RSA")) - sig_alg = EVP_PKEY_RSA; - else if (!strcmp(etmp, "DSA")) - sig_alg = EVP_PKEY_DSA; - else if (!strcmp(etmp, "ECDSA")) - sig_alg = EVP_PKEY_EC; - else - return 0; - - hash_alg = OBJ_sn2nid(p); - if (hash_alg == NID_undef) - hash_alg = OBJ_ln2nid(p); - if (hash_alg == NID_undef) - return 0; - - for (i = 0; i < sarg->sigalgcnt; i += 2) { - if (sarg->sigalgs[i] == sig_alg && sarg->sigalgs[i + 1] == hash_alg) - return 0; - } - sarg->sigalgs[sarg->sigalgcnt++] = hash_alg; - sarg->sigalgs[sarg->sigalgcnt++] = sig_alg; - return 1; -} - -/* - * Set suppored signature algorithms based on a colon separated list of the - * form sig+hash e.g. RSA+SHA512:DSA+SHA512 - */ -int tls1_set_sigalgs_list(CERT *c, const char *str, int client) -{ - sig_cb_st sig; - sig.sigalgcnt = 0; - if (!CONF_parse_list(str, ':', 1, sig_cb, &sig)) - return 0; - if (c == NULL) - return 1; - return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client); -} - -int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, - int client) -{ - unsigned char *sigalgs, *sptr; - int rhash, rsign; - size_t i; - if (salglen & 1) - return 0; - sigalgs = OPENSSL_malloc(salglen); - if (sigalgs == NULL) - return 0; - for (i = 0, sptr = sigalgs; i < salglen; i += 2) { - rhash = tls12_find_id(*psig_nids++, tls12_md, - sizeof(tls12_md) / sizeof(tls12_lookup)); - rsign = tls12_find_id(*psig_nids++, tls12_sig, - sizeof(tls12_sig) / sizeof(tls12_lookup)); - - if (rhash == -1 || rsign == -1) - goto err; - *sptr++ = rhash; - *sptr++ = rsign; - } - - if (client) { - if (c->client_sigalgs) - OPENSSL_free(c->client_sigalgs); - c->client_sigalgs = sigalgs; - c->client_sigalgslen = salglen; - } else { - if (c->conf_sigalgs) - OPENSSL_free(c->conf_sigalgs); - c->conf_sigalgs = sigalgs; - c->conf_sigalgslen = salglen; - } - - return 1; - - err: - OPENSSL_free(sigalgs); - return 0; -} - -static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid) -{ - int sig_nid; - size_t i; - if (default_nid == -1) - return 1; - sig_nid = X509_get_signature_nid(x); - if (default_nid) - return sig_nid == default_nid ? 1 : 0; - for (i = 0; i < c->shared_sigalgslen; i++) - if (sig_nid == c->shared_sigalgs[i].signandhash_nid) - return 1; - return 0; -} - -/* Check to see if a certificate issuer name matches list of CA names */ -static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x) -{ - X509_NAME *nm; - int i; - nm = X509_get_issuer_name(x); - for (i = 0; i < sk_X509_NAME_num(names); i++) { - if (!X509_NAME_cmp(nm, sk_X509_NAME_value(names, i))) - return 1; - } - return 0; -} - -/* - * Check certificate chain is consistent with TLS extensions and is usable by - * server. This servers two purposes: it allows users to check chains before - * passing them to the server and it allows the server to check chains before - * attempting to use them. - */ - -/* Flags which need to be set for a certificate when stict mode not set */ - -# define CERT_PKEY_VALID_FLAGS \ - (CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM) -/* Strict mode flags */ -# define CERT_PKEY_STRICT_FLAGS \ - (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \ - | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE) - -int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, - int idx) -{ - int i; - int rv = 0; - int check_flags = 0, strict_mode; - CERT_PKEY *cpk = NULL; - CERT *c = s->cert; - unsigned int suiteb_flags = tls1_suiteb(s); - /* idx == -1 means checking server chains */ - if (idx != -1) { - /* idx == -2 means checking client certificate chains */ - if (idx == -2) { - cpk = c->key; - idx = cpk - c->pkeys; - } else - cpk = c->pkeys + idx; - x = cpk->x509; - pk = cpk->privatekey; - chain = cpk->chain; - strict_mode = c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT; - /* If no cert or key, forget it */ - if (!x || !pk) - goto end; -# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - /* Allow any certificate to pass test */ - if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) { - rv = CERT_PKEY_STRICT_FLAGS | CERT_PKEY_EXPLICIT_SIGN | - CERT_PKEY_VALID | CERT_PKEY_SIGN; - cpk->valid_flags = rv; - return rv; - } -# endif - } else { - if (!x || !pk) - return 0; - idx = ssl_cert_type(x, pk); - if (idx == -1) - return 0; - cpk = c->pkeys + idx; - if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) - check_flags = CERT_PKEY_STRICT_FLAGS; - else - check_flags = CERT_PKEY_VALID_FLAGS; - strict_mode = 1; - } - - if (suiteb_flags) { - int ok; - if (check_flags) - check_flags |= CERT_PKEY_SUITEB; - ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags); - if (ok == X509_V_OK) - rv |= CERT_PKEY_SUITEB; - else if (!check_flags) - goto end; - } - - /* - * Check all signature algorithms are consistent with signature - * algorithms extension if TLS 1.2 or later and strict mode. - */ - if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) { - int default_nid; - unsigned char rsign = 0; - if (c->peer_sigalgs) - default_nid = 0; - /* If no sigalgs extension use defaults from RFC5246 */ - else { - switch (idx) { - case SSL_PKEY_RSA_ENC: - case SSL_PKEY_RSA_SIGN: - case SSL_PKEY_DH_RSA: - rsign = TLSEXT_signature_rsa; - default_nid = NID_sha1WithRSAEncryption; - break; - - case SSL_PKEY_DSA_SIGN: - case SSL_PKEY_DH_DSA: - rsign = TLSEXT_signature_dsa; - default_nid = NID_dsaWithSHA1; - break; - - case SSL_PKEY_ECC: - rsign = TLSEXT_signature_ecdsa; - default_nid = NID_ecdsa_with_SHA1; - break; - - default: - default_nid = -1; - break; - } - } - /* - * If peer sent no signature algorithms extension and we have set - * preferred signature algorithms check we support sha1. - */ - if (default_nid > 0 && c->conf_sigalgs) { - size_t j; - const unsigned char *p = c->conf_sigalgs; - for (j = 0; j < c->conf_sigalgslen; j += 2, p += 2) { - if (p[0] == TLSEXT_hash_sha1 && p[1] == rsign) - break; - } - if (j == c->conf_sigalgslen) { - if (check_flags) - goto skip_sigs; - else - goto end; - } - } - /* Check signature algorithm of each cert in chain */ - if (!tls1_check_sig_alg(c, x, default_nid)) { - if (!check_flags) - goto end; - } else - rv |= CERT_PKEY_EE_SIGNATURE; - rv |= CERT_PKEY_CA_SIGNATURE; - for (i = 0; i < sk_X509_num(chain); i++) { - if (!tls1_check_sig_alg(c, sk_X509_value(chain, i), default_nid)) { - if (check_flags) { - rv &= ~CERT_PKEY_CA_SIGNATURE; - break; - } else - goto end; - } - } - } - /* Else not TLS 1.2, so mark EE and CA signing algorithms OK */ - else if (check_flags) - rv |= CERT_PKEY_EE_SIGNATURE | CERT_PKEY_CA_SIGNATURE; - skip_sigs: - /* Check cert parameters are consistent */ - if (tls1_check_cert_param(s, x, check_flags ? 1 : 2)) - rv |= CERT_PKEY_EE_PARAM; - else if (!check_flags) - goto end; - if (!s->server) - rv |= CERT_PKEY_CA_PARAM; - /* In strict mode check rest of chain too */ - else if (strict_mode) { - rv |= CERT_PKEY_CA_PARAM; - for (i = 0; i < sk_X509_num(chain); i++) { - X509 *ca = sk_X509_value(chain, i); - if (!tls1_check_cert_param(s, ca, 0)) { - if (check_flags) { - rv &= ~CERT_PKEY_CA_PARAM; - break; - } else - goto end; - } - } - } - if (!s->server && strict_mode) { - STACK_OF(X509_NAME) *ca_dn; - int check_type = 0; - switch (pk->type) { - case EVP_PKEY_RSA: - check_type = TLS_CT_RSA_SIGN; - break; - case EVP_PKEY_DSA: - check_type = TLS_CT_DSS_SIGN; - break; - case EVP_PKEY_EC: - check_type = TLS_CT_ECDSA_SIGN; - break; - case EVP_PKEY_DH: - case EVP_PKEY_DHX: - { - int cert_type = X509_certificate_type(x, pk); - if (cert_type & EVP_PKS_RSA) - check_type = TLS_CT_RSA_FIXED_DH; - if (cert_type & EVP_PKS_DSA) - check_type = TLS_CT_DSS_FIXED_DH; - } - } - if (check_type) { - const unsigned char *ctypes; - int ctypelen; - if (c->ctypes) { - ctypes = c->ctypes; - ctypelen = (int)c->ctype_num; - } else { - ctypes = (unsigned char *)s->s3->tmp.ctype; - ctypelen = s->s3->tmp.ctype_num; - } - for (i = 0; i < ctypelen; i++) { - if (ctypes[i] == check_type) { - rv |= CERT_PKEY_CERT_TYPE; - break; - } - } - if (!(rv & CERT_PKEY_CERT_TYPE) && !check_flags) - goto end; - } else - rv |= CERT_PKEY_CERT_TYPE; - - ca_dn = s->s3->tmp.ca_names; - - if (!sk_X509_NAME_num(ca_dn)) - rv |= CERT_PKEY_ISSUER_NAME; - - if (!(rv & CERT_PKEY_ISSUER_NAME)) { - if (ssl_check_ca_name(ca_dn, x)) - rv |= CERT_PKEY_ISSUER_NAME; - } - if (!(rv & CERT_PKEY_ISSUER_NAME)) { - for (i = 0; i < sk_X509_num(chain); i++) { - X509 *xtmp = sk_X509_value(chain, i); - if (ssl_check_ca_name(ca_dn, xtmp)) { - rv |= CERT_PKEY_ISSUER_NAME; - break; - } - } - } - if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME)) - goto end; - } else - rv |= CERT_PKEY_ISSUER_NAME | CERT_PKEY_CERT_TYPE; - - if (!check_flags || (rv & check_flags) == check_flags) - rv |= CERT_PKEY_VALID; - - end: - - if (TLS1_get_version(s) >= TLS1_2_VERSION) { - if (cpk->valid_flags & CERT_PKEY_EXPLICIT_SIGN) - rv |= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN; - else if (cpk->digest) - rv |= CERT_PKEY_SIGN; - } else - rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN; - - /* - * When checking a CERT_PKEY structure all flags are irrelevant if the - * chain is invalid. - */ - if (!check_flags) { - if (rv & CERT_PKEY_VALID) - cpk->valid_flags = rv; - else { - /* Preserve explicit sign flag, clear rest */ - cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN; - return 0; - } - } - return rv; -} - -/* Set validity of certificates in an SSL structure */ -void tls1_set_cert_validity(SSL *s) -{ - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_ENC); - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_SIGN); - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN); - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_RSA); - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_DSA); - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC); -} - -/* User level utiity function to check a chain is suitable */ -int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) -{ - return tls1_check_chain(s, x, pk, chain, -1); -} - -#endif diff --git a/thirdparty/openssl/ssl/t1_meth.c b/thirdparty/openssl/ssl/t1_meth.c deleted file mode 100644 index 335d57b530..0000000000 --- a/thirdparty/openssl/ssl/t1_meth.c +++ /dev/null @@ -1,84 +0,0 @@ -/* ssl/t1_meth.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include <openssl/objects.h> -#include "ssl_locl.h" - -static const SSL_METHOD *tls1_get_method(int ver) -{ - if (ver == TLS1_2_VERSION) - return TLSv1_2_method(); - if (ver == TLS1_1_VERSION) - return TLSv1_1_method(); - if (ver == TLS1_VERSION) - return TLSv1_method(); - return NULL; -} - -IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method, - ssl3_accept, - ssl3_connect, tls1_get_method, TLSv1_2_enc_data) - - IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method, - ssl3_accept, - ssl3_connect, tls1_get_method, TLSv1_1_enc_data) - - IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method, - ssl3_accept, - ssl3_connect, tls1_get_method, TLSv1_enc_data) diff --git a/thirdparty/openssl/ssl/t1_reneg.c b/thirdparty/openssl/ssl/t1_reneg.c deleted file mode 100644 index b9a35c7fc2..0000000000 --- a/thirdparty/openssl/ssl/t1_reneg.c +++ /dev/null @@ -1,292 +0,0 @@ -/* ssl/t1_reneg.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2009 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 - * openssl-core@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). - * - */ -#include <stdio.h> -#include <openssl/objects.h> -#include "ssl_locl.h" - -/* Add the client's renegotiation binding */ -int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, - int maxlen) -{ - if (p) { - if ((s->s3->previous_client_finished_len + 1) > maxlen) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATE_EXT_TOO_LONG); - return 0; - } - - /* Length byte */ - *p = s->s3->previous_client_finished_len; - p++; - - memcpy(p, s->s3->previous_client_finished, - s->s3->previous_client_finished_len); -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "%s RI extension sent by client\n", - s->s3->previous_client_finished_len ? "Non-empty" : "Empty"); -#endif - } - - *len = s->s3->previous_client_finished_len + 1; - - return 1; -} - -/* - * Parse the client's renegotiation binding and abort if it's not right - */ -int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, - int *al) -{ - int ilen; - - /* Parse the length byte */ - if (len < 1) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_ENCODING_ERR); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - ilen = *d; - d++; - - /* Consistency check */ - if ((ilen + 1) != len) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_ENCODING_ERR); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - - /* Check that the extension matches */ - if (ilen != s->s3->previous_client_finished_len) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_MISMATCH); - *al = SSL_AD_HANDSHAKE_FAILURE; - return 0; - } - - if (memcmp(d, s->s3->previous_client_finished, - s->s3->previous_client_finished_len)) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_MISMATCH); - *al = SSL_AD_HANDSHAKE_FAILURE; - return 0; - } -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "%s RI extension received by server\n", - ilen ? "Non-empty" : "Empty"); -#endif - - s->s3->send_connection_binding = 1; - - return 1; -} - -/* Add the server's renegotiation binding */ -int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, - int maxlen) -{ - if (p) { - if ((s->s3->previous_client_finished_len + - s->s3->previous_server_finished_len + 1) > maxlen) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATE_EXT_TOO_LONG); - return 0; - } - - /* Length byte */ - *p = s->s3->previous_client_finished_len + - s->s3->previous_server_finished_len; - p++; - - memcpy(p, s->s3->previous_client_finished, - s->s3->previous_client_finished_len); - p += s->s3->previous_client_finished_len; - - memcpy(p, s->s3->previous_server_finished, - s->s3->previous_server_finished_len); -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "%s RI extension sent by server\n", - s->s3->previous_client_finished_len ? "Non-empty" : "Empty"); -#endif - } - - *len = s->s3->previous_client_finished_len - + s->s3->previous_server_finished_len + 1; - - return 1; -} - -/* - * Parse the server's renegotiation binding and abort if it's not right - */ -int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, - int *al) -{ - int expected_len = s->s3->previous_client_finished_len - + s->s3->previous_server_finished_len; - int ilen; - - /* Check for logic errors */ - OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len); - OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len); - - /* Parse the length byte */ - if (len < 1) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_ENCODING_ERR); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - ilen = *d; - d++; - - /* Consistency check */ - if (ilen + 1 != len) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_ENCODING_ERR); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - - /* Check that the extension matches */ - if (ilen != expected_len) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_MISMATCH); - *al = SSL_AD_HANDSHAKE_FAILURE; - return 0; - } - - if (memcmp(d, s->s3->previous_client_finished, - s->s3->previous_client_finished_len)) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_MISMATCH); - *al = SSL_AD_HANDSHAKE_FAILURE; - return 0; - } - d += s->s3->previous_client_finished_len; - - if (memcmp(d, s->s3->previous_server_finished, - s->s3->previous_server_finished_len)) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_MISMATCH); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "%s RI extension received by client\n", - ilen ? "Non-empty" : "Empty"); -#endif - s->s3->send_connection_binding = 1; - - return 1; -} diff --git a/thirdparty/openssl/ssl/t1_srvr.c b/thirdparty/openssl/ssl/t1_srvr.c deleted file mode 100644 index 8c6b3dff2f..0000000000 --- a/thirdparty/openssl/ssl/t1_srvr.c +++ /dev/null @@ -1,92 +0,0 @@ -/* ssl/t1_srvr.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#include "ssl_locl.h" -#include <openssl/buffer.h> -#include <openssl/rand.h> -#include <openssl/objects.h> -#include <openssl/evp.h> -#include <openssl/x509.h> - -static const SSL_METHOD *tls1_get_server_method(int ver); -static const SSL_METHOD *tls1_get_server_method(int ver) -{ - if (ver == TLS1_2_VERSION) - return TLSv1_2_server_method(); - if (ver == TLS1_1_VERSION) - return TLSv1_1_server_method(); - if (ver == TLS1_VERSION) - return TLSv1_server_method(); - return NULL; -} - -IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_server_method, - ssl3_accept, - ssl_undefined_function, - tls1_get_server_method, TLSv1_2_enc_data) - - IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method, - ssl3_accept, - ssl_undefined_function, - tls1_get_server_method, TLSv1_1_enc_data) - - IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_server_method, - ssl3_accept, - ssl_undefined_function, - tls1_get_server_method, TLSv1_enc_data) diff --git a/thirdparty/openssl/ssl/t1_trce.c b/thirdparty/openssl/ssl/t1_trce.c deleted file mode 100644 index c5e21df77a..0000000000 --- a/thirdparty/openssl/ssl/t1_trce.c +++ /dev/null @@ -1,1266 +0,0 @@ -/* ssl/t1_trce.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2012 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. - * ==================================================================== - * - */ - -#include "ssl_locl.h" - -#ifndef OPENSSL_NO_SSL_TRACE - -/* Packet trace support for OpenSSL */ - -typedef struct { - int num; - const char *name; -} ssl_trace_tbl; - -# define ssl_trace_str(val, tbl) \ - do_ssl_trace_str(val, tbl, sizeof(tbl)/sizeof(ssl_trace_tbl)) - -# define ssl_trace_list(bio, indent, msg, msglen, value, table) \ - do_ssl_trace_list(bio, indent, msg, msglen, value, \ - table, sizeof(table)/sizeof(ssl_trace_tbl)) - -static const char *do_ssl_trace_str(int val, ssl_trace_tbl *tbl, size_t ntbl) -{ - size_t i; - for (i = 0; i < ntbl; i++, tbl++) { - if (tbl->num == val) - return tbl->name; - } - return "UNKNOWN"; -} - -static int do_ssl_trace_list(BIO *bio, int indent, - const unsigned char *msg, size_t msglen, - size_t vlen, ssl_trace_tbl *tbl, size_t ntbl) -{ - int val; - if (msglen % vlen) - return 0; - while (msglen) { - val = msg[0]; - if (vlen == 2) - val = (val << 8) | msg[1]; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "%s (%d)\n", do_ssl_trace_str(val, tbl, ntbl), val); - msg += vlen; - msglen -= vlen; - } - return 1; -} - -/* Version number */ - -static ssl_trace_tbl ssl_version_tbl[] = { - {SSL2_VERSION, "SSL 2.0"}, - {SSL3_VERSION, "SSL 3.0"}, - {TLS1_VERSION, "TLS 1.0"}, - {TLS1_1_VERSION, "TLS 1.1"}, - {TLS1_2_VERSION, "TLS 1.2"}, - {DTLS1_VERSION, "DTLS 1.0"}, - {DTLS1_2_VERSION, "DTLS 1.2"}, - {DTLS1_BAD_VER, "DTLS 1.0 (bad)"} -}; - -static ssl_trace_tbl ssl_content_tbl[] = { - {SSL3_RT_CHANGE_CIPHER_SPEC, "ChangeCipherSpec"}, - {SSL3_RT_ALERT, "Alert"}, - {SSL3_RT_HANDSHAKE, "Handshake"}, - {SSL3_RT_APPLICATION_DATA, "ApplicationData"}, - {TLS1_RT_HEARTBEAT, "HeartBeat"} -}; - -/* Handshake types */ -static ssl_trace_tbl ssl_handshake_tbl[] = { - {SSL3_MT_HELLO_REQUEST, "HelloRequest"}, - {SSL3_MT_CLIENT_HELLO, "ClientHello"}, - {SSL3_MT_SERVER_HELLO, "ServerHello"}, - {DTLS1_MT_HELLO_VERIFY_REQUEST, "HelloVerifyRequest"}, - {SSL3_MT_NEWSESSION_TICKET, "NewSessionTicket"}, - {SSL3_MT_CERTIFICATE, "Certificate"}, - {SSL3_MT_SERVER_KEY_EXCHANGE, "ServerKeyExchange"}, - {SSL3_MT_CERTIFICATE_REQUEST, "CertificateRequest"}, - {SSL3_MT_CLIENT_KEY_EXCHANGE, "ClientKeyExchange"}, - {SSL3_MT_CERTIFICATE_STATUS, "CertificateStatus"}, - {SSL3_MT_SERVER_DONE, "ServerHelloDone"}, - {SSL3_MT_CERTIFICATE_VERIFY, "CertificateVerify"}, - {SSL3_MT_CLIENT_KEY_EXCHANGE, "ClientKeyExchange"}, - {SSL3_MT_FINISHED, "Finished"}, - {SSL3_MT_CERTIFICATE_STATUS, "CertificateStatus"} -}; - -/* Cipher suites */ -static ssl_trace_tbl ssl_ciphers_tbl[] = { - {0x0000, "SSL_NULL_WITH_NULL_NULL"}, - {0x0001, "SSL_RSA_WITH_NULL_MD5"}, - {0x0002, "SSL_RSA_WITH_NULL_SHA"}, - {0x0003, "SSL_RSA_EXPORT_WITH_RC4_40_MD5"}, - {0x0004, "SSL_RSA_WITH_RC4_128_MD5"}, - {0x0005, "SSL_RSA_WITH_RC4_128_SHA"}, - {0x0006, "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"}, - {0x0007, "SSL_RSA_WITH_IDEA_CBC_SHA"}, - {0x0008, "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"}, - {0x0009, "SSL_RSA_WITH_DES_CBC_SHA"}, - {0x000A, "SSL_RSA_WITH_3DES_EDE_CBC_SHA"}, - {0x000B, "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"}, - {0x000C, "SSL_DH_DSS_WITH_DES_CBC_SHA"}, - {0x000D, "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA"}, - {0x000E, "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"}, - {0x000F, "SSL_DH_RSA_WITH_DES_CBC_SHA"}, - {0x0010, "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA"}, - {0x0011, "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"}, - {0x0012, "SSL_DHE_DSS_WITH_DES_CBC_SHA"}, - {0x0013, "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"}, - {0x0014, "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"}, - {0x0015, "SSL_DHE_RSA_WITH_DES_CBC_SHA"}, - {0x0016, "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"}, - {0x0017, "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"}, - {0x0018, "SSL_DH_anon_WITH_RC4_128_MD5"}, - {0x0019, "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"}, - {0x001A, "SSL_DH_anon_WITH_DES_CBC_SHA"}, - {0x001B, "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"}, - {0x001D, "SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA"}, - {0x001E, "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA"}, - {0x001F, "TLS_KRB5_WITH_3DES_EDE_CBC_SHA"}, - {0x0020, "TLS_KRB5_WITH_RC4_128_SHA"}, - {0x0021, "TLS_KRB5_WITH_IDEA_CBC_SHA"}, - {0x0022, "TLS_KRB5_WITH_DES_CBC_MD5"}, - {0x0023, "TLS_KRB5_WITH_3DES_EDE_CBC_MD5"}, - {0x0024, "TLS_KRB5_WITH_RC4_128_MD5"}, - {0x0025, "TLS_KRB5_WITH_IDEA_CBC_MD5"}, - {0x0026, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA"}, - {0x0027, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA"}, - {0x0028, "TLS_KRB5_EXPORT_WITH_RC4_40_SHA"}, - {0x0029, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5"}, - {0x002A, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5"}, - {0x002B, "TLS_KRB5_EXPORT_WITH_RC4_40_MD5"}, - {0x002F, "TLS_RSA_WITH_AES_128_CBC_SHA"}, - {0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA"}, - {0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA"}, - {0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"}, - {0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"}, - {0x0034, "TLS_DH_anon_WITH_AES_128_CBC_SHA"}, - {0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA"}, - {0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA"}, - {0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA"}, - {0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"}, - {0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"}, - {0x003A, "TLS_DH_anon_WITH_AES_256_CBC_SHA"}, - {0x003B, "TLS_RSA_WITH_NULL_SHA256"}, - {0x003C, "TLS_RSA_WITH_AES_128_CBC_SHA256"}, - {0x003D, "TLS_RSA_WITH_AES_256_CBC_SHA256"}, - {0x003E, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"}, - {0x003F, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"}, - {0x0040, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"}, - {0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA"}, - {0x0042, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA"}, - {0x0043, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA"}, - {0x0044, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA"}, - {0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA"}, - {0x0046, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA"}, - {0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"}, - {0x0068, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"}, - {0x0069, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"}, - {0x006A, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"}, - {0x006B, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"}, - {0x006C, "TLS_DH_anon_WITH_AES_128_CBC_SHA256"}, - {0x006D, "TLS_DH_anon_WITH_AES_256_CBC_SHA256"}, - {0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA"}, - {0x0085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA"}, - {0x0086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA"}, - {0x0087, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA"}, - {0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA"}, - {0x0089, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA"}, - {0x008A, "TLS_PSK_WITH_RC4_128_SHA"}, - {0x008B, "TLS_PSK_WITH_3DES_EDE_CBC_SHA"}, - {0x008C, "TLS_PSK_WITH_AES_128_CBC_SHA"}, - {0x008D, "TLS_PSK_WITH_AES_256_CBC_SHA"}, - {0x008E, "TLS_DHE_PSK_WITH_RC4_128_SHA"}, - {0x008F, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"}, - {0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"}, - {0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"}, - {0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA"}, - {0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"}, - {0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"}, - {0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"}, - {0x0096, "TLS_RSA_WITH_SEED_CBC_SHA"}, - {0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA"}, - {0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA"}, - {0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA"}, - {0x009A, "TLS_DHE_RSA_WITH_SEED_CBC_SHA"}, - {0x009B, "TLS_DH_anon_WITH_SEED_CBC_SHA"}, - {0x009C, "TLS_RSA_WITH_AES_128_GCM_SHA256"}, - {0x009D, "TLS_RSA_WITH_AES_256_GCM_SHA384"}, - {0x009E, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"}, - {0x009F, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"}, - {0x00A0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"}, - {0x00A1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"}, - {0x00A2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"}, - {0x00A3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"}, - {0x00A4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"}, - {0x00A5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"}, - {0x00A6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256"}, - {0x00A7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384"}, - {0x00A8, "TLS_PSK_WITH_AES_128_GCM_SHA256"}, - {0x00A9, "TLS_PSK_WITH_AES_256_GCM_SHA384"}, - {0x00AA, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"}, - {0x00AB, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"}, - {0x00AC, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"}, - {0x00AD, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384"}, - {0x00AE, "TLS_PSK_WITH_AES_128_CBC_SHA256"}, - {0x00AF, "TLS_PSK_WITH_AES_256_CBC_SHA384"}, - {0x00B0, "TLS_PSK_WITH_NULL_SHA256"}, - {0x00B1, "TLS_PSK_WITH_NULL_SHA384"}, - {0x00B2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"}, - {0x00B3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"}, - {0x00B4, "TLS_DHE_PSK_WITH_NULL_SHA256"}, - {0x00B5, "TLS_DHE_PSK_WITH_NULL_SHA384"}, - {0x00B6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"}, - {0x00B7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"}, - {0x00B8, "TLS_RSA_PSK_WITH_NULL_SHA256"}, - {0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384"}, - {0x00BA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256"}, - {0x00BB, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256"}, - {0x00BC, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256"}, - {0x00BD, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256"}, - {0x00BE, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"}, - {0x00BF, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256"}, - {0x00C0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256"}, - {0x00C1, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256"}, - {0x00C2, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256"}, - {0x00C3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256"}, - {0x00C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256"}, - {0x00C5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256"}, - {0x00FF, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"}, - {0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA"}, - {0xC002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"}, - {0xC003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"}, - {0xC004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"}, - {0xC005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"}, - {0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"}, - {0xC007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"}, - {0xC008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"}, - {0xC009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"}, - {0xC00A, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"}, - {0xC00B, "TLS_ECDH_RSA_WITH_NULL_SHA"}, - {0xC00C, "TLS_ECDH_RSA_WITH_RC4_128_SHA"}, - {0xC00D, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"}, - {0xC00E, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"}, - {0xC00F, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"}, - {0xC010, "TLS_ECDHE_RSA_WITH_NULL_SHA"}, - {0xC011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"}, - {0xC012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"}, - {0xC013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"}, - {0xC014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"}, - {0xC015, "TLS_ECDH_anon_WITH_NULL_SHA"}, - {0xC016, "TLS_ECDH_anon_WITH_RC4_128_SHA"}, - {0xC017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"}, - {0xC018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"}, - {0xC019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"}, - {0xC01A, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA"}, - {0xC01B, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA"}, - {0xC01C, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA"}, - {0xC01D, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA"}, - {0xC01E, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA"}, - {0xC01F, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA"}, - {0xC020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA"}, - {0xC021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA"}, - {0xC022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA"}, - {0xC023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"}, - {0xC024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"}, - {0xC025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"}, - {0xC026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"}, - {0xC027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"}, - {0xC028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"}, - {0xC029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"}, - {0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"}, - {0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"}, - {0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"}, - {0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"}, - {0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"}, - {0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"}, - {0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"}, - {0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"}, - {0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"}, - {0xFEFE, "SSL_RSA_FIPS_WITH_DES_CBC_SHA"}, - {0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, -}; - -/* Compression methods */ -static ssl_trace_tbl ssl_comp_tbl[] = { - {0x0000, "No Compression"}, - {0x0001, "Zlib Compression"} -}; - -/* Extensions */ -static ssl_trace_tbl ssl_exts_tbl[] = { - {TLSEXT_TYPE_server_name, "server_name"}, - {TLSEXT_TYPE_max_fragment_length, "max_fragment_length"}, - {TLSEXT_TYPE_client_certificate_url, "client_certificate_url"}, - {TLSEXT_TYPE_trusted_ca_keys, "trusted_ca_keys"}, - {TLSEXT_TYPE_truncated_hmac, "truncated_hmac"}, - {TLSEXT_TYPE_status_request, "status_request"}, - {TLSEXT_TYPE_user_mapping, "user_mapping"}, - {TLSEXT_TYPE_client_authz, "client_authz"}, - {TLSEXT_TYPE_server_authz, "server_authz"}, - {TLSEXT_TYPE_cert_type, "cert_type"}, - {TLSEXT_TYPE_elliptic_curves, "elliptic_curves"}, - {TLSEXT_TYPE_ec_point_formats, "ec_point_formats"}, - {TLSEXT_TYPE_srp, "srp"}, - {TLSEXT_TYPE_signature_algorithms, "signature_algorithms"}, - {TLSEXT_TYPE_use_srtp, "use_srtp"}, - {TLSEXT_TYPE_heartbeat, "heartbeat"}, - {TLSEXT_TYPE_session_ticket, "session_ticket"}, -# ifdef TLSEXT_TYPE_opaque_prf_input - {TLSEXT_TYPE_opaque_prf_input, "opaque_prf_input"}, -# endif - {TLSEXT_TYPE_renegotiate, "renegotiate"}, - {TLSEXT_TYPE_next_proto_neg, "next_proto_neg"}, - {TLSEXT_TYPE_padding, "padding"} -}; - -static ssl_trace_tbl ssl_curve_tbl[] = { - {1, "sect163k1 (K-163)"}, - {2, "sect163r1"}, - {3, "sect163r2 (B-163)"}, - {4, "sect193r1"}, - {5, "sect193r2"}, - {6, "sect233k1 (K-233)"}, - {7, "sect233r1 (B-233)"}, - {8, "sect239k1"}, - {9, "sect283k1 (K-283)"}, - {10, "sect283r1 (B-283)"}, - {11, "sect409k1 (K-409)"}, - {12, "sect409r1 (B-409)"}, - {13, "sect571k1 (K-571)"}, - {14, "sect571r1 (B-571)"}, - {15, "secp160k1"}, - {16, "secp160r1"}, - {17, "secp160r2"}, - {18, "secp192k1"}, - {19, "secp192r1 (P-192)"}, - {20, "secp224k1"}, - {21, "secp224r1 (P-224)"}, - {22, "secp256k1"}, - {23, "secp256r1 (P-256)"}, - {24, "secp384r1 (P-384)"}, - {25, "secp521r1 (P-521)"}, - {26, "brainpoolP256r1"}, - {27, "brainpoolP384r1"}, - {28, "brainpoolP512r1"}, - {0xFF01, "arbitrary_explicit_prime_curves"}, - {0xFF02, "arbitrary_explicit_char2_curves"} -}; - -static ssl_trace_tbl ssl_point_tbl[] = { - {0, "uncompressed"}, - {1, "ansiX962_compressed_prime"}, - {2, "ansiX962_compressed_char2"} -}; - -static ssl_trace_tbl ssl_md_tbl[] = { - {0, "none"}, - {1, "md5"}, - {2, "sha1"}, - {3, "sha224"}, - {4, "sha256"}, - {5, "sha384"}, - {6, "sha512"} -}; - -static ssl_trace_tbl ssl_sig_tbl[] = { - {0, "anonymous"}, - {1, "rsa"}, - {2, "dsa"}, - {3, "ecdsa"} -}; - -static ssl_trace_tbl ssl_hb_tbl[] = { - {1, "peer_allowed_to_send"}, - {2, "peer_not_allowed_to_send"} -}; - -static ssl_trace_tbl ssl_hb_type_tbl[] = { - {1, "heartbeat_request"}, - {2, "heartbeat_response"} -}; - -static ssl_trace_tbl ssl_ctype_tbl[] = { - {1, "rsa_sign"}, - {2, "dss_sign"}, - {3, "rsa_fixed_dh"}, - {4, "dss_fixed_dh"}, - {5, "rsa_ephemeral_dh"}, - {6, "dss_ephemeral_dh"}, - {20, "fortezza_dms"}, - {64, "ecdsa_sign"}, - {65, "rsa_fixed_ecdh"}, - {66, "ecdsa_fixed_ecdh"} -}; - -static ssl_trace_tbl ssl_crypto_tbl[] = { - {TLS1_RT_CRYPTO_PREMASTER, "Premaster Secret"}, - {TLS1_RT_CRYPTO_CLIENT_RANDOM, "Client Random"}, - {TLS1_RT_CRYPTO_SERVER_RANDOM, "Server Random"}, - {TLS1_RT_CRYPTO_MASTER, "Master Secret"}, - {TLS1_RT_CRYPTO_MAC | TLS1_RT_CRYPTO_WRITE, "Write Mac Secret"}, - {TLS1_RT_CRYPTO_MAC | TLS1_RT_CRYPTO_READ, "Read Mac Secret"}, - {TLS1_RT_CRYPTO_KEY | TLS1_RT_CRYPTO_WRITE, "Write Key"}, - {TLS1_RT_CRYPTO_KEY | TLS1_RT_CRYPTO_READ, "Read Key"}, - {TLS1_RT_CRYPTO_IV | TLS1_RT_CRYPTO_WRITE, "Write IV"}, - {TLS1_RT_CRYPTO_IV | TLS1_RT_CRYPTO_READ, "Read IV"}, - {TLS1_RT_CRYPTO_FIXED_IV | TLS1_RT_CRYPTO_WRITE, "Write IV (fixed part)"}, - {TLS1_RT_CRYPTO_FIXED_IV | TLS1_RT_CRYPTO_READ, "Read IV (fixed part)"} -}; - -static void ssl_print_hex(BIO *bio, int indent, const char *name, - const unsigned char *msg, size_t msglen) -{ - size_t i; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "%s (len=%d): ", name, (int)msglen); - for (i = 0; i < msglen; i++) - BIO_printf(bio, "%02X", msg[i]); - BIO_puts(bio, "\n"); -} - -static int ssl_print_hexbuf(BIO *bio, int indent, - const char *name, size_t nlen, - const unsigned char **pmsg, size_t *pmsglen) -{ - size_t blen; - const unsigned char *p = *pmsg; - if (*pmsglen < nlen) - return 0; - blen = p[0]; - if (nlen > 1) - blen = (blen << 8) | p[1]; - if (*pmsglen < nlen + blen) - return 0; - p += nlen; - ssl_print_hex(bio, indent, name, p, blen); - *pmsg += blen + nlen; - *pmsglen -= blen + nlen; - return 1; -} - -static int ssl_print_version(BIO *bio, int indent, const char *name, - const unsigned char **pmsg, size_t *pmsglen) -{ - int vers; - if (*pmsglen < 2) - return 0; - vers = ((*pmsg)[0] << 8) | (*pmsg)[1]; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "%s=0x%x (%s)\n", - name, vers, ssl_trace_str(vers, ssl_version_tbl)); - *pmsg += 2; - *pmsglen -= 2; - return 1; -} - -static int ssl_print_random(BIO *bio, int indent, - const unsigned char **pmsg, size_t *pmsglen) -{ - unsigned int tm; - const unsigned char *p = *pmsg; - if (*pmsglen < 32) - return 0; - tm = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; - p += 4; - BIO_indent(bio, indent, 80); - BIO_puts(bio, "Random:\n"); - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "gmt_unix_time=0x%08X\n", tm); - ssl_print_hex(bio, indent + 2, "random_bytes", p, 28); - *pmsg += 32; - *pmsglen -= 32; - return 1; -} - -static int ssl_print_signature(BIO *bio, int indent, SSL *s, - const unsigned char **pmsg, size_t *pmsglen) -{ - if (*pmsglen < 2) - return 0; - if (SSL_USE_SIGALGS(s)) { - const unsigned char *p = *pmsg; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "Signature Algorithm %s+%s (%d+%d)\n", - ssl_trace_str(p[0], ssl_md_tbl), - ssl_trace_str(p[1], ssl_sig_tbl), p[0], p[1]); - *pmsg += 2; - *pmsglen -= 2; - } - return ssl_print_hexbuf(bio, indent, "Signature", 2, pmsg, pmsglen); -} - -static int ssl_print_extension(BIO *bio, int indent, int server, int extype, - const unsigned char *ext, size_t extlen) -{ - size_t xlen; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "extension_type=%s(%d), length=%d\n", - ssl_trace_str(extype, ssl_exts_tbl), extype, (int)extlen); - switch (extype) { - case TLSEXT_TYPE_ec_point_formats: - if (extlen < 1) - return 0; - xlen = ext[0]; - if (extlen != xlen + 1) - return 0; - return ssl_trace_list(bio, indent + 2, - ext + 1, xlen, 1, ssl_point_tbl); - - case TLSEXT_TYPE_elliptic_curves: - if (extlen < 2) - return 0; - xlen = (ext[0] << 8) | ext[1]; - if (extlen != xlen + 2) - return 0; - return ssl_trace_list(bio, indent + 2, - ext + 2, xlen, 2, ssl_curve_tbl); - - case TLSEXT_TYPE_signature_algorithms: - - if (extlen < 2) - return 0; - xlen = (ext[0] << 8) | ext[1]; - if (extlen != xlen + 2) - return 0; - if (xlen & 1) - return 0; - ext += 2; - while (xlen > 0) { - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "%s+%s (%d+%d)\n", - ssl_trace_str(ext[0], ssl_md_tbl), - ssl_trace_str(ext[1], ssl_sig_tbl), ext[0], ext[1]); - xlen -= 2; - ext += 2; - } - break; - - case TLSEXT_TYPE_renegotiate: - if (extlen < 1) - return 0; - xlen = ext[0]; - if (xlen + 1 != extlen) - return 0; - ext++; - if (xlen) { - if (server) { - if (xlen & 1) - return 0; - xlen >>= 1; - } - ssl_print_hex(bio, indent + 4, "client_verify_data", ext, xlen); - if (server) { - ext += xlen; - ssl_print_hex(bio, indent + 4, - "server_verify_data", ext, xlen); - } - } else { - BIO_indent(bio, indent + 4, 80); - BIO_puts(bio, "<EMPTY>\n"); - } - break; - - case TLSEXT_TYPE_heartbeat: - if (extlen != 1) - return 0; - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "HeartbeatMode: %s\n", - ssl_trace_str(ext[0], ssl_hb_tbl)); - break; - - case TLSEXT_TYPE_session_ticket: - if (extlen != 0) - ssl_print_hex(bio, indent + 4, "ticket", ext, extlen); - break; - - default: - BIO_dump_indent(bio, (char *)ext, extlen, indent + 2); - } - return 1; -} - -static int ssl_print_extensions(BIO *bio, int indent, int server, - const unsigned char *msg, size_t msglen) -{ - size_t extslen; - BIO_indent(bio, indent, 80); - if (msglen == 0) { - BIO_puts(bio, "No Extensions\n"); - return 1; - } - extslen = (msg[0] << 8) | msg[1]; - if (extslen != msglen - 2) - return 0; - msg += 2; - msglen = extslen; - BIO_printf(bio, "extensions, length = %d\n", (int)msglen); - while (msglen > 0) { - int extype; - size_t extlen; - if (msglen < 4) - return 0; - extype = (msg[0] << 8) | msg[1]; - extlen = (msg[2] << 8) | msg[3]; - if (msglen < extlen + 4) - return 0; - msg += 4; - if (!ssl_print_extension(bio, indent + 2, server, - extype, msg, extlen)) - return 0; - msg += extlen; - msglen -= extlen + 4; - } - return 1; -} - -static int ssl_print_client_hello(BIO *bio, SSL *ssl, int indent, - const unsigned char *msg, size_t msglen) -{ - size_t len; - unsigned int cs; - if (!ssl_print_version(bio, indent, "client_version", &msg, &msglen)) - return 0; - if (!ssl_print_random(bio, indent, &msg, &msglen)) - return 0; - if (!ssl_print_hexbuf(bio, indent, "session_id", 1, &msg, &msglen)) - return 0; - if (SSL_IS_DTLS(ssl)) { - if (!ssl_print_hexbuf(bio, indent, "cookie", 1, &msg, &msglen)) - return 0; - } - if (msglen < 2) - return 0; - len = (msg[0] << 8) | msg[1]; - msg += 2; - msglen -= 2; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "cipher_suites (len=%d)\n", (int)len); - if (msglen < len || len & 1) - return 0; - while (len > 0) { - cs = (msg[0] << 8) | msg[1]; - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "{0x%02X, 0x%02X} %s\n", - msg[0], msg[1], ssl_trace_str(cs, ssl_ciphers_tbl)); - msg += 2; - msglen -= 2; - len -= 2; - } - if (msglen < 1) - return 0; - len = msg[0]; - msg++; - msglen--; - if (msglen < len) - return 0; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "compression_methods (len=%d)\n", (int)len); - while (len > 0) { - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "%s (0x%02X)\n", - ssl_trace_str(msg[0], ssl_comp_tbl), msg[0]); - msg++; - msglen--; - len--; - } - if (!ssl_print_extensions(bio, indent, 0, msg, msglen)) - return 0; - return 1; -} - -static int dtls_print_hello_vfyrequest(BIO *bio, int indent, - const unsigned char *msg, - size_t msglen) -{ - if (!ssl_print_version(bio, indent, "server_version", &msg, &msglen)) - return 0; - if (!ssl_print_hexbuf(bio, indent, "cookie", 1, &msg, &msglen)) - return 0; - return 1; -} - -static int ssl_print_server_hello(BIO *bio, int indent, - const unsigned char *msg, size_t msglen) -{ - unsigned int cs; - if (!ssl_print_version(bio, indent, "server_version", &msg, &msglen)) - return 0; - if (!ssl_print_random(bio, indent, &msg, &msglen)) - return 0; - if (!ssl_print_hexbuf(bio, indent, "session_id", 1, &msg, &msglen)) - return 0; - if (msglen < 2) - return 0; - cs = (msg[0] << 8) | msg[1]; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "cipher_suite {0x%02X, 0x%02X} %s\n", - msg[0], msg[1], ssl_trace_str(cs, ssl_ciphers_tbl)); - msg += 2; - msglen -= 2; - if (msglen < 1) - return 0; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "compression_method: %s (0x%02X)\n", - ssl_trace_str(msg[0], ssl_comp_tbl), msg[0]); - msg++; - msglen--; - if (!ssl_print_extensions(bio, indent, 1, msg, msglen)) - return 0; - return 1; -} - -static int ssl_get_keyex(const char **pname, SSL *ssl) -{ - unsigned long alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey; - if (alg_k & SSL_kRSA) { - *pname = "rsa"; - return SSL_kRSA; - } - if (alg_k & SSL_kDHr) { - *pname = "dh_rsa"; - return SSL_kDHr; - } - if (alg_k & SSL_kDHd) { - *pname = "dh_dss"; - return SSL_kDHd; - } - if (alg_k & SSL_kKRB5) { - *pname = "krb5"; - return SSL_kKRB5; - } - if (alg_k & SSL_kEDH) { - *pname = "edh"; - return SSL_kEDH; - } - if (alg_k & SSL_kEECDH) { - *pname = "EECDH"; - return SSL_kEECDH; - } - if (alg_k & SSL_kECDHr) { - *pname = "ECDH RSA"; - return SSL_kECDHr; - } - if (alg_k & SSL_kECDHe) { - *pname = "ECDH ECDSA"; - return SSL_kECDHe; - } - if (alg_k & SSL_kPSK) { - *pname = "PSK"; - return SSL_kPSK; - } - if (alg_k & SSL_kSRP) { - *pname = "SRP"; - return SSL_kSRP; - } - if (alg_k & SSL_kGOST) { - *pname = "GOST"; - return SSL_kGOST; - } - *pname = "UNKNOWN"; - return 0; -} - -static int ssl_print_client_keyex(BIO *bio, int indent, SSL *ssl, - const unsigned char *msg, size_t msglen) -{ - const char *algname; - int id; - id = ssl_get_keyex(&algname, ssl); - BIO_indent(bio, indent, 80); - BIO_printf(bio, "KeyExchangeAlgorithm=%s\n", algname); - switch (id) { - - case SSL_kRSA: - if (TLS1_get_version(ssl) == SSL3_VERSION) { - ssl_print_hex(bio, indent + 2, - "EncyptedPreMasterSecret", msg, msglen); - } else { - if (!ssl_print_hexbuf(bio, indent + 2, - "EncyptedPreMasterSecret", 2, - &msg, &msglen)) - return 0; - } - break; - - /* Implicit parameters only allowed for static DH */ - case SSL_kDHd: - case SSL_kDHr: - if (msglen == 0) { - BIO_indent(bio, indent + 2, 80); - BIO_puts(bio, "implicit\n"); - break; - } - case SSL_kEDH: - if (!ssl_print_hexbuf(bio, indent + 2, "dh_Yc", 2, &msg, &msglen)) - return 0; - break; - - case SSL_kECDHr: - case SSL_kECDHe: - if (msglen == 0) { - BIO_indent(bio, indent + 2, 80); - BIO_puts(bio, "implicit\n"); - break; - } - case SSL_kEECDH: - if (!ssl_print_hexbuf(bio, indent + 2, "ecdh_Yc", 1, &msg, &msglen)) - return 0; - break; - } - - return 1; -} - -static int ssl_print_server_keyex(BIO *bio, int indent, SSL *ssl, - const unsigned char *msg, size_t msglen) -{ - const char *algname; - int id; - id = ssl_get_keyex(&algname, ssl); - BIO_indent(bio, indent, 80); - BIO_printf(bio, "KeyExchangeAlgorithm=%s\n", algname); - switch (id) { - /* Should never happen */ - case SSL_kDHd: - case SSL_kDHr: - case SSL_kECDHr: - case SSL_kECDHe: - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "Unexpected Message\n"); - break; - - case SSL_kRSA: - - if (!ssl_print_hexbuf(bio, indent + 2, "rsa_modulus", 2, - &msg, &msglen)) - return 0; - if (!ssl_print_hexbuf(bio, indent + 2, "rsa_exponent", 2, - &msg, &msglen)) - return 0; - break; - - case SSL_kEDH: - if (!ssl_print_hexbuf(bio, indent + 2, "dh_p", 2, &msg, &msglen)) - return 0; - if (!ssl_print_hexbuf(bio, indent + 2, "dh_g", 2, &msg, &msglen)) - return 0; - if (!ssl_print_hexbuf(bio, indent + 2, "dh_Ys", 2, &msg, &msglen)) - return 0; - break; - - case SSL_kEECDH: - if (msglen < 1) - return 0; - BIO_indent(bio, indent + 2, 80); - if (msg[0] == EXPLICIT_PRIME_CURVE_TYPE) - BIO_puts(bio, "explicit_prime\n"); - else if (msg[0] == EXPLICIT_CHAR2_CURVE_TYPE) - BIO_puts(bio, "explicit_char2\n"); - else if (msg[0] == NAMED_CURVE_TYPE) { - int curve; - if (msglen < 3) - return 0; - curve = (msg[1] << 8) | msg[2]; - BIO_printf(bio, "named_curve: %s (%d)\n", - ssl_trace_str(curve, ssl_curve_tbl), curve); - msg += 3; - msglen -= 3; - if (!ssl_print_hexbuf(bio, indent + 2, "point", 1, &msg, &msglen)) - return 0; - } - break; - } - return ssl_print_signature(bio, indent, ssl, &msg, &msglen); -} - -static int ssl_print_certificate(BIO *bio, int indent, - const unsigned char **pmsg, size_t *pmsglen) -{ - size_t msglen = *pmsglen; - size_t clen; - X509 *x; - const unsigned char *p = *pmsg, *q; - if (msglen < 3) - return 0; - clen = (p[0] << 16) | (p[1] << 8) | p[2]; - if (msglen < clen + 3) - return 0; - q = p + 3; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "ASN.1Cert, length=%d", (int)clen); - x = d2i_X509(NULL, &q, clen); - if (!x) - BIO_puts(bio, "<UNPARSEABLE CERTIFICATE>\n"); - else { - BIO_puts(bio, "\n------details-----\n"); - X509_print_ex(bio, x, XN_FLAG_ONELINE, 0); - PEM_write_bio_X509(bio, x); - /* Print certificate stuff */ - BIO_puts(bio, "------------------\n"); - X509_free(x); - } - if (q != p + 3 + clen) { - BIO_puts(bio, "<TRAILING GARBAGE AFTER CERTIFICATE>\n"); - } - *pmsg += clen + 3; - *pmsglen -= clen + 3; - return 1; -} - -static int ssl_print_certificates(BIO *bio, int indent, - const unsigned char *msg, size_t msglen) -{ - size_t clen; - if (msglen < 3) - return 0; - clen = (msg[0] << 16) | (msg[1] << 8) | msg[2]; - if (msglen != clen + 3) - return 0; - msg += 3; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "certificate_list, length=%d\n", (int)clen); - while (clen > 0) { - if (!ssl_print_certificate(bio, indent + 2, &msg, &clen)) - return 0; - } - return 1; -} - -static int ssl_print_cert_request(BIO *bio, int indent, SSL *s, - const unsigned char *msg, size_t msglen) -{ - size_t xlen; - if (msglen < 1) - return 0; - xlen = msg[0]; - if (msglen < xlen + 1) - return 0; - msg++; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "certificate_types (len=%d)\n", (int)xlen); - if (!ssl_trace_list(bio, indent + 2, msg, xlen, 1, ssl_ctype_tbl)) - return 0; - msg += xlen; - msglen -= xlen + 1; - if (!SSL_USE_SIGALGS(s)) - goto skip_sig; - if (msglen < 2) - return 0; - xlen = (msg[0] << 8) | msg[1]; - if (msglen < xlen + 2 || (xlen & 1)) - return 0; - msg += 2; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "signature_algorithms (len=%d)\n", (int)xlen); - while (xlen > 0) { - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "%s+%s (%d+%d)\n", - ssl_trace_str(msg[0], ssl_md_tbl), - ssl_trace_str(msg[1], ssl_sig_tbl), msg[0], msg[1]); - xlen -= 2; - msg += 2; - } - msg += xlen; - msglen -= xlen + 2; - - skip_sig: - xlen = (msg[0] << 8) | msg[1]; - BIO_indent(bio, indent, 80); - if (msglen < xlen + 2) - return 0; - msg += 2; - msglen -= 2; - BIO_printf(bio, "certificate_authorities (len=%d)\n", (int)xlen); - while (xlen > 0) { - size_t dlen; - X509_NAME *nm; - const unsigned char *p; - if (xlen < 2) - return 0; - dlen = (msg[0] << 8) | msg[1]; - if (xlen < dlen + 2) - return 0; - msg += 2; - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "DistinguishedName (len=%d): ", (int)dlen); - p = msg; - nm = d2i_X509_NAME(NULL, &p, dlen); - if (!nm) { - BIO_puts(bio, "<UNPARSEABLE DN>\n"); - } else { - X509_NAME_print_ex(bio, nm, 0, XN_FLAG_ONELINE); - BIO_puts(bio, "\n"); - X509_NAME_free(nm); - } - xlen -= dlen + 2; - msg += dlen; - } - return 1; -} - -static int ssl_print_ticket(BIO *bio, int indent, - const unsigned char *msg, size_t msglen) -{ - unsigned int tick_life; - if (msglen == 0) { - BIO_indent(bio, indent + 2, 80); - BIO_puts(bio, "No Ticket\n"); - return 1; - } - if (msglen < 4) - return 0; - tick_life = (msg[0] << 24) | (msg[1] << 16) | (msg[2] << 8) | msg[3]; - msglen -= 4; - msg += 4; - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "ticket_lifetime_hint=%u\n", tick_life); - if (!ssl_print_hexbuf(bio, indent + 2, "ticket", 2, &msg, &msglen)) - return 0; - if (msglen) - return 0; - return 1; -} - -static int ssl_print_handshake(BIO *bio, SSL *ssl, - const unsigned char *msg, size_t msglen, - int indent) -{ - size_t hlen; - unsigned char htype; - if (msglen < 4) - return 0; - htype = msg[0]; - hlen = (msg[1] << 16) | (msg[2] << 8) | msg[3]; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "%s, Length=%d\n", - ssl_trace_str(htype, ssl_handshake_tbl), (int)hlen); - msg += 4; - msglen -= 4; - if (SSL_IS_DTLS(ssl)) { - if (msglen < 8) - return 0; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "message_seq=%d, fragment_offset=%d, " - "fragment_length=%d\n", - (msg[0] << 8) | msg[1], - (msg[2] << 16) | (msg[3] << 8) | msg[4], - (msg[5] << 16) | (msg[6] << 8) | msg[7]); - msg += 8; - msglen -= 8; - } - if (msglen < hlen) - return 0; - switch (htype) { - case SSL3_MT_CLIENT_HELLO: - if (!ssl_print_client_hello(bio, ssl, indent + 2, msg, msglen)) - return 0; - break; - - case DTLS1_MT_HELLO_VERIFY_REQUEST: - if (!dtls_print_hello_vfyrequest(bio, indent + 2, msg, msglen)) - return 0; - break; - - case SSL3_MT_SERVER_HELLO: - if (!ssl_print_server_hello(bio, indent + 2, msg, msglen)) - return 0; - break; - - case SSL3_MT_SERVER_KEY_EXCHANGE: - if (!ssl_print_server_keyex(bio, indent + 2, ssl, msg, msglen)) - return 0; - break; - - case SSL3_MT_CLIENT_KEY_EXCHANGE: - if (!ssl_print_client_keyex(bio, indent + 2, ssl, msg, msglen)) - return 0; - break; - - case SSL3_MT_CERTIFICATE: - if (!ssl_print_certificates(bio, indent + 2, msg, msglen)) - return 0; - break; - - case SSL3_MT_CERTIFICATE_VERIFY: - if (!ssl_print_signature(bio, indent + 2, ssl, &msg, &msglen)) - return 0; - break; - - case SSL3_MT_CERTIFICATE_REQUEST: - if (!ssl_print_cert_request(bio, indent + 2, ssl, msg, msglen)) - return 0; - break; - - case SSL3_MT_FINISHED: - ssl_print_hex(bio, indent + 2, "verify_data", msg, msglen); - break; - - case SSL3_MT_SERVER_DONE: - if (msglen != 0) - ssl_print_hex(bio, indent + 2, "unexpected value", msg, msglen); - break; - - case SSL3_MT_NEWSESSION_TICKET: - if (!ssl_print_ticket(bio, indent + 2, msg, msglen)) - return 0; - break; - - default: - BIO_indent(bio, indent + 2, 80); - BIO_puts(bio, "Unsupported, hex dump follows:\n"); - BIO_dump_indent(bio, (char *)msg, msglen, indent + 4); - } - return 1; -} - -static int ssl_print_heartbeat(BIO *bio, int indent, - const unsigned char *msg, size_t msglen) -{ - if (msglen < 3) - return 0; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "HeartBeatMessageType: %s\n", - ssl_trace_str(msg[0], ssl_hb_type_tbl)); - msg++; - msglen--; - if (!ssl_print_hexbuf(bio, indent, "payload", 2, &msg, &msglen)) - return 0; - ssl_print_hex(bio, indent, "padding", msg, msglen); - return 1; -} - -const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c) -{ - if (c->algorithm_ssl & SSL_SSLV2) - return NULL; - return ssl_trace_str(c->id & 0xFFFF, ssl_ciphers_tbl); -} - -void SSL_trace(int write_p, int version, int content_type, - const void *buf, size_t msglen, SSL *ssl, void *arg) -{ - const unsigned char *msg = buf; - BIO *bio = arg; - - if (write_p == 2) { - BIO_puts(bio, "Session "); - ssl_print_hex(bio, 0, - ssl_trace_str(content_type, ssl_crypto_tbl), - msg, msglen); - return; - } - switch (content_type) { - case SSL3_RT_HEADER: - { - int hvers = msg[1] << 8 | msg[2]; - BIO_puts(bio, write_p ? "Sent" : "Received"); - BIO_printf(bio, " Record\nHeader:\n Version = %s (0x%x)\n", - ssl_trace_str(hvers, ssl_version_tbl), hvers); - if (SSL_IS_DTLS(ssl)) { - BIO_printf(bio, - " epoch=%d, sequence_number=%04x%04x%04x\n", - (msg[3] << 8 | msg[4]), - (msg[5] << 8 | msg[6]), - (msg[7] << 8 | msg[8]), (msg[9] << 8 | msg[10])); -# if 0 - /* - * Just print handshake type so we can see what is going on - * during fragmentation. - */ - BIO_printf(bio, "(%s)\n", - ssl_trace_str(msg[msglen], ssl_handshake_tbl)); -# endif - } - - BIO_printf(bio, " Content Type = %s (%d)\n Length = %d", - ssl_trace_str(msg[0], ssl_content_tbl), msg[0], - msg[msglen - 2] << 8 | msg[msglen - 1]); - } - break; - case SSL3_RT_HANDSHAKE: - if (!ssl_print_handshake(bio, ssl, msg, msglen, 4)) - BIO_printf(bio, "Message length parse error!\n"); - break; - - case SSL3_RT_CHANGE_CIPHER_SPEC: - if (msglen == 1 && msg[0] == 1) - BIO_puts(bio, " change_cipher_spec (1)\n"); - else - ssl_print_hex(bio, 4, "unknown value", msg, msglen); - break; - - case SSL3_RT_ALERT: - if (msglen != 2) - BIO_puts(bio, " Illegal Alert Length\n"); - else { - BIO_printf(bio, " Level=%s(%d), description=%s(%d)\n", - SSL_alert_type_string_long(msg[0] << 8), - msg[0], SSL_alert_desc_string_long(msg[1]), msg[1]); - } - case TLS1_RT_HEARTBEAT: - ssl_print_heartbeat(bio, 4, msg, msglen); - break; - - } - - BIO_puts(bio, "\n"); -} - -#endif diff --git a/thirdparty/openssl/ssl/tls_srp.c b/thirdparty/openssl/ssl/tls_srp.c deleted file mode 100644 index bb719ba4cf..0000000000 --- a/thirdparty/openssl/ssl/tls_srp.c +++ /dev/null @@ -1,542 +0,0 @@ -/* ssl/tls_srp.c */ -/* - * Written by Christophe Renou (christophe.renou@edelweb.fr) with the - * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the - * EdelKey project and contributed to the OpenSSL project 2004. - */ -/* ==================================================================== - * Copyright (c) 2004-2011 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). - * - */ -#include "ssl_locl.h" -#ifndef OPENSSL_NO_SRP - -# include <openssl/rand.h> -# include <openssl/srp.h> -# include <openssl/err.h> - -int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx) -{ - if (ctx == NULL) - return 0; - OPENSSL_free(ctx->srp_ctx.login); - BN_free(ctx->srp_ctx.N); - BN_free(ctx->srp_ctx.g); - BN_free(ctx->srp_ctx.s); - BN_free(ctx->srp_ctx.B); - BN_free(ctx->srp_ctx.A); - BN_free(ctx->srp_ctx.a); - BN_free(ctx->srp_ctx.b); - BN_free(ctx->srp_ctx.v); - ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; - ctx->srp_ctx.SRP_cb_arg = NULL; - ctx->srp_ctx.SRP_verify_param_callback = NULL; - ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; - ctx->srp_ctx.N = NULL; - ctx->srp_ctx.g = NULL; - ctx->srp_ctx.s = NULL; - ctx->srp_ctx.B = NULL; - ctx->srp_ctx.A = NULL; - ctx->srp_ctx.a = NULL; - ctx->srp_ctx.b = NULL; - ctx->srp_ctx.v = NULL; - ctx->srp_ctx.login = NULL; - ctx->srp_ctx.info = NULL; - ctx->srp_ctx.strength = SRP_MINIMAL_N; - ctx->srp_ctx.srp_Mask = 0; - return (1); -} - -int SSL_SRP_CTX_free(struct ssl_st *s) -{ - if (s == NULL) - return 0; - OPENSSL_free(s->srp_ctx.login); - BN_free(s->srp_ctx.N); - BN_free(s->srp_ctx.g); - BN_free(s->srp_ctx.s); - BN_free(s->srp_ctx.B); - BN_free(s->srp_ctx.A); - BN_free(s->srp_ctx.a); - BN_free(s->srp_ctx.b); - BN_free(s->srp_ctx.v); - s->srp_ctx.TLS_ext_srp_username_callback = NULL; - s->srp_ctx.SRP_cb_arg = NULL; - s->srp_ctx.SRP_verify_param_callback = NULL; - s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; - s->srp_ctx.N = NULL; - s->srp_ctx.g = NULL; - s->srp_ctx.s = NULL; - s->srp_ctx.B = NULL; - s->srp_ctx.A = NULL; - s->srp_ctx.a = NULL; - s->srp_ctx.b = NULL; - s->srp_ctx.v = NULL; - s->srp_ctx.login = NULL; - s->srp_ctx.info = NULL; - s->srp_ctx.strength = SRP_MINIMAL_N; - s->srp_ctx.srp_Mask = 0; - return (1); -} - -int SSL_SRP_CTX_init(struct ssl_st *s) -{ - SSL_CTX *ctx; - - if ((s == NULL) || ((ctx = s->ctx) == NULL)) - return 0; - s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg; - /* set client Hello login callback */ - s->srp_ctx.TLS_ext_srp_username_callback = - ctx->srp_ctx.TLS_ext_srp_username_callback; - /* set SRP N/g param callback for verification */ - s->srp_ctx.SRP_verify_param_callback = - ctx->srp_ctx.SRP_verify_param_callback; - /* set SRP client passwd callback */ - s->srp_ctx.SRP_give_srp_client_pwd_callback = - ctx->srp_ctx.SRP_give_srp_client_pwd_callback; - - s->srp_ctx.N = NULL; - s->srp_ctx.g = NULL; - s->srp_ctx.s = NULL; - s->srp_ctx.B = NULL; - s->srp_ctx.A = NULL; - s->srp_ctx.a = NULL; - s->srp_ctx.b = NULL; - s->srp_ctx.v = NULL; - s->srp_ctx.login = NULL; - s->srp_ctx.info = ctx->srp_ctx.info; - s->srp_ctx.strength = ctx->srp_ctx.strength; - - if (((ctx->srp_ctx.N != NULL) && - ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) || - ((ctx->srp_ctx.g != NULL) && - ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) || - ((ctx->srp_ctx.s != NULL) && - ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) || - ((ctx->srp_ctx.B != NULL) && - ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) || - ((ctx->srp_ctx.A != NULL) && - ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) || - ((ctx->srp_ctx.a != NULL) && - ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) || - ((ctx->srp_ctx.v != NULL) && - ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) || - ((ctx->srp_ctx.b != NULL) && - ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL))) { - SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_BN_LIB); - goto err; - } - if ((ctx->srp_ctx.login != NULL) && - ((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL)) { - SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_INTERNAL_ERROR); - goto err; - } - s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask; - - return (1); - err: - OPENSSL_free(s->srp_ctx.login); - BN_free(s->srp_ctx.N); - BN_free(s->srp_ctx.g); - BN_free(s->srp_ctx.s); - BN_free(s->srp_ctx.B); - BN_free(s->srp_ctx.A); - BN_free(s->srp_ctx.a); - BN_free(s->srp_ctx.b); - BN_free(s->srp_ctx.v); - return (0); -} - -int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx) -{ - if (ctx == NULL) - return 0; - - ctx->srp_ctx.SRP_cb_arg = NULL; - /* set client Hello login callback */ - ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; - /* set SRP N/g param callback for verification */ - ctx->srp_ctx.SRP_verify_param_callback = NULL; - /* set SRP client passwd callback */ - ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; - - ctx->srp_ctx.N = NULL; - ctx->srp_ctx.g = NULL; - ctx->srp_ctx.s = NULL; - ctx->srp_ctx.B = NULL; - ctx->srp_ctx.A = NULL; - ctx->srp_ctx.a = NULL; - ctx->srp_ctx.b = NULL; - ctx->srp_ctx.v = NULL; - ctx->srp_ctx.login = NULL; - ctx->srp_ctx.srp_Mask = 0; - ctx->srp_ctx.info = NULL; - ctx->srp_ctx.strength = SRP_MINIMAL_N; - - return (1); -} - -/* server side */ -int SSL_srp_server_param_with_username(SSL *s, int *ad) -{ - unsigned char b[SSL_MAX_MASTER_KEY_LENGTH]; - int al; - - *ad = SSL_AD_UNKNOWN_PSK_IDENTITY; - if ((s->srp_ctx.TLS_ext_srp_username_callback != NULL) && - ((al = - s->srp_ctx.TLS_ext_srp_username_callback(s, ad, - s->srp_ctx.SRP_cb_arg)) != - SSL_ERROR_NONE)) - return al; - - *ad = SSL_AD_INTERNAL_ERROR; - if ((s->srp_ctx.N == NULL) || - (s->srp_ctx.g == NULL) || - (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL)) - return SSL3_AL_FATAL; - - if (RAND_bytes(b, sizeof(b)) <= 0) - return SSL3_AL_FATAL; - s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL); - OPENSSL_cleanse(b, sizeof(b)); - - /* Calculate: B = (kv + g^b) % N */ - - return ((s->srp_ctx.B = - SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, - s->srp_ctx.v)) != - NULL) ? SSL_ERROR_NONE : SSL3_AL_FATAL; -} - -/* - * If the server just has the raw password, make up a verifier entry on the - * fly - */ -int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, - const char *grp) -{ - SRP_gN *GN = SRP_get_default_gN(grp); - if (GN == NULL) - return -1; - s->srp_ctx.N = BN_dup(GN->N); - s->srp_ctx.g = BN_dup(GN->g); - if (s->srp_ctx.v != NULL) { - BN_clear_free(s->srp_ctx.v); - s->srp_ctx.v = NULL; - } - if (s->srp_ctx.s != NULL) { - BN_clear_free(s->srp_ctx.s); - s->srp_ctx.s = NULL; - } - if (!SRP_create_verifier_BN - (user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) - return -1; - - return 1; -} - -int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, - BIGNUM *sa, BIGNUM *v, char *info) -{ - if (N != NULL) { - if (s->srp_ctx.N != NULL) { - if (!BN_copy(s->srp_ctx.N, N)) { - BN_free(s->srp_ctx.N); - s->srp_ctx.N = NULL; - } - } else - s->srp_ctx.N = BN_dup(N); - } - if (g != NULL) { - if (s->srp_ctx.g != NULL) { - if (!BN_copy(s->srp_ctx.g, g)) { - BN_free(s->srp_ctx.g); - s->srp_ctx.g = NULL; - } - } else - s->srp_ctx.g = BN_dup(g); - } - if (sa != NULL) { - if (s->srp_ctx.s != NULL) { - if (!BN_copy(s->srp_ctx.s, sa)) { - BN_free(s->srp_ctx.s); - s->srp_ctx.s = NULL; - } - } else - s->srp_ctx.s = BN_dup(sa); - } - if (v != NULL) { - if (s->srp_ctx.v != NULL) { - if (!BN_copy(s->srp_ctx.v, v)) { - BN_free(s->srp_ctx.v); - s->srp_ctx.v = NULL; - } - } else - s->srp_ctx.v = BN_dup(v); - } - s->srp_ctx.info = info; - - if (!(s->srp_ctx.N) || - !(s->srp_ctx.g) || !(s->srp_ctx.s) || !(s->srp_ctx.v)) - return -1; - - return 1; -} - -int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key) -{ - BIGNUM *K = NULL, *u = NULL; - int ret = -1, tmp_len; - unsigned char *tmp = NULL; - - if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N)) - goto err; - if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N))) - goto err; - if (! - (K = - SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, - s->srp_ctx.N))) - goto err; - - tmp_len = BN_num_bytes(K); - if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) - goto err; - BN_bn2bin(K, tmp); - ret = - s->method->ssl3_enc->generate_master_secret(s, master_key, tmp, - tmp_len); - err: - if (tmp) { - OPENSSL_cleanse(tmp, tmp_len); - OPENSSL_free(tmp); - } - BN_clear_free(K); - BN_clear_free(u); - return ret; -} - -/* client side */ -int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key) -{ - BIGNUM *x = NULL, *u = NULL, *K = NULL; - int ret = -1, tmp_len; - char *passwd = NULL; - unsigned char *tmp = NULL; - - /* - * Checks if b % n == 0 - */ - if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0) - goto err; - if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N))) - goto err; - if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) - goto err; - if (! - (passwd = - s->srp_ctx.SRP_give_srp_client_pwd_callback(s, - s->srp_ctx.SRP_cb_arg))) - goto err; - if (!(x = SRP_Calc_x(s->srp_ctx.s, s->srp_ctx.login, passwd))) - goto err; - if (! - (K = - SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, - s->srp_ctx.a, u))) - goto err; - - tmp_len = BN_num_bytes(K); - if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) - goto err; - BN_bn2bin(K, tmp); - ret = - s->method->ssl3_enc->generate_master_secret(s, master_key, tmp, - tmp_len); - err: - if (tmp) { - OPENSSL_cleanse(tmp, tmp_len); - OPENSSL_free(tmp); - } - BN_clear_free(K); - BN_clear_free(x); - if (passwd) { - OPENSSL_cleanse(passwd, strlen(passwd)); - OPENSSL_free(passwd); - } - BN_clear_free(u); - return ret; -} - -int srp_verify_server_param(SSL *s, int *al) -{ - SRP_CTX *srp = &s->srp_ctx; - /* - * Sanity check parameters: we can quickly check B % N == 0 by checking B - * != 0 since B < N - */ - if (BN_ucmp(srp->g, srp->N) >= 0 || BN_ucmp(srp->B, srp->N) >= 0 - || BN_is_zero(srp->B)) { - *al = SSL3_AD_ILLEGAL_PARAMETER; - return 0; - } - - if (BN_num_bits(srp->N) < srp->strength) { - *al = TLS1_AD_INSUFFICIENT_SECURITY; - return 0; - } - - if (srp->SRP_verify_param_callback) { - if (srp->SRP_verify_param_callback(s, srp->SRP_cb_arg) <= 0) { - *al = TLS1_AD_INSUFFICIENT_SECURITY; - return 0; - } - } else if (!SRP_check_known_gN_param(srp->g, srp->N)) { - *al = TLS1_AD_INSUFFICIENT_SECURITY; - return 0; - } - - return 1; -} - -int SRP_Calc_A_param(SSL *s) -{ - unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH]; - - if (RAND_bytes(rnd, sizeof(rnd)) <= 0) - return -1; - s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a); - OPENSSL_cleanse(rnd, sizeof(rnd)); - - if (! - (s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a, s->srp_ctx.N, s->srp_ctx.g))) - return -1; - - return 1; -} - -BIGNUM *SSL_get_srp_g(SSL *s) -{ - if (s->srp_ctx.g != NULL) - return s->srp_ctx.g; - return s->ctx->srp_ctx.g; -} - -BIGNUM *SSL_get_srp_N(SSL *s) -{ - if (s->srp_ctx.N != NULL) - return s->srp_ctx.N; - return s->ctx->srp_ctx.N; -} - -char *SSL_get_srp_username(SSL *s) -{ - if (s->srp_ctx.login != NULL) - return s->srp_ctx.login; - return s->ctx->srp_ctx.login; -} - -char *SSL_get_srp_userinfo(SSL *s) -{ - if (s->srp_ctx.info != NULL) - return s->srp_ctx.info; - return s->ctx->srp_ctx.info; -} - -# define tls1_ctx_ctrl ssl3_ctx_ctrl -# define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl - -int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name) -{ - return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name); -} - -int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password) -{ - return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password); -} - -int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength) -{ - return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength, - NULL); -} - -int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, - int (*cb) (SSL *, void *)) -{ - return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB, - (void (*)(void))cb); -} - -int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg) -{ - return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_SRP_ARG, 0, arg); -} - -int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, - int (*cb) (SSL *, int *, void *)) -{ - return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB, - (void (*)(void))cb); -} - -int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, - char *(*cb) (SSL *, void *)) -{ - return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB, - (void (*)(void))cb); -} - -#endif |