Merge OpenSSL 1.0.1k.

This commit is contained in:
Jung-uk Kim 2015-01-08 23:42:41 +00:00
commit 751d29910b
443 changed files with 9110 additions and 7958 deletions

View File

@ -2,6 +2,136 @@
OpenSSL CHANGES OpenSSL CHANGES
_______________ _______________
Changes between 1.0.1j and 1.0.1k [8 Jan 2015]
*) Fix DTLS segmentation fault in dtls1_get_record. A carefully crafted DTLS
message can cause a segmentation fault in OpenSSL due to a NULL pointer
dereference. This could lead to a Denial Of Service attack. Thanks to
Markus Stenberg of Cisco Systems, Inc. for reporting this issue.
(CVE-2014-3571)
[Steve Henson]
*) Fix DTLS memory leak in dtls1_buffer_record. A memory leak can occur in the
dtls1_buffer_record function under certain conditions. In particular this
could occur if an attacker sent repeated DTLS records with the same
sequence number but for the next epoch. The memory leak could be exploited
by an attacker in a Denial of Service attack through memory exhaustion.
Thanks to Chris Mueller for reporting this issue.
(CVE-2015-0206)
[Matt Caswell]
*) Fix issue where no-ssl3 configuration sets method to NULL. When openssl is
built with the no-ssl3 option and a SSL v3 ClientHello is received the ssl
method would be set to NULL which could later result in a NULL pointer
dereference. Thanks to Frank Schmirler for reporting this issue.
(CVE-2014-3569)
[Kurt Roeckx]
*) Abort handshake if server key exchange message is omitted for ephemeral
ECDH ciphersuites.
Thanks to Karthikeyan Bhargavan of the PROSECCO team at INRIA for
reporting this issue.
(CVE-2014-3572)
[Steve Henson]
*) Remove non-export ephemeral RSA code on client and server. This code
violated the TLS standard by allowing the use of temporary RSA keys in
non-export ciphersuites and could be used by a server to effectively
downgrade the RSA key length used to a value smaller than the server
certificate. Thanks for Karthikeyan Bhargavan of the PROSECCO team at
INRIA or reporting this issue.
(CVE-2015-0204)
[Steve Henson]
*) Fixed issue where DH client certificates are accepted without verification.
An OpenSSL server will accept a DH certificate for client authentication
without the certificate verify message. This effectively allows a client to
authenticate without the use of a private key. This only affects servers
which trust a client certificate authority which issues certificates
containing DH keys: these are extremely rare and hardly ever encountered.
Thanks for Karthikeyan Bhargavan of the PROSECCO team at INRIA or reporting
this issue.
(CVE-2015-0205)
[Steve Henson]
*) Ensure that the session ID context of an SSL is updated when its
SSL_CTX is updated via SSL_set_SSL_CTX.
The session ID context is typically set from the parent SSL_CTX,
and can vary with the CTX.
[Adam Langley]
*) Fix various certificate fingerprint issues.
By using non-DER or invalid encodings outside the signed portion of a
certificate the fingerprint can be changed without breaking the signature.
Although no details of the signed portion of the certificate can be changed
this can cause problems with some applications: e.g. those using the
certificate fingerprint for blacklists.
1. Reject signatures with non zero unused bits.
If the BIT STRING containing the signature has non zero unused bits reject
the signature. All current signature algorithms require zero unused bits.
2. Check certificate algorithm consistency.
Check the AlgorithmIdentifier inside TBS matches the one in the
certificate signature. NB: this will result in signature failure
errors for some broken certificates.
Thanks to Konrad Kraszewski from Google for reporting this issue.
3. Check DSA/ECDSA signatures use DER.
Reencode DSA/ECDSA signatures and compare with the original received
signature. Return an error if there is a mismatch.
This will reject various cases including garbage after signature
(thanks to Antti Karjalainen and Tuomo Untinen from the Codenomicon CROSS
program for discovering this case) and use of BER or invalid ASN.1 INTEGERs
(negative or with leading zeroes).
Further analysis was conducted and fixes were developed by Stephen Henson
of the OpenSSL core team.
(CVE-2014-8275)
[Steve Henson]
*) Correct Bignum squaring. Bignum squaring (BN_sqr) may produce incorrect
results on some platforms, including x86_64. This bug occurs at random
with a very low probability, and is not known to be exploitable in any
way, though its exact impact is difficult to determine. Thanks to Pieter
Wuille (Blockstream) who reported this issue and also suggested an initial
fix. Further analysis was conducted by the OpenSSL development team and
Adam Langley of Google. The final fix was developed by Andy Polyakov of
the OpenSSL core team.
(CVE-2014-3570)
[Andy Polyakov]
*) Do not resume sessions on the server if the negotiated protocol
version does not match the session's version. Resuming with a different
version, while not strictly forbidden by the RFC, is of questionable
sanity and breaks all known clients.
[David Benjamin, Emilia Käsper]
*) Tighten handling of the ChangeCipherSpec (CCS) message: reject
early CCS messages during renegotiation. (Note that because
renegotiation is encrypted, this early CCS was not exploitable.)
[Emilia Käsper]
*) Tighten client-side session ticket handling during renegotiation:
ensure that the client only accepts a session ticket if the server sends
the extension anew in the ServerHello. Previously, a TLS client would
reuse the old extension state and thus accept a session ticket if one was
announced in the initial ServerHello.
Similarly, ensure that the client requires a session ticket if one
was advertised in the ServerHello. Previously, a TLS client would
ignore a missing NewSessionTicket message.
[Emilia Käsper]
Changes between 1.0.1i and 1.0.1j [15 Oct 2014] Changes between 1.0.1i and 1.0.1j [15 Oct 2014]
*) SRTP Memory Leak. *) SRTP Memory Leak.

View File

@ -804,6 +804,11 @@ PROCESS_ARGS:
{ {
$disabled{"tls1"} = "option(tls)" $disabled{"tls1"} = "option(tls)"
} }
elsif ($1 eq "ssl3-method")
{
$disabled{"ssl3-method"} = "option(ssl)";
$disabled{"ssl3"} = "option(ssl)";
}
else else
{ {
$disabled{$1} = "option"; $disabled{$1} = "option";

View File

@ -4,7 +4,7 @@
## Makefile for OpenSSL ## Makefile for OpenSSL
## ##
VERSION=1.0.1j VERSION=1.0.1k
MAJOR=1 MAJOR=1
MINOR=0.1 MINOR=0.1
SHLIB_VERSION_NUMBER=1.0.0 SHLIB_VERSION_NUMBER=1.0.0

View File

@ -5,6 +5,17 @@
This file gives a brief overview of the major changes between each OpenSSL This file gives a brief overview of the major changes between each OpenSSL
release. For more details please read the CHANGES file. release. For more details please read the CHANGES file.
Major changes between OpenSSL 1.0.1j and OpenSSL 1.0.1k [8 Jan 2015]
o Fix for CVE-2014-3571
o Fix for CVE-2015-0206
o Fix for CVE-2014-3569
o Fix for CVE-2014-3572
o Fix for CVE-2015-0204
o Fix for CVE-2015-0205
o Fix for CVE-2014-8275
o Fix for CVE-2014-3570
Major changes between OpenSSL 1.0.1i and OpenSSL 1.0.1j [15 Oct 2014] Major changes between OpenSSL 1.0.1i and OpenSSL 1.0.1j [15 Oct 2014]
o Fix for CVE-2014-3513 o Fix for CVE-2014-3513

View File

@ -1,5 +1,5 @@
OpenSSL 1.0.1j 15 Oct 2014 OpenSSL 1.0.1k 8 Jan 2015
Copyright (c) 1998-2011 The OpenSSL Project Copyright (c) 1998-2011 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson

View File

@ -703,7 +703,7 @@ EF_ALIGNMENT=0;
ERR_clear_error(); ERR_clear_error();
#ifdef RL_DEBUG #ifdef RL_DEBUG
if (!p) if (!p)
BIO_printf(bio_err, "DEBUG: unique_subject undefined\n", p); BIO_printf(bio_err, "DEBUG: unique_subject undefined\n");
#endif #endif
#ifdef RL_DEBUG #ifdef RL_DEBUG
BIO_printf(bio_err, "DEBUG: configured unique_subject is %d\n", BIO_printf(bio_err, "DEBUG: configured unique_subject is %d\n",

View File

@ -273,6 +273,8 @@ int MAIN(int argc, char **argv)
BIO_printf(bio_err,"-d to output debug info\n"); BIO_printf(bio_err,"-d to output debug info\n");
BIO_printf(bio_err,"-hex output as hex dump\n"); BIO_printf(bio_err,"-hex output as hex dump\n");
BIO_printf(bio_err,"-binary output in binary form\n"); BIO_printf(bio_err,"-binary output in binary form\n");
BIO_printf(bio_err,"-hmac arg set the HMAC key to arg\n");
BIO_printf(bio_err,"-non-fips-allow allow use of non FIPS digest\n");
BIO_printf(bio_err,"-sign file sign digest using private key in file\n"); BIO_printf(bio_err,"-sign file sign digest using private key in file\n");
BIO_printf(bio_err,"-verify file verify a signature using public key in file\n"); BIO_printf(bio_err,"-verify file verify a signature using public key in file\n");
BIO_printf(bio_err,"-prverify file verify a signature using private key in file\n"); BIO_printf(bio_err,"-prverify file verify a signature using private key in file\n");

View File

@ -583,51 +583,52 @@ int MAIN(int argc, char **argv)
BIO_printf (bio_err, "OCSP utility\n"); BIO_printf (bio_err, "OCSP utility\n");
BIO_printf (bio_err, "Usage ocsp [options]\n"); BIO_printf (bio_err, "Usage ocsp [options]\n");
BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "where options are\n");
BIO_printf (bio_err, "-out file output filename\n"); BIO_printf (bio_err, "-out file output filename\n");
BIO_printf (bio_err, "-issuer file issuer certificate\n"); BIO_printf (bio_err, "-issuer file issuer certificate\n");
BIO_printf (bio_err, "-cert file certificate to check\n"); BIO_printf (bio_err, "-cert file certificate to check\n");
BIO_printf (bio_err, "-serial n serial number to check\n"); BIO_printf (bio_err, "-serial n serial number to check\n");
BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n"); BIO_printf (bio_err, "-signer file certificate to sign OCSP request with\n");
BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n"); BIO_printf (bio_err, "-signkey file private key to sign OCSP request with\n");
BIO_printf (bio_err, "-sign_other file additional certificates to include in signed request\n"); BIO_printf (bio_err, "-sign_other file additional certificates to include in signed request\n");
BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n"); BIO_printf (bio_err, "-no_certs don't include any certificates in signed request\n");
BIO_printf (bio_err, "-req_text print text form of request\n"); BIO_printf (bio_err, "-req_text print text form of request\n");
BIO_printf (bio_err, "-resp_text print text form of response\n"); BIO_printf (bio_err, "-resp_text print text form of response\n");
BIO_printf (bio_err, "-text print text form of request and response\n"); BIO_printf (bio_err, "-text print text form of request and response\n");
BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n"); BIO_printf (bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n");
BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n"); BIO_printf (bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n");
BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n"); BIO_printf (bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n");
BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n"); BIO_printf (bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n");
BIO_printf (bio_err, "-nonce add OCSP nonce to request\n"); BIO_printf (bio_err, "-nonce add OCSP nonce to request\n");
BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n"); BIO_printf (bio_err, "-no_nonce don't add OCSP nonce to request\n");
BIO_printf (bio_err, "-url URL OCSP responder URL\n"); BIO_printf (bio_err, "-url URL OCSP responder URL\n");
BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n"); BIO_printf (bio_err, "-host host:n send OCSP request to host on port n\n");
BIO_printf (bio_err, "-path path to use in OCSP request\n"); BIO_printf (bio_err, "-path path to use in OCSP request\n");
BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
BIO_printf (bio_err, "-VAfile file validator certificates file\n"); BIO_printf (bio_err, "-VAfile file validator certificates file\n");
BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n"); BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
BIO_printf (bio_err, "-status_age n maximum status age in seconds\n"); BIO_printf (bio_err, "-status_age n maximum status age in seconds\n");
BIO_printf (bio_err, "-noverify don't verify response at all\n"); BIO_printf (bio_err, "-noverify don't verify response at all\n");
BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n"); BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
BIO_printf (bio_err, "-trust_other don't verify additional certificates\n"); BIO_printf (bio_err, "-trust_other don't verify additional certificates\n");
BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n"); BIO_printf (bio_err, "-no_intern don't search certificates contained in response for signer\n");
BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n"); BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n"); BIO_printf (bio_err, "-no_cert_verify don't check signing certificate\n");
BIO_printf (bio_err, "-no_chain don't chain verify response\n"); BIO_printf (bio_err, "-no_chain don't chain verify response\n");
BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n"); BIO_printf (bio_err, "-no_cert_checks don't do additional checks on signing certificate\n");
BIO_printf (bio_err, "-port num port to run responder on\n"); BIO_printf (bio_err, "-port num port to run responder on\n");
BIO_printf (bio_err, "-index file certificate status index file\n"); BIO_printf (bio_err, "-index file certificate status index file\n");
BIO_printf (bio_err, "-CA file CA certificate\n"); BIO_printf (bio_err, "-CA file CA certificate\n");
BIO_printf (bio_err, "-rsigner file responder certificate to sign responses with\n"); BIO_printf (bio_err, "-rsigner file responder certificate to sign responses with\n");
BIO_printf (bio_err, "-rkey file responder key to sign responses with\n"); BIO_printf (bio_err, "-rkey file responder key to sign responses with\n");
BIO_printf (bio_err, "-rother file other certificates to include in response\n"); BIO_printf (bio_err, "-rother file other certificates to include in response\n");
BIO_printf (bio_err, "-resp_no_certs don't include any certificates in response\n"); BIO_printf (bio_err, "-resp_no_certs don't include any certificates in response\n");
BIO_printf (bio_err, "-nmin n number of minutes before next update\n"); BIO_printf (bio_err, "-nmin n number of minutes before next update\n");
BIO_printf (bio_err, "-ndays n number of days before next update\n"); BIO_printf (bio_err, "-ndays n number of days before next update\n");
BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n"); BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n");
BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n"); BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n");
BIO_printf (bio_err, "-<dgst alg> use specified digest in the request\n"); BIO_printf (bio_err, "-<dgst alg> use specified digest in the request\n");
BIO_printf (bio_err, "-timeout n timeout connection to OCSP responder after n seconds\n");
goto end; goto end;
} }
@ -1398,16 +1399,7 @@ OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
if (use_ssl == 1) if (use_ssl == 1)
{ {
BIO *sbio; BIO *sbio;
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
ctx = SSL_CTX_new(SSLv23_client_method()); 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) if (ctx == NULL)
{ {
BIO_printf(err, "Error creating SSL context.\n"); BIO_printf(err, "Error creating SSL context.\n");

View File

@ -435,9 +435,7 @@ int main(int Argc, char *ARGV[])
if (prog != NULL) lh_FUNCTION_free(prog); if (prog != NULL) lh_FUNCTION_free(prog);
if (arg.data != NULL) OPENSSL_free(arg.data); if (arg.data != NULL) OPENSSL_free(arg.data);
apps_shutdown();
CRYPTO_mem_leaks(bio_err);
if (bio_err != NULL) if (bio_err != NULL)
{ {
BIO_free(bio_err); BIO_free(bio_err);
@ -450,6 +448,9 @@ int main(int Argc, char *ARGV[])
OPENSSL_free(Argv); OPENSSL_free(Argv);
} }
#endif #endif
apps_shutdown();
CRYPTO_mem_leaks(bio_err);
OPENSSL_EXIT(ret); OPENSSL_EXIT(ret);
} }

View File

@ -329,10 +329,12 @@ static void sc_usage(void)
BIO_printf(bio_err," -srppass arg - password for 'user'\n"); BIO_printf(bio_err," -srppass arg - password for 'user'\n");
BIO_printf(bio_err," -srp_lateuser - SRP username into second ClientHello message\n"); BIO_printf(bio_err," -srp_lateuser - SRP username into second ClientHello message\n");
BIO_printf(bio_err," -srp_moregroups - Tolerate other than the known g N values.\n"); BIO_printf(bio_err," -srp_moregroups - Tolerate other than the known g N values.\n");
BIO_printf(bio_err," -srp_strength int - minimal mength in bits for N (default %d).\n",SRP_MINIMAL_N); BIO_printf(bio_err," -srp_strength int - minimal length in bits for N (default %d).\n",SRP_MINIMAL_N);
#endif #endif
BIO_printf(bio_err," -ssl2 - just use SSLv2\n"); BIO_printf(bio_err," -ssl2 - just use SSLv2\n");
#ifndef OPENSSL_NO_SSL3_METHOD
BIO_printf(bio_err," -ssl3 - just use SSLv3\n"); BIO_printf(bio_err," -ssl3 - just use SSLv3\n");
#endif
BIO_printf(bio_err," -tls1_2 - just use TLSv1.2\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_1 - just use TLSv1.1\n");
BIO_printf(bio_err," -tls1 - just use TLSv1\n"); BIO_printf(bio_err," -tls1 - just use TLSv1\n");
@ -807,7 +809,7 @@ int MAIN(int argc, char **argv)
else if (strcmp(*argv,"-ssl2") == 0) else if (strcmp(*argv,"-ssl2") == 0)
meth=SSLv2_client_method(); meth=SSLv2_client_method();
#endif #endif
#ifndef OPENSSL_NO_SSL3 #ifndef OPENSSL_NO_SSL3_METHOD
else if (strcmp(*argv,"-ssl3") == 0) else if (strcmp(*argv,"-ssl3") == 0)
meth=SSLv3_client_method(); meth=SSLv3_client_method();
#endif #endif
@ -1319,10 +1321,22 @@ int MAIN(int argc, char **argv)
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
} }
if (socket_mtu > 28) if (socket_mtu)
{ {
if(socket_mtu < DTLS_get_link_min_mtu(con))
{
BIO_printf(bio_err,"MTU too small. Must be at least %ld\n",
DTLS_get_link_min_mtu(con));
BIO_free(sbio);
goto shut;
}
SSL_set_options(con, SSL_OP_NO_QUERY_MTU); SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
SSL_set_mtu(con, socket_mtu - 28); if(!DTLS_set_link_mtu(con, socket_mtu))
{
BIO_printf(bio_err, "Failed to set MTU\n");
BIO_free(sbio);
goto shut;
}
} }
else else
/* want to do MTU discovery */ /* want to do MTU discovery */

View File

@ -515,7 +515,9 @@ static void sv_usage(void)
BIO_printf(bio_err," -srpuserseed string - A seed string for a default user salt.\n"); BIO_printf(bio_err," -srpuserseed string - A seed string for a default user salt.\n");
#endif #endif
BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n"); BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n");
#ifndef OPENSSL_NO_SSL3_METHOD
BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n"); BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n");
#endif
BIO_printf(bio_err," -tls1_2 - Just talk TLSv1.2\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_1 - Just talk TLSv1.1\n");
BIO_printf(bio_err," -tls1 - Just talk TLSv1\n"); BIO_printf(bio_err," -tls1 - Just talk TLSv1\n");
@ -1251,7 +1253,7 @@ int MAIN(int argc, char *argv[])
else if (strcmp(*argv,"-ssl2") == 0) else if (strcmp(*argv,"-ssl2") == 0)
{ meth=SSLv2_server_method(); } { meth=SSLv2_server_method(); }
#endif #endif
#ifndef OPENSSL_NO_SSL3 #ifndef OPENSSL_NO_SSL3_METHOD
else if (strcmp(*argv,"-ssl3") == 0) else if (strcmp(*argv,"-ssl3") == 0)
{ meth=SSLv3_server_method(); } { meth=SSLv3_server_method(); }
#endif #endif
@ -2049,10 +2051,24 @@ static int sv_body(char *hostname, int s, unsigned char *context)
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
} }
if (socket_mtu > 28) if (socket_mtu)
{ {
if(socket_mtu < DTLS_get_link_min_mtu(con))
{
BIO_printf(bio_err,"MTU too small. Must be at least %ld\n",
DTLS_get_link_min_mtu(con));
ret = -1;
BIO_free(sbio);
goto err;
}
SSL_set_options(con, SSL_OP_NO_QUERY_MTU); SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
SSL_set_mtu(con, socket_mtu - 28); if(!DTLS_set_link_mtu(con, socket_mtu))
{
BIO_printf(bio_err, "Failed to set MTU\n");
ret = -1;
BIO_free(sbio);
goto err;
}
} }
else else
/* want to do MTU discovery */ /* want to do MTU discovery */

View File

@ -349,13 +349,7 @@ int MAIN(int argc, char **argv)
if (bio_err == NULL) if (bio_err == NULL)
bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
s_time_meth=SSLv23_client_method(); s_time_meth=SSLv23_client_method();
#elif !defined(OPENSSL_NO_SSL3)
s_time_meth=SSLv3_client_method();
#elif !defined(OPENSSL_NO_SSL2)
s_time_meth=SSLv2_client_method();
#endif
/* parse the command line arguments */ /* parse the command line arguments */
if( parseArgs( argc, argv ) < 0 ) if( parseArgs( argc, argv ) < 0 )

View File

@ -225,7 +225,7 @@
#undef BUFSIZE #undef BUFSIZE
#define BUFSIZE ((long)1024*8+1) #define BUFSIZE ((long)1024*8+1)
int run=0; static volatile int run=0;
static int mr=0; static int mr=0;
static int usertime=1; static int usertime=1;
@ -2727,27 +2727,6 @@ static int do_multi(int multi)
k=atoi(sstrsep(&p,sep)); k=atoi(sstrsep(&p,sep));
sstrsep(&p,sep); sstrsep(&p,sep);
d=atof(sstrsep(&p,sep));
if(n)
rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
else
rsa_results[k][0]=d;
d=atof(sstrsep(&p,sep));
if(n)
rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
else
rsa_results[k][1]=d;
}
else if(!strncmp(buf,"+F2:",4))
{
int k;
double d;
p=buf+4;
k=atoi(sstrsep(&p,sep));
sstrsep(&p,sep);
d=atof(sstrsep(&p,sep)); d=atof(sstrsep(&p,sep));
if(n) if(n)
rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d); rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);

View File

@ -56,12 +56,7 @@ top:
all: shared all: shared
buildinf.h: ../Makefile buildinf.h: ../Makefile
( echo "#ifndef MK1MF_BUILD"; \ $(PERL) $(TOP)/util/mkbuildinf.pl "$(CFLAGS)" "$(PLATFORM)" >buildinf.h
echo ' /* auto-generated by crypto/Makefile for crypto/cversion.c */'; \
echo ' #define CFLAGS "$(CC) $(CFLAG)"'; \
echo ' #define PLATFORM "$(PLATFORM)"'; \
echo " #define DATE \"`LC_ALL=C LC_TIME=C date`\""; \
echo '#endif' ) >buildinf.h
x86cpuid.s: x86cpuid.pl perlasm/x86asm.pl x86cpuid.s: x86cpuid.pl perlasm/x86asm.pl
$(PERL) x86cpuid.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@ $(PERL) x86cpuid.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@

View File

@ -70,7 +70,7 @@ $pf = ($flavour =~ /nubi/i) ? $t0 : $t2;
# #
###################################################################### ######################################################################
$big_endian=(`echo MIPSEL | $ENV{CC} -E -P -`=~/MIPSEL/)?1:0; $big_endian=(`echo MIPSEL | $ENV{CC} -E -`=~/MIPSEL/)?1:0 if ($ENV{CC});
for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); } for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); }
open STDOUT,">$output"; open STDOUT,">$output";

View File

@ -136,11 +136,16 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
p= *pp; p= *pp;
i= *(p++); i= *(p++);
if (i > 7)
{
i=ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
goto err;
}
/* We do this to preserve the settings. If we modify /* We do this to preserve the settings. If we modify
* the settings, via the _set_bit function, we will recalculate * the settings, via the _set_bit function, we will recalculate
* on output */ * on output */
ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */ ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */ ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|i); /* set */
if (len-- > 1) /* using one because of the bits left byte */ if (len-- > 1) /* using one because of the bits left byte */
{ {

View File

@ -113,7 +113,7 @@ IMPLEMENT_STACK_OF(ASN1_TYPE)
IMPLEMENT_ASN1_SET_OF(ASN1_TYPE) IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
/* Returns 0 if they are equal, != 0 otherwise. */ /* Returns 0 if they are equal, != 0 otherwise. */
int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b) int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
{ {
int result = -1; int result = -1;

View File

@ -90,6 +90,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
goto err; goto err;
} }
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
{
ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
goto err;
}
inl=i2d(data,NULL); inl=i2d(data,NULL);
buf_in=OPENSSL_malloc((unsigned int)inl); buf_in=OPENSSL_malloc((unsigned int)inl);
@ -146,6 +152,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
return -1; return -1;
} }
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
{
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
return -1;
}
EVP_MD_CTX_init(&ctx); EVP_MD_CTX_init(&ctx);
/* Convert signature OID into digest and public key OIDs */ /* Convert signature OID into digest and public key OIDs */

View File

@ -776,7 +776,7 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
int ASN1_TYPE_get(ASN1_TYPE *a); int ASN1_TYPE_get(ASN1_TYPE *a);
void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b); int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
ASN1_OBJECT * ASN1_OBJECT_new(void ); ASN1_OBJECT * ASN1_OBJECT_new(void );
void ASN1_OBJECT_free(ASN1_OBJECT *a); void ASN1_OBJECT_free(ASN1_OBJECT *a);
@ -1329,6 +1329,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_ILLEGAL_TIME_VALUE 184 #define ASN1_R_ILLEGAL_TIME_VALUE 184
#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 #define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185
#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 #define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220
#define ASN1_R_INVALID_BMPSTRING_LENGTH 129 #define ASN1_R_INVALID_BMPSTRING_LENGTH 129
#define ASN1_R_INVALID_DIGIT 130 #define ASN1_R_INVALID_DIGIT 130
#define ASN1_R_INVALID_MIME_TYPE 205 #define ASN1_R_INVALID_MIME_TYPE 205
@ -1378,6 +1379,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_TIME_NOT_ASCII_FORMAT 193 #define ASN1_R_TIME_NOT_ASCII_FORMAT 193
#define ASN1_R_TOO_LONG 155 #define ASN1_R_TOO_LONG 155
#define ASN1_R_TYPE_NOT_CONSTRUCTED 156 #define ASN1_R_TYPE_NOT_CONSTRUCTED 156
#define ASN1_R_TYPE_NOT_PRIMITIVE 218
#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157 #define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157
#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158 #define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158
#define ASN1_R_UNEXPECTED_EOC 159 #define ASN1_R_UNEXPECTED_EOC 159

View File

