original files of m241
This commit is contained in:
@@ -0,0 +1,585 @@
|
||||
/* 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 <time.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:
|
||||
/* ugly bit of a hack */
|
||||
if (ssl->rbio != ssl->wbio) { /* we are in trouble :-( */
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if (ret != NULL)
|
||||
BIO_free(ret);
|
||||
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;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,250 @@
|
||||
/* ssl/d1_enc.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 "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
|
||||
|
||||
/*-
|
||||
* dtls1_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 dtls1_enc(SSL *s, int send)
|
||||
{
|
||||
SSL3_RECORD *rec;
|
||||
EVP_CIPHER_CTX *ds;
|
||||
unsigned long l;
|
||||
int bs, i, j, k, mac_size = 0;
|
||||
const EVP_CIPHER *enc;
|
||||
|
||||
if (send) {
|
||||
if (s->write_hash) {
|
||||
mac_size = EVP_MD_size(s->write_hash);
|
||||
if (mac_size < 0)
|
||||
return -1;
|
||||
}
|
||||
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);
|
||||
if (rec->data != rec->input)
|
||||
/* we can't write into the input stream */
|
||||
fprintf(stderr, "%s:%d: rec->data != rec->input\n",
|
||||
__FILE__, __LINE__);
|
||||
else if (EVP_CIPHER_block_size(ds->cipher) > 1) {
|
||||
if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher))
|
||||
<= 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (s->read_hash) {
|
||||
mac_size = EVP_MD_size(s->read_hash);
|
||||
OPENSSL_assert(mac_size >= 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
|
||||
printf("dtls1_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;
|
||||
} else {
|
||||
l = rec->length;
|
||||
bs = EVP_CIPHER_block_size(ds->cipher);
|
||||
|
||||
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;
|
||||
printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
|
||||
(void *)ds, rec->data, rec->input, l);
|
||||
printf
|
||||
("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n",
|
||||
ds->buf_len, ds->cipher->key_len, (unsigned long)DES_KEY_SZ,
|
||||
(unsigned long)DES_SCHEDULE_SZ, ds->cipher->iv_len);
|
||||
printf("\t\tIV: ");
|
||||
for (i = 0; i < ds->cipher->iv_len; i++)
|
||||
printf("%02X", ds->iv[i]);
|
||||
printf("\n");
|
||||
printf("\trec->input=");
|
||||
for (ui = 0; ui < l; ui++)
|
||||
printf(" %02x", rec->input[ui]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif /* KSSL_DEBUG */
|
||||
|
||||
if (!send) {
|
||||
if (l == 0 || l % bs != 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVP_Cipher(ds, rec->data, rec->input, l);
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
{
|
||||
unsigned long ki;
|
||||
printf("\trec->data=");
|
||||
for (ki = 0; ki < l; ki++)
|
||||
printf(" %02x", rec->data[ki]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif /* KSSL_DEBUG */
|
||||
|
||||
if ((bs != 1) && !send)
|
||||
return tls1_cbc_remove_padding(s, rec, bs, mac_size);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
@@ -0,0 +1,512 @@
|
||||
/* 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>
|
||||
#include <sys/socket.h>
|
||||
#define USE_SOCKETS
|
||||
#include <openssl/objects.h>
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
|
||||
# include <sys/timeb.h>
|
||||
#endif
|
||||
|
||||
static void get_current_time(struct timeval *t);
|
||||
const char dtls1_version_str[] = "DTLSv1" OPENSSL_VERSION_PTEXT;
|
||||
int dtls1_listen(SSL *s, struct sockaddr *client);
|
||||
|
||||
SSL3_ENC_METHOD DTLSv1_enc_data = {
|
||||
dtls1_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,
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
IMPLEMENT_dtls1_meth_func(dtlsv1_base_method,
|
||||
ssl_undefined_function,
|
||||
ssl_undefined_function, ssl_bad_method)
|
||||
|
||||
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; */
|
||||
#if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST)
|
||||
d1->bitmap.length = 64;
|
||||
#else
|
||||
d1->bitmap.length = sizeof(d1->bitmap.map) * 8;
|
||||
#endif
|
||||
pq_64bit_init(&(d1->bitmap.map));
|
||||
pq_64bit_init(&(d1->bitmap.max_seq_num));
|
||||
|
||||
d1->next_bitmap.length = d1->bitmap.length;
|
||||
pq_64bit_init(&(d1->next_bitmap.map));
|
||||
pq_64bit_init(&(d1->next_bitmap.max_seq_num));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
hm_fragment *frag = 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_messages)) != NULL) {
|
||||
frag = (hm_fragment *)item->data;
|
||||
OPENSSL_free(frag->fragment);
|
||||
OPENSSL_free(frag);
|
||||
pitem_free(item);
|
||||
}
|
||||
|
||||
while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) {
|
||||
frag = (hm_fragment *)item->data;
|
||||
OPENSSL_free(frag->fragment);
|
||||
OPENSSL_free(frag);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
pq_64bit_free(&(s->d1->bitmap.map));
|
||||
pq_64bit_free(&(s->d1->bitmap.max_seq_num));
|
||||
|
||||
pq_64bit_free(&(s->d1->next_bitmap.map));
|
||||
pq_64bit_free(&(s->d1->next_bitmap.max_seq_num));
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
dtls1_clear_queues(s);
|
||||
|
||||
pq_64bit_free(&(s->d1->bitmap.map));
|
||||
pq_64bit_free(&(s->d1->bitmap.max_seq_num));
|
||||
|
||||
pq_64bit_free(&(s->d1->next_bitmap.map));
|
||||
pq_64bit_free(&(s->d1->next_bitmap.max_seq_num));
|
||||
|
||||
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->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;
|
||||
|
||||
#if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST)
|
||||
s->d1->bitmap.length = 64;
|
||||
#else
|
||||
s->d1->bitmap.length = sizeof(s->d1->bitmap.map) * 8;
|
||||
#endif
|
||||
pq_64bit_init(&(s->d1->bitmap.map));
|
||||
pq_64bit_init(&(s->d1->bitmap.max_seq_num));
|
||||
|
||||
s->d1->next_bitmap.length = s->d1->bitmap.length;
|
||||
pq_64bit_init(&(s->d1->next_bitmap.map));
|
||||
pq_64bit_init(&(s->d1->next_bitmap.max_seq_num));
|
||||
}
|
||||
|
||||
ssl3_clear(s);
|
||||
if (s->options & SSL_OP_CISCO_ANYCONNECT)
|
||||
s->version = DTLS1_BAD_VER;
|
||||
else
|
||||
s->version = DTLS1_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 DTLS_MAX_VERSION != DTLS1_VERSION
|
||||
# error Code needs update for DTLS_method() support beyond DTLS1_VERSION.
|
||||
#endif
|
||||
/*
|
||||
* Just one protocol version is supported so far; fail closed if the
|
||||
* version is not as expected.
|
||||
*/
|
||||
return s->version == DTLS_MAX_VERSION;
|
||||
|
||||
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...
|
||||
*/
|
||||
SSL_CIPHER *dtls1_get_cipher(unsigned int u)
|
||||
{
|
||||
SSL_CIPHER *ciph = ssl3_get_cipher(u);
|
||||
|
||||
if (ciph != NULL) {
|
||||
if ((ciph->algorithms & SSL_ENC_MASK) == SSL_RC4)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ciph;
|
||||
}
|
||||
|
||||
void dtls1_start_timer(SSL *s)
|
||||
{
|
||||
/* 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_record_buffer(s);
|
||||
}
|
||||
|
||||
int dtls1_check_timeout_num(SSL *s)
|
||||
{
|
||||
s->d1->timeout.num_alerts++;
|
||||
|
||||
/* Reduce MTU after 2 unsuccessful retransmissions */
|
||||
if (s->d1->timeout.num_alerts > 2) {
|
||||
s->d1->mtu =
|
||||
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
dtls1_start_timer(s);
|
||||
return dtls1_retransmit_buffered_messages(s);
|
||||
}
|
||||
|
||||
static void get_current_time(struct timeval *t)
|
||||
{
|
||||
#ifdef OPENSSL_SYS_WIN32
|
||||
struct _timeb tb;
|
||||
_ftime(&tb);
|
||||
t->tv_sec = (long)tb.time;
|
||||
t->tv_usec = (long)tb.millitm * 1000;
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/* 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 SSL_METHOD *dtls1_get_method(int ver);
|
||||
static SSL_METHOD *dtls1_get_method(int ver)
|
||||
{
|
||||
if (ver == DTLS1_VERSION)
|
||||
return (DTLSv1_method());
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
IMPLEMENT_dtls1_meth_func(DTLSv1_method,
|
||||
dtls1_accept, dtls1_connect, dtls1_get_method)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,88 @@
|
||||
/* ssl/kssl.h -*- mode: C; c-file-style: "eay" -*- */
|
||||
/*
|
||||
* 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);
|
||||
|
||||
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 */
|
||||
@@ -0,0 +1,619 @@
|
||||
/* 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.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ssl_locl.h"
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
static SSL_METHOD *ssl23_get_client_method(int ver);
|
||||
static int ssl23_client_hello(SSL *s);
|
||||
static int ssl23_get_server_hello(SSL *s);
|
||||
static 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
|
||||
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;
|
||||
}
|
||||
|
||||
ssl3_init_finished_mac(s);
|
||||
|
||||
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_client_hello(SSL *s)
|
||||
{
|
||||
unsigned char *buf;
|
||||
unsigned char *p, *d;
|
||||
int i, ch_len;
|
||||
unsigned long Time, l;
|
||||
int ssl2_compat;
|
||||
int version = 0, version_major, version_minor;
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
int j;
|
||||
SSL_COMP *comp;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
ssl2_compat = (s->options & SSL_OP_NO_SSLv2) ? 0 : 1;
|
||||
|
||||
if (!(s->options & SSL_OP_NO_TLSv1)) {
|
||||
version = TLS1_VERSION;
|
||||
} else if (!(s->options & SSL_OP_NO_SSLv3)) {
|
||||
version = SSL3_VERSION;
|
||||
} else if (!(s->options & SSL_OP_NO_SSLv2)) {
|
||||
version = SSL2_VERSION;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
|
||||
buf = (unsigned char *)s->init_buf->data;
|
||||
if (s->state == SSL23_ST_CW_CLNT_HELLO_A) {
|
||||
#if 0
|
||||
/* don't reuse session-id's */
|
||||
if (!ssl_get_new_session(s, 0)) {
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
p = s->s3->client_random;
|
||||
Time = (unsigned long)time(NULL); /* Time */
|
||||
l2n(Time, p);
|
||||
if (RAND_pseudo_bytes(p, SSL3_RANDOM_SIZE - 4) <= 0)
|
||||
return -1;
|
||||
|
||||
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)
|
||||
*/
|
||||
#if 0
|
||||
s->session->session_id_length = 0;
|
||||
#endif
|
||||
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 */
|
||||
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_pseudo_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;
|
||||
}
|
||||
s2n(i, p);
|
||||
p += i;
|
||||
#ifdef OPENSSL_NO_COMP
|
||||
*(p++) = 1;
|
||||
#else
|
||||
/* COMPRESSION */
|
||||
if (s->ctx->comp_methods == NULL)
|
||||
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
|
||||
if ((p =
|
||||
ssl_add_clienthello_tlsext(s, p,
|
||||
buf +
|
||||
SSL3_RT_MAX_PLAIN_LENGTH)) ==
|
||||
NULL) {
|
||||
SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
l = p - d;
|
||||
*p = 42;
|
||||
|
||||
/* 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;
|
||||
*(d++) = version_minor; /* arguably we should send the *lowest*
|
||||
* suported version here (indicating,
|
||||
* e.g., TLS 1.0 in "SSL 3.0 format") */
|
||||
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_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 */
|
||||
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] == SSL3_VERSION_MINOR) ||
|
||||
(p[2] == TLS1_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 {
|
||||
SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* 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_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_buffers(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;
|
||||
|
||||
/*
|
||||
* Since, if we are sending a ssl23 client hello, we are not reusing a
|
||||
* session-id
|
||||
*/
|
||||
if (!ssl_get_new_session(s, 0))
|
||||
goto err;
|
||||
|
||||
return (SSL_connect(s));
|
||||
err:
|
||||
return (-1);
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/* 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);
|
||||
}
|
||||
|
||||
IMPLEMENT_ssl23_meth_func(sslv23_base_method,
|
||||
ssl_undefined_function,
|
||||
ssl_undefined_function, ssl_bad_method)
|
||||
|
||||
int ssl23_num_ciphers(void)
|
||||
{
|
||||
return (ssl3_num_ciphers()
|
||||
#ifndef OPENSSL_NO_SSL2
|
||||
+ ssl2_num_ciphers()
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p)
|
||||
{
|
||||
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->algorithms & (SSL_ECDH | 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/* 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 SSL_METHOD *ssl23_get_method(int ver);
|
||||
static 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
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
IMPLEMENT_ssl23_meth_func(SSLv23_method,
|
||||
ssl23_accept, ssl23_connect, ssl23_get_method)
|
||||
@@ -0,0 +1,113 @@
|
||||
/* 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>
|
||||
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,598 @@
|
||||
/* 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-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 <stdio.h>
|
||||
#include "ssl_locl.h"
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
static SSL_METHOD *ssl23_get_server_method(int ver);
|
||||
int ssl23_get_client_hello(SSL *s);
|
||||
static 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
|
||||
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)) {
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
s->init_buf = buf;
|
||||
}
|
||||
|
||||
ssl3_init_finished_mac(s);
|
||||
|
||||
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 (!(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 (!(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;
|
||||
}
|
||||
}
|
||||
#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
|
||||
|
||||
/* ensure that TLS_MAX_VERSION is up-to-date */
|
||||
OPENSSL_assert(s->version <= TLS_MAX_VERSION);
|
||||
|
||||
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) {
|
||||
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;
|
||||
|
||||
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)
|
||||
*/
|
||||
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;
|
||||
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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,194 @@
|
||||
/* 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 <stdio.h>
|
||||
#include "ssl_locl.h"
|
||||
#ifndef OPENSSL_NO_SSL2
|
||||
|
||||
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))
|
||||
{
|
||||
ssl2_return_error(s,SSL2_PE_NO_CIPHER);
|
||||
SSLerr(SSL_F_SSL2_ENC_INIT,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
|
||||
return(0);
|
||||
}
|
||||
|
||||
s->read_hash=md;
|
||||
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 */
|
||||
void 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;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
EVP_Cipher(ds,s->s2->mac_data,s->s2->mac_data,l);
|
||||
}
|
||||
|
||||
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_DigestInit_ex(&c, s->read_hash, NULL);
|
||||
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
|
||||
@@ -0,0 +1,480 @@
|
||||
/* 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.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ssl_locl.h"
|
||||
#ifndef OPENSSL_NO_SSL2
|
||||
#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 SSL_CIPHER ssl2_ciphers[]={
|
||||
/* NULL_WITH_MD5 v3 */
|
||||
#if 0
|
||||
{
|
||||
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,
|
||||
SSL_ALL_CIPHERS,
|
||||
SSL_ALL_STRENGTHS,
|
||||
},
|
||||
#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_EXP|SSL_MEDIUM,
|
||||
0,
|
||||
128,
|
||||
128,
|
||||
SSL_ALL_CIPHERS,
|
||||
SSL_ALL_STRENGTHS,
|
||||
},
|
||||
/* 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_EXPORT|SSL_EXP40,
|
||||
SSL2_CF_5_BYTE_ENC,
|
||||
40,
|
||||
128,
|
||||
SSL_ALL_CIPHERS,
|
||||
SSL_ALL_STRENGTHS,
|
||||
},
|
||||
/* 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_EXP|SSL_MEDIUM,
|
||||
0,
|
||||
128,
|
||||
128,
|
||||
SSL_ALL_CIPHERS,
|
||||
SSL_ALL_STRENGTHS,
|
||||
},
|
||||
/* 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_EXPORT|SSL_EXP40,
|
||||
SSL2_CF_5_BYTE_ENC,
|
||||
40,
|
||||
128,
|
||||
SSL_ALL_CIPHERS,
|
||||
SSL_ALL_STRENGTHS,
|
||||
},
|
||||
/* IDEA_128_CBC_WITH_MD5 */
|
||||
#ifndef OPENSSL_NO_IDEA
|
||||
{
|
||||
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_EXP|SSL_MEDIUM,
|
||||
0,
|
||||
128,
|
||||
128,
|
||||
SSL_ALL_CIPHERS,
|
||||
SSL_ALL_STRENGTHS,
|
||||
},
|
||||
#endif
|
||||
/* 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_EXP|SSL_LOW,
|
||||
0,
|
||||
56,
|
||||
56,
|
||||
SSL_ALL_CIPHERS,
|
||||
SSL_ALL_STRENGTHS,
|
||||
},
|
||||
/* 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_EXP|SSL_HIGH,
|
||||
0,
|
||||
168,
|
||||
168,
|
||||
SSL_ALL_CIPHERS,
|
||||
SSL_ALL_STRENGTHS,
|
||||
},
|
||||
/* RC4_64_WITH_MD5 */
|
||||
#if 0
|
||||
{
|
||||
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_EXP|SSL_LOW,
|
||||
SSL2_CF_8_BYTE_ENC,
|
||||
64,
|
||||
64,
|
||||
SSL_ALL_CIPHERS,
|
||||
SSL_ALL_STRENGTHS,
|
||||
},
|
||||
#endif
|
||||
/* NULL SSLeay (testing) */
|
||||
#if 0
|
||||
{
|
||||
0,
|
||||
SSL2_TXT_NULL,
|
||||
SSL2_CK_NULL,
|
||||
0,
|
||||
SSL_STRONG_NONE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
SSL_ALL_CIPHERS,
|
||||
SSL_ALL_STRENGTHS,
|
||||
},
|
||||
#endif
|
||||
|
||||
/* end of list :-) */
|
||||
};
|
||||
|
||||
long ssl2_default_timeout(void)
|
||||
{
|
||||
return(300);
|
||||
}
|
||||
|
||||
IMPLEMENT_ssl2_meth_func(sslv2_base_method,
|
||||
ssl_undefined_function,
|
||||
ssl_undefined_function,
|
||||
ssl_bad_method)
|
||||
|
||||
int ssl2_num_ciphers(void)
|
||||
{
|
||||
return(SSL2_NUM_CIPHERS);
|
||||
}
|
||||
|
||||
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 */
|
||||
SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p)
|
||||
{
|
||||
SSL_CIPHER c,*cp;
|
||||
unsigned long id;
|
||||
|
||||
id=0x02000000L|((unsigned long)p[0]<<16L)|
|
||||
((unsigned long)p[1]<<8L)|(unsigned long)p[2];
|
||||
c.id=id;
|
||||
cp = (SSL_CIPHER *)OBJ_bsearch((char *)&c,
|
||||
(char *)ssl2_ciphers,
|
||||
SSL2_NUM_CIPHERS,sizeof(SSL_CIPHER),
|
||||
FP_ICC ssl_cipher_id_cmp);
|
||||
if ((cp == NULL) || (cp->valid == 0))
|
||||
return NULL;
|
||||
else
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
for (i=0; i<s->s2->key_material_length; i += EVP_MD_size(md5))
|
||||
{
|
||||
if (((km - s->s2->key_material) + EVP_MD_size(md5)) >
|
||||
(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 += EVP_MD_size(md5);
|
||||
}
|
||||
|
||||
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)
|
||||
s->msg_callback(1, s->version, 0, buf, 3, s, s->msg_callback_arg); /* ERROR */
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -0,0 +1,84 @@
|
||||
/* 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 <stdio.h>
|
||||
#include "ssl_locl.h"
|
||||
#ifndef OPENSSL_NO_SSL2
|
||||
#include <openssl/objects.h>
|
||||
|
||||
static SSL_METHOD *ssl2_get_method(int ver);
|
||||
static 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 */
|
||||
|
||||
# if PEDANTIC
|
||||
static void *dummy=&dummy;
|
||||
# endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,700 @@
|
||||
/* 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 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;
|
||||
unsigned 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_size(s->read_hash);
|
||||
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 >= mac_size)) {
|
||||
ssl2_enc(s, 0);
|
||||
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);
|
||||
}
|
||||
|
||||
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 = 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;
|
||||
}
|
||||
}
|
||||
|
||||
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 do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
|
||||
{
|
||||
unsigned int j, k, olen, p, mac_size, bs;
|
||||
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_size(s->write_hash);
|
||||
|
||||
/* 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]);
|
||||
/* 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;
|
||||
ssl2_enc(s, 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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,635 @@
|
||||
/* 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, *d;
|
||||
int i;
|
||||
unsigned long l;
|
||||
|
||||
if (s->state == a) {
|
||||
d = (unsigned char *)s->init_buf->data;
|
||||
p = &(d[4]);
|
||||
|
||||
i = s->method->ssl3_enc->final_finish_mac(s,
|
||||
&(s->s3->finish_dgst1),
|
||||
&(s->s3->finish_dgst2),
|
||||
sender, slen,
|
||||
s->s3->tmp.finish_md);
|
||||
s->s3->tmp.finish_md_len = i;
|
||||
memcpy(p, s->s3->tmp.finish_md, i);
|
||||
p += 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
|
||||
|
||||
*(d++) = SSL3_MT_FINISHED;
|
||||
l2n3(l, d);
|
||||
s->init_num = (int)l + 4;
|
||||
s->init_off = 0;
|
||||
|
||||
s->state = b;
|
||||
}
|
||||
|
||||
/* SSL3_ST_SEND_xxxxxx_HELLO_B */
|
||||
return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
|
||||
}
|
||||
|
||||
int ssl3_get_finished(SSL *s, int a, int b)
|
||||
{
|
||||
int al, i, ok;
|
||||
long n;
|
||||
unsigned char *p;
|
||||
|
||||
/*
|
||||
* the mac has already been generated when we received the change cipher
|
||||
* spec message and is in s->s3->tmp.peer_finish_md
|
||||
*/
|
||||
|
||||
/* 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));
|
||||
}
|
||||
|
||||
static int ssl3_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
|
||||
{
|
||||
int n;
|
||||
unsigned char *p;
|
||||
|
||||
n = i2d_X509(x, NULL);
|
||||
if (!BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) {
|
||||
SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF, ERR_R_BUF_LIB);
|
||||
return (-1);
|
||||
}
|
||||
p = (unsigned char *)&(buf->data[*l]);
|
||||
l2n3(n, p);
|
||||
i2d_X509(x, &p);
|
||||
*l += n + 3;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
|
||||
{
|
||||
unsigned char *p;
|
||||
int i;
|
||||
unsigned long l = 7;
|
||||
BUF_MEM *buf;
|
||||
int no_chain;
|
||||
|
||||
if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
|
||||
no_chain = 1;
|
||||
else
|
||||
no_chain = 0;
|
||||
|
||||
/* TLSv1 sends a chain with nothing in it, instead of an alert */
|
||||
buf = s->init_buf;
|
||||
if (!BUF_MEM_grow_clean(buf, 10)) {
|
||||
SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_BUF_LIB);
|
||||
return (0);
|
||||
}
|
||||
if (x != NULL) {
|
||||
if (no_chain) {
|
||||
if (ssl3_add_cert_to_buf(buf, &l, x))
|
||||
return (0);
|
||||
} else {
|
||||
X509_STORE_CTX xs_ctx;
|
||||
|
||||
if (!X509_STORE_CTX_init(&xs_ctx, s->ctx->cert_store, x, NULL)) {
|
||||
SSLerr(SSL_F_SSL3_OUTPUT_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 (ssl3_add_cert_to_buf(buf, &l, x)) {
|
||||
X509_STORE_CTX_cleanup(&xs_ctx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
X509_STORE_CTX_cleanup(&xs_ctx);
|
||||
}
|
||||
}
|
||||
/* Thawte special :-) */
|
||||
for (i = 0; i < sk_X509_num(s->ctx->extra_certs); i++) {
|
||||
x = sk_X509_value(s->ctx->extra_certs, i);
|
||||
if (ssl3_add_cert_to_buf(buf, &l, x))
|
||||
return (0);
|
||||
}
|
||||
|
||||
l -= 7;
|
||||
p = (unsigned char *)&(buf->data[4]);
|
||||
l2n3(l, p);
|
||||
l += 3;
|
||||
p = (unsigned char *)&(buf->data[0]);
|
||||
*(p++) = SSL3_MT_CERTIFICATE;
|
||||
l2n3(l, p);
|
||||
l += 4;
|
||||
return (l);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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->init_msg = s->init_buf->data + 4;
|
||||
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 < 4 */
|
||||
int skip_message;
|
||||
|
||||
do {
|
||||
while (s->init_num < 4) {
|
||||
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
|
||||
&p[s->init_num],
|
||||
4 - 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, 4, s, s->msg_callback_arg);
|
||||
}
|
||||
}
|
||||
while (skip_message);
|
||||
|
||||
/* s->init_num == 4 */
|
||||
|
||||
if ((mt >= 0) && (*p != mt)) {
|
||||
al = SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
|
||||
goto f_err;
|
||||
}
|
||||
if ((mt < 0) && (*p == SSL3_MT_CLIENT_HELLO) &&
|
||||
(st1 == SSL3_ST_SR_CERT_A) && (stn == SSL3_ST_SR_CERT_B)) {
|
||||
/*
|
||||
* At this point we have got an MS SGC second client hello (maybe
|
||||
* we should always allow the client to start a new handshake?).
|
||||
* We need to restart the mac. Don't increment
|
||||
* {num,total}_renegotiations because we have not completed the
|
||||
* handshake.
|
||||
*/
|
||||
ssl3_init_finished_mac(s);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if (l > (INT_MAX - 4)) { /* BUF_MEM_grow takes an 'int' parameter */
|
||||
al = SSL_AD_ILLEGAL_PARAMETER;
|
||||
SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
|
||||
goto f_err;
|
||||
}
|
||||
if (l && !BUF_MEM_grow_clean(s->init_buf, (int)l + 4)) {
|
||||
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 + 4;
|
||||
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;
|
||||
}
|
||||
ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
|
||||
if (s->msg_callback)
|
||||
s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
|
||||
(size_t)s->init_num + 4, 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
|
||||
|
||||
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:
|
||||
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_OUT_OF_MEM:
|
||||
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);
|
||||
}
|
||||
|
||||
int ssl3_setup_buffers(SSL *s)
|
||||
{
|
||||
unsigned char *p;
|
||||
unsigned int extra, headerlen;
|
||||
size_t len;
|
||||
|
||||
if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
|
||||
headerlen = DTLS1_RT_HEADER_LENGTH;
|
||||
else
|
||||
headerlen = SSL3_RT_HEADER_LENGTH;
|
||||
|
||||
if (s->s3->rbuf.buf == NULL) {
|
||||
if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
|
||||
extra = SSL3_RT_MAX_EXTRA;
|
||||
else
|
||||
extra = 0;
|
||||
len = SSL3_RT_MAX_PACKET_SIZE + extra;
|
||||
if ((p = OPENSSL_malloc(len)) == NULL)
|
||||
goto err;
|
||||
s->s3->rbuf.buf = p;
|
||||
s->s3->rbuf.len = len;
|
||||
}
|
||||
|
||||
if (s->s3->wbuf.buf == NULL) {
|
||||
len = SSL3_RT_MAX_PACKET_SIZE;
|
||||
len += headerlen + 256; /* extra space for empty fragment */
|
||||
if ((p = OPENSSL_malloc(len)) == NULL)
|
||||
goto err;
|
||||
s->s3->wbuf.buf = p;
|
||||
s->s3->wbuf.len = len;
|
||||
}
|
||||
s->packet = &(s->s3->rbuf.buf[0]);
|
||||
return (1);
|
||||
err:
|
||||
SSLerr(SSL_F_SSL3_SETUP_BUFFERS, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,789 @@
|
||||
/* 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).
|
||||
*
|
||||
*/
|
||||
|
||||
#if __SIZEOF_POINTER__ == 8
|
||||
typedef long int intptr_t;
|
||||
#else
|
||||
typedef int intptr_t;
|
||||
#endif
|
||||
|
||||
#include <openssl/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 (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) {
|
||||
/*
|
||||
* 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 ((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--;
|
||||
}
|
||||
}
|
||||
|
||||
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 *digest)
|
||||
{
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return 0;
|
||||
#endif
|
||||
switch (EVP_MD_type(digest)) {
|
||||
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. )
|
||||
*/
|
||||
void ssl3_cbc_digest_record(const EVP_MD *digest,
|
||||
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_type(digest)) {
|
||||
case NID_md5:
|
||||
MD5_Init((MD5_CTX *)md_state.c);
|
||||
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:
|
||||
SHA1_Init((SHA_CTX *)md_state.c);
|
||||
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:
|
||||
SHA224_Init((SHA256_CTX *)md_state.c);
|
||||
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:
|
||||
SHA256_Init((SHA256_CTX *)md_state.c);
|
||||
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:
|
||||
SHA384_Init((SHA512_CTX *)md_state.c);
|
||||
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:
|
||||
SHA512_Init((SHA512_CTX *)md_state.c);
|
||||
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 = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
/*
|
||||
* 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).
|
||||
*/
|
||||
unsigned 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);
|
||||
EVP_DigestInit_ex(&md_ctx, digest, NULL /* engine */ );
|
||||
if (is_sslv3) {
|
||||
/* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
|
||||
memset(hmac_pad, 0x5c, sslv3_pad_length);
|
||||
|
||||
EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length);
|
||||
EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length);
|
||||
EVP_DigestUpdate(&md_ctx, mac_out, md_size);
|
||||
} else {
|
||||
/* Complete the HMAC in the standard manner. */
|
||||
for (i = 0; i < md_block_size; i++)
|
||||
hmac_pad[i] ^= 0x6a;
|
||||
|
||||
EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
|
||||
EVP_DigestUpdate(&md_ctx, mac_out, md_size);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
#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,
|
||||
const EVP_MD *hash, HMAC_CTX *hctx,
|
||||
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_block_size(hash);
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
HMAC_Update(hctx, data, (blocks_orig - blocks_data + 1) * block_size);
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,787 @@
|
||||
/* 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-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 "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, EVP_MD_CTX *in_ctx,
|
||||
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 */
|
||||
SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (j = 0; j < k; j++)
|
||||
buf[j] = c;
|
||||
c++;
|
||||
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);
|
||||
|
||||
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);
|
||||
if ((int)(i + MD5_DIGEST_LENGTH) > num) {
|
||||
EVP_DigestFinal_ex(&m5, smd, NULL);
|
||||
memcpy(km, smd, (num - i));
|
||||
} else
|
||||
EVP_DigestFinal_ex(&m5, km, NULL);
|
||||
|
||||
km += MD5_DIGEST_LENGTH;
|
||||
}
|
||||
OPENSSL_cleanse(smd, SHA_DIGEST_LENGTH);
|
||||
EVP_MD_CTX_cleanup(&m5);
|
||||
EVP_MD_CTX_cleanup(&s1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
#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;
|
||||
s->read_hash = m;
|
||||
#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;
|
||||
s->write_hash = m;
|
||||
#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);
|
||||
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 :-).
|
||||
*/
|
||||
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);
|
||||
key = &(exp_key[0]);
|
||||
|
||||
if (k > 0) {
|
||||
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);
|
||||
iv = &(exp_iv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
s->session->key_arg_length = 0;
|
||||
|
||||
EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE));
|
||||
|
||||
OPENSSL_cleanse(&(exp_key[0]), sizeof(exp_key));
|
||||
OPENSSL_cleanse(&(exp_iv[0]), sizeof(exp_iv));
|
||||
EVP_MD_CTX_cleanup(&md);
|
||||
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, &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_CIPHER_key_length(c) + EVP_MD_size(hash) +
|
||||
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->algorithms & SSL_ENC_MASK) == SSL_eNULL)
|
||||
s->s3->need_empty_fragments = 0;
|
||||
|
||||
#ifndef OPENSSL_NO_RC4
|
||||
if ((s->session->cipher->algorithms & SSL_ENC_MASK) == 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 */
|
||||
}
|
||||
|
||||
EVP_Cipher(ds, rec->data, rec->input, l);
|
||||
|
||||
if (s->read_hash != NULL)
|
||||
mac_size = EVP_MD_size(s->read_hash);
|
||||
|
||||
if ((bs != 1) && !send)
|
||||
return ssl3_cbc_remove_padding(s, rec, bs, mac_size);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
void ssl3_init_finished_mac(SSL *s)
|
||||
{
|
||||
EVP_MD_CTX_set_flags(&(s->s3->finish_dgst1),
|
||||
EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||
EVP_DigestInit_ex(&(s->s3->finish_dgst1), s->ctx->md5, NULL);
|
||||
EVP_DigestInit_ex(&(s->s3->finish_dgst2), s->ctx->sha1, NULL);
|
||||
}
|
||||
|
||||
void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
|
||||
{
|
||||
EVP_DigestUpdate(&(s->s3->finish_dgst1), buf, len);
|
||||
EVP_DigestUpdate(&(s->s3->finish_dgst2), buf, len);
|
||||
}
|
||||
|
||||
int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *ctx, unsigned char *p)
|
||||
{
|
||||
return (ssl3_handshake_mac(s, ctx, NULL, 0, p));
|
||||
}
|
||||
|
||||
int ssl3_final_finish_mac(SSL *s, EVP_MD_CTX *ctx1, EVP_MD_CTX *ctx2,
|
||||
const char *sender, int len, unsigned char *p)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ssl3_handshake_mac(s, ctx1, sender, len, p);
|
||||
p += ret;
|
||||
ret += ssl3_handshake_mac(s, ctx2, sender, len, p);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx,
|
||||
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;
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||
EVP_MD_CTX_copy_ex(&ctx, in_ctx);
|
||||
|
||||
n = EVP_MD_CTX_size(&ctx);
|
||||
npad = (48 / n) * n;
|
||||
|
||||
if (sender != NULL)
|
||||
EVP_DigestUpdate(&ctx, sender, len);
|
||||
EVP_DigestUpdate(&ctx, s->session->master_key,
|
||||
s->session->master_key_length);
|
||||
EVP_DigestUpdate(&ctx, ssl3_pad_1, npad);
|
||||
EVP_DigestFinal_ex(&ctx, md_buf, &i);
|
||||
|
||||
EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL);
|
||||
EVP_DigestUpdate(&ctx, s->session->master_key,
|
||||
s->session->master_key_length);
|
||||
EVP_DigestUpdate(&ctx, ssl3_pad_2, npad);
|
||||
EVP_DigestUpdate(&ctx, md_buf, i);
|
||||
EVP_DigestFinal_ex(&ctx, p, &ret);
|
||||
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
|
||||
return ((int)ret);
|
||||
}
|
||||
|
||||
int 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 *hash;
|
||||
unsigned char *p, rec_char;
|
||||
size_t md_size, orig_len;
|
||||
int npad;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
md_size = EVP_MD_size(hash);
|
||||
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 */
|
||||
ssl3_cbc_digest_record(hash,
|
||||
md, &md_size,
|
||||
header, rec->input,
|
||||
rec->length + md_size, orig_len,
|
||||
mac_sec, md_size, 1);
|
||||
} else {
|
||||
unsigned int md_size_u;
|
||||
/* Chop the digest off the end :-) */
|
||||
EVP_MD_CTX_init(&md_ctx);
|
||||
|
||||
EVP_DigestInit_ex(&md_ctx, hash, NULL);
|
||||
EVP_DigestUpdate(&md_ctx, mac_sec, md_size);
|
||||
EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad);
|
||||
EVP_DigestUpdate(&md_ctx, seq, 8);
|
||||
rec_char = rec->type;
|
||||
EVP_DigestUpdate(&md_ctx, &rec_char, 1);
|
||||
p = md;
|
||||
s2n(rec->length, p);
|
||||
EVP_DigestUpdate(&md_ctx, md, 2);
|
||||
EVP_DigestUpdate(&md_ctx, rec->input, rec->length);
|
||||
EVP_DigestFinal_ex(&md_ctx, md, NULL);
|
||||
|
||||
EVP_DigestInit_ex(&md_ctx, hash, NULL);
|
||||
EVP_DigestUpdate(&md_ctx, mac_sec, md_size);
|
||||
EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad);
|
||||
EVP_DigestUpdate(&md_ctx, md, md_size);
|
||||
EVP_DigestFinal_ex(&md_ctx, md, &md_size_u);
|
||||
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;
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
for (i = 0; i < 3; i++) {
|
||||
EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL);
|
||||
EVP_DigestUpdate(&ctx, salt[i], strlen((const char *)salt[i]));
|
||||
EVP_DigestUpdate(&ctx, p, len);
|
||||
EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]), SSL3_RANDOM_SIZE);
|
||||
EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE);
|
||||
EVP_DigestFinal_ex(&ctx, buf, &n);
|
||||
|
||||
EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL);
|
||||
EVP_DigestUpdate(&ctx, p, len);
|
||||
EVP_DigestUpdate(&ctx, buf, n);
|
||||
EVP_DigestFinal_ex(&ctx, out, &n);
|
||||
out += n;
|
||||
ret += n;
|
||||
}
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
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);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,73 @@
|
||||
/* 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"
|
||||
|
||||
static SSL_METHOD *ssl3_get_method(int ver);
|
||||
static 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)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,137 @@
|
||||
/* 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());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_RC2
|
||||
EVP_add_cipher(EVP_rc2_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());
|
||||
#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);
|
||||
}
|
||||
@@ -0,0 +1,502 @@
|
||||
/* 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.]
|
||||
*/
|
||||
|
||||
#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 */
|
||||
} 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_COMP
|
||||
int v11 = 0;
|
||||
unsigned char cbuf;
|
||||
#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 */
|
||||
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 */
|
||||
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);
|
||||
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
|
||||
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;
|
||||
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) {
|
||||
if (os.length != 2) {
|
||||
c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH;
|
||||
goto err;
|
||||
}
|
||||
id = 0x03000000L |
|
||||
((unsigned long)os.data[0] << 8L) | (unsigned long)os.data[1];
|
||||
} else {
|
||||
c.error = SSL_R_UNKNOWN_SSL_VERSION;
|
||||
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;
|
||||
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;
|
||||
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
|
||||
|
||||
M_ASN1_D2I_Finish(a, SSL_SESSION_free, SSL_F_D2I_SSL_SESSION);
|
||||
}
|
||||
@@ -0,0 +1,806 @@
|
||||
/*
|
||||
* ! \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-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 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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->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 = cert->mask;
|
||||
ret->export_mask = cert->export_mask;
|
||||
|
||||
#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;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < SSL_PKEY_NUM; i++) {
|
||||
if (cert->pkeys[i].x509 != NULL) {
|
||||
ret->pkeys[i].x509 = cert->pkeys[i].x509;
|
||||
CRYPTO_add(&ret->pkeys[i].x509->references, 1, CRYPTO_LOCK_X509);
|
||||
}
|
||||
|
||||
if (cert->pkeys[i].privatekey != NULL) {
|
||||
ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
|
||||
CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
|
||||
CRYPTO_LOCK_EVP_PKEY);
|
||||
|
||||
switch (i) {
|
||||
/*
|
||||
* If there was anything special to do for certain types of
|
||||
* keys, we'd do it here. (Nothing at the moment, I think.)
|
||||
*/
|
||||
|
||||
case SSL_PKEY_RSA_ENC:
|
||||
case SSL_PKEY_RSA_SIGN:
|
||||
/* We have an RSA key. */
|
||||
break;
|
||||
|
||||
case SSL_PKEY_DSA_SIGN:
|
||||
/* We have a DSA key. */
|
||||
break;
|
||||
|
||||
case SSL_PKEY_DH_RSA:
|
||||
case SSL_PKEY_DH_DSA:
|
||||
/* We have a DH key. */
|
||||
break;
|
||||
|
||||
case SSL_PKEY_ECC:
|
||||
/* We have an ECC key */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Can't happen. */
|
||||
SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ret->extra_certs *should* exist, but currently the own certificate
|
||||
* chain is held inside SSL_CTX
|
||||
*/
|
||||
|
||||
ret->references = 1;
|
||||
|
||||
return (ret);
|
||||
|
||||
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
|
||||
err:
|
||||
#endif
|
||||
#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
|
||||
|
||||
for (i = 0; i < SSL_PKEY_NUM; i++) {
|
||||
if (ret->pkeys[i].x509 != NULL)
|
||||
X509_free(ret->pkeys[i].x509);
|
||||
if (ret->pkeys[i].privatekey != NULL)
|
||||
EVP_PKEY_free(ret->pkeys[i].privatekey);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
for (i = 0; i < SSL_PKEY_NUM; i++) {
|
||||
if (c->pkeys[i].x509 != NULL)
|
||||
X509_free(c->pkeys[i].x509);
|
||||
if (c->pkeys[i].privatekey != NULL)
|
||||
EVP_PKEY_free(c->pkeys[i].privatekey);
|
||||
#if 0
|
||||
if (c->pkeys[i].publickey != NULL)
|
||||
EVP_PKEY_free(c->pkeys[i].publickey);
|
||||
#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);
|
||||
}
|
||||
|
||||
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_CTX ctx;
|
||||
|
||||
if ((sk == NULL) || (sk_X509_num(sk) == 0))
|
||||
return (0);
|
||||
|
||||
x = sk_X509_value(sk, 0);
|
||||
if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) {
|
||||
SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB);
|
||||
return (0);
|
||||
}
|
||||
#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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,688 @@
|
||||
/* ssl/ssl_err.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-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
|
||||
* 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 <time.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_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_ENC), "DTLS1_ENC"},
|
||||
{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_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"},
|
||||
{ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"},
|
||||
{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_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_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_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_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_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_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_BUFFERS), "SSL3_SETUP_BUFFERS"},
|
||||
{ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK), "SSL3_SETUP_KEY_BLOCK"},
|
||||
{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_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_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_BAD_METHOD), "SSL_BAD_METHOD"},
|
||||
{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_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_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_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_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_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_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_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_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_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_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_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_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_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_TLS1_CHANGE_CIPHER_STATE), "TLS1_CHANGE_CIPHER_STATE"},
|
||||
{ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"},
|
||||
{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"},
|
||||
{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_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_PUB_KEY_LENGTH), "bad dh pub key length"},
|
||||
{ERR_REASON(SSL_R_BAD_DH_P_LENGTH), "bad dh p length"},
|
||||
{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_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_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_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_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_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_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_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_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_ECGROUP_TOO_LARGE_FOR_CIPHER),
|
||||
"ecgroup too large for cipher"},
|
||||
{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_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_INAPPROPRIATE_FALLBACK), "inappropriate fallback"},
|
||||
{ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"},
|
||||
{ERR_REASON(SSL_R_INVALID_COMMAND), "invalid command"},
|
||||
{ERR_REASON(SSL_R_INVALID_PURPOSE), "invalid purpose"},
|
||||
{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_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_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_METHOD_SPECIFIED), "no method specified"},
|
||||
{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_SHARED_CIPHER), "no shared cipher"},
|
||||
{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_ONLY_TLS_ALLOWED_IN_FIPS_MODE),
|
||||
"only tls allowed in fips mode"},
|
||||
{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_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_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_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_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),
|
||||
"signature for non signing certificate"},
|
||||
{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_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_INVALID_ECPOINTFORMAT_LIST),
|
||||
"tls invalid ecpointformat list"},
|
||||
{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_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_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_WRITE_BIO_NOT_SET), "write bio not set"},
|
||||
{ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED), "wrong cipher returned"},
|
||||
{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_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
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/* 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 <time.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
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,729 @@
|
||||
/* 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);
|
||||
EVP_PKEY_assign_RSA(pkey, rsa);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
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) {
|
||||
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);
|
||||
EVP_PKEY_assign_RSA(pkey, rsa);
|
||||
|
||||
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;
|
||||
|
||||
if (ctx->extra_certs != NULL) {
|
||||
sk_X509_pop_free(ctx->extra_certs, X509_free);
|
||||
ctx->extra_certs = NULL;
|
||||
}
|
||||
|
||||
while ((ca =
|
||||
PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
|
||||
ctx->default_passwd_callback_userdata))
|
||||
!= NULL) {
|
||||
r = SSL_CTX_add_extra_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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,397 @@
|
||||
/* 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);
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/* 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.]
|
||||
*/
|
||||
|
||||
#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_VERSION)
|
||||
s = "TLSv1";
|
||||
else if (x->ssl_version == DTLS1_VERSION)
|
||||
s = "DTLSv1";
|
||||
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_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, &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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,77 @@
|
||||
/* 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 SSL_METHOD *tls1_get_client_method(int ver);
|
||||
static SSL_METHOD *tls1_get_client_method(int ver)
|
||||
{
|
||||
if (ver == TLS1_VERSION)
|
||||
return (TLSv1_client_method());
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
IMPLEMENT_tls1_meth_func(TLSv1_client_method,
|
||||
ssl_undefined_function,
|
||||
ssl3_connect, tls1_get_client_method)
|
||||
@@ -0,0 +1,882 @@
|
||||
/* 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-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 "ssl_locl.h"
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
#include <openssl/comp.h>
|
||||
#endif
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/md5.h>
|
||||
#ifdef KSSL_DEBUG
|
||||
#include <openssl/des.h>
|
||||
#endif
|
||||
|
||||
void ipssl_tls1_PRF(const EVP_MD *md5, const EVP_MD *sha1,
|
||||
unsigned char *label, int label_len,
|
||||
const unsigned char *sec, int slen, unsigned char *out1,
|
||||
unsigned char *out2, int olen);
|
||||
|
||||
static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
|
||||
int sec_len, unsigned char *seed, int seed_len,
|
||||
unsigned char *out, int olen)
|
||||
{
|
||||
int chunk;
|
||||
unsigned int j;
|
||||
HMAC_CTX ctx;
|
||||
HMAC_CTX ctx_tmp;
|
||||
unsigned char A1[EVP_MAX_MD_SIZE];
|
||||
unsigned int A1_len;
|
||||
|
||||
chunk=EVP_MD_size(md);
|
||||
|
||||
HMAC_CTX_init(&ctx);
|
||||
HMAC_CTX_init(&ctx_tmp);
|
||||
HMAC_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||
HMAC_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||
HMAC_Init_ex(&ctx,sec,sec_len,md, NULL);
|
||||
HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL);
|
||||
HMAC_Update(&ctx,seed,seed_len);
|
||||
HMAC_Final(&ctx,A1,&A1_len);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HMAC_Init_ex(&ctx,NULL,0,NULL,NULL); /* re-init */
|
||||
HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL); /* re-init */
|
||||
HMAC_Update(&ctx,A1,A1_len);
|
||||
HMAC_Update(&ctx_tmp,A1,A1_len);
|
||||
HMAC_Update(&ctx,seed,seed_len);
|
||||
|
||||
if (olen > chunk)
|
||||
{
|
||||
HMAC_Final(&ctx,out,&j);
|
||||
out+=j;
|
||||
olen-=j;
|
||||
HMAC_Final(&ctx_tmp,A1,&A1_len); /* calc the next A1 value */
|
||||
}
|
||||
else /* last one */
|
||||
{
|
||||
HMAC_Final(&ctx,A1,&A1_len);
|
||||
memcpy(out,A1,olen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
HMAC_CTX_cleanup(&ctx_tmp);
|
||||
OPENSSL_cleanse(A1,sizeof(A1));
|
||||
}
|
||||
|
||||
static void tls1_PRF(const EVP_MD *md5, const EVP_MD *sha1,
|
||||
unsigned char *label, int label_len,
|
||||
const unsigned char *sec, int slen, unsigned char *out1,
|
||||
unsigned char *out2, int olen)
|
||||
{
|
||||
int len,i;
|
||||
const unsigned char *S1,*S2;
|
||||
|
||||
len=slen/2;
|
||||
S1=sec;
|
||||
S2= &(sec[len]);
|
||||
len+=(slen&1); /* add for odd, make longer */
|
||||
|
||||
|
||||
tls1_P_hash(md5 ,S1,len,label,label_len,out1,olen);
|
||||
tls1_P_hash(sha1,S2,len,label,label_len,out2,olen);
|
||||
|
||||
for (i=0; i<olen; i++)
|
||||
out1[i]^=out2[i];
|
||||
}
|
||||
|
||||
static void tls1_generate_key_block(SSL *s, unsigned char *km,
|
||||
unsigned char *tmp, int num)
|
||||
{
|
||||
unsigned char *p;
|
||||
unsigned char buf[SSL3_RANDOM_SIZE*2+
|
||||
TLS_MD_MAX_CONST_SIZE];
|
||||
p=buf;
|
||||
|
||||
memcpy(p,TLS_MD_KEY_EXPANSION_CONST,
|
||||
TLS_MD_KEY_EXPANSION_CONST_SIZE);
|
||||
p+=TLS_MD_KEY_EXPANSION_CONST_SIZE;
|
||||
memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
|
||||
p+=SSL3_RANDOM_SIZE;
|
||||
memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
|
||||
p+=SSL3_RANDOM_SIZE;
|
||||
|
||||
tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),
|
||||
s->session->master_key,s->session->master_key_length,
|
||||
km,tmp,num);
|
||||
#ifdef KSSL_DEBUG
|
||||
printf("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++)
|
||||
{
|
||||
printf("%02X", s->session->master_key[i]);
|
||||
}
|
||||
printf("\n"); }
|
||||
#endif /* KSSL_DEBUG */
|
||||
}
|
||||
|
||||
int tls1_change_cipher_state(SSL *s, int which)
|
||||
{
|
||||
static const unsigned char empty[]="";
|
||||
unsigned char *p,*mac_secret;
|
||||
unsigned char *exp_label,buf[TLS_MD_MAX_CONST_SIZE+
|
||||
SSL3_RANDOM_SIZE*2];
|
||||
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 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;
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
comp=s->s3->tmp.new_compression;
|
||||
#endif
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
key_block=s->s3->tmp.key_block;
|
||||
|
||||
printf("tls1_change_cipher_state(which= %d) w/\n", which);
|
||||
printf("\talg= %ld, comp= %p\n", s->s3->tmp.new_cipher->algorithms,
|
||||
(void *)comp);
|
||||
printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", (void *)c);
|
||||
printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
|
||||
c->nid,c->block_size,c->key_len,c->iv_len);
|
||||
printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
|
||||
{
|
||||
int ki;
|
||||
for (ki=0; ki<s->s3->tmp.key_block_length; ki++)
|
||||
printf("%02x", s->s3->tmp.key_block[ki]); printf("\n");
|
||||
}
|
||||
#endif /* KSSL_DEBUG */
|
||||
|
||||
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;
|
||||
s->read_hash=m;
|
||||
#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 DTLS1_VERSION */
|
||||
if (s->version != DTLS1_VERSION)
|
||||
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;
|
||||
s->write_hash=m;
|
||||
#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 DTLS1_VERSION */
|
||||
if (s->version != DTLS1_VERSION)
|
||||
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);
|
||||
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); */
|
||||
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);
|
||||
#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 :-).
|
||||
*/
|
||||
p=buf;
|
||||
memcpy(p,exp_label,exp_label_len);
|
||||
p+=exp_label_len;
|
||||
memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
|
||||
p+=SSL3_RANDOM_SIZE;
|
||||
memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
|
||||
p+=SSL3_RANDOM_SIZE;
|
||||
tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),key,j,
|
||||
tmp1,tmp2,EVP_CIPHER_key_length(c));
|
||||
key=tmp1;
|
||||
|
||||
if (k > 0)
|
||||
{
|
||||
p=buf;
|
||||
memcpy(p,TLS_MD_IV_BLOCK_CONST,
|
||||
TLS_MD_IV_BLOCK_CONST_SIZE);
|
||||
p+=TLS_MD_IV_BLOCK_CONST_SIZE;
|
||||
memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
|
||||
p+=SSL3_RANDOM_SIZE;
|
||||
memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
|
||||
p+=SSL3_RANDOM_SIZE;
|
||||
tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,p-buf,empty,0,
|
||||
iv1,iv2,k*2);
|
||||
if (client_write)
|
||||
iv=iv1;
|
||||
else
|
||||
iv= &(iv1[k]);
|
||||
}
|
||||
}
|
||||
|
||||
s->session->key_arg_length=0;
|
||||
#ifdef KSSL_DEBUG
|
||||
{
|
||||
int ki;
|
||||
printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
|
||||
printf("\tkey= ");
|
||||
for (ki=0; ki<c->key_len; ki++) printf("%02x", key[ki]);
|
||||
printf("\n");
|
||||
printf("\t iv= ");
|
||||
for (ki=0; ki<c->iv_len; ki++) printf("%02x", iv[ki]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif /* KSSL_DEBUG */
|
||||
|
||||
EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
|
||||
#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;
|
||||
const EVP_CIPHER *c;
|
||||
const EVP_MD *hash;
|
||||
int num;
|
||||
SSL_COMP *comp;
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
printf ("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,&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;
|
||||
|
||||
num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c);
|
||||
num*=2;
|
||||
|
||||
ssl3_cleanup_key_block(s);
|
||||
|
||||
if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL)
|
||||
goto err;
|
||||
if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL)
|
||||
goto err;
|
||||
|
||||
s->s3->tmp.key_block_length=num;
|
||||
s->s3->tmp.key_block=p1;
|
||||
|
||||
|
||||
#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
|
||||
tls1_generate_key_block(s,p1,p2,num);
|
||||
OPENSSL_cleanse(p2,num);
|
||||
OPENSSL_free(p2);
|
||||
#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))
|
||||
{
|
||||
/* 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->algorithms & SSL_ENC_MASK) == SSL_eNULL)
|
||||
s->s3->need_empty_fragments = 0;
|
||||
|
||||
#ifndef OPENSSL_NO_RC4
|
||||
if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4)
|
||||
s->s3->need_empty_fragments = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return(1);
|
||||
err:
|
||||
SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
printf("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 ((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;
|
||||
printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
|
||||
ds,rec->data,rec->input,l);
|
||||
printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
|
||||
ds->buf_len, ds->cipher->key_len,
|
||||
DES_KEY_SZ, DES_SCHEDULE_SZ,
|
||||
ds->cipher->iv_len);
|
||||
printf("\t\tIV: ");
|
||||
for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
|
||||
printf("\n");
|
||||
printf("\trec->input=");
|
||||
for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif /* KSSL_DEBUG */
|
||||
|
||||
if (!send)
|
||||
{
|
||||
if (l == 0 || l%bs != 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVP_Cipher(ds,rec->data,rec->input,l);
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
{
|
||||
unsigned long ki;
|
||||
printf("\trec->data=");
|
||||
for (ki=0; ki<l; i++)
|
||||
printf(" %02x", rec->data[ki]); printf("\n");
|
||||
}
|
||||
#endif /* KSSL_DEBUG */
|
||||
|
||||
ret = 1;
|
||||
if (s->read_hash != NULL)
|
||||
mac_size = EVP_MD_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, EVP_MD_CTX *in_ctx, unsigned char *out)
|
||||
{
|
||||
unsigned int ret;
|
||||
EVP_MD_CTX ctx;
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
EVP_MD_CTX_copy_ex(&ctx,in_ctx);
|
||||
EVP_DigestFinal_ex(&ctx,out,&ret);
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
return((int)ret);
|
||||
}
|
||||
|
||||
int tls1_final_finish_mac(SSL *s, EVP_MD_CTX *in1_ctx, EVP_MD_CTX *in2_ctx,
|
||||
const char *str, int slen, unsigned char *out)
|
||||
{
|
||||
unsigned int i;
|
||||
EVP_MD_CTX ctx;
|
||||
unsigned char buf[TLS_MD_MAX_CONST_SIZE+MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
|
||||
unsigned char *q,buf2[12];
|
||||
|
||||
q=buf;
|
||||
memcpy(q,str,slen);
|
||||
q+=slen;
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
EVP_MD_CTX_copy_ex(&ctx,in1_ctx);
|
||||
EVP_DigestFinal_ex(&ctx,q,&i);
|
||||
q+=i;
|
||||
EVP_MD_CTX_copy_ex(&ctx,in2_ctx);
|
||||
EVP_DigestFinal_ex(&ctx,q,&i);
|
||||
q+=i;
|
||||
|
||||
tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(q-buf),
|
||||
s->session->master_key,s->session->master_key_length,
|
||||
out,buf2,sizeof buf2);
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
|
||||
OPENSSL_cleanse(buf, (int)(q - buf));
|
||||
OPENSSL_cleanse(buf2, sizeof(buf2));
|
||||
return sizeof buf2;
|
||||
}
|
||||
|
||||
int tls1_mac(SSL *ssl, unsigned char *md, int send)
|
||||
{
|
||||
SSL3_RECORD *rec;
|
||||
unsigned char *mac_sec,*seq;
|
||||
const EVP_MD *hash;
|
||||
size_t md_size, orig_len;
|
||||
int i;
|
||||
HMAC_CTX hmac;
|
||||
unsigned char header[13];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
md_size=EVP_MD_size(hash);
|
||||
|
||||
/* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
|
||||
HMAC_CTX_init(&hmac);
|
||||
HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL);
|
||||
|
||||
if (ssl->version == DTLS1_BAD_VER ||
|
||||
(ssl->version == DTLS1_VERSION && ssl->client_version != DTLS1_BAD_VER))
|
||||
{
|
||||
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(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. */
|
||||
ssl3_cbc_digest_record(
|
||||
hash,
|
||||
md, &md_size,
|
||||
header, rec->input,
|
||||
rec->length + md_size, orig_len,
|
||||
ssl->s3->read_mac_secret,
|
||||
EVP_MD_size(ssl->read_hash),
|
||||
0 /* not SSLv3 */);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned mds;
|
||||
|
||||
HMAC_Update(&hmac,header,sizeof(header));
|
||||
HMAC_Update(&hmac,rec->input,rec->length);
|
||||
HMAC_Final(&hmac,md,&mds);
|
||||
md_size = mds;
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (!send && FIPS_mode())
|
||||
tls_fips_digest_extra(
|
||||
ssl->enc_read_ctx,
|
||||
hash,
|
||||
&hmac, rec->input,
|
||||
rec->length, orig_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
HMAC_CTX_cleanup(&hmac);
|
||||
#ifdef TLS_DEBUG
|
||||
printf("seq=");
|
||||
{int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); }
|
||||
printf("rec=");
|
||||
{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",rec->data[z]); printf("\n"); }
|
||||
#endif
|
||||
|
||||
if ( SSL_version(ssl) != DTLS1_VERSION && SSL_version(ssl) != DTLS1_BAD_VER)
|
||||
{
|
||||
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++) printf("%02X ",md[z]); printf("\n"); }
|
||||
#endif
|
||||
return(md_size);
|
||||
}
|
||||
|
||||
int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
|
||||
int len)
|
||||
{
|
||||
unsigned char buf[SSL3_RANDOM_SIZE*2+TLS_MD_MASTER_SECRET_CONST_SIZE];
|
||||
unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", (void *)s,out, p,len);
|
||||
#endif /* KSSL_DEBUG */
|
||||
|
||||
/* Setup the stuff to munge */
|
||||
memcpy(buf,TLS_MD_MASTER_SECRET_CONST,
|
||||
TLS_MD_MASTER_SECRET_CONST_SIZE);
|
||||
memcpy(&(buf[TLS_MD_MASTER_SECRET_CONST_SIZE]),
|
||||
s->s3->client_random,SSL3_RANDOM_SIZE);
|
||||
memcpy(&(buf[SSL3_RANDOM_SIZE+TLS_MD_MASTER_SECRET_CONST_SIZE]),
|
||||
s->s3->server_random,SSL3_RANDOM_SIZE);
|
||||
tls1_PRF(s->ctx->md5,s->ctx->sha1,
|
||||
buf,TLS_MD_MASTER_SECRET_CONST_SIZE+SSL3_RANDOM_SIZE*2,p,len,
|
||||
s->session->master_key,buff,sizeof buff);
|
||||
OPENSSL_cleanse(buf, sizeof buf);
|
||||
OPENSSL_cleanse(buff, sizeof buff);
|
||||
#ifdef KSSL_DEBUG
|
||||
printf ("tls1_generate_master_secret() complete\n");
|
||||
#endif /* KSSL_DEBUG */
|
||||
return(SSL3_MASTER_SECRET_SIZE);
|
||||
}
|
||||
|
||||
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);
|
||||
#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
|
||||
case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return
|
||||
(DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
|
||||
#endif
|
||||
default: return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void ipssl_tls1_PRF(const EVP_MD *md5, const EVP_MD *sha1,
|
||||
unsigned char *label, int label_len,
|
||||
const unsigned char *sec, int slen, unsigned char *out1,
|
||||
unsigned char *out2, int olen)
|
||||
{
|
||||
tls1_PRF(md5, sha1, label, label_len, sec, slen, out1, out2, olen);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,73 @@
|
||||
/* 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 SSL_METHOD *tls1_get_method(int ver);
|
||||
static SSL_METHOD *tls1_get_method(int ver)
|
||||
{
|
||||
if (ver == TLS1_VERSION)
|
||||
return (TLSv1_method());
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
IMPLEMENT_tls1_meth_func(TLSv1_method,
|
||||
ssl3_accept, ssl3_connect, tls1_get_method)
|
||||
@@ -0,0 +1,292 @@
|
||||
/* 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;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/* 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 SSL_METHOD *tls1_get_server_method(int ver);
|
||||
static SSL_METHOD *tls1_get_server_method(int ver)
|
||||
{
|
||||
if (ver == TLS1_VERSION)
|
||||
return (TLSv1_server_method());
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
IMPLEMENT_tls1_meth_func(TLSv1_server_method,
|
||||
ssl3_accept,
|
||||
ssl_undefined_function, tls1_get_server_method)
|
||||
Reference in New Issue
Block a user