提交 3dbc46df 编写于 作者: D Dr. Stephen Henson

Separate client and server permitted signature algorithm support: by default

the permitted signature algorithms for server and client authentication
are the same but it is now possible to set different algorithms for client
authentication only.
上级 32e03a30
...@@ -4,6 +4,9 @@ ...@@ -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]
*) Support for distinct client and server supported signature algorithms.
[Steve Henson]
*) Add certificate callback. If set this is called whenever a certificate *) Add certificate callback. If set this is called whenever a certificate
is required by client or server. An application can decide which is required by client or server. An application can decide which
certificate chain to present based on arbitrary criteria: for example certificate chain to present based on arbitrary criteria: for example
......
...@@ -607,6 +607,7 @@ int MAIN(int argc, char **argv) ...@@ -607,6 +607,7 @@ int MAIN(int argc, char **argv)
char *servername = NULL; char *servername = NULL;
char *curves=NULL; char *curves=NULL;
char *sigalgs=NULL; char *sigalgs=NULL;
char *client_sigalgs=NULL;
tlsextctx tlsextcbp = tlsextctx tlsextcbp =
{NULL,0}; {NULL,0};
# ifndef OPENSSL_NO_NEXTPROTONEG # ifndef OPENSSL_NO_NEXTPROTONEG
...@@ -964,6 +965,11 @@ int MAIN(int argc, char **argv) ...@@ -964,6 +965,11 @@ int MAIN(int argc, char **argv)
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
sigalgs= *(++argv); sigalgs= *(++argv);
} }
else if (strcmp(*argv,"-client_sigalgs") == 0)
{
if (--argc < 1) goto bad;
client_sigalgs= *(++argv);
}
#endif #endif
#ifndef OPENSSL_NO_JPAKE #ifndef OPENSSL_NO_JPAKE
else if (strcmp(*argv,"-jpake") == 0) else if (strcmp(*argv,"-jpake") == 0)
...@@ -1215,6 +1221,12 @@ bad: ...@@ -1215,6 +1221,12 @@ bad:
ERR_print_errors(bio_err); ERR_print_errors(bio_err);
goto end; goto end;
} }
if (client_sigalgs != NULL)
if(!SSL_CTX_set1_client_sigalgs_list(ctx,client_sigalgs)) {
BIO_printf(bio_err,"error setting client signature algorithms list\n");
ERR_print_errors(bio_err);
goto end;
}
if (servername != NULL) if (servername != NULL)
{ {
tlsextcbp.biodebug = bio_err; tlsextcbp.biodebug = bio_err;
......
...@@ -275,6 +275,7 @@ static const char *s_cert_file=TEST_CERT,*s_key_file=NULL, *s_chain_file=NULL; ...@@ -275,6 +275,7 @@ static const char *s_cert_file=TEST_CERT,*s_key_file=NULL, *s_chain_file=NULL;
static const char *s_cert_file2=TEST_CERT2,*s_key_file2=NULL; static const char *s_cert_file2=TEST_CERT2,*s_key_file2=NULL;
static char *curves=NULL; static char *curves=NULL;
static char *sigalgs=NULL; static char *sigalgs=NULL;
static char *client_sigalgs=NULL;
#endif #endif
static char *s_dcert_file=NULL,*s_dkey_file=NULL, *s_dchain_file=NULL; static char *s_dcert_file=NULL,*s_dkey_file=NULL, *s_dchain_file=NULL;
#ifdef FIONBIO #ifdef FIONBIO
...@@ -1219,6 +1220,11 @@ int MAIN(int argc, char *argv[]) ...@@ -1219,6 +1220,11 @@ int MAIN(int argc, char *argv[])
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
sigalgs= *(++argv); sigalgs= *(++argv);
} }
else if (strcmp(*argv,"-client_sigalgs") == 0)
{
if (--argc < 1) goto bad;
client_sigalgs= *(++argv);
}
#endif #endif
else if (strcmp(*argv,"-msg") == 0) else if (strcmp(*argv,"-msg") == 0)
{ s_msg=1; } { s_msg=1; }
...@@ -1963,6 +1969,21 @@ bad: ...@@ -1963,6 +1969,21 @@ bad:
goto end; goto end;
} }
} }
if (client_sigalgs)
{
if(!SSL_CTX_set1_client_sigalgs_list(ctx,client_sigalgs))
{
BIO_printf(bio_err,"error setting client signature algorithms\n");
ERR_print_errors(bio_err);
goto end;
}
if(ctx2 && !SSL_CTX_set1_client_sigalgs_list(ctx2,client_sigalgs))
{
BIO_printf(bio_err,"error setting client signature algorithms\n");
ERR_print_errors(bio_err);
goto end;
}
}
#endif #endif
SSL_CTX_set_verify(ctx,s_server_verify,verify_callback); SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context, SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
......
...@@ -3415,10 +3415,16 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) ...@@ -3415,10 +3415,16 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
break; break;
case SSL_CTRL_SET_SIGALGS: case SSL_CTRL_SET_SIGALGS:
return tls1_set_sigalgs(s->cert, parg, larg); return tls1_set_sigalgs(s->cert, parg, larg, 0);
case SSL_CTRL_SET_SIGALGS_LIST: case SSL_CTRL_SET_SIGALGS_LIST:
return tls1_set_sigalgs_list(s->cert, parg); return tls1_set_sigalgs_list(s->cert, parg, 0);
case SSL_CTRL_SET_CLIENT_SIGALGS:
return tls1_set_sigalgs(s->cert, parg, larg, 1);
case SSL_CTRL_SET_CLIENT_SIGALGS_LIST:
return tls1_set_sigalgs_list(s->cert, parg, 1);
default: default:
break; break;
...@@ -3703,10 +3709,16 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) ...@@ -3703,10 +3709,16 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
break; break;
case SSL_CTRL_SET_SIGALGS: case SSL_CTRL_SET_SIGALGS:
return tls1_set_sigalgs(ctx->cert, parg, larg); return tls1_set_sigalgs(ctx->cert, parg, larg, 0);
case SSL_CTRL_SET_SIGALGS_LIST: case SSL_CTRL_SET_SIGALGS_LIST:
return tls1_set_sigalgs_list(ctx->cert, parg); return tls1_set_sigalgs_list(ctx->cert, parg, 0);
case SSL_CTRL_SET_CLIENT_SIGALGS:
return tls1_set_sigalgs(ctx->cert, parg, larg, 1);
case SSL_CTRL_SET_CLIENT_SIGALGS_LIST:
return tls1_set_sigalgs_list(ctx->cert, parg, 1);
case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG: case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG:
ctx->tlsext_authz_server_audit_proof_cb_arg = parg; ctx->tlsext_authz_server_audit_proof_cb_arg = parg;
......
...@@ -1662,6 +1662,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) ...@@ -1662,6 +1662,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_SET_SIGALGS_LIST 98 #define SSL_CTRL_SET_SIGALGS_LIST 98
#define SSL_CTRL_CERT_FLAGS 99 #define SSL_CTRL_CERT_FLAGS 99
#define SSL_CTRL_CLEAR_CERT_FLAGS 100 #define SSL_CTRL_CLEAR_CERT_FLAGS 100
#define SSL_CTRL_SET_CLIENT_SIGALGS 101
#define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102
#define DTLSv1_get_timeout(ssl, arg) \ #define DTLSv1_get_timeout(ssl, arg) \
SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
...@@ -1747,6 +1749,15 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) ...@@ -1747,6 +1749,15 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_set1_sigalgs_list(ctx, s) \ #define SSL_set1_sigalgs_list(ctx, s) \
SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s) SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s)
#define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)slist)
#define SSL_CTX_set1_client_sigalgs_list(ctx, s) \
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s)
#define SSL_set1_client_sigalgs(ctx, slist, slistlen) \
SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,clistlen,(int *)slist)
#define SSL_set1_client_sigalgs_list(ctx, s) \
SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s)
#ifndef OPENSSL_NO_BIO #ifndef OPENSSL_NO_BIO
BIO_METHOD *BIO_f_ssl(void); BIO_METHOD *BIO_f_ssl(void);
BIO *BIO_new_ssl(SSL_CTX *ctx,int client); BIO *BIO_new_ssl(SSL_CTX *ctx,int client);
......
...@@ -361,19 +361,31 @@ CERT *ssl_cert_dup(CERT *cert) ...@@ -361,19 +361,31 @@ CERT *ssl_cert_dup(CERT *cert)
/* Peer sigalgs set to NULL as we get these from handshake too */ /* Peer sigalgs set to NULL as we get these from handshake too */
ret->peer_sigalgs = NULL; ret->peer_sigalgs = NULL;
ret->peer_sigalgslen = 0; ret->peer_sigalgslen = 0;
/* Configure sigalgs however we copy across */ /* Configured sigalgs however we copy across */
if (cert->conf_sigalgs) if (cert->conf_sigalgs)
{ {
ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen);
* sizeof(TLS_SIGALGS));
if (!ret->conf_sigalgs) if (!ret->conf_sigalgs)
goto err; goto err;
memcpy(ret->conf_sigalgs, cert->conf_sigalgs, memcpy(ret->conf_sigalgs, cert->conf_sigalgs,
cert->conf_sigalgslen * sizeof(TLS_SIGALGS)); cert->conf_sigalgslen);
ret->conf_sigalgslen = cert->conf_sigalgslen; ret->conf_sigalgslen = cert->conf_sigalgslen;
} }
else else
ret->conf_sigalgs = NULL; ret->conf_sigalgs = NULL;
if (cert->client_sigalgs)
{
ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen);
if (!ret->client_sigalgs)
goto err;
memcpy(ret->client_sigalgs, cert->client_sigalgs,
cert->client_sigalgslen);
ret->client_sigalgslen = cert->client_sigalgslen;
}
else
ret->client_sigalgs = NULL;
/* Shared sigalgs also NULL */ /* Shared sigalgs also NULL */
ret->shared_sigalgs = NULL; ret->shared_sigalgs = NULL;
...@@ -473,6 +485,8 @@ void ssl_cert_free(CERT *c) ...@@ -473,6 +485,8 @@ void ssl_cert_free(CERT *c)
OPENSSL_free(c->peer_sigalgs); OPENSSL_free(c->peer_sigalgs);
if (c->conf_sigalgs) if (c->conf_sigalgs)
OPENSSL_free(c->conf_sigalgs); OPENSSL_free(c->conf_sigalgs);
if (c->client_sigalgs)
OPENSSL_free(c->client_sigalgs);
if (c->shared_sigalgs) if (c->shared_sigalgs)
OPENSSL_free(c->shared_sigalgs); OPENSSL_free(c->shared_sigalgs);
OPENSSL_free(c); OPENSSL_free(c);
......
...@@ -538,14 +538,25 @@ typedef struct cert_st ...@@ -538,14 +538,25 @@ typedef struct cert_st
unsigned char *peer_sigalgs; unsigned char *peer_sigalgs;
/* Size of above array */ /* Size of above array */
size_t peer_sigalgslen; size_t peer_sigalgslen;
/* configured signature algorithms (can be NULL for default). /* suppported signature algorithms.
* sent in signature algorithms extension or certificate request. * When set on a client this is sent in the client hello as the
* supported signature algorithms extension. For servers
* it represents the signature algorithms we are willing to use.
*/ */
unsigned char *conf_sigalgs; unsigned char *conf_sigalgs;
/* Size of above array */ /* Size of above array */
size_t conf_sigalgslen; size_t conf_sigalgslen;
/* Client authentication signature algorithms, if not set then
* uses conf_sigalgs. On servers these will be the signature
* algorithms sent to the client in a cerificate request for TLS 1.2.
* On a client this represents the signature algortithms we are
* willing to use for client authentication.
*/
unsigned char *client_sigalgs;
/* Size of above array */
size_t client_sigalgslen;
/* Signature algorithms shared by client and server: cached /* Signature algorithms shared by client and server: cached
* because these are used most often * because these are used most often.
*/ */
TLS_SIGALGS *shared_sigalgs; TLS_SIGALGS *shared_sigalgs;
size_t shared_sigalgslen; size_t shared_sigalgslen;
...@@ -1200,8 +1211,8 @@ int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, ...@@ -1200,8 +1211,8 @@ int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
int tls12_get_sigid(const EVP_PKEY *pk); int tls12_get_sigid(const EVP_PKEY *pk);
const EVP_MD *tls12_get_hash(unsigned char hash_alg); const EVP_MD *tls12_get_hash(unsigned char hash_alg);
int tls1_set_sigalgs_list(CERT *c, const char *str); int tls1_set_sigalgs_list(CERT *c, const char *str, int client);
int tls1_set_sigalgs(CERT *c, const int *salg, size_t salglen); int tls1_set_sigalgs(CERT *c, const int *salg, size_t salglen, int client);
int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
int idx); int idx);
void tls1_set_cert_validity(SSL *s); void tls1_set_cert_validity(SSL *s);
......
...@@ -639,10 +639,17 @@ size_t tls12_get_sig_algs(SSL *s, unsigned char *p) ...@@ -639,10 +639,17 @@ size_t tls12_get_sig_algs(SSL *s, unsigned char *p)
{ {
const unsigned char *sigs; const unsigned char *sigs;
size_t sigslen; size_t sigslen;
sigs = s->cert->conf_sigalgs; /* If server use client authentication sigalgs if not NULL */
if (s->server && s->cert->client_sigalgs)
if (sigs) {
sigs = s->cert->client_sigalgs;
sigslen = s->cert->client_sigalgslen;
}
else if (s->cert->conf_sigalgs)
{
sigs = s->cert->conf_sigalgs;
sigslen = s->cert->conf_sigalgslen; sigslen = s->cert->conf_sigalgslen;
}
else else
{ {
sigs = tls12_sigalgs; sigs = tls12_sigalgs;
...@@ -2975,9 +2982,17 @@ static int tls1_set_shared_sigalgs(SSL *s) ...@@ -2975,9 +2982,17 @@ static int tls1_set_shared_sigalgs(SSL *s)
size_t nmatch; size_t nmatch;
TLS_SIGALGS *salgs = NULL; TLS_SIGALGS *salgs = NULL;
CERT *c = s->cert; CERT *c = s->cert;
conf = c->conf_sigalgs; /* If client use client signature algorithms if not NULL */
if (conf) if (!s->server && c->client_sigalgs)
{
conf = c->client_sigalgs;
conflen = c->client_sigalgslen;
}
else if (c->conf_sigalgs)
{
conf = c->conf_sigalgs;
conflen = c->conf_sigalgslen; conflen = c->conf_sigalgslen;
}
else else
{ {
conf = tls12_sigalgs; conf = tls12_sigalgs;
...@@ -3328,16 +3343,16 @@ static int sig_cb(const char *elem, int len, void *arg) ...@@ -3328,16 +3343,16 @@ static int sig_cb(const char *elem, int len, void *arg)
/* Set suppored signature algorithms based on a colon separated list /* Set suppored signature algorithms based on a colon separated list
* of the form sig+hash e.g. RSA+SHA512:DSA+SHA512 */ * of the form sig+hash e.g. RSA+SHA512:DSA+SHA512 */
int tls1_set_sigalgs_list(CERT *c, const char *str) int tls1_set_sigalgs_list(CERT *c, const char *str, int client)
{ {
sig_cb_st sig; sig_cb_st sig;
sig.sigalgcnt = 0; sig.sigalgcnt = 0;
if (!CONF_parse_list(str, ':', 1, sig_cb, &sig)) if (!CONF_parse_list(str, ':', 1, sig_cb, &sig))
return 0; return 0;
return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt); return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client);
} }
int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen) int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
{ {
unsigned char *sigalgs, *sptr; unsigned char *sigalgs, *sptr;
int rhash, rsign; int rhash, rsign;
...@@ -3360,11 +3375,21 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen) ...@@ -3360,11 +3375,21 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen)
*sptr++ = rsign; *sptr++ = rsign;
} }
if (c->conf_sigalgs) if (client)
OPENSSL_free(c->conf_sigalgs); {
if (c->client_sigalgs)
OPENSSL_free(c->client_sigalgs);
c->client_sigalgs = sigalgs;
c->client_sigalgslen = salglen;
}
else
{
if (c->conf_sigalgs)
OPENSSL_free(c->conf_sigalgs);
c->conf_sigalgs = sigalgs;
c->conf_sigalgslen = salglen;
}
c->conf_sigalgs = sigalgs;
c->conf_sigalgslen = salglen;
return 1; return 1;
err: err:
...@@ -3457,7 +3482,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, ...@@ -3457,7 +3482,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
* have set preferred signature algorithms check we support * have set preferred signature algorithms check we support
* sha1. * sha1.
*/ */
if (default_nid > 0 && c->conf_sigalgs) if (s->server && default_nid > 0 && c->conf_sigalgs)
{ {
size_t j; size_t j;
const unsigned char *p = c->conf_sigalgs; const unsigned char *p = c->conf_sigalgs;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册