@ -1,6 +1,6 @@
/* crypto/asn1/asn1_err.c */ /* crypto/asn1/asn1_err.c */
/* ==================================================================== /* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -246,6 +246,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) ,"illegal time value"}, {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) ,"illegal time value"},
{ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"}, {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"}, {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),"invalid bit string bits left"},
{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"}, {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
{ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"}, {ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"},
{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"}, {ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
@ -295,6 +296,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT),"time not ascii format"}, {ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT),"time not ascii format"},
{ERR_REASON(ASN1_R_TOO_LONG) ,"too long"}, {ERR_REASON(ASN1_R_TOO_LONG) ,"too long"},
{ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) ,"type not constructed"}, {ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) ,"type not constructed"},
{ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE) ,"type not primitive"},
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"}, {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"},
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"}, {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"},
{ERR_REASON(ASN1_R_UNEXPECTED_EOC) ,"unexpected eoc"}, {ERR_REASON(ASN1_R_UNEXPECTED_EOC) ,"unexpected eoc"},

View File

@ -870,6 +870,14 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
} }
else if (cst) else if (cst)
{ {
if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
|| utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
|| utype == V_ASN1_ENUMERATED)
{
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
ASN1_R_TYPE_NOT_PRIMITIVE);
return 0;
}
buf.length = 0; buf.length = 0;
buf.max = 0; buf.max = 0;
buf.data = NULL; buf.data = NULL;

View File

@ -142,3 +142,14 @@ void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
} }
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
{
int rv;
rv = OBJ_cmp(a->algorithm, b->algorithm);
if (rv)
return rv;
if (!a->parameter && !b->parameter)
return 0;
return ASN1_TYPE_cmp(a->parameter, b->parameter);
}

View File

@ -350,6 +350,8 @@ static int x509_name_canon(X509_NAME *a)
set = entry->set; set = entry->set;
} }
tmpentry = X509_NAME_ENTRY_new(); tmpentry = X509_NAME_ENTRY_new();
if (!tmpentry)
goto err;
tmpentry->object = OBJ_dup(entry->object); tmpentry->object = OBJ_dup(entry->object);
if (!asn1_string_canon(tmpentry->value, entry->value)) if (!asn1_string_canon(tmpentry->value, entry->value))
goto err; goto err;

View File

@ -175,6 +175,8 @@ extern "C" {
#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to #define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to
* adjust socket timeouts */ * adjust socket timeouts */
#define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD 49
#ifndef OPENSSL_NO_SCTP #ifndef OPENSSL_NO_SCTP
/* SCTP stuff */ /* SCTP stuff */
#define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50 #define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50
@ -607,6 +609,8 @@ int BIO_ctrl_reset_read_request(BIO *b);
(int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer) (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer)
#define BIO_dgram_set_peer(b,peer) \ #define BIO_dgram_set_peer(b,peer) \
(int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer) (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
#define BIO_dgram_get_mtu_overhead(b) \
(unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL)
/* These two aren't currently implemented */ /* These two aren't currently implemented */
/* int BIO_get_ex_num(BIO *bio); */ /* int BIO_get_ex_num(BIO *bio); */

View File

@ -454,6 +454,36 @@ static int dgram_write(BIO *b, const char *in, int inl)
return(ret); return(ret);
} }
static long dgram_get_mtu_overhead(bio_dgram_data *data)
{
long ret;
switch (data->peer.sa.sa_family)
{
case AF_INET:
/* Assume this is UDP - 20 bytes for IP, 8 bytes for UDP */
ret = 28;
break;
#if OPENSSL_USE_IPV6
case AF_INET6:
#ifdef IN6_IS_ADDR_V4MAPPED
if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
/* Assume this is UDP - 20 bytes for IP, 8 bytes for UDP */
ret = 28;
else
#endif
/* Assume this is UDP - 40 bytes for IP, 8 bytes for UDP */
ret = 48;
break;
#endif
default:
/* We don't know. Go with the historical default */
ret = 28;
break;
}
return ret;
}
static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
{ {
long ret=1; long ret=1;
@ -630,23 +660,24 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
#endif #endif
break; break;
case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
ret = -dgram_get_mtu_overhead(data);
switch (data->peer.sa.sa_family) switch (data->peer.sa.sa_family)
{ {
case AF_INET: case AF_INET:
ret = 576 - 20 - 8; ret += 576;
break; break;
#if OPENSSL_USE_IPV6 #if OPENSSL_USE_IPV6
case AF_INET6: case AF_INET6:
#ifdef IN6_IS_ADDR_V4MAPPED #ifdef IN6_IS_ADDR_V4MAPPED
if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
ret = 576 - 20 - 8; ret += 576;
else else
#endif #endif
ret = 1280 - 40 - 8; ret += 1280;
break; break;
#endif #endif
default: default:
ret = 576 - 20 - 8; ret += 576;
break; break;
} }
break; break;
@ -847,6 +878,9 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = 0; ret = 0;
break; break;
#endif #endif
case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
ret = dgram_get_mtu_overhead(data);
break;
default: default:
ret=0; ret=0;
break; break;
@ -893,10 +927,18 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag)
/* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */ /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE; auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk)); ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk));
OPENSSL_assert(ret >= 0); if (ret < 0)
{
BIO_vfree(bio);
return(NULL);
}
auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE; auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk)); ret = setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, sizeof(struct sctp_authchunk));
OPENSSL_assert(ret >= 0); if (ret < 0)
{
BIO_vfree(bio);
return(NULL);
}
/* Test if activation was successful. When using accept(), /* Test if activation was successful. When using accept(),
* SCTP-AUTH has to be activated for the listening socket * SCTP-AUTH has to be activated for the listening socket
@ -905,7 +947,13 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag)
authchunks = OPENSSL_malloc(sockopt_len); authchunks = OPENSSL_malloc(sockopt_len);
memset(authchunks, 0, sizeof(sockopt_len)); memset(authchunks, 0, sizeof(sockopt_len));
ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, &sockopt_len); ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, &sockopt_len);
OPENSSL_assert(ret >= 0);
if (ret < 0)
{
OPENSSL_free(authchunks);
BIO_vfree(bio);
return(NULL);
}
for (p = (unsigned char*) authchunks->gauth_chunks; for (p = (unsigned char*) authchunks->gauth_chunks;
p < (unsigned char*) authchunks + sockopt_len; p < (unsigned char*) authchunks + sockopt_len;
@ -927,16 +975,28 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag)
event.se_type = SCTP_AUTHENTICATION_EVENT; event.se_type = SCTP_AUTHENTICATION_EVENT;
event.se_on = 1; event.se_on = 1;
ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event)); ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
OPENSSL_assert(ret >= 0); if (ret < 0)
{
BIO_vfree(bio);
return(NULL);
}
#else #else
sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe); sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len); ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
OPENSSL_assert(ret >= 0); if (ret < 0)
{
BIO_vfree(bio);
return(NULL);
}
event.sctp_authentication_event = 1; event.sctp_authentication_event = 1;
ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
OPENSSL_assert(ret >= 0); if (ret < 0)
{
BIO_vfree(bio);
return(NULL);
}
#endif #endif
#endif #endif
@ -944,7 +1004,11 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag)
* larger than the max record size of 2^14 + 2048 + 13 * larger than the max record size of 2^14 + 2048 + 13
*/ */
ret = setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, sizeof(optval)); ret = setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, sizeof(optval));
OPENSSL_assert(ret >= 0); if (ret < 0)
{
BIO_vfree(bio);
return(NULL);
}
return(bio); return(bio);
} }
@ -982,7 +1046,12 @@ static int dgram_sctp_free(BIO *a)
return 0; return 0;
data = (bio_dgram_sctp_data *)a->ptr; data = (bio_dgram_sctp_data *)a->ptr;
if(data != NULL) OPENSSL_free(data); if(data != NULL)
{
if(data->saved_message.data != NULL)
OPENSSL_free(data->saved_message.data);
OPENSSL_free(data);
}
return(1); return(1);
} }
@ -1034,6 +1103,13 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
msg.msg_flags = 0; msg.msg_flags = 0;
n = recvmsg(b->num, &msg, 0); n = recvmsg(b->num, &msg, 0);
if (n <= 0)
{
if (n < 0)
ret = n;
break;
}
if (msg.msg_controllen > 0) if (msg.msg_controllen > 0)
{ {
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
@ -1073,13 +1149,6 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
} }
} }
if (n <= 0)
{
if (n < 0)
ret = n;
break;
}
if (msg.msg_flags & MSG_NOTIFICATION) if (msg.msg_flags & MSG_NOTIFICATION)
{ {
snp = (union sctp_notification*) out; snp = (union sctp_notification*) out;
@ -1099,6 +1168,7 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
dgram_sctp_write(data->saved_message.bio, data->saved_message.data, dgram_sctp_write(data->saved_message.bio, data->saved_message.data,
data->saved_message.length); data->saved_message.length);
OPENSSL_free(data->saved_message.data); OPENSSL_free(data->saved_message.data);
data->saved_message.data = NULL;
data->saved_message.length = 0; data->saved_message.length = 0;
} }
@ -1109,16 +1179,28 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
event.se_type = SCTP_SENDER_DRY_EVENT; event.se_type = SCTP_SENDER_DRY_EVENT;
event.se_on = 0; event.se_on = 0;
i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event)); i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(struct sctp_event));
OPENSSL_assert(i >= 0); if (i < 0)
{
ret = i;
break;
}
#else #else
eventsize = sizeof(struct sctp_event_subscribe); eventsize = sizeof(struct sctp_event_subscribe);
i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
OPENSSL_assert(i >= 0); if (i < 0)
{
ret = i;
break;
}
event.sctp_sender_dry_event = 0; event.sctp_sender_dry_event = 0;
i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
OPENSSL_assert(i >= 0); if (i < 0)
{
ret = i;
break;
}
#endif #endif
} }
@ -1151,8 +1233,8 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
*/ */
optlen = (socklen_t) sizeof(int); optlen = (socklen_t) sizeof(int);
ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen); ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
OPENSSL_assert(ret >= 0); if (ret >= 0)
OPENSSL_assert(optval >= 18445); OPENSSL_assert(optval >= 18445);
/* Test if SCTP doesn't partially deliver below /* Test if SCTP doesn't partially deliver below
* max record size (2^14 + 2048 + 13) * max record size (2^14 + 2048 + 13)
@ -1160,8 +1242,8 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
optlen = (socklen_t) sizeof(int); optlen = (socklen_t) sizeof(int);
ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
&optval, &optlen); &optval, &optlen);
OPENSSL_assert(ret >= 0); if (ret >= 0)
OPENSSL_assert(optval >= 18445); OPENSSL_assert(optval >= 18445);
/* Partially delivered notification??? Probably a bug.... */ /* Partially delivered notification??? Probably a bug.... */
OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION)); OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
@ -1195,15 +1277,15 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
authchunks = OPENSSL_malloc(optlen); authchunks = OPENSSL_malloc(optlen);
memset(authchunks, 0, sizeof(optlen)); memset(authchunks, 0, sizeof(optlen));
ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, authchunks, &optlen); ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, authchunks, &optlen);
OPENSSL_assert(ii >= 0);
for (p = (unsigned char*) authchunks->gauth_chunks; if (ii >= 0)
p < (unsigned char*) authchunks + optlen; for (p = (unsigned char*) authchunks->gauth_chunks;
p += sizeof(uint8_t)) p < (unsigned char*) authchunks + optlen;
{ p += sizeof(uint8_t))
if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1; {
if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1; if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1;
} if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1;
}
OPENSSL_free(authchunks); OPENSSL_free(authchunks);
@ -1258,9 +1340,11 @@ static int dgram_sctp_write(BIO *b, const char *in, int inl)
if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b)) if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b))
{ {
data->saved_message.bio = b; data->saved_message.bio = b;
data->saved_message.length = inl; if (data->saved_message.data)
OPENSSL_free(data->saved_message.data);
data->saved_message.data = OPENSSL_malloc(inl); data->saved_message.data = OPENSSL_malloc(inl);
memcpy(data->saved_message.data, in, inl); memcpy(data->saved_message.data, in, inl);
data->saved_message.length = inl;
return inl; return inl;
} }
@ -1367,6 +1451,10 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
* Returns always 1. * Returns always 1.
*/ */
break; break;
case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
/* We allow transport protocol fragmentation so this is irrelevant */
ret = 0;
break;
case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE: case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
if (num > 0) if (num > 0)
data->in_handshake = 1; data->in_handshake = 1;

View File

@ -1872,6 +1872,41 @@ ___
($a_4,$a_5,$a_6,$a_7)=($b_0,$b_1,$b_2,$b_3); ($a_4,$a_5,$a_6,$a_7)=($b_0,$b_1,$b_2,$b_3);
sub add_c2 () {
my ($hi,$lo,$c0,$c1,$c2,
$warm, # !$warm denotes first call with specific sequence of
# $c_[XYZ] when there is no Z-carry to accumulate yet;
$an,$bn # these two are arguments for multiplication which
# result is used in *next* step [which is why it's
# commented as "forward multiplication" below];
)=@_;
$code.=<<___;
mflo $lo
mfhi $hi
$ADDU $c0,$lo
sltu $at,$c0,$lo
$MULTU $an,$bn # forward multiplication
$ADDU $c0,$lo
$ADDU $at,$hi
sltu $lo,$c0,$lo
$ADDU $c1,$at
$ADDU $hi,$lo
___
$code.=<<___ if (!$warm);
sltu $c2,$c1,$at
$ADDU $c1,$hi
sltu $hi,$c1,$hi
$ADDU $c2,$hi
___
$code.=<<___ if ($warm);
sltu $at,$c1,$at
$ADDU $c1,$hi
$ADDU $c2,$at
sltu $hi,$c1,$hi
$ADDU $c2,$hi
___
}
$code.=<<___; $code.=<<___;
.align 5 .align 5
@ -1920,21 +1955,10 @@ $code.=<<___;
sltu $at,$c_2,$t_1 sltu $at,$c_2,$t_1
$ADDU $c_3,$t_2,$at $ADDU $c_3,$t_2,$at
$ST $c_2,$BNSZ($a0) $ST $c_2,$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
mfhi $t_2 $a_1,$a_1); # mul_add_c(a[1],b[1],c3,c1,c2);
slt $c_2,$t_2,$zero $code.=<<___;
$SLL $t_2,1
$MULTU $a_1,$a_1 # mul_add_c(a[1],b[1],c3,c1,c2);
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_3,$t_1
sltu $at,$c_3,$t_1
$ADDU $t_2,$at
$ADDU $c_1,$t_2
sltu $at,$c_1,$t_2
$ADDU $c_2,$at
mflo $t_1 mflo $t_1
mfhi $t_2 mfhi $t_2
$ADDU $c_3,$t_1 $ADDU $c_3,$t_1
@ -1945,67 +1969,19 @@ $code.=<<___;
sltu $at,$c_1,$t_2 sltu $at,$c_1,$t_2
$ADDU $c_2,$at $ADDU $c_2,$at
$ST $c_3,2*$BNSZ($a0) $ST $c_3,2*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
mfhi $t_2 $a_1,$a_2); # mul_add_c2(a[1],b[2],c1,c2,c3);
slt $c_3,$t_2,$zero &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
$SLL $t_2,1 $a_4,$a_0); # mul_add_c2(a[4],b[0],c2,c3,c1);
$MULTU $a_1,$a_2 # mul_add_c2(a[1],b[2],c1,c2,c3); $code.=<<___;
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_1,$t_1
sltu $at,$c_1,$t_1
$ADDU $t_2,$at
$ADDU $c_2,$t_2
sltu $at,$c_2,$t_2
$ADDU $c_3,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_3,$at
$MULTU $a_4,$a_0 # mul_add_c2(a[4],b[0],c2,c3,c1);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_1,$t_1
sltu $at,$c_1,$t_1
$ADDU $t_2,$at
$ADDU $c_2,$t_2
sltu $at,$c_2,$t_2
$ADDU $c_3,$at
$ST $c_1,3*$BNSZ($a0) $ST $c_1,3*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
mfhi $t_2 $a_3,$a_1); # mul_add_c2(a[3],b[1],c2,c3,c1);
slt $c_1,$t_2,$zero &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
$SLL $t_2,1 $a_2,$a_2); # mul_add_c(a[2],b[2],c2,c3,c1);
$MULTU $a_3,$a_1 # mul_add_c2(a[3],b[1],c2,c3,c1); $code.=<<___;
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_2,$t_1
sltu $at,$c_2,$t_1
$ADDU $t_2,$at
$ADDU $c_3,$t_2
sltu $at,$c_3,$t_2
$ADDU $c_1,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_1,$at
$MULTU $a_2,$a_2 # mul_add_c(a[2],b[2],c2,c3,c1);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_2,$t_1
sltu $at,$c_2,$t_1
$ADDU $t_2,$at
$ADDU $c_3,$t_2
sltu $at,$c_3,$t_2
$ADDU $c_1,$at
mflo $t_1 mflo $t_1
mfhi $t_2 mfhi $t_2
$ADDU $c_2,$t_1 $ADDU $c_2,$t_1
@ -2016,97 +1992,23 @@ $code.=<<___;
sltu $at,$c_3,$t_2 sltu $at,$c_3,$t_2
$ADDU $c_1,$at $ADDU $c_1,$at
$ST $c_2,4*$BNSZ($a0) $ST $c_2,4*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
mfhi $t_2 $a_1,$a_4); # mul_add_c2(a[1],b[4],c3,c1,c2);
slt $c_2,$t_2,$zero &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
$SLL $t_2,1 $a_2,$a_3); # mul_add_c2(a[2],b[3],c3,c1,c2);
$MULTU $a_1,$a_4 # mul_add_c2(a[1],b[4],c3,c1,c2); &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
slt $a2,$t_1,$zero $a_6,$a_0); # mul_add_c2(a[6],b[0],c1,c2,c3);
$ADDU $t_2,$a2 $code.=<<___;
$SLL $t_1,1
$ADDU $c_3,$t_1
sltu $at,$c_3,$t_1
$ADDU $t_2,$at
$ADDU $c_1,$t_2
sltu $at,$c_1,$t_2
$ADDU $c_2,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_2,$at
$MULTU $a_2,$a_3 # mul_add_c2(a[2],b[3],c3,c1,c2);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_3,$t_1
sltu $at,$c_3,$t_1
$ADDU $t_2,$at
$ADDU $c_1,$t_2
sltu $at,$c_1,$t_2
$ADDU $c_2,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$MULTU $a_6,$a_0 # mul_add_c2(a[6],b[0],c1,c2,c3);
$ADDU $c_2,$at
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_3,$t_1
sltu $at,$c_3,$t_1
$ADDU $t_2,$at
$ADDU $c_1,$t_2
sltu $at,$c_1,$t_2
$ADDU $c_2,$at
$ST $c_3,5*$BNSZ($a0) $ST $c_3,5*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
mfhi $t_2 $a_5,$a_1); # mul_add_c2(a[5],b[1],c1,c2,c3);
slt $c_3,$t_2,$zero &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
$SLL $t_2,1 $a_4,$a_2); # mul_add_c2(a[4],b[2],c1,c2,c3);
$MULTU $a_5,$a_1 # mul_add_c2(a[5],b[1],c1,c2,c3); &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
slt $a2,$t_1,$zero $a_3,$a_3); # mul_add_c(a[3],b[3],c1,c2,c3);
$ADDU $t_2,$a2 $code.=<<___;
$SLL $t_1,1
$ADDU $c_1,$t_1
sltu $at,$c_1,$t_1
$ADDU $t_2,$at
$ADDU $c_2,$t_2
sltu $at,$c_2,$t_2
$ADDU $c_3,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_3,$at
$MULTU $a_4,$a_2 # mul_add_c2(a[4],b[2],c1,c2,c3);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_1,$t_1
sltu $at,$c_1,$t_1
$ADDU $t_2,$at
$ADDU $c_2,$t_2
sltu $at,$c_2,$t_2
$ADDU $c_3,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_3,$at
$MULTU $a_3,$a_3 # mul_add_c(a[3],b[3],c1,c2,c3);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_1,$t_1
sltu $at,$c_1,$t_1
$ADDU $t_2,$at
$ADDU $c_2,$t_2
sltu $at,$c_2,$t_2
$ADDU $c_3,$at
mflo $t_1 mflo $t_1
mfhi $t_2 mfhi $t_2
$ADDU $c_1,$t_1 $ADDU $c_1,$t_1
@ -2117,112 +2019,25 @@ $code.=<<___;
sltu $at,$c_2,$t_2 sltu $at,$c_2,$t_2
$ADDU $c_3,$at $ADDU $c_3,$at
$ST $c_1,6*$BNSZ($a0) $ST $c_1,6*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
mfhi $t_2 $a_1,$a_6); # mul_add_c2(a[1],b[6],c2,c3,c1);
slt $c_1,$t_2,$zero &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
$SLL $t_2,1 $a_2,$a_5); # mul_add_c2(a[2],b[5],c2,c3,c1);
$MULTU $a_1,$a_6 # mul_add_c2(a[1],b[6],c2,c3,c1); &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
slt $a2,$t_1,$zero $a_3,$a_4); # mul_add_c2(a[3],b[4],c2,c3,c1);
$ADDU $t_2,$a2 &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
$SLL $t_1,1 $a_7,$a_1); # mul_add_c2(a[7],b[1],c3,c1,c2);
$ADDU $c_2,$t_1 $code.=<<___;
sltu $at,$c_2,$t_1
$ADDU $t_2,$at
$ADDU $c_3,$t_2
sltu $at,$c_3,$t_2
$ADDU $c_1,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_1,$at
$MULTU $a_2,$a_5 # mul_add_c2(a[2],b[5],c2,c3,c1);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_2,$t_1
sltu $at,$c_2,$t_1
$ADDU $t_2,$at
$ADDU $c_3,$t_2
sltu $at,$c_3,$t_2
$ADDU $c_1,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_1,$at
$MULTU $a_3,$a_4 # mul_add_c2(a[3],b[4],c2,c3,c1);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_2,$t_1
sltu $at,$c_2,$t_1
$ADDU $t_2,$at
$ADDU $c_3,$t_2
sltu $at,$c_3,$t_2
$ADDU $c_1,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_1,$at
$MULTU $a_7,$a_1 # mul_add_c2(a[7],b[1],c3,c1,c2);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_2,$t_1
sltu $at,$c_2,$t_1
$ADDU $t_2,$at
$ADDU $c_3,$t_2
sltu $at,$c_3,$t_2
$ADDU $c_1,$at
$ST $c_2,7*$BNSZ($a0) $ST $c_2,7*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
mfhi $t_2 $a_6,$a_2); # mul_add_c2(a[6],b[2],c3,c1,c2);
slt $c_2,$t_2,$zero &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
$SLL $t_2,1 $a_5,$a_3); # mul_add_c2(a[5],b[3],c3,c1,c2);
$MULTU $a_6,$a_2 # mul_add_c2(a[6],b[2],c3,c1,c2); &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
slt $a2,$t_1,$zero $a_4,$a_4); # mul_add_c(a[4],b[4],c3,c1,c2);
$ADDU $t_2,$a2 $code.=<<___;
$SLL $t_1,1
$ADDU $c_3,$t_1
sltu $at,$c_3,$t_1
$ADDU $t_2,$at
$ADDU $c_1,$t_2
sltu $at,$c_1,$t_2
$ADDU $c_2,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_2,$at
$MULTU $a_5,$a_3 # mul_add_c2(a[5],b[3],c3,c1,c2);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_3,$t_1
sltu $at,$c_3,$t_1
$ADDU $t_2,$at
$ADDU $c_1,$t_2
sltu $at,$c_1,$t_2
$ADDU $c_2,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_2,$at
$MULTU $a_4,$a_4 # mul_add_c(a[4],b[4],c3,c1,c2);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_3,$t_1
sltu $at,$c_3,$t_1
$ADDU $t_2,$at
$ADDU $c_1,$t_2
sltu $at,$c_1,$t_2
$ADDU $c_2,$at
mflo $t_1 mflo $t_1
mfhi $t_2 mfhi $t_2
$ADDU $c_3,$t_1 $ADDU $c_3,$t_1
@ -2233,82 +2048,21 @@ $code.=<<___;
sltu $at,$c_1,$t_2 sltu $at,$c_1,$t_2
$ADDU $c_2,$at $ADDU $c_2,$at
$ST $c_3,8*$BNSZ($a0) $ST $c_3,8*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
mfhi $t_2 $a_3,$a_6); # mul_add_c2(a[3],b[6],c1,c2,c3);
slt $c_3,$t_2,$zero &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
$SLL $t_2,1 $a_4,$a_5); # mul_add_c2(a[4],b[5],c1,c2,c3);
$MULTU $a_3,$a_6 # mul_add_c2(a[3],b[6],c1,c2,c3); &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
slt $a2,$t_1,$zero $a_7,$a_3); # mul_add_c2(a[7],b[3],c2,c3,c1);
$ADDU $t_2,$a2 $code.=<<___;
$SLL $t_1,1
$ADDU $c_1,$t_1
sltu $at,$c_1,$t_1
$ADDU $t_2,$at
$ADDU $c_2,$t_2
sltu $at,$c_2,$t_2
$ADDU $c_3,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_3,$at
$MULTU $a_4,$a_5 # mul_add_c2(a[4],b[5],c1,c2,c3);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_1,$t_1
sltu $at,$c_1,$t_1
$ADDU $t_2,$at
$ADDU $c_2,$t_2
sltu $at,$c_2,$t_2
$ADDU $c_3,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_3,$at
$MULTU $a_7,$a_3 # mul_add_c2(a[7],b[3],c2,c3,c1);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_1,$t_1
sltu $at,$c_1,$t_1
$ADDU $t_2,$at
$ADDU $c_2,$t_2
sltu $at,$c_2,$t_2
$ADDU $c_3,$at
$ST $c_1,9*$BNSZ($a0) $ST $c_1,9*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
mfhi $t_2 $a_6,$a_4); # mul_add_c2(a[6],b[4],c2,c3,c1);
slt $c_1,$t_2,$zero &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
$SLL $t_2,1 $a_5,$a_5); # mul_add_c(a[5],b[5],c2,c3,c1);
$MULTU $a_6,$a_4 # mul_add_c2(a[6],b[4],c2,c3,c1); $code.=<<___;
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_2,$t_1
sltu $at,$c_2,$t_1
$ADDU $t_2,$at
$ADDU $c_3,$t_2
sltu $at,$c_3,$t_2
$ADDU $c_1,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_1,$at
$MULTU $a_5,$a_5 # mul_add_c(a[5],b[5],c2,c3,c1);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_2,$t_1
sltu $at,$c_2,$t_1
$ADDU $t_2,$at
$ADDU $c_3,$t_2
sltu $at,$c_3,$t_2
$ADDU $c_1,$at
mflo $t_1 mflo $t_1
mfhi $t_2 mfhi $t_2
$ADDU $c_2,$t_1 $ADDU $c_2,$t_1
@ -2319,52 +2073,17 @@ $code.=<<___;
sltu $at,$c_3,$t_2 sltu $at,$c_3,$t_2
$ADDU $c_1,$at $ADDU $c_1,$at
$ST $c_2,10*$BNSZ($a0) $ST $c_2,10*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
mfhi $t_2 $a_5,$a_6); # mul_add_c2(a[5],b[6],c3,c1,c2);
slt $c_2,$t_2,$zero &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
$SLL $t_2,1 $a_7,$a_5); # mul_add_c2(a[7],b[5],c1,c2,c3);
$MULTU $a_5,$a_6 # mul_add_c2(a[5],b[6],c3,c1,c2); $code.=<<___;
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_3,$t_1
sltu $at,$c_3,$t_1
$ADDU $t_2,$at
$ADDU $c_1,$t_2
sltu $at,$c_1,$t_2
$ADDU $c_2,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_2,$at
$MULTU $a_7,$a_5 # mul_add_c2(a[7],b[5],c1,c2,c3);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_3,$t_1
sltu $at,$c_3,$t_1
$ADDU $t_2,$at
$ADDU $c_1,$t_2
sltu $at,$c_1,$t_2
$ADDU $c_2,$at
$ST $c_3,11*$BNSZ($a0) $ST $c_3,11*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
mfhi $t_2 $a_6,$a_6); # mul_add_c(a[6],b[6],c1,c2,c3);
slt $c_3,$t_2,$zero $code.=<<___;
$SLL $t_2,1
$MULTU $a_6,$a_6 # mul_add_c(a[6],b[6],c1,c2,c3);
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_1,$t_1
sltu $at,$c_1,$t_1
$ADDU $t_2,$at
$ADDU $c_2,$t_2
sltu $at,$c_2,$t_2
$ADDU $c_3,$at
mflo $t_1 mflo $t_1
mfhi $t_2 mfhi $t_2
$ADDU $c_1,$t_1 $ADDU $c_1,$t_1
@ -2375,21 +2094,10 @@ $code.=<<___;
sltu $at,$c_2,$t_2 sltu $at,$c_2,$t_2
$ADDU $c_3,$at $ADDU $c_3,$at
$ST $c_1,12*$BNSZ($a0) $ST $c_1,12*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
mfhi $t_2 $a_7,$a_7); # mul_add_c(a[7],b[7],c3,c1,c2);
slt $c_1,$t_2,$zero $code.=<<___;
$SLL $t_2,1
$MULTU $a_7,$a_7 # mul_add_c(a[7],b[7],c3,c1,c2);
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_2,$t_1
sltu $at,$c_2,$t_1
$ADDU $t_2,$at
$ADDU $c_3,$t_2
sltu $at,$c_3,$t_2
$ADDU $c_1,$at
$ST $c_2,13*$BNSZ($a0) $ST $c_2,13*$BNSZ($a0)
mflo $t_1 mflo $t_1
@ -2457,21 +2165,10 @@ $code.=<<___;
sltu $at,$c_2,$t_1 sltu $at,$c_2,$t_1
$ADDU $c_3,$t_2,$at $ADDU $c_3,$t_2,$at
$ST $c_2,$BNSZ($a0) $ST $c_2,$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
mfhi $t_2 $a_1,$a_1); # mul_add_c(a[1],b[1],c3,c1,c2);
slt $c_2,$t_2,$zero $code.=<<___;
$SLL $t_2,1
$MULTU $a_1,$a_1 # mul_add_c(a[1],b[1],c3,c1,c2);
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_3,$t_1
sltu $at,$c_3,$t_1
$ADDU $t_2,$at
$ADDU $c_1,$t_2
sltu $at,$c_1,$t_2
$ADDU $c_2,$at
mflo $t_1 mflo $t_1
mfhi $t_2 mfhi $t_2
$ADDU $c_3,$t_1 $ADDU $c_3,$t_1
@ -2482,52 +2179,17 @@ $code.=<<___;
sltu $at,$c_1,$t_2 sltu $at,$c_1,$t_2
$ADDU $c_2,$at $ADDU $c_2,$at
$ST $c_3,2*$BNSZ($a0) $ST $c_3,2*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
mfhi $t_2 $a_1,$a_2); # mul_add_c2(a2[1],b[2],c1,c2,c3);
slt $c_3,$t_2,$zero &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
$SLL $t_2,1 $a_3,$a_1); # mul_add_c2(a[3],b[1],c2,c3,c1);
$MULTU $a_1,$a_2 # mul_add_c(a2[1],b[2],c1,c2,c3); $code.=<<___;
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_1,$t_1
sltu $at,$c_1,$t_1
$ADDU $t_2,$at
$ADDU $c_2,$t_2
sltu $at,$c_2,$t_2
$ADDU $c_3,$at
mflo $t_1
mfhi $t_2
slt $at,$t_2,$zero
$ADDU $c_3,$at
$MULTU $a_3,$a_1 # mul_add_c2(a[3],b[1],c2,c3,c1);
$SLL $t_2,1
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_1,$t_1
sltu $at,$c_1,$t_1
$ADDU $t_2,$at
$ADDU $c_2,$t_2
sltu $at,$c_2,$t_2
$ADDU $c_3,$at
$ST $c_1,3*$BNSZ($a0) $ST $c_1,3*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
mfhi $t_2 $a_2,$a_2); # mul_add_c(a[2],b[2],c2,c3,c1);
slt $c_1,$t_2,$zero $code.=<<___;
$SLL $t_2,1
$MULTU $a_2,$a_2 # mul_add_c(a[2],b[2],c2,c3,c1);
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_2,$t_1
sltu $at,$c_2,$t_1
$ADDU $t_2,$at
$ADDU $c_3,$t_2
sltu $at,$c_3,$t_2
$ADDU $c_1,$at
mflo $t_1 mflo $t_1
mfhi $t_2 mfhi $t_2
$ADDU $c_2,$t_1 $ADDU $c_2,$t_1
@ -2538,21 +2200,10 @@ $code.=<<___;
sltu $at,$c_3,$t_2 sltu $at,$c_3,$t_2
$ADDU $c_1,$at $ADDU $c_1,$at
$ST $c_2,4*$BNSZ($a0) $ST $c_2,4*$BNSZ($a0)
___
mflo $t_1 &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
mfhi $t_2 $a_3,$a_3); # mul_add_c(a[3],b[3],c1,c2,c3);
slt $c_2,$t_2,$zero $code.=<<___;
$SLL $t_2,1
$MULTU $a_3,$a_3 # mul_add_c(a[3],b[3],c1,c2,c3);
slt $a2,$t_1,$zero
$ADDU $t_2,$a2
$SLL $t_1,1
$ADDU $c_3,$t_1
sltu $at,$c_3,$t_1
$ADDU $t_2,$at
$ADDU $c_1,$t_2
sltu $at,$c_1,$t_2
$ADDU $c_2,$at
$ST $c_3,5*$BNSZ($a0) $ST $c_3,5*$BNSZ($a0)
mflo $t_1 mflo $t_1

