RFC 5878 support.

This commit is contained in:
Ben Laurie 2012-05-30 10:10:58 +00:00
parent 03c1d9f99d
commit a9e1c50bb0
19 changed files with 864 additions and 57 deletions

View File

@ -4,6 +4,9 @@
Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] Changes between 1.0.1 and 1.1.0 [xx XXX xxxx]
*) RFC 5878 support.
[Emilia Kasper, Adam Langley, Ben Laurie (Google)]
*) Support for automatic EC temporary key parameter selection. If enabled *) Support for automatic EC temporary key parameter selection. If enabled
the most preferred EC parameters are automatically used instead of the most preferred EC parameters are automatically used instead of
hardcoded fixed parameters. Now a server just has to call: hardcoded fixed parameters. Now a server just has to call:

View File

@ -156,6 +156,10 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key, int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
STACK_OF(X509) *chain); STACK_OF(X509) *chain);
# ifndef OPENSSL_NO_TLSEXT
int set_cert_key_and_authz(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
unsigned char *authz, size_t authz_length);
# endif
int ssl_print_sigalgs(BIO *out, SSL *s); int ssl_print_sigalgs(BIO *out, SSL *s);
int ssl_print_curves(BIO *out, SSL *s); int ssl_print_curves(BIO *out, SSL *s);
#endif #endif

View File

@ -261,6 +261,7 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
ERR_print_errors(bio_err); ERR_print_errors(bio_err);
return 0; return 0;
} }
if (SSL_CTX_use_PrivateKey(ctx,key) <= 0) if (SSL_CTX_use_PrivateKey(ctx,key) <= 0)
{ {
BIO_printf(bio_err,"error setting private key\n"); BIO_printf(bio_err,"error setting private key\n");
@ -268,7 +269,6 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
return 0; return 0;
} }
/* Now we know that a key and cert have been set against /* Now we know that a key and cert have been set against
* the SSL context */ * the SSL context */
if (!SSL_CTX_check_private_key(ctx)) if (!SSL_CTX_check_private_key(ctx))

View File

@ -202,6 +202,7 @@ static int c_debug=0;
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
static int c_tlsextdebug=0; static int c_tlsextdebug=0;
static int c_status_req=0; static int c_status_req=0;
static int c_proof_debug=0;
#endif #endif
static int c_msg=0; static int c_msg=0;
static int c_showcerts=0; static int c_showcerts=0;
@ -213,6 +214,7 @@ static void sc_usage(void);
static void print_stuff(BIO *berr,SSL *con,int full); static void print_stuff(BIO *berr,SSL *con,int full);
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
static int ocsp_resp_cb(SSL *s, void *arg); static int ocsp_resp_cb(SSL *s, void *arg);
static int audit_proof_cb(SSL *s, void *arg);
#endif #endif
static BIO *bio_c_out=NULL; static BIO *bio_c_out=NULL;
static int c_quiet=0; static int c_quiet=0;
@ -357,6 +359,7 @@ static void sc_usage(void)
BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n"); BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n");
BIO_printf(bio_err," -status - request certificate status from server\n"); BIO_printf(bio_err," -status - request certificate status from server\n");
BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n"); BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
BIO_printf(bio_err," -proof_debug - request an audit proof and print its hex dump\n");
# ifndef OPENSSL_NO_NEXTPROTONEG # ifndef OPENSSL_NO_NEXTPROTONEG
BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n"); BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
# endif # endif
@ -731,6 +734,8 @@ int MAIN(int argc, char **argv)
c_tlsextdebug=1; c_tlsextdebug=1;
else if (strcmp(*argv,"-status") == 0) else if (strcmp(*argv,"-status") == 0)
c_status_req=1; c_status_req=1;
else if (strcmp(*argv,"-proof_debug") == 0)
c_proof_debug=1;
#endif #endif
#ifdef WATT32 #ifdef WATT32
else if (strcmp(*argv,"-wdebug") == 0) else if (strcmp(*argv,"-wdebug") == 0)
@ -1212,6 +1217,9 @@ bad:
} }
#endif #endif
if (c_proof_debug)
SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx,
audit_proof_cb);
#endif #endif
con=SSL_new(ctx); con=SSL_new(ctx);
@ -2147,4 +2155,26 @@ static int ocsp_resp_cb(SSL *s, void *arg)
return 1; return 1;
} }
static int audit_proof_cb(SSL *s, void *arg)
{
const unsigned char *proof;
size_t proof_len;
size_t i;
SSL_SESSION *sess = SSL_get_session(s);
proof = SSL_SESSION_get_tlsext_authz_server_audit_proof(sess,
&proof_len);
if (proof != NULL)
{
BIO_printf(bio_c_out, "Audit proof: ");
for (i = 0; i < proof_len; ++i)
BIO_printf(bio_c_out, "%02X", proof[i]);
BIO_printf(bio_c_out, "\n");
}
else
{
BIO_printf(bio_c_out, "No audit proof found.\n");
}
return 1;
}
#endif #endif

View File

@ -313,6 +313,12 @@ static long socket_mtu;
static int cert_chain = 0; static int cert_chain = 0;
#endif #endif
#ifndef OPENSSL_NO_TLSEXT
static BIO *authz_in = NULL;
static const char *s_authz_file = NULL;
static unsigned char *authz = NULL;
static size_t authz_length;
#endif
#ifndef OPENSSL_NO_PSK #ifndef OPENSSL_NO_PSK
static char *psk_identity="Client_identity"; static char *psk_identity="Client_identity";
@ -473,6 +479,7 @@ static void sv_usage(void)
BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n"); BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n");
BIO_printf(bio_err," -cert arg - certificate file to use\n"); BIO_printf(bio_err," -cert arg - certificate file to use\n");
BIO_printf(bio_err," (default is %s)\n",TEST_CERT); BIO_printf(bio_err," (default is %s)\n",TEST_CERT);
BIO_printf(bio_err," -authz arg - binary authz file for certificate\n");
BIO_printf(bio_err," -crl_check - check the peer certificate has not been revoked by its CA.\n" \ BIO_printf(bio_err," -crl_check - check the peer certificate has not been revoked by its CA.\n" \
" The CRL(s) are appended to the certificate file\n"); " The CRL(s) are appended to the certificate file\n");
BIO_printf(bio_err," -crl_check_all - check the peer certificate has not been revoked by its CA\n" \ BIO_printf(bio_err," -crl_check_all - check the peer certificate has not been revoked by its CA\n" \
@ -1044,6 +1051,13 @@ int MAIN(int argc, char *argv[])
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
s_cert_file= *(++argv); s_cert_file= *(++argv);
} }
#ifndef OPENSSL_NO_TLSEXT
else if (strcmp(*argv,"-authz") == 0)
{
if (--argc < 1) goto bad;
s_authz_file = *(++argv);
}
#endif
else if (strcmp(*argv,"-certform") == 0) else if (strcmp(*argv,"-certform") == 0)
{ {
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
@ -1490,7 +1504,34 @@ bad:
next_proto.data = NULL; next_proto.data = NULL;
} }
# endif # endif
#endif if (s_authz_file != NULL)
{
/* Allow authzs up to 64KB bytes. */
static const size_t authz_limit = 65536;
authz_in = BIO_new(BIO_s_file_internal());
if (authz_in == NULL)
{
ERR_print_errors(bio_err);
goto end;
}
if (BIO_read_filename(authz_in, s_authz_file) <= 0)
{
ERR_print_errors(bio_err);
goto end;
}
authz = OPENSSL_malloc(authz_limit);
authz_length = BIO_read(authz_in, authz, authz_limit);
if (authz_length == authz_limit || authz_length <= 0)
{
BIO_printf(bio_err, "authz too large\n");
goto end;
}
BIO_free(authz_in);
authz_in = NULL;
}
#endif /* OPENSSL_NO_TLSEXT */
} }
@ -1789,6 +1830,10 @@ bad:
if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain)) if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain))
goto end; goto end;
#ifndef OPENSSL_NO_TLSEXT
if (authz != NULL && !SSL_CTX_use_authz(ctx, authz, authz_length))
goto end;
#endif
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL)) if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL))
goto end; goto end;
@ -1983,6 +2028,10 @@ end:
X509_free(s_cert2); X509_free(s_cert2);
if (s_key2) if (s_key2)
EVP_PKEY_free(s_key2); EVP_PKEY_free(s_key2);
if (authz != NULL)
OPENSSL_free(authz);
if (authz_in != NULL)
BIO_free(authz_in);
#endif #endif
if (bio_s_out != NULL) if (bio_s_out != NULL)
{ {

View File

@ -340,6 +340,8 @@ static int ssl23_client_hello(SSL *s)
if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL) if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL)
ssl2_compat = 0; ssl2_compat = 0;
#endif #endif
if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL)
ssl2_compat = 0;
} }
#endif #endif

