Support for certificate status TLS extension.
This commit is contained in:
parent
74eb3e0914
commit
67c8e7f414
26 changed files with 885 additions and 56 deletions
7
CHANGES
7
CHANGES
|
@ -4,6 +4,13 @@
|
|||
|
||||
Changes between 0.9.8f and 0.9.9 [xx XXX xxxx]
|
||||
|
||||
*) Implement certificate status request TLS extension defined in RFC3546.
|
||||
A client can set the appropriate parameters and receive the encoded
|
||||
OCSP response via a callback. A server can query the supplied parameters
|
||||
and set the encoded OCSP response in the callback. Add simplified examples
|
||||
to s_client and s_server.
|
||||
[Steve Henson]
|
||||
|
||||
*) Implement Opaque PRF Input TLS extension as specified in
|
||||
draft-rescorla-tls-opaque-prf-input-00.txt. Since this is not an
|
||||
official specification yet and no extension type assignment by
|
||||
|
|
|
@ -122,6 +122,9 @@
|
|||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_OCSP
|
||||
#include <openssl/ocsp.h>
|
||||
#endif
|
||||
#include <openssl/ossl_typ.h>
|
||||
|
||||
int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn);
|
||||
|
@ -247,6 +250,12 @@ X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
|
|||
ENGINE *setup_engine(BIO *err, const char *engine, int debug);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_OCSP
|
||||
OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
|
||||
char *host, char *path, char *port, int use_ssl,
|
||||
int req_timeout);
|
||||
#endif
|
||||
|
||||
int load_config(BIO *err, CONF *cnf);
|
||||
char *make_config_name(void);
|
||||
|
||||
|
|
91
apps/ocsp.c
91
apps/ocsp.c
|
@ -120,7 +120,6 @@ int MAIN(int argc, char **argv)
|
|||
long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
|
||||
char *CAfile = NULL, *CApath = NULL;
|
||||
X509_STORE *store = NULL;
|
||||
SSL_CTX *ctx = NULL;
|
||||
STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
|
||||
char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
|
||||
unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
|
||||
|
@ -723,48 +722,14 @@ int MAIN(int argc, char **argv)
|
|||
else if (host)
|
||||
{
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
cbio = BIO_new_connect(host);
|
||||
resp = process_responder(bio_err, req, host, path,
|
||||
port, use_ssl, req_timeout);
|
||||
if (!resp)
|
||||
goto end;
|
||||
#else
|
||||
BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
|
||||
goto end;
|
||||
#endif
|
||||
if (!cbio)
|
||||
{
|
||||
BIO_printf(bio_err, "Error creating connect BIO\n");
|
||||
goto end;
|
||||
}
|
||||
if (port) BIO_set_conn_port(cbio, port);
|
||||
if (use_ssl == 1)
|
||||
{
|
||||
BIO *sbio;
|
||||
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
|
||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
#elif !defined(OPENSSL_NO_SSL3)
|
||||
ctx = SSL_CTX_new(SSLv3_client_method());
|
||||
#elif !defined(OPENSSL_NO_SSL2)
|
||||
ctx = SSL_CTX_new(SSLv2_client_method());
|
||||
#else
|
||||
BIO_printf(bio_err, "SSL is disabled\n");
|
||||
goto end;
|
||||
#endif
|
||||
if (ctx == NULL)
|
||||
{
|
||||
BIO_printf(bio_err, "Error creating SSL context.\n");
|
||||
goto end;
|
||||
}
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
|
||||
sbio = BIO_new_ssl(ctx, 1);
|
||||
cbio = BIO_push(sbio, cbio);
|
||||
}
|
||||
|
||||
resp = query_responder(bio_err, cbio, path, req, req_timeout);
|
||||
BIO_free_all(cbio);
|
||||
cbio = NULL;
|
||||
if (!resp)
|
||||
{
|
||||
BIO_printf(bio_err, "Error querying OCSP responsder\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else if (respin)
|
||||
{
|
||||
|
@ -913,7 +878,6 @@ end:
|
|||
OPENSSL_free(host);
|
||||
OPENSSL_free(port);
|
||||
OPENSSL_free(path);
|
||||
SSL_CTX_free(ctx);
|
||||
}
|
||||
|
||||
OPENSSL_EXIT(ret);
|
||||
|
@ -1334,4 +1298,51 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
|
|||
return rsp;
|
||||
}
|
||||
|
||||
OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
|
||||
char *host, char *path, char *port, int use_ssl,
|
||||
int req_timeout)
|
||||
{
|
||||
BIO *cbio = NULL;
|
||||
SSL_CTX *ctx = NULL;
|
||||
OCSP_RESPONSE *resp = NULL;
|
||||
cbio = BIO_new_connect(host);
|
||||
if (!cbio)
|
||||
{
|
||||
BIO_printf(err, "Error creating connect BIO\n");
|
||||
goto end;
|
||||
}
|
||||
if (port) BIO_set_conn_port(cbio, port);
|
||||
if (use_ssl == 1)
|
||||
{
|
||||
BIO *sbio;
|
||||
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
|
||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
#elif !defined(OPENSSL_NO_SSL3)
|
||||
ctx = SSL_CTX_new(SSLv3_client_method());
|
||||
#elif !defined(OPENSSL_NO_SSL2)
|
||||
ctx = SSL_CTX_new(SSLv2_client_method());
|
||||
#else
|
||||
BIO_printf(err, "SSL is disabled\n");
|
||||
goto end;
|
||||
#endif
|
||||
if (ctx == NULL)
|
||||
{
|
||||
BIO_printf(err, "Error creating SSL context.\n");
|
||||
goto end;
|
||||
}
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
|
||||
sbio = BIO_new_ssl(ctx, 1);
|
||||
cbio = BIO_push(sbio, cbio);
|
||||
}
|
||||
resp = query_responder(err, cbio, path, req, req_timeout);
|
||||
if (!resp)
|
||||
BIO_printf(bio_err, "Error querying OCSP responsder\n");
|
||||
end:
|
||||
if (ctx)
|
||||
SSL_CTX_free(ctx);
|
||||
if (cbio)
|
||||
BIO_free_all(cbio);
|
||||
return resp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -161,6 +161,7 @@ typedef unsigned int u_int;
|
|||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/ocsp.h>
|
||||
#include "s_apps.h"
|
||||
#include "timeouts.h"
|
||||
|
||||
|
@ -196,12 +197,14 @@ static int c_Pause=0;
|
|||
static int c_debug=0;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int c_tlsextdebug=0;
|
||||
static int c_status_req=0;
|
||||
#endif
|
||||
static int c_msg=0;
|
||||
static int c_showcerts=0;
|
||||
|
||||
static void sc_usage(void);
|
||||
static void print_stuff(BIO *berr,SSL *con,int full);
|
||||
static int ocsp_resp_cb(SSL *s, void *arg);
|
||||
static BIO *bio_c_out=NULL;
|
||||
static int c_quiet=0;
|
||||
static int c_ign_eof=0;
|
||||
|
@ -329,6 +332,7 @@ static void sc_usage(void)
|
|||
#ifndef OPENSSL_NO_TLSEXT
|
||||
BIO_printf(bio_err," -servername host - Set TLS extension servername in ClientHello\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," -no_ticket - disable use of RFC4507bis session tickets\n");
|
||||
#endif
|
||||
}
|
||||
|
@ -528,6 +532,8 @@ int MAIN(int argc, char **argv)
|
|||
#ifndef OPENSSL_NO_TLSEXT
|
||||
else if (strcmp(*argv,"-tlsextdebug") == 0)
|
||||
c_tlsextdebug=1;
|
||||
else if (strcmp(*argv,"-status") == 0)
|
||||
c_status_req=1;
|
||||
#endif
|
||||
#ifdef WATT32
|
||||
else if (strcmp(*argv,"-wdebug") == 0)
|
||||
|
@ -954,6 +960,23 @@ re_start:
|
|||
SSL_set_tlsext_debug_callback(con, tlsext_cb);
|
||||
SSL_set_tlsext_debug_arg(con, bio_c_out);
|
||||
}
|
||||
if (c_status_req)
|
||||
{
|
||||
SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
|
||||
SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
|
||||
SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
|
||||
#if 0
|
||||
{
|
||||
STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();
|
||||
OCSP_RESPID *id = OCSP_RESPID_new();
|
||||
id->value.byKey = ASN1_OCTET_STRING_new();
|
||||
id->type = V_OCSP_RESPID_KEY;
|
||||
ASN1_STRING_set(id->value.byKey, "Hello World", -1);
|
||||
sk_OCSP_RESPID_push(ids, id);
|
||||
SSL_set_tlsext_status_ids(con, ids);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
SSL_set_bio(con,sbio,sbio);
|
||||
|
@ -1592,3 +1615,28 @@ static void print_stuff(BIO *bio, SSL *s, int full)
|
|||
(void)BIO_flush(bio);
|
||||
}
|
||||
|
||||
static int ocsp_resp_cb(SSL *s, void *arg)
|
||||
{
|
||||
const unsigned char *p;
|
||||
int len;
|
||||
OCSP_RESPONSE *rsp;
|
||||
len = SSL_get_tlsext_status_ocsp_resp(s, &p);
|
||||
BIO_puts(arg, "OCSP response: ");
|
||||
if (!p)
|
||||
{
|
||||
BIO_puts(arg, "no response sent\n");
|
||||
return 1;
|
||||
}
|
||||
rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
|
||||
if (!rsp)
|
||||
{
|
||||
BIO_puts(arg, "response parse error\n");
|
||||
BIO_dump_indent(arg, (char *)p, len, 4);
|
||||
return 0;
|
||||
}
|
||||
BIO_puts(arg, "\n======================================\n");
|
||||
OCSP_RESPONSE_print(arg, rsp, 0);
|
||||
BIO_puts(arg, "======================================\n");
|
||||
OCSP_RESPONSE_free(rsp);
|
||||
return 1;
|
||||
}
|
||||
|
|
182
apps/s_server.c
182
apps/s_server.c
|
@ -179,6 +179,7 @@ typedef unsigned int u_int;
|
|||
#include <openssl/x509.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/ocsp.h>
|
||||
#ifndef OPENSSL_NO_DH
|
||||
#include <openssl/dh.h>
|
||||
#endif
|
||||
|
@ -283,6 +284,8 @@ static BIO *bio_s_out=NULL;
|
|||
static int s_debug=0;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int s_tlsextdebug=0;
|
||||
static int s_tlsextstatus=0;
|
||||
static int cert_status_cb(SSL *s, void *arg);
|
||||
#endif
|
||||
static int s_msg=0;
|
||||
static int s_quiet=0;
|
||||
|
@ -664,6 +667,152 @@ static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
|
|||
}
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
|
||||
/* Structure passed to cert status callback */
|
||||
|
||||
typedef struct tlsextstatusctx_st {
|
||||
/* Default responder to use */
|
||||
char *host, *path, *port;
|
||||
int use_ssl;
|
||||
int timeout;
|
||||
BIO *err;
|
||||
int verbose;
|
||||
} tlsextstatusctx;
|
||||
|
||||
static tlsextstatusctx tlscstatp = {NULL, NULL, NULL, 0, -1, NULL, 0};
|
||||
|
||||
/* Certificate Status callback. This is called when a client includes a
|
||||
* certificate status request extension.
|
||||
*
|
||||
* This is a simplified version. It examines certificates each time and
|
||||
* makes one OCSP responder query for each request.
|
||||
*
|
||||
* A full version would store details such as the OCSP certificate IDs and
|
||||
* minimise the number of OCSP responses by caching them until they were
|
||||
* considered "expired".
|
||||
*/
|
||||
|
||||
static int cert_status_cb(SSL *s, void *arg)
|
||||
{
|
||||
tlsextstatusctx *srctx = arg;
|
||||
BIO *err = srctx->err;
|
||||
char *host, *port, *path;
|
||||
int use_ssl;
|
||||
unsigned char *rspder = NULL;
|
||||
int rspderlen;
|
||||
STACK *aia = NULL;
|
||||
X509 *x = NULL;
|
||||
X509_STORE_CTX inctx;
|
||||
X509_OBJECT obj;
|
||||
OCSP_REQUEST *req = NULL;
|
||||
OCSP_RESPONSE *resp = NULL;
|
||||
OCSP_CERTID *id = NULL;
|
||||
STACK_OF(X509_EXTENSION) *exts;
|
||||
int ret = SSL_TLSEXT_ERR_NOACK;
|
||||
int i;
|
||||
#if 0
|
||||
STACK_OF(OCSP_RESPID) *ids;
|
||||
SSL_get_tlsext_status_ids(s, &ids);
|
||||
BIO_printf(err, "cert_status: received %d ids\n", sk_OCSP_RESPID_num(ids));
|
||||
#endif
|
||||
if (srctx->verbose)
|
||||
BIO_puts(err, "cert_status: callback called\n");
|
||||
/* Build up OCSP query from server certificate */
|
||||
x = SSL_get_certificate(s);
|
||||
aia = X509_get1_ocsp(x);
|
||||
if (aia)
|
||||
{
|
||||
if (!OCSP_parse_url(sk_value(aia, 0),
|
||||
&host, &port, &path, &use_ssl))
|
||||
{
|
||||
BIO_puts(err, "cert_status: can't parse AIA URL\n");
|
||||
goto err;
|
||||
}
|
||||
if (srctx->verbose)
|
||||
BIO_printf(err, "cert_status: AIA URL: %s\n",
|
||||
sk_value(aia, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!srctx->host)
|
||||
{
|
||||
BIO_puts(srctx->err, "cert_status: no AIA and no default responder URL\n");
|
||||
goto done;
|
||||
}
|
||||
host = srctx->host;
|
||||
path = srctx->path;
|
||||
port = srctx->port;
|
||||
use_ssl = srctx->use_ssl;
|
||||
}
|
||||
|
||||
if (!X509_STORE_CTX_init(&inctx,
|
||||
SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
|
||||
NULL, NULL))
|
||||
goto err;
|
||||
if (X509_STORE_get_by_subject(&inctx,X509_LU_X509,
|
||||
X509_get_issuer_name(x),&obj) <= 0)
|
||||
{
|
||||
BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n");
|
||||
X509_STORE_CTX_cleanup(&inctx);
|
||||
goto done;
|
||||
}
|
||||
req = OCSP_REQUEST_new();
|
||||
if (!req)
|
||||
goto err;
|
||||
id = OCSP_cert_to_id(NULL, x, obj.data.x509);
|
||||
X509_free(obj.data.x509);
|
||||
X509_STORE_CTX_cleanup(&inctx);
|
||||
if (!id)
|
||||
goto err;
|
||||
if (!OCSP_request_add0_id(req, id))
|
||||
goto err;
|
||||
id = NULL;
|
||||
/* Add any extensions to the request */
|
||||
SSL_get_tlsext_status_exts(s, &exts);
|
||||
for (i = 0; i < sk_X509_EXTENSION_num(exts); i++)
|
||||
{
|
||||
X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
|
||||
if (!OCSP_REQUEST_add_ext(req, ext, -1))
|
||||
goto err;
|
||||
}
|
||||
resp = process_responder(err, req, host, path, port, use_ssl,
|
||||
srctx->timeout);
|
||||
if (!resp)
|
||||
{
|
||||
BIO_puts(err, "cert_status: error querying responder\n");
|
||||
goto done;
|
||||
}
|
||||
rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
|
||||
if (rspderlen <= 0)
|
||||
goto err;
|
||||
SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
|
||||
if (srctx->verbose)
|
||||
{
|
||||
BIO_puts(err, "cert_status: ocsp response sent:\n");
|
||||
OCSP_RESPONSE_print(err, resp, 2);
|
||||
}
|
||||
ret = SSL_TLSEXT_ERR_OK;
|
||||
done:
|
||||
if (ret != SSL_TLSEXT_ERR_OK)
|
||||
ERR_print_errors(err);
|
||||
if (aia)
|
||||
{
|
||||
OPENSSL_free(host);
|
||||
OPENSSL_free(path);
|
||||
OPENSSL_free(port);
|
||||
X509_email_free(aia);
|
||||
}
|
||||
if (id)
|
||||
OCSP_CERTID_free(id);
|
||||
if (req)
|
||||
OCSP_REQUEST_free(req);
|
||||
if (resp)
|
||||
OCSP_RESPONSE_free(resp);
|
||||
return ret;
|
||||
err:
|
||||
ret = SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
int MAIN(int, char **);
|
||||
|
@ -877,6 +1026,33 @@ int MAIN(int argc, char *argv[])
|
|||
#ifndef OPENSSL_NO_TLSEXT
|
||||
else if (strcmp(*argv,"-tlsextdebug") == 0)
|
||||
s_tlsextdebug=1;
|
||||
else if (strcmp(*argv,"-status") == 0)
|
||||
s_tlsextstatus=1;
|
||||
else if (strcmp(*argv,"-status_verbose") == 0)
|
||||
{
|
||||
s_tlsextstatus=1;
|
||||
tlscstatp.verbose = 1;
|
||||
}
|
||||
else if (!strcmp(*argv, "-status_timeout"))
|
||||
{
|
||||
s_tlsextstatus=1;
|
||||
if (--argc < 1) goto bad;
|
||||
tlscstatp.timeout = atoi(*(++argv));
|
||||
}
|
||||
else if (!strcmp(*argv, "-status_url"))
|
||||
{
|
||||
s_tlsextstatus=1;
|
||||
if (--argc < 1) goto bad;
|
||||
if (!OCSP_parse_url(*(++argv),
|
||||
&tlscstatp.host,
|
||||
&tlscstatp.port,
|
||||
&tlscstatp.path,
|
||||
&tlscstatp.use_ssl))
|
||||
{
|
||||
BIO_printf(bio_err, "Error parsing URL\n");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (strcmp(*argv,"-msg") == 0)
|
||||
{ s_msg=1; }
|
||||
|
@ -1560,6 +1736,12 @@ static int sv_body(char *hostname, int s, unsigned char *context)
|
|||
SSL_set_tlsext_debug_callback(con, tlsext_cb);
|
||||
SSL_set_tlsext_debug_arg(con, bio_s_out);
|
||||
}
|
||||
if (s_tlsextstatus);
|
||||
{
|
||||
SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb);
|
||||
tlscstatp.err = bio_err;
|
||||
SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp);
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
|
||||
|
|
11
apps/x509.c
11
apps/x509.c
|
@ -114,6 +114,7 @@ static const char *x509_usage[]={
|
|||
" -alias - output certificate alias\n",
|
||||
" -noout - no certificate output\n",
|
||||
" -ocspid - print OCSP hash values for the subject name and public key\n",
|
||||
" -ocspurl - print OCSP Responder URL(s)\n",
|
||||
" -trustout - output a \"trusted\" certificate\n",
|
||||
" -clrtrust - clear all trusted purposes\n",
|
||||
" -clrreject - clear all rejected purposes\n",
|
||||
|
@ -179,6 +180,7 @@ int MAIN(int argc, char **argv)
|
|||
int next_serial=0;
|
||||
int subject_hash=0,issuer_hash=0,ocspid=0;
|
||||
int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
|
||||
int ocsp_uri=0;
|
||||
int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
|
||||
int C=0;
|
||||
int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
|
||||
|
@ -378,6 +380,8 @@ int MAIN(int argc, char **argv)
|
|||
C= ++num;
|
||||
else if (strcmp(*argv,"-email") == 0)
|
||||
email= ++num;
|
||||
else if (strcmp(*argv,"-ocsp_uri") == 0)
|
||||
ocsp_uri= ++num;
|
||||
else if (strcmp(*argv,"-serial") == 0)
|
||||
serial= ++num;
|
||||
else if (strcmp(*argv,"-next_serial") == 0)
|
||||
|
@ -731,11 +735,14 @@ bad:
|
|||
ASN1_INTEGER_free(ser);
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
else if (email == i)
|
||||
else if ((email == i) || (ocsp_uri == i))
|
||||
{
|
||||
int j;
|
||||
STACK *emlst;
|
||||
emlst = X509_get1_email(x);
|
||||
if (email == i)
|
||||
emlst = X509_get1_email(x);
|
||||
else
|
||||
emlst = X509_get1_ocsp(x);
|
||||
for (j = 0; j < sk_num(emlst); j++)
|
||||
BIO_printf(STDout, "%s\n", sk_value(emlst, j));
|
||||
X509_email_free(emlst);
|
||||
|
|
|
@ -67,5 +67,10 @@ ASN1_SEQUENCE(X509_EXTENSION) = {
|
|||
ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
|
||||
} ASN1_SEQUENCE_END(X509_EXTENSION)
|
||||
|
||||
ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
|
||||
ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION)
|
||||
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
|
||||
IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION)
|
||||
|
|
|
@ -187,11 +187,11 @@ typedef struct ocsp_resp_bytes_st
|
|||
* responseStatus OCSPResponseStatus,
|
||||
* responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
|
||||
*/
|
||||
typedef struct ocsp_response_st
|
||||
struct ocsp_response_st
|
||||
{
|
||||
ASN1_ENUMERATED *responseStatus;
|
||||
OCSP_RESPBYTES *responseBytes;
|
||||
} OCSP_RESPONSE;
|
||||
};
|
||||
|
||||
/* ResponderID ::= CHOICE {
|
||||
* byName [1] Name,
|
||||
|
@ -199,14 +199,18 @@ typedef struct ocsp_response_st
|
|||
*/
|
||||
#define V_OCSP_RESPID_NAME 0
|
||||
#define V_OCSP_RESPID_KEY 1
|
||||
typedef struct ocsp_responder_id_st
|
||||
struct ocsp_responder_id_st
|
||||
{
|
||||
int type;
|
||||
union {
|
||||
X509_NAME* byName;
|
||||
ASN1_OCTET_STRING *byKey;
|
||||
} value;
|
||||
} OCSP_RESPID;
|
||||
};
|
||||
|
||||
DECLARE_STACK_OF(OCSP_RESPID)
|
||||
DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
|
||||
|
||||
/* KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
|
||||
* --(excluding the tag and length fields)
|
||||
*/
|
||||
|
|
|
@ -188,5 +188,7 @@ typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d
|
|||
int idx, long argl, void *argp);
|
||||
|
||||
typedef struct ocsp_req_ctx_st OCSP_REQ_CTX;
|
||||
typedef struct ocsp_response_st OCSP_RESPONSE;
|
||||
typedef struct ocsp_responder_id_st OCSP_RESPID;
|
||||
|
||||
#endif /* def HEADER_OPENSSL_TYPES_H */
|
||||
|
|
|
@ -1074,6 +1074,28 @@ STACK_OF(type) \
|
|||
#define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
|
||||
#define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
|
||||
|
||||
#define sk_OCSP_RESPID_new(st) SKM_sk_new(OCSP_RESPID, (st))
|
||||
#define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID)
|
||||
#define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st))
|
||||
#define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st))
|
||||
#define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i))
|
||||
#define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val))
|
||||
#define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st))
|
||||
#define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val))
|
||||
#define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val))
|
||||
#define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val))
|
||||
#define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val))
|
||||
#define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i))
|
||||
#define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr))
|
||||
#define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i))
|
||||
#define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp))
|
||||
#define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st)
|
||||
#define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func))
|
||||
#define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st))
|
||||
#define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st))
|
||||
#define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st))
|
||||
#define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st))
|
||||
|
||||
#define sk_OCSP_SINGLERESP_new(st) SKM_sk_new(OCSP_SINGLERESP, (st))
|
||||
#define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
|
||||
#define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
|
||||
|
|
|
@ -205,6 +205,8 @@ typedef struct X509_extension_st
|
|||
ASN1_OCTET_STRING *value;
|
||||
} X509_EXTENSION;
|
||||
|
||||
typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
|
||||
|
||||
DECLARE_STACK_OF(X509_EXTENSION)
|
||||
DECLARE_ASN1_SET_OF(X509_EXTENSION)
|
||||
|
||||
|
@ -801,6 +803,7 @@ DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
|
|||
X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
|
||||
DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)
|
||||
|
||||
|
|
|
@ -67,10 +67,6 @@
|
|||
#include <openssl/buffer.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
|
||||
ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS)
|
||||
|
||||
X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
|
||||
{
|
||||
X509_REQ *ret;
|
||||
|
|
|
@ -473,6 +473,30 @@ STACK *X509_get1_email(X509 *x)
|
|||
return ret;
|
||||
}
|
||||
|
||||
STACK *X509_get1_ocsp(X509 *x)
|
||||
{
|
||||
AUTHORITY_INFO_ACCESS *info;
|
||||
STACK *ret = NULL;
|
||||
int i;
|
||||
info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
|
||||
if (!info)
|
||||
return NULL;
|
||||
for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++)
|
||||
{
|
||||
ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
|
||||
if (OBJ_obj2nid(ad->method) == NID_ad_OCSP)
|
||||
{
|
||||
if (ad->location->type == GEN_URI)
|
||||
{
|
||||
if (!append_ia5(&ret, ad->location->d.uniformResourceIdentifier))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
AUTHORITY_INFO_ACCESS_free(info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
STACK *X509_REQ_get1_email(X509_REQ *x)
|
||||
{
|
||||
GENERAL_NAMES *gens;
|
||||
|
|
|
@ -649,6 +649,7 @@ int X509_PURPOSE_get_id(X509_PURPOSE *);
|
|||
STACK *X509_get1_email(X509 *x);
|
||||
STACK *X509_REQ_get1_email(X509_REQ *x);
|
||||
void X509_email_free(STACK *sk);
|
||||
STACK *X509_get1_ocsp(X509 *x);
|
||||
|
||||
ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
|
||||
ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
|
||||
|
|
|
@ -283,6 +283,8 @@ static int ssl23_client_hello(SSL *s)
|
|||
|
||||
if (s->tlsext_hostname != NULL)
|
||||
ssl2_compat = 0;
|
||||
if (s->tlsext_status_type != -1)
|
||||
ssl2_compat = 0;
|
||||
|
||||
#ifdef TLSEXT_TYPE_opaque_prf_input
|
||||
if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL)
|
||||
|
|
|
@ -307,10 +307,23 @@ int ssl3_connect(SSL *s)
|
|||
{
|
||||
ret=ssl3_get_server_certificate(s);
|
||||
if (ret <= 0) goto end;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s->tlsext_status_expected)
|
||||
s->state=SSL3_ST_CR_CERT_STATUS_A;
|
||||
else
|
||||
s->state=SSL3_ST_CR_KEY_EXCH_A;
|
||||
}
|
||||
else
|
||||
{
|
||||
skip = 1;
|
||||
s->state=SSL3_ST_CR_KEY_EXCH_A;
|
||||
}
|
||||
#else
|
||||
else
|
||||
skip=1;
|
||||
|
||||
s->state=SSL3_ST_CR_KEY_EXCH_A;
|
||||
#endif
|
||||
s->init_num=0;
|
||||
break;
|
||||
|
||||
|
@ -473,6 +486,14 @@ int ssl3_connect(SSL *s)
|
|||
s->state=SSL3_ST_CR_FINISHED_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
|
||||
case SSL3_ST_CR_CERT_STATUS_A:
|
||||
case SSL3_ST_CR_CERT_STATUS_B:
|
||||
ret=ssl3_get_cert_status(s);
|
||||
if (ret <= 0) goto end;
|
||||
s->state=SSL3_ST_CR_KEY_EXCH_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SSL3_ST_CR_FINISHED_A:
|
||||
|
@ -1795,6 +1816,75 @@ f_err:
|
|||
err:
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int ssl3_get_cert_status(SSL *s)
|
||||
{
|
||||
int ok, al;
|
||||
unsigned long resplen;
|
||||
long n;
|
||||
const unsigned char *p;
|
||||
|
||||
n=s->method->ssl_get_message(s,
|
||||
SSL3_ST_CR_CERT_STATUS_A,
|
||||
SSL3_ST_CR_CERT_STATUS_B,
|
||||
SSL3_MT_CERTIFICATE_STATUS,
|
||||
16384,
|
||||
&ok);
|
||||
|
||||
if (!ok) return((int)n);
|
||||
if (n < 4)
|
||||
{
|
||||
/* need at least status type + length */
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_LENGTH_MISMATCH);
|
||||
goto f_err;
|
||||
}
|
||||
p = (unsigned char *)s->init_msg;
|
||||
if (*p++ != TLSEXT_STATUSTYPE_ocsp)
|
||||
{
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_UNSUPPORTED_STATUS_TYPE);
|
||||
goto f_err;
|
||||
}
|
||||
n2l3(p, resplen);
|
||||
if (resplen + 4 != n)
|
||||
{
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_LENGTH_MISMATCH);
|
||||
goto f_err;
|
||||
}
|
||||
if (s->tlsext_ocsp_resp)
|
||||
OPENSSL_free(s->tlsext_ocsp_resp);
|
||||
s->tlsext_ocsp_resp = BUF_memdup(p, resplen);
|
||||
if (!s->tlsext_ocsp_resp)
|
||||
{
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_STATUS,ERR_R_MALLOC_FAILURE);
|
||||
goto f_err;
|
||||
}
|
||||
s->tlsext_ocsp_resplen = resplen;
|
||||
if (s->ctx->tlsext_status_cb)
|
||||
{
|
||||
int ret;
|
||||
ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
|
||||
if (ret == 0)
|
||||
{
|
||||
al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_INVALID_STATUS_RESPONSE);
|
||||
goto f_err;
|
||||
}
|
||||
if (ret < 0)
|
||||
{
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_STATUS,ERR_R_MALLOC_FAILURE);
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
f_err:
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,al);
|
||||
return(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
int ssl3_get_server_done(SSL *s)
|
||||
|
|
46
ssl/s3_lib.c
46
ssl/s3_lib.c
|
@ -2383,6 +2383,43 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
|||
break;
|
||||
#endif
|
||||
|
||||
case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE:
|
||||
s->tlsext_status_type=larg;
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS:
|
||||
*(STACK_OF(X509_EXTENSION) **)parg = s->tlsext_ocsp_exts;
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS:
|
||||
s->tlsext_ocsp_exts = parg;
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS:
|
||||
*(STACK_OF(OCSP_RESPID) **)parg = s->tlsext_ocsp_ids;
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS:
|
||||
s->tlsext_ocsp_ids = parg;
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP:
|
||||
*(unsigned char **)parg = s->tlsext_ocsp_resp;
|
||||
return s->tlsext_ocsp_resplen;
|
||||
|
||||
case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP:
|
||||
if (s->tlsext_ocsp_resp)
|
||||
OPENSSL_free(s->tlsext_ocsp_resp);
|
||||
s->tlsext_ocsp_resp = parg;
|
||||
s->tlsext_ocsp_resplen = larg;
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
#endif /* !OPENSSL_NO_TLSEXT */
|
||||
default:
|
||||
break;
|
||||
|
@ -2610,6 +2647,11 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
|
|||
return 1;
|
||||
#endif
|
||||
|
||||
case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG:
|
||||
ctx->tlsext_status_arg=parg;
|
||||
return 1;
|
||||
break;
|
||||
|
||||
#endif /* !OPENSSL_NO_TLSEXT */
|
||||
|
||||
/* A Thawte special :-) */
|
||||
|
@ -2668,6 +2710,10 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
|
|||
break;
|
||||
#endif
|
||||
|
||||
case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB:
|
||||
ctx->tlsext_status_cb=(int (*)(SSL *,void *))fp;
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
return(0);
|
||||
|
|
|
@ -332,10 +332,23 @@ int ssl3_accept(SSL *s)
|
|||
{
|
||||
ret=ssl3_send_server_certificate(s);
|
||||
if (ret <= 0) goto end;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s->tlsext_status_expected)
|
||||
s->state=SSL3_ST_SW_CERT_STATUS_A;
|
||||
else
|
||||
s->state=SSL3_ST_SW_KEY_EXCH_A;
|
||||
}
|
||||
else
|
||||
{
|
||||
skip = 1;
|
||||
s->state=SSL3_ST_SW_KEY_EXCH_A;
|
||||
}
|
||||
#else
|
||||
else
|
||||
skip=1;
|
||||
|
||||
s->state=SSL3_ST_SW_KEY_EXCH_A;
|
||||
#endif
|
||||
s->init_num=0;
|
||||
break;
|
||||
|
||||
|
@ -551,6 +564,14 @@ int ssl3_accept(SSL *s)
|
|||
s->init_num=0;
|
||||
break;
|
||||
|
||||
case SSL3_ST_SW_CERT_STATUS_A:
|
||||
case SSL3_ST_SW_CERT_STATUS_B:
|
||||
ret=ssl3_send_cert_status(s);
|
||||
if (ret <= 0) goto end;
|
||||
s->state=SSL3_ST_SW_KEY_EXCH_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
case SSL3_ST_SW_CHANGE_A:
|
||||
|
@ -2823,4 +2844,39 @@ int ssl3_send_newsession_ticket(SSL *s)
|
|||
/* SSL3_ST_SW_SESSION_TICKET_B */
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
}
|
||||
|
||||
int ssl3_send_cert_status(SSL *s)
|
||||
{
|
||||
if (s->state == SSL3_ST_SW_CERT_STATUS_A)
|
||||
{
|
||||
unsigned char *p;
|
||||
/* Grow buffer if need be: the length calculation is as
|
||||
* follows 1 (message type) + 3 (message length) +
|
||||
* 1 (ocsp response type) + 3 (ocsp response length)
|
||||
* + (ocsp response)
|
||||
*/
|
||||
if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen))
|
||||
return -1;
|
||||
|
||||
p=(unsigned char *)s->init_buf->data;
|
||||
|
||||
/* do the header */
|
||||
*(p++)=SSL3_MT_CERTIFICATE_STATUS;
|
||||
/* message length */
|
||||
l2n3(s->tlsext_ocsp_resplen + 4, p);
|
||||
/* status type */
|
||||
*(p++)= s->tlsext_status_type;
|
||||
/* length of OCSP response */
|
||||
l2n3(s->tlsext_ocsp_resplen, p);
|
||||
/* actual response */
|
||||
memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen);
|
||||
/* number of bytes to write */
|
||||
s->init_num = 8 + s->tlsext_ocsp_resplen;
|
||||
s->state=SSL3_ST_SW_CERT_STATUS_B;
|
||||
s->init_off = 0;
|
||||
}
|
||||
|
||||
/* SSL3_ST_SW_CERT_STATUS_B */
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
}
|
||||
#endif
|
||||
|
|
29
ssl/ssl.h
29
ssl/ssl.h
|
@ -800,6 +800,11 @@ struct ssl_ctx_st
|
|||
unsigned char tlsext_tick_hmac_key[16];
|
||||
unsigned char tlsext_tick_aes_key[16];
|
||||
|
||||
/* certificate status request info */
|
||||
/* Callback for status request */
|
||||
int (*tlsext_status_cb)(SSL *ssl, void *arg);
|
||||
void *tlsext_status_arg;
|
||||
|
||||
/* draft-rescorla-tls-opaque-prf-input-00.txt information */
|
||||
int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg);
|
||||
void *tlsext_opaque_prf_input_callback_arg;
|
||||
|
@ -1083,6 +1088,18 @@ struct ssl_st
|
|||
1 : prepare 2, allow last ack just after in server callback.
|
||||
2 : don't call servername callback, no ack in server hello
|
||||
*/
|
||||
/* certificate status request info */
|
||||
/* Status type or -1 if no status type */
|
||||
int tlsext_status_type;
|
||||
/* Expect OCSP CertificateStatus message */
|
||||
int tlsext_status_expected;
|
||||
/* OCSP status request only */
|
||||
STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids;
|
||||
X509_EXTENSIONS *tlsext_ocsp_exts;
|
||||
/* OCSP response received or to be sent */
|
||||
unsigned char *tlsext_ocsp_resp;
|
||||
int tlsext_ocsp_resplen;
|
||||
|
||||
/* RFC4507 session ticket expected to be received or sent */
|
||||
int tlsext_ticket_expected;
|
||||
#ifndef OPENSSL_NO_EC
|
||||
|
@ -1317,6 +1334,15 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
|||
#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT 60
|
||||
#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61
|
||||
#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62
|
||||
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63
|
||||
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64
|
||||
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65
|
||||
#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66
|
||||
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67
|
||||
#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68
|
||||
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69
|
||||
#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70
|
||||
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71
|
||||
#endif
|
||||
|
||||
#define SSL_session_reused(ssl) \
|
||||
|
@ -1766,6 +1792,7 @@ void ERR_load_SSL_strings(void);
|
|||
#define SSL_F_SSL3_ENC 134
|
||||
#define SSL_F_SSL3_GENERATE_KEY_BLOCK 238
|
||||
#define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135
|
||||
#define SSL_F_SSL3_GET_CERT_STATUS 288
|
||||
#define SSL_F_SSL3_GET_CERT_VERIFY 136
|
||||
#define SSL_F_SSL3_GET_CLIENT_CERTIFICATE 137
|
||||
#define SSL_F_SSL3_GET_CLIENT_HELLO 138
|
||||
|
@ -1964,6 +1991,7 @@ void ERR_load_SSL_strings(void);
|
|||
#define SSL_R_INVALID_CHALLENGE_LENGTH 158
|
||||
#define SSL_R_INVALID_COMMAND 280
|
||||
#define SSL_R_INVALID_PURPOSE 278
|
||||
#define SSL_R_INVALID_STATUS_RESPONSE 328
|
||||
#define SSL_R_INVALID_TICKET_KEYS_LENGTH 325
|
||||
#define SSL_R_INVALID_TRUST 279
|
||||
#define SSL_R_KEY_ARG_TOO_LONG 284
|
||||
|
@ -2132,6 +2160,7 @@ void ERR_load_SSL_strings(void);
|
|||
#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315
|
||||
#define SSL_R_UNSUPPORTED_PROTOCOL 258
|
||||
#define SSL_R_UNSUPPORTED_SSL_VERSION 259
|
||||
#define SSL_R_UNSUPPORTED_STATUS_TYPE 329
|
||||
#define SSL_R_WRITE_BIO_NOT_SET 260
|
||||
#define SSL_R_WRONG_CIPHER_RETURNED 261
|
||||
#define SSL_R_WRONG_MESSAGE_TYPE 262
|
||||
|
|
|
@ -545,6 +545,8 @@ typedef struct ssl3_state_st
|
|||
#define SSL3_ST_CR_FINISHED_B (0x1D1|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_SESSION_TICKET_A (0x1E0|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_SESSION_TICKET_B (0x1E1|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_CERT_STATUS_A (0x1F0|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_CERT_STATUS_B (0x1F1|SSL_ST_CONNECT)
|
||||
|
||||
/* server */
|
||||
/* extra state */
|
||||
|
@ -588,6 +590,8 @@ typedef struct ssl3_state_st
|
|||
#define SSL3_ST_SW_FINISHED_B (0x1E1|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SW_SESSION_TICKET_A (0x1F0|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_B (0x201|SSL_ST_ACCEPT)
|
||||
|
||||
#define SSL3_MT_HELLO_REQUEST 0
|
||||
#define SSL3_MT_CLIENT_HELLO 1
|
||||
|
@ -600,6 +604,7 @@ typedef struct ssl3_state_st
|
|||
#define SSL3_MT_CERTIFICATE_VERIFY 15
|
||||
#define SSL3_MT_CLIENT_KEY_EXCHANGE 16
|
||||
#define SSL3_MT_FINISHED 20
|
||||
#define SSL3_MT_CERTIFICATE_STATUS 22
|
||||
#define DTLS1_MT_HELLO_VERIFY_REQUEST 3
|
||||
|
||||
|
||||
|
|
|
@ -140,6 +140,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
|||
{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"},
|
||||
|
@ -341,6 +342,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
|||
{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"},
|
||||
|
@ -509,6 +511,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
|||
{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"},
|
||||
|
|
|
@ -152,6 +152,7 @@
|
|||
#include <openssl/lhash.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/ocsp.h>
|
||||
#ifndef OPENSSL_NO_DH
|
||||
#include <openssl/dh.h>
|
||||
#endif
|
||||
|
@ -340,6 +341,12 @@ SSL *SSL_new(SSL_CTX *ctx)
|
|||
s->tlsext_debug_cb = 0;
|
||||
s->tlsext_debug_arg = NULL;
|
||||
s->tlsext_ticket_expected = 0;
|
||||
s->tlsext_status_type = -1;
|
||||
s->tlsext_status_expected = 0;
|
||||
s->tlsext_ocsp_ids = NULL;
|
||||
s->tlsext_ocsp_exts = NULL;
|
||||
s->tlsext_ocsp_resp = NULL;
|
||||
s->tlsext_ocsp_resplen = -1;
|
||||
CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
|
||||
s->initial_ctx=ctx;
|
||||
#endif
|
||||
|
@ -543,6 +550,13 @@ void SSL_free(SSL *s)
|
|||
if (s->tlsext_ellipticcurvelist) OPENSSL_free(s->tlsext_ellipticcurvelist);
|
||||
#endif /* OPENSSL_NO_EC */
|
||||
if (s->tlsext_opaque_prf_input) OPENSSL_free(s->tlsext_opaque_prf_input);
|
||||
if (s->tlsext_ocsp_exts)
|
||||
sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
|
||||
X509_EXTENSION_free);
|
||||
if (s->tlsext_ocsp_ids)
|
||||
sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
|
||||
if (s->tlsext_ocsp_resp)
|
||||
OPENSSL_free(s->tlsext_ocsp_resp);
|
||||
#endif
|
||||
|
||||
if (s->client_CA != NULL)
|
||||
|
@ -1556,6 +1570,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
|
|||
|| (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0))
|
||||
ret->options |= SSL_OP_NO_TICKET;
|
||||
|
||||
ret->tlsext_status_cb = 0;
|
||||
ret->tlsext_status_arg = NULL;
|
||||
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
ret->psk_identity_hint=NULL;
|
||||
|
|
|
@ -829,6 +829,7 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p);
|
|||
void ssl3_init_finished_mac(SSL *s);
|
||||
int ssl3_send_server_certificate(SSL *s);
|
||||
int ssl3_send_newsession_ticket(SSL *s);
|
||||
int ssl3_send_cert_status(SSL *s);
|
||||
int ssl3_get_finished(SSL *s,int state_a,int state_b);
|
||||
int ssl3_setup_key_block(SSL *s);
|
||||
int ssl3_send_change_cipher_spec(SSL *s,int state_a,int state_b);
|
||||
|
@ -921,6 +922,7 @@ int ssl3_client_hello(SSL *s);
|
|||
int ssl3_get_server_hello(SSL *s);
|
||||
int ssl3_get_certificate_request(SSL *s);
|
||||
int ssl3_get_new_session_ticket(SSL *s);
|
||||
int ssl3_get_cert_status(SSL *s);
|
||||
int ssl3_get_server_done(SSL *s);
|
||||
int ssl3_send_client_verify(SSL *s);
|
||||
int ssl3_send_client_certificate(SSL *s);
|
||||
|
|
|
@ -899,7 +899,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
|
|||
{
|
||||
unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
|
||||
const void *co = NULL, *so = NULL;
|
||||
int col = 0, sol = NULL;
|
||||
int col = 0, sol = 0;
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
|
||||
|
|
233
ssl/t1_lib.c
233
ssl/t1_lib.c
|
@ -113,6 +113,7 @@
|
|||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/ocsp.h>
|
||||
#include "ssl_locl.h"
|
||||
|
||||
const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
|
||||
|
@ -387,6 +388,54 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
|||
}
|
||||
#endif
|
||||
|
||||
if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
|
||||
{
|
||||
int i;
|
||||
long extlen, idlen, itmp;
|
||||
OCSP_RESPID *id;
|
||||
|
||||
idlen = 0;
|
||||
for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
|
||||
{
|
||||
id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
|
||||
itmp = i2d_OCSP_RESPID(id, NULL);
|
||||
if (itmp <= 0)
|
||||
return NULL;
|
||||
idlen += itmp + 2;
|
||||
}
|
||||
|
||||
if (s->tlsext_ocsp_exts)
|
||||
{
|
||||
extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
|
||||
if (extlen < 0)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
extlen = 0;
|
||||
|
||||
if ((long)(limit - ret - 7 - extlen - idlen) < 0) return NULL;
|
||||
s2n(TLSEXT_TYPE_status_request, ret);
|
||||
if (extlen + idlen > 0xFFF0)
|
||||
return NULL;
|
||||
s2n(extlen + idlen + 5, ret);
|
||||
*(ret++) = TLSEXT_STATUSTYPE_ocsp;
|
||||
s2n(idlen, ret);
|
||||
for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
|
||||
{
|
||||
/* save position of id len */
|
||||
unsigned char *q = ret;
|
||||
id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
|
||||
/* skip over id len */
|
||||
ret += 2;
|
||||
itmp = i2d_OCSP_RESPID(id, &ret);
|
||||
/* write id len */
|
||||
s2n(itmp, q);
|
||||
}
|
||||
s2n(extlen, ret);
|
||||
if (extlen > 0)
|
||||
i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
|
||||
}
|
||||
|
||||
if ((extdatalen = ret-p-2)== 0)
|
||||
return p;
|
||||
|
||||
|
@ -432,7 +481,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
|||
}
|
||||
/* Currently the server should not respond with a SupportedCurves extension */
|
||||
#endif /* OPENSSL_NO_EC */
|
||||
|
||||
|
||||
if (s->tlsext_ticket_expected
|
||||
&& !(SSL_get_options(s) & SSL_OP_NO_TICKET))
|
||||
{
|
||||
|
@ -441,6 +490,13 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
|||
s2n(0,ret);
|
||||
}
|
||||
|
||||
if (s->tlsext_status_expected)
|
||||
{
|
||||
if ((long)(limit - ret - 4) < 0) return NULL;
|
||||
s2n(TLSEXT_TYPE_status_request,ret);
|
||||
s2n(0,ret);
|
||||
}
|
||||
|
||||
#ifdef TLSEXT_TYPE_opaque_prf_input
|
||||
if (s->s3->server_opaque_prf_input != NULL)
|
||||
{
|
||||
|
@ -473,6 +529,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
|||
unsigned short len;
|
||||
unsigned char *data = *p;
|
||||
s->servername_done = 0;
|
||||
s->tlsext_status_type = -1;
|
||||
|
||||
if (data >= (d+n-2))
|
||||
return 1;
|
||||
|
@ -675,6 +732,106 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
|||
}
|
||||
}
|
||||
#endif
|
||||
else if (type == TLSEXT_TYPE_status_request
|
||||
&& s->ctx->tlsext_status_cb)
|
||||
{
|
||||
|
||||
if (size < 5)
|
||||
{
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s->tlsext_status_type = *data++;
|
||||
size--;
|
||||
if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
|
||||
{
|
||||
const unsigned char *sdata;
|
||||
int dsize;
|
||||
/* Read in responder_id_list */
|
||||
n2s(data,dsize);
|
||||
size -= 2;
|
||||
if (dsize > size )
|
||||
{
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
while (dsize > 0)
|
||||
{
|
||||
OCSP_RESPID *id;
|
||||
int idsize;
|
||||
if (dsize < 4)
|
||||
{
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
n2s(data, idsize);
|
||||
dsize -= 2 + idsize;
|
||||
if (dsize < 0)
|
||||
{
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
sdata = data;
|
||||
data += idsize;
|
||||
id = d2i_OCSP_RESPID(NULL,
|
||||
&sdata, idsize);
|
||||
if (!id)
|
||||
{
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
if (data != sdata)
|
||||
{
|
||||
OCSP_RESPID_free(id);
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
if (!s->tlsext_ocsp_ids
|
||||
&& !(s->tlsext_ocsp_ids =
|
||||
sk_OCSP_RESPID_new_null()))
|
||||
{
|
||||
OCSP_RESPID_free(id);
|
||||
*al = SSL_AD_INTERNAL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
if (!sk_OCSP_RESPID_push(
|
||||
s->tlsext_ocsp_ids, id))
|
||||
{
|
||||
OCSP_RESPID_free(id);
|
||||
*al = SSL_AD_INTERNAL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read in request_extensions */
|
||||
n2s(data,dsize);
|
||||
size -= 2;
|
||||
if (dsize > size)
|
||||
{
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
sdata = data;
|
||||
if (dsize > 0)
|
||||
{
|
||||
s->tlsext_ocsp_exts =
|
||||
d2i_X509_EXTENSIONS(NULL,
|
||||
&sdata, dsize);
|
||||
if (!s->tlsext_ocsp_exts
|
||||
|| (data + dsize != sdata))
|
||||
{
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* We don't know what to do with any other type
|
||||
* so ignore it.
|
||||
*/
|
||||
else
|
||||
s->tlsext_status_type = -1;
|
||||
}
|
||||
|
||||
/* session ticket processed earlier */
|
||||
data+=size;
|
||||
|
@ -791,6 +948,19 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
|||
}
|
||||
}
|
||||
#endif
|
||||
else if (type == TLSEXT_TYPE_status_request)
|
||||
{
|
||||
/* MUST be empty and only sent if we've requested
|
||||
* a status request message.
|
||||
*/
|
||||
if ((s->tlsext_status_type == -1) || (size > 0))
|
||||
{
|
||||
*al = TLS1_AD_UNSUPPORTED_EXTENSION;
|
||||
return 0;
|
||||
}
|
||||
/* Set flag to expect CertificateStatus message */
|
||||
s->tlsext_status_expected = 1;
|
||||
}
|
||||
|
||||
data+=size;
|
||||
}
|
||||
|
@ -822,6 +992,35 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
|||
}
|
||||
}
|
||||
|
||||
/* If we've requested certificate status and we wont get one
|
||||
* tell the callback
|
||||
*/
|
||||
if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
|
||||
&& s->ctx->tlsext_status_cb)
|
||||
{
|
||||
int r;
|
||||
/* Set resp to NULL, resplen to -1 so callback knows
|
||||
* there is no response.
|
||||
*/
|
||||
if (s->tlsext_ocsp_resp)
|
||||
{
|
||||
OPENSSL_free(s->tlsext_ocsp_resp);
|
||||
s->tlsext_ocsp_resp = NULL;
|
||||
}
|
||||
s->tlsext_ocsp_resplen = -1;
|
||||
r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
|
||||
if (r == 0)
|
||||
{
|
||||
*al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
{
|
||||
*al = SSL_AD_INTERNAL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
*p = data;
|
||||
return 1;
|
||||
}
|
||||
|
@ -966,6 +1165,36 @@ int ssl_check_clienthello_tlsext(SSL *s)
|
|||
else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0)
|
||||
ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
|
||||
|
||||
/* If status request then ask callback what to do.
|
||||
* Note: this must be called after servername callbacks in case
|
||||
* the certificate has changed.
|
||||
*/
|
||||
if ((s->tlsext_status_type != -1) && s->ctx->tlsext_status_cb)
|
||||
{
|
||||
int r;
|
||||
r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
|
||||
switch (r)
|
||||
{
|
||||
/* We don't want to send a status request response */
|
||||
case SSL_TLSEXT_ERR_NOACK:
|
||||
s->tlsext_status_expected = 0;
|
||||
break;
|
||||
/* status request response should be sent */
|
||||
case SSL_TLSEXT_ERR_OK:
|
||||
if (s->tlsext_ocsp_resp)
|
||||
s->tlsext_status_expected = 1;
|
||||
else
|
||||
s->tlsext_status_expected = 0;
|
||||
break;
|
||||
/* something bad happened */
|
||||
case SSL_TLSEXT_ERR_ALERT_FATAL:
|
||||
ret = SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
s->tlsext_status_expected = 0;
|
||||
|
||||
#ifdef TLSEXT_TYPE_opaque_prf_input
|
||||
{
|
||||
|
@ -1022,8 +1251,8 @@ int ssl_check_clienthello_tlsext(SSL *s)
|
|||
al = SSL_AD_HANDSHAKE_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
err:
|
||||
switch (ret)
|
||||
{
|
||||
|
|
35
ssl/tls1.h
35
ssl/tls1.h
|
@ -203,6 +203,8 @@ extern "C" {
|
|||
|
||||
/* NameType value from RFC 3546 */
|
||||
#define TLSEXT_NAMETYPE_host_name 0
|
||||
/* status request value from RFC 3546 */
|
||||
#define TLSEXT_STATUSTYPE_ocsp 1
|
||||
|
||||
/* ECPointFormat values from draft-ietf-tls-ecc-12 */
|
||||
#define TLSEXT_ECPOINTFORMAT_first 0
|
||||
|
@ -227,12 +229,33 @@ SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb)
|
|||
#define SSL_set_tlsext_debug_arg(ssl, arg) \
|
||||
SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg)
|
||||
|
||||
#define SSL_set_tlsext_status_type(ssl, type) \
|
||||
SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL)
|
||||
|
||||
#define SSL_get_tlsext_status_exts(ssl, arg) \
|
||||
SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)
|
||||
|
||||
#define SSL_set_tlsext_status_exts(ssl, arg) \
|
||||
SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)
|
||||
|
||||
#define SSL_get_tlsext_status_ids(ssl, arg) \
|
||||
SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)
|
||||
|
||||
#define SSL_set_tlsext_status_ids(ssl, arg) \
|
||||
SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)
|
||||
|
||||
#define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \
|
||||
SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg)
|
||||
|
||||
#define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \
|
||||
SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg)
|
||||
|
||||
#define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
|
||||
SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb)
|
||||
|
||||
#define SSL_TLSEXT_ERR_OK 0
|
||||
#define SSL_TLSEXT_ERR_ALERT_WARNING 1
|
||||
#define SSL_TLSEXT_ERR_ALERT_FATAL 2
|
||||
#define SSL_TLSEXT_ERR_OK 0
|
||||
#define SSL_TLSEXT_ERR_ALERT_WARNING 1
|
||||
#define SSL_TLSEXT_ERR_ALERT_FATAL 2
|
||||
#define SSL_TLSEXT_ERR_NOACK 3
|
||||
|
||||
#define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \
|
||||
|
@ -243,6 +266,12 @@ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg)
|
|||
#define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \
|
||||
SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLXEXT_TICKET_KEYS,(keylen),(keys))
|
||||
|
||||
#define SSL_CTX_set_tlsext_status_cb(ssl, cb) \
|
||||
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb)
|
||||
|
||||
#define SSL_CTX_set_tlsext_status_arg(ssl, arg) \
|
||||
SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg)
|
||||
|
||||
#define SSL_set_tlsext_opaque_prf_input(s, src, len) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src)
|
||||
#define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \
|
||||
|
|
Loading…
Reference in a new issue