File diff suppressed because it is too large Load Diff

View File

@ -273,6 +273,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */ /* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */ /* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
/*
* Keep in mind that carrying into high part of multiplication result
* can not overflow, because it cannot be all-ones.
*/
#if 0 #if 0
/* original macros are kept for reference purposes */ /* original macros are kept for reference purposes */
#define mul_add_c(a,b,c0,c1,c2) { \ #define mul_add_c(a,b,c0,c1,c2) { \
@ -287,10 +291,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
BN_ULONG ta=(a),tb=(b),t0; \ BN_ULONG ta=(a),tb=(b),t0; \
t1 = BN_UMULT_HIGH(ta,tb); \ t1 = BN_UMULT_HIGH(ta,tb); \
t0 = ta * tb; \ t0 = ta * tb; \
t2 = t1+t1; c2 += (t2<t1)?1:0; \ c0 += t0; t2 = t1+((c0<t0)?1:0);\
t1 = t0+t0; t2 += (t1<t0)?1:0; \
c0 += t1; t2 += (c0<t1)?1:0; \
c1 += t2; c2 += (c1<t2)?1:0; \ c1 += t2; c2 += (c1<t2)?1:0; \
c0 += t0; t1 += (c0<t0)?1:0; \
c1 += t1; c2 += (c1<t1)?1:0; \
} }
#else #else
#define mul_add_c(a,b,c0,c1,c2) do { \ #define mul_add_c(a,b,c0,c1,c2) do { \
@ -328,22 +332,14 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
: "=a"(t1),"=d"(t2) \ : "=a"(t1),"=d"(t2) \
: "a"(a),"m"(b) \ : "a"(a),"m"(b) \
: "cc"); \ : "cc"); \
asm ("addq %0,%0; adcq %2,%1" \ asm ("addq %3,%0; adcq %4,%1; adcq %5,%2" \
: "+d"(t2),"+r"(c2) \ : "+r"(c0),"+r"(c1),"+r"(c2) \
: "g"(0) \ : "r"(t1),"r"(t2),"g"(0) \
: "cc"); \ : "cc"); \
asm ("addq %0,%0; adcq %2,%1" \ asm ("addq %3,%0; adcq %4,%1; adcq %5,%2" \
: "+a"(t1),"+d"(t2) \ : "+r"(c0),"+r"(c1),"+r"(c2) \
: "g"(0) \ : "r"(t1),"r"(t2),"g"(0) \
: "cc"); \ : "cc"); \
asm ("addq %2,%0; adcq %3,%1" \
: "+r"(c0),"+d"(t2) \
: "a"(t1),"g"(0) \
: "cc"); \
asm ("addq %2,%0; adcq %3,%1" \
: "+r"(c1),"+r"(c2) \
: "d"(t2),"g"(0) \
: "cc"); \
} while (0) } while (0)
#endif #endif

View File

@ -780,7 +780,9 @@ int RAND_pseudo_bytes(unsigned char *buf,int num);
#define bn_wcheck_size(bn, words) \ #define bn_wcheck_size(bn, words) \
do { \ do { \
const BIGNUM *_bnum2 = (bn); \ const BIGNUM *_bnum2 = (bn); \
assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \ assert((words) <= (_bnum2)->dmax && (words) >= (_bnum2)->top); \
/* avoid unused variable warning with NDEBUG */ \
(void)(_bnum2); \
} while(0) } while(0)
#else /* !BN_DEBUG */ #else /* !BN_DEBUG */

View File

@ -438,6 +438,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */ /* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */ /* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
/*
* Keep in mind that carrying into high part of multiplication result
* can not overflow, because it cannot be all-ones.
*/
#ifdef BN_LLONG #ifdef BN_LLONG
#define mul_add_c(a,b,c0,c1,c2) \ #define mul_add_c(a,b,c0,c1,c2) \
t=(BN_ULLONG)a*b; \ t=(BN_ULLONG)a*b; \
@ -478,10 +482,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
#define mul_add_c2(a,b,c0,c1,c2) { \ #define mul_add_c2(a,b,c0,c1,c2) { \
BN_ULONG ta=(a),tb=(b),t0; \ BN_ULONG ta=(a),tb=(b),t0; \
BN_UMULT_LOHI(t0,t1,ta,tb); \ BN_UMULT_LOHI(t0,t1,ta,tb); \
t2 = t1+t1; c2 += (t2<t1)?1:0; \ c0 += t0; t2 = t1+((c0<t0)?1:0);\
t1 = t0+t0; t2 += (t1<t0)?1:0; \
c0 += t1; t2 += (c0<t1)?1:0; \
c1 += t2; c2 += (c1<t2)?1:0; \ c1 += t2; c2 += (c1<t2)?1:0; \
c0 += t0; t1 += (c0<t0)?1:0; \
c1 += t1; c2 += (c1<t1)?1:0; \
} }
#define sqr_add_c(a,i,c0,c1,c2) { \ #define sqr_add_c(a,i,c0,c1,c2) { \
@ -508,10 +512,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
BN_ULONG ta=(a),tb=(b),t0; \ BN_ULONG ta=(a),tb=(b),t0; \
t1 = BN_UMULT_HIGH(ta,tb); \ t1 = BN_UMULT_HIGH(ta,tb); \
t0 = ta * tb; \ t0 = ta * tb; \
t2 = t1+t1; c2 += (t2<t1)?1:0; \ c0 += t0; t2 = t1+((c0<t0)?1:0);\
t1 = t0+t0; t2 += (t1<t0)?1:0; \
c0 += t1; t2 += (c0<t1)?1:0; \
c1 += t2; c2 += (c1<t2)?1:0; \ c1 += t2; c2 += (c1<t2)?1:0; \
c0 += t0; t1 += (c0<t0)?1:0; \
c1 += t1; c2 += (c1<t1)?1:0; \
} }
#define sqr_add_c(a,i,c0,c1,c2) { \ #define sqr_add_c(a,i,c0,c1,c2) { \

View File

@ -158,7 +158,7 @@ static void ctxdbg(BN_CTX *ctx)
unsigned int bnidx = 0, fpidx = 0; unsigned int bnidx = 0, fpidx = 0;
BN_POOL_ITEM *item = ctx->pool.head; BN_POOL_ITEM *item = ctx->pool.head;
BN_STACK *stack = &ctx->stack; BN_STACK *stack = &ctx->stack;
fprintf(stderr,"(%08x): ", (unsigned int)ctx); fprintf(stderr,"(%16p): ", ctx);
while(bnidx < ctx->used) while(bnidx < ctx->used)
{ {
fprintf(stderr,"%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax); fprintf(stderr,"%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);

View File

@ -189,15 +189,17 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
int no_branch=0; int no_branch=0;
/* Invalid zero-padding would have particularly bad consequences /* Invalid zero-padding would have particularly bad consequences
* in the case of 'num', so don't just rely on bn_check_top() for this one * so don't just rely on bn_check_top() here
* (bn_check_top() works only for BN_DEBUG builds) */ * (bn_check_top() works only for BN_DEBUG builds) */
if (num->top > 0 && num->d[num->top - 1] == 0) if ((num->top > 0 && num->d[num->top - 1] == 0) ||
(divisor->top > 0 && divisor->d[divisor->top - 1] == 0))
{ {
BNerr(BN_F_BN_DIV,BN_R_NOT_INITIALIZED); BNerr(BN_F_BN_DIV,BN_R_NOT_INITIALIZED);
return 0; return 0;
} }
bn_check_top(num); bn_check_top(num);
bn_check_top(divisor);
if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0))
{ {
@ -207,7 +209,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
bn_check_top(dv); bn_check_top(dv);
bn_check_top(rm); bn_check_top(rm);
/* bn_check_top(num); */ /* 'num' has been checked already */ /* bn_check_top(num); */ /* 'num' has been checked already */
bn_check_top(divisor); /* bn_check_top(divisor); */ /* 'divisor' has been checked already */
if (BN_is_zero(divisor)) if (BN_is_zero(divisor))
{ {

View File

@ -107,6 +107,7 @@ int test_mod(BIO *bp,BN_CTX *ctx);
int test_mod_mul(BIO *bp,BN_CTX *ctx); int test_mod_mul(BIO *bp,BN_CTX *ctx);
int test_mod_exp(BIO *bp,BN_CTX *ctx); int test_mod_exp(BIO *bp,BN_CTX *ctx);
int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx); int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx);
int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx);
int test_exp(BIO *bp,BN_CTX *ctx); int test_exp(BIO *bp,BN_CTX *ctx);
int test_gf2m_add(BIO *bp); int test_gf2m_add(BIO *bp);
int test_gf2m_mod(BIO *bp); int test_gf2m_mod(BIO *bp);
@ -249,6 +250,7 @@ int main(int argc, char *argv[])
message(out,"BN_mod_exp_mont_consttime"); message(out,"BN_mod_exp_mont_consttime");
if (!test_mod_exp_mont_consttime(out,ctx)) goto err; if (!test_mod_exp_mont_consttime(out,ctx)) goto err;
if (!test_mod_exp_mont5(out,ctx)) goto err;
(void)BIO_flush(out); (void)BIO_flush(out);
message(out,"BN_exp"); message(out,"BN_exp");
@ -676,44 +678,98 @@ int test_mul(BIO *bp)
int test_sqr(BIO *bp, BN_CTX *ctx) int test_sqr(BIO *bp, BN_CTX *ctx)
{ {
BIGNUM a,c,d,e; BIGNUM *a,*c,*d,*e;
int i; int i, ret = 0;
BN_init(&a); a = BN_new();
BN_init(&c); c = BN_new();
BN_init(&d); d = BN_new();
BN_init(&e); e = BN_new();
if (a == NULL || c == NULL || d == NULL || e == NULL)
{
goto err;
}
for (i=0; i<num0; i++) for (i=0; i<num0; i++)
{ {
BN_bntest_rand(&a,40+i*10,0,0); BN_bntest_rand(a,40+i*10,0,0);
a.neg=rand_neg(); a->neg=rand_neg();
BN_sqr(&c,&a,ctx); BN_sqr(c,a,ctx);
if (bp != NULL) if (bp != NULL)
{ {
if (!results) if (!results)
{ {
BN_print(bp,&a); BN_print(bp,a);
BIO_puts(bp," * "); BIO_puts(bp," * ");
BN_print(bp,&a); BN_print(bp,a);
BIO_puts(bp," - "); BIO_puts(bp," - ");
} }
BN_print(bp,&c); BN_print(bp,c);
BIO_puts(bp,"\n"); BIO_puts(bp,"\n");
} }
BN_div(&d,&e,&c,&a,ctx); BN_div(d,e,c,a,ctx);
BN_sub(&d,&d,&a); BN_sub(d,d,a);
if(!BN_is_zero(&d) || !BN_is_zero(&e)) if(!BN_is_zero(d) || !BN_is_zero(e))
{ {
fprintf(stderr,"Square test failed!\n"); fprintf(stderr,"Square test failed!\n");
return 0; goto err;
} }
} }
BN_free(&a);
BN_free(&c); /* Regression test for a BN_sqr overflow bug. */
BN_free(&d); BN_hex2bn(&a,
BN_free(&e); "80000000000000008000000000000001FFFFFFFFFFFFFFFE0000000000000000");
return(1); BN_sqr(c, a, ctx);
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp," * ");
BN_print(bp,a);
BIO_puts(bp," - ");
}
BN_print(bp,c);
BIO_puts(bp,"\n");
}
BN_mul(d, a, a, ctx);
if (BN_cmp(c, d))
{
fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
"different results!\n");
goto err;
}
/* Regression test for a BN_sqr overflow bug. */
BN_hex2bn(&a,
"80000000000000000000000080000001FFFFFFFE000000000000000000000000");
BN_sqr(c, a, ctx);
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp," * ");
BN_print(bp,a);
BIO_puts(bp," - ");
}
BN_print(bp,c);
BIO_puts(bp,"\n");
}
BN_mul(d, a, a, ctx);
if (BN_cmp(c, d))
{
fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
"different results!\n");
goto err;
}
ret = 1;
err:
if (a != NULL) BN_free(a);
if (c != NULL) BN_free(c);
if (d != NULL) BN_free(d);
if (e != NULL) BN_free(e);
return ret;
} }
int test_mont(BIO *bp, BN_CTX *ctx) int test_mont(BIO *bp, BN_CTX *ctx)
@ -1012,6 +1068,80 @@ int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
return(1); return(1);
} }
/* Test constant-time modular exponentiation with 1024-bit inputs,
* which on x86_64 cause a different code branch to be taken.
*/
int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx)
{
BIGNUM *a,*p,*m,*d,*e;
BN_MONT_CTX *mont;
a=BN_new();
p=BN_new();
m=BN_new();
d=BN_new();
e=BN_new();
mont = BN_MONT_CTX_new();
BN_bntest_rand(m,1024,0,1); /* must be odd for montgomery */
/* Zero exponent */
BN_bntest_rand(a,1024,0,0);
BN_zero(p);
if(!BN_mod_exp_mont_consttime(d,a,p,m,ctx,NULL))
return 0;
if(!BN_is_one(d))
{
fprintf(stderr, "Modular exponentiation test failed!\n");
return 0;
}
/* Zero input */
BN_bntest_rand(p,1024,0,0);
BN_zero(a);
if(!BN_mod_exp_mont_consttime(d,a,p,m,ctx,NULL))
return 0;
if(!BN_is_zero(d))
{
fprintf(stderr, "Modular exponentiation test failed!\n");
return 0;
}
/* Craft an input whose Montgomery representation is 1,
* i.e., shorter than the modulus m, in order to test
* the const time precomputation scattering/gathering.
*/
BN_one(a);
BN_MONT_CTX_set(mont,m,ctx);
if(!BN_from_montgomery(e,a,mont,ctx))
return 0;
if(!BN_mod_exp_mont_consttime(d,e,p,m,ctx,NULL))
return 0;
if(!BN_mod_exp_simple(a,e,p,m,ctx))
return 0;
if(BN_cmp(a,d) != 0)
{
fprintf(stderr,"Modular exponentiation test failed!\n");
return 0;
}
/* Finally, some regular test vectors. */
BN_bntest_rand(e,1024,0,0);
if(!BN_mod_exp_mont_consttime(d,e,p,m,ctx,NULL))
return 0;
if(!BN_mod_exp_simple(a,e,p,m,ctx))
return 0;
if(BN_cmp(a,d) != 0)
{
fprintf(stderr,"Modular exponentiation test failed!\n");
return 0;
}
BN_free(a);
BN_free(p);
BN_free(m);
BN_free(d);
BN_free(e);
return(1);
}
int test_exp(BIO *bp, BN_CTX *ctx) int test_exp(BIO *bp, BN_CTX *ctx)
{ {
BIGNUM *a,*b,*d,*e,*one; BIGNUM *a,*b,*d,*e,*one;

View File

@ -129,17 +129,12 @@ static inline int constant_time_select_int(unsigned int mask, int a, int b);
static inline unsigned int constant_time_msb(unsigned int a) static inline unsigned int constant_time_msb(unsigned int a)
{ {
return (unsigned int)((int)(a) >> (sizeof(int) * 8 - 1)); return 0-(a >> (sizeof(a) * 8 - 1));
} }
static inline unsigned int constant_time_lt(unsigned int a, unsigned int b) static inline unsigned int constant_time_lt(unsigned int a, unsigned int b)
{ {
unsigned int lt; return constant_time_msb(a^((a^b)|((a-b)^b)));
/* Case 1: msb(a) == msb(b). a < b iff the MSB of a - b is set.*/
lt = ~(a ^ b) & (a - b);
/* Case 2: msb(a) != msb(b). a < b iff the MSB of b is set. */
lt |= ~a & b;
return constant_time_msb(lt);
} }
static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b) static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
@ -149,12 +144,7 @@ static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
static inline unsigned int constant_time_ge(unsigned int a, unsigned int b) static inline unsigned int constant_time_ge(unsigned int a, unsigned int b)
{ {
unsigned int ge; return ~constant_time_lt(a, b);
/* Case 1: msb(a) == msb(b). a >= b iff the MSB of a - b is not set.*/
ge = ~((a ^ b) | (a - b));
/* Case 2: msb(a) != msb(b). a >= b iff the MSB of a is set. */
ge |= a & ~b;
return constant_time_msb(ge);
} }
static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b) static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b)
@ -204,7 +194,7 @@ static inline unsigned char constant_time_select_8(unsigned char mask,
return (unsigned char)(constant_time_select(mask, a, b)); return (unsigned char)(constant_time_select(mask, a, b));
} }
inline int constant_time_select_int(unsigned int mask, int a, int b) static inline int constant_time_select_int(unsigned int mask, int a, int b)
{ {
return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b))); return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
} }

View File

@ -69,10 +69,7 @@ const char *SSLeay_version(int t)
if (t == SSLEAY_BUILT_ON) if (t == SSLEAY_BUILT_ON)
{ {
#ifdef DATE #ifdef DATE
static char buf[sizeof(DATE)+11]; return(DATE);
BIO_snprintf(buf,sizeof buf,"built on: %s",DATE);
return(buf);
#else #else
return("built on: date not available"); return("built on: date not available");
#endif #endif
@ -80,10 +77,7 @@ const char *SSLeay_version(int t)
if (t == SSLEAY_CFLAGS) if (t == SSLEAY_CFLAGS)
{ {
#ifdef CFLAGS #ifdef CFLAGS
static char buf[sizeof(CFLAGS)+11]; return(cflags);
BIO_snprintf(buf,sizeof buf,"compiler: %s",CFLAGS);
return(buf);
#else #else
return("compiler: information not available"); return("compiler: information not available");
#endif #endif
@ -91,10 +85,7 @@ const char *SSLeay_version(int t)
if (t == SSLEAY_PLATFORM) if (t == SSLEAY_PLATFORM)
{ {
#ifdef PLATFORM #ifdef PLATFORM
static char buf[sizeof(PLATFORM)+11]; return(PLATFORM);
BIO_snprintf(buf,sizeof buf,"platform: %s", PLATFORM);
return(buf);
#else #else
return("platform: information not available"); return("platform: information not available");
#endif #endif

View File

@ -176,13 +176,25 @@ int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
const unsigned char *sigbuf, int siglen, DSA *dsa) const unsigned char *sigbuf, int siglen, DSA *dsa)
{ {
DSA_SIG *s; DSA_SIG *s;
const unsigned char *p = sigbuf;
unsigned char *der = NULL;
int derlen = -1;
int ret=-1; int ret=-1;
s = DSA_SIG_new(); s = DSA_SIG_new();
if (s == NULL) return(ret); if (s == NULL) return(ret);
if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err; if (d2i_DSA_SIG(&s,&p,siglen) == NULL) goto err;
/* Ensure signature uses DER and doesn't have trailing garbage */
derlen = i2d_DSA_SIG(s, &der);
if (derlen != siglen || memcmp(sigbuf, der, derlen))
goto err;
ret=DSA_do_verify(dgst,dgst_len,s,dsa); ret=DSA_do_verify(dgst,dgst_len,s,dsa);
err: err:
if (derlen > 0)
{
OPENSSL_cleanse(der, derlen);
OPENSSL_free(der);
}
DSA_SIG_free(s); DSA_SIG_free(s);
return(ret); return(ret);
} }

View File

@ -60,10 +60,8 @@
that handle _GNU_SOURCE and other similar macros. Defining it later that handle _GNU_SOURCE and other similar macros. Defining it later
is simply too late, because those headers are protected from re- is simply too late, because those headers are protected from re-
inclusion. */ inclusion. */
#ifdef __linux #ifndef _GNU_SOURCE
# ifndef _GNU_SOURCE # define _GNU_SOURCE /* make sure dladdr is declared */
# define _GNU_SOURCE /* make sure dladdr is declared */
# endif
#endif #endif
#include <stdio.h> #include <stdio.h>

View File

@ -68,7 +68,7 @@
#include "ec_lcl.h" #include "ec_lcl.h"
static const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT; const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
/* functions for EC_GROUP objects */ /* functions for EC_GROUP objects */

View File

@ -445,15 +445,16 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]); wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
wNAF = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space for pivot */ wNAF = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space for pivot */
val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]); val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
/* Ensure wNAF is initialised in case we end up going to err */
if (wNAF) wNAF[0] = NULL; /* preliminary pivot */
if (!wsize || !wNAF_len || !wNAF || !val_sub) if (!wsize || !wNAF_len || !wNAF || !val_sub)
{ {
ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
goto err; goto err;
} }
wNAF[0] = NULL; /* preliminary pivot */
/* num_val will be the total number of temporarily precomputed points */ /* num_val will be the total number of temporarily precomputed points */
num_val = 0; num_val = 0;