View File

@ -307,10 +307,27 @@ int ssl3_connect(SSL *s)
#endif #endif
} }
else else
{
#ifndef OPENSSL_NO_TLSEXT
/* The server hello indicated that
* an audit proof would follow. */
if (s->s3->tlsext_authz_server_promised)
s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A;
else
#endif
s->state=SSL3_ST_CR_CERT_A; s->state=SSL3_ST_CR_CERT_A;
}
s->init_num=0; s->init_num=0;
break; break;
#ifndef OPENSSL_NO_TLSEXT
case SSL3_ST_CR_SUPPLEMENTAL_DATA_A:
case SSL3_ST_CR_SUPPLEMENTAL_DATA_B:
ret = tls1_get_server_supplemental_data(s);
if (ret <= 0) goto end;
s->state=SSL3_ST_CR_CERT_A;
s->init_num = 0;
break;
#endif
case SSL3_ST_CR_CERT_A: case SSL3_ST_CR_CERT_A:
case SSL3_ST_CR_CERT_B: case SSL3_ST_CR_CERT_B:
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
@ -1231,8 +1248,22 @@ int ssl3_get_server_certificate(SSL *s)
s->session->verify_result = s->verify_result; s->session->verify_result = s->verify_result;
x=NULL; x=NULL;
ret=1; #ifndef OPENSSL_NO_TLSEXT
/* Check the audit proof. */
if (s->ctx->tlsext_authz_server_audit_proof_cb)
{
ret = s->ctx->tlsext_authz_server_audit_proof_cb(s,
s->ctx->tlsext_authz_server_audit_proof_cb_arg);
if (ret <= 0)
{
al = SSL_AD_BAD_CERTIFICATE;
SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_INVALID_AUDIT_PROOF);
goto f_err;
}
}
#endif
ret=1;
if (0) if (0)
{ {
f_err: f_err:
@ -3432,3 +3463,106 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
i = s->ctx->client_cert_cb(s,px509,ppkey); i = s->ctx->client_cert_cb(s,px509,ppkey);
return i; return i;
} }
#ifndef OPENSSL_NO_TLSEXT
int tls1_get_server_supplemental_data(SSL *s)
{
int al;
int ok;
unsigned long supp_data_len, authz_data_len;
long n;
unsigned short supp_data_type, authz_data_type, proof_len;
const unsigned char *p;
unsigned char *new_proof;
n=s->method->ssl_get_message(s,
SSL3_ST_CR_SUPPLEMENTAL_DATA_A,
SSL3_ST_CR_SUPPLEMENTAL_DATA_B,
SSL3_MT_SUPPLEMENTAL_DATA,
/* use default limit */
TLSEXT_MAXLEN_supplemental_data,
&ok);
if (!ok) return((int)n);
p = (unsigned char *)s->init_msg;
/* The message cannot be empty */
if (n < 3)
{
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
goto f_err;
}
/* Length of supplemental data */
n2l3(p,supp_data_len);
n -= 3;
/* We must have at least one supplemental data entry
* with type (1 byte) and length (2 bytes). */
if (supp_data_len != (unsigned long) n || n < 4)
{
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
goto f_err;
}
/* Supplemental data type: must be authz_data */
n2s(p,supp_data_type);
n -= 2;
if (supp_data_type != TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
{
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_UNKNOWN_SUPPLEMENTAL_DATA_TYPE);
goto f_err;
}
/* Authz data length */
n2s(p, authz_data_len);
n -= 2;
if (authz_data_len != (unsigned long) n || n < 1)
{
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
goto f_err;
}
/* Authz data type: must be audit_proof */
authz_data_type = *(p++);
n -= 1;
if (authz_data_type != TLSEXT_AUTHZDATAFORMAT_audit_proof)
{
al=SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_UNKNOWN_AUTHZ_DATA_TYPE);
goto f_err;
}
/* We have a proof: read its length */
if (n < 2)
{
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
goto f_err;
}
n2s(p, proof_len);
n -= 2;
if (proof_len != (unsigned long) n)
{
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
goto f_err;
}
/* Store the proof */
new_proof = OPENSSL_realloc(s->session->audit_proof,
proof_len);
if (new_proof == NULL)
{
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,ERR_R_MALLOC_FAILURE);
return 0;
}
s->session->audit_proof_length = proof_len;
s->session->audit_proof = new_proof;
memcpy(s->session->audit_proof, p, proof_len);
/* Got the proof, but can't verify it yet. */
return 1;
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
return -1;
}
#endif

View File

