_______________
Changes between 1.0.0d and 1.0.1 [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
+ support yet and no support for client certificates.
+ [Steve Henson]
+
+ *) Initial TLS v1.2 support. Add new SHA256 digest to ssl code, switch
+ to SHA256 for PRF when using TLS v1.2 and later. Add new SHA256 based
+ ciphersuites. At present only RSA key exchange ciphersuites work with
+ TLS v1.2. Add new option for TLS v1.2 replacing the old and obsolete
+ SSL_OP_PKCS1_CHECK flags with SSL_OP_NO_TLSv1_2. New TLSv1.2 methods
+ and version checking.
+ [Steve Henson]
*) New option OPENSSL_NO_SSL_INTERN. If an application can be compiled
with this defined it will not be affected by any changes to ssl internal
extname = "renegotiate";
break;
+ case TLSEXT_TYPE_signature_algorithms:
+ extname = "signature algorithms";
+ break;
+
#ifdef TLSEXT_TYPE_opaque_prf_input
case TLSEXT_TYPE_opaque_prf_input:
extname = "opaque PRF input";
#endif
BIO_printf(bio_err," -ssl2 - just use SSLv2\n");
BIO_printf(bio_err," -ssl3 - just use SSLv3\n");
+ BIO_printf(bio_err," -tls1_2 - just use TLSv1.2\n");
BIO_printf(bio_err," -tls1_1 - just use TLSv1.1\n");
BIO_printf(bio_err," -tls1 - just use TLSv1\n");
BIO_printf(bio_err," -dtls1 - just use DTLSv1\n");
BIO_printf(bio_err," -mtu - set the link layer MTU\n");
- BIO_printf(bio_err," -no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
+ BIO_printf(bio_err," -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n");
BIO_printf(bio_err," -serverpref - Use server's cipher preferences (only SSLv2)\n");
BIO_printf(bio_err," -cipher - preferred cipher to use, use the 'openssl ciphers'\n");
meth=SSLv3_client_method();
#endif
#ifndef OPENSSL_NO_TLS1
+ else if (strcmp(*argv,"-tls1_2") == 0)
+ meth=TLSv1_2_client_method();
else if (strcmp(*argv,"-tls1_1") == 0)
meth=TLSv1_1_client_method();
else if (strcmp(*argv,"-tls1") == 0)
if (--argc < 1) goto bad;
CAfile= *(++argv);
}
+ else if (strcmp(*argv,"-no_tls1_2") == 0)
+ off|=SSL_OP_NO_TLSv1_2;
else if (strcmp(*argv,"-no_tls1_1") == 0)
off|=SSL_OP_NO_TLSv1_1;
else if (strcmp(*argv,"-no_tls1") == 0)
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
BIO_printf(bio,"Expansion: %s\n",
expansion ? SSL_COMP_get_name(expansion) : "NONE");
#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)
#endif
BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n");
BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n");
+ BIO_printf(bio_err," -tls1_2 - Just talk TLSv1.2\n");
BIO_printf(bio_err," -tls1_1 - Just talk TLSv1.1\n");
BIO_printf(bio_err," -tls1 - Just talk TLSv1\n");
BIO_printf(bio_err," -dtls1 - Just talk DTLSv1\n");
BIO_printf(bio_err," -no_ssl3 - Just disable SSLv3\n");
BIO_printf(bio_err," -no_tls1 - Just disable TLSv1\n");
BIO_printf(bio_err," -no_tls1_1 - Just disable TLSv1.1\n");
+ BIO_printf(bio_err," -no_tls1_2 - Just disable TLSv1.2\n");
#ifndef OPENSSL_NO_DH
BIO_printf(bio_err," -no_dhe - Disable ephemeral DH\n");
#endif
{ off|=SSL_OP_NO_TLSv1; }
else if (strcmp(*argv,"-no_tls1_1") == 0)
{ off|=SSL_OP_NO_TLSv1_1; }
+ else if (strcmp(*argv,"-no_tls1_2") == 0)
+ { off|=SSL_OP_NO_TLSv1_2; }
else if (strcmp(*argv,"-no_comp") == 0)
{ off|=SSL_OP_NO_COMPRESSION; }
#ifndef OPENSSL_NO_TLSEXT
{ meth=TLSv1_server_method(); }
else if (strcmp(*argv,"-tls1_1") == 0)
{ meth=TLSv1_1_server_method(); }
+ else if (strcmp(*argv,"-tls1_2") == 0)
+ { meth=TLSv1_2_server_method(); }
#endif
#ifndef OPENSSL_NO_DTLS1
else if (strcmp(*argv,"-dtls1") == 0)
SSL_CTX_set_quiet_shutdown(ctx,1);
if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);
if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
+ /* 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);
SSL_CTX_set_options(ctx,off);
/* DTLS: partial reads end up discarding unread UDP bytes :-(
* Setting read ahead solves this problem.
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
{
- if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
+ if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher, NULL))
== NULL)
{
al=SSL_AD_DECODE_ERROR;
return(TLSv1_client_method());
else if (ver == TLS1_1_VERSION)
return(TLSv1_1_client_method());
+ else if (ver == TLS1_2_VERSION)
+ return(TLSv1_2_client_method());
else
return(NULL);
}
if (ssl2_compat && ssl23_no_ssl2_ciphers(s))
ssl2_compat = 0;
- if (!(s->options & SSL_OP_NO_TLSv1_1))
+ if (!(s->options & SSL_OP_NO_TLSv1_2))
+ {
+ version = TLS1_2_VERSION;
+ }
+ else if (!(s->options & SSL_OP_NO_TLSv1_1))
{
version = TLS1_1_VERSION;
}
if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
return -1;
- if (version == TLS1_1_VERSION)
+ if (version == TLS1_2_VERSION)
+ {
+ version_major = TLS1_2_VERSION_MAJOR;
+ version_minor = TLS1_2_VERSION_MINOR;
+ }
+ else if (version == TLS1_1_VERSION)
{
version_major = TLS1_1_VERSION_MAJOR;
version_minor = TLS1_1_VERSION_MINOR;
#endif
}
else if (p[1] == SSL3_VERSION_MAJOR &&
- p[2] <= TLS1_1_VERSION_MINOR &&
+ p[2] <= TLS1_2_VERSION_MINOR &&
((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) ||
(p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2)))
{
s->version=TLS1_1_VERSION;
s->method=TLSv1_1_client_method();
}
+ else if ((p[2] == TLS1_2_VERSION_MINOR) &&
+ !(s->options & SSL_OP_NO_TLSv1_2))
+ {
+ s->version=TLS1_2_VERSION;
+ s->method=TLSv1_2_client_method();
+ }
else
{
SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
return(TLSv1_method());
else if (ver == TLS1_1_VERSION)
return(TLSv1_1_method());
+ else if (ver == TLS1_2_VERSION)
+ return(TLSv1_2_method());
else
#endif
return(NULL);
return(TLSv1_server_method());
else if (ver == TLS1_1_VERSION)
return(TLSv1_1_server_method());
+ else if (ver == TLS1_2_VERSION)
+ return(TLSv1_2_server_method());
else
return(NULL);
}
/* SSLv3/TLSv1 */
if (p[4] >= TLS1_VERSION_MINOR)
{
- if (p[4] >= TLS1_1_VERSION_MINOR &&
+ if (p[4] >= TLS1_2_VERSION_MINOR &&
+ !(s->options & SSL_OP_NO_TLSv1_2))
+ {
+ s->version=TLS1_2_VERSION;
+ s->state=SSL23_ST_SR_CLNT_HELLO_B;
+ }
+ else if (p[4] >= TLS1_1_VERSION_MINOR &&
!(s->options & SSL_OP_NO_TLSv1_1))
{
s->version=TLS1_1_VERSION;
+ /* type=2; */ /* done later to survive restarts */
s->state=SSL23_ST_SR_CLNT_HELLO_B;
}
else if (!(s->options & SSL_OP_NO_TLSv1))
v[1]=p[10]; /* minor version according to client_version */
if (v[1] >= TLS1_VERSION_MINOR)
{
- if (v[1] >= TLS1_1_VERSION_MINOR &&
+ if (v[1] >= TLS1_2_VERSION_MINOR &&
+ !(s->options & SSL_OP_NO_TLSv1_2))
+ {
+ s->version=TLS1_2_VERSION;
+ type=3;
+ }
+ else if (v[1] >= TLS1_1_VERSION_MINOR &&
!(s->options & SSL_OP_NO_TLSv1_1))
{
s->version=TLS1_1_VERSION;
s->s3->rbuf.left=0;
s->s3->rbuf.offset=0;
}
-
- if (s->version == TLS1_1_VERSION)
+ if (s->version == TLS1_2_VERSION)
+ s->method = TLSv1_2_server_method();
+ else if (s->version == TLS1_1_VERSION)
s->method = TLSv1_1_server_method();
else if (s->version == TLS1_VERSION)
s->method = TLSv1_server_method();
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
/* 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);
}
#ifndef OPENSSL_NO_RSA
- if (pkey->type == EVP_PKEY_RSA)
+ if (pkey->type == EVP_PKEY_RSA && s->version < TLS1_2_VERSION)
{
int num;
}
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);
goto f_err;
}
}
- else
-#endif
- {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
- goto err;
- }
}
else
{
{
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;
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);
}
#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);
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;
/* Loop through bitso of algorithm2 field and create MD_CTX-es */
for (i=0;ssl_get_handshake_digest(i,&mask,&md); i++)
{
- if ((mask & s->s3->tmp.new_cipher->algorithm2) && md)
+ if ((mask & ssl_get_algorithm2(s)) && md)
{
s->s3->handshake_dgst[i]=EVP_MD_CTX_create();
EVP_DigestInit_ex(s->s3->handshake_dgst[i],md,NULL);
256,
},
+ /* TLS v1.2 ciphersuites */
+ /* Cipher 3B */
+ {
+ 1,
+ TLS1_TXT_RSA_WITH_NULL_SHA256,
+ TLS1_CK_RSA_WITH_NULL_SHA256,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_eNULL,
+ SSL_SHA256,
+ SSL_SSLV3,
+ SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 0,
+ 0,
+ },
+
+ /* Cipher 3C */
+ {
+ 1,
+ TLS1_TXT_RSA_WITH_AES_128_SHA256,
+ TLS1_CK_RSA_WITH_AES_128_SHA256,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher 3D */
+ {
+ 1,
+ TLS1_TXT_RSA_WITH_AES_256_SHA256,
+ TLS1_CK_RSA_WITH_AES_256_SHA256,
+ SSL_kRSA,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* Cipher 3E */
+ {
+ 0, /* not implemented (non-ephemeral DH) */
+ TLS1_TXT_DH_DSS_WITH_AES_128_SHA256,
+ TLS1_CK_DH_DSS_WITH_AES_128_SHA256,
+ SSL_kDHr,
+ SSL_aDH,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher 3F */
+ {
+ 0, /* not implemented (non-ephemeral DH) */
+ TLS1_TXT_DH_RSA_WITH_AES_128_SHA256,
+ TLS1_CK_DH_RSA_WITH_AES_128_SHA256,
+ SSL_kDHr,
+ SSL_aDH,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher 40 */
+ {
+ 1,
+ TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256,
+ TLS1_CK_DHE_DSS_WITH_AES_128_SHA256,
+ SSL_kEDH,
+ SSL_aDSS,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
#ifndef OPENSSL_NO_CAMELLIA
/* Camellia ciphersuites from RFC4132 (128-bit portion) */
128,
},
#endif
+
+ /* TLS v1.2 ciphersuites */
+ /* Cipher 67 */
+ {
+ 1,
+ TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256,
+ TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
+ SSL_kEDH,
+ SSL_aRSA,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher 68 */
+ {
+ 0, /* not implemented (non-ephemeral DH) */
+ TLS1_TXT_DH_DSS_WITH_AES_256_SHA256,
+ TLS1_CK_DH_DSS_WITH_AES_256_SHA256,
+ SSL_kDHr,
+ SSL_aDH,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* Cipher 69 */
+ {
+ 0, /* not implemented (non-ephemeral DH) */
+ TLS1_TXT_DH_RSA_WITH_AES_256_SHA256,
+ TLS1_CK_DH_RSA_WITH_AES_256_SHA256,
+ SSL_kDHr,
+ SSL_aDH,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* Cipher 6A */
+ {
+ 1,
+ TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256,
+ TLS1_CK_DHE_DSS_WITH_AES_256_SHA256,
+ SSL_kEDH,
+ SSL_aDSS,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* Cipher 6B */
+ {
+ 1,
+ TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256,
+ TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
+ SSL_kEDH,
+ SSL_aRSA,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* Cipher 6C */
+ {
+ 1,
+ TLS1_TXT_ADH_WITH_AES_128_SHA256,
+ TLS1_CK_ADH_WITH_AES_128_SHA256,
+ SSL_kEDH,
+ SSL_aNULL,
+ SSL_AES128,
+ SSL_SHA256,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 128,
+ 128,
+ },
+
+ /* Cipher 6D */
+ {
+ 1,
+ TLS1_TXT_ADH_WITH_AES_256_SHA256,
+ TLS1_CK_ADH_WITH_AES_256_SHA256,
+ SSL_kEDH,
+ SSL_aNULL,
+ SSL_AES256,
+ SSL_SHA256,
+ SSL_TLSV1,
+ SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
+ SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ 256,
+ 256,
+ },
+
+ /* GOST Ciphersuites */
+
{
1,
"GOST94-GOST89-GOST89",
id=0x03000000L|((unsigned long)p[0]<<8L)|(unsigned long)p[1];
c.id=id;
cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS);
+#ifdef DEBUG_PRINT_UNKNOWN_CIPHERSUITES
+if (cp == NULL) fprintf(stderr, "Unknown cipher ID %x\n", (p[0] << 8) | p[1]);
+#endif
if (cp == NULL || cp->valid == 0)
return NULL;
else
}
return(ret);
}
+/* If we are using TLS v1.2 or later and default SHA1+MD5 algorithms switch
+ * to new SHA256 PRF and handshake macs
+ */
+long ssl_get_algorithm2(SSL *s)
+ {
+ long alg2 = s->s3->tmp.new_cipher->algorithm2;
+ if (s->version >= TLS1_2_VERSION &&
+ alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF))
+ return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
+ return alg2;
+ }
+
{
default:
#ifndef OPENSSL_NO_TLS
- /* TLS just ignores unknown message types */
+ /* TLS up to v1.1 just ignores unknown message types:
+ * TLS v1.2 give an unexpected message alert.
+ */
if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION)
{
rr->length = 0;
BN_CTX *bn_ctx = NULL;
#endif
EVP_PKEY *pkey;
+ const EVP_MD *md = NULL;
unsigned char *p,*d;
int al,i;
unsigned long type;
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
{
- if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
+ if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md))
== NULL)
{
al=SSL_AD_DECODE_ERROR;
/* n is the length of the params, they start at &(d[4])
* and p points to the space at the end. */
#ifndef OPENSSL_NO_RSA
- if (pkey->type == EVP_PKEY_RSA)
+ if (pkey->type == EVP_PKEY_RSA
+ && s->version < TLS1_2_VERSION)
{
q=md_buf;
j=0;
}
else
#endif
-#if !defined(OPENSSL_NO_DSA)
- if (pkey->type == EVP_PKEY_DSA)
+ if (md)
{
- /* lets do DSS */
- EVP_SignInit_ex(&md_ctx,EVP_dss1(), 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);
- EVP_SignUpdate(&md_ctx,&(d[4]),n);
- if (!EVP_SignFinal(&md_ctx,&(p[2]),
- (unsigned int *)&i,pkey))
+ /* For TLS1.2 and later send signature
+ * algorithm */
+ if (s->version >= TLS1_2_VERSION)
{
- SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA);
- goto err;
+ if (!tls12_get_sigandhash(p, pkey, md))
+ {
+ /* Should never happen */
+ al=SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+ p+=2;
}
- s2n(i,p);
- n+=i+2;
- }
- else
+#ifdef SSL_DEBUG
+ fprintf(stderr, "Using hash %s\n",
+ EVP_MD_name(md));
#endif
-#if !defined(OPENSSL_NO_ECDSA)
- if (pkey->type == EVP_PKEY_EC)
- {
- /* let's do ECDSA */
- EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL);
+ 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);
EVP_SignUpdate(&md_ctx,&(d[4]),n);
if (!EVP_SignFinal(&md_ctx,&(p[2]),
(unsigned int *)&i,pkey))
{
- SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_ECDSA);
+ SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_EVP);
goto err;
}
s2n(i,p);
n+=i+2;
+ if (s->version >= TLS1_2_VERSION)
+ n+= 2;
}
else
-#endif
{
/* Is this error check actually needed? */
al=SSL_AD_HANDSHAKE_FAILURE;
#define SSL_TXT_SHA "SHA" /* same as "SHA1" */
#define SSL_TXT_GOST94 "GOST94"
#define SSL_TXT_GOST89MAC "GOST89MAC"
+#define SSL_TXT_SHA256 "SHA256"
#define SSL_TXT_SSLV2 "SSLv2"
#define SSL_TXT_SSLV3 "SSLv3"
#define SSL_TXT_TLSV1 "TLSv1"
#define SSL_TXT_TLSV1_1 "TLSv1.1"
+#define SSL_TXT_TLSV1_2 "TLSv1.2"
#define SSL_TXT_EXP "EXP"
#define SSL_TXT_EXPORT "EXPORT"
#define SSL_OP_NO_SSLv2 0x01000000L
#define SSL_OP_NO_SSLv3 0x02000000L
#define SSL_OP_NO_TLSv1 0x04000000L
+#define SSL_OP_NO_TLSv1_2 0x08000000L
+/* These next two were never actually used for anything since SSLeay
+ * zap so we have some more flags.
+ */
/* The next flag deliberately changes the ciphertest, this is a check
* for the PKCS#1 attack */
-#define SSL_OP_PKCS1_CHECK_1 0x08000000L
-#define SSL_OP_PKCS1_CHECK_2 0x10000000L
+#define SSL_OP_PKCS1_CHECK_1 0x0
+#define SSL_OP_PKCS1_CHECK_2 0x0
+
#define SSL_OP_NETSCAPE_CA_DN_BUG 0x20000000L
#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x40000000L
/* Make server add server-hello extension from early version of
const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */
const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */
+const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */
+const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */
+const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */
+
+
const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */
const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */
const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */
#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
#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
int finish_md_len;
unsigned char peer_finish_md[EVP_MAX_MD_SIZE*2];
int peer_finish_md_len;
-
+
unsigned long message_size;
int message_type;
return ssl_x509_store_ctx_idx;
}
+static void ssl_cert_set_default_md(CERT *cert)
+ {
+ /* Set digest values to defaults */
+#ifndef OPENSSL_NO_DSA
+ cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_dss1();
+#endif
+#ifndef OPENSSL_NO_RSA
+ cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
+ cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ cert->pkeys[SSL_PKEY_ECC].digest = EVP_ecdsa();
+#endif
+ }
+
CERT *ssl_cert_new(void)
{
CERT *ret;
ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]);
ret->references=1;
-
+ ssl_cert_set_default_md(ret);
return(ret);
}
* chain is held inside SSL_CTX */
ret->references=1;
+ /* Set digests to defaults. NB: we don't copy existing values as they
+ * will be set during handshake.
+ */
+ ssl_cert_set_default_md(ret);
return(ret);
#define SSL_MD_SHA1_IDX 1
#define SSL_MD_GOST94_IDX 2
#define SSL_MD_GOST89MAC_IDX 3
+#define SSL_MD_SHA256_IDX 4
/*Constant SSL_MAX_DIGEST equal to size of digests array should be
* defined in the
* ssl_locl.h */
#define SSL_MD_NUM_IDX SSL_MAX_DIGEST
static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={
- NULL,NULL,NULL,NULL
+ NULL,NULL,NULL,NULL,NULL
};
/* PKEY_TYPE for GOST89MAC is known in advance, but, because
* implementation is engine-provided, we'll fill it only if
* corresponding EVP_PKEY_METHOD is found
*/
static int ssl_mac_pkey_id[SSL_MD_NUM_IDX]={
- EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef
+ EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef,EVP_PKEY_HMAC
};
static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={
- 0,0,0,0
+ 0,0,0,0,0
};
static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX]={
SSL_HANDSHAKE_MAC_MD5,SSL_HANDSHAKE_MAC_SHA,
- SSL_HANDSHAKE_MAC_GOST94,0
+ SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256
};
#define CIPHER_ADD 1
{0,SSL_TXT_SHA,0, 0,0,0,SSL_SHA1, 0,0,0,0,0},
{0,SSL_TXT_GOST94,0, 0,0,0,SSL_GOST94, 0,0,0,0,0},
{0,SSL_TXT_GOST89MAC,0, 0,0,0,SSL_GOST89MAC, 0,0,0,0,0},
+ {0,SSL_TXT_SHA256,0, 0,0,0,SSL_SHA256, 0,0,0,0,0},
/* protocol version aliases */
{0,SSL_TXT_SSLV2,0, 0,0,0,0,SSL_SSLV2, 0,0,0,0},
ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX]=32;
}
+ ssl_digest_methods[SSL_MD_SHA256_IDX]=
+ EVP_get_digestbyname(SN_sha256);
+ ssl_mac_secret_size[SSL_MD_SHA256_IDX]=
+ EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]);
}
#ifndef OPENSSL_NO_COMP
case SSL_SHA1:
i=SSL_MD_SHA1_IDX;
break;
+ case SSL_SHA256:
+ i=SSL_MD_SHA256_IDX;
+ break;
case SSL_GOST94:
i = SSL_MD_GOST94_IDX;
break;
{
return 0;
}
- if (ssl_handshake_digest_flag[idx]==0) return 0;
*mask = ssl_handshake_digest_flag[idx];
- *md = ssl_digest_methods[idx];
+ if (*mask)
+ *md = ssl_digest_methods[idx];
+ else
+ *md = NULL;
return 1;
}
*mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
*mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
+ *mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256:0;
*mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94:0;
*mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]==NID_undef)? SSL_GOST89MAC:0;
case SSL_SHA1:
mac="SHA1";
break;
+ case SSL_SHA256:
+ mac="SHA256";
+ break;
default:
mac="unknown";
break;
{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"},
{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"},
* deployed might change this.
*/
ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
+ /* Disable TLS v1.2 by default for now */
+ ret->options |= SSL_OP_NO_TLSv1_2;
return(ret);
err:
#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;
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)
return 0;
}
}
- if (alg_k & SSL_kECDHr)
+ if ((alg_k & SSL_kECDHr) && s->version < TLS1_2_VERSION)
{
/* signature alg must be RSA */
return(c->pkeys[i].x509);
}
-EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher)
+EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd)
{
unsigned long alg_a;
CERT *c;
+ int idx = -1;
alg_a = cipher->algorithm_auth;
c=s->cert;
if ((alg_a & SSL_aDSS) &&
(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
- return(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey);
+ idx = SSL_PKEY_DSA_SIGN;
else if (alg_a & SSL_aRSA)
{
if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)
- return(c->pkeys[SSL_PKEY_RSA_SIGN].privatekey);
+ idx = SSL_PKEY_RSA_SIGN;
else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL)
- return(c->pkeys[SSL_PKEY_RSA_ENC].privatekey);
- else
- return(NULL);
+ idx = SSL_PKEY_RSA_ENC;
}
else if ((alg_a & SSL_aECDSA) &&
(c->pkeys[SSL_PKEY_ECC].privatekey != NULL))
- return(c->pkeys[SSL_PKEY_ECC].privatekey);
- else /* if (alg_a & SSL_aNULL) */
+ idx = SSL_PKEY_ECC;
+ if (idx == -1)
{
SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR);
return(NULL);
}
+ if (pmd)
+ *pmd = c->pkeys[idx].digest;
+ return c->pkeys[idx].privatekey;
}
void ssl_update_cache(SSL *s,int mode)
const char *SSL_get_version(const SSL *s)
{
- if (s->version == TLS1_1_VERSION)
+ if (s->version == TLS1_2_VERSION)
+ return("TLSv1.2");
+ else if (s->version == TLS1_1_VERSION)
return("TLSv1.1");
if (s->version == TLS1_VERSION)
return("TLSv1");
# define OPENSSL_EXTERN OPENSSL_EXPORT
#endif
-#define PKCS1_CHECK
+#undef PKCS1_CHECK
#define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \
l|=(((unsigned long)(*((c)++)))<< 8), \
#define SSL_SHA1 0x00000002L
#define SSL_GOST94 0x00000004L
#define SSL_GOST89MAC 0x00000008L
+#define SSL_SHA256 0x00000010L
/* Bits for algorithm_ssl (protocol version) */
#define SSL_SSLV2 0x00000001L
#define SSL_HANDSHAKE_MAC_MD5 0x10
#define SSL_HANDSHAKE_MAC_SHA 0x20
#define SSL_HANDSHAKE_MAC_GOST94 0x40
+#define SSL_HANDSHAKE_MAC_SHA256 0x80
#define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
/* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX
* make sure to update this constant too */
-#define SSL_MAX_DIGEST 4
+#define SSL_MAX_DIGEST 5
#define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT)
{
X509 *x509;
EVP_PKEY *privatekey;
+ /* Digest to use when signing */
+ const EVP_MD *digest;
} CERT_PKEY;
typedef struct cert_st
const SSL_METHOD *func_name(void) \
{ \
static const SSL_METHOD func_name##_data= { \
- TLS1_1_VERSION, \
+ TLS1_2_VERSION, \
tls1_new, \
tls1_clear, \
tls1_free, \
int ssl_undefined_void_function(void);
int ssl_undefined_const_function(const SSL *s);
X509 *ssl_get_server_send_cert(SSL *);
-EVP_PKEY *ssl_get_sign_pkey(SSL *,const SSL_CIPHER *);
+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);
void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
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);
#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);
int maxlen);
int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
int *al);
+long ssl_get_algorithm2(SSL *s);
#endif
ss->ssl_version=TLS1_1_VERSION;
ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
}
+ else if (s->version == TLS1_2_VERSION)
+ {
+ ss->ssl_version=TLS1_2_VERSION;
+ ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH;
+ }
else if (s->version == DTLS1_BAD_VER)
{
ss->ssl_version=DTLS1_BAD_VER;
s="SSLv2";
else if (x->ssl_version == SSL3_VERSION)
s="SSLv3";
+ else if (x->ssl_version == TLS1_2_VERSION)
+ s="TLSv1.2";
else if (x->ssl_version == TLS1_1_VERSION)
s="TLSv1.1";
else if (x->ssl_version == TLS1_VERSION)
static const SSL_METHOD *tls1_get_client_method(int ver);
static const SSL_METHOD *tls1_get_client_method(int ver)
{
+ if (ver == TLS1_2_VERSION)
+ return TLSv1_2_client_method();
if (ver == TLS1_1_VERSION)
return TLSv1_1_client_method();
if (ver == TLS1_VERSION)
return NULL;
}
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_client_method,
+ ssl_undefined_function,
+ ssl3_connect,
+ tls1_get_client_method)
+
IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_client_method,
ssl_undefined_function,
ssl3_connect,
unsigned char *tmp, int num)
{
int ret;
- ret = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ ret = tls1_PRF(ssl_get_algorithm2(s),
TLS_MD_KEY_EXPANSION_CONST,TLS_MD_KEY_EXPANSION_CONST_SIZE,
s->s3->server_random,SSL3_RANDOM_SIZE,
s->s3->client_random,SSL3_RANDOM_SIZE,
/* In here I set both the read and write key/iv to the
* same value since only the correct one will be used :-).
*/
- if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ if (!tls1_PRF(ssl_get_algorithm2(s),
exp_label,exp_label_len,
s->s3->client_random,SSL3_RANDOM_SIZE,
s->s3->server_random,SSL3_RANDOM_SIZE,
if (k > 0)
{
- if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ if (!tls1_PRF(ssl_get_algorithm2(s),
TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE,
s->s3->client_random,SSL3_RANDOM_SIZE,
s->s3->server_random,SSL3_RANDOM_SIZE,
for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
{
- if (mask & s->s3->tmp.new_cipher->algorithm2)
+ if (mask & ssl_get_algorithm2(s))
{
int hashsize = EVP_MD_size(md);
if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
}
}
- if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ if (!tls1_PRF(ssl_get_algorithm2(s),
str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
s->session->master_key,s->session->master_key_length,
out,buf2,sizeof buf2))
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 */
}
#endif
- tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ tls1_PRF(ssl_get_algorithm2(s),
TLS_MD_MASTER_SECRET_CONST,TLS_MD_MASTER_SECRET_CONST_SIZE,
s->s3->client_random,SSL3_RANDOM_SIZE,
co, col,
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");
if (!tmp)
return 0;
- rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ rv = tls1_PRF(ssl_get_algorithm2(s),
label, label_len,
s->s3->client_random,SSL3_RANDOM_SIZE,
s->s3->server_random,SSL3_RANDOM_SIZE,
static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
const unsigned char *sess_id, int sesslen,
SSL_SESSION **psess);
+static int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
#endif
SSL3_ENC_METHOD TLSv1_enc_data={
}
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)
unsigned short len;
unsigned char *data = *p;
int renegotiate_seen = 0;
+ int sigalg_seen = 0;
s->servername_done = 0;
s->tlsext_status_type = -1;
return 0;
renegotiate_seen = 1;
}
+ else if (type == TLSEXT_TYPE_signature_algorithms)
+ {
+ int dsize;
+ if (sigalg_seen || size < 2)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ sigalg_seen = 1;
+ n2s(data,dsize);
+ size -= 2;
+ if (dsize != size || dsize & 1)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ if (!tls1_process_sigalgs(s, data, dsize))
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ }
else if (type == TLSEXT_TYPE_status_request &&
s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb)
{
return 0;
}
+/* Tables to translate from NIDs to TLS v1.2 ids */
+
+typedef struct
+ {
+ int nid;
+ int id;
+ } tls12_lookup;
+
+static tls12_lookup tls12_md[] = {
+#ifndef OPENSSL_NO_MD5
+ {NID_md5, TLSEXT_hash_md5},
+#endif
+#ifndef OPENSSL_NO_SHA
+ {NID_sha1, TLSEXT_hash_sha1},
+#endif
+#ifndef OPENSSL_NO_SHA256
+ {NID_sha224, TLSEXT_hash_sha224},
+ {NID_sha256, TLSEXT_hash_sha256},
+#endif
+#ifndef OPENSSL_NO_SHA512
+ {NID_sha384, TLSEXT_hash_sha384},
+ {NID_sha512, TLSEXT_hash_sha512}
+#endif
+};
+
+static tls12_lookup tls12_sig[] = {
+#ifndef OPENSSL_NO_RSA
+ {EVP_PKEY_RSA, TLSEXT_signature_rsa},
+#endif
+#ifndef OPENSSL_NO_RSA
+ {EVP_PKEY_DSA, TLSEXT_signature_dsa},
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ {EVP_PKEY_EC, TLSEXT_signature_ecdsa}
+#endif
+};
+
+static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen)
+ {
+ size_t i;
+ for (i = 0; i < tlen; i++)
+ {
+ if (table[i].nid == nid)
+ return table[i].id;
+ }
+ return -1;
+ }
+#if 0
+static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen)
+ {
+ size_t i;
+ for (i = 0; i < tlen; i++)
+ {
+ if (table[i].id == id)
+ return table[i].nid;
+ }
+ return -1;
+ }
+#endif
+
+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_get_sigid(pk);
+ if (sig_id == -1)
+ return 0;
+ p[0] = (unsigned char)md_id;
+ p[1] = (unsigned char)sig_id;
+ 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 */
+
+static int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
+ {
+ int i, idx;
+ const EVP_MD *md;
+ CERT *c = s->cert;
+ /* Extension ignored for TLS versions below 1.2 */
+ if (s->version < TLS1_2_VERSION)
+ return 1;
+
+ c->pkeys[SSL_PKEY_DSA_SIGN].digest = NULL;
+ c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL;
+ c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL;
+ c->pkeys[SSL_PKEY_ECC].digest = NULL;
+
+ for (i = 0; i < dsize; i += 2)
+ {
+ unsigned char hash_alg = data[i], sig_alg = data[i+1];
+
+ switch(sig_alg)
+ {
+#ifndef OPENSSL_NO_RSA
+ case TLSEXT_signature_rsa:
+ idx = SSL_PKEY_RSA_SIGN;
+ break;
+#endif
+#ifndef OPENSSL_NO_DSA
+ case TLSEXT_signature_dsa:
+ idx = SSL_PKEY_DSA_SIGN;
+ break;
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ case TLSEXT_signature_ecdsa:
+ idx = SSL_PKEY_ECC;
+ break;
+#endif
+ default:
+ continue;
+ }
+
+ if (c->pkeys[idx].digest == NULL)
+ {
+ 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;
+ }
+ }
+
+ }
+
+ /* Set any remaining keys to default values. NOTE: if alg is not
+ * supported it stays as NULL.
+ */
+#ifndef OPENSSL_NO_DSA
+ if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest)
+ c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_dss1();
+#endif
+#ifndef OPENSSL_NO_RSA
+ if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest)
+ {
+ c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
+ c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
+ }
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ if (!c->pkeys[SSL_PKEY_ECC].digest)
+ c->pkeys[SSL_PKEY_ECC].digest = EVP_ecdsa();
+#endif
+ return 1;
+ }
+
#endif
static const SSL_METHOD *tls1_get_method(int ver)
{
+ if (ver == TLS1_2_VERSION)
+ return TLSv1_2_method();
if (ver == TLS1_1_VERSION)
return TLSv1_1_method();
if (ver == TLS1_VERSION)
return NULL;
}
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method,
+ ssl3_accept,
+ ssl3_connect,
+ tls1_get_method)
+
IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method,
ssl3_accept,
ssl3_connect,
static const SSL_METHOD *tls1_get_server_method(int ver);
static const SSL_METHOD *tls1_get_server_method(int ver)
{
+ if (ver == TLS1_2_VERSION)
+ return TLSv1_2_server_method();
if (ver == TLS1_1_VERSION)
return TLSv1_1_server_method();
if (ver == TLS1_VERSION)
return NULL;
}
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_server_method,
+ ssl3_accept,
+ ssl_undefined_function,
+ tls1_get_server_method)
+
IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method,
ssl3_accept,
ssl_undefined_function,
#define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0
+#define TLS1_2_VERSION 0x0303
+#define TLS1_2_VERSION_MAJOR 0x03
+#define TLS1_2_VERSION_MINOR 0x03
+
#define TLS1_1_VERSION 0x0302
#define TLS1_1_VERSION_MAJOR 0x03
#define TLS1_1_VERSION_MINOR 0x02
#define TLSEXT_TYPE_ec_point_formats 11
/* ExtensionType value from RFC5054 */
#define TLSEXT_TYPE_srp 12
+#define TLSEXT_TYPE_signature_algorithms 13
#define TLSEXT_TYPE_session_ticket 35
/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */
#if 0 /* will have to be provided externally for now ,
#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2
#define TLSEXT_ECPOINTFORMAT_last 2
+/* Signature and hash algorithms from RFC 5246 */
+
+#define TLSEXT_signature_anonymous 0
+#define TLSEXT_signature_rsa 1
+#define TLSEXT_signature_dsa 2
+#define TLSEXT_signature_ecdsa 3
+
+#define TLSEXT_hash_none 0
+#define TLSEXT_hash_md5 1
+#define TLSEXT_hash_sha1 2
+#define TLSEXT_hash_sha224 3
+#define TLSEXT_hash_sha256 4
+#define TLSEXT_hash_sha384 5
+#define TLSEXT_hash_sha512 6
+
#ifndef OPENSSL_NO_TLSEXT
#define TLSEXT_MAXLEN_host_name 255
#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039
#define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A
+/* TLS v1.2 ciphersuites */
+#define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B
+#define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C
+#define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D
+#define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E
+#define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F
+#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040
+
/* Camellia ciphersuites from RFC4132 */
#define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041
#define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042
#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045
#define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046
+/* TLS v1.2 ciphersuites */
+#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067
+#define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068
+#define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069
+#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A
+#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B
+#define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C
+#define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D
+
+/* Camellia ciphersuites from RFC4132 */
#define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084
#define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085
#define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086
#define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA"
#define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA"
+/* TLS v1.2 ciphersuites */
+#define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256"
+#define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256"
+#define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256"
+#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256"
+#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256"
+#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256"
+#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256"
+#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256"
+#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256"
+#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256"
+#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256"
+#define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256"
+#define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256"
#define TLS_CT_RSA_SIGN 1
#define TLS_CT_DSS_SIGN 2