View File

@ -167,6 +167,7 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
return ret; return ret;
} }
#ifndef OPENSSL_NO_ECDH
static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
{ {
int ret; int ret;
@ -200,6 +201,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
*keylen = ret; *keylen = ret;
return 1; return 1;
} }
#endif
static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{ {
@ -333,7 +335,11 @@ const EVP_PKEY_METHOD ec_pkey_meth =
0,0, 0,0,
0, 0,
#ifndef OPENSSL_NO_ECDH
pkey_ec_derive, pkey_ec_derive,
#else
0,
#endif
pkey_ec_ctrl, pkey_ec_ctrl,
pkey_ec_ctrl_str pkey_ec_ctrl_str

View File

@ -113,7 +113,6 @@ typedef u64 smallfelem[NLIMBS];
/* This is the value of the prime as four 64-bit words, little-endian. */ /* This is the value of the prime as four 64-bit words, little-endian. */
static const u64 kPrime[4] = { 0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul }; static const u64 kPrime[4] = { 0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul };
static const limb bottom32bits = 0xffffffff;
static const u64 bottom63bits = 0x7ffffffffffffffful; static const u64 bottom63bits = 0x7ffffffffffffffful;
/* bin32_to_felem takes a little-endian byte array and converts it into felem /* bin32_to_felem takes a little-endian byte array and converts it into felem

View File

@ -1366,7 +1366,7 @@ static const struct nistp_test_params nistp_tests_params[] =
}, },
}; };
void nistp_single_test(const struct nistp_test_params *test) static void nistp_single_test(const struct nistp_test_params *test)
{ {
BN_CTX *ctx; BN_CTX *ctx;
BIGNUM *p, *a, *b, *x, *y, *n, *m, *order; BIGNUM *p, *a, *b, *x, *y, *n, *m, *order;
@ -1469,7 +1469,7 @@ void nistp_single_test(const struct nistp_test_params *test)
BN_CTX_free(ctx); BN_CTX_free(ctx);
} }
void nistp_tests() static void nistp_tests()
{ {
unsigned i; unsigned i;

View File

@ -126,15 +126,16 @@ ecs_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
ecs_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h ecs_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
ecs_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h ecs_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
ecs_sign.o: ecs_locl.h ecs_sign.c ecs_sign.o: ecs_locl.h ecs_sign.c
ecs_vrf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ecs_vrf.o: ../../e_os.h ../../include/openssl/asn1.h
ecs_vrf.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h ecs_vrf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
ecs_vrf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h ecs_vrf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
ecs_vrf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h ecs_vrf.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
ecs_vrf.o: ../../include/openssl/engine.h ../../include/openssl/evp.h ecs_vrf.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
ecs_vrf.o: ../../include/openssl/err.h ../../include/openssl/evp.h
ecs_vrf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h ecs_vrf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
ecs_vrf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h ecs_vrf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
ecs_vrf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h ecs_vrf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ecs_vrf.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h ecs_vrf.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
ecs_vrf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h ecs_vrf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
ecs_vrf.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h ecs_vrf.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
ecs_vrf.o: ../../include/openssl/x509_vfy.h ecs_locl.h ecs_vrf.c ecs_vrf.o: ../../include/openssl/x509_vfy.h ../cryptlib.h ecs_locl.h ecs_vrf.c

View File

@ -57,6 +57,7 @@
*/ */
#include "ecs_locl.h" #include "ecs_locl.h"
#include "cryptlib.h"
#ifndef OPENSSL_NO_ENGINE #ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h> #include <openssl/engine.h>
#endif #endif
@ -84,13 +85,25 @@ int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
{ {
ECDSA_SIG *s; ECDSA_SIG *s;
const unsigned char *p = sigbuf;
unsigned char *der = NULL;
int derlen = -1;
int ret=-1; int ret=-1;
s = ECDSA_SIG_new(); s = ECDSA_SIG_new();
if (s == NULL) return(ret); if (s == NULL) return(ret);
if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err; if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) goto err;
/* Ensure signature uses DER and doesn't have trailing garbage */
derlen = i2d_ECDSA_SIG(s, &der);
if (derlen != sig_len || memcmp(sigbuf, der, derlen))
goto err;
ret=ECDSA_do_verify(dgst, dgst_len, s, eckey); ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
err: err:
if (derlen > 0)
{
OPENSSL_cleanse(der, derlen);
OPENSSL_free(der);
}
ECDSA_SIG_free(s); ECDSA_SIG_free(s);
return(ret); return(ret);
} }

View File

@ -114,9 +114,6 @@ static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
ENGINE_CMD_FLAG_NO_INPUT}, ENGINE_CMD_FLAG_NO_INPUT},
{0, NULL, NULL, 0} {0, NULL, NULL, 0}
}; };
static const ENGINE_CMD_DEFN dynamic_cmd_defns_empty[] = {
{0, NULL, NULL, 0}
};
/* Loading code stores state inside the ENGINE structure via the "ex_data" /* Loading code stores state inside the ENGINE structure via the "ex_data"
* element. We load all our state into a single structure and use that as a * element. We load all our state into a single structure and use that as a

View File

@ -383,7 +383,7 @@ evp_enc.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
evp_enc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h evp_enc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
evp_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h evp_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
evp_enc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h evp_enc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
evp_enc.o: ../constant_time_locl.h ../cryptlib.h evp_enc.c evp_locl.h evp_enc.o: ../cryptlib.h evp_enc.c evp_locl.h
evp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h evp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
evp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h evp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
evp_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h evp_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h

View File

@ -124,12 +124,11 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
{ {
int i; int i;
char *cp; fprintf(stderr,"des_ede_cbc_cipher(ctx=%p, buflen=%d)\n", ctx, ctx->buf_len);
printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", ctx, ctx->buf_len); fprintf(stderr,"\t iv= ");
printf("\t iv= ");
for(i=0;i<8;i++) for(i=0;i<8;i++)
printf("%02X",ctx->iv[i]); fprintf(stderr,"%02X",ctx->iv[i]);
printf("\n"); fprintf(stderr,"\n");
} }
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
while (inl>=EVP_MAXCHUNK) while (inl>=EVP_MAXCHUNK)
@ -260,11 +259,14 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
{ {
int i; int i;
printf("des_ede3_init_key(ctx=%lx)\n", ctx); fprintf(stderr,"des_ede3_init_key(ctx=%p)\n", ctx);
printf("\tKEY= "); fprintf(stderr,"\tKEY= ");
for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n"); for(i=0;i<24;i++) fprintf(stderr,"%02X",key[i]); fprintf(stderr,"\n");
printf("\t IV= "); if (iv)
for(i=0;i<8;i++) printf("%02X",iv[i]); printf("\n"); {
fprintf(stderr,"\t IV= ");
for(i=0;i<8;i++) fprintf(stderr,"%02X",iv[i]); fprintf(stderr,"\n");
}
} }
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */

View File

@ -67,7 +67,6 @@
#ifdef OPENSSL_FIPS #ifdef OPENSSL_FIPS
#include <openssl/fips.h> #include <openssl/fips.h>
#endif #endif
#include "constant_time_locl.h"
#include "evp_locl.h" #include "evp_locl.h"
#ifdef OPENSSL_FIPS #ifdef OPENSSL_FIPS
@ -501,21 +500,21 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{ {
unsigned int i, b; int i,n;
unsigned char pad, padding_good; unsigned int b;
*outl=0; *outl=0;
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
{ {
int ret = M_do_cipher(ctx, out, NULL, 0); i = M_do_cipher(ctx, out, NULL, 0);
if (ret < 0) if (i < 0)
return 0; return 0;
else else
*outl = ret; *outl = i;
return 1; return 1;
} }
b=(unsigned int)(ctx->cipher->block_size); b=ctx->cipher->block_size;
if (ctx->flags & EVP_CIPH_NO_PADDING) if (ctx->flags & EVP_CIPH_NO_PADDING)
{ {
if(ctx->buf_len) if(ctx->buf_len)
@ -534,34 +533,33 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
return(0); return(0);
} }
OPENSSL_assert(b <= sizeof ctx->final); OPENSSL_assert(b <= sizeof ctx->final);
pad=ctx->final[b-1];
padding_good = (unsigned char)(~constant_time_is_zero_8(pad));
padding_good &= constant_time_ge_8(b, pad);
for (i = 1; i < b; ++i)
{
unsigned char is_pad_index = constant_time_lt_8(i, pad);
unsigned char pad_byte_good = constant_time_eq_8(ctx->final[b-i-1], pad);
padding_good &= constant_time_select_8(is_pad_index, pad_byte_good, 0xff);
}
/* /*
* At least 1 byte is always padding, so we always write b - 1 * The following assumes that the ciphertext has been authenticated.
* bytes to avoid a timing leak. The caller is required to have |b| * Otherwise it provides a padding oracle.
* bytes space in |out| by the API contract.
*/ */
for (i = 0; i < b - 1; ++i) n=ctx->final[b-1];
out[i] = ctx->final[i] & padding_good; if (n == 0 || n > (int)b)
/* Safe cast: for a good padding, EVP_MAX_IV_LENGTH >= b >= pad */ {
*outl = padding_good & ((unsigned char)(b - pad)); EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
return padding_good & 1; return(0);
}
for (i=0; i<n; i++)
{
if (ctx->final[--b] != n)
{
EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
return(0);
}
}
n=ctx->cipher->block_size-n;
for (i=0; i<n; i++)
out[i]=ctx->final[i];
*outl=n;
} }
else else
{ *outl=0;
*outl = 0; return(1);
return 1;
}
} }
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)

View File

@ -225,8 +225,7 @@
#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
l|=(((unsigned long)(*((c)++)))<<16), \ l|=(((unsigned long)(*((c)++)))<<16), \
l|=(((unsigned long)(*((c)++)))<< 8), \ l|=(((unsigned long)(*((c)++)))<< 8), \
l|=(((unsigned long)(*((c)++))) ), \ l|=(((unsigned long)(*((c)++))) ) )
l)
#endif #endif
#ifndef HOST_l2c #ifndef HOST_l2c
#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
@ -262,8 +261,7 @@
#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
l|=(((unsigned long)(*((c)++)))<< 8), \ l|=(((unsigned long)(*((c)++)))<< 8), \
l|=(((unsigned long)(*((c)++)))<<16), \ l|=(((unsigned long)(*((c)++)))<<16), \
l|=(((unsigned long)(*((c)++)))<<24), \ l|=(((unsigned long)(*((c)++)))<<24) )
l)
#endif #endif
#ifndef HOST_l2c #ifndef HOST_l2c
#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \

View File

@ -255,10 +255,12 @@ void *CRYPTO_malloc_locked(int num, const char *file, int line)
if (num <= 0) return NULL; if (num <= 0) return NULL;
allow_customize = 0; if(allow_customize)
allow_customize = 0;
if (malloc_debug_func != NULL) if (malloc_debug_func != NULL)
{ {
allow_customize_debug = 0; if(allow_customize_debug)
allow_customize_debug = 0;
malloc_debug_func(NULL, num, file, line, 0); malloc_debug_func(NULL, num, file, line, 0);
} }
ret = malloc_locked_ex_func(num,file,line); ret = malloc_locked_ex_func(num,file,line);
@ -299,10 +301,12 @@ void *CRYPTO_malloc(int num, const char *file, int line)
if (num <= 0) return NULL; if (num <= 0) return NULL;
allow_customize = 0; if(allow_customize)
allow_customize = 0;
if (malloc_debug_func != NULL) if (malloc_debug_func != NULL)
{ {
allow_customize_debug = 0; if(allow_customize_debug)
allow_customize_debug = 0;
malloc_debug_func(NULL, num, file, line, 0); malloc_debug_func(NULL, num, file, line, 0);
} }
ret = malloc_ex_func(num,file,line); ret = malloc_ex_func(num,file,line);

View File

@ -43,9 +43,6 @@ static const nid_triple sigoid_srt[] =
static const nid_triple * const sigoid_srt_xref[] = static const nid_triple * const sigoid_srt_xref[] =
{ {
&sigoid_srt[29],
&sigoid_srt[17],
&sigoid_srt[18],
&sigoid_srt[0], &sigoid_srt[0],
&sigoid_srt[1], &sigoid_srt[1],
&sigoid_srt[7], &sigoid_srt[7],

View File

@ -90,7 +90,10 @@ EOF
foreach (@srt2) foreach (@srt2)
{ {
my $x = $xref_tbl{$_}[2]; my ($p1, $p2, $x) = @{$xref_tbl{$_}};
# If digest or signature algorithm is "undef" then the algorithm
# needs special handling and is excluded from the cross reference table.
next if $p1 eq "undef" || $p2 eq "undef";
print "\t\&sigoid_srt\[$x\],\n"; print "\t\&sigoid_srt\[$x\],\n";
} }

View File

@ -29,11 +29,11 @@ extern "C" {
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta) * major minor fix final patch/beta)
*/ */
#define OPENSSL_VERSION_NUMBER 0x100010afL #define OPENSSL_VERSION_NUMBER 0x100010bfL
#ifdef OPENSSL_FIPS #ifdef OPENSSL_FIPS
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1j-fips 15 Oct 2014" #define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1k-fips 8 Jan 2015"
#else #else
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1j-freebsd 15 Oct 2014" #define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1k-freebsd 8 Jan 2015"
#endif #endif
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT #define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT

View File

@ -64,7 +64,7 @@ if ($flavour =~ /64|n32/i) {
# #
###################################################################### ######################################################################
$big_endian=(`echo MIPSEL | $ENV{CC} -E -P -`=~/MIPSEL/)?1:0; $big_endian=(`echo MIPSEL | $ENV{CC} -E -`=~/MIPSEL/)?1:0 if ($ENV{CC});
for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); } for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); }
open STDOUT,">$output"; open STDOUT,">$output";

View File

@ -68,7 +68,7 @@ $pf = ($flavour =~ /nubi/i) ? $t0 : $t2;
# #
###################################################################### ######################################################################
$big_endian=(`echo MIPSEL | $ENV{CC} -E -P -`=~/MIPSEL/)?1:0; $big_endian=(`echo MIPSEL | $ENV{CC} -E -`=~/MIPSEL/)?1:0 if ($ENV{CC});
for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); } for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); }
open STDOUT,">$output"; open STDOUT,">$output";

View File

@ -977,7 +977,7 @@ TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time,
if (precision > 0) if (precision > 0)
{ {
/* Add fraction of seconds (leave space for dot and null). */ /* Add fraction of seconds (leave space for dot and null). */
BIO_snprintf(p, 2 + precision, ".%ld", usec); BIO_snprintf(p, 2 + precision, ".%06ld", usec);
/* We cannot use the snprintf return value, /* We cannot use the snprintf return value,
because it might have been truncated. */ because it might have been truncated. */
p += strlen(p); p += strlen(p);

View File

@ -768,6 +768,7 @@ int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval);
void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
X509_ALGOR *algor); X509_ALGOR *algor);
void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
X509_NAME *X509_NAME_dup(X509_NAME *xn); X509_NAME *X509_NAME_dup(X509_NAME *xn);
X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);

View File

@ -89,6 +89,8 @@ X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
{ {
X509_VERIFY_PARAM *param; X509_VERIFY_PARAM *param;
param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM)); param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
if (!param)
return NULL;
memset(param, 0, sizeof(X509_VERIFY_PARAM)); memset(param, 0, sizeof(X509_VERIFY_PARAM));
x509_verify_param_zero(param); x509_verify_param_zero(param);
return param; return param;

View File

@ -72,6 +72,8 @@
int X509_verify(X509 *a, EVP_PKEY *r) int X509_verify(X509 *a, EVP_PKEY *r)
{ {
if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
return 0;
return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg, return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
a->signature,a->cert_info,r)); a->signature,a->cert_info,r));
} }

View File

