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

Initial TLS v1.2 client support. Include a default supported signature

algorithms extension (including everything we support). Swicth to new
signature format where needed and relax ECC restrictions.

Not TLS v1.2 client certifcate support yet but client will handle case
where a certificate is requested and we don't have one.
上级 0b59755f
......@@ -4,6 +4,12 @@
Changes between 1.0.1 and 1.1.0 [xx XXX xxxx]
*) Initial TLS v1.2 client support. Add a default signature algorithms
extension including all the algorithms we support. Parse new signature
format in client key exchange. Relax some ECC signing restrictions for
TLS v1.2 as indicated in RFC5246.
[Steve Henson]
*) Add server support for TLS v1.2 signature algorithms extension. Switch
to new signature format when needed using client digest preference.
All server ciphersuites should now work correctly in TLS v1.2. No client
......
......@@ -1103,6 +1103,9 @@ bad:
SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
}
#endif
/* HACK while TLS v1.2 is disabled by default */
if (!(off & SSL_OP_NO_TLSv1_2))
SSL_CTX_clear_options(ctx, SSL_OP_NO_TLSv1_2);
if (bugs)
SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
else
......@@ -2011,6 +2014,18 @@ static void print_stuff(BIO *bio, SSL *s, int full)
}
#endif
#ifdef SSL_DEBUG
{
/* Print out local port of connection: useful for debugging */
int sock;
struct sockaddr_in ladd;
socklen_t ladd_size = sizeof(ladd);
sock = SSL_get_fd(s);
getsockname(sock, (struct sockaddr *)&ladd, &ladd_size);
BIO_printf(bio_c_out, "LOCAL PORT is %u\n", ntohs(ladd.sin_port));
}
#endif
SSL_SESSION_print(bio,SSL_get_session(s));
BIO_printf(bio,"---\n");
if (peer != NULL)
......
......@@ -1203,6 +1203,7 @@ int ssl3_get_key_exchange(SSL *s)
int al,i,j,param_len,ok;
long n,alg_k,alg_a;
EVP_PKEY *pkey=NULL;
const EVP_MD *md = NULL;
#ifndef OPENSSL_NO_RSA
RSA *rsa=NULL;
#endif
......@@ -1653,6 +1654,38 @@ int ssl3_get_key_exchange(SSL *s)
/* if it was signed, check the signature */
if (pkey != NULL)
{
if (s->version >= TLS1_2_VERSION)
{
int sigalg = tls12_get_sigid(pkey);
/* Should never happen */
if (sigalg == -1)
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
goto err;
}
/* Check key type is consistent with signature */
if (sigalg != (int)p[1])
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_TYPE);
al=SSL_AD_DECODE_ERROR;
goto f_err;
}
md = tls12_get_hash(p[0]);
if (md == NULL)
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNKNOWN_DIGEST);
al=SSL_AD_DECODE_ERROR;
goto f_err;
}
#ifdef SSL_DEBUG
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
#endif
p += 2;
n -= 2;
}
else
md = EVP_sha1();
n2s(p,i);
n-=2;
j=EVP_PKEY_size(pkey);
......@@ -1666,7 +1699,7 @@ int ssl3_get_key_exchange(SSL *s)
}
#ifndef OPENSSL_NO_RSA
if (pkey->type == EVP_PKEY_RSA)
if (pkey->type == EVP_PKEY_RSA && s->version < TLS1_2_VERSION)
{
int num;
......@@ -1701,29 +1734,8 @@ int ssl3_get_key_exchange(SSL *s)
}
else
#endif
#ifndef OPENSSL_NO_DSA
if (pkey->type == EVP_PKEY_DSA)
{
/* lets do DSS */
EVP_VerifyInit_ex(&md_ctx,EVP_dss1(), NULL);
EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,param,param_len);
if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0)
{
/* bad signature */
al=SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE);
goto f_err;
}
}
else
#endif
#ifndef OPENSSL_NO_ECDSA
if (pkey->type == EVP_PKEY_EC)
{
/* let's do ECDSA */
EVP_VerifyInit_ex(&md_ctx,EVP_ecdsa(), NULL);
EVP_VerifyInit_ex(&md_ctx, md, NULL);
EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx,param,param_len);
......@@ -1735,12 +1747,6 @@ int ssl3_get_key_exchange(SSL *s)
goto f_err;
}
}
else
#endif
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
goto err;
}
}
else
{
......@@ -1787,7 +1793,7 @@ int ssl3_get_certificate_request(SSL *s)
{
int ok,ret=0;
unsigned long n,nc,l;
unsigned int llen,ctype_num,i;
unsigned int llen,sigalglen, ctype_num,i;
X509_NAME *xn=NULL;
const unsigned char *p,*q;
unsigned char *d;
......@@ -1843,6 +1849,17 @@ int ssl3_get_certificate_request(SSL *s)
for (i=0; i<ctype_num; i++)
s->s3->tmp.ctype[i]= p[i];
p+=ctype_num;
/* HACK! For now just skip over signatature algorithms */
if (s->version >= TLS1_2_VERSION)
{
n2s(p, sigalglen);
p += sigalglen;
sigalglen += 2;
}
else
sigalglen = 0;
/* get the CA RDNs */
n2s(p,llen);
......@@ -1855,7 +1872,7 @@ fclose(out);
}
#endif
if ((llen+ctype_num+2+1) != n)
if ((llen+ctype_num+sigalglen+2+1) != n)
{
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH);
......@@ -3059,7 +3076,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
if (idx == SSL_PKEY_ECC)
{
if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509,
s->s3->tmp.new_cipher) == 0)
s) == 0)
{ /* check failed */
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_BAD_ECC_CERT);
goto f_err;
......
......@@ -1932,6 +1932,10 @@ int ssl3_send_server_key_exchange(SSL *s)
}
p+=2;
}
#ifdef SSL_DEBUG
fprintf(stderr, "Using hash %s\n",
EVP_MD_name(md));
#endif
EVP_SignInit_ex(&md_ctx, md, NULL);
EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
......
......@@ -2500,6 +2500,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247
#define SSL_R_UNKNOWN_CIPHER_RETURNED 248
#define SSL_R_UNKNOWN_CIPHER_TYPE 249
#define SSL_R_UNKNOWN_DIGEST 357
#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250
#define SSL_R_UNKNOWN_PKEY_TYPE 251
#define SSL_R_UNKNOWN_PROTOCOL 252
......@@ -2520,6 +2521,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_WRONG_NUMBER_OF_KEY_BITS 263
#define SSL_R_WRONG_SIGNATURE_LENGTH 264
#define SSL_R_WRONG_SIGNATURE_SIZE 265
#define SSL_R_WRONG_SIGNATURE_TYPE 358
#define SSL_R_WRONG_SSL_VERSION 266
#define SSL_R_WRONG_VERSION_NUMBER 267
#define SSL_R_X509_LIB 268
......
......@@ -543,6 +543,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE),"unknown certificate type"},
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED),"unknown cipher returned"},
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE) ,"unknown cipher type"},
{ERR_REASON(SSL_R_UNKNOWN_DIGEST) ,"unknown digest"},
{ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE),"unknown key exchange type"},
{ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE) ,"unknown pkey type"},
{ERR_REASON(SSL_R_UNKNOWN_PROTOCOL) ,"unknown protocol"},
......@@ -563,6 +564,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS),"wrong number of key bits"},
{ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
{ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE) ,"wrong signature size"},
{ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE) ,"wrong signature type"},
{ERR_REASON(SSL_R_WRONG_SSL_VERSION) ,"wrong ssl version"},
{ERR_REASON(SSL_R_WRONG_VERSION_NUMBER) ,"wrong version number"},
{ERR_REASON(SSL_R_X509_LIB) ,"x509 lib"},
......
......@@ -2185,12 +2185,13 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
#ifndef OPENSSL_NO_EC
int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)
int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
{
unsigned long alg_k, alg_a;
EVP_PKEY *pkey = NULL;
int keysize = 0;
int signature_nid = 0;
const SSL_CIPHER *cs = s->s3->tmp.new_cipher;
alg_k = cs->algorithm_mkey;
alg_a = cs->algorithm_auth;
......@@ -2217,7 +2218,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)
SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT);
return 0;
}
if (alg_k & SSL_kECDHe)
if ((alg_k & SSL_kECDHe) && s->version < TLS1_2_VERSION)
{
/* signature alg must be ECDSA */
if (signature_nid != NID_ecdsa_with_SHA1)
......@@ -2226,7 +2227,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)
return 0;
}
}
if (alg_k & SSL_kECDHr)
if ((alg_k & SSL_kECDHr) && s->version < TLS1_2_VERSION)
{
/* signature alg must be RSA */
......
......@@ -1050,7 +1050,7 @@ int ssl3_alert_code(int code);
int ssl_ok(SSL *s);
#ifndef OPENSSL_NO_ECDH
int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs);
int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s);
#endif
SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
......@@ -1077,6 +1077,12 @@ int ssl_check_serverhello_tlsext(SSL *s);
#endif
int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
const unsigned char *limit, SSL_SESSION **ret);
int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
const EVP_MD *md);
int tls12_get_sigid(const EVP_PKEY *pk);
const EVP_MD *tls12_get_hash(unsigned char hash_alg);
#endif
EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
......@@ -1090,4 +1096,3 @@ int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
int *al);
long ssl_get_algorithm2(SSL *s);
#endif
int tls12_get_sigandhash(unsigned char *p, EVP_PKEY *pk, const EVP_MD *md);
......@@ -1008,6 +1008,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
const void *co = NULL, *so = NULL;
int col = 0, sol = 0;
#ifdef KSSL_DEBUG
printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
#endif /* KSSL_DEBUG */
......@@ -1032,6 +1033,16 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
so, sol,
p,len,
s->session->master_key,buff,sizeof buff);
#ifdef SSL_DEBUG
fprintf(stderr, "Premaster Secret:\n");
BIO_dump_fp(stderr, (char *)p, len);
fprintf(stderr, "Client Random:\n");
BIO_dump_fp(stderr, (char *)s->s3->client_random, SSL3_RANDOM_SIZE);
fprintf(stderr, "Server Random:\n");
BIO_dump_fp(stderr, (char *)s->s3->server_random, SSL3_RANDOM_SIZE);
fprintf(stderr, "Master Secret:\n");
BIO_dump_fp(stderr, (char *)s->session->master_key, SSL3_MASTER_SECRET_SIZE);
#endif
#ifdef KSSL_DEBUG
printf ("tls1_generate_master_secret() complete\n");
......
......@@ -451,6 +451,62 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
skip_ext:
if (s->version >= TLS1_2_VERSION)
{
/* List of supported signature algorithms and hashes.
* Should make this customisable at some point, for
* now include everything we support.
*/
static unsigned char sigalgs[] = {
#ifndef OPENSSL_NO_RSA
# ifndef OPENSSL_NO_SHA512
TLSEXT_hash_sha512, TLSEXT_signature_rsa,
TLSEXT_hash_sha384, TLSEXT_signature_rsa,
# endif
# ifndef OPENSSL_NO_SHA256
TLSEXT_hash_sha256, TLSEXT_signature_rsa,
TLSEXT_hash_sha224, TLSEXT_signature_rsa,
# endif
# ifndef OPENSSL_NO_SHA
TLSEXT_hash_sha1, TLSEXT_signature_rsa,
# endif
#endif
#ifndef OPENSSL_NO_ECDSA
# ifndef OPENSSL_NO_SHA512
TLSEXT_hash_sha512, TLSEXT_signature_ecdsa,
TLSEXT_hash_sha384, TLSEXT_signature_ecdsa,
# endif
# ifndef OPENSSL_NO_SHA256
TLSEXT_hash_sha256, TLSEXT_signature_ecdsa,
TLSEXT_hash_sha224, TLSEXT_signature_ecdsa,
# endif
# ifndef OPENSSL_NO_SHA
TLSEXT_hash_sha1, TLSEXT_signature_ecdsa,
# endif
#endif
#ifndef OPENSSL_NO_DSA
# ifndef OPENSSL_NO_SHA512
TLSEXT_hash_sha512, TLSEXT_signature_dsa,
TLSEXT_hash_sha384, TLSEXT_signature_dsa,
# endif
# ifndef OPENSSL_NO_SHA256
TLSEXT_hash_sha256, TLSEXT_signature_dsa,
TLSEXT_hash_sha224, TLSEXT_signature_dsa,
# endif
# ifndef OPENSSL_NO_SHA
TLSEXT_hash_sha1, TLSEXT_signature_dsa
# endif
#endif
};
if ((size_t)(limit - ret) < sizeof(sigalgs) + 6)
return NULL;
s2n(TLSEXT_TYPE_signature_algorithms,ret);
s2n(sizeof(sigalgs) + 2, ret);
s2n(sizeof(sigalgs), ret);
memcpy(ret, sigalgs, sizeof(sigalgs));
ret += sizeof(sigalgs);
}
#ifdef TLSEXT_TYPE_opaque_prf_input
if (s->s3->client_opaque_prf_input != NULL &&
s->version != DTLS1_VERSION)
......@@ -1976,15 +2032,15 @@ static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen)
return -1;
}
#endif
int tls12_get_sigandhash(unsigned char *p, EVP_PKEY *pk, const EVP_MD *md)
int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, const EVP_MD *md)
{
int sig_id, md_id;
md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
sizeof(tls12_md)/sizeof(tls12_lookup));
if (md_id == -1)
return 0;
sig_id = tls12_find_id(pk->type, tls12_sig,
sizeof(tls12_sig)/sizeof(tls12_lookup));
sig_id = tls12_get_sigid(pk);
if (sig_id == -1)
return 0;
p[0] = (unsigned char)md_id;
......@@ -1992,9 +2048,47 @@ int tls12_get_sigandhash(unsigned char *p, EVP_PKEY *pk, const EVP_MD *md)
return 1;
}
int tls12_get_sigid(const EVP_PKEY *pk)
{
return tls12_find_id(pk->type, tls12_sig,
sizeof(tls12_sig)/sizeof(tls12_lookup));
}
const EVP_MD *tls12_get_hash(unsigned char hash_alg)
{
switch(hash_alg)
{
#ifndef OPENSSL_NO_MD5
case TLSEXT_hash_md5:
return EVP_md5();
#endif
#ifndef OPENSSL_NO_SHA
case TLSEXT_hash_sha1:
return EVP_sha1();
#endif
#ifndef OPENSSL_NO_SHA256
case TLSEXT_hash_sha224:
return EVP_sha224();
case TLSEXT_hash_sha256:
return EVP_sha256();
#endif
#ifndef OPENSSL_NO_SHA512
case TLSEXT_hash_sha384:
return EVP_sha384();
case TLSEXT_hash_sha512:
return EVP_sha512();
#endif
default:
return NULL;
}
}
/* Set preferred digest for each key type */
int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
static int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
{
int i, idx;
const EVP_MD *md;
......@@ -2033,48 +2127,17 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
continue;
}
if (c->pkeys[idx].digest)
continue;
switch(hash_alg)
if (c->pkeys[idx].digest == NULL)
{
#ifndef OPENSSL_NO_MD5
case TLSEXT_hash_md5:
md = EVP_md5();
break;
#endif
#ifndef OPENSSL_NO_SHA
case TLSEXT_hash_sha1:
md = EVP_sha1();
break;
#endif
#ifndef OPENSSL_NO_SHA256
case TLSEXT_hash_sha224:
md = EVP_sha224();
break;
case TLSEXT_hash_sha256:
md = EVP_sha256();
break;
#endif
#ifndef OPENSSL_NO_SHA512
case TLSEXT_hash_sha384:
md = EVP_sha384();
break;
case TLSEXT_hash_sha512:
md = EVP_sha512();
break;
#endif
default:
continue;
md = tls12_get_hash(hash_alg);
if (md)
{
c->pkeys[idx].digest = md;
if (idx == SSL_PKEY_RSA_SIGN)
c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
}
}
c->pkeys[idx].digest = md;
if (idx == SSL_PKEY_RSA_SIGN)
c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
}
/* Set any remaining keys to default values. NOTE: if alg is not
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册