@ -3684,6 +3684,11 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
case SSL_CTRL_SET_ECDH_AUTO: case SSL_CTRL_SET_ECDH_AUTO:
ctx->cert->ecdh_tmp_auto = larg; ctx->cert->ecdh_tmp_auto = larg;
break; break;
case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG:
ctx->tlsext_authz_server_audit_proof_cb_arg = parg;
break;
#endif /* !OPENSSL_NO_TLSEXT */ #endif /* !OPENSSL_NO_TLSEXT */
/* A Thawte special :-) */ /* A Thawte special :-) */
@ -3793,6 +3798,12 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp; ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp;
break; break;
#endif #endif
case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB:
ctx->tlsext_authz_server_audit_proof_cb =
(int (*)(SSL *, void *))fp;
break;
#endif #endif
case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB: case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB:
{ {

View File

@ -403,10 +403,31 @@ int ssl3_accept(SSL *s)
s->state=SSL3_ST_SW_CHANGE_A; s->state=SSL3_ST_SW_CHANGE_A;
#endif #endif
else else
s->state=SSL3_ST_SW_CERT_A; #ifndef OPENSSL_NO_TLSEXT
s->init_num=0; s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_A;
#else
s->state = SSL3_ST_SW_CERT_A;
#endif
s->init_num = 0;
break; break;
#ifndef OPENSSL_NO_TLSEXT
case SSL3_ST_SW_SUPPLEMENTAL_DATA_A:
case SSL3_ST_SW_SUPPLEMENTAL_DATA_B:
/* We promised to send an audit proof in the hello. */
if (s->s3->tlsext_authz_promised_to_client)
{
ret = tls1_send_server_supplemental_data(s);
if (ret <= 0) goto end;
}
else
skip = 1;
s->state = SSL3_ST_SW_CERT_A;
s->init_num = 0;
break;
#endif
case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_A:
case SSL3_ST_SW_CERT_B: case SSL3_ST_SW_CERT_B:
/* Check if it is anon DH or anon ECDH, */ /* Check if it is anon DH or anon ECDH, */
@ -3629,4 +3650,95 @@ int ssl3_get_next_proto(SSL *s)
return 1; return 1;
} }
# endif # endif
int tls1_send_server_supplemental_data(SSL *s)
{
size_t length = 0;
const unsigned char *authz, *orig_authz;
unsigned char *p;
size_t authz_length, i;
if (s->state != SSL3_ST_SW_SUPPLEMENTAL_DATA_A)
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
orig_authz = authz = ssl_get_authz_data(s, &authz_length);
if (authz == NULL)
{
/* This should never occur. */
return 0;
}
/* First we walk over the authz data to see how long the handshake
* message will be. */
for (i = 0; i < authz_length; i++)
{
unsigned short len;
unsigned char type;
type = *(authz++);
n2s(authz, len);
if (memchr(s->s3->tlsext_authz_client_types,
type,
s->s3->tlsext_authz_client_types_len) != NULL)
length += 1 /* authz type */ + 2 /* length */ + len;
authz += len;
i += len;
}
length += 1 /* handshake type */ +
3 /* handshake length */ +
3 /* supplemental data length */ +
2 /* supplemental entry type */ +
2 /* supplemental entry length */;
if (!BUF_MEM_grow_clean(s->init_buf, length))
{
SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
return 0;
}
p = (unsigned char *)s->init_buf->data;
*(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
/* Handshake length */
l2n3(length - 4, p);
/* Length of supplemental data */
l2n3(length - 7, p);
/* Supplemental data type */
s2n(TLSEXT_SUPPLEMENTALDATATYPE_authz_data, p);
/* Its length */
s2n(length - 11, p);
authz = orig_authz;
/* Walk over the authz again and append the selected elements. */
for (i = 0; i < authz_length; i++)
{
unsigned short len;
unsigned char type;
type = *(authz++);
n2s(authz, len);
if (memchr(s->s3->tlsext_authz_client_types,
type,
s->s3->tlsext_authz_client_types_len) != NULL)
{
*(p++) = type;
s2n(len, p);
memcpy(p, authz, len);
p += len;
}
authz += len;
i += len;
}
s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B;
s->init_num = length;
s->init_off = 0;
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
}
#endif #endif

View File

@ -544,6 +544,13 @@ struct ssl_session_st
#endif #endif
#ifndef OPENSSL_NO_SRP #ifndef OPENSSL_NO_SRP
char *srp_username; char *srp_username;
#endif
#ifndef OPENSSL_NO_TLSEXT
/* Used by client: the proof for this session.
* We store it outside the sess_cert structure, since the proof
* is received before the certificate. */
unsigned char *audit_proof;
size_t audit_proof_length;
#endif #endif
}; };
@ -989,6 +996,8 @@ struct ssl_ctx_st
size_t tlsext_ellipticcurvelist_length; size_t tlsext_ellipticcurvelist_length;
unsigned char *tlsext_ellipticcurvelist; unsigned char *tlsext_ellipticcurvelist;
#endif /* OPENSSL_NO_EC */ #endif /* OPENSSL_NO_EC */
int (*tlsext_authz_server_audit_proof_cb)(SSL *s, void *arg);
void *tlsext_authz_server_audit_proof_cb_arg;
}; };
#endif #endif
@ -1608,7 +1617,10 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86 #define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86
#define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87 #define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87
#endif #endif
#endif /* Callback for verifying audit proofs (client only) */
#define SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB 95
#define SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG 96
#endif /* OPENSSL_NO_TLSEXT */
#define DTLS_CTRL_GET_TIMEOUT 73 #define DTLS_CTRL_GET_TIMEOUT 73
#define DTLS_CTRL_HANDLE_TIMEOUT 74 #define DTLS_CTRL_HANDLE_TIMEOUT 74
@ -1768,6 +1780,11 @@ int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
int SSL_use_certificate(SSL *ssl, X509 *x); int SSL_use_certificate(SSL *ssl, X509 *x);
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
#ifndef OPENSSL_NO_TLSEXT
int SSL_CTX_use_authz(SSL_CTX *ctx, unsigned char *authz, size_t authz_length);
int SSL_use_authz(SSL *ssl, unsigned char *authz, size_t authz_length);
#endif
#ifndef OPENSSL_NO_STDIO #ifndef OPENSSL_NO_STDIO
int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
@ -1812,6 +1829,10 @@ int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
#ifndef OPENSSL_NO_BIO #ifndef OPENSSL_NO_BIO
int SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses); int SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
#endif #endif
#ifndef OPENSSL_NO_TLSEXT
unsigned char *SSL_SESSION_get_tlsext_authz_server_audit_proof(SSL_SESSION *s,
size_t *proof_length);
#endif
void SSL_SESSION_free(SSL_SESSION *ses); void SSL_SESSION_free(SSL_SESSION *ses);
int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp); int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
int SSL_set_session(SSL *to, SSL_SESSION *session); int SSL_set_session(SSL *to, SSL_SESSION *session);
@ -2115,6 +2136,7 @@ void ERR_load_SSL_strings(void);
/* Error codes for the SSL functions. */ /* Error codes for the SSL functions. */
/* Function codes. */ /* Function codes. */
#define SSL_F_AUTHZ_VALIDATE 323
#define SSL_F_CLIENT_CERTIFICATE 100 #define SSL_F_CLIENT_CERTIFICATE 100
#define SSL_F_CLIENT_FINISHED 167 #define SSL_F_CLIENT_FINISHED 167
#define SSL_F_CLIENT_HELLO 101 #define SSL_F_CLIENT_HELLO 101
@ -2260,6 +2282,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 #define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219
#define SSL_F_SSL_CTX_SET_SSL_VERSION 170 #define SSL_F_SSL_CTX_SET_SSL_VERSION 170
#define SSL_F_SSL_CTX_SET_TRUST 229 #define SSL_F_SSL_CTX_SET_TRUST 229
#define SSL_F_SSL_CTX_USE_AUTHZ 324
#define SSL_F_SSL_CTX_USE_CERTIFICATE 171 #define SSL_F_SSL_CTX_USE_CERTIFICATE 171
#define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 #define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172
#define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220 #define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220
@ -2274,6 +2297,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_DO_HANDSHAKE 180 #define SSL_F_SSL_DO_HANDSHAKE 180
#define SSL_F_SSL_GET_NEW_SESSION 181 #define SSL_F_SSL_GET_NEW_SESSION 181
#define SSL_F_SSL_GET_PREV_SESSION 217 #define SSL_F_SSL_GET_PREV_SESSION 217
#define SSL_F_SSL_GET_SERVER_CERT_INDEX 329
#define SSL_F_SSL_GET_SERVER_SEND_PKEY 182 #define SSL_F_SSL_GET_SERVER_SEND_PKEY 182
#define SSL_F_SSL_GET_SIGN_PKEY 183 #define SSL_F_SSL_GET_SIGN_PKEY 183
#define SSL_F_SSL_INIT_WBIO_BUFFER 184 #define SSL_F_SSL_INIT_WBIO_BUFFER 184
@ -2297,6 +2321,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_SESSION_PRINT_FP 190 #define SSL_F_SSL_SESSION_PRINT_FP 190
#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 #define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312
#define SSL_F_SSL_SESS_CERT_NEW 225 #define SSL_F_SSL_SESS_CERT_NEW 225
#define SSL_F_SSL_SET_AUTHZ 325
#define SSL_F_SSL_SET_CERT 191 #define SSL_F_SSL_SET_CERT 191
#define SSL_F_SSL_SET_CIPHER_LIST 271 #define SSL_F_SSL_SET_CIPHER_LIST 271
#define SSL_F_SSL_SET_FD 192 #define SSL_F_SSL_SET_FD 192
@ -2313,6 +2338,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243 #define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243
#define SSL_F_SSL_UNDEFINED_FUNCTION 197 #define SSL_F_SSL_UNDEFINED_FUNCTION 197
#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 #define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244
#define SSL_F_SSL_USE_AUTHZ 328
#define SSL_F_SSL_USE_CERTIFICATE 198 #define SSL_F_SSL_USE_CERTIFICATE 198
#define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 #define SSL_F_SSL_USE_CERTIFICATE_ASN1 199
#define SSL_F_SSL_USE_CERTIFICATE_FILE 200 #define SSL_F_SSL_USE_CERTIFICATE_FILE 200
@ -2330,16 +2356,19 @@ void ERR_load_SSL_strings(void);
#define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 #define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274
#define SSL_F_TLS1_ENC 210 #define SSL_F_TLS1_ENC 210
#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 #define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314
#define SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA 326
#define SSL_F_TLS1_HEARTBEAT 315 #define SSL_F_TLS1_HEARTBEAT 315
#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275 #define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275
#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276 #define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276
#define SSL_F_TLS1_PRF 284 #define SSL_F_TLS1_PRF 284
#define SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA 327
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211 #define SSL_F_TLS1_SETUP_KEY_BLOCK 211
#define SSL_F_WRITE_PENDING 212 #define SSL_F_WRITE_PENDING 212
/* Reason codes. */ /* Reason codes. */
#define SSL_R_APP_DATA_IN_HANDSHAKE 100 #define SSL_R_APP_DATA_IN_HANDSHAKE 100
#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 #define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
#define SSL_R_AUTHZ_DATA_TOO_LARGE 375
#define SSL_R_BAD_ALERT_RECORD 101 #define SSL_R_BAD_ALERT_RECORD 101
#define SSL_R_BAD_AUTHENTICATION_TYPE 102 #define SSL_R_BAD_AUTHENTICATION_TYPE 102
#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 #define SSL_R_BAD_CHANGE_CIPHER_SPEC 103
@ -2428,6 +2457,8 @@ void ERR_load_SSL_strings(void);
#define SSL_R_HTTP_REQUEST 156 #define SSL_R_HTTP_REQUEST 156
#define SSL_R_ILLEGAL_PADDING 283 #define SSL_R_ILLEGAL_PADDING 283
#define SSL_R_INCONSISTENT_COMPRESSION 340 #define SSL_R_INCONSISTENT_COMPRESSION 340
#define SSL_R_INVALID_AUDIT_PROOF 371
#define SSL_R_INVALID_AUTHZ_DATA 374
#define SSL_R_INVALID_CHALLENGE_LENGTH 158 #define SSL_R_INVALID_CHALLENGE_LENGTH 158
#define SSL_R_INVALID_COMMAND 280 #define SSL_R_INVALID_COMMAND 280
#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 #define SSL_R_INVALID_COMPRESSION_ALGORITHM 341
@ -2607,6 +2638,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_UNEXPECTED_RECORD 245 #define SSL_R_UNEXPECTED_RECORD 245
#define SSL_R_UNINITIALIZED 276 #define SSL_R_UNINITIALIZED 276
#define SSL_R_UNKNOWN_ALERT_TYPE 246 #define SSL_R_UNKNOWN_ALERT_TYPE 246
#define SSL_R_UNKNOWN_AUTHZ_DATA_TYPE 372
#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 #define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247
#define SSL_R_UNKNOWN_CIPHER_RETURNED 248 #define SSL_R_UNKNOWN_CIPHER_RETURNED 248
#define SSL_R_UNKNOWN_CIPHER_TYPE 249 #define SSL_R_UNKNOWN_CIPHER_TYPE 249
@ -2617,6 +2649,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 253 #define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 253
#define SSL_R_UNKNOWN_SSL_VERSION 254 #define SSL_R_UNKNOWN_SSL_VERSION 254
#define SSL_R_UNKNOWN_STATE 255 #define SSL_R_UNKNOWN_STATE 255
#define SSL_R_UNKNOWN_SUPPLEMENTAL_DATA_TYPE 373
#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 #define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338
#define SSL_R_UNSUPPORTED_CIPHER 256 #define SSL_R_UNSUPPORTED_CIPHER 256
#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 #define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257