@ -3,22 +3,22 @@
1. Introduction 1. Introduction
How you handle certificates depend a great deal on what your role is. How you handle certificates depends a great deal on what your role is.
Your role can be one or several of: Your role can be one or several of:
- User of some client software - User of some client application
- User of some server software - User of some server application
- Certificate authority - Certificate authority
This file is for users who wish to get a certificate of their own. This file is for users who wish to get a certificate of their own.
Certificate authorities should read ca.txt. Certificate authorities should read https://www.openssl.org/docs/apps/ca.html.
In all the cases shown below, the standard configuration file, as In all the cases shown below, the standard configuration file, as
compiled into openssl, will be used. You may find it in /etc/, compiled into openssl, will be used. You may find it in /etc/,
/usr/local/ssl/ or somewhere else. The name is openssl.cnf, and /usr/local/ssl/ or somewhere else. By default the file is named
is better described in another HOWTO <config.txt?>. If you want to openssl.cnf and is described at https://www.openssl.org/docs/apps/config.html.
use a different configuration file, use the argument '-config {file}' You can specify a different configuration file using the
with the command shown below. '-config {file}' argument with the commands shown below.
2. Relationship with keys 2. Relationship with keys
@ -29,24 +29,26 @@ somewhere. With OpenSSL, public keys are easily derived from private
keys, so before you create a certificate or a certificate request, you keys, so before you create a certificate or a certificate request, you
need to create a private key. need to create a private key.
Private keys are generated with 'openssl genrsa' if you want a RSA Private keys are generated with 'openssl genrsa -out privkey.pem' if
private key, or 'openssl gendsa' if you want a DSA private key. you want a RSA private key, or if you want a DSA private key:
Further information on how to create private keys can be found in 'openssl dsaparam -out dsaparam.pem 2048; openssl gendsa -out privkey.pem dsaparam.pem'.
another HOWTO <keys.txt?>. The rest of this text assumes you have
a private key in the file privkey.pem. The private keys created by these commands are not passphrase protected;
it might or might not be the desirable thing. Further information on how to
create private keys can be found at https://www.openssl.org/docs/HOWTO/keys.txt.
The rest of this text assumes you have a private key in the file privkey.pem.
3. Creating a certificate request 3. Creating a certificate request
To create a certificate, you need to start with a certificate To create a certificate, you need to start with a certificate request
request (or, as some certificate authorities like to put (or, as some certificate authorities like to put it, "certificate
it, "certificate signing request", since that's exactly what they do, signing request", since that's exactly what they do, they sign it and
they sign it and give you the result back, thus making it authentic give you the result back, thus making it authentic according to their
according to their policies). A certificate request can then be sent policies). A certificate request is sent to a certificate authority
to a certificate authority to get it signed into a certificate, or if to get it signed into a certificate. You can also sign the certificate
you have your own certificate authority, you may sign it yourself, or yourself if you have your own certificate authority or create a
if you need a self-signed certificate (because you just want a test self-signed certificate (typically for testing purpose).
certificate or because you are setting up your own CA).
The certificate request is created like this: The certificate request is created like this:
@ -55,12 +57,14 @@ The certificate request is created like this:
Now, cert.csr can be sent to the certificate authority, if they can Now, cert.csr can be sent to the certificate authority, if they can
handle files in PEM format. If not, use the extra argument '-outform' handle files in PEM format. If not, use the extra argument '-outform'
followed by the keyword for the format to use (see another HOWTO followed by the keyword for the format to use (see another HOWTO
<formats.txt?>). In some cases, that isn't sufficient and you will <formats.txt?>). In some cases, -outform does not let you output the
have to be more creative. certificate request in the right format and you will have to use one
of the various other commands that are exposed by openssl (or get
creative and use a combination of tools).
When the certificate authority has then done the checks the need to The certificate authority performs various checks (according to their
do (and probably gotten payment from you), they will hand over your policies) and usually waits for payment from you. Once that is
new certificate to you. complete, they send you your new certificate.
Section 5 will tell you more on how to handle the certificate you Section 5 will tell you more on how to handle the certificate you
received. received.
@ -68,11 +72,12 @@ received.
4. Creating a self-signed test certificate 4. Creating a self-signed test certificate
If you don't want to deal with another certificate authority, or just You can create a self-signed certificate if you don't want to deal
want to create a test certificate for yourself. This is similar to with a certificate authority, or if you just want to create a test
creating a certificate request, but creates a certificate instead of certificate for yourself. This is similar to creating a certificate
a certificate request. This is NOT the recommended way to create a request, but creates a certificate instead of a certificate request.
CA certificate, see ca.txt. This is NOT the recommended way to create a CA certificate, see
https://www.openssl.org/docs/apps/ca.html.
openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095
@ -93,13 +98,13 @@ certificate and your key to various formats, most often also putting
them together into one file. The ways to do this is described in them together into one file. The ways to do this is described in
another HOWTO <formats.txt?>, I will just mention the simplest case. another HOWTO <formats.txt?>, I will just mention the simplest case.
In the case of a raw DER thing in PEM format, and assuming that's all In the case of a raw DER thing in PEM format, and assuming that's all
right for yor applications, simply concatenating the certificate and right for your applications, simply concatenating the certificate and
the key into a new file and using that one should be enough. With the key into a new file and using that one should be enough. With
some applications, you don't even have to do that. some applications, you don't even have to do that.
By now, you have your cetificate and your private key and can start By now, you have your certificate and your private key and can start
using the software that depend on it. using applications that depend on it.
-- --
Richard Levitte Richard Levitte

View File

@ -1,74 +1,69 @@
<DRAFT!>
HOWTO proxy certificates HOWTO proxy certificates
0. WARNING 0. WARNING
NONE OF THE CODE PRESENTED HERE HAVE BEEN CHECKED! They are just an NONE OF THE CODE PRESENTED HERE HAS BEEN CHECKED! The code is just examples to
example to show you how things can be done. There may be typos or show you how things could be done. There might be typos or type conflicts, and
type conflicts, and you will have to resolve them. you will have to resolve them.
1. Introduction 1. Introduction
Proxy certificates are defined in RFC 3820. They are really usual Proxy certificates are defined in RFC 3820. They are really usual certificates
certificates with the mandatory extension proxyCertInfo. with the mandatory extension proxyCertInfo.
Proxy certificates are issued by an End Entity (typically a user), Proxy certificates are issued by an End Entity (typically a user), either
either directly with the EE certificate as issuing certificate, or by directly with the EE certificate as issuing certificate, or by extension through
extension through an already issued proxy certificate.. They are used an already issued proxy certificate. Proxy certificates are used to extend
to extend rights to some other entity (a computer process, typically, rights to some other entity (a computer process, typically, or sometimes to the
or sometimes to the user itself), so it can perform operations in the user itself). This allows the entity to perform operations on behalf of the
name of the owner of the EE certificate. owner of the EE certificate.
See http://www.ietf.org/rfc/rfc3820.txt for more information. See http://www.ietf.org/rfc/rfc3820.txt for more information.
2. A warning about proxy certificates 2. A warning about proxy certificates
Noone seems to have tested proxy certificates with security in mind. No one seems to have tested proxy certificates with security in mind. To this
Basically, to this date, it seems that proxy certificates have only date, it seems that proxy certificates have only been used in a context highly
been used in a world that's highly aware of them. What would happen aware of them.
if an unsuspecting application is to validate a chain of certificates
that contains proxy certificates? It would usually consider the leaf
to be the certificate to check for authorisation data, and since proxy
certificates are controlled by the EE certificate owner alone, it's
would be normal to consider what the EE certificate owner could do
with them.
subjectAltName and issuerAltName are forbidden in proxy certificates, Existing applications might misbehave when trying to validate a chain of
and this is enforced in OpenSSL. The subject must be the same as the certificates which use a proxy certificate. They might incorrectly consider the
issuer, with one commonName added on. leaf to be the certificate to check for authorisation data, which is controlled
by the EE certificate owner.
Possible threats are, as far as has been imagined so far: subjectAltName and issuerAltName are forbidden in proxy certificates, and this
is enforced in OpenSSL. The subject must be the same as the issuer, with one
commonName added on.
Possible threats we can think of at this time include:
- impersonation through commonName (think server certificates). - impersonation through commonName (think server certificates).
- use of additional extensions, possibly non-standard ones used in - use of additional extensions, possibly non-standard ones used in certain
certain environments, that would grant extra or different environments, that would grant extra or different authorisation rights.
authorisation rights.
For this reason, OpenSSL requires that the use of proxy certificates For these reasons, OpenSSL requires that the use of proxy certificates be
be explicitely allowed. Currently, this can be done using the explicitly allowed. Currently, this can be done using the following methods:
following methods:
- if the application calls X509_verify_cert() itself, it can do the - if the application directly calls X509_verify_cert(), it can first call:
following prior to that call (ctx is the pointer passed in the call
to X509_verify_cert()):
X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS); X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
- in all other cases, proxy certificate validation can be enabled Where ctx is the pointer which then gets passed to X509_verify_cert().
before starting the application by setting the envirnoment variable
OPENSSL_ALLOW_PROXY_CERTS with some non-empty value.
There are thoughts to allow proxy certificates with a line in the - proxy certificate validation can be enabled before starting the application
default openssl.cnf, but that's still in the future. by setting the environment variable OPENSSL_ALLOW_PROXY_CERTS.
In the future, it might be possible to enable proxy certificates by editing
openssl.cnf.
3. How to create proxy cerificates 3. How to create proxy certificates
It's quite easy to create proxy certificates, by taking advantage of Creating proxy certificates is quite easy, by taking advantage of a lack of
the lack of checks of the 'openssl x509' application (*ahem*). But checks in the 'openssl x509' application (*ahem*). You must first create a
first, you need to create a configuration section that contains a configuration section that contains a definition of the proxyCertInfo extension,
definition of the proxyCertInfo extension, a little like this: for example:
[ v3_proxy ] [ v3_proxy ]
# A proxy certificate MUST NEVER be a CA certificate. # A proxy certificate MUST NEVER be a CA certificate.
@ -77,10 +72,10 @@ definition of the proxyCertInfo extension, a little like this:
# Usual authority key ID # Usual authority key ID
authorityKeyIdentifier=keyid,issuer:always authorityKeyIdentifier=keyid,issuer:always
# Now, for the extension that marks this certificate as a proxy one # The extension which marks this certificate as a proxy
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB
It's also possible to give the proxy extension in a separate section: It's also possible to specify the proxy extension in a separate section:
proxyCertInfo=critical,@proxy_ext proxyCertInfo=critical,@proxy_ext
@ -89,96 +84,85 @@ It's also possible to give the proxy extension in a separate section:
pathlen=0 pathlen=0
policy=text:BC policy=text:BC
The policy value has a specific syntax, {syntag}:{string}, where the The policy value has a specific syntax, {syntag}:{string}, where the syntag
syntag determines what will be done with the string. The recognised determines what will be done with the string. The following syntags are
syntags are as follows: recognised:
text indicates that the string is simply the bytes, not text indicates that the string is simply bytes, without any encoding:
encoded in any kind of way:
policy=text:räksmörgås policy=text:räksmörgås
Previous versions of this design had a specific tag Previous versions of this design had a specific tag for UTF-8 text.
for UTF-8 text. However, since the bytes are copied However, since the bytes are copied as-is anyway, there is no need for
as-is anyway, there's no need for it. Instead, use such a specific tag.
the text: tag, like this:
policy=text:räksmörgås hex indicates the string is encoded in hex, with colons between each byte
(every second hex digit):
hex indicates the string is encoded in hex, with colons policy=hex:72:E4:6B:73:6D:F6:72:67:E5:73
between each byte (every second hex digit):
policy=hex:72:E4:6B:73:6D:F6:72:67:E5:73 Previous versions of this design had a tag to insert a complete DER
blob. However, the only legal use for this would be to surround the
bytes that would go with the hex: tag with whatever is needed to
construct a correct OCTET STRING. The DER tag therefore felt
superfluous, and was removed.
Previous versions of this design had a tag to insert a file indicates that the text of the policy should really be taken from a
complete DER blob. However, the only legal use for file. The string is then really a file name. This is useful for
this would be to surround the bytes that would go with policies that are large (more than a few lines, e.g. XML documents).
the hex: tag with what's needed to construct a correct
OCTET STRING. Since hex: does that, the DER tag felt
superfluous, and was therefore removed.
file indicates that the text of the policy should really be
taken from a file. The string is then really a file
name. This is useful for policies that are large
(more than a few of lines) XML documents, for example.
The 'policy' setting can be split up in multiple lines like this: The 'policy' setting can be split up in multiple lines like this:
0.policy=This is 0.policy=This is
1.polisy= a multi- 1.policy= a multi-
2.policy=line policy. 2.policy=line policy.
NOTE: the proxy policy value is the part that determines the rights NOTE: the proxy policy value is the part which determines the rights granted to
granted to the process using the proxy certificate. The value is the process using the proxy certificate. The value is completely dependent on
completely dependent on the application reading and interpretting it! the application reading and interpreting it!
Now that you have created an extension section for your proxy Now that you have created an extension section for your proxy certificate, you
certificate, you can now easily create a proxy certificate like this: can easily create a proxy certificate by doing:
openssl req -new -config openssl.cnf \ openssl req -new -config openssl.cnf -out proxy.req -keyout proxy.key
-out proxy.req -keyout proxy.key openssl x509 -req -CAcreateserial -in proxy.req -days 7 -out proxy.crt \
openssl x509 -req -CAcreateserial -in proxy.req -days 7 \ -CA user.crt -CAkey user.key -extfile openssl.cnf -extensions v3_proxy
-out proxy.crt -CA user.crt -CAkey user.key \
-extfile openssl.cnf -extensions v3_proxy
It's just as easy to create a proxy certificate using another proxy You can also create a proxy certificate using another proxy certificate as
certificate as issuer (note that I'm using a different configuration issuer (note: I'm using a different configuration section for it):
section for it):
openssl req -new -config openssl.cnf \ openssl req -new -config openssl.cnf -out proxy2.req -keyout proxy2.key
-out proxy2.req -keyout proxy2.key openssl x509 -req -CAcreateserial -in proxy2.req -days 7 -out proxy2.crt \
openssl x509 -req -CAcreateserial -in proxy2.req -days 7 \ -CA proxy.crt -CAkey proxy.key -extfile openssl.cnf -extensions v3_proxy2
-out proxy2.crt -CA proxy.crt -CAkey proxy.key \
-extfile openssl.cnf -extensions v3_proxy2
4. How to have your application interpret the policy? 4. How to have your application interpret the policy?
The basic way to interpret proxy policies is to prepare some default The basic way to interpret proxy policies is to start with some default rights,
rights, then do a check of the proxy certificate against the a chain then compute the resulting rights by checking the proxy certificate against
of proxy certificates, user certificate and CA certificates, and see the chain of proxy certificates, user certificate and CA certificates. You then
what rights came out by the end. Sounds easy, huh? It almost is. use the final computed rights. Sounds easy, huh? It almost is.
The slightly complicated part is how to pass data between your The slightly complicated part is figuring out how to pass data between your
application and the certificate validation procedure. application and the certificate validation procedure.
You need the following ingredients: You need the following ingredients:
- a callback routing that will be called for every certificate that's - a callback function that will be called for every certificate being
validated. It will be called several times for each certificates, validated. The callback be called several times for each certificate,
so you must be attentive to when it's a good time to do the proxy so you must be careful to do the proxy policy interpretation at the right
policy interpretation and check, as well as to fill in the defaults time. You also need to fill in the defaults when the EE certificate is
when the EE certificate is checked. checked.
- a structure of data that's shared between your application code and - a data structure that is shared between your application code and the
the callback. callback.
- a wrapper function that sets it all up. - a wrapper function that sets it all up.
- an ex_data index function that creates an index into the generic - an ex_data index function that creates an index into the generic ex_data
ex_data store that's attached to an X509 validation context. store that is attached to an X509 validation context.
This is some cookbook code for you to fill in: Here is some skeleton code you can fill in:
/* In this example, I will use a view of granted rights as a bit /* In this example, I will use a view of granted rights as a bit
array, one bit for each possible right. */ array, one bit for each possible right. */
@ -210,7 +194,7 @@ This is some cookbook code for you to fill in:
static int verify_callback(int ok, X509_STORE_CTX *ctx) static int verify_callback(int ok, X509_STORE_CTX *ctx)
{ {
if (ok == 1) /* It's REALLY important you keep the proxy policy if (ok == 1) /* It's REALLY important you keep the proxy policy
check within this secion. It's important to know check within this section. It's important to know
that when ok is 1, the certificates are checked that when ok is 1, the certificates are checked
from top to bottom. You get the CA root first, from top to bottom. You get the CA root first,
followed by the possible chain of intermediate followed by the possible chain of intermediate
@ -221,7 +205,7 @@ This is some cookbook code for you to fill in:
if (xs->ex_flags & EXFLAG_PROXY) if (xs->ex_flags & EXFLAG_PROXY)
{ {
YOUR_RIGHTS *rights = YOUR_RIGHTS *rights =
(YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx, (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx,
get_proxy_auth_ex_data_idx()); get_proxy_auth_ex_data_idx());
PROXY_CERT_INFO_EXTENSION *pci = PROXY_CERT_INFO_EXTENSION *pci =
@ -250,12 +234,12 @@ This is some cookbook code for you to fill in:
bit array and fill it with the rights granted by bit array and fill it with the rights granted by
the current proxy certificate, then use it as a the current proxy certificate, then use it as a
mask on the accumulated rights bit array, and mask on the accumulated rights bit array, and
voilà, you now have a new accumulated rights bit voilà, you now have a new accumulated rights bit
array. */ array. */
{ {
int i; int i;
YOUR_RIGHTS tmp_rights; YOUR_RIGHTS tmp_rights;
memset(tmp_rights.rights, 0, sizeof(tmp_rights.rights)); memset(tmp_rights.rights, 0, sizeof(tmp_rights.rights));
/* process_rights() is supposed to be a procedure /* process_rights() is supposed to be a procedure
that takes a string and it's length, interprets that takes a string and it's length, interprets
@ -276,7 +260,7 @@ This is some cookbook code for you to fill in:
{ {
/* We have a EE certificate, let's use it to set default! /* We have a EE certificate, let's use it to set default!
*/ */
YOUR_RIGHTS *rights = YOUR_RIGHTS *rights =
(YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx, (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx,
get_proxy_auth_ex_data_idx()); get_proxy_auth_ex_data_idx());

View File

@ -13,6 +13,8 @@ B<openssl> B<dgst>
[B<-hex>] [B<-hex>]
[B<-binary>] [B<-binary>]
[B<-r>] [B<-r>]
[B<-hmac arg>]
[B<-non-fips-allow>]
[B<-out filename>] [B<-out filename>]
[B<-sign filename>] [B<-sign filename>]
[B<-keyform arg>] [B<-keyform arg>]
@ -62,6 +64,15 @@ output the digest or signature in binary form.
output the digest in the "coreutils" format used by programs like B<sha1sum>. output the digest in the "coreutils" format used by programs like B<sha1sum>.
=item B<-hmac arg>
set the HMAC key to "arg".
=item B<-non-fips-allow>
Allow use of non FIPS digest when in FIPS mode. This has no effect when not in
FIPS mode.
=item B<-out filename> =item B<-out filename>
filename to output to, or standard output by default. filename to output to, or standard output by default.

View File

@ -133,6 +133,10 @@ if the B<host> option is present then the OCSP request is sent to the host
B<hostname> on port B<port>. B<path> specifies the HTTP path name to use B<hostname> on port B<port>. B<path> specifies the HTTP path name to use
or "/" by default. or "/" by default.
=item B<-timeout seconds>
connection timeout to the OCSP responder in seconds
=item B<-CAfile file>, B<-CApath pathname> =item B<-CAfile file>, B<-CApath pathname>
file or pathname containing trusted CA certificates. These are used to verify file or pathname containing trusted CA certificates. These are used to verify

View File

@ -115,7 +115,7 @@ writes the encrypted version to B<out>. This function can be called
multiple times to encrypt successive blocks of data. The amount multiple times to encrypt successive blocks of data. The amount
of data written depends on the block alignment of the encrypted data: of data written depends on the block alignment of the encrypted data:
as a result the amount of data written may be anything from zero bytes as a result the amount of data written may be anything from zero bytes
to (inl + cipher_block_size - 1) so B<outl> should contain sufficient to (inl + cipher_block_size - 1) so B<out> should contain sufficient
room. The actual number of bytes written is placed in B<outl>. room. The actual number of bytes written is placed in B<outl>.
If padding is enabled (the default) then EVP_EncryptFinal_ex() encrypts If padding is enabled (the default) then EVP_EncryptFinal_ex() encrypts

View File

@ -43,19 +43,23 @@ indicates the operation is not supported by the public key algorithm.
=head1 EXAMPLE =head1 EXAMPLE
Encrypt data using OAEP (for RSA keys): Encrypt data using OAEP (for RSA keys). See also L<PEM_read_PUBKEY(3)|pem(3)> or
L<d2i_X509(3)|d2i_X509(3)> for means to load a public key. You may also simply
set 'eng = NULL;' to start with the default OpenSSL RSA implementation:
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/rsa.h> #include <openssl/rsa.h>
#include <openssl/engine.h>
EVP_PKEY_CTX *ctx; EVP_PKEY_CTX *ctx;
ENGINE *eng;
unsigned char *out, *in; unsigned char *out, *in;
size_t outlen, inlen; size_t outlen, inlen;
EVP_PKEY *key; EVP_PKEY *key;
/* NB: assumes key in, inlen are already set up /* NB: assumes eng, key, in, inlen are already set up,
* and that key is an RSA public key * and that key is an RSA public key
*/ */
ctx = EVP_PKEY_CTX_new(key); ctx = EVP_PKEY_CTX_new(key,eng);
if (!ctx) if (!ctx)
/* Error occurred */ /* Error occurred */
if (EVP_PKEY_encrypt_init(ctx) <= 0) if (EVP_PKEY_encrypt_init(ctx) <= 0)
@ -79,6 +83,8 @@ Encrypt data using OAEP (for RSA keys):
=head1 SEE ALSO =head1 SEE ALSO
L<d2i_X509(3)|d2i_X509(3)>,
L<engine(3)|engine(3)>,
L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>, L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>, L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>, L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,

View File

@ -81,14 +81,14 @@ Create an B<X509_NAME> structure:
nm = X509_NAME_new(); nm = X509_NAME_new();
if (nm == NULL) if (nm == NULL)
/* Some error */ /* Some error */
if (!X509_NAME_add_entry_by_txt(nm, MBSTRING_ASC, if (!X509_NAME_add_entry_by_txt(nm, "C", MBSTRING_ASC,
"C", "UK", -1, -1, 0)) "UK", -1, -1, 0))
/* Error */ /* Error */
if (!X509_NAME_add_entry_by_txt(nm, MBSTRING_ASC, if (!X509_NAME_add_entry_by_txt(nm, "O", MBSTRING_ASC,
"O", "Disorganized Organization", -1, -1, 0)) "Disorganized Organization", -1, -1, 0))
/* Error */ /* Error */
if (!X509_NAME_add_entry_by_txt(nm, MBSTRING_ASC, if (!X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC,
"CN", "Joe Bloggs", -1, -1, 0)) "Joe Bloggs", -1, -1, 0))
/* Error */ /* Error */
=head1 RETURN VALUES =head1 RETURN VALUES

View File

@ -59,6 +59,10 @@ X509_NAME_get_index_by_OBJ() should be used followed by
X509_NAME_get_entry() on any matching indices and then the X509_NAME_get_entry() on any matching indices and then the
various B<X509_NAME_ENTRY> utility functions on the result. various B<X509_NAME_ENTRY> utility functions on the result.
The list of all relevant B<NID_*> and B<OBJ_* codes> can be found in
the source code header files E<lt>openssl/obj_mac.hE<gt> and/or
E<lt>openssl/objects.hE<gt>.
=head1 EXAMPLES =head1 EXAMPLES
Process all entries: Process all entries:

View File

@ -71,6 +71,16 @@ SSL_CTX->freelist_max_len, which defaults to 32. Using this flag can
save around 34k per idle SSL connection. save around 34k per idle SSL connection.
This flag has no effect on SSL v2 connections, or on DTLS connections. This flag has no effect on SSL v2 connections, or on DTLS connections.
=item SSL_MODE_SEND_FALLBACK_SCSV
Send TLS_FALLBACK_SCSV in the ClientHello.
To be set only by applications that reconnect with a downgraded protocol
version; see draft-ietf-tls-downgrade-scsv-00 for details.
DO NOT ENABLE THIS if your application attempts a normal handshake.
Only use this in explicit fallback retries, following the guidance
in draft-ietf-tls-downgrade-scsv-00.
=back =back
=head1 RETURN VALUES =head1 RETURN VALUES

View File

@ -158,15 +158,7 @@ temporary/ephemeral DH parameters are used.
=item SSL_OP_EPHEMERAL_RSA =item SSL_OP_EPHEMERAL_RSA
Always use ephemeral (temporary) RSA key when doing RSA operations This option is no longer implemented and is treated as no op.
(see L<SSL_CTX_set_tmp_rsa_callback(3)|SSL_CTX_set_tmp_rsa_callback(3)>).
According to the specifications this is only done, when a RSA key
can only be used for signature operations (namely under export ciphers
with restricted RSA keylength). By setting this option, ephemeral
RSA keys are always used. This option breaks compatibility with the
SSL/TLS specifications and may lead to interoperability problems with
clients and should therefore never be used. Ciphers with EDH (ephemeral
Diffie-Hellman) key exchange should be used instead.
=item SSL_OP_CIPHER_SERVER_PREFERENCE =item SSL_OP_CIPHER_SERVER_PREFERENCE

View File

@ -74,21 +74,14 @@ exchange and use EDH (Ephemeral Diffie-Hellman) key exchange instead
in order to achieve forward secrecy (see in order to achieve forward secrecy (see
L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>). L<SSL_CTX_set_tmp_dh_callback(3)|SSL_CTX_set_tmp_dh_callback(3)>).
On OpenSSL servers ephemeral RSA key exchange is therefore disabled by default An application may either directly specify the key or can supply the key via a
and must be explicitly enabled using the SSL_OP_EPHEMERAL_RSA option of callback function. The callback approach has the advantage, that the callback
L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>, violating the TLS/SSL may generate the key only in case it is actually needed. As the generation of a
standard. When ephemeral RSA key exchange is required for export ciphers, RSA key is however costly, it will lead to a significant delay in the handshake
it will automatically be used without this option! procedure. Another advantage of the callback function is that it can supply
keys of different size while the explicit setting of the key is only useful for
An application may either directly specify the key or can supply the key via key size of 512 bits to satisfy the export restricted ciphers and does give
a callback function. The callback approach has the advantage, that the away key length if a longer key would be allowed.
callback may generate the key only in case it is actually needed. As the
generation of a RSA key is however costly, it will lead to a significant
delay in the handshake procedure. Another advantage of the callback function
is that it can supply keys of different size (e.g. for SSL_OP_EPHEMERAL_RSA
usage) while the explicit setting of the key is only useful for key size of
512 bits to satisfy the export restricted ciphers and does give away key length
if a longer key would be allowed.
The B<tmp_rsa_callback> is called with the B<keylength> needed and The B<tmp_rsa_callback> is called with the B<keylength> needed and
the B<is_export> information. The B<is_export> flag is set, when the the B<is_export> information. The B<is_export> flag is set, when the

View File

@ -290,7 +290,7 @@ extern "C" {
# ifdef _WIN64 # ifdef _WIN64
# define strlen(s) _strlen31(s) # define strlen(s) _strlen31(s)
/* cut strings to 2GB */ /* cut strings to 2GB */
static unsigned int _strlen31(const char *str) static __inline unsigned int _strlen31(const char *str)
{ {
unsigned int len=0; unsigned int len=0;
while (*str && len<0x80000000U) str++, len++; while (*str && len<0x80000000U) str++, len++;
@ -375,15 +375,6 @@ static unsigned int _strlen31(const char *str)
# define check_winnt() (GetVersion() < 0x80000000) # define check_winnt() (GetVersion() < 0x80000000)
#endif #endif
/*
* Visual Studio: inline is available in C++ only, however
* __inline is available for C, see
* http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
*/
#if defined(_MSC_VER) && !defined(__cplusplus) && !defined(inline)
# define inline __inline
#endif
#else /* The non-microsoft world */ #else /* The non-microsoft world */
# ifdef OPENSSL_SYS_VMS # ifdef OPENSSL_SYS_VMS
@ -741,6 +732,22 @@ struct servent *getservbyname(const char *name, const char *proto);
#include <OS.h> #include <OS.h>
#endif #endif
#if !defined(inline) && !defined(__cplusplus)
# if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
/* do nothing, inline works */
# elif defined(__GNUC__) && __GNUC__>=2
# define inline __inline__
# elif defined(_MSC_VER)
/*
* Visual Studio: inline is available in C++ only, however
* __inline is available for C, see
* http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
*/
# define inline __inline
# else
# define inline
# endif
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -384,6 +384,7 @@ padlock_available(void)
} }
#ifndef OPENSSL_NO_AES #ifndef OPENSSL_NO_AES
#ifndef AES_ASM
/* Our own htonl()/ntohl() */ /* Our own htonl()/ntohl() */
static inline void static inline void
padlock_bswapl(AES_KEY *ks) padlock_bswapl(AES_KEY *ks)
@ -397,6 +398,7 @@ padlock_bswapl(AES_KEY *ks)
} }
} }
#endif #endif
#endif
/* Force key reload from memory to the CPU microcode. /* Force key reload from memory to the CPU microcode.
Loading EFLAGS from the stack clears EFLAGS[30] Loading EFLAGS from the stack clears EFLAGS[30]

View File

@ -156,9 +156,8 @@ static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe
static unsigned char bitmask_end_values[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}; static unsigned char bitmask_end_values[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
/* XDTLS: figure out the right values */ /* XDTLS: figure out the right values */
static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; static const unsigned int g_probable_mtu[] = {1500, 512, 256};
static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
unsigned long frag_len); unsigned long frag_len);
static unsigned char *dtls1_write_message_header(SSL *s, static unsigned char *dtls1_write_message_header(SSL *s,
@ -211,8 +210,7 @@ dtls1_hm_fragment_new(unsigned long frag_len, int reassembly)
return frag; return frag;
} }
static void void dtls1_hm_fragment_free(hm_fragment *frag)
dtls1_hm_fragment_free(hm_fragment *frag)
{ {
if (frag->msg_header.is_ccs) if (frag->msg_header.is_ccs)
@ -225,53 +223,50 @@ dtls1_hm_fragment_free(hm_fragment *frag)
OPENSSL_free(frag); OPENSSL_free(frag);
} }
static int dtls1_query_mtu(SSL *s)
{
if(s->d1->link_mtu)
{
s->d1->mtu = s->d1->link_mtu-BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
s->d1->link_mtu = 0;
}
/* AHA! Figure out the MTU, and stick to the right size */
if (s->d1->mtu < dtls1_min_mtu(s))
{
if(!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
{
s->d1->mtu =
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
/* I've seen the kernel return bogus numbers when it doesn't know
* (initial write), so just make sure we have a reasonable number */
if (s->d1->mtu < dtls1_min_mtu(s))
{
/* Set to min mtu */
s->d1->mtu = dtls1_min_mtu(s);
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
s->d1->mtu, NULL);
}
}
else
return 0;
}
return 1;
}
/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */ /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
int dtls1_do_write(SSL *s, int type) int dtls1_do_write(SSL *s, int type)
{ {
int ret; int ret;
int curr_mtu; unsigned int curr_mtu;
unsigned int len, frag_off, mac_size, blocksize; int retry = 1;
unsigned int len, frag_off, mac_size, blocksize, used_len;
/* AHA! Figure out the MTU, and stick to the right size */ if(!dtls1_query_mtu(s))
if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) return -1;
{
s->d1->mtu =
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
/* I've seen the kernel return bogus numbers when it doesn't know OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu(s)); /* should have something reasonable now */
* (initial write), so just make sure we have a reasonable number */
if (s->d1->mtu < dtls1_min_mtu())
{
s->d1->mtu = 0;
s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
s->d1->mtu, NULL);
}
}
#if 0
mtu = s->d1->mtu;
fprintf(stderr, "using MTU = %d\n", mtu);
mtu -= (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
curr_mtu = mtu - BIO_wpending(SSL_get_wbio(s));
if ( curr_mtu > 0)
mtu = curr_mtu;
else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0)
return ret;
if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu)
{
ret = BIO_flush(SSL_get_wbio(s));
if ( ret <= 0)
return ret;
mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
}
#endif
OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); /* should have something reasonable now */
if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE) if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE)
OPENSSL_assert(s->init_num == OPENSSL_assert(s->init_num ==
@ -289,10 +284,15 @@ int dtls1_do_write(SSL *s, int type)
blocksize = 0; blocksize = 0;
frag_off = 0; frag_off = 0;
while( s->init_num) /* s->init_num shouldn't ever be < 0...but just in case */
while(s->init_num > 0)
{ {
curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - used_len = BIO_wpending(SSL_get_wbio(s)) + DTLS1_RT_HEADER_LENGTH
DTLS1_RT_HEADER_LENGTH - mac_size - blocksize; + mac_size + blocksize;
if(s->d1->mtu > used_len)
curr_mtu = s->d1->mtu - used_len;
else
curr_mtu = 0;
if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH) if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH)
{ {
@ -300,15 +300,27 @@ int dtls1_do_write(SSL *s, int type)
ret = BIO_flush(SSL_get_wbio(s)); ret = BIO_flush(SSL_get_wbio(s));
if ( ret <= 0) if ( ret <= 0)
return ret; return ret;
curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH - used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize;
mac_size - blocksize; if(s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH)
{
curr_mtu = s->d1->mtu - used_len;
}
else
{
/* Shouldn't happen */
return -1;
}
} }
if ( s->init_num > curr_mtu) /* We just checked that s->init_num > 0 so this cast should be safe */
if (((unsigned int)s->init_num) > curr_mtu)
len = curr_mtu; len = curr_mtu;
else else
len = s->init_num; len = s->init_num;
/* Shouldn't ever happen */
if(len > INT_MAX)
len = INT_MAX;
/* XDTLS: this function is too long. split out the CCS part */ /* XDTLS: this function is too long. split out the CCS part */
if ( type == SSL3_RT_HANDSHAKE) if ( type == SSL3_RT_HANDSHAKE)
@ -319,18 +331,29 @@ int dtls1_do_write(SSL *s, int type)
s->init_off -= DTLS1_HM_HEADER_LENGTH; s->init_off -= DTLS1_HM_HEADER_LENGTH;
s->init_num += DTLS1_HM_HEADER_LENGTH; s->init_num += DTLS1_HM_HEADER_LENGTH;
if ( s->init_num > curr_mtu) /* We just checked that s->init_num > 0 so this cast should be safe */
if (((unsigned int)s->init_num) > curr_mtu)
len = curr_mtu; len = curr_mtu;
else else
len = s->init_num; len = s->init_num;
} }
/* Shouldn't ever happen */
if(len > INT_MAX)
len = INT_MAX;
if ( len < DTLS1_HM_HEADER_LENGTH )
{
/*
* len is so small that we really can't do anything sensible
* so fail
*/
return -1;
}
dtls1_fix_message_header(s, frag_off, dtls1_fix_message_header(s, frag_off,
len - DTLS1_HM_HEADER_LENGTH); len - DTLS1_HM_HEADER_LENGTH);
dtls1_write_message_header(s, (unsigned char *)&s->init_buf->data[s->init_off]); dtls1_write_message_header(s, (unsigned char *)&s->init_buf->data[s->init_off]);
OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH);
} }
ret=dtls1_write_bytes(s,type,&s->init_buf->data[s->init_off], ret=dtls1_write_bytes(s,type,&s->init_buf->data[s->init_off],
@ -343,12 +366,23 @@ int dtls1_do_write(SSL *s, int type)
* is fine and wait for an alert to handle the * is fine and wait for an alert to handle the
* retransmit * retransmit
*/ */
if ( BIO_ctrl(SSL_get_wbio(s), if ( retry && BIO_ctrl(SSL_get_wbio(s),
BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 ) BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 )
s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), {
BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); if(!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
{
if(!dtls1_query_mtu(s))
return -1;
/* Have one more go */
retry = 0;
}
else
return -1;
}
else else
{
return(-1); return(-1);
}
} }
else else
{ {
@ -1412,28 +1446,20 @@ dtls1_write_message_header(SSL *s, unsigned char *p)
return p; return p;
} }
unsigned int unsigned int
dtls1_min_mtu(void) dtls1_link_min_mtu(void)
{ {
return (g_probable_mtu[(sizeof(g_probable_mtu) / return (g_probable_mtu[(sizeof(g_probable_mtu) /
sizeof(g_probable_mtu[0])) - 1]); sizeof(g_probable_mtu[0])) - 1]);
} }
static unsigned int unsigned int
dtls1_guess_mtu(unsigned int curr_mtu) dtls1_min_mtu(SSL *s)
{ {
unsigned int i; return dtls1_link_min_mtu()-BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
if ( curr_mtu == 0 )
return g_probable_mtu[0] ;
for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++)
if ( curr_mtu > g_probable_mtu[i])
return g_probable_mtu[i];
return curr_mtu;
} }
void void
dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
{ {

View File

@ -249,6 +249,9 @@ int dtls1_connect(SSL *s)
memset(s->s3->client_random,0,sizeof(s->s3->client_random)); memset(s->s3->client_random,0,sizeof(s->s3->client_random));
s->d1->send_cookie = 0; s->d1->send_cookie = 0;
s->hit = 0; s->hit = 0;
s->d1->change_cipher_spec_ok = 0;
/* Should have been reset by ssl3_get_finished, too. */
s->s3->change_cipher_spec = 0;
break; break;
#ifndef OPENSSL_NO_SCTP #ifndef OPENSSL_NO_SCTP
@ -370,20 +373,6 @@ int dtls1_connect(SSL *s)
case SSL3_ST_CR_CERT_A: case SSL3_ST_CR_CERT_A:
case SSL3_ST_CR_CERT_B: case SSL3_ST_CR_CERT_B:
#ifndef OPENSSL_NO_TLSEXT
ret=ssl3_check_finished(s);
if (ret <= 0) goto end;
if (ret == 2)
{
s->hit = 1;
if (s->tlsext_ticket_expected)
s->state=SSL3_ST_CR_SESSION_TICKET_A;
else
s->state=SSL3_ST_CR_FINISHED_A;
s->init_num=0;
break;
}
#endif
/* Check if it is anon DH or PSK */ /* Check if it is anon DH or PSK */
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
!(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
@ -506,7 +495,6 @@ int dtls1_connect(SSL *s)
else else
#endif #endif
s->state=SSL3_ST_CW_CHANGE_A; s->state=SSL3_ST_CW_CHANGE_A;
s->s3->change_cipher_spec=0;
} }
s->init_num=0; s->init_num=0;
@ -527,7 +515,6 @@ int dtls1_connect(SSL *s)
#endif #endif
s->state=SSL3_ST_CW_CHANGE_A; s->state=SSL3_ST_CW_CHANGE_A;
s->init_num=0; s->init_num=0;
s->s3->change_cipher_spec=0;
break; break;
case SSL3_ST_CW_CHANGE_A: case SSL3_ST_CW_CHANGE_A:
@ -1730,6 +1717,12 @@ int dtls1_send_client_certificate(SSL *s)
s->state=SSL3_ST_CW_CERT_D; s->state=SSL3_ST_CW_CERT_D;
l=dtls1_output_cert_chain(s, l=dtls1_output_cert_chain(s,
(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509); (s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
if (!l)
{
SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
return 0;
}
s->init_num=(int)l; s->init_num=(int)l;
s->init_off=0; s->init_off=0;

View File

@ -241,7 +241,8 @@ int dtls1_enc(SSL *s, int send)
return 0; return 0;
} }
EVP_Cipher(ds,rec->data,rec->input,l); if(EVP_Cipher(ds,rec->data,rec->input,l) < 1)
return -1;
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
{ {

View File

@ -113,6 +113,9 @@ int dtls1_new(SSL *s)
d1->cookie_len = sizeof(s->d1->cookie); d1->cookie_len = sizeof(s->d1->cookie);
} }
d1->link_mtu = 0;
d1->mtu = 0;
if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q
|| ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q) || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
{ {
@ -161,16 +164,14 @@ static void dtls1_clear_queues(SSL *s)
while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL) while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
{ {
frag = (hm_fragment *)item->data; frag = (hm_fragment *)item->data;
OPENSSL_free(frag->fragment); dtls1_hm_fragment_free(frag);
OPENSSL_free(frag);
pitem_free(item); pitem_free(item);
} }
while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL) while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
{ {
frag = (hm_fragment *)item->data; frag = (hm_fragment *)item->data;
OPENSSL_free(frag->fragment); dtls1_hm_fragment_free(frag);
OPENSSL_free(frag);
pitem_free(item); pitem_free(item);
} }
@ -210,6 +211,7 @@ void dtls1_clear(SSL *s)
pqueue sent_messages; pqueue sent_messages;
pqueue buffered_app_data; pqueue buffered_app_data;
unsigned int mtu; unsigned int mtu;
unsigned int link_mtu;
if (s->d1) if (s->d1)
{ {
@ -219,6 +221,7 @@ void dtls1_clear(SSL *s)
sent_messages = s->d1->sent_messages; sent_messages = s->d1->sent_messages;
buffered_app_data = s->d1->buffered_app_data.q; buffered_app_data = s->d1->buffered_app_data.q;
mtu = s->d1->mtu; mtu = s->d1->mtu;
link_mtu = s->d1->link_mtu;
dtls1_clear_queues(s); dtls1_clear_queues(s);
@ -232,6 +235,7 @@ void dtls1_clear(SSL *s)
if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)
{ {
s->d1->mtu = mtu; s->d1->mtu = mtu;
s->d1->link_mtu = link_mtu;
} }
s->d1->unprocessed_rcds.q = unprocessed_rcds; s->d1->unprocessed_rcds.q = unprocessed_rcds;
@ -276,7 +280,22 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
/* Just one protocol version is supported so far; /* Just one protocol version is supported so far;
* fail closed if the version is not as expected. */ * fail closed if the version is not as expected. */
return s->version == DTLS_MAX_VERSION; return s->version == DTLS_MAX_VERSION;
case DTLS_CTRL_SET_LINK_MTU:
if (larg < (long)dtls1_link_min_mtu())
return 0;
s->d1->link_mtu = larg;
return 1;
case DTLS_CTRL_GET_LINK_MIN_MTU:
return (long)dtls1_link_min_mtu();
case SSL_CTRL_SET_MTU:
/*
* We may not have a BIO set yet so can't call dtls1_min_mtu()
* We'll have to make do with dtls1_link_min_mtu() and max overhead
*/
if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD)
return 0;
s->d1->mtu = larg;
return larg;
default: default:
ret = ssl3_ctrl(s, cmd, larg, parg); ret = ssl3_ctrl(s, cmd, larg, parg);
break; break;
@ -415,12 +434,17 @@ void dtls1_stop_timer(SSL *s)
int dtls1_check_timeout_num(SSL *s) int dtls1_check_timeout_num(SSL *s)
{ {
unsigned int mtu;
s->d1->timeout.num_alerts++; s->d1->timeout.num_alerts++;
/* Reduce MTU after 2 unsuccessful retransmissions */ /* Reduce MTU after 2 unsuccessful retransmissions */
if (s->d1->timeout.num_alerts > 2) if (s->d1->timeout.num_alerts > 2
&& !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
{ {
s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL); mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
if(mtu < s->d1->mtu)
s->d1->mtu = mtu;
} }
if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)

View File

@ -212,7 +212,7 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
/* Limit the size of the queue to prevent DOS attacks */ /* Limit the size of the queue to prevent DOS attacks */
if (pqueue_size(queue->q) >= 100) if (pqueue_size(queue->q) >= 100)
return 0; return 0;
rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
item = pitem_new(priority, rdata); item = pitem_new(priority, rdata);
if (rdata == NULL || item == NULL) if (rdata == NULL || item == NULL)
@ -247,18 +247,22 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
if (!ssl3_setup_buffers(s)) if (!ssl3_setup_buffers(s))
{ {
SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
if (rdata->rbuf.buf != NULL)
OPENSSL_free(rdata->rbuf.buf);
OPENSSL_free(rdata); OPENSSL_free(rdata);
pitem_free(item); pitem_free(item);
return(0); return(-1);
} }
/* insert should not fail, since duplicates are dropped */ /* insert should not fail, since duplicates are dropped */
if (pqueue_insert(queue->q, item) == NULL) if (pqueue_insert(queue->q, item) == NULL)
{ {
SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
if (rdata->rbuf.buf != NULL)
OPENSSL_free(rdata->rbuf.buf);
OPENSSL_free(rdata); OPENSSL_free(rdata);
pitem_free(item); pitem_free(item);
return(0); return(-1);
} }
return(1); return(1);
@ -314,8 +318,9 @@ dtls1_process_buffered_records(SSL *s)
dtls1_get_unprocessed_record(s); dtls1_get_unprocessed_record(s);
if ( ! dtls1_process_record(s)) if ( ! dtls1_process_record(s))
return(0); return(0);
dtls1_buffer_record(s, &(s->d1->processed_rcds), if(dtls1_buffer_record(s, &(s->d1->processed_rcds),
s->s3->rrec.seq_num); s->s3->rrec.seq_num)<0)
return -1;
} }
} }
@ -530,7 +535,6 @@ printf("\n");
/* we have pulled in a full packet so zero things */ /* we have pulled in a full packet so zero things */
s->packet_length=0; s->packet_length=0;
dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
return(1); return(1);
f_err: f_err:
@ -563,7 +567,8 @@ int dtls1_get_record(SSL *s)
/* The epoch may have changed. If so, process all the /* The epoch may have changed. If so, process all the
* pending records. This is a non-blocking operation. */ * pending records. This is a non-blocking operation. */
dtls1_process_buffered_records(s); if(dtls1_process_buffered_records(s)<0)
return -1;
/* if we're renegotiating, then there may be buffered records */ /* if we're renegotiating, then there may be buffered records */
if (dtls1_get_processed_record(s)) if (dtls1_get_processed_record(s))
@ -642,8 +647,6 @@ int dtls1_get_record(SSL *s)
/* now s->packet_length == DTLS1_RT_HEADER_LENGTH */ /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
i=rr->length; i=rr->length;
n=ssl3_read_n(s,i,i,1); n=ssl3_read_n(s,i,i,1);
if (n <= 0) return(n); /* error or non-blocking io */
/* this packet contained a partial record, dump it */ /* this packet contained a partial record, dump it */
if ( n != i) if ( n != i)
{ {
@ -678,7 +681,8 @@ int dtls1_get_record(SSL *s)
* would be dropped unnecessarily. * would be dropped unnecessarily.
*/ */
if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
*p == SSL3_MT_CLIENT_HELLO) && s->packet_length > DTLS1_RT_HEADER_LENGTH &&
s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) &&
!dtls1_record_replay_check(s, bitmap)) !dtls1_record_replay_check(s, bitmap))
{ {
rr->length = 0; rr->length = 0;
@ -701,7 +705,9 @@ int dtls1_get_record(SSL *s)
{ {
if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen)
{ {
dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num); if(dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num)<0)
return -1;
dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */
} }
rr->length = 0; rr->length = 0;
s->packet_length = 0; s->packet_length = 0;
@ -714,6 +720,7 @@ int dtls1_get_record(SSL *s)
s->packet_length = 0; /* dump this record */ s->packet_length = 0; /* dump this record */
goto again; /* get another record */ goto again; /* get another record */
} }
dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */
return(1); return(1);
@ -865,7 +872,11 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
* buffer the application data for later processing rather * buffer the application data for later processing rather
* than dropping the connection. * than dropping the connection.
*/ */
dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num); if(dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num)<0)
{
SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
return -1;
}
rr->length = 0; rr->length = 0;
goto start; goto start;
} }
@ -1619,7 +1630,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
wr->length += bs; wr->length += bs;
} }
s->method->ssl3_enc->enc(s,1); if(s->method->ssl3_enc->enc(s,1) < 1) goto err;
/* record length after mac and block padding */ /* record length after mac and block padding */
/* if (type == SSL3_RT_APPLICATION_DATA || /* if (type == SSL3_RT_APPLICATION_DATA ||

View File

@ -233,6 +233,7 @@ int dtls1_accept(SSL *s)
} }
if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
{ {
BUF_MEM_free(buf);
ret= -1; ret= -1;
goto end; goto end;
} }
@ -246,6 +247,9 @@ int dtls1_accept(SSL *s)
} }
s->init_num=0; s->init_num=0;
s->d1->change_cipher_spec_ok = 0;
/* Should have been reset by ssl3_get_finished, too. */
s->s3->change_cipher_spec = 0;
if (s->state != SSL_ST_RENEGOTIATE) if (s->state != SSL_ST_RENEGOTIATE)
{ {
@ -450,24 +454,15 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SW_KEY_EXCH_B: case SSL3_ST_SW_KEY_EXCH_B:
alg_k = s->s3->tmp.new_cipher->algorithm_mkey; alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
/* clear this, it may get reset by /*
* send_server_key_exchange */ * clear this, it may get reset by
if ((s->options & SSL_OP_EPHEMERAL_RSA) * send_server_key_exchange
#ifndef OPENSSL_NO_KRB5 */
&& !(alg_k & SSL_kKRB5) s->s3->tmp.use_rsa_tmp=0;
#endif /* OPENSSL_NO_KRB5 */
)
/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
* even when forbidden by protocol specs
* (handshake may fail as clients are not required to
* be able to handle this) */
s->s3->tmp.use_rsa_tmp=1;
else
s->s3->tmp.use_rsa_tmp=0;
/* only send if a DH key exchange or /* only send if a DH key exchange or
* RSA but we have a sign only certificate */ * RSA but we have a sign only certificate */
if (s->s3->tmp.use_rsa_tmp if (0
/* PSK: send ServerKeyExchange if PSK identity /* PSK: send ServerKeyExchange if PSK identity
* hint if provided */ * hint if provided */
#ifndef OPENSSL_NO_PSK #ifndef OPENSSL_NO_PSK
@ -658,8 +653,14 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_A:
case SSL3_ST_SR_CERT_VRFY_B: case SSL3_ST_SR_CERT_VRFY_B:
/*
s->d1->change_cipher_spec_ok = 1; * This *should* be the first time we enable CCS, but be
* extra careful about surrounding code changes. We need
* to set this here because we don't know if we're
* expecting a CertificateVerify or not.
*/
if (!s->s3->change_cipher_spec)
s->d1->change_cipher_spec_ok = 1;
/* we should decide if we expected this one */ /* we should decide if we expected this one */
ret=ssl3_get_cert_verify(s); ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end; if (ret <= 0) goto end;
@ -675,7 +676,18 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B: case SSL3_ST_SR_FINISHED_B:
s->d1->change_cipher_spec_ok = 1; /*
* Enable CCS for resumed handshakes.
* In a full handshake, we end up here through
* SSL3_ST_SR_CERT_VRFY_B, so change_cipher_spec_ok was
* already set. Receiving a CCS clears the flag, so make
* sure not to re-enable it to ban duplicates.
* s->s3->change_cipher_spec is set when a CCS is
* processed in d1_pkt.c, and remains set until
* the client's Finished message is read.
*/
if (!s->s3->change_cipher_spec)
s->d1->change_cipher_spec_ok = 1;
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
SSL3_ST_SR_FINISHED_B); SSL3_ST_SR_FINISHED_B);
if (ret <= 0) goto end; if (ret <= 0) goto end;
@ -1604,6 +1616,11 @@ int dtls1_send_server_certificate(SSL *s)
} }
l=dtls1_output_cert_chain(s,x); l=dtls1_output_cert_chain(s,x);
if (!l)
{
SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
return(0);
}
s->state=SSL3_ST_SW_CERT_B; s->state=SSL3_ST_SW_CERT_B;
s->init_num=(int)l; s->init_num=(int)l;
s->init_off=0; s->init_off=0;

View File

@ -117,6 +117,9 @@ extern "C" {
#define DTLS1_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP" #define DTLS1_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP"
#endif #endif
/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */
#define DTLS1_MAX_MTU_OVERHEAD 48
typedef struct dtls1_bitmap_st typedef struct dtls1_bitmap_st
{ {
unsigned long map; /* track 32 packets on 32-bit systems unsigned long map; /* track 32 packets on 32-bit systems
@ -231,6 +234,7 @@ typedef struct dtls1_state_st
/* Is set when listening for new connections with dtls1_listen() */ /* Is set when listening for new connections with dtls1_listen() */
unsigned int listen; unsigned int listen;
unsigned int link_mtu; /* max on-the-wire DTLS packet size */
unsigned int mtu; /* max DTLS packet size */ unsigned int mtu; /* max DTLS packet size */
struct hm_header_st w_msg_hdr; struct hm_header_st w_msg_hdr;
@ -252,6 +256,10 @@ typedef struct dtls1_state_st
unsigned int handshake_fragment_len; unsigned int handshake_fragment_len;
unsigned int retransmitting; unsigned int retransmitting;
/*
* Set when the handshake is ready to process peer's ChangeCipherSpec message.
* Cleared after the message has been processed.
*/
unsigned int change_cipher_spec_ok; unsigned int change_cipher_spec_ok;
#ifndef OPENSSL_NO_SCTP #ifndef OPENSSL_NO_SCTP

View File

@ -954,15 +954,15 @@ print_krb5_data(char *label, krb5_data *kdata)
{ {
int i; int i;
printf("%s[%d] ", label, kdata->length); fprintf(stderr,"%s[%d] ", label, kdata->length);
for (i=0; i < (int)kdata->length; i++) for (i=0; i < (int)kdata->length; i++)
{ {
if (0 && isprint((int) kdata->data[i])) if (0 && isprint((int) kdata->data[i]))
printf( "%c ", kdata->data[i]); fprintf(stderr, "%c ", kdata->data[i]);
else else
printf( "%02x ", (unsigned char) kdata->data[i]); fprintf(stderr, "%02x ", (unsigned char) kdata->data[i]);
} }
printf("\n"); fprintf(stderr,"\n");
} }
@ -973,20 +973,20 @@ print_krb5_authdata(char *label, krb5_authdata **adata)
{ {
if (adata == NULL) if (adata == NULL)
{ {
printf("%s, authdata==0\n", label); fprintf(stderr,"%s, authdata==0\n", label);
return; return;
} }
printf("%s [%p]\n", label, (void *)adata); fprintf(stderr,"%s [%p]\n", label, (void *)adata);
#if 0 #if 0
{ {
int i; int i;
printf("%s[at%d:%d] ", label, adata->ad_type, adata->length); fprintf(stderr,"%s[at%d:%d] ", label, adata->ad_type, adata->length);
for (i=0; i < adata->length; i++) for (i=0; i < adata->length; i++)
{ {
printf((isprint(adata->contents[i]))? "%c ": "%02x", fprintf(stderr,(isprint(adata->contents[i]))? "%c ": "%02x",
adata->contents[i]); adata->contents[i]);
} }
printf("\n"); fprintf(stderr,"\n");
} }
#endif #endif
} }
@ -1001,24 +1001,24 @@ print_krb5_keyblock(char *label, krb5_keyblock *keyblk)
if (keyblk == NULL) if (keyblk == NULL)
{ {
printf("%s, keyblk==0\n", label); fprintf(stderr,"%s, keyblk==0\n", label);
return; return;
} }
#ifdef KRB5_HEIMDAL #ifdef KRB5_HEIMDAL
printf("%s\n\t[et%d:%d]: ", label, keyblk->keytype, fprintf(stderr,"%s\n\t[et%d:%d]: ", label, keyblk->keytype,
keyblk->keyvalue->length); keyblk->keyvalue->length);
for (i=0; i < (int)keyblk->keyvalue->length; i++) for (i=0; i < (int)keyblk->keyvalue->length; i++)
{ {
printf("%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]); fprintf(stderr,"%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]);
} }
printf("\n"); fprintf(stderr,"\n");
#else #else
printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length); fprintf(stderr,"%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length);
for (i=0; i < (int)keyblk->length; i++) for (i=0; i < (int)keyblk->length; i++)
{ {
printf("%02x",keyblk->contents[i]); fprintf(stderr,"%02x",keyblk->contents[i]);
} }
printf("\n"); fprintf(stderr,"\n");
#endif #endif
} }
@ -1031,17 +1031,17 @@ print_krb5_princ(char *label, krb5_principal_data *princ)
{ {
int i, ui, uj; int i, ui, uj;
printf("%s principal Realm: ", label); fprintf(stderr,"%s principal Realm: ", label);
if (princ == NULL) return; if (princ == NULL) return;
for (ui=0; ui < (int)princ->realm.length; ui++) putchar(princ->realm.data[ui]); for (ui=0; ui < (int)princ->realm.length; ui++) putchar(princ->realm.data[ui]);
printf(" (nametype %d) has %d strings:\n", princ->type,princ->length); fprintf(stderr," (nametype %d) has %d strings:\n", princ->type,princ->length);
for (i=0; i < (int)princ->length; i++) for (i=0; i < (int)princ->length; i++)
{ {
printf("\t%d [%d]: ", i, princ->data[i].length); fprintf(stderr,"\t%d [%d]: ", i, princ->data[i].length);
for (uj=0; uj < (int)princ->data[i].length; uj++) { for (uj=0; uj < (int)princ->data[i].length; uj++) {
putchar(princ->data[i].data[uj]); putchar(princ->data[i].data[uj]);
} }
printf("\n"); fprintf(stderr,"\n");
} }
return; return;
} }
@ -1332,7 +1332,7 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx,
} }
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
printf("in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name)); fprintf(stderr,"in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name));
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
if (!krb5context && (krb5rc = krb5_init_context(&krb5context))) if (!krb5context && (krb5rc = krb5_init_context(&krb5context)))
@ -1481,18 +1481,18 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx,
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
{ {
int i; krb5_address **paddr = krb5ticket->enc_part2->caddrs; int i; krb5_address **paddr = krb5ticket->enc_part2->caddrs;
printf("Decrypted ticket fields:\n"); fprintf(stderr,"Decrypted ticket fields:\n");
printf("\tflags: %X, transit-type: %X", fprintf(stderr,"\tflags: %X, transit-type: %X",
krb5ticket->enc_part2->flags, krb5ticket->enc_part2->flags,
krb5ticket->enc_part2->transited.tr_type); krb5ticket->enc_part2->transited.tr_type);
print_krb5_data("\ttransit-data: ", print_krb5_data("\ttransit-data: ",
&(krb5ticket->enc_part2->transited.tr_contents)); &(krb5ticket->enc_part2->transited.tr_contents));
printf("\tcaddrs: %p, authdata: %p\n", fprintf(stderr,"\tcaddrs: %p, authdata: %p\n",
krb5ticket->enc_part2->caddrs, krb5ticket->enc_part2->caddrs,
krb5ticket->enc_part2->authorization_data); krb5ticket->enc_part2->authorization_data);
if (paddr) if (paddr)
{ {
printf("\tcaddrs:\n"); fprintf(stderr,"\tcaddrs:\n");
for (i=0; paddr[i] != NULL; i++) for (i=0; paddr[i] != NULL; i++)
{ {
krb5_data d; krb5_data d;
@ -1501,7 +1501,7 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx,
print_krb5_data("\t\tIP: ", &d); print_krb5_data("\t\tIP: ", &d);
} }
} }
printf("\tstart/auth/end times: %d / %d / %d\n", fprintf(stderr,"\tstart/auth/end times: %d / %d / %d\n",
krb5ticket->enc_part2->times.starttime, krb5ticket->enc_part2->times.starttime,
krb5ticket->enc_part2->times.authtime, krb5ticket->enc_part2->times.authtime,
krb5ticket->enc_part2->times.endtime); krb5ticket->enc_part2->times.endtime);
@ -1976,7 +1976,7 @@ krb5_error_code kssl_validate_times( krb5_timestamp atime,
if ((now - ttimes->endtime) > skew) return SSL_R_KRB5_S_TKT_EXPIRED; if ((now - ttimes->endtime) > skew) return SSL_R_KRB5_S_TKT_EXPIRED;
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
printf("kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n", fprintf(stderr,"kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n",
start, atime, now, skew, ttimes->endtime); start, atime, now, skew, ttimes->endtime);
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
@ -2027,10 +2027,10 @@ krb5_error_code kssl_check_authent(
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
{ {
unsigned int ui; unsigned int ui;
printf("kssl_check_authent: authenticator[%d]:\n",authentp->length); fprintf(stderr,"kssl_check_authent: authenticator[%d]:\n",authentp->length);
p = authentp->data; p = authentp->data;
for (ui=0; ui < authentp->length; ui++) printf("%02x ",p[ui]); for (ui=0; ui < authentp->length; ui++) fprintf(stderr,"%02x ",p[ui]);
printf("\n"); fprintf(stderr,"\n");
} }
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
@ -2095,9 +2095,9 @@ krb5_error_code kssl_check_authent(
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
{ {
int padl; int padl;
printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl); fprintf(stderr,"kssl_check_authent: decrypted authenticator[%d] =\n", outl);
for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]); for (padl=0; padl < outl; padl++) fprintf(stderr,"%02x ",unenc_authent[padl]);
printf("\n"); fprintf(stderr,"\n");
} }
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
@ -2132,10 +2132,10 @@ krb5_error_code kssl_check_authent(
} }
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
printf("kssl_check_authent: returns %d for client time ", *atimep); fprintf(stderr,"kssl_check_authent: returns %d for client time ", *atimep);
if (auth && auth->ctime && auth->ctime->length && auth->ctime->data) if (auth && auth->ctime && auth->ctime->length && auth->ctime->data)
printf("%.*s\n", auth->ctime->length, auth->ctime->data); fprintf(stderr,"%.*s\n", auth->ctime->length, auth->ctime->data);
else printf("NULL\n"); else fprintf(stderr,"NULL\n");
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
err: err:

View File

@ -192,6 +192,7 @@ int ssl23_accept(SSL *s)
} }
if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
{ {
BUF_MEM_free(buf);
ret= -1; ret= -1;
goto end; goto end;
} }
@ -602,12 +603,14 @@ int ssl23_get_client_hello(SSL *s)
if ((type == 2) || (type == 3)) if ((type == 2) || (type == 3))
{ {
/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */ /* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
s->method = ssl23_get_server_method(s->version); const SSL_METHOD *new_method;
if (s->method == NULL) new_method = ssl23_get_server_method(s->version);
if (new_method == NULL)
{ {
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
goto err; goto err;
} }
s->method = new_method;
if (!ssl_init_wbio_buffer(s,1)) goto err; if (!ssl_init_wbio_buffer(s,1)) goto err;

View File

@ -117,8 +117,9 @@ int ssl2_enc_init(SSL *s, int client)
/* read/writes from s->s2->mac_data using length for encrypt and /* read/writes from s->s2->mac_data using length for encrypt and
* decrypt. It sets s->s2->padding and s->[rw]length * decrypt. It sets s->s2->padding and s->[rw]length
* if we are encrypting */ * if we are encrypting
void ssl2_enc(SSL *s, int send) * Returns 0 on error and 1 on success */
int ssl2_enc(SSL *s, int send)
{ {
EVP_CIPHER_CTX *ds; EVP_CIPHER_CTX *ds;
unsigned long l; unsigned long l;
@ -136,7 +137,7 @@ void ssl2_enc(SSL *s, int send)
} }
/* check for NULL cipher */ /* check for NULL cipher */
if (ds == NULL) return; if (ds == NULL) return 1;
bs=ds->cipher->block_size; bs=ds->cipher->block_size;
@ -145,7 +146,10 @@ void ssl2_enc(SSL *s, int send)
if (bs == 8) if (bs == 8)
l=(l+7)/8*8; l=(l+7)/8*8;
EVP_Cipher(ds,s->s2->mac_data,s->s2->mac_data,l); if(EVP_Cipher(ds,s->s2->mac_data,s->s2->mac_data,l) < 1)
return 0;
return 1;
} }
void ssl2_mac(SSL *s, unsigned char *md, int send) void ssl2_mac(SSL *s, unsigned char *md, int send)