View File

@ -540,6 +540,22 @@ typedef struct ssl3_state_st
our peer. */ our peer. */
int next_proto_neg_seen; int next_proto_neg_seen;
#endif #endif
#ifndef OPENSSL_NO_TLSEXT
/* tlsext_authz_client_types contains an array of supported authz
* types, as advertised by the client. The array is sorted and
* does not contain any duplicates. */
unsigned char *tlsext_authz_client_types;
size_t tlsext_authz_client_types_len;
/* tlsext_authz_promised_to_client is true iff we're a server and we
* echoed the client's supplemental data extension and therefore must
* send a supplemental data handshake message. */
char tlsext_authz_promised_to_client;
/* tlsext_authz_server_promised is true iff we're a client and the
* server echoed our server_authz extension and therefore must send us
* a supplemental data handshake message. */
char tlsext_authz_server_promised;
#endif
} SSL3_STATE; } SSL3_STATE;
#endif #endif
@ -568,6 +584,8 @@ typedef struct ssl3_state_st
#define SSL3_ST_CR_CERT_REQ_B (0x151|SSL_ST_CONNECT) #define SSL3_ST_CR_CERT_REQ_B (0x151|SSL_ST_CONNECT)
#define SSL3_ST_CR_SRVR_DONE_A (0x160|SSL_ST_CONNECT) #define SSL3_ST_CR_SRVR_DONE_A (0x160|SSL_ST_CONNECT)
#define SSL3_ST_CR_SRVR_DONE_B (0x161|SSL_ST_CONNECT) #define SSL3_ST_CR_SRVR_DONE_B (0x161|SSL_ST_CONNECT)
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_A (0x210|SSL_ST_CONNECT)
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_B (0x211|SSL_ST_CONNECT)
/* write to server */ /* write to server */
#define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT) #define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT)
#define SSL3_ST_CW_CERT_B (0x171|SSL_ST_CONNECT) #define SSL3_ST_CW_CERT_B (0x171|SSL_ST_CONNECT)
@ -647,6 +665,8 @@ typedef struct ssl3_state_st
#define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT) #define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT)
#define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT) #define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT)
#define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT) #define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT)
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_A (0x220|SSL_ST_ACCEPT)
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_B (0x221|SSL_ST_ACCEPT)
#define SSL3_MT_HELLO_REQUEST 0 #define SSL3_MT_HELLO_REQUEST 0
#define SSL3_MT_CLIENT_HELLO 1 #define SSL3_MT_CLIENT_HELLO 1
@ -660,6 +680,7 @@ typedef struct ssl3_state_st
#define SSL3_MT_CLIENT_KEY_EXCHANGE 16 #define SSL3_MT_CLIENT_KEY_EXCHANGE 16
#define SSL3_MT_FINISHED 20 #define SSL3_MT_FINISHED 20
#define SSL3_MT_CERTIFICATE_STATUS 22 #define SSL3_MT_CERTIFICATE_STATUS 22
#define SSL3_MT_SUPPLEMENTAL_DATA 23
#ifndef OPENSSL_NO_NEXTPROTONEG #ifndef OPENSSL_NO_NEXTPROTONEG
#define SSL3_MT_NEXT_PROTO 67 #define SSL3_MT_NEXT_PROTO 67
#endif #endif
@ -682,4 +703,3 @@ typedef struct ssl3_state_st
} }
#endif #endif
#endif #endif