View File

@ -265,7 +265,11 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
if ((!s->s2->clear_text) && if ((!s->s2->clear_text) &&
(s->s2->rlength >= (unsigned int)mac_size)) (s->s2->rlength >= (unsigned int)mac_size))
{ {
ssl2_enc(s,0); if(!ssl2_enc(s,0))
{
SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_DECRYPTION_FAILED);
return(-1);
}
s->s2->ract_data_length-=mac_size; s->s2->ract_data_length-=mac_size;
ssl2_mac(s,mac,0); ssl2_mac(s,mac,0);
s->s2->ract_data_length-=s->s2->padding; s->s2->ract_data_length-=s->s2->padding;
@ -616,7 +620,8 @@ static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
s->s2->wact_data_length=len+p; s->s2->wact_data_length=len+p;
ssl2_mac(s,s->s2->mac_data,1); ssl2_mac(s,s->s2->mac_data,1);
s->s2->wlength+=p+mac_size; s->s2->wlength+=p+mac_size;
ssl2_enc(s,1); if(ssl2_enc(s,1) < 1)
return -1;
} }
/* package up the header */ /* package up the header */

View File

@ -188,13 +188,21 @@ int ssl2_accept(SSL *s)
s->version=SSL2_VERSION; s->version=SSL2_VERSION;
s->type=SSL_ST_ACCEPT; s->type=SSL_ST_ACCEPT;
buf=s->init_buf; if(s->init_buf == NULL)
if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL)) {
{ ret= -1; goto end; } if ((buf=BUF_MEM_new()) == NULL)
if (!BUF_MEM_grow(buf,(int) {
SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) ret= -1;
{ ret= -1; goto end; } goto end;
s->init_buf=buf; }
if (!BUF_MEM_grow(buf,(int) SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
{
BUF_MEM_free(buf);
ret= -1;
goto end;
}
s->init_buf=buf;
}
s->init_num=0; s->init_num=0;
s->ctx->stats.sess_accept++; s->ctx->stats.sess_accept++;
s->handshake_func=ssl2_accept; s->handshake_func=ssl2_accept;

View File

@ -439,6 +439,7 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
goto f_err; goto f_err;
} }
*ok=1; *ok=1;
s->state = stn;
s->init_msg = s->init_buf->data + 4; s->init_msg = s->init_buf->data + 4;
s->init_num = (int)s->s3->tmp.message_size; s->init_num = (int)s->s3->tmp.message_size;
return s->init_num; return s->init_num;

View File

@ -167,9 +167,9 @@
#include <openssl/engine.h> #include <openssl/engine.h>
#endif #endif
static const SSL_METHOD *ssl3_get_client_method(int ver);
static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b); static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
#ifndef OPENSSL_NO_SSL3_METHOD
static const SSL_METHOD *ssl3_get_client_method(int ver) static const SSL_METHOD *ssl3_get_client_method(int ver)
{ {
if (ver == SSL3_VERSION) if (ver == SSL3_VERSION)
@ -182,6 +182,7 @@ IMPLEMENT_ssl3_meth_func(SSLv3_client_method,
ssl_undefined_function, ssl_undefined_function,
ssl3_connect, ssl3_connect,
ssl3_get_client_method) ssl3_get_client_method)
#endif
int ssl3_connect(SSL *s) int ssl3_connect(SSL *s)
{ {
@ -272,6 +273,9 @@ int ssl3_connect(SSL *s)
s->state=SSL3_ST_CW_CLNT_HELLO_A; s->state=SSL3_ST_CW_CLNT_HELLO_A;
s->ctx->stats.sess_connect++; s->ctx->stats.sess_connect++;
s->init_num=0; s->init_num=0;
s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
/* Should have been reset by ssl3_get_finished, too. */
s->s3->change_cipher_spec = 0;
break; break;
case SSL3_ST_CW_CLNT_HELLO_A: case SSL3_ST_CW_CLNT_HELLO_A:
@ -312,20 +316,6 @@ int ssl3_connect(SSL *s)
case SSL3_ST_CR_CERT_A: case SSL3_ST_CR_CERT_A:
case SSL3_ST_CR_CERT_B: case SSL3_ST_CR_CERT_B:
#ifndef OPENSSL_NO_TLSEXT
ret=ssl3_check_finished(s);
if (ret <= 0) goto end;
if (ret == 2)
{
s->hit = 1;
if (s->tlsext_ticket_expected)
s->state=SSL3_ST_CR_SESSION_TICKET_A;
else
s->state=SSL3_ST_CR_FINISHED_A;
s->init_num=0;
break;
}
#endif
/* Check if it is anon DH/ECDH, SRP auth */ /* Check if it is anon DH/ECDH, SRP auth */
/* or PSK */ /* or PSK */
if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP)) && if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP)) &&
@ -433,12 +423,10 @@ int ssl3_connect(SSL *s)
else else
{ {
s->state=SSL3_ST_CW_CHANGE_A; s->state=SSL3_ST_CW_CHANGE_A;
s->s3->change_cipher_spec=0;
} }
if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
{ {
s->state=SSL3_ST_CW_CHANGE_A; s->state=SSL3_ST_CW_CHANGE_A;
s->s3->change_cipher_spec=0;
} }
s->init_num=0; s->init_num=0;
@ -450,7 +438,6 @@ int ssl3_connect(SSL *s)
if (ret <= 0) goto end; if (ret <= 0) goto end;
s->state=SSL3_ST_CW_CHANGE_A; s->state=SSL3_ST_CW_CHANGE_A;
s->init_num=0; s->init_num=0;
s->s3->change_cipher_spec=0;
break; break;
case SSL3_ST_CW_CHANGE_A: case SSL3_ST_CW_CHANGE_A:
@ -510,7 +497,6 @@ int ssl3_connect(SSL *s)
s->method->ssl3_enc->client_finished_label, s->method->ssl3_enc->client_finished_label,
s->method->ssl3_enc->client_finished_label_len); s->method->ssl3_enc->client_finished_label_len);
if (ret <= 0) goto end; if (ret <= 0) goto end;
s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->state=SSL3_ST_CW_FLUSH; s->state=SSL3_ST_CW_FLUSH;
/* clear flags */ /* clear flags */
@ -559,7 +545,6 @@ int ssl3_connect(SSL *s)
case SSL3_ST_CR_FINISHED_A: case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_CR_FINISHED_B: case SSL3_ST_CR_FINISHED_B:
s->s3->flags |= SSL3_FLAGS_CCS_OK; s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
SSL3_ST_CR_FINISHED_B); SSL3_ST_CR_FINISHED_B);
@ -669,11 +654,7 @@ int ssl3_client_hello(SSL *s)
SSL_SESSION *sess = s->session; SSL_SESSION *sess = s->session;
if ((sess == NULL) || if ((sess == NULL) ||
(sess->ssl_version != s->version) || (sess->ssl_version != s->version) ||
#ifdef OPENSSL_NO_TLSEXT
!sess->session_id_length || !sess->session_id_length ||
#else
(!sess->session_id_length && !sess->tlsext_tick) ||
#endif
(sess->not_resumable)) (sess->not_resumable))
{ {
if (!ssl_get_new_session(s,0)) if (!ssl_get_new_session(s,0))
@ -879,6 +860,8 @@ int ssl3_get_server_hello(SSL *s)
memcpy(s->s3->server_random,p,SSL3_RANDOM_SIZE); memcpy(s->s3->server_random,p,SSL3_RANDOM_SIZE);
p+=SSL3_RANDOM_SIZE; p+=SSL3_RANDOM_SIZE;
s->hit = 0;
/* get the session-id */ /* get the session-id */
j= *(p++); j= *(p++);
@ -902,12 +885,12 @@ int ssl3_get_server_hello(SSL *s)
{ {
s->session->cipher = pref_cipher ? s->session->cipher = pref_cipher ?
pref_cipher : ssl_get_cipher_by_char(s, p+j); pref_cipher : ssl_get_cipher_by_char(s, p+j);
s->s3->flags |= SSL3_FLAGS_CCS_OK; s->hit = 1;
} }
} }
#endif /* OPENSSL_NO_TLSEXT */ #endif /* OPENSSL_NO_TLSEXT */
if (j != 0 && j == s->session->session_id_length if (!s->hit && j != 0 && j == s->session->session_id_length
&& memcmp(p,s->session->session_id,j) == 0) && memcmp(p,s->session->session_id,j) == 0)
{ {
if(s->sid_ctx_length != s->session->sid_ctx_length if(s->sid_ctx_length != s->session->sid_ctx_length
@ -918,14 +901,13 @@ int ssl3_get_server_hello(SSL *s)
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
goto f_err; goto f_err;
} }
s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->hit=1; s->hit=1;
} }
else /* a miss or crap from the other end */ /* a miss or crap from the other end */
if (!s->hit)
{ {
/* If we were trying for session-id reuse, make a new /* If we were trying for session-id reuse, make a new
* SSL_SESSION so we don't stuff up other people */ * SSL_SESSION so we don't stuff up other people */
s->hit=0;
if (s->session->session_id_length > 0) if (s->session->session_id_length > 0)
{ {
if (!ssl_get_new_session(s,0)) if (!ssl_get_new_session(s,0))
@ -1203,9 +1185,9 @@ int ssl3_get_server_certificate(SSL *s)
? 0 : 1; ? 0 : 1;
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
printf("pkey,x = %p, %p\n", pkey,x); fprintf(stderr,"pkey,x = %p, %p\n", pkey,x);
printf("ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey)); fprintf(stderr,"ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey));
printf("cipher, alg, nc = %s, %lx, %lx, %d\n", s->s3->tmp.new_cipher->name, fprintf(stderr,"cipher, alg, nc = %s, %lx, %lx, %d\n", s->s3->tmp.new_cipher->name,
s->s3->tmp.new_cipher->algorithm_mkey, s->s3->tmp.new_cipher->algorithm_auth, need_cert); s->s3->tmp.new_cipher->algorithm_mkey, s->s3->tmp.new_cipher->algorithm_auth, need_cert);
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
@ -1295,6 +1277,8 @@ int ssl3_get_key_exchange(SSL *s)
int encoded_pt_len = 0; int encoded_pt_len = 0;
#endif #endif
EVP_MD_CTX_init(&md_ctx);
/* use same message size as in ssl3_get_certificate_request() /* use same message size as in ssl3_get_certificate_request()
* as ServerKeyExchange message may be skipped */ * as ServerKeyExchange message may be skipped */
n=s->method->ssl_get_message(s, n=s->method->ssl_get_message(s,
@ -1305,14 +1289,26 @@ int ssl3_get_key_exchange(SSL *s)
&ok); &ok);
if (!ok) return((int)n); if (!ok) return((int)n);
alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
{ {
/*
* Can't skip server key exchange if this is an ephemeral
* ciphersuite.
*/
if (alg_k & (SSL_kEDH|SSL_kEECDH))
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
al = SSL_AD_UNEXPECTED_MESSAGE;
goto f_err;
}
#ifndef OPENSSL_NO_PSK #ifndef OPENSSL_NO_PSK
/* In plain PSK ciphersuite, ServerKeyExchange can be /* In plain PSK ciphersuite, ServerKeyExchange can be
omitted if no identity hint is sent. Set omitted if no identity hint is sent. Set
session->sess_cert anyway to avoid problems session->sess_cert anyway to avoid problems
later.*/ later.*/
if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) if (alg_k & SSL_kPSK)
{ {
s->session->sess_cert=ssl_sess_cert_new(); s->session->sess_cert=ssl_sess_cert_new();
if (s->ctx->psk_identity_hint) if (s->ctx->psk_identity_hint)
@ -1357,9 +1353,7 @@ int ssl3_get_key_exchange(SSL *s)
/* Total length of the parameters including the length prefix */ /* Total length of the parameters including the length prefix */
param_len=0; param_len=0;
alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
alg_a=s->s3->tmp.new_cipher->algorithm_auth; alg_a=s->s3->tmp.new_cipher->algorithm_auth;
EVP_MD_CTX_init(&md_ctx);
al=SSL_AD_DECODE_ERROR; al=SSL_AD_DECODE_ERROR;
@ -1543,6 +1537,13 @@ int ssl3_get_key_exchange(SSL *s)
#ifndef OPENSSL_NO_RSA #ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA) if (alg_k & SSL_kRSA)
{ {
/* Temporary RSA keys only allowed in export ciphersuites */
if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher))
{
al=SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
if ((rsa=RSA_new()) == NULL) if ((rsa=RSA_new()) == NULL)
{ {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
@ -2174,24 +2175,13 @@ int ssl3_get_new_session_ticket(SSL *s)
n=s->method->ssl_get_message(s, n=s->method->ssl_get_message(s,
SSL3_ST_CR_SESSION_TICKET_A, SSL3_ST_CR_SESSION_TICKET_A,
SSL3_ST_CR_SESSION_TICKET_B, SSL3_ST_CR_SESSION_TICKET_B,
-1, SSL3_MT_NEWSESSION_TICKET,
16384, 16384,
&ok); &ok);
if (!ok) if (!ok)
return((int)n); return((int)n);
if (s->s3->tmp.message_type == SSL3_MT_FINISHED)
{
s->s3->tmp.reuse_message=1;
return(1);
}
if (s->s3->tmp.message_type != SSL3_MT_NEWSESSION_TICKET)
{
al=SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_BAD_MESSAGE_TYPE);
goto f_err;
}
if (n < 6) if (n < 6)
{ {
/* need at least ticket_lifetime_hint + ticket length */ /* need at least ticket_lifetime_hint + ticket length */
@ -2223,7 +2213,7 @@ int ssl3_get_new_session_ticket(SSL *s)
} }
memcpy(s->session->tlsext_tick, p, ticklen); memcpy(s->session->tlsext_tick, p, ticklen);
s->session->tlsext_ticklen = ticklen; s->session->tlsext_ticklen = ticklen;
/* There are two ways to detect a resumed ticket sesion. /* There are two ways to detect a resumed ticket session.
* One is to set an appropriate session ID and then the server * One is to set an appropriate session ID and then the server
* must return a match in ServerHello. This allows the normal * must return a match in ServerHello. This allows the normal
* client session ID matching to work and we know much * client session ID matching to work and we know much
@ -2462,7 +2452,7 @@ int ssl3_send_client_key_exchange(SSL *s)
EVP_CIPHER_CTX_init(&ciph_ctx); EVP_CIPHER_CTX_init(&ciph_ctx);
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
printf("ssl3_send_client_key_exchange(%lx & %lx)\n", fprintf(stderr,"ssl3_send_client_key_exchange(%lx & %lx)\n",
alg_k, SSL_kKRB5); alg_k, SSL_kKRB5);
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
@ -2478,9 +2468,9 @@ int ssl3_send_client_key_exchange(SSL *s)
goto err; goto err;
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
{ {
printf("kssl_cget_tkt rtn %d\n", krb5rc); fprintf(stderr,"kssl_cget_tkt rtn %d\n", krb5rc);
if (krb5rc && kssl_err.text) if (krb5rc && kssl_err.text)
printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text); fprintf(stderr,"kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
} }
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
@ -3309,6 +3299,12 @@ int ssl3_send_client_certificate(SSL *s)
s->state=SSL3_ST_CW_CERT_D; s->state=SSL3_ST_CW_CERT_D;
l=ssl3_output_cert_chain(s, l=ssl3_output_cert_chain(s,
(s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509); (s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
if (!l)
{
SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
return 0;
}
s->init_num=(int)l; s->init_num=(int)l;
s->init_off=0; s->init_off=0;
} }
@ -3478,40 +3474,9 @@ int ssl3_send_next_proto(SSL *s)
} }
return ssl3_do_write(s, SSL3_RT_HANDSHAKE); return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
} }
#endif /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */ #endif /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
/* Check to see if handshake is full or resumed. Usually this is just a
* case of checking to see if a cache hit has occurred. In the case of
* session tickets we have to check the next message to be sure.
*/
#ifndef OPENSSL_NO_TLSEXT
int ssl3_check_finished(SSL *s)
{
int ok;
long n;
/* If we have no ticket it cannot be a resumed session. */
if (!s->session->tlsext_tick)
return 1;
/* this function is called when we really expect a Certificate
* message, so permit appropriate message length */
n=s->method->ssl_get_message(s,
SSL3_ST_CR_CERT_A,
SSL3_ST_CR_CERT_B,
-1,
s->max_cert_list,
&ok);
if (!ok) return((int)n);
s->s3->tmp.reuse_message = 1;
if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
|| (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
return 2;
return 1;
}
#endif
int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
{ {
int i = 0; int i = 0;

View File

@ -535,7 +535,8 @@ int ssl3_enc(SSL *s, int send)
/* otherwise, rec->length >= bs */ /* otherwise, rec->length >= bs */
} }
EVP_Cipher(ds,rec->data,rec->input,l); if(EVP_Cipher(ds,rec->data,rec->input,l) < 1)
return -1;
if (EVP_MD_CTX_md(s->read_hash) != NULL) if (EVP_MD_CTX_md(s->read_hash) != NULL)
mac_size = EVP_MD_CTX_size(s->read_hash); mac_size = EVP_MD_CTX_size(s->read_hash);

View File

@ -3810,17 +3810,17 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
#endif #endif
#ifdef CIPHER_DEBUG #ifdef CIPHER_DEBUG
printf("Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), (void *)srvr); fprintf(stderr, "Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), (void *)srvr);
for(i=0 ; i < sk_SSL_CIPHER_num(srvr) ; ++i) for(i=0 ; i < sk_SSL_CIPHER_num(srvr) ; ++i)
{ {
c=sk_SSL_CIPHER_value(srvr,i); c=sk_SSL_CIPHER_value(srvr,i);
printf("%p:%s\n",(void *)c,c->name); fprintf(stderr, "%p:%s\n",(void *)c,c->name);
} }
printf("Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), (void *)clnt); fprintf(stderr, "Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), (void *)clnt);
for(i=0 ; i < sk_SSL_CIPHER_num(clnt) ; ++i) for(i=0 ; i < sk_SSL_CIPHER_num(clnt) ; ++i)
{ {
c=sk_SSL_CIPHER_value(clnt,i); c=sk_SSL_CIPHER_value(clnt,i);
printf("%p:%s\n",(void *)c,c->name); fprintf(stderr, "%p:%s\n",(void *)c,c->name);
} }
#endif #endif
@ -3860,7 +3860,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
#endif #endif
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
/* printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/ /* fprintf(stderr,"ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
alg_k=c->algorithm_mkey; alg_k=c->algorithm_mkey;
@ -3883,7 +3883,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
{ {
ok = (alg_k & emask_k) && (alg_a & emask_a); ok = (alg_k & emask_k) && (alg_a & emask_a);
#ifdef CIPHER_DEBUG #ifdef CIPHER_DEBUG
printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n",ok,alg_k,alg_a,emask_k,emask_a, fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n",ok,alg_k,alg_a,emask_k,emask_a,
(void *)c,c->name); (void *)c,c->name);
#endif #endif
} }
@ -3891,7 +3891,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
{ {
ok = (alg_k & mask_k) && (alg_a & mask_a); ok = (alg_k & mask_k) && (alg_a & mask_a);
#ifdef CIPHER_DEBUG #ifdef CIPHER_DEBUG
printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n",ok,alg_k,alg_a,mask_k,mask_a,(void *)c, fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n",ok,alg_k,alg_a,mask_k,mask_a,(void *)c,
c->name); c->name);
#endif #endif
} }
@ -4000,6 +4000,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
} }
ok = ok && ec_ok; ok = ok && ec_ok;
} }
#ifndef OPENSSL_NO_ECDH
if ( if (
/* if we are considering an ECC cipher suite that uses an ephemeral EC key */ /* if we are considering an ECC cipher suite that uses an ephemeral EC key */
(alg_k & SSL_kEECDH) (alg_k & SSL_kEECDH)
@ -4047,6 +4048,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
} }
ok = ok && ec_ok; ok = ok && ec_ok;
} }
#endif /* OPENSSL_NO_ECDH */
#endif /* OPENSSL_NO_EC */ #endif /* OPENSSL_NO_EC */
#endif /* OPENSSL_NO_TLSEXT */ #endif /* OPENSSL_NO_TLSEXT */

View File

@ -60,7 +60,7 @@
#include <openssl/objects.h> #include <openssl/objects.h>
#include "ssl_locl.h" #include "ssl_locl.h"
static const SSL_METHOD *ssl3_get_method(int ver); #ifndef OPENSSL_NO_SSL3_METHOD
static const SSL_METHOD *ssl3_get_method(int ver) static const SSL_METHOD *ssl3_get_method(int ver)
{ {
if (ver == SSL3_VERSION) if (ver == SSL3_VERSION)
@ -73,5 +73,4 @@ IMPLEMENT_ssl3_meth_func(SSLv3_method,
ssl3_accept, ssl3_accept,
ssl3_connect, ssl3_connect,
ssl3_get_method) ssl3_get_method)
#endif

View File

@ -183,6 +183,8 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
* at once (as long as it fits into the buffer). */ * at once (as long as it fits into the buffer). */
if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
{ {
if (left == 0 && extend)
return 0;
if (left > 0 && n > left) if (left > 0 && n > left)
n = left; n = left;
} }
@ -856,8 +858,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
wr->length += eivlen; wr->length += eivlen;
} }
/* ssl3_enc can only have an error on read */ if(s->method->ssl3_enc->enc(s,1)<1) goto err;
s->method->ssl3_enc->enc(s,1);
/* record length after mac and block padding */ /* record length after mac and block padding */
s2n(wr->length,plen); s2n(wr->length,plen);

View File

@ -170,6 +170,7 @@
#endif #endif
#include <openssl/md5.h> #include <openssl/md5.h>
#ifndef OPENSSL_NO_SSL3_METHOD
static const SSL_METHOD *ssl3_get_server_method(int ver); static const SSL_METHOD *ssl3_get_server_method(int ver);
static const SSL_METHOD *ssl3_get_server_method(int ver) static const SSL_METHOD *ssl3_get_server_method(int ver)
@ -180,6 +181,12 @@ static const SSL_METHOD *ssl3_get_server_method(int ver)
return(NULL); return(NULL);
} }
IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
ssl3_accept,
ssl_undefined_function,
ssl3_get_server_method)
#endif
#ifndef OPENSSL_NO_SRP #ifndef OPENSSL_NO_SRP
static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
{ {
@ -206,11 +213,6 @@ static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
} }
#endif #endif
IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
ssl3_accept,
ssl_undefined_function,
ssl3_get_server_method)
int ssl3_accept(SSL *s) int ssl3_accept(SSL *s)
{ {
BUF_MEM *buf; BUF_MEM *buf;
@ -284,6 +286,7 @@ int ssl3_accept(SSL *s)
} }
if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
{ {
BUF_MEM_free(buf);
ret= -1; ret= -1;
goto end; goto end;
} }
@ -298,6 +301,9 @@ int ssl3_accept(SSL *s)
s->init_num=0; s->init_num=0;
s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE; s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
/* Should have been reset by ssl3_get_finished, too. */
s->s3->change_cipher_spec = 0;
if (s->state != SSL_ST_RENEGOTIATE) if (s->state != SSL_ST_RENEGOTIATE)
{ {
@ -441,20 +447,11 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SW_KEY_EXCH_B: case SSL3_ST_SW_KEY_EXCH_B:
alg_k = s->s3->tmp.new_cipher->algorithm_mkey; alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
/* clear this, it may get reset by /*
* send_server_key_exchange */ * clear this, it may get reset by
if ((s->options & SSL_OP_EPHEMERAL_RSA) * send_server_key_exchange
#ifndef OPENSSL_NO_KRB5 */
&& !(alg_k & SSL_kKRB5) s->s3->tmp.use_rsa_tmp=0;
#endif /* OPENSSL_NO_KRB5 */
)
/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
* even when forbidden by protocol specs
* (handshake may fail as clients are not required to
* be able to handle this) */
s->s3->tmp.use_rsa_tmp=1;
else
s->s3->tmp.use_rsa_tmp=0;
/* only send if a DH key exchange, fortezza or /* only send if a DH key exchange, fortezza or
@ -468,7 +465,7 @@ int ssl3_accept(SSL *s)
* server certificate contains the server's * server certificate contains the server's
* public key for key exchange. * public key for key exchange.
*/ */
if (s->s3->tmp.use_rsa_tmp if (0
/* PSK: send ServerKeyExchange if PSK identity /* PSK: send ServerKeyExchange if PSK identity
* hint if provided */ * hint if provided */
#ifndef OPENSSL_NO_PSK #ifndef OPENSSL_NO_PSK
@ -674,8 +671,14 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_A:
case SSL3_ST_SR_CERT_VRFY_B: case SSL3_ST_SR_CERT_VRFY_B:
/*
s->s3->flags |= SSL3_FLAGS_CCS_OK; * This *should* be the first time we enable CCS, but be
* extra careful about surrounding code changes. We need
* to set this here because we don't know if we're
* expecting a CertificateVerify or not.
*/
if (!s->s3->change_cipher_spec)
s->s3->flags |= SSL3_FLAGS_CCS_OK;
/* we should decide if we expected this one */ /* we should decide if we expected this one */
ret=ssl3_get_cert_verify(s); ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end; if (ret <= 0) goto end;
@ -694,6 +697,19 @@ int ssl3_accept(SSL *s)
#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
case SSL3_ST_SR_NEXT_PROTO_A: case SSL3_ST_SR_NEXT_PROTO_A:
case SSL3_ST_SR_NEXT_PROTO_B: case SSL3_ST_SR_NEXT_PROTO_B:
/*
* Enable CCS for resumed handshakes with NPN.
* In a full handshake with NPN, we end up here through
* SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was
* already set. Receiving a CCS clears the flag, so make
* sure not to re-enable it to ban duplicates.
* s->s3->change_cipher_spec is set when a CCS is
* processed in s3_pkt.c, and remains set until
* the client's Finished message is read.
*/
if (!s->s3->change_cipher_spec)
s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_next_proto(s); ret=ssl3_get_next_proto(s);
if (ret <= 0) goto end; if (ret <= 0) goto end;
s->init_num = 0; s->init_num = 0;
@ -703,7 +719,18 @@ int ssl3_accept(SSL *s)
case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B: case SSL3_ST_SR_FINISHED_B:
s->s3->flags |= SSL3_FLAGS_CCS_OK; /*
* Enable CCS for resumed handshakes without NPN.
* In a full handshake, we end up here through
* SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was
* already set. Receiving a CCS clears the flag, so make
* sure not to re-enable it to ban duplicates.
* s->s3->change_cipher_spec is set when a CCS is
* processed in s3_pkt.c, and remains set until
* the client's Finished message is read.
*/
if (!s->s3->change_cipher_spec)
s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
SSL3_ST_SR_FINISHED_B); SSL3_ST_SR_FINISHED_B);
if (ret <= 0) goto end; if (ret <= 0) goto end;
@ -775,7 +802,6 @@ int ssl3_accept(SSL *s)
#else #else
if (s->s3->next_proto_neg_seen) if (s->s3->next_proto_neg_seen)
{ {
s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A; s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
} }
else else
@ -1017,7 +1043,16 @@ int ssl3_get_client_hello(SSL *s)
else else
{ {
i=ssl_get_prev_session(s, p, j, d + n); i=ssl_get_prev_session(s, p, j, d + n);
if (i == 1) /*
* Only resume if the session's version matches the negotiated
* version.
* RFC 5246 does not provide much useful advice on resumption
* with a different protocol version. It doesn't forbid it but
* the sanity of such behaviour would be questionable.
* In practice, clients do not accept a version mismatch and
* will abort the handshake with an error.
*/
if (i == 1 && s->version == s->session->ssl_version)
{ /* previous session */ { /* previous session */
s->hit=1; s->hit=1;
} }
@ -1112,14 +1147,15 @@ int ssl3_get_client_hello(SSL *s)
id=s->session->cipher->id; id=s->session->cipher->id;
#ifdef CIPHER_DEBUG #ifdef CIPHER_DEBUG
printf("client sent %d ciphers\n",sk_num(ciphers)); fprintf(stderr,"client sent %d ciphers\n",sk_SSL_CIPHER_num(ciphers));
#endif #endif
for (i=0; i<sk_SSL_CIPHER_num(ciphers); i++) for (i=0; i<sk_SSL_CIPHER_num(ciphers); i++)
{ {
c=sk_SSL_CIPHER_value(ciphers,i); c=sk_SSL_CIPHER_value(ciphers,i);
#ifdef CIPHER_DEBUG #ifdef CIPHER_DEBUG
printf("client [%2d of %2d]:%s\n", fprintf(stderr,"client [%2d of %2d]:%s\n",
i,sk_num(ciphers),SSL_CIPHER_get_name(c)); i,sk_SSL_CIPHER_num(ciphers),
SSL_CIPHER_get_name(c));
#endif #endif
if (c->id == id) if (c->id == id)
{ {
@ -2171,6 +2207,7 @@ int ssl3_get_client_key_exchange(SSL *s)
unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
int decrypt_len; int decrypt_len;
unsigned char decrypt_good, version_good; unsigned char decrypt_good, version_good;
size_t j;
/* FIX THIS UP EAY EAY EAY EAY */ /* FIX THIS UP EAY EAY EAY EAY */
if (s->s3->tmp.use_rsa_tmp) if (s->s3->tmp.use_rsa_tmp)
@ -2209,8 +2246,9 @@ int ssl3_get_client_key_exchange(SSL *s)
{ {
if (!(s->options & SSL_OP_TLS_D5_BUG)) if (!(s->options & SSL_OP_TLS_D5_BUG))
{ {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
goto err; goto f_err;
} }
else else
p-=2; p-=2;
@ -2219,6 +2257,20 @@ int ssl3_get_client_key_exchange(SSL *s)
n=i; n=i;
} }
/*
* Reject overly short RSA ciphertext because we want to be sure
* that the buffer size makes it safe to iterate over the entire
* size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The
* actual expected size is larger due to RSA padding, but the
* bound is sufficient to be safe.
*/
if (n < SSL_MAX_MASTER_KEY_LENGTH)
{
al = SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
goto f_err;
}
/* We must not leak whether a decryption failure occurs because /* We must not leak whether a decryption failure occurs because
* of Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see * of Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see
* RFC 2246, section 7.4.7.1). The code follows that advice of * RFC 2246, section 7.4.7.1). The code follows that advice of
@ -2266,19 +2318,23 @@ int ssl3_get_client_key_exchange(SSL *s)
* to remain non-zero (0xff). */ * to remain non-zero (0xff). */
decrypt_good &= version_good; decrypt_good &= version_good;
/* Now copy rand_premaster_secret over p using /*
* decrypt_good_mask. */ * Now copy rand_premaster_secret over from p using
for (i = 0; i < (int) sizeof(rand_premaster_secret); i++) * decrypt_good_mask. If decryption failed, then p does not
* contain valid plaintext, however, a check above guarantees
* it is still sufficiently large to read from.
*/
for (j = 0; j < sizeof(rand_premaster_secret); j++)
{ {
p[i] = constant_time_select_8(decrypt_good, p[i], p[j] = constant_time_select_8(decrypt_good, p[j],
rand_premaster_secret[i]); rand_premaster_secret[j]);
} }
s->session->master_key_length= s->session->master_key_length=
s->method->ssl3_enc->generate_master_secret(s, s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key, s->session->master_key,
p,i); p,sizeof(rand_premaster_secret));
OPENSSL_cleanse(p,i); OPENSSL_cleanse(p,sizeof(rand_premaster_secret));
} }
else else
#endif #endif
@ -2420,10 +2476,10 @@ int ssl3_get_client_key_exchange(SSL *s)
&kssl_err)) != 0) &kssl_err)) != 0)
{ {
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
printf("kssl_sget_tkt rtn %d [%d]\n", fprintf(stderr,"kssl_sget_tkt rtn %d [%d]\n",
krb5rc, kssl_err.reason); krb5rc, kssl_err.reason);
if (kssl_err.text) if (kssl_err.text)
printf("kssl_err text= %s\n", kssl_err.text); fprintf(stderr,"kssl_err text= %s\n", kssl_err.text);
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
kssl_err.reason); kssl_err.reason);
@ -2437,10 +2493,10 @@ int ssl3_get_client_key_exchange(SSL *s)
&authtime, &kssl_err)) != 0) &authtime, &kssl_err)) != 0)
{ {
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
printf("kssl_check_authent rtn %d [%d]\n", fprintf(stderr,"kssl_check_authent rtn %d [%d]\n",
krb5rc, kssl_err.reason); krb5rc, kssl_err.reason);
if (kssl_err.text) if (kssl_err.text)
printf("kssl_err text= %s\n", kssl_err.text); fprintf(stderr,"kssl_err text= %s\n", kssl_err.text);
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
kssl_err.reason); kssl_err.reason);
@ -2958,7 +3014,7 @@ int ssl3_get_cert_verify(SSL *s)
if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY) if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
{ {
s->s3->tmp.reuse_message=1; s->s3->tmp.reuse_message=1;
if ((peer != NULL) && (type & EVP_PKT_SIGN)) if (peer != NULL)
{ {
al=SSL_AD_UNEXPECTED_MESSAGE; al=SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE); SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
@ -3362,6 +3418,11 @@ int ssl3_send_server_certificate(SSL *s)
} }
l=ssl3_output_cert_chain(s,x); l=ssl3_output_cert_chain(s,x);
if (!l)
{
SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
return(0);
}
s->state=SSL3_ST_SW_CERT_B; s->state=SSL3_ST_SW_CERT_B;
s->init_num=(int)l; s->init_num=(int)l;
s->init_off=0; s->init_off=0;

View File

@ -1,4 +1,4 @@
/* ssl/tls1.h */ /* ssl/srtp.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved. * All rights reserved.
* *
@ -118,6 +118,8 @@
#ifndef HEADER_D1_SRTP_H #ifndef HEADER_D1_SRTP_H
#define HEADER_D1_SRTP_H #define HEADER_D1_SRTP_H
#include <openssl/ssl.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -596,9 +596,8 @@ struct ssl_session_st
#define SSL_OP_SINGLE_ECDH_USE 0x00080000L #define SSL_OP_SINGLE_ECDH_USE 0x00080000L
/* If set, always create a new key when using tmp_dh parameters */ /* If set, always create a new key when using tmp_dh parameters */
#define SSL_OP_SINGLE_DH_USE 0x00100000L #define SSL_OP_SINGLE_DH_USE 0x00100000L
/* Set to always use the tmp_rsa key when doing RSA operations, /* Does nothing: retained for compatibiity */
* even when this violates protocol specs */ #define SSL_OP_EPHEMERAL_RSA 0x0
#define SSL_OP_EPHEMERAL_RSA 0x00200000L
/* Set on servers to choose the cipher according to the server's /* Set on servers to choose the cipher according to the server's
* preferences */ * preferences */
#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L #define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L
@ -654,8 +653,13 @@ struct ssl_session_st
#define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L #define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
#define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L #define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
/* Send TLS_FALLBACK_SCSV in the ClientHello. /* Send TLS_FALLBACK_SCSV in the ClientHello.
* To be set by applications that reconnect with a downgraded protocol * To be set only by applications that reconnect with a downgraded protocol
* version; see draft-ietf-tls-downgrade-scsv-00 for details. */ * version; see draft-ietf-tls-downgrade-scsv-00 for details.
*
* DO NOT ENABLE THIS if your application attempts a normal handshake.
* Only use this in explicit fallback retries, following the guidance
* in draft-ietf-tls-downgrade-scsv-00.
*/
#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L #define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L
/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
@ -688,6 +692,10 @@ struct ssl_session_st
SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL) SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
#define SSL_set_mtu(ssl, mtu) \ #define SSL_set_mtu(ssl, mtu) \
SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
#define DTLS_set_link_mtu(ssl, mtu) \
SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL)
#define DTLS_get_link_min_mtu(ssl) \
SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL)
#define SSL_get_secure_renegotiation_support(ssl) \ #define SSL_get_secure_renegotiation_support(ssl) \
SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
@ -1627,6 +1635,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 #define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83
#define SSL_CTRL_CHECK_PROTO_VERSION 119 #define SSL_CTRL_CHECK_PROTO_VERSION 119
#define DTLS_CTRL_SET_LINK_MTU 120
#define DTLS_CTRL_GET_LINK_MIN_MTU 121
#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)
@ -1878,13 +1888,15 @@ const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */
const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */ const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */
#endif #endif
#ifndef OPENSSL_NO_SSL3_METHOD
const SSL_METHOD *SSLv3_method(void); /* SSLv3 */ const SSL_METHOD *SSLv3_method(void); /* SSLv3 */
const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */ const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */
const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */ const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */
#endif
const SSL_METHOD *SSLv23_method(void); /* SSLv3 but can rollback to v2 */ const SSL_METHOD *SSLv23_method(void); /* Negotiate highest available SSL/TLS version */
const SSL_METHOD *SSLv23_server_method(void); /* SSLv3 but can rollback to v2 */ const SSL_METHOD *SSLv23_server_method(void); /* Negotiate highest available SSL/TLS version */
const SSL_METHOD *SSLv23_client_method(void); /* SSLv3 but can rollback to v2 */ const SSL_METHOD *SSLv23_client_method(void); /* Negotiate highest available SSL/TLS version */
const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */
const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */ const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */

View File

@ -393,8 +393,12 @@ typedef struct ssl3_buffer_st
#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 #define TLS1_FLAGS_TLS_PADDING_BUG 0x0008
#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 #define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010
#define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020 #define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020
/*
* Set when the handshake is ready to process peer's ChangeCipherSpec message.
* Cleared after the message has been processed.
*/
#define SSL3_FLAGS_CCS_OK 0x0080 #define SSL3_FLAGS_CCS_OK 0x0080
/* SSL3_FLAGS_SGC_RESTART_DONE is set when we /* SSL3_FLAGS_SGC_RESTART_DONE is set when we
* restart a handshake because of MS SGC and so prevents us * restart a handshake because of MS SGC and so prevents us
* from restarting the handshake in a loop. It's reset on a * from restarting the handshake in a loop. It's reset on a
@ -456,8 +460,11 @@ typedef struct ssl3_state_st
* and freed and MD_CTX-es for all required digests are stored in * and freed and MD_CTX-es for all required digests are stored in
* this array */ * this array */
EVP_MD_CTX **handshake_dgst; EVP_MD_CTX **handshake_dgst;
/* this is set whenerver we see a change_cipher_spec message /*
* come in when we are not looking for one */ * Set whenever an expected ChangeCipherSpec message is processed.
* Unset when the peer's Finished message is received.
* Unexpected ChangeCipherSpec messages trigger a fatal alert.
*/
int change_cipher_spec; int change_cipher_spec;
int warn_alert; int warn_alert;

View File

@ -286,35 +286,6 @@ CERT *ssl_cert_dup(CERT *cert)
ret->pkeys[i].privatekey = cert->pkeys[i].privatekey; ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
CRYPTO_add(&ret->pkeys[i].privatekey->references, 1, CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
CRYPTO_LOCK_EVP_PKEY); CRYPTO_LOCK_EVP_PKEY);
switch(i)
{
/* If there was anything special to do for
* certain types of keys, we'd do it here.
* (Nothing at the moment, I think.) */
case SSL_PKEY_RSA_ENC:
case SSL_PKEY_RSA_SIGN:
/* We have an RSA key. */
break;
case SSL_PKEY_DSA_SIGN:
/* We have a DSA key. */
break;
case SSL_PKEY_DH_RSA:
case SSL_PKEY_DH_DSA:
/* We have a DH key. */
break;
case SSL_PKEY_ECC:
/* We have an ECC key */
break;
default:
/* Can't happen. */
SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
}
} }
} }

View File

@ -814,7 +814,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
co_list[co_list_num].active = 0; co_list[co_list_num].active = 0;
co_list_num++; co_list_num++;
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
printf("\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth); fprintf(stderr,"\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth);
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
/* /*
if (!sk_push(ca_list,(char *)c)) goto err; if (!sk_push(ca_list,(char *)c)) goto err;
@ -931,7 +931,7 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
int reverse = 0; int reverse = 0;
#ifdef CIPHER_DEBUG #ifdef CIPHER_DEBUG
printf("Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n", fprintf(stderr, "Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n",
rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength, strength_bits); rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength, strength_bits);
#endif #endif
@ -977,7 +977,7 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
else else
{ {
#ifdef CIPHER_DEBUG #ifdef CIPHER_DEBUG
printf("\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength); fprintf(stderr, "\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength);
#endif #endif
if (alg_mkey && !(alg_mkey & cp->algorithm_mkey)) if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
@ -997,7 +997,7 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
} }
#ifdef CIPHER_DEBUG #ifdef CIPHER_DEBUG
printf("Action = %d\n", rule); fprintf(stderr, "Action = %d\n", rule);
#endif #endif
/* add the cipher if it has not been added yet. */ /* add the cipher if it has not been added yet. */
@ -1386,7 +1386,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
*/ */
num_of_ciphers = ssl_method->num_ciphers(); num_of_ciphers = ssl_method->num_ciphers();
#ifdef KSSL_DEBUG #ifdef KSSL_DEBUG
printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers); fprintf(stderr,"ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers);
#endif /* KSSL_DEBUG */ #endif /* KSSL_DEBUG */
co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers); co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);
if (co_list == NULL) if (co_list == NULL)
@ -1513,7 +1513,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
{ {
sk_SSL_CIPHER_push(cipherstack, curr->cipher); sk_SSL_CIPHER_push(cipherstack, curr->cipher);
#ifdef CIPHER_DEBUG #ifdef CIPHER_DEBUG
printf("<%s>\n",curr->cipher->name); fprintf(stderr, "<%s>\n",curr->cipher->name);
#endif #endif
} }
} }

View File

@ -383,13 +383,7 @@ SSL *SSL_new(SSL_CTX *ctx)
return(s); return(s);
err: err:
if (s != NULL) if (s != NULL)
{ SSL_free(s);
if (s->cert != NULL)
ssl_cert_free(s->cert);
if (s->ctx != NULL)
SSL_CTX_free(s->ctx); /* decrement reference count */
OPENSSL_free(s);
}
SSLerr(SSL_F_SSL_NEW,ERR_R_MALLOC_FAILURE); SSLerr(SSL_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
return(NULL); return(NULL);
} }
@ -1080,19 +1074,6 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
l=s->max_cert_list; l=s->max_cert_list;
s->max_cert_list=larg; s->max_cert_list=larg;
return(l); return(l);
case SSL_CTRL_SET_MTU:
#ifndef OPENSSL_NO_DTLS1
if (larg < (long)dtls1_min_mtu())
return 0;
#endif
if (SSL_version(s) == DTLS1_VERSION ||
SSL_version(s) == DTLS1_BAD_VER)
{
s->d1->mtu = larg;
return larg;
}
return 0;
case SSL_CTRL_SET_MAX_SEND_FRAGMENT: case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
return 0; return 0;
@ -1507,6 +1488,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK); ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK);
goto err; goto err;
} }
p += n;
continue; continue;
} }
@ -2112,7 +2094,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
#ifdef CIPHER_DEBUG #ifdef CIPHER_DEBUG
printf("rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n", fprintf(stderr,"rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
rsa_tmp,rsa_tmp_export,dh_tmp,have_ecdh_tmp, rsa_tmp,rsa_tmp_export,dh_tmp,have_ecdh_tmp,
rsa_enc,rsa_enc_export,rsa_sign,dsa_sign,dh_rsa,dh_dsa); rsa_enc,rsa_enc_export,rsa_sign,dsa_sign,dh_rsa,dh_dsa);
#endif #endif
@ -2996,10 +2978,32 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
} }
ssl_cert_free(ocert); ssl_cert_free(ocert);
} }
/*
* Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH),
* so setter APIs must prevent invalid lengths from entering the system.
*/
OPENSSL_assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
/*
* If the session ID context matches that of the parent SSL_CTX,
* inherit it from the new SSL_CTX as well. If however the context does
* not match (i.e., it was set per-ssl with SSL_set_session_id_context),
* leave it unchanged.
*/
if ((ssl->ctx != NULL) &&
(ssl->sid_ctx_length == ssl->ctx->sid_ctx_length) &&
(memcmp(ssl->sid_ctx, ssl->ctx->sid_ctx, ssl->sid_ctx_length) == 0))
{
ssl->sid_ctx_length = ctx->sid_ctx_length;
memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx));
}
CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
if (ssl->ctx != NULL) if (ssl->ctx != NULL)
SSL_CTX_free(ssl->ctx); /* decrement reference count */ SSL_CTX_free(ssl->ctx); /* decrement reference count */
ssl->ctx = ctx; ssl->ctx = ctx;
return(ssl->ctx); return(ssl->ctx);
} }

View File

@ -864,7 +864,7 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, int len);
int ssl2_enc_init(SSL *s, int client); int ssl2_enc_init(SSL *s, int client);
int ssl2_generate_key_material(SSL *s); int ssl2_generate_key_material(SSL *s);
void ssl2_enc(SSL *s,int send_data); int ssl2_enc(SSL *s,int send_data);
void ssl2_mac(SSL *s,unsigned char *mac,int send_data); void ssl2_mac(SSL *s,unsigned char *mac,int send_data);
const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p); const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p);
int ssl2_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p); int ssl2_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p);
@ -997,7 +997,9 @@ void dtls1_stop_timer(SSL *s);
int dtls1_is_timer_expired(SSL *s); int dtls1_is_timer_expired(SSL *s);
void dtls1_double_timeout(SSL *s); void dtls1_double_timeout(SSL *s);
int dtls1_send_newsession_ticket(SSL *s); int dtls1_send_newsession_ticket(SSL *s);
unsigned int dtls1_min_mtu(void); unsigned int dtls1_min_mtu(SSL *s);
unsigned int dtls1_link_min_mtu(void);
void dtls1_hm_fragment_free(hm_fragment *frag);
/* some client-only functions */ /* some client-only functions */
int ssl3_client_hello(SSL *s); int ssl3_client_hello(SSL *s);
@ -1014,7 +1016,6 @@ int ssl3_get_key_exchange(SSL *s);
int ssl3_get_server_certificate(SSL *s); int ssl3_get_server_certificate(SSL *s);
int ssl3_check_cert_and_algorithm(SSL *s); int ssl3_check_cert_and_algorithm(SSL *s);
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
int ssl3_check_finished(SSL *s);
# ifndef OPENSSL_NO_NEXTPROTONEG # ifndef OPENSSL_NO_NEXTPROTONEG
int ssl3_send_next_proto(SSL *s); int ssl3_send_next_proto(SSL *s);
# endif # endif

View File

@ -335,7 +335,21 @@ int ssl_get_new_session(SSL *s, int session)
return(0); return(0);
} }
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
/* If RFC4507 ticket use empty session ID */ /*
* If RFC5077 ticket, use empty session ID (as server).
* Note that:
* (a) ssl_get_prev_session() does lookahead into the
* ClientHello extensions to find the session ticket.
* When ssl_get_prev_session() fails, s3_srvr.c calls
* ssl_get_new_session() in ssl3_get_client_hello().
* At that point, it has not yet parsed the extensions,
* however, because of the lookahead, it already knows
* whether a ticket is expected or not.
*
* (b) s3_clnt.c calls ssl_get_new_session() before parsing
* ServerHello extensions, and before recording the session
* ID received from the server, so this block is a noop.
*/
if (s->tlsext_ticket_expected) if (s->tlsext_ticket_expected)
{ {
ss->session_id_length = 0; ss->session_id_length = 0;

View File

@ -345,7 +345,7 @@ static void sv_usage(void)
#ifndef OPENSSL_NO_SSL2 #ifndef OPENSSL_NO_SSL2
fprintf(stderr," -ssl2 - use SSLv2\n"); fprintf(stderr," -ssl2 - use SSLv2\n");
#endif #endif
#ifndef OPENSSL_NO_SSL3 #ifndef OPENSSL_NO_SSL3_METHOD
fprintf(stderr," -ssl3 - use SSLv3\n"); fprintf(stderr," -ssl3 - use SSLv3\n");
#endif #endif
#ifndef OPENSSL_NO_TLS1 #ifndef OPENSSL_NO_TLS1
@ -368,7 +368,9 @@ static void sv_usage(void)
" Use \"openssl ecparam -list_curves\" for all names\n" \ " Use \"openssl ecparam -list_curves\" for all names\n" \
" (default is sect163r2).\n"); " (default is sect163r2).\n");
#endif #endif
fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n"); fprintf(stderr," -test_cipherlist - Verifies the order of the ssl cipher lists.\n"
" When this option is requested, the cipherlist\n"
" tests are run instead of handshake tests.\n");
} }
static void print_details(SSL *c_ssl, const char *prefix) static void print_details(SSL *c_ssl, const char *prefix)
@ -549,6 +551,7 @@ int main(int argc, char *argv[])
#ifdef OPENSSL_FIPS #ifdef OPENSSL_FIPS
int fips_mode=0; int fips_mode=0;
#endif #endif
int no_protocol = 0;
verbose = 0; verbose = 0;
debug = 0; debug = 0;
@ -658,11 +661,26 @@ int main(int argc, char *argv[])
} }
#endif #endif
else if (strcmp(*argv,"-ssl2") == 0) else if (strcmp(*argv,"-ssl2") == 0)
ssl2=1; {
#ifdef OPENSSL_NO_SSL2
no_protocol = 1;
#endif
ssl2 = 1;
}
else if (strcmp(*argv,"-tls1") == 0) else if (strcmp(*argv,"-tls1") == 0)
tls1=1; {
#ifdef OPENSSL_NO_TLS1
no_protocol = 1;
#endif
tls1 = 1;
}
else if (strcmp(*argv,"-ssl3") == 0) else if (strcmp(*argv,"-ssl3") == 0)
ssl3=1; {
#ifdef OPENSSL_NO_SSL3_METHOD
no_protocol = 1;
#endif
ssl3 = 1;
}
else if (strncmp(*argv,"-num",4) == 0) else if (strncmp(*argv,"-num",4) == 0)
{ {
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
@ -781,15 +799,41 @@ int main(int argc, char *argv[])
goto end; goto end;
} }
/*
* test_cipherlist prevails over protocol switch: we test the cipherlist
* for all enabled protocols.
*/
if (test_cipherlist == 1) if (test_cipherlist == 1)
{ {
/* ensure that the cipher list are correctly sorted and exit */ /* ensure that the cipher list are correctly sorted and exit */
fprintf(stdout, "Testing cipherlist order only. Ignoring all "
"other options.\n");
if (do_test_cipherlist() == 0) if (do_test_cipherlist() == 0)
EXIT(1); EXIT(1);
ret = 0; ret = 0;
goto end; goto end;
} }
if (ssl2 + ssl3 + tls1 > 1)
{
fprintf(stderr, "At most one of -ssl2, -ssl3, or -tls1 should "
"be requested.\n");
EXIT(1);
}
/*
* Testing was requested for a compiled-out protocol (e.g. SSLv2).
* Ideally, we would error out, but the generic test wrapper can't know
* when to expect failure. So we do nothing and return success.
*/
if (no_protocol)
{
fprintf(stderr, "Testing was requested for a disabled protocol. "
"Skipping tests.\n");
ret = 0;
goto end;
}
if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force) if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force)
{ {
fprintf(stderr, "This case cannot work. Use -f to perform " fprintf(stderr, "This case cannot work. Use -f to perform "
@ -868,30 +912,25 @@ int main(int argc, char *argv[])
} }
#endif #endif
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) /* At this point, ssl2/ssl3/tls1 is only set if the protocol is available.
* (Otherwise we exit early.)
* However the compiler doesn't know this, so we ifdef. */
#ifndef OPENSSL_NO_SSL2
if (ssl2) if (ssl2)
meth=SSLv2_method(); meth=SSLv2_method();
else
if (tls1)
meth=TLSv1_method();
else else
#endif
#ifndef OPENSSL_NO_SSL3
if (ssl3) if (ssl3)
meth=SSLv3_method(); meth=SSLv3_method();
else else
meth=SSLv23_method(); #endif
#else #ifndef OPENSSL_NO_TLS1
#ifdef OPENSSL_NO_SSL2
if (tls1) if (tls1)
meth=TLSv1_method(); meth=TLSv1_method();
else else
if (ssl3)
meth=SSLv3_method();
else
meth=SSLv23_method();
#else
meth=SSLv2_method();
#endif
#endif #endif
meth=SSLv23_method();
c_ctx=SSL_CTX_new(meth); c_ctx=SSL_CTX_new(meth);
s_ctx=SSL_CTX_new(meth); s_ctx=SSL_CTX_new(meth);

Some files were not shown because too many files have changed in this diff Show More