View File

@ -334,6 +334,22 @@ CERT *ssl_cert_dup(CERT *cert)
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
} }
} }
if (cert->pkeys[i].authz != NULL)
{
/* Just copy everything. */
ret->pkeys[i].authz_length =
cert->pkeys[i].authz_length;
ret->pkeys[i].authz =
OPENSSL_malloc(ret->pkeys[i].authz_length);
if (ret->pkeys[i].authz == NULL)
{
SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
return(NULL);
}
memcpy(ret->pkeys[i].authz,
cert->pkeys[i].authz,
cert->pkeys[i].authz_length);
}
} }
ret->references=1; ret->references=1;
@ -421,6 +437,10 @@ void ssl_cert_free(CERT *c)
#if 0 #if 0
if (c->pkeys[i].publickey != NULL) if (c->pkeys[i].publickey != NULL)
EVP_PKEY_free(c->pkeys[i].publickey); EVP_PKEY_free(c->pkeys[i].publickey);
#endif
#ifndef OPENSSL_NO_TLSEXT
if (c->pkeys[i].authz != NULL)
OPENSSL_free(c->pkeys[i].authz);
#endif #endif
} }
if (c->sigalgs) if (c->sigalgs)

View File

@ -70,6 +70,7 @@
static ERR_STRING_DATA SSL_str_functs[]= static ERR_STRING_DATA SSL_str_functs[]=
{ {
{ERR_FUNC(SSL_F_AUTHZ_VALIDATE), "AUTHZ_VALIDATE"},
{ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"}, {ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"},
{ERR_FUNC(SSL_F_CLIENT_FINISHED), "CLIENT_FINISHED"}, {ERR_FUNC(SSL_F_CLIENT_FINISHED), "CLIENT_FINISHED"},
{ERR_FUNC(SSL_F_CLIENT_HELLO), "CLIENT_HELLO"}, {ERR_FUNC(SSL_F_CLIENT_HELLO), "CLIENT_HELLO"},
@ -215,6 +216,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT), "SSL_CTX_set_session_id_context"}, {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_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_SET_TRUST), "SSL_CTX_set_trust"},
{ERR_FUNC(SSL_F_SSL_CTX_USE_AUTHZ), "SSL_CTX_use_authz"},
{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE), "SSL_CTX_use_certificate"}, {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_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_CHAIN_FILE), "SSL_CTX_use_certificate_chain_file"},
@ -229,6 +231,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_DO_HANDSHAKE), "SSL_do_handshake"}, {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_NEW_SESSION), "SSL_GET_NEW_SESSION"},
{ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "SSL_GET_PREV_SESSION"}, {ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "SSL_GET_PREV_SESSION"},
{ERR_FUNC(SSL_F_SSL_GET_SERVER_CERT_INDEX), "SSL_GET_SERVER_CERT_INDEX"},
{ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY), "SSL_GET_SERVER_SEND_PKEY"}, {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_GET_SIGN_PKEY), "SSL_GET_SIGN_PKEY"},
{ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "SSL_INIT_WBIO_BUFFER"}, {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "SSL_INIT_WBIO_BUFFER"},
@ -252,6 +255,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"}, {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"},
{ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), "SSL_SESSION_set1_id_context"}, {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), "SSL_SESSION_set1_id_context"},
{ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "SSL_SESS_CERT_NEW"}, {ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "SSL_SESS_CERT_NEW"},
{ERR_FUNC(SSL_F_SSL_SET_AUTHZ), "SSL_SET_AUTHZ"},
{ERR_FUNC(SSL_F_SSL_SET_CERT), "SSL_SET_CERT"}, {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_CIPHER_LIST), "SSL_set_cipher_list"},
{ERR_FUNC(SSL_F_SSL_SET_FD), "SSL_set_fd"}, {ERR_FUNC(SSL_F_SSL_SET_FD), "SSL_set_fd"},
@ -268,6 +272,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), "SSL_UNDEFINED_CONST_FUNCTION"}, {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_FUNCTION), "SSL_UNDEFINED_FUNCTION"},
{ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), "SSL_UNDEFINED_VOID_FUNCTION"}, {ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), "SSL_UNDEFINED_VOID_FUNCTION"},
{ERR_FUNC(SSL_F_SSL_USE_AUTHZ), "SSL_use_authz"},
{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE), "SSL_use_certificate"}, {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_ASN1), "SSL_use_certificate_ASN1"},
{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE), "SSL_use_certificate_file"}, {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE), "SSL_use_certificate_file"},
@ -285,10 +290,12 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT), "TLS1_CHECK_SERVERHELLO_TLSEXT"}, {ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT), "TLS1_CHECK_SERVERHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"}, {ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"},
{ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), "TLS1_EXPORT_KEYING_MATERIAL"}, {ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), "TLS1_EXPORT_KEYING_MATERIAL"},
{ERR_FUNC(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA), "TLS1_GET_SERVER_SUPPLEMENTAL_DATA"},
{ERR_FUNC(SSL_F_TLS1_HEARTBEAT), "SSL_F_TLS1_HEARTBEAT"}, {ERR_FUNC(SSL_F_TLS1_HEARTBEAT), "SSL_F_TLS1_HEARTBEAT"},
{ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT), "TLS1_PREPARE_CLIENTHELLO_TLSEXT"}, {ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT), "TLS1_PREPARE_CLIENTHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT), "TLS1_PREPARE_SERVERHELLO_TLSEXT"}, {ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT), "TLS1_PREPARE_SERVERHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"}, {ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"},
{ERR_FUNC(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA), "TLS1_SEND_SERVER_SUPPLEMENTAL_DATA"},
{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"}, {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"},
{ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"}, {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"},
{0,NULL} {0,NULL}
@ -298,6 +305,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ {
{ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE) ,"app data in handshake"}, {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_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT),"attempt to reuse session in different context"},
{ERR_REASON(SSL_R_AUTHZ_DATA_TOO_LARGE) ,"authz data too large"},
{ERR_REASON(SSL_R_BAD_ALERT_RECORD) ,"bad alert record"}, {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_AUTHENTICATION_TYPE),"bad authentication type"},
{ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC),"bad change cipher spec"}, {ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC),"bad change cipher spec"},
@ -386,6 +394,8 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_HTTP_REQUEST) ,"http request"}, {ERR_REASON(SSL_R_HTTP_REQUEST) ,"http request"},
{ERR_REASON(SSL_R_ILLEGAL_PADDING) ,"illegal padding"}, {ERR_REASON(SSL_R_ILLEGAL_PADDING) ,"illegal padding"},
{ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"}, {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"},
{ERR_REASON(SSL_R_INVALID_AUDIT_PROOF) ,"invalid audit proof"},
{ERR_REASON(SSL_R_INVALID_AUTHZ_DATA) ,"invalid authz data"},
{ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"}, {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
{ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"}, {ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"},
{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"}, {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
@ -565,6 +575,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_UNEXPECTED_RECORD) ,"unexpected record"}, {ERR_REASON(SSL_R_UNEXPECTED_RECORD) ,"unexpected record"},
{ERR_REASON(SSL_R_UNINITIALIZED) ,"uninitialized"}, {ERR_REASON(SSL_R_UNINITIALIZED) ,"uninitialized"},
{ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE) ,"unknown alert type"}, {ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE) ,"unknown alert type"},
{ERR_REASON(SSL_R_UNKNOWN_AUTHZ_DATA_TYPE),"unknown authz data type"},
{ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE),"unknown certificate 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_RETURNED),"unknown cipher returned"},
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE) ,"unknown cipher type"}, {ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE) ,"unknown cipher type"},
@ -575,6 +586,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE),"unknown remote error type"}, {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_SSL_VERSION) ,"unknown ssl version"},
{ERR_REASON(SSL_R_UNKNOWN_STATE) ,"unknown state"}, {ERR_REASON(SSL_R_UNKNOWN_STATE) ,"unknown state"},
{ERR_REASON(SSL_R_UNKNOWN_SUPPLEMENTAL_DATA_TYPE),"unknown supplemental data type"},
{ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED),"unsafe legacy renegotiation disabled"}, {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_CIPHER) ,"unsupported cipher"},
{ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"}, {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"},

View File

@ -2323,14 +2323,9 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
#endif #endif
/* THIS NEEDS CLEANING UP */ /* THIS NEEDS CLEANING UP */
CERT_PKEY *ssl_get_server_send_pkey(SSL *s) static int ssl_get_server_cert_index(SSL *s)
{ {
unsigned long alg_k,alg_a; unsigned long alg_k, alg_a;
CERT *c;
int i;
c=s->cert;
ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
alg_k = s->s3->tmp.new_cipher->algorithm_mkey; alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
alg_a = s->s3->tmp.new_cipher->algorithm_auth; alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@ -2348,42 +2343,53 @@ CERT_PKEY *ssl_get_server_send_pkey(SSL *s)
* checks for SSL_kECDH before RSA * checks for SSL_kECDH before RSA
* checks ensures the correct cert is chosen. * checks ensures the correct cert is chosen.
*/ */
i=SSL_PKEY_ECC; return SSL_PKEY_ECC;
} }
else if (alg_a & SSL_aECDSA) else if (alg_a & SSL_aECDSA)
{ return SSL_PKEY_ECC;
i=SSL_PKEY_ECC;
}
else if (alg_k & SSL_kDHr) else if (alg_k & SSL_kDHr)
i=SSL_PKEY_DH_RSA; return SSL_PKEY_DH_RSA;
else if (alg_k & SSL_kDHd) else if (alg_k & SSL_kDHd)
i=SSL_PKEY_DH_DSA; return SSL_PKEY_DH_DSA;
else if (alg_a & SSL_aDSS) else if (alg_a & SSL_aDSS)
i=SSL_PKEY_DSA_SIGN; return SSL_PKEY_DSA_SIGN;
else if (alg_a & SSL_aRSA) else if (alg_a & SSL_aRSA)
{ {
if (c->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL) if (s->cert->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL)
i=SSL_PKEY_RSA_SIGN; return SSL_PKEY_RSA_SIGN;
else else
i=SSL_PKEY_RSA_ENC; return SSL_PKEY_RSA_ENC;
} }
else if (alg_a & SSL_aKRB5) else if (alg_a & SSL_aKRB5)
{
/* VRS something else here? */ /* VRS something else here? */
return(NULL); return -1;
}
else if (alg_a & SSL_aGOST94) else if (alg_a & SSL_aGOST94)
i=SSL_PKEY_GOST94; return SSL_PKEY_GOST94;
else if (alg_a & SSL_aGOST01) else if (alg_a & SSL_aGOST01)
i=SSL_PKEY_GOST01; return SSL_PKEY_GOST01;
else /* if (alg_a & SSL_aNULL) */ else /* if (alg_a & SSL_aNULL) */
{ {
SSLerr(SSL_F_SSL_GET_SERVER_SEND_PKEY,ERR_R_INTERNAL_ERROR); SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX,ERR_R_INTERNAL_ERROR);
return(NULL); return -1;
}
} }
if (c->pkeys[i].x509 == NULL) return(NULL);
return(&c->pkeys[i]); CERT_PKEY *ssl_get_server_send_pkey(SSL *s)
{
CERT *c;
int i;
c = s->cert;
ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
i = ssl_get_server_cert_index(s);
/* This may or may not be an error. */
if (i < 0)
return NULL;
/* May be NULL. */
return &c->pkeys[i];
} }
EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd) EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd)
@ -2418,6 +2424,27 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd)
return c->pkeys[idx].privatekey; return c->pkeys[idx].privatekey;
} }
#ifndef OPENSSL_NO_TLSEXT
unsigned char *ssl_get_authz_data(SSL *s, size_t *authz_length)
{
CERT *c;
int i;
c = s->cert;
i = ssl_get_server_cert_index(s);
if (i == -1)
return NULL;
*authz_length = 0;
if (c->pkeys[i].authz == NULL)
return(NULL);
*authz_length = c->pkeys[i].authz_length;
return c->pkeys[i].authz;
}
#endif
void ssl_update_cache(SSL *s,int mode) void ssl_update_cache(SSL *s,int mode)
{ {
int i; int i;

View File

@ -474,6 +474,15 @@ typedef struct cert_pkey_st
const EVP_MD *digest; const EVP_MD *digest;
/* Chain for this certificate */ /* Chain for this certificate */
STACK_OF(X509) *chain; STACK_OF(X509) *chain;
#ifndef OPENSSL_NO_TLSEXT
/* authz/authz_length contain authz data for this certificate. The data
* is in wire format, specifically it's a series of records like:
* uint8_t authz_type; // (RFC 5878, AuthzDataFormat)
* uint16_t length;
* uint8_t data[length]; */
unsigned char *authz;
size_t authz_length;
#endif
} CERT_PKEY; } CERT_PKEY;
typedef struct cert_st typedef struct cert_st
@ -856,6 +865,7 @@ int ssl_undefined_function(SSL *s);
int ssl_undefined_void_function(void); int ssl_undefined_void_function(void);
int ssl_undefined_const_function(const SSL *s); int ssl_undefined_const_function(const SSL *s);
CERT_PKEY *ssl_get_server_send_pkey(SSL *); CERT_PKEY *ssl_get_server_send_pkey(SSL *);
unsigned char *ssl_get_authz_data(SSL *s, size_t *authz_length);
EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *c, const EVP_MD **pmd); EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *c, const EVP_MD **pmd);
int ssl_cert_type(X509 *x,EVP_PKEY *pkey); int ssl_cert_type(X509 *x,EVP_PKEY *pkey);
void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher); void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
@ -1125,6 +1135,11 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d,
int ssl_prepare_clienthello_tlsext(SSL *s); int ssl_prepare_clienthello_tlsext(SSL *s);
int ssl_prepare_serverhello_tlsext(SSL *s); int ssl_prepare_serverhello_tlsext(SSL *s);
/* server only */
int tls1_send_server_supplemental_data(SSL *s);
/* client only */
int tls1_get_server_supplemental_data(SSL *s);
#ifndef OPENSSL_NO_HEARTBEATS #ifndef OPENSSL_NO_HEARTBEATS
int tls1_heartbeat(SSL *s); int tls1_heartbeat(SSL *s);
int dtls1_heartbeat(SSL *s); int dtls1_heartbeat(SSL *s);

View File

@ -66,6 +66,10 @@
static int ssl_set_cert(CERT *c, X509 *x509); static int ssl_set_cert(CERT *c, X509 *x509);
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
#ifndef OPENSSL_NO_TLSEXT
static int ssl_set_authz(CERT *c, unsigned char *authz,
size_t authz_length);
#endif
int SSL_use_certificate(SSL *ssl, X509 *x) int SSL_use_certificate(SSL *ssl, X509 *x)
{ {
if (x == NULL) if (x == NULL)
@ -459,6 +463,15 @@ static int ssl_set_cert(CERT *c, X509 *x)
X509_free(c->pkeys[i].x509); X509_free(c->pkeys[i].x509);
CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509); CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
c->pkeys[i].x509=x; c->pkeys[i].x509=x;
#ifndef OPENSSL_NO_TLSEXT
/* Free the old authz data, if it exists. */
if (c->pkeys[i].authz != NULL)
{
OPENSSL_free(c->pkeys[i].authz);
c->pkeys[i].authz = NULL;
c->pkeys[i].authz_length = 0;
}
#endif
c->key= &(c->pkeys[i]); c->key= &(c->pkeys[i]);
c->valid=0; c->valid=0;
@ -725,7 +738,7 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */ ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
in=BIO_new(BIO_s_file_internal()); in = BIO_new(BIO_s_file_internal());
if (in == NULL) if (in == NULL)
{ {
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_BUF_LIB); SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_BUF_LIB);
@ -738,14 +751,16 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
goto end; goto end;
} }
x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata); x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata);
if (x == NULL) if (x == NULL)
{ {
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_PEM_LIB); SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_PEM_LIB);
goto end; goto end;
} }
ret=SSL_CTX_use_certificate(ctx,x); ret = SSL_CTX_use_certificate(ctx, x);
if (ERR_peek_error() != 0) if (ERR_peek_error() != 0)
ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */ ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */
if (ret) if (ret)
@ -763,7 +778,9 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
ctx->extra_certs = NULL; ctx->extra_certs = NULL;
} }
while ((ca = PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata)) while ((ca = PEM_read_bio_X509(in, NULL,
ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata))
!= NULL) != NULL)
{ {
r = SSL_CTX_add_extra_chain_cert(ctx, ca); r = SSL_CTX_add_extra_chain_cert(ctx, ca);
@ -792,3 +809,96 @@ end:
return(ret); return(ret);
} }
#endif #endif
#ifndef OPENSSL_NO_TLSEXT
/* authz_validate returns true iff authz is well formed, i.e. that it meets the
* wire format as documented in the CERT_PKEY structure and that there are no
* duplicate entries. */
static char authz_validate(const unsigned char *authz, size_t length)
{
unsigned char types_seen_bitmap[32];
if (!authz)
return 1;
memset(types_seen_bitmap, 0, sizeof(types_seen_bitmap));
for (;;)
{
unsigned char type, byte, bit;
unsigned short len;
if (!length)
return 1;
type = *(authz++);
length--;
byte = type / 8;
bit = type & 7;
if (types_seen_bitmap[byte] & (1 << bit))
return 0;
types_seen_bitmap[byte] |= (1 << bit);
if (length < 2)
return 0;
len = ((unsigned short) authz[0]) << 8 |
((unsigned short) authz[1]);
authz += 2;
length -= 2;
if (length < len)
return 0;
authz += len;
length -= len;
}
}
static int ssl_set_authz(CERT *c, unsigned char *authz, size_t authz_length)
{
CERT_PKEY *current_key = c->key;
if (current_key == NULL)
return 0;
if (!authz_validate(authz, authz_length))
{
SSLerr(SSL_F_SSL_SET_AUTHZ,SSL_R_INVALID_AUTHZ_DATA);
return(0);
}
current_key->authz = OPENSSL_realloc(current_key->authz, authz_length);
current_key->authz_length = authz_length;
memcpy(current_key->authz, authz, authz_length);
return 1;
}
int SSL_CTX_use_authz(SSL_CTX *ctx, unsigned char *authz,
size_t authz_length)
{
if (authz == NULL)
{
SSLerr(SSL_F_SSL_CTX_USE_AUTHZ,ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (!ssl_cert_inst(&ctx->cert))
{
SSLerr(SSL_F_SSL_CTX_USE_AUTHZ,ERR_R_MALLOC_FAILURE);
return 0;
}
return ssl_set_authz(ctx->cert, authz, authz_length);
}
int SSL_use_authz(SSL *ssl, unsigned char *authz, size_t authz_length)
{
if (authz == NULL)
{
SSLerr(SSL_F_SSL_USE_AUTHZ,ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (!ssl_cert_inst(&ssl->cert))
{
SSLerr(SSL_F_SSL_USE_AUTHZ,ERR_R_MALLOC_FAILURE);
return 0;
}
return ssl_set_authz(ssl->cert, authz, authz_length);
}
#endif /* OPENSSL_NO_TLSEXT */

View File

@ -739,6 +739,8 @@ void SSL_SESSION_free(SSL_SESSION *ss)
ss->tlsext_ellipticcurvelist_length = 0; ss->tlsext_ellipticcurvelist_length = 0;
if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist); if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist);
#endif /* OPENSSL_NO_EC */ #endif /* OPENSSL_NO_EC */
if (ss->audit_proof != NULL) OPENSSL_free(ss->audit_proof);
ss->audit_proof_length = 0;
#endif #endif
#ifndef OPENSSL_NO_PSK #ifndef OPENSSL_NO_PSK
if (ss->psk_identity_hint != NULL) if (ss->psk_identity_hint != NULL)
@ -860,6 +862,15 @@ int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx,
return 1; return 1;
} }
#ifndef OPENSSL_NO_TLSEXT
unsigned char *SSL_SESSION_get_tlsext_authz_server_audit_proof(SSL_SESSION *s, size_t *proof_length)
{
if (s->audit_proof != NULL)
*proof_length = s->audit_proof_length;
return s->audit_proof;
}
#endif
long SSL_CTX_set_timeout(SSL_CTX *s, long t) long SSL_CTX_set_timeout(SSL_CTX *s, long t)
{ {
long l; long l;

View File

@ -642,6 +642,19 @@ int tls12_get_req_sig_algs(SSL *s, unsigned char *p)
return (int)slen; return (int)slen;
} }
/* byte_compare is a compare function for qsort(3) that compares bytes. */
static int byte_compare(const void *in_a, const void *in_b)
{
unsigned char a = *((const unsigned char*) in_a);
unsigned char b = *((const unsigned char*) in_b);
if (a > b)
return 1;
else if (a < b)
return -1;
return 0;
}
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
{ {
int extdatalen=0; int extdatalen=0;
@ -983,7 +996,27 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
ret += el; ret += el;
} }
if ((extdatalen = ret-p-2)== 0) /* Add TLS extension Server_Authz_DataFormats to the ClientHello */
/* 2 bytes for extension type */
/* 2 bytes for extension length */
/* 1 byte for the list length */
/* 1 byte for the list (we only support audit proofs) */
if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL)
{
size_t lenmax;
const unsigned short ext_len = 2;
const unsigned char list_len = 1;
if ((lenmax = limit - ret - 6) < 0) return NULL;
s2n(TLSEXT_TYPE_server_authz, ret);
/* Extension length: 2 bytes */
s2n(ext_len, ret);
*(ret++) = list_len;
*(ret++) = TLSEXT_AUTHZDATAFORMAT_audit_proof;
}
if ((extdatalen = ret-p-2) == 0)
return p; return p;
s2n(extdatalen,p); s2n(extdatalen,p);
@ -1170,6 +1203,75 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
} }
#endif #endif
/* If the client supports authz then see whether we have any to offer
* to it. */
if (s->s3->tlsext_authz_client_types_len)
{
size_t authz_length;
/* By now we already know the new cipher, so we can look ahead
* to see whether the cert we are going to send
* has any authz data attached to it. */
const unsigned char* authz = ssl_get_authz_data(s, &authz_length);
const unsigned char* const orig_authz = authz;
size_t i;
unsigned authz_count = 0;
/* The authz data contains a number of the following structures:
* uint8_t authz_type
* uint16_t length
* uint8_t data[length]
*
* First we walk over it to find the number of authz elements. */
for (i = 0; i < authz_length; i++)
{
unsigned short length;
unsigned char type;
type = *(authz++);
if (memchr(s->s3->tlsext_authz_client_types,
type,
s->s3->tlsext_authz_client_types_len) != NULL)
authz_count++;
n2s(authz, length);
authz += length;
i += length;
}
if (authz_count)
{
/* Add TLS extension server_authz to the ServerHello message
* 2 bytes for extension type
* 2 bytes for extension length
* 1 byte for the list length
* n bytes for the list */
const unsigned short ext_len = 1 + authz_count;
if ((long)(limit - ret - 4 - ext_len) < 0) return NULL;
s2n(TLSEXT_TYPE_server_authz, ret);
s2n(ext_len, ret);
*(ret++) = authz_count;
s->s3->tlsext_authz_promised_to_client = 1;
}
authz = orig_authz;
for (i = 0; i < authz_length; i++)
{
unsigned short length;
unsigned char type;
authz_count++;
type = *(authz++);
if (memchr(s->s3->tlsext_authz_client_types,
type,
s->s3->tlsext_authz_client_types_len) != NULL)
*(ret++) = type;
n2s(authz, length);
authz += length;
i += length;
}
}
if ((extdatalen = ret-p-2)== 0) if ((extdatalen = ret-p-2)== 0)
return p; return p;
@ -1650,6 +1752,64 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
return 0; return 0;
} }
else if (type == TLSEXT_TYPE_server_authz)
{
unsigned char *sdata = data;
unsigned char server_authz_dataformatlist_length;
if (size == 0)
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
server_authz_dataformatlist_length = *(sdata++);
if (server_authz_dataformatlist_length != size - 1)
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
/* Successful session resumption uses the same authz
* information as the original session so we ignore this
* in the case of a session resumption. */
if (!s->hit)
{
size_t i;
s->s3->tlsext_authz_client_types =
OPENSSL_malloc(server_authz_dataformatlist_length);
if (!s->s3->tlsext_authz_client_types)
{
*al = TLS1_AD_INTERNAL_ERROR;
return 0;
}
s->s3->tlsext_authz_client_types_len =
server_authz_dataformatlist_length;
memcpy(s->s3->tlsext_authz_client_types,
sdata,
server_authz_dataformatlist_length);
/* Sort the types in order to check for duplicates. */
qsort(s->s3->tlsext_authz_client_types,
server_authz_dataformatlist_length,
1 /* element size */,
byte_compare);
for (i = 0; i < server_authz_dataformatlist_length; i++)
{
if (i > 0 &&
s->s3->tlsext_authz_client_types[i] ==
s->s3->tlsext_authz_client_types[i-1])
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
}
}
}
data+=size; data+=size;
} }
@ -1916,7 +2076,46 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
return 0; return 0;
} }
data+=size; else if (type == TLSEXT_TYPE_server_authz)
{
/* We only support audit proofs. It's an error to send
* an authz hello extension if the client
* didn't request a proof. */
unsigned char *sdata = data;
unsigned char server_authz_dataformatlist_length;
if (!s->ctx->tlsext_authz_server_audit_proof_cb)
{
*al = TLS1_AD_UNSUPPORTED_EXTENSION;
return 0;
}
if (!size)
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
server_authz_dataformatlist_length = *(sdata++);
if (server_authz_dataformatlist_length != size - 1)
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
/* We only support audit proofs, so a legal ServerHello
* authz list contains exactly one entry. */
if (server_authz_dataformatlist_length != 1 ||
sdata[0] != TLSEXT_AUTHZDATAFORMAT_audit_proof)
{
*al = TLS1_AD_UNSUPPORTED_EXTENSION;
return 0;
}
s->s3->tlsext_authz_server_promised = 1;
}
data += size;
} }
if (data != d+n) if (data != d+n)

View File

@ -281,6 +281,14 @@ extern "C" {
#define TLSEXT_MAXLEN_host_name 255 #define TLSEXT_MAXLEN_host_name 255
/* From RFC 5878 */
#define TLSEXT_SUPPLEMENTALDATATYPE_authz_data 16386
/* This is not IANA assigned. See
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#authorization-data-rules */
#define TLSEXT_AUTHZDATAFORMAT_audit_proof 182
#define TLSEXT_MAXLEN_supplemental_data 1024*16 /* Let's limit to 16k */
const char *SSL_get_servername(const SSL *s, const int type); const char *SSL_get_servername(const SSL *s, const int type);
int SSL_get_servername_type(const SSL *s); int SSL_get_servername_type(const SSL *s);
/* SSL_export_keying_material exports a value derived from the master secret, /* SSL_export_keying_material exports a value derived from the master secret,
@ -360,6 +368,13 @@ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
#define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ #define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
/* Used by clients to process audit proofs. */
#define SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx, cb) \
SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB,(void (*)(void))cb)
#define SSL_CTX_set_tlsext_authz_server_audit_proof_cb_arg(ctx, arg) \
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG, 0, arg);
#ifndef OPENSSL_NO_HEARTBEATS #ifndef OPENSSL_NO_HEARTBEATS
#define SSL_TLSEXT_HB_ENABLED 0x01 #define SSL_TLSEXT_HB_ENABLED 0x01
#define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02 #define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02