From e6bc27f598cd201e6b06905e35059a83926e6920 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Fri, 12 Oct 2007 19:40:12 +0000 Subject: [PATCH] Import OpenSSL-0.9.8f. --- crypto/openssl-0.9/CHANGES | 182 ++- crypto/openssl-0.9/FAQ | 13 +- crypto/openssl-0.9/NEWS | 11 + crypto/openssl-0.9/README | 15 +- crypto/openssl-0.9/apps/CA.pl | 2 +- crypto/openssl-0.9/apps/dgst.c | 22 +- crypto/openssl-0.9/apps/dsa.c | 4 + crypto/openssl-0.9/apps/gendsa.c | 8 + crypto/openssl-0.9/apps/genrsa.c | 8 + crypto/openssl-0.9/apps/ocsp.c | 2 +- crypto/openssl-0.9/apps/pkcs12.c | 10 +- crypto/openssl-0.9/apps/progs.h | 15 + crypto/openssl-0.9/apps/rand.c | 2 +- crypto/openssl-0.9/apps/rsa.c | 4 + crypto/openssl-0.9/apps/s_apps.h | 3 + crypto/openssl-0.9/apps/s_cb.c | 61 +- crypto/openssl-0.9/apps/s_client.c | 140 +- crypto/openssl-0.9/apps/s_server.c | 296 ++++- crypto/openssl-0.9/apps/smime.c | 7 + crypto/openssl-0.9/apps/speed.c | 138 +- crypto/openssl-0.9/crypto/aes/aes_ige.c | 206 +-- crypto/openssl-0.9/crypto/asn1/asn1.h | 63 +- crypto/openssl-0.9/crypto/asn1/asn_moid.c | 2 +- crypto/openssl-0.9/crypto/asn1/t_req.c | 4 +- crypto/openssl-0.9/crypto/asn1/tasn_dec.c | 4 +- crypto/openssl-0.9/crypto/asn1/tasn_enc.c | 2 +- crypto/openssl-0.9/crypto/asn1/x_crl.c | 2 +- crypto/openssl-0.9/crypto/asn1/x_name.c | 40 +- crypto/openssl-0.9/crypto/bio/b_print.c | 4 +- crypto/openssl-0.9/crypto/bio/b_sock.c | 10 +- crypto/openssl-0.9/crypto/bio/bio.h | 16 +- crypto/openssl-0.9/crypto/bn/bn.h | 20 +- crypto/openssl-0.9/crypto/bn/bn_blind.c | 12 +- crypto/openssl-0.9/crypto/bn/bn_div.c | 236 +++- crypto/openssl-0.9/crypto/bn/bn_err.c | 4 +- crypto/openssl-0.9/crypto/bn/bn_exp.c | 20 +- crypto/openssl-0.9/crypto/bn/bn_gcd.c | 161 +++ crypto/openssl-0.9/crypto/bn/bn_lib.c | 2 +- crypto/openssl-0.9/crypto/bn/bn_mont.c | 80 +- crypto/openssl-0.9/crypto/bn/bn_mul.c | 8 +- crypto/openssl-0.9/crypto/bn/bn_prime.c | 4 +- crypto/openssl-0.9/crypto/bn/bn_prime.h | 4 +- crypto/openssl-0.9/crypto/conf/conf.h | 1 + crypto/openssl-0.9/crypto/conf/conf_api.c | 2 +- crypto/openssl-0.9/crypto/conf/conf_mod.c | 11 +- crypto/openssl-0.9/crypto/conf/conf_sap.c | 4 +- crypto/openssl-0.9/crypto/cryptlib.c | 4 +- crypto/openssl-0.9/crypto/des/set_key.c | 2 +- crypto/openssl-0.9/crypto/dh/dh_check.c | 2 +- crypto/openssl-0.9/crypto/dh/dh_key.c | 4 +- crypto/openssl-0.9/crypto/dsa/dsa_gen.c | 11 +- crypto/openssl-0.9/crypto/dsa/dsa_key.c | 2 +- crypto/openssl-0.9/crypto/dsa/dsa_ossl.c | 2 +- crypto/openssl-0.9/crypto/ec/ec.h | 1 + crypto/openssl-0.9/crypto/ec/ec_err.c | 3 +- crypto/openssl-0.9/crypto/ec/ec_mult.c | 34 +- .../openssl-0.9/crypto/engine/eng_padlock.c | 2 +- crypto/openssl-0.9/crypto/engine/eng_table.c | 4 +- crypto/openssl-0.9/crypto/evp/c_allc.c | 9 + crypto/openssl-0.9/crypto/evp/evp.h | 9 + crypto/openssl-0.9/crypto/evp/evp_lib.c | 2 +- crypto/openssl-0.9/crypto/evp/evp_locl.h | 2 +- crypto/openssl-0.9/crypto/ex_data.c | 2 +- crypto/openssl-0.9/crypto/mem_clr.c | 12 +- crypto/openssl-0.9/crypto/objects/obj_dat.h | 38 +- crypto/openssl-0.9/crypto/objects/obj_mac.h | 25 + crypto/openssl-0.9/crypto/ocsp/ocsp.h | 2 +- crypto/openssl-0.9/crypto/opensslv.h | 6 +- crypto/openssl-0.9/crypto/pem/pem.h | 63 +- crypto/openssl-0.9/crypto/pkcs7/pk7_mime.c | 4 +- crypto/openssl-0.9/crypto/pkcs7/pk7_smime.c | 2 +- crypto/openssl-0.9/crypto/pqueue/pq_compat.h | 2 +- crypto/openssl-0.9/crypto/rand/randfile.c | 4 +- crypto/openssl-0.9/crypto/rsa/rsa.h | 16 +- crypto/openssl-0.9/crypto/rsa/rsa_eay.c | 87 +- crypto/openssl-0.9/crypto/rsa/rsa_gen.c | 33 +- crypto/openssl-0.9/crypto/rsa/rsa_lib.c | 14 +- crypto/openssl-0.9/crypto/stack/safestack.h | 96 +- crypto/openssl-0.9/crypto/store/str_lib.c | 2 +- crypto/openssl-0.9/crypto/x509/x509_txt.c | 2 +- crypto/openssl-0.9/crypto/x509/x509_vfy.c | 4 +- crypto/openssl-0.9/crypto/x509/x509_vpm.c | 2 +- crypto/openssl-0.9/crypto/x509v3/pcy_tree.c | 4 +- crypto/openssl-0.9/crypto/x509v3/v3_pci.c | 11 - crypto/openssl-0.9/engines/e_ubsec.c | 4 +- crypto/openssl-0.9/ssl/d1_both.c | 1150 ++++++++--------- crypto/openssl-0.9/ssl/d1_clnt.c | 27 +- crypto/openssl-0.9/ssl/d1_lib.c | 20 + crypto/openssl-0.9/ssl/d1_pkt.c | 96 +- crypto/openssl-0.9/ssl/d1_srvr.c | 43 +- crypto/openssl-0.9/ssl/dtls1.h | 7 +- crypto/openssl-0.9/ssl/s23_clnt.c | 16 + crypto/openssl-0.9/ssl/s2_clnt.c | 4 +- crypto/openssl-0.9/ssl/s2_srvr.c | 4 +- crypto/openssl-0.9/ssl/s3_clnt.c | 173 ++- crypto/openssl-0.9/ssl/s3_lib.c | 199 ++- crypto/openssl-0.9/ssl/s3_srvr.c | 147 ++- crypto/openssl-0.9/ssl/ssl.h | 77 +- crypto/openssl-0.9/ssl/ssl3.h | 5 + crypto/openssl-0.9/ssl/ssl_algs.c | 5 +- crypto/openssl-0.9/ssl/ssl_asn1.c | 101 +- crypto/openssl-0.9/ssl/ssl_cert.c | 2 +- crypto/openssl-0.9/ssl/ssl_ciph.c | 23 +- crypto/openssl-0.9/ssl/ssl_err.c | 17 +- crypto/openssl-0.9/ssl/ssl_lib.c | 87 +- crypto/openssl-0.9/ssl/ssl_locl.h | 32 +- crypto/openssl-0.9/ssl/ssl_sess.c | 102 +- crypto/openssl-0.9/ssl/ssl_txt.c | 15 + crypto/openssl-0.9/ssl/t1_enc.c | 30 +- crypto/openssl-0.9/ssl/t1_lib.c | 511 ++++++++ crypto/openssl-0.9/ssl/tls1.h | 71 +- 111 files changed, 4172 insertions(+), 1185 deletions(-) diff --git a/crypto/openssl-0.9/CHANGES b/crypto/openssl-0.9/CHANGES index c5a639f989..05bd75df9f 100644 --- a/crypto/openssl-0.9/CHANGES +++ b/crypto/openssl-0.9/CHANGES @@ -2,13 +2,164 @@ OpenSSL CHANGES _______________ - Changes between 0.9.8d and 0.9.8e [23 Feb 2007] + Changes between 0.9.8e and 0.9.8f [11 Oct 2007] + + *) DTLS Handshake overhaul. There were longstanding issues with + OpenSSL DTLS implementation, which were making it impossible for + RFC 4347 compliant client to communicate with OpenSSL server. + Unfortunately just fixing these incompatibilities would "cut off" + pre-0.9.8f clients. To allow for hassle free upgrade post-0.9.8e + server keeps tolerating non RFC compliant syntax. The opposite is + not true, 0.9.8f client can not communicate with earlier server. + This update even addresses CVE-2007-4995. + [Andy Polyakov] + + *) Changes to avoid need for function casts in OpenSSL: some compilers + (gcc 4.2 and later) reject their use. + [Kurt Roeckx , Peter Hartley , + Steve Henson] + + *) Add RFC4507 support to OpenSSL. This includes the corrections in + RFC4507bis. The encrypted ticket format is an encrypted encoded + SSL_SESSION structure, that way new session features are automatically + supported. + + If a client application caches session in an SSL_SESSION structure + support is transparent because tickets are now stored in the encoded + SSL_SESSION. + + The SSL_CTX structure automatically generates keys for ticket + protection in servers so again support should be possible + with no application modification. + + If a client or server wishes to disable RFC4507 support then the option + SSL_OP_NO_TICKET can be set. + + Add a TLS extension debugging callback to allow the contents of any client + or server extensions to be examined. + + This work was sponsored by Google. + [Steve Henson] + + *) Add initial support for TLS extensions, specifically for the server_name + extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now + have new members for a host name. The SSL data structure has an + additional member SSL_CTX *initial_ctx so that new sessions can be + stored in that context to allow for session resumption, even after the + SSL has been switched to a new SSL_CTX in reaction to a client's + server_name extension. + + New functions (subject to change): + + SSL_get_servername() + SSL_get_servername_type() + SSL_set_SSL_CTX() + + New CTRL codes and macros (subject to change): + + SSL_CTRL_SET_TLSEXT_SERVERNAME_CB + - SSL_CTX_set_tlsext_servername_callback() + SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG + - SSL_CTX_set_tlsext_servername_arg() + SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name() + + openssl s_client has a new '-servername ...' option. + + openssl s_server has new options '-servername_host ...', '-cert2 ...', + '-key2 ...', '-servername_fatal' (subject to change). This allows + testing the HostName extension for a specific single host name ('-cert' + and '-key' remain fallbacks for handshakes without HostName + negotiation). If the unrecogninzed_name alert has to be sent, this by + default is a warning; it becomes fatal with the '-servername_fatal' + option. + + [Peter Sylvester, Remy Allais, Christophe Renou, Steve Henson] + + *) Add AES and SSE2 assembly language support to VC++ build. + [Steve Henson] + + *) Mitigate attack on final subtraction in Montgomery reduction. + [Andy Polyakov] + + *) Fix crypto/ec/ec_mult.c to work properly with scalars of value 0 + (which previously caused an internal error). + [Bodo Moeller] + + *) Squeeze another 10% out of IGE mode when in != out. + [Ben Laurie] + + *) AES IGE mode speedup. + [Dean Gaudet (Google)] + + *) Add the Korean symmetric 128-bit cipher SEED (see + http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp) and + add SEED ciphersuites from RFC 4162: + + TLS_RSA_WITH_SEED_CBC_SHA = "SEED-SHA" + TLS_DHE_DSS_WITH_SEED_CBC_SHA = "DHE-DSS-SEED-SHA" + TLS_DHE_RSA_WITH_SEED_CBC_SHA = "DHE-RSA-SEED-SHA" + TLS_DH_anon_WITH_SEED_CBC_SHA = "ADH-SEED-SHA" + + To minimize changes between patchlevels in the OpenSSL 0.9.8 + series, SEED remains excluded from compilation unless OpenSSL + is configured with 'enable-seed'. + [KISA, Bodo Moeller] + + *) Mitigate branch prediction attacks, which can be practical if a + single processor is shared, allowing a spy process to extract + information. For detailed background information, see + http://eprint.iacr.org/2007/039 (O. Aciicmez, S. Gueron, + J.-P. Seifert, "New Branch Prediction Vulnerabilities in OpenSSL + and Necessary Software Countermeasures"). The core of the change + are new versions BN_div_no_branch() and + BN_mod_inverse_no_branch() of BN_div() and BN_mod_inverse(), + respectively, which are slower, but avoid the security-relevant + conditional branches. These are automatically called by BN_div() + and BN_mod_inverse() if the flag BN_FLG_CONSTTIME is set for one + of the input BIGNUMs. Also, BN_is_bit_set() has been changed to + remove a conditional branch. + + BN_FLG_CONSTTIME is the new name for the previous + BN_FLG_EXP_CONSTTIME flag, since it now affects more than just + modular exponentiation. (Since OpenSSL 0.9.7h, setting this flag + in the exponent causes BN_mod_exp_mont() to use the alternative + implementation in BN_mod_exp_mont_consttime().) The old name + remains as a deprecated alias. + + Similary, RSA_FLAG_NO_EXP_CONSTTIME is replaced by a more general + RSA_FLAG_NO_CONSTTIME flag since the RSA implementation now uses + constant-time implementations for more than just exponentiation. + Here too the old name is kept as a deprecated alias. + + BN_BLINDING_new() will now use BN_dup() for the modulus so that + the BN_BLINDING structure gets an independent copy of the + modulus. This means that the previous "BIGNUM *m" argument to + BN_BLINDING_new() and to BN_BLINDING_create_param() now + essentially becomes "const BIGNUM *m", although we can't actually + change this in the header file before 0.9.9. It allows + RSA_setup_blinding() to use BN_with_flags() on the modulus to + enable BN_FLG_CONSTTIME. + + [Matthew D Wood (Intel Corp)] + + *) In the SSL/TLS server implementation, be strict about session ID + context matching (which matters if an application uses a single + external cache for different purposes). Previously, + out-of-context reuse was forbidden only if SSL_VERIFY_PEER was + set. This did ensure strict client verification, but meant that, + with applications using a single external cache for quite + different requirements, clients could circumvent ciphersuite + restrictions for a given session ID context by starting a session + in a different context. + [Bodo Moeller] *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that a ciphersuite string such as "DEFAULT:RSA" cannot enable authentication-only ciphersuites. [Bodo Moeller] + Changes between 0.9.8d and 0.9.8e [23 Feb 2007] + *) Since AES128 and AES256 (and similarly Camellia128 and Camellia256) share a single mask bit in the logic of ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a @@ -1047,7 +1198,20 @@ differing sizes. [Richard Levitte] - Changes between 0.9.7l and 0.9.7m [xx XXX xxxx] + Changes between 0.9.7m and 0.9.7n [xx XXX xxxx] + + *) In the SSL/TLS server implementation, be strict about session ID + context matching (which matters if an application uses a single + external cache for different purposes). Previously, + out-of-context reuse was forbidden only if SSL_VERIFY_PEER was + set. This did ensure strict client verification, but meant that, + with applications using a single external cache for quite + different requirements, clients could circumvent ciphersuite + restrictions for a given session ID context by starting a session + in a different context. + [Bodo Moeller] + + Changes between 0.9.7l and 0.9.7m [23 Feb 2007] *) Cleanse PEM buffers before freeing them since they may contain sensitive data. @@ -1063,6 +1227,20 @@ kludge to work properly if AES128 is available and AES256 isn't. [Victor Duchovni] + *) Expand security boundary to match 1.1.1 module. + [Steve Henson] + + *) Remove redundant features: hash file source, editing of test vectors + modify fipsld to use external fips_premain.c signature. + [Steve Henson] + + *) New perl script mkfipsscr.pl to create shell scripts or batch files to + run algorithm test programs. + [Steve Henson] + + *) Make algorithm test programs more tolerant of whitespace. + [Steve Henson] + *) Have SSL/TLS server implementation tolerate "mismatched" record protocol version while receiving ClientHello even if the ClientHello is fragmented. (The server can't insist on the diff --git a/crypto/openssl-0.9/FAQ b/crypto/openssl-0.9/FAQ index 74bf952ddc..7cd71ca0a9 100644 --- a/crypto/openssl-0.9/FAQ +++ b/crypto/openssl-0.9/FAQ @@ -66,6 +66,7 @@ OpenSSL - Frequently Asked Questions * Why doesn't my server application receive a client certificate? * Why does compilation fail due to an undefined symbol NID_uniqueIdentifier? * I think I've detected a memory leak, is this a bug? +* Why does Valgrind complain about the use of uninitialized data? =============================================================================== @@ -74,7 +75,7 @@ OpenSSL - Frequently Asked Questions * Which is the current version of OpenSSL? The current version is available from . -OpenSSL 0.9.8e was released on February 23rd, 2007. +OpenSSL 0.9.8f was released on October 11th, 2007. In addition to the current stable release, you can also access daily snapshots of the OpenSSL development version at ack = !SSL_session_reused(s) && hn != NULL; + else + BIO_printf(bio_err,"Can't use SSL_get_servername\n"); + + return SSL_TLSEXT_ERR_OK; + } +#endif enum { PROTO_OFF = 0, @@ -287,6 +317,13 @@ int MAIN(int argc, char **argv) struct timeval tv; #endif +#ifndef OPENSSL_NO_TLSEXT + char *servername = NULL; + tlsextctx tlsextcbp = + {NULL,0}; +#endif + char *sess_in = NULL; + char *sess_out = NULL; struct sockaddr peer; int peerlen = sizeof(peer); int enable_timeouts = 0 ; @@ -361,6 +398,16 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; cert_file= *(++argv); } + else if (strcmp(*argv,"-sess_out") == 0) + { + if (--argc < 1) goto bad; + sess_out = *(++argv); + } + else if (strcmp(*argv,"-sess_in") == 0) + { + if (--argc < 1) goto bad; + sess_in = *(++argv); + } else if (strcmp(*argv,"-certform") == 0) { if (--argc < 1) goto bad; @@ -385,6 +432,10 @@ int MAIN(int argc, char **argv) c_Pause=1; else if (strcmp(*argv,"-debug") == 0) c_debug=1; +#ifndef OPENSSL_NO_TLSEXT + else if (strcmp(*argv,"-tlsextdebug") == 0) + c_tlsextdebug=1; +#endif #ifdef WATT32 else if (strcmp(*argv,"-wdebug") == 0) dbug_init(); @@ -460,6 +511,10 @@ int MAIN(int argc, char **argv) off|=SSL_OP_NO_SSLv3; else if (strcmp(*argv,"-no_ssl2") == 0) off|=SSL_OP_NO_SSLv2; +#ifndef OPENSSL_NO_TLSEXT + else if (strcmp(*argv,"-no_ticket") == 0) + { off|=SSL_OP_NO_TICKET; } +#endif else if (strcmp(*argv,"-serverpref") == 0) off|=SSL_OP_CIPHER_SERVER_PREFERENCE; else if (strcmp(*argv,"-cipher") == 0) @@ -498,6 +553,14 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; inrand= *(++argv); } +#ifndef OPENSSL_NO_TLSEXT + else if (strcmp(*argv,"-servername") == 0) + { + if (--argc < 1) goto bad; + servername= *(++argv); + /* meth=TLSv1_client_method(); */ + } +#endif else { BIO_printf(bio_err,"unknown option %s\n",*argv); @@ -621,8 +684,51 @@ bad: store = SSL_CTX_get_cert_store(ctx); X509_STORE_set_flags(store, vflags); +#ifndef OPENSSL_NO_TLSEXT + if (servername != NULL) + { + tlsextcbp.biodebug = bio_err; + SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); + SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); + } +#endif con=SSL_new(ctx); + if (sess_in) + { + SSL_SESSION *sess; + BIO *stmp = BIO_new_file(sess_in, "r"); + if (!stmp) + { + BIO_printf(bio_err, "Can't open session file %s\n", + sess_in); + ERR_print_errors(bio_err); + goto end; + } + sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL); + BIO_free(stmp); + if (!sess) + { + BIO_printf(bio_err, "Can't open session file %s\n", + sess_in); + ERR_print_errors(bio_err); + goto end; + } + SSL_set_session(con, sess); + SSL_SESSION_free(sess); + } +#ifndef OPENSSL_NO_TLSEXT + if (servername != NULL) + { + if (!SSL_set_tlsext_host_name(con,servername)) + { + BIO_printf(bio_err,"Unable to set TLS servername extension.\n"); + ERR_print_errors(bio_err); + goto end; + } + } +#endif + #ifndef OPENSSL_NO_KRB5 if (con && (con->kssl_ctx = kssl_ctx_new()) != NULL) { @@ -668,7 +774,7 @@ re_start: goto end; } - BIO_ctrl_set_connected(sbio, 1, &peer); + (void)BIO_ctrl_set_connected(sbio, 1, &peer); if ( enable_timeouts) { @@ -714,6 +820,13 @@ re_start: SSL_set_msg_callback(con, msg_cb); SSL_set_msg_callback_arg(con, bio_c_out); } +#ifndef OPENSSL_NO_TLSEXT + if (c_tlsextdebug) + { + SSL_set_tlsext_debug_callback(con, tlsext_cb); + SSL_set_tlsext_debug_arg(con, bio_c_out); + } +#endif SSL_set_bio(con,sbio,sbio); SSL_set_connect_state(con); @@ -752,7 +865,7 @@ re_start: while (mbuf_len>3 && mbuf[3]=='-'); /* STARTTLS command requires EHLO... */ BIO_printf(fbio,"EHLO openssl.client.net\r\n"); - BIO_flush(fbio); + (void)BIO_flush(fbio); /* wait for multi-line response to end EHLO SMTP response */ do { @@ -761,7 +874,7 @@ re_start: foundit=1; } while (mbuf_len>3 && mbuf[3]=='-'); - BIO_flush(fbio); + (void)BIO_flush(fbio); BIO_pop(fbio); BIO_free(fbio); if (!foundit) @@ -785,7 +898,7 @@ re_start: BIO_gets(fbio,mbuf,BUFSIZZ); /* STARTTLS command requires CAPABILITY... */ BIO_printf(fbio,". CAPABILITY\r\n"); - BIO_flush(fbio); + (void)BIO_flush(fbio); /* wait for multi-line CAPABILITY response */ do { @@ -794,7 +907,7 @@ re_start: foundit=1; } while (mbuf_len>3 && mbuf[0]!='.'); - BIO_flush(fbio); + (void)BIO_flush(fbio); BIO_pop(fbio); BIO_free(fbio); if (!foundit) @@ -814,7 +927,7 @@ re_start: mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ); } while (mbuf_len>3 && mbuf[3]=='-'); - BIO_flush(fbio); + (void)BIO_flush(fbio); BIO_pop(fbio); BIO_free(fbio); BIO_printf(sbio,"AUTH TLS\r\n"); @@ -837,6 +950,17 @@ re_start: if (in_init) { in_init=0; + if (sess_out) + { + BIO *stmp = BIO_new_file(sess_out, "w"); + if (stmp) + { + PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con)); + BIO_free(stmp); + } + else + BIO_printf(bio_err, "Error writing session file %s\n", sess_out); + } print_stuff(bio_c_out,con,full_log); if (full_log > 0) full_log--; @@ -1303,6 +1427,6 @@ static void print_stuff(BIO *bio, SSL *s, int full) if (peer != NULL) X509_free(peer); /* flush, or debugging output gets mixed with http response */ - BIO_flush(bio); + (void)BIO_flush(bio); } diff --git a/crypto/openssl-0.9/apps/s_server.c b/crypto/openssl-0.9/apps/s_server.c index 6c433e63fd..7c5775f81c 100644 --- a/crypto/openssl-0.9/apps/s_server.c +++ b/crypto/openssl-0.9/apps/s_server.c @@ -238,6 +238,9 @@ static int bufsize=BUFSIZZ; static int accept_socket= -1; #define TEST_CERT "server.pem" +#ifndef OPENSSL_NO_TLSEXT +#define TEST_CERT2 "server2.pem" +#endif #undef PROG #define PROG s_server_main @@ -247,6 +250,9 @@ static char *cipher=NULL; static int s_server_verify=SSL_VERIFY_NONE; static int s_server_session_id_context = 1; /* anything will do */ static const char *s_cert_file=TEST_CERT,*s_key_file=NULL; +#ifndef OPENSSL_NO_TLSEXT +static const char *s_cert_file2=TEST_CERT2,*s_key_file2=NULL; +#endif static char *s_dcert_file=NULL,*s_dkey_file=NULL; #ifdef FIONBIO static int s_nbio=0; @@ -254,10 +260,16 @@ static int s_nbio=0; static int s_nbio_test=0; int s_crlf=0; static SSL_CTX *ctx=NULL; +#ifndef OPENSSL_NO_TLSEXT +static SSL_CTX *ctx2=NULL; +#endif static int www=0; static BIO *bio_s_out=NULL; static int s_debug=0; +#ifndef OPENSSL_NO_TLSEXT +static int s_tlsextdebug=0; +#endif static int s_msg=0; static int s_quiet=0; @@ -285,6 +297,11 @@ static void s_server_init(void) s_dkey_file=NULL; s_cert_file=TEST_CERT; s_key_file=NULL; +#ifndef OPENSSL_NO_TLSEXT + s_cert_file2=TEST_CERT2; + s_key_file2=NULL; + ctx2=NULL; +#endif #ifdef FIONBIO s_nbio=0; #endif @@ -371,6 +388,16 @@ static void sv_usage(void) #endif BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n"); BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); +#ifndef OPENSSL_NO_TLSEXT + BIO_printf(bio_err," -servername host - servername for HostName TLS extension\n"); + BIO_printf(bio_err," -servername_fatal - on mismatch send fatal alert (default warning alert)\n"); + BIO_printf(bio_err," -cert2 arg - certificate file to use for servername\n"); + BIO_printf(bio_err," (default is %s)\n",TEST_CERT2); + BIO_printf(bio_err," -key2 arg - Private Key file to use for servername, in cert file if\n"); + BIO_printf(bio_err," not specified (default is %s)\n",TEST_CERT2); + BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n"); + BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n"); +#endif } static int local_argc=0; @@ -526,6 +553,39 @@ static int ebcdic_puts(BIO *bp, const char *str) } #endif +#ifndef OPENSSL_NO_TLSEXT + +/* This is a context that we pass to callbacks */ +typedef struct tlsextctx_st { + char * servername; + BIO * biodebug; + int extension_error; +} tlsextctx; + + +static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg) + { + tlsextctx * p = (tlsextctx *) arg; + const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); + if (servername && p->biodebug) + BIO_printf(p->biodebug,"Hostname in TLS extension: \"%s\"\n",servername); + + if (!p->servername) + return SSL_TLSEXT_ERR_NOACK; + + if (servername) + { + if (strcmp(servername,p->servername)) + return p->extension_error; + if (ctx2) + { + BIO_printf(p->biodebug,"Swiching server context.\n"); + SSL_set_SSL_CTX(s,ctx2); + } + } + return SSL_TLSEXT_ERR_OK; +} +#endif int MAIN(int, char **); int MAIN(int argc, char *argv[]) @@ -545,10 +605,7 @@ int MAIN(int argc, char *argv[]) int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0; int state=0; SSL_METHOD *meth=NULL; -#ifdef sock_type -#undef sock_type -#endif - int sock_type=SOCK_STREAM; + int socket_type=SOCK_STREAM; #ifndef OPENSSL_NO_ENGINE ENGINE *e=NULL; #endif @@ -559,6 +616,14 @@ int MAIN(int argc, char *argv[]) int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM; X509 *s_cert = NULL, *s_dcert = NULL; EVP_PKEY *s_key = NULL, *s_dkey = NULL; +#ifndef OPENSSL_NO_TLSEXT + EVP_PKEY *s_key2 = NULL; + X509 *s_cert2 = NULL; +#endif + +#ifndef OPENSSL_NO_TLSEXT + tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING}; +#endif #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) meth=SSLv23_server_method(); @@ -724,6 +789,10 @@ int MAIN(int argc, char *argv[]) } else if (strcmp(*argv,"-debug") == 0) { s_debug=1; } +#ifndef OPENSSL_NO_TLSEXT + else if (strcmp(*argv,"-tlsextdebug") == 0) + s_tlsextdebug=1; +#endif else if (strcmp(*argv,"-msg") == 0) { s_msg=1; } else if (strcmp(*argv,"-hack") == 0) @@ -754,6 +823,10 @@ int MAIN(int argc, char *argv[]) { off|=SSL_OP_NO_SSLv3; } else if (strcmp(*argv,"-no_tls1") == 0) { off|=SSL_OP_NO_TLSv1; } +#ifndef OPENSSL_NO_TLSEXT + else if (strcmp(*argv,"-no_ticket") == 0) + { off|=SSL_OP_NO_TICKET; } +#endif #ifndef OPENSSL_NO_SSL2 else if (strcmp(*argv,"-ssl2") == 0) { meth=SSLv2_server_method(); } @@ -770,7 +843,7 @@ int MAIN(int argc, char *argv[]) else if (strcmp(*argv,"-dtls1") == 0) { meth=DTLSv1_server_method(); - sock_type = SOCK_DGRAM; + socket_type = SOCK_DGRAM; } else if (strcmp(*argv,"-timeout") == 0) enable_timeouts = 1; @@ -799,6 +872,25 @@ int MAIN(int argc, char *argv[]) if (--argc < 1) goto bad; inrand= *(++argv); } +#ifndef OPENSSL_NO_TLSEXT + else if (strcmp(*argv,"-servername") == 0) + { + if (--argc < 1) goto bad; + tlsextcbp.servername= *(++argv); + } + else if (strcmp(*argv,"-servername_fatal") == 0) + { tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; } + else if (strcmp(*argv,"-cert2") == 0) + { + if (--argc < 1) goto bad; + s_cert_file2= *(++argv); + } + else if (strcmp(*argv,"-key2") == 0) + { + if (--argc < 1) goto bad; + s_key_file2= *(++argv); + } +#endif else { BIO_printf(bio_err,"unknown option %s\n",*argv); @@ -831,6 +923,10 @@ bad: if (s_key_file == NULL) s_key_file = s_cert_file; +#ifndef OPENSSL_NO_TLSEXT + if (s_key_file2 == NULL) + s_key_file2 = s_cert_file2; +#endif if (nocert == 0) { @@ -850,8 +946,29 @@ bad: ERR_print_errors(bio_err); goto end; } - } +#ifndef OPENSSL_NO_TLSEXT + if (tlsextcbp.servername) + { + s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e, + "second server certificate private key file"); + if (!s_key2) + { + ERR_print_errors(bio_err); + goto end; + } + + s_cert2 = load_cert(bio_err,s_cert_file2,s_cert_format, + NULL, e, "second server certificate file"); + + if (!s_cert2) + { + ERR_print_errors(bio_err); + goto end; + } + } +#endif + } if (s_dcert_file) { @@ -908,6 +1025,10 @@ bad: s_key_file=NULL; s_dcert_file=NULL; s_dkey_file=NULL; +#ifndef OPENSSL_NO_TLSEXT + s_cert_file2=NULL; + s_key_file2=NULL; +#endif } ctx=SSL_CTX_new(meth); @@ -939,7 +1060,7 @@ bad: /* DTLS: partial reads end up discarding unread UDP bytes :-( * Setting read ahead solves this problem. */ - if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1); + if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1); if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback); @@ -966,6 +1087,62 @@ bad: } store = SSL_CTX_get_cert_store(ctx); X509_STORE_set_flags(store, vflags); +#ifndef OPENSSL_NO_TLSEXT + if (s_cert2) + { + ctx2=SSL_CTX_new(meth); + if (ctx2 == NULL) + { + ERR_print_errors(bio_err); + goto end; + } + } + + if (ctx2) + { + BIO_printf(bio_s_out,"Setting secondary ctx parameters\n"); + + if (session_id_prefix) + { + if(strlen(session_id_prefix) >= 32) + BIO_printf(bio_err, + "warning: id_prefix is too long, only one new session will be possible\n"); + else if(strlen(session_id_prefix) >= 16) + BIO_printf(bio_err, + "warning: id_prefix is too long if you use SSLv2\n"); + if(!SSL_CTX_set_generate_session_id(ctx2, generate_session_id)) + { + BIO_printf(bio_err,"error setting 'id_prefix'\n"); + ERR_print_errors(bio_err); + goto end; + } + BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix); + } + SSL_CTX_set_quiet_shutdown(ctx2,1); + if (bugs) SSL_CTX_set_options(ctx2,SSL_OP_ALL); + if (hack) SSL_CTX_set_options(ctx2,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); + SSL_CTX_set_options(ctx2,off); + + /* DTLS: partial reads end up discarding unread UDP bytes :-( + * Setting read ahead solves this problem. + */ + if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx2, 1); + + + if (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback); + + SSL_CTX_sess_set_cache_size(ctx2,128); + + if ((!SSL_CTX_load_verify_locations(ctx2,CAfile,CApath)) || + (!SSL_CTX_set_default_verify_paths(ctx2))) + { + ERR_print_errors(bio_err); + } + store = SSL_CTX_get_cert_store(ctx2); + X509_STORE_set_flags(store, vflags); + } +#endif + #ifndef OPENSSL_NO_DH if (!no_dhe) @@ -989,6 +1166,24 @@ bad: (void)BIO_flush(bio_s_out); SSL_CTX_set_tmp_dh(ctx,dh); +#ifndef OPENSSL_NO_TLSEXT + if (ctx2) + { + if (!dhfile) + { + DH *dh2=load_dh_param(s_cert_file2); + if (dh2 != NULL) + { + BIO_printf(bio_s_out,"Setting temp DH parameters\n"); + (void)BIO_flush(bio_s_out); + + DH_free(dh); + dh = dh2; + } + } + SSL_CTX_set_tmp_dh(ctx2,dh); + } +#endif DH_free(dh); } #endif @@ -1034,12 +1229,20 @@ bad: (void)BIO_flush(bio_s_out); SSL_CTX_set_tmp_ecdh(ctx,ecdh); +#ifndef OPENSSL_NO_TLSEXT + if (ctx2) + SSL_CTX_set_tmp_ecdh(ctx2,ecdh); +#endif EC_KEY_free(ecdh); } #endif if (!set_cert_key_stuff(ctx,s_cert,s_key)) goto end; +#ifndef OPENSSL_NO_TLSEXT + if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2)) + goto end; +#endif if (s_dcert != NULL) { if (!set_cert_key_stuff(ctx,s_dcert,s_dkey)) @@ -1049,7 +1252,13 @@ bad: #ifndef OPENSSL_NO_RSA #if 1 if (!no_tmp_rsa) + { SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb); +#ifndef OPENSSL_NO_TLSEXT + if (ctx2) + SSL_CTX_set_tmp_rsa_callback(ctx2,tmp_rsa_cb); +#endif + } #else if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx)) { @@ -1065,6 +1274,16 @@ bad: ERR_print_errors(bio_err); goto end; } +#ifndef OPENSSL_NO_TLSEXT + if (ctx2) + { + if (!SSL_CTX_set_tmp_rsa(ctx2,rsa)) + { + ERR_print_errors(bio_err); + goto end; + } + } +#endif RSA_free(rsa); BIO_printf(bio_s_out,"\n"); } @@ -1076,19 +1295,46 @@ bad: BIO_printf(bio_err,"error setting cipher list\n"); ERR_print_errors(bio_err); goto end; +#ifndef OPENSSL_NO_TLSEXT + if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,cipher)) + { + BIO_printf(bio_err,"error setting cipher list\n"); + ERR_print_errors(bio_err); + goto end; + } +#endif } SSL_CTX_set_verify(ctx,s_server_verify,verify_callback); SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context, sizeof s_server_session_id_context); +#ifndef OPENSSL_NO_TLSEXT + if (ctx2) + { + SSL_CTX_set_verify(ctx2,s_server_verify,verify_callback); + SSL_CTX_set_session_id_context(ctx2,(void*)&s_server_session_id_context, + sizeof s_server_session_id_context); + + tlsextcbp.biodebug = bio_s_out; + SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb); + SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp); + SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); + SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); + } +#endif if (CAfile != NULL) - SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); - + { + SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); +#ifndef OPENSSL_NO_TLSEXT + if (ctx2) + SSL_CTX_set_client_CA_list(ctx2,SSL_load_client_CA_file(CAfile)); +#endif + } BIO_printf(bio_s_out,"ACCEPT\n"); if (www) - do_server(port,sock_type,&accept_socket,www_body, context); + do_server(port,socket_type,&accept_socket,www_body, context); else - do_server(port,sock_type,&accept_socket,sv_body, context); + do_server(port,socket_type,&accept_socket,sv_body, context); print_stats(bio_s_out,ctx); ret=0; end: @@ -1105,6 +1351,13 @@ end: OPENSSL_free(pass); if (dpass) OPENSSL_free(dpass); +#ifndef OPENSSL_NO_TLSEXT + if (ctx2 != NULL) SSL_CTX_free(ctx2); + if (s_cert2) + X509_free(s_cert2); + if (s_key2) + EVP_PKEY_free(s_key2); +#endif if (bio_s_out != NULL) { BIO_free(bio_s_out); @@ -1171,6 +1424,13 @@ static int sv_body(char *hostname, int s, unsigned char *context) if (con == NULL) { con=SSL_new(ctx); +#ifndef OPENSSL_NO_TLSEXT + if (s_tlsextdebug) + { + SSL_set_tlsext_debug_callback(con, tlsext_cb); + SSL_set_tlsext_debug_arg(con, bio_s_out); + } +#endif #ifndef OPENSSL_NO_KRB5 if ((con->kssl_ctx = kssl_ctx_new()) != NULL) { @@ -1241,6 +1501,13 @@ static int sv_body(char *hostname, int s, unsigned char *context) SSL_set_msg_callback(con, msg_cb); SSL_set_msg_callback_arg(con, bio_s_out); } +#ifndef OPENSSL_NO_TLSEXT + if (s_tlsextdebug) + { + SSL_set_tlsext_debug_callback(con, tlsext_cb); + SSL_set_tlsext_debug_arg(con, bio_s_out); + } +#endif width=s+1; for (;;) @@ -1606,6 +1873,13 @@ static int www_body(char *hostname, int s, unsigned char *context) if (!BIO_set_write_buffer_size(io,bufsize)) goto err; if ((con=SSL_new(ctx)) == NULL) goto err; +#ifndef OPENSSL_NO_TLSEXT + if (s_tlsextdebug) + { + SSL_set_tlsext_debug_callback(con, tlsext_cb); + SSL_set_tlsext_debug_arg(con, bio_s_out); + } +#endif #ifndef OPENSSL_NO_KRB5 if ((con->kssl_ctx = kssl_ctx_new()) != NULL) { diff --git a/crypto/openssl-0.9/apps/smime.c b/crypto/openssl-0.9/apps/smime.c index 830f18cd84..ce8a1cbecb 100644 --- a/crypto/openssl-0.9/apps/smime.c +++ b/crypto/openssl-0.9/apps/smime.c @@ -145,6 +145,10 @@ int MAIN(int argc, char **argv) else if (!strcmp (*args, "-des")) cipher = EVP_des_cbc(); #endif +#ifndef OPENSSL_NO_SEED + else if (!strcmp (*args, "-seed")) + cipher = EVP_seed_cbc(); +#endif #ifndef OPENSSL_NO_RC2 else if (!strcmp (*args, "-rc2-40")) cipher = EVP_rc2_40_cbc(); @@ -423,6 +427,9 @@ int MAIN(int argc, char **argv) BIO_printf (bio_err, "-des3 encrypt with triple DES\n"); BIO_printf (bio_err, "-des encrypt with DES\n"); #endif +#ifndef OPENSSL_NO_SEED + BIO_printf (bio_err, "-seed encrypt with SEED\n"); +#endif #ifndef OPENSSL_NO_RC2 BIO_printf (bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); BIO_printf (bio_err, "-rc2-64 encrypt with RC2-64\n"); diff --git a/crypto/openssl-0.9/apps/speed.c b/crypto/openssl-0.9/apps/speed.c index 7858aee76e..85f559ed81 100644 --- a/crypto/openssl-0.9/apps/speed.c +++ b/crypto/openssl-0.9/apps/speed.c @@ -201,6 +201,9 @@ #ifndef OPENSSL_NO_IDEA #include #endif +#ifndef OPENSSL_NO_SEED +#include +#endif #ifndef OPENSSL_NO_BF #include #endif @@ -272,7 +275,7 @@ static void print_result(int alg,int run_no,int count,double time_used); static int do_multi(int multi); #endif -#define ALGOR_NUM 24 +#define ALGOR_NUM 28 #define SIZE_NUM 5 #define RSA_NUM 4 #define DSA_NUM 3 @@ -282,11 +285,12 @@ static int do_multi(int multi); static const char *names[ALGOR_NUM]={ "md2","mdc2","md4","md5","hmac(md5)","sha1","rmd160","rc4", - "des cbc","des ede3","idea cbc", + "des cbc","des ede3","idea cbc","seed cbc", "rc2 cbc","rc5-32/12 cbc","blowfish cbc","cast cbc", "aes-128 cbc","aes-192 cbc","aes-256 cbc", "camellia-128 cbc","camellia-192 cbc","camellia-256 cbc", - "evp","sha256","sha512"}; + "evp","sha256","sha512", + "aes-128 ige","aes-192 ige","aes-256 ige"}; static double results[ALGOR_NUM][SIZE_NUM]; static int lengths[SIZE_NUM]={16,64,256,1024,8*1024}; static double rsa_results[RSA_NUM][2]; @@ -533,6 +537,9 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_IDEA IDEA_KEY_SCHEDULE idea_ks; #endif +#ifndef OPENSSL_NO_SEED + SEED_KEY_SCHEDULE seed_ks; +#endif #ifndef OPENSSL_NO_BF BF_KEY bf_ks; #endif @@ -597,19 +604,23 @@ int MAIN(int argc, char **argv) #define D_CBC_DES 8 #define D_EDE3_DES 9 #define D_CBC_IDEA 10 -#define D_CBC_RC2 11 -#define D_CBC_RC5 12 -#define D_CBC_BF 13 -#define D_CBC_CAST 14 -#define D_CBC_128_AES 15 -#define D_CBC_192_AES 16 -#define D_CBC_256_AES 17 -#define D_CBC_128_CML 18 -#define D_CBC_192_CML 19 -#define D_CBC_256_CML 20 -#define D_EVP 21 -#define D_SHA256 22 -#define D_SHA512 23 +#define D_CBC_SEED 11 +#define D_CBC_RC2 12 +#define D_CBC_RC5 13 +#define D_CBC_BF 14 +#define D_CBC_CAST 15 +#define D_CBC_128_AES 16 +#define D_CBC_192_AES 17 +#define D_CBC_256_AES 18 +#define D_CBC_128_CML 19 +#define D_CBC_192_CML 20 +#define D_CBC_256_CML 21 +#define D_EVP 22 +#define D_SHA256 23 +#define D_SHA512 24 +#define D_IGE_128_AES 25 +#define D_IGE_192_AES 26 +#define D_IGE_256_AES 27 double d=0.0; long c[ALGOR_NUM][SIZE_NUM]; #define R_DSA_512 0 @@ -950,7 +961,10 @@ int MAIN(int argc, char **argv) if (strcmp(*argv,"aes-128-cbc") == 0) doit[D_CBC_128_AES]=1; else if (strcmp(*argv,"aes-192-cbc") == 0) doit[D_CBC_192_AES]=1; else if (strcmp(*argv,"aes-256-cbc") == 0) doit[D_CBC_256_AES]=1; - else + else if (strcmp(*argv,"aes-128-ige") == 0) doit[D_IGE_128_AES]=1; + else if (strcmp(*argv,"aes-192-ige") == 0) doit[D_IGE_192_AES]=1; + else if (strcmp(*argv,"aes-256-ige") == 0) doit[D_IGE_256_AES]=1; + else #endif #ifndef OPENSSL_NO_CAMELLIA if (strcmp(*argv,"camellia-128-cbc") == 0) doit[D_CBC_128_CML]=1; @@ -999,6 +1013,11 @@ int MAIN(int argc, char **argv) else if (strcmp(*argv,"idea") == 0) doit[D_CBC_IDEA]=1; else #endif +#ifndef OPENSSL_NO_SEED + if (strcmp(*argv,"seed-cbc") == 0) doit[D_CBC_SEED]=1; + else if (strcmp(*argv,"seed") == 0) doit[D_CBC_SEED]=1; + else +#endif #ifndef OPENSSL_NO_BF if (strcmp(*argv,"bf-cbc") == 0) doit[D_CBC_BF]=1; else if (strcmp(*argv,"blowfish") == 0) doit[D_CBC_BF]=1; @@ -1144,6 +1163,9 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_IDEA BIO_printf(bio_err,"idea-cbc "); #endif +#ifndef OPENSSL_NO_SEED + BIO_printf(bio_err,"seed-cbc "); +#endif #ifndef OPENSSL_NO_RC2 BIO_printf(bio_err,"rc2-cbc "); #endif @@ -1153,7 +1175,7 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_BF BIO_printf(bio_err,"bf-cbc"); #endif -#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_RC2) || \ +#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || !defined(OPENSSL_NO_RC2) || \ !defined(OPENSSL_NO_BF) || !defined(OPENSSL_NO_RC5) BIO_printf(bio_err,"\n"); #endif @@ -1162,6 +1184,7 @@ int MAIN(int argc, char **argv) #endif #ifndef OPENSSL_NO_AES BIO_printf(bio_err,"aes-128-cbc aes-192-cbc aes-256-cbc "); + BIO_printf(bio_err,"aes-128-ige aes-192-ige aes-256-ige "); #endif #ifndef OPENSSL_NO_CAMELLIA BIO_printf(bio_err,"\n"); @@ -1195,6 +1218,9 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_IDEA BIO_printf(bio_err,"idea "); #endif +#ifndef OPENSSL_NO_SEED + BIO_printf(bio_err,"seed "); +#endif #ifndef OPENSSL_NO_RC2 BIO_printf(bio_err,"rc2 "); #endif @@ -1213,10 +1239,10 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_BF BIO_printf(bio_err,"blowfish"); #endif -#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_RC2) || \ - !defined(OPENSSL_NO_DES) || !defined(OPENSSL_NO_RSA) || \ - !defined(OPENSSL_NO_BF) || !defined(OPENSSL_NO_AES) || \ - !defined(OPENSSL_NO_CAMELLIA) +#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || \ + !defined(OPENSSL_NO_RC2) || !defined(OPENSSL_NO_DES) || \ + !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_BF) || \ + !defined(OPENSSL_NO_AES) || !defined(OPENSSL_NO_CAMELLIA) BIO_printf(bio_err,"\n"); #endif @@ -1318,6 +1344,9 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_IDEA idea_set_encrypt_key(key16,&idea_ks); #endif +#ifndef OPENSSL_NO_SEED + SEED_set_key(key16,&seed_ks); +#endif #ifndef OPENSSL_NO_RC4 RC4_set_key(&rc4_ks,16,key16); #endif @@ -1361,6 +1390,7 @@ int MAIN(int argc, char **argv) c[D_CBC_DES][0]=count; c[D_EDE3_DES][0]=count/3; c[D_CBC_IDEA][0]=count; + c[D_CBC_SEED][0]=count; c[D_CBC_RC2][0]=count; c[D_CBC_RC5][0]=count; c[D_CBC_BF][0]=count; @@ -1373,6 +1403,9 @@ int MAIN(int argc, char **argv) c[D_CBC_256_CML][0]=count; c[D_SHA256][0]=count; c[D_SHA512][0]=count; + c[D_IGE_128_AES][0]=count; + c[D_IGE_192_AES][0]=count; + c[D_IGE_256_AES][0]=count; for (i=1; i #include "aes_locl.h" -/* -static void hexdump(FILE *f,const char *title,const unsigned char *s,int l) - { - int n=0; +#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long)) +typedef struct { + unsigned long data[N_WORDS]; +} aes_block_t; - fprintf(f,"%s",title); - for( ; n < l ; ++n) - { - if((n%16) == 0) - fprintf(f,"\n%04x",n); - fprintf(f," %02x",s[n]); - } - fprintf(f,"\n"); - } -*/ +/* XXX: probably some better way to do this */ +#if defined(__i386__) || defined(__x86_64__) +#define UNALIGNED_MEMOPS_ARE_FAST 1 +#else +#define UNALIGNED_MEMOPS_ARE_FAST 0 +#endif + +#if UNALIGNED_MEMOPS_ARE_FAST +#define load_block(d, s) (d) = *(const aes_block_t *)(s) +#define store_block(d, s) *(aes_block_t *)(d) = (s) +#else +#define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE) +#define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE) +#endif /* N.B. The IV for this mode is _twice_ the block size */ @@ -77,68 +81,125 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, unsigned char *ivec, const int enc) { unsigned long n; - unsigned long len = length; - unsigned char tmp[AES_BLOCK_SIZE]; - unsigned char tmp2[AES_BLOCK_SIZE]; - unsigned char prev[AES_BLOCK_SIZE]; - const unsigned char *iv = ivec; - const unsigned char *iv2 = ivec + AES_BLOCK_SIZE; + unsigned long len; OPENSSL_assert(in && out && key && ivec); OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); OPENSSL_assert((length%AES_BLOCK_SIZE) == 0); + len = length / AES_BLOCK_SIZE; + if (AES_ENCRYPT == enc) { - /* XXX: Do a separate case for when in != out (strictly should - check for overlap, too) */ - while (len >= AES_BLOCK_SIZE) + if (in != out && + (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0)) { - /* hexdump(stdout, "in", in, AES_BLOCK_SIZE); */ - /* hexdump(stdout, "iv", iv, AES_BLOCK_SIZE); */ - for(n=0 ; n < AES_BLOCK_SIZE ; ++n) - out[n] = in[n] ^ iv[n]; - /* hexdump(stdout, "in ^ iv", out, AES_BLOCK_SIZE); */ - AES_encrypt(out, out, key); - /* hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */ - /* hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */ - for(n=0 ; n < AES_BLOCK_SIZE ; ++n) - out[n] ^= iv2[n]; - /* hexdump(stdout,"out", out, AES_BLOCK_SIZE); */ - iv = out; - memcpy(prev, in, AES_BLOCK_SIZE); - iv2 = prev; - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; + aes_block_t *ivp = (aes_block_t *)ivec; + aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE); + + while (len) + { + aes_block_t *inp = (aes_block_t *)in; + aes_block_t *outp = (aes_block_t *)out; + + for(n=0 ; n < N_WORDS; ++n) + outp->data[n] = inp->data[n] ^ ivp->data[n]; + AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key); + for(n=0 ; n < N_WORDS; ++n) + outp->data[n] ^= iv2p->data[n]; + ivp = outp; + iv2p = inp; + --len; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + memcpy(ivec, ivp->data, AES_BLOCK_SIZE); + memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); + } + else + { + aes_block_t tmp, tmp2; + aes_block_t iv; + aes_block_t iv2; + + load_block(iv, ivec); + load_block(iv2, ivec + AES_BLOCK_SIZE); + + while (len) + { + load_block(tmp, in); + for(n=0 ; n < N_WORDS; ++n) + tmp2.data[n] = tmp.data[n] ^ iv.data[n]; + AES_encrypt((unsigned char *)tmp2.data, (unsigned char *)tmp2.data, key); + for(n=0 ; n < N_WORDS; ++n) + tmp2.data[n] ^= iv2.data[n]; + store_block(out, tmp2); + iv = tmp2; + iv2 = tmp; + --len; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + memcpy(ivec, iv.data, AES_BLOCK_SIZE); + memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); } - memcpy(ivec, iv, AES_BLOCK_SIZE); - memcpy(ivec + AES_BLOCK_SIZE, iv2, AES_BLOCK_SIZE); } else { - while (len >= AES_BLOCK_SIZE) + if (in != out && + (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0)) { - memcpy(tmp, in, AES_BLOCK_SIZE); - memcpy(tmp2, in, AES_BLOCK_SIZE); - /* hexdump(stdout, "in", in, AES_BLOCK_SIZE); */ - /* hexdump(stdout, "iv2", iv2, AES_BLOCK_SIZE); */ - for(n=0 ; n < AES_BLOCK_SIZE ; ++n) - tmp[n] ^= iv2[n]; - /* hexdump(stdout, "in ^ iv2", tmp, AES_BLOCK_SIZE); */ - AES_decrypt(tmp, out, key); - /* hexdump(stdout, "dec", out, AES_BLOCK_SIZE); */ - /* hexdump(stdout, "iv", ivec, AES_BLOCK_SIZE); */ - for(n=0 ; n < AES_BLOCK_SIZE ; ++n) - out[n] ^= ivec[n]; - /* hexdump(stdout, "out", out, AES_BLOCK_SIZE); */ - memcpy(ivec, tmp2, AES_BLOCK_SIZE); - iv2 = out; - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; + aes_block_t *ivp = (aes_block_t *)ivec; + aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE); + + while (len) + { + aes_block_t tmp; + aes_block_t *inp = (aes_block_t *)in; + aes_block_t *outp = (aes_block_t *)out; + + for(n=0 ; n < N_WORDS; ++n) + tmp.data[n] = inp->data[n] ^ iv2p->data[n]; + AES_decrypt((unsigned char *)tmp.data, (unsigned char *)outp->data, key); + for(n=0 ; n < N_WORDS; ++n) + outp->data[n] ^= ivp->data[n]; + ivp = inp; + iv2p = outp; + --len; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + memcpy(ivec, ivp->data, AES_BLOCK_SIZE); + memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); + } + else + { + aes_block_t tmp, tmp2; + aes_block_t iv; + aes_block_t iv2; + + load_block(iv, ivec); + load_block(iv2, ivec + AES_BLOCK_SIZE); + + while (len) + { + load_block(tmp, in); + tmp2 = tmp; + for(n=0 ; n < N_WORDS; ++n) + tmp.data[n] ^= iv2.data[n]; + AES_decrypt((unsigned char *)tmp.data, (unsigned char *)tmp.data, key); + for(n=0 ; n < N_WORDS; ++n) + tmp.data[n] ^= iv.data[n]; + store_block(out, tmp); + iv = tmp2; + iv2 = tmp; + --len; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + memcpy(ivec, iv.data, AES_BLOCK_SIZE); + memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); } - memcpy(ivec + AES_BLOCK_SIZE, iv2, AES_BLOCK_SIZE); } } @@ -177,17 +238,11 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, iv2 = ivec + AES_BLOCK_SIZE; while (len >= AES_BLOCK_SIZE) { - /* hexdump(stdout, "in", in, AES_BLOCK_SIZE); */ - /* hexdump(stdout, "iv", iv, AES_BLOCK_SIZE); */ for(n=0 ; n < AES_BLOCK_SIZE ; ++n) out[n] = in[n] ^ iv[n]; - /* hexdump(stdout, "in ^ iv", out, AES_BLOCK_SIZE); */ AES_encrypt(out, out, key); - /* hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */ - /* hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */ for(n=0 ; n < AES_BLOCK_SIZE ; ++n) out[n] ^= iv2[n]; - /* hexdump(stdout,"out", out, AES_BLOCK_SIZE); */ iv = out; memcpy(prev, in, AES_BLOCK_SIZE); iv2 = prev; @@ -203,8 +258,6 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, while(len >= AES_BLOCK_SIZE) { out -= AES_BLOCK_SIZE; - /* hexdump(stdout, "intermediate", out, AES_BLOCK_SIZE); */ - /* hexdump(stdout, "iv", iv, AES_BLOCK_SIZE); */ /* XXX: reduce copies by alternating between buffers */ memcpy(tmp, out, AES_BLOCK_SIZE); for(n=0 ; n < AES_BLOCK_SIZE ; ++n) @@ -235,17 +288,11 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, out -= AES_BLOCK_SIZE; memcpy(tmp, in, AES_BLOCK_SIZE); memcpy(tmp2, in, AES_BLOCK_SIZE); - /* hexdump(stdout, "in", in, AES_BLOCK_SIZE); */ - /* hexdump(stdout, "iv2", iv2, AES_BLOCK_SIZE); */ for(n=0 ; n < AES_BLOCK_SIZE ; ++n) tmp[n] ^= iv2[n]; - /* hexdump(stdout, "in ^ iv2", tmp, AES_BLOCK_SIZE); */ AES_decrypt(tmp, out, key); - /* hexdump(stdout, "dec", out, AES_BLOCK_SIZE); */ - /* hexdump(stdout, "iv", iv, AES_BLOCK_SIZE); */ for(n=0 ; n < AES_BLOCK_SIZE ; ++n) out[n] ^= iv[n]; - /* hexdump(stdout, "out", out, AES_BLOCK_SIZE); */ memcpy(tmp3, tmp2, AES_BLOCK_SIZE); iv = tmp3; iv2 = out; @@ -260,17 +307,11 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, { memcpy(tmp, out, AES_BLOCK_SIZE); memcpy(tmp2, out, AES_BLOCK_SIZE); - /* hexdump(stdout, "intermediate", out, AES_BLOCK_SIZE); */ - /* hexdump(stdout, "iv2", iv2, AES_BLOCK_SIZE); */ for(n=0 ; n < AES_BLOCK_SIZE ; ++n) tmp[n] ^= iv2[n]; - /* hexdump(stdout, "out ^ iv2", tmp, AES_BLOCK_SIZE); */ AES_decrypt(tmp, out, key); - /* hexdump(stdout, "dec", out, AES_BLOCK_SIZE); */ - /* hexdump(stdout, "iv", ivec, AES_BLOCK_SIZE); */ for(n=0 ; n < AES_BLOCK_SIZE ; ++n) out[n] ^= iv[n]; - /* hexdump(stdout, "out", out, AES_BLOCK_SIZE); */ memcpy(tmp3, tmp2, AES_BLOCK_SIZE); iv = tmp3; iv2 = out; @@ -278,6 +319,5 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, in += AES_BLOCK_SIZE; out += AES_BLOCK_SIZE; } - } } diff --git a/crypto/openssl-0.9/crypto/asn1/asn1.h b/crypto/openssl-0.9/crypto/asn1/asn1.h index 30f1eecd5b..f15131ea3e 100644 --- a/crypto/openssl-0.9/crypto/asn1/asn1.h +++ b/crypto/openssl-0.9/crypto/asn1/asn1.h @@ -322,6 +322,17 @@ typedef struct ASN1_VALUE_st ASN1_VALUE; #define I2D_OF(type) int (*)(type *,unsigned char **) #define I2D_OF_const(type) int (*)(const type *,unsigned char **) +#define CHECKED_D2I_OF(type, d2i) \ + ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) +#define CHECKED_I2D_OF(type, i2d) \ + ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) +#define CHECKED_NEW_OF(type, xnew) \ + ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) +#define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +#define CHECKED_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + #define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) #define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) #define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) @@ -902,23 +913,41 @@ int ASN1_object_size(int constructed, int length, int tag); /* Used to implement other functions */ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x); + #define ASN1_dup_of(type,i2d,d2i,x) \ - ((type *(*)(I2D_OF(type),D2I_OF(type),type *))openssl_fcast(ASN1_dup))(i2d,d2i,x) + ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(type, x))) + #define ASN1_dup_of_const(type,i2d,d2i,x) \ - ((type *(*)(I2D_OF_const(type),D2I_OF(type),type *))openssl_fcast(ASN1_dup))(i2d,d2i,x) + ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(const type, x))) void *ASN1_item_dup(const ASN1_ITEM *it, void *x); #ifndef OPENSSL_NO_FP_API void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x); + #define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ - ((type *(*)(type *(*)(void),D2I_OF(type),FILE *,type **))openssl_fcast(ASN1_d2i_fp))(xnew,d2i,in,x) + ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x); + #define ASN1_i2d_fp_of(type,i2d,out,x) \ - ((int (*)(I2D_OF(type),FILE *,type *))openssl_fcast(ASN1_i2d_fp))(i2d,out,x) + (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + #define ASN1_i2d_fp_of_const(type,i2d,out,x) \ - ((int (*)(I2D_OF_const(type),FILE *,type *))openssl_fcast(ASN1_i2d_fp))(i2d,out,x) + (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); #endif @@ -927,14 +956,26 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in); #ifndef OPENSSL_NO_BIO void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x); + #define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ - ((type *(*)(type *(*)(void),D2I_OF(type),BIO *,type **))openssl_fcast(ASN1_d2i_bio))(xnew,d2i,in,x) + ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x); + #define ASN1_i2d_bio_of(type,i2d,out,x) \ - ((int (*)(I2D_OF(type),BIO *,type *))openssl_fcast(ASN1_i2d_bio))(i2d,out,x) + (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + #define ASN1_i2d_bio_of_const(type,i2d,out,x) \ - ((int (*)(I2D_OF_const(type),BIO *,const type *))openssl_fcast(ASN1_i2d_bio))(i2d,out,x) + (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); int ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a); int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a); @@ -977,8 +1018,12 @@ void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i); void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_OCTET_STRING **oct); + #define ASN1_pack_string_of(type,obj,i2d,oct) \ - ((ASN1_STRING *(*)(type *,I2D_OF(type),ASN1_OCTET_STRING **))openssl_fcast(ASN1_pack_string))(obj,i2d,oct) + (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \ + CHECKED_I2D_OF(type, i2d), \ + oct)) + ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct); void ASN1_STRING_set_default_mask(unsigned long mask); diff --git a/crypto/openssl-0.9/crypto/asn1/asn_moid.c b/crypto/openssl-0.9/crypto/asn1/asn_moid.c index 72cc1210be..9132350f10 100644 --- a/crypto/openssl-0.9/crypto/asn1/asn_moid.c +++ b/crypto/openssl-0.9/crypto/asn1/asn_moid.c @@ -149,7 +149,7 @@ static int do_create(char *value, char *name) if (lntmp == NULL) return 0; memcpy(lntmp, ln, p - ln); - lntmp[p - ln + 1] = 0; + lntmp[p - ln] = 0; oid = OBJ_nid2obj(nid); oid->ln = lntmp; } diff --git a/crypto/openssl-0.9/crypto/asn1/t_req.c b/crypto/openssl-0.9/crypto/asn1/t_req.c index c779a9bb18..5557e06584 100644 --- a/crypto/openssl-0.9/crypto/asn1/t_req.c +++ b/crypto/openssl-0.9/crypto/asn1/t_req.c @@ -244,7 +244,7 @@ get_next: } } } - if(!(cflag & X509_FLAG_NO_ATTRIBUTES)) + if(!(cflag & X509_FLAG_NO_EXTENSIONS)) { exts = X509_REQ_get_extensions(x); if(exts) @@ -262,7 +262,7 @@ get_next: j=X509_EXTENSION_get_critical(ex); if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0) goto err; - if(!X509V3_EXT_print(bp, ex, 0, 16)) + if(!X509V3_EXT_print(bp, ex, cflag, 16)) { BIO_printf(bp, "%16s", ""); M_ASN1_OCTET_STRING_print(bp,ex->value); diff --git a/crypto/openssl-0.9/crypto/asn1/tasn_dec.c b/crypto/openssl-0.9/crypto/asn1/tasn_dec.c index 66d229b08b..c4a3abe4f6 100644 --- a/crypto/openssl-0.9/crypto/asn1/tasn_dec.c +++ b/crypto/openssl-0.9/crypto/asn1/tasn_dec.c @@ -130,7 +130,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, ASN1_VALUE *ptmpval = NULL; if (!pval) pval = &ptmpval; - asn1_tlc_clear(&c); + c.valid = 0; if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) return *pval; return NULL; @@ -140,7 +140,7 @@ int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt) { ASN1_TLC c; - asn1_tlc_clear(&c); + c.valid = 0; return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); } diff --git a/crypto/openssl-0.9/crypto/asn1/tasn_enc.c b/crypto/openssl-0.9/crypto/asn1/tasn_enc.c index 25c94aa1d9..ed892e2cb2 100644 --- a/crypto/openssl-0.9/crypto/asn1/tasn_enc.c +++ b/crypto/openssl-0.9/crypto/asn1/tasn_enc.c @@ -494,7 +494,7 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, { for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) - sk_ASN1_VALUE_set(sk, i, tder->field); + (void)sk_ASN1_VALUE_set(sk, i, tder->field); } OPENSSL_free(derlst); OPENSSL_free(tmpdat); diff --git a/crypto/openssl-0.9/crypto/asn1/x_crl.c b/crypto/openssl-0.9/crypto/asn1/x_crl.c index b99f8fc522..70d56a67f2 100644 --- a/crypto/openssl-0.9/crypto/asn1/x_crl.c +++ b/crypto/openssl-0.9/crypto/asn1/x_crl.c @@ -84,7 +84,7 @@ static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) * would affect the output of X509_CRL_print(). */ case ASN1_OP_D2I_POST: - sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp); + (void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp); break; } return 1; diff --git a/crypto/openssl-0.9/crypto/asn1/x_name.c b/crypto/openssl-0.9/crypto/asn1/x_name.c index 681e5d110f..04380abc3f 100644 --- a/crypto/openssl-0.9/crypto/asn1/x_name.c +++ b/crypto/openssl-0.9/crypto/asn1/x_name.c @@ -160,40 +160,40 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len int tag, int aclass, char opt, ASN1_TLC *ctx) { const unsigned char *p = *in, *q; - STACK *intname = NULL, **intname_pp = &intname; + union { STACK *s; ASN1_VALUE *a; } intname = {NULL}; + union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL}; int i, j, ret; - X509_NAME *nm = NULL, **nm_pp = &nm; STACK_OF(X509_NAME_ENTRY) *entries; X509_NAME_ENTRY *entry; q = p; /* Get internal representation of Name */ - ret = ASN1_item_ex_d2i((ASN1_VALUE **)intname_pp, + ret = ASN1_item_ex_d2i(&intname.a, &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), tag, aclass, opt, ctx); if(ret <= 0) return ret; if(*val) x509_name_ex_free(val, NULL); - if(!x509_name_ex_new((ASN1_VALUE **)nm_pp, NULL)) goto err; + if(!x509_name_ex_new(&nm.a, NULL)) goto err; /* We've decoded it: now cache encoding */ - if(!BUF_MEM_grow(nm->bytes, p - q)) goto err; - memcpy(nm->bytes->data, q, p - q); + if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err; + memcpy(nm.x->bytes->data, q, p - q); /* Convert internal representation to X509_NAME structure */ - for(i = 0; i < sk_num(intname); i++) { - entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname, i); + for(i = 0; i < sk_num(intname.s); i++) { + entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname.s, i); for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { entry = sk_X509_NAME_ENTRY_value(entries, j); entry->set = i; - if(!sk_X509_NAME_ENTRY_push(nm->entries, entry)) + if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) goto err; } sk_X509_NAME_ENTRY_free(entries); } - sk_free(intname); - nm->modified = 0; - *val = (ASN1_VALUE *)nm; + sk_free(intname.s); + nm.x->modified = 0; + *val = nm.a; *in = p; return ret; err: @@ -219,35 +219,35 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_IT static int x509_name_encode(X509_NAME *a) { - STACK *intname = NULL, **intname_pp = &intname; + union { STACK *s; ASN1_VALUE *a; } intname = {NULL}; int len; unsigned char *p; STACK_OF(X509_NAME_ENTRY) *entries = NULL; X509_NAME_ENTRY *entry; int i, set = -1; - intname = sk_new_null(); - if(!intname) goto memerr; + intname.s = sk_new_null(); + if(!intname.s) goto memerr; for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { entry = sk_X509_NAME_ENTRY_value(a->entries, i); if(entry->set != set) { entries = sk_X509_NAME_ENTRY_new_null(); if(!entries) goto memerr; - if(!sk_push(intname, (char *)entries)) goto memerr; + if(!sk_push(intname.s, (char *)entries)) goto memerr; set = entry->set; } if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr; } - len = ASN1_item_ex_i2d((ASN1_VALUE **)intname_pp, NULL, + len = ASN1_item_ex_i2d(&intname.a, NULL, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); if (!BUF_MEM_grow(a->bytes,len)) goto memerr; p=(unsigned char *)a->bytes->data; - ASN1_item_ex_i2d((ASN1_VALUE **)intname_pp, + ASN1_item_ex_i2d(&intname.a, &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); - sk_pop_free(intname, sk_internal_free); + sk_pop_free(intname.s, sk_internal_free); a->modified = 0; return len; memerr: - sk_pop_free(intname, sk_internal_free); + sk_pop_free(intname.s, sk_internal_free); ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); return -1; } diff --git a/crypto/openssl-0.9/crypto/bio/b_print.c b/crypto/openssl-0.9/crypto/bio/b_print.c index 4857cfe0ce..3a87b0ec0b 100644 --- a/crypto/openssl-0.9/crypto/bio/b_print.c +++ b/crypto/openssl-0.9/crypto/bio/b_print.c @@ -79,7 +79,7 @@ #include /* To get BN_LLONG properly defined */ #include -#ifdef BN_LLONG +#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT) # ifndef HAVE_LONG_LONG # define HAVE_LONG_LONG 1 # endif @@ -117,7 +117,7 @@ #if HAVE_LONG_LONG # if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__) -# define LLONG _int64 +# define LLONG __int64 # else # define LLONG long long # endif diff --git a/crypto/openssl-0.9/crypto/bio/b_sock.c b/crypto/openssl-0.9/crypto/bio/b_sock.c index 4b3860b991..cd78de1e87 100644 --- a/crypto/openssl-0.9/crypto/bio/b_sock.c +++ b/crypto/openssl-0.9/crypto/bio/b_sock.c @@ -456,9 +456,6 @@ int BIO_sock_init(void) { int err; -#ifdef SIGINT - signal(SIGINT,(void (*)(int))BIO_sock_cleanup); -#endif wsa_init_done=1; memset(&wsa_state,0,sizeof(wsa_state)); if (WSAStartup(0x0101,&wsa_state)!=0) @@ -484,11 +481,6 @@ int BIO_sock_init(void) if (!wsa_init_done) { - -# ifdef SIGINT - signal(SIGINT,(void (*)(int))BIO_sock_cleanup); -# endif - wsa_init_done=1; wVerReq = MAKEWORD( 2, 0 ); err = WSAStartup(wVerReq,&wsaData); @@ -511,7 +503,7 @@ void BIO_sock_cleanup(void) { wsa_init_done=0; #ifndef OPENSSL_SYS_WINCE - WSACancelBlockingCall(); + WSACancelBlockingCall(); /* Winsock 1.1 specific */ #endif WSACleanup(); } diff --git a/crypto/openssl-0.9/crypto/bio/bio.h b/crypto/openssl-0.9/crypto/bio/bio.h index 2c9e8a7c80..0362bb90ca 100644 --- a/crypto/openssl-0.9/crypto/bio/bio.h +++ b/crypto/openssl-0.9/crypto/bio/bio.h @@ -129,8 +129,8 @@ extern "C" { /* dgram BIO stuff */ #define BIO_CTRL_DGRAM_CONNECT 31 /* BIO dgram special */ #define BIO_CTRL_DGRAM_SET_CONNECTED 32 /* allow for an externally - * connected socket to be - * passed in */ + * connected socket to be + * passed in */ #define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33 /* setsockopt, essentially */ #define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34 /* getsockopt, essentially */ #define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35 /* setsockopt, essentially */ @@ -146,14 +146,14 @@ extern "C" { #define BIO_CTRL_DGRAM_QUERY_MTU 40 /* as kernel for current MTU */ #define BIO_CTRL_DGRAM_GET_MTU 41 /* get cached value for MTU */ #define BIO_CTRL_DGRAM_SET_MTU 42 /* set cached value for - * MTU. want to use this - * if asking the kernel - * fails */ + * MTU. want to use this + * if asking the kernel + * fails */ #define BIO_CTRL_DGRAM_MTU_EXCEEDED 43 /* check whether the MTU - * was exceed in the - * previous write - * operation */ + * was exceed in the + * previous write + * operation */ #define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */ diff --git a/crypto/openssl-0.9/crypto/bn/bn.h b/crypto/openssl-0.9/crypto/bn/bn.h index 95c5d643cb..df6eea29a7 100644 --- a/crypto/openssl-0.9/crypto/bn/bn.h +++ b/crypto/openssl-0.9/crypto/bn/bn.h @@ -245,8 +245,18 @@ extern "C" { #define BN_FLG_MALLOCED 0x01 #define BN_FLG_STATIC_DATA 0x02 -#define BN_FLG_EXP_CONSTTIME 0x04 /* avoid leaking exponent information through timings - * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */ +#define BN_FLG_CONSTTIME 0x04 /* avoid leaking exponent information through timing, + * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime, + * BN_div() will call BN_div_no_branch, + * BN_mod_inverse() will call BN_mod_inverse_no_branch. + */ + +#ifndef OPENSSL_NO_DEPRECATED +#define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME /* deprecated name for the flag */ + /* avoid leaking exponent information through timings + * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */ +#endif + #ifndef OPENSSL_NO_DEPRECATED #define BN_FLG_FREE 0x8000 /* used for debuging */ #endif @@ -534,7 +544,7 @@ BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, #define BN_BLINDING_NO_UPDATE 0x00000001 #define BN_BLINDING_NO_RECREATE 0x00000002 -BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod); +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod); void BN_BLINDING_free(BN_BLINDING *b); int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx); int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); @@ -546,7 +556,7 @@ void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long); unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, - const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, + const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx, int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), BN_MONT_CTX *m_ctx); @@ -775,6 +785,7 @@ void ERR_load_BN_strings(void); #define BN_F_BN_CTX_NEW 106 #define BN_F_BN_CTX_START 129 #define BN_F_BN_DIV 107 +#define BN_F_BN_DIV_NO_BRANCH 138 #define BN_F_BN_DIV_RECP 130 #define BN_F_BN_EXP 123 #define BN_F_BN_EXPAND2 108 @@ -793,6 +804,7 @@ void ERR_load_BN_strings(void); #define BN_F_BN_MOD_EXP_RECP 125 #define BN_F_BN_MOD_EXP_SIMPLE 126 #define BN_F_BN_MOD_INVERSE 110 +#define BN_F_BN_MOD_INVERSE_NO_BRANCH 139 #define BN_F_BN_MOD_LSHIFT_QUICK 119 #define BN_F_BN_MOD_MUL_RECIPROCAL 111 #define BN_F_BN_MOD_SQRT 121 diff --git a/crypto/openssl-0.9/crypto/bn/bn_blind.c b/crypto/openssl-0.9/crypto/bn/bn_blind.c index ca22d4f8bd..c11fb4ccc2 100644 --- a/crypto/openssl-0.9/crypto/bn/bn_blind.c +++ b/crypto/openssl-0.9/crypto/bn/bn_blind.c @@ -131,7 +131,7 @@ struct bn_blinding_st BN_MONT_CTX *m_ctx); }; -BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod) { BN_BLINDING *ret=NULL; @@ -151,7 +151,12 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) { if ((ret->Ai = BN_dup(Ai)) == NULL) goto err; } - ret->mod = mod; + + /* save a copy of mod in the BN_BLINDING structure */ + if ((ret->mod = BN_dup(mod)) == NULL) goto err; + if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) + BN_set_flags(ret->mod, BN_FLG_CONSTTIME); + ret->counter = BN_BLINDING_COUNTER; return(ret); err: @@ -167,6 +172,7 @@ void BN_BLINDING_free(BN_BLINDING *r) if (r->A != NULL) BN_free(r->A ); if (r->Ai != NULL) BN_free(r->Ai); if (r->e != NULL) BN_free(r->e ); + if (r->mod != NULL) BN_free(r->mod); OPENSSL_free(r); } @@ -278,7 +284,7 @@ void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags) } BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, - const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, + const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx, int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), BN_MONT_CTX *m_ctx) diff --git a/crypto/openssl-0.9/crypto/bn/bn_div.c b/crypto/openssl-0.9/crypto/bn/bn_div.c index 2857f44861..8655eb118e 100644 --- a/crypto/openssl-0.9/crypto/bn/bn_div.c +++ b/crypto/openssl-0.9/crypto/bn/bn_div.c @@ -169,13 +169,15 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, #endif /* OPENSSL_NO_ASM */ -/* BN_div computes dv := num / divisor, rounding towards zero, and sets up - * rm such that dv*divisor + rm = num holds. +/* BN_div[_no_branch] computes dv := num / divisor, rounding towards + * zero, and sets up rm such that dv*divisor + rm = num holds. * Thus: * dv->neg == num->neg ^ divisor->neg (unless the result is zero) * rm->neg == num->neg (unless the remainder is zero) * If 'dv' or 'rm' is NULL, the respective value is not returned. */ +static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, + const BIGNUM *divisor, BN_CTX *ctx); int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, BN_CTX *ctx) { @@ -185,6 +187,11 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, BN_ULONG d0,d1; int num_n,div_n; + if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) + { + return BN_div_no_branch(dv, rm, num, divisor, ctx); + } + bn_check_top(dv); bn_check_top(rm); bn_check_top(num); @@ -397,4 +404,229 @@ err: return(0); } + +/* BN_div_no_branch is a special version of BN_div. It does not contain + * branches that may leak sensitive information. + */ +static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, + const BIGNUM *divisor, BN_CTX *ctx) + { + int norm_shift,i,loop; + BIGNUM *tmp,wnum,*snum,*sdiv,*res; + BN_ULONG *resp,*wnump; + BN_ULONG d0,d1; + int num_n,div_n; + + bn_check_top(dv); + bn_check_top(rm); + bn_check_top(num); + bn_check_top(divisor); + + if (BN_is_zero(divisor)) + { + BNerr(BN_F_BN_DIV_NO_BRANCH,BN_R_DIV_BY_ZERO); + return(0); + } + + BN_CTX_start(ctx); + tmp=BN_CTX_get(ctx); + snum=BN_CTX_get(ctx); + sdiv=BN_CTX_get(ctx); + if (dv == NULL) + res=BN_CTX_get(ctx); + else res=dv; + if (sdiv == NULL || res == NULL) goto err; + + /* First we normalise the numbers */ + norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2); + if (!(BN_lshift(sdiv,divisor,norm_shift))) goto err; + sdiv->neg=0; + norm_shift+=BN_BITS2; + if (!(BN_lshift(snum,num,norm_shift))) goto err; + snum->neg=0; + + /* Since we don't know whether snum is larger than sdiv, + * we pad snum with enough zeroes without changing its + * value. + */ + if (snum->top <= sdiv->top+1) + { + if (bn_wexpand(snum, sdiv->top + 2) == NULL) goto err; + for (i = snum->top; i < sdiv->top + 2; i++) snum->d[i] = 0; + snum->top = sdiv->top + 2; + } + else + { + if (bn_wexpand(snum, snum->top + 1) == NULL) goto err; + snum->d[snum->top] = 0; + snum->top ++; + } + + div_n=sdiv->top; + num_n=snum->top; + loop=num_n-div_n; + /* Lets setup a 'window' into snum + * This is the part that corresponds to the current + * 'area' being divided */ + wnum.neg = 0; + wnum.d = &(snum->d[loop]); + wnum.top = div_n; + /* only needed when BN_ucmp messes up the values between top and max */ + wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */ + + /* Get the top 2 words of sdiv */ + /* div_n=sdiv->top; */ + d0=sdiv->d[div_n-1]; + d1=(div_n == 1)?0:sdiv->d[div_n-2]; + + /* pointer to the 'top' of snum */ + wnump= &(snum->d[num_n-1]); + + /* Setup to 'res' */ + res->neg= (num->neg^divisor->neg); + if (!bn_wexpand(res,(loop+1))) goto err; + res->top=loop-1; + resp= &(res->d[loop-1]); + + /* space for temp */ + if (!bn_wexpand(tmp,(div_n+1))) goto err; + + /* if res->top == 0 then clear the neg value otherwise decrease + * the resp pointer */ + if (res->top == 0) + res->neg = 0; + else + resp--; + + for (i=0; i 0x%08X\n", + n0, n1, d0, q); +#endif +#endif + +#ifndef REMAINDER_IS_ALREADY_CALCULATED + /* + * rem doesn't have to be BN_ULLONG. The least we + * know it's less that d0, isn't it? + */ + rem=(n1-q*d0)&BN_MASK2; +#endif + t2=(BN_ULLONG)d1*q; + + for (;;) + { + if (t2 <= ((((BN_ULLONG)rem)< 0x%08X\n", + n0, n1, d0, q); +#endif +#ifndef REMAINDER_IS_ALREADY_CALCULATED + rem=(n1-q*d0)&BN_MASK2; +#endif + +#if defined(BN_UMULT_LOHI) + BN_UMULT_LOHI(t2l,t2h,d1,q); +#elif defined(BN_UMULT_HIGH) + t2l = d1 * q; + t2h = BN_UMULT_HIGH(d1,q); +#else + t2l=LBITS(d1); t2h=HBITS(d1); + ql =LBITS(q); qh =HBITS(q); + mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */ +#endif + + for (;;) + { + if ((t2h < rem) || + ((t2h == rem) && (t2l <= wnump[-2]))) + break; + q--; + rem += d0; + if (rem < d0) break; /* don't let rem overflow */ + if (t2l < d1) t2h--; t2l -= d1; + } +#endif /* !BN_LLONG */ + } +#endif /* !BN_DIV3W */ + + l0=bn_mul_words(tmp->d,sdiv->d,div_n,q); + tmp->d[div_n]=l0; + wnum.d--; + /* ingore top values of the bignums just sub the two + * BN_ULONG arrays with bn_sub_words */ + if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n+1)) + { + /* Note: As we have considered only the leading + * two BN_ULONGs in the calculation of q, sdiv * q + * might be greater than wnum (but then (q-1) * sdiv + * is less or equal than wnum) + */ + q--; + if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n)) + /* we can't have an overflow here (assuming + * that q != 0, but if q == 0 then tmp is + * zero anyway) */ + (*wnump)++; + } + /* store part of the result */ + *resp = q; + } + bn_correct_top(snum); + if (rm != NULL) + { + /* Keep a copy of the neg flag in num because if rm==num + * BN_rshift() will overwrite it. + */ + int neg = num->neg; + BN_rshift(rm,snum,norm_shift); + if (!BN_is_zero(rm)) + rm->neg = neg; + bn_check_top(rm); + } + bn_correct_top(res); + BN_CTX_end(ctx); + return(1); +err: + bn_check_top(rm); + BN_CTX_end(ctx); + return(0); + } + #endif diff --git a/crypto/openssl-0.9/crypto/bn/bn_err.c b/crypto/openssl-0.9/crypto/bn/bn_err.c index 24fbbb772d..cfe2eb94a0 100644 --- a/crypto/openssl-0.9/crypto/bn/bn_err.c +++ b/crypto/openssl-0.9/crypto/bn/bn_err.c @@ -1,6 +1,6 @@ /* crypto/bn/bn_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -82,6 +82,7 @@ static ERR_STRING_DATA BN_str_functs[]= {ERR_FUNC(BN_F_BN_CTX_NEW), "BN_CTX_new"}, {ERR_FUNC(BN_F_BN_CTX_START), "BN_CTX_start"}, {ERR_FUNC(BN_F_BN_DIV), "BN_div"}, +{ERR_FUNC(BN_F_BN_DIV_NO_BRANCH), "BN_div_no_branch"}, {ERR_FUNC(BN_F_BN_DIV_RECP), "BN_div_recp"}, {ERR_FUNC(BN_F_BN_EXP), "BN_exp"}, {ERR_FUNC(BN_F_BN_EXPAND2), "bn_expand2"}, @@ -100,6 +101,7 @@ static ERR_STRING_DATA BN_str_functs[]= {ERR_FUNC(BN_F_BN_MOD_EXP_RECP), "BN_mod_exp_recp"}, {ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE), "BN_mod_exp_simple"}, {ERR_FUNC(BN_F_BN_MOD_INVERSE), "BN_mod_inverse"}, +{ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH), "BN_mod_inverse_no_branch"}, {ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK), "BN_mod_lshift_quick"}, {ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL), "BN_mod_mul_reciprocal"}, {ERR_FUNC(BN_F_BN_MOD_SQRT), "BN_mod_sqrt"}, diff --git a/crypto/openssl-0.9/crypto/bn/bn_exp.c b/crypto/openssl-0.9/crypto/bn/bn_exp.c index 8f8c694481..70a33f0d93 100644 --- a/crypto/openssl-0.9/crypto/bn/bn_exp.c +++ b/crypto/openssl-0.9/crypto/bn/bn_exp.c @@ -122,9 +122,9 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) int i,bits,ret=0; BIGNUM *v,*rr; - if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0) + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { - /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */ + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; } @@ -213,7 +213,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, if (BN_is_odd(m)) { # ifdef MONT_EXP_WORD - if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) == 0)) + if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) { BN_ULONG A = a->d[0]; ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL); @@ -245,9 +245,9 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BIGNUM *val[TABLE_SIZE]; BN_RECP_CTX recp; - if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0) + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { - /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */ + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_RECP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; } @@ -379,7 +379,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, BIGNUM *val[TABLE_SIZE]; BN_MONT_CTX *mont=NULL; - if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0) + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont); } @@ -745,9 +745,9 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, #define BN_TO_MONTGOMERY_WORD(r, w, mont) \ (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) - if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0) + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { - /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */ + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_MONT_WORD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; } @@ -881,9 +881,9 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, /* Table of variables obtained from 'ctx' */ BIGNUM *val[TABLE_SIZE]; - if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0) + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { - /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */ + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_SIMPLE,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; } diff --git a/crypto/openssl-0.9/crypto/bn/bn_gcd.c b/crypto/openssl-0.9/crypto/bn/bn_gcd.c index f02e6fcdb4..4a352119ba 100644 --- a/crypto/openssl-0.9/crypto/bn/bn_gcd.c +++ b/crypto/openssl-0.9/crypto/bn/bn_gcd.c @@ -203,6 +203,8 @@ err: /* solves ax == 1 (mod n) */ +static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); BIGNUM *BN_mod_inverse(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) { @@ -210,6 +212,11 @@ BIGNUM *BN_mod_inverse(BIGNUM *in, BIGNUM *ret=NULL; int sign; + if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) + { + return BN_mod_inverse_no_branch(in, a, n, ctx); + } + bn_check_top(a); bn_check_top(n); @@ -491,3 +498,157 @@ err: bn_check_top(ret); return(ret); } + + +/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. + * It does not contain branches that may leak sensitive information. + */ +static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) + { + BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL; + BIGNUM local_A, local_B; + BIGNUM *pA, *pB; + BIGNUM *ret=NULL; + int sign; + + bn_check_top(a); + bn_check_top(n); + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + B = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + D = BN_CTX_get(ctx); + M = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + T = BN_CTX_get(ctx); + if (T == NULL) goto err; + + if (in == NULL) + R=BN_new(); + else + R=in; + if (R == NULL) goto err; + + BN_one(X); + BN_zero(Y); + if (BN_copy(B,a) == NULL) goto err; + if (BN_copy(A,n) == NULL) goto err; + A->neg = 0; + + if (B->neg || (BN_ucmp(B, A) >= 0)) + { + /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, + * BN_div_no_branch will be called eventually. + */ + pB = &local_B; + BN_with_flags(pB, B, BN_FLG_CONSTTIME); + if (!BN_nnmod(B, pB, A, ctx)) goto err; + } + sign = -1; + /* From B = a mod |n|, A = |n| it follows that + * + * 0 <= B < A, + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + */ + + while (!BN_is_zero(B)) + { + BIGNUM *tmp; + + /* + * 0 < B < A, + * (*) -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|) + */ + + /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, + * BN_div_no_branch will be called eventually. + */ + pA = &local_A; + BN_with_flags(pA, A, BN_FLG_CONSTTIME); + + /* (D, M) := (A/B, A%B) ... */ + if (!BN_div(D,M,pA,B,ctx)) goto err; + + /* Now + * A = D*B + M; + * thus we have + * (**) sign*Y*a == D*B + M (mod |n|). + */ + + tmp=A; /* keep the BIGNUM object, the value does not matter */ + + /* (A, B) := (B, A mod B) ... */ + A=B; + B=M; + /* ... so we have 0 <= B < A again */ + + /* Since the former M is now B and the former B is now A, + * (**) translates into + * sign*Y*a == D*A + B (mod |n|), + * i.e. + * sign*Y*a - D*A == B (mod |n|). + * Similarly, (*) translates into + * -sign*X*a == A (mod |n|). + * + * Thus, + * sign*Y*a + D*sign*X*a == B (mod |n|), + * i.e. + * sign*(Y + D*X)*a == B (mod |n|). + * + * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + * Note that X and Y stay non-negative all the time. + */ + + if (!BN_mul(tmp,D,X,ctx)) goto err; + if (!BN_add(tmp,tmp,Y)) goto err; + + M=Y; /* keep the BIGNUM object, the value does not matter */ + Y=X; + X=tmp; + sign = -sign; + } + + /* + * The while loop (Euclid's algorithm) ends when + * A == gcd(a,n); + * we have + * sign*Y*a == A (mod |n|), + * where Y is non-negative. + */ + + if (sign < 0) + { + if (!BN_sub(Y,n,Y)) goto err; + } + /* Now Y*a == A (mod |n|). */ + + if (BN_is_one(A)) + { + /* Y*a == 1 (mod |n|) */ + if (!Y->neg && BN_ucmp(Y,n) < 0) + { + if (!BN_copy(R,Y)) goto err; + } + else + { + if (!BN_nnmod(R,Y,n,ctx)) goto err; + } + } + else + { + BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH,BN_R_NO_INVERSE); + goto err; + } + ret=R; +err: + if ((ret == NULL) && (in == NULL)) BN_free(R); + BN_CTX_end(ctx); + bn_check_top(ret); + return(ret); + } diff --git a/crypto/openssl-0.9/crypto/bn/bn_lib.c b/crypto/openssl-0.9/crypto/bn/bn_lib.c index 210ccb42bb..2649b8c538 100644 --- a/crypto/openssl-0.9/crypto/bn/bn_lib.c +++ b/crypto/openssl-0.9/crypto/bn/bn_lib.c @@ -763,7 +763,7 @@ int BN_is_bit_set(const BIGNUM *a, int n) i=n/BN_BITS2; j=n%BN_BITS2; if (a->top <= i) return 0; - return((a->d[i]&(((BN_ULONG)1)<d[i])>>j)&((BN_ULONG)1)); } int BN_mask_bits(BIGNUM *a, int n) diff --git a/crypto/openssl-0.9/crypto/bn/bn_mont.c b/crypto/openssl-0.9/crypto/bn/bn_mont.c index 961ca67ea1..b5d35d10be 100644 --- a/crypto/openssl-0.9/crypto/bn/bn_mont.c +++ b/crypto/openssl-0.9/crypto/bn/bn_mont.c @@ -176,7 +176,6 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, max=(nl+al+1); /* allow for overflow (no?) XXX */ if (bn_wexpand(r,max) == NULL) goto err; - if (bn_wexpand(ret,max) == NULL) goto err; r->neg=a->neg^n->neg; np=n->d; @@ -228,19 +227,72 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, } bn_correct_top(r); - /* mont->ri will be a multiple of the word size */ -#if 0 - BN_rshift(ret,r,mont->ri); -#else - ret->neg = r->neg; - x=ri; + /* mont->ri will be a multiple of the word size and below code + * is kind of BN_rshift(ret,r,mont->ri) equivalent */ + if (r->top <= ri) + { + ret->top=0; + retn=1; + goto err; + } + al=r->top-ri; + +# define BRANCH_FREE 1 +# if BRANCH_FREE + if (bn_wexpand(ret,ri) == NULL) goto err; + x=0-(((al-ri)>>(sizeof(al)*8-1))&1); + ret->top=x=(ri&~x)|(al&x); /* min(ri,al) */ + ret->neg=r->neg; + rp=ret->d; - ap= &(r->d[x]); - if (r->top < x) - al=0; - else - al=r->top-x; + ap=&(r->d[ri]); + + { + size_t m1,m2; + + v=bn_sub_words(rp,ap,np,ri); + /* this ----------------^^ works even in alri) nrp=rp; else nrp=ap; */ + /* in other words if subtraction result is real, then + * trick unconditional memcpy below to perform in-place + * "refresh" instead of actual copy. */ + m1=0-(size_t)(((al-ri)>>(sizeof(al)*8-1))&1); /* al>(sizeof(al)*8-1))&1); /* al>ri */ + m1|=m2; /* (al!=ri) */ + m1|=(0-(size_t)v); /* (al!=ri || v) */ + m1&=~m2; /* (al!=ri || v) && !al>ri */ + nrp=(BN_ULONG *)(((size_t)rp&~m1)|((size_t)ap&m1)); + } + + /* 'itop=al; + ret->neg=r->neg; + + rp=ret->d; + ap=&(r->d[ri]); al-=4; for (i=0; iri)) goto err; #endif /* MONT_WORD */ +#if !defined(BRANCH_FREE) || BRANCH_FREE==0 if (BN_ucmp(ret, &(mont->N)) >= 0) { if (!BN_usub(ret,ret,&(mont->N))) goto err; } +#endif retn=1; bn_check_top(ret); err: diff --git a/crypto/openssl-0.9/crypto/bn/bn_mul.c b/crypto/openssl-0.9/crypto/bn/bn_mul.c index aec1eafc65..312b467645 100644 --- a/crypto/openssl-0.9/crypto/bn/bn_mul.c +++ b/crypto/openssl-0.9/crypto/bn/bn_mul.c @@ -655,16 +655,16 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, for (;;) { i/=2; - if (i < tna && i < tnb) + if (i <= tna && tna == tnb) { - bn_mul_part_recursive(&(r[n2]), + bn_mul_recursive(&(r[n2]), &(a[n]),&(b[n]), i,tna-i,tnb-i,p); break; } - else if (i <= tna && i <= tnb) + else if (i < tna || i < tnb) { - bn_mul_recursive(&(r[n2]), + bn_mul_part_recursive(&(r[n2]), &(a[n]),&(b[n]), i,tna-i,tnb-i,p); break; diff --git a/crypto/openssl-0.9/crypto/bn/bn_prime.c b/crypto/openssl-0.9/crypto/bn/bn_prime.c index 5bab019553..7b25979dd1 100644 --- a/crypto/openssl-0.9/crypto/bn/bn_prime.c +++ b/crypto/openssl-0.9/crypto/bn/bn_prime.c @@ -377,14 +377,14 @@ static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, static int probable_prime(BIGNUM *rnd, int bits) { int i; - BN_ULONG mods[NUMPRIMES]; + prime_t mods[NUMPRIMES]; BN_ULONG delta,maxdelta; again: if (!BN_rand(rnd,bits,1,1)) return(0); /* we now have a random number 'rand' to test. */ for (i=1; idata, value); if (v != NULL) { - sk_CONF_VALUE_delete_ptr(ts,v); + (void)sk_CONF_VALUE_delete_ptr(ts,v); OPENSSL_free(v->name); OPENSSL_free(v->value); OPENSSL_free(v); diff --git a/crypto/openssl-0.9/crypto/conf/conf_mod.c b/crypto/openssl-0.9/crypto/conf/conf_mod.c index 587211a59c..628e8333a6 100644 --- a/crypto/openssl-0.9/crypto/conf/conf_mod.c +++ b/crypto/openssl-0.9/crypto/conf/conf_mod.c @@ -126,17 +126,18 @@ int CONF_modules_load(const CONF *cnf, const char *appname, { STACK_OF(CONF_VALUE) *values; CONF_VALUE *vl; - char *vsection; + char *vsection = NULL; int ret, i; if (!cnf) return 1; - if (appname == NULL) - appname = "openssl_conf"; + if (appname) + vsection = NCONF_get_string(cnf, NULL, appname); - vsection = NCONF_get_string(cnf, NULL, appname); + if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION))) + vsection = NCONF_get_string(cnf, NULL, "openssl_conf"); if (!vsection) { @@ -431,7 +432,7 @@ void CONF_modules_unload(int all) if (((md->links > 0) || !md->dso) && !all) continue; /* Since we're working in reverse this is OK */ - sk_CONF_MODULE_delete(supported_modules, i); + (void)sk_CONF_MODULE_delete(supported_modules, i); module_free(md); } if (sk_CONF_MODULE_num(supported_modules) == 0) diff --git a/crypto/openssl-0.9/crypto/conf/conf_sap.c b/crypto/openssl-0.9/crypto/conf/conf_sap.c index e15c2e5546..9c53bac1a8 100644 --- a/crypto/openssl-0.9/crypto/conf/conf_sap.c +++ b/crypto/openssl-0.9/crypto/conf/conf_sap.c @@ -88,8 +88,8 @@ void OPENSSL_config(const char *config_name) ERR_clear_error(); - if (CONF_modules_load_file(NULL, NULL, - CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0) + if (CONF_modules_load_file(NULL, config_name, + CONF_MFLAGS_DEFAULT_SECTION|CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0) { BIO *bio_err; ERR_load_crypto_strings(); diff --git a/crypto/openssl-0.9/crypto/cryptlib.c b/crypto/openssl-0.9/crypto/cryptlib.c index 86af760d38..8c68623828 100644 --- a/crypto/openssl-0.9/crypto/cryptlib.c +++ b/crypto/openssl-0.9/crypto/cryptlib.c @@ -277,7 +277,7 @@ int CRYPTO_get_new_dynlockid(void) else /* If we found a place with a NULL pointer, put our pointer in it. */ - sk_CRYPTO_dynlock_set(dyn_locks,i,pointer); + (void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer); CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); if (i == -1) @@ -319,7 +319,7 @@ void CRYPTO_destroy_dynlockid(int i) #endif if (pointer->references <= 0) { - sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); + (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); } else pointer = NULL; diff --git a/crypto/openssl-0.9/crypto/des/set_key.c b/crypto/openssl-0.9/crypto/des/set_key.c index 55efe03f42..a43ef3c881 100644 --- a/crypto/openssl-0.9/crypto/des/set_key.c +++ b/crypto/openssl-0.9/crypto/des/set_key.c @@ -115,7 +115,7 @@ int DES_check_key_parity(const_DES_cblock *key) * (and actual cblock values). */ #define NUM_WEAK_KEY 16 -static DES_cblock weak_keys[NUM_WEAK_KEY]={ +static const DES_cblock weak_keys[NUM_WEAK_KEY]={ /* weak keys */ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE}, diff --git a/crypto/openssl-0.9/crypto/dh/dh_check.c b/crypto/openssl-0.9/crypto/dh/dh_check.c index 058aec75bc..b846913004 100644 --- a/crypto/openssl-0.9/crypto/dh/dh_check.c +++ b/crypto/openssl-0.9/crypto/dh/dh_check.c @@ -62,7 +62,7 @@ #include /* Check that p is a safe prime and - * if g is 2, 3 or 5, check that is is a suitable generator + * if g is 2, 3 or 5, check that it is a suitable generator * where * for 2, p mod 24 == 11 * for 3, p mod 12 == 5 diff --git a/crypto/openssl-0.9/crypto/dh/dh_key.c b/crypto/openssl-0.9/crypto/dh/dh_key.c index 37a2c1bca2..e7db440342 100644 --- a/crypto/openssl-0.9/crypto/dh/dh_key.c +++ b/crypto/openssl-0.9/crypto/dh/dh_key.c @@ -150,7 +150,7 @@ static int generate_key(DH *dh) { BN_init(&local_prk); prk = &local_prk; - BN_with_flags(prk, priv_key, BN_FLG_EXP_CONSTTIME); + BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); } else prk = priv_key; @@ -203,7 +203,7 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { /* XXX */ - BN_set_flags(dh->priv_key, BN_FLG_EXP_CONSTTIME); + BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME); } if (!mont) goto err; diff --git a/crypto/openssl-0.9/crypto/dsa/dsa_gen.c b/crypto/openssl-0.9/crypto/dsa/dsa_gen.c index 6a6be3b575..ca0b86a6cf 100644 --- a/crypto/openssl-0.9/crypto/dsa/dsa_gen.c +++ b/crypto/openssl-0.9/crypto/dsa/dsa_gen.c @@ -117,13 +117,20 @@ static int dsa_builtin_paramgen(DSA *ret, int bits, if (bits < 512) bits=512; bits=(bits+63)/64*64; - if (seed_len < 20) + /* NB: seed_len == 0 is special case: copy generated seed to + * seed_in if it is not NULL. + */ + if (seed_len && (seed_len < 20)) seed_in = NULL; /* seed buffer too small -- ignore */ if (seed_len > 20) seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED, * but our internal buffers are restricted to 160 bits*/ if ((seed_in != NULL) && (seed_len == 20)) + { memcpy(seed,seed_in,seed_len); + /* set seed_in to NULL to avoid it being copied back */ + seed_in = NULL; + } if ((ctx=BN_CTX_new()) == NULL) goto err; @@ -300,7 +307,7 @@ err: ok=0; goto err; } - if ((m > 1) && (seed_in != NULL)) memcpy(seed_in,seed,20); + if (seed_in != NULL) memcpy(seed_in,seed,20); if (counter_ret != NULL) *counter_ret=counter; if (h_ret != NULL) *h_ret=h; } diff --git a/crypto/openssl-0.9/crypto/dsa/dsa_key.c b/crypto/openssl-0.9/crypto/dsa/dsa_key.c index 0423f2e00c..c4aa86bc6d 100644 --- a/crypto/openssl-0.9/crypto/dsa/dsa_key.c +++ b/crypto/openssl-0.9/crypto/dsa/dsa_key.c @@ -107,7 +107,7 @@ static int dsa_builtin_keygen(DSA *dsa) { BN_init(&local_prk); prk = &local_prk; - BN_with_flags(prk, priv_key, BN_FLG_EXP_CONSTTIME); + BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); } else prk = priv_key; diff --git a/crypto/openssl-0.9/crypto/dsa/dsa_ossl.c b/crypto/openssl-0.9/crypto/dsa/dsa_ossl.c index e6aad85825..75ff7cc4af 100644 --- a/crypto/openssl-0.9/crypto/dsa/dsa_ossl.c +++ b/crypto/openssl-0.9/crypto/dsa/dsa_ossl.c @@ -229,7 +229,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) while (BN_is_zero(&k)); if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { - BN_set_flags(&k, BN_FLG_EXP_CONSTTIME); + BN_set_flags(&k, BN_FLG_CONSTTIME); } if (dsa->flags & DSA_FLAG_CACHE_MONT_P) diff --git a/crypto/openssl-0.9/crypto/ec/ec.h b/crypto/openssl-0.9/crypto/ec/ec.h index 3c96fbd0d8..8bc2a235b1 100644 --- a/crypto/openssl-0.9/crypto/ec/ec.h +++ b/crypto/openssl-0.9/crypto/ec/ec.h @@ -471,6 +471,7 @@ void ERR_load_EC_strings(void); #define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 #define EC_F_EC_POINT_SET_TO_INFINITY 127 #define EC_F_EC_PRE_COMP_DUP 207 +#define EC_F_EC_PRE_COMP_NEW 196 #define EC_F_EC_WNAF_MUL 187 #define EC_F_EC_WNAF_PRECOMPUTE_MULT 188 #define EC_F_I2D_ECPARAMETERS 190 diff --git a/crypto/openssl-0.9/crypto/ec/ec_err.c b/crypto/openssl-0.9/crypto/ec/ec_err.c index 7be315bac9..d04c895560 100644 --- a/crypto/openssl-0.9/crypto/ec/ec_err.c +++ b/crypto/openssl-0.9/crypto/ec/ec_err.c @@ -1,6 +1,6 @@ /* crypto/ec/ec_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -170,6 +170,7 @@ static ERR_STRING_DATA EC_str_functs[]= {ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_set_Jprojective_coordinates_GFp"}, {ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"}, {ERR_FUNC(EC_F_EC_PRE_COMP_DUP), "EC_PRE_COMP_DUP"}, +{ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "EC_PRE_COMP_NEW"}, {ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"}, {ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"}, {ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"}, diff --git a/crypto/openssl-0.9/crypto/ec/ec_mult.c b/crypto/openssl-0.9/crypto/ec/ec_mult.c index a045139a00..2ba173ef36 100644 --- a/crypto/openssl-0.9/crypto/ec/ec_mult.c +++ b/crypto/openssl-0.9/crypto/ec/ec_mult.c @@ -3,7 +3,7 @@ * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. */ /* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -104,7 +104,10 @@ static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group) ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP)); if (!ret) + { + ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); return ret; + } ret->group = group; ret->blocksize = 8; /* default */ ret->numblocks = 0; @@ -194,6 +197,19 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) int bit, next_bit, mask; size_t len = 0, j; + if (BN_is_zero(scalar)) + { + r = OPENSSL_malloc(1); + if (!r) + { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); + goto err; + } + r[0] = 0; + *ret_len = 1; + return r; + } + if (w <= 0 || w > 7) /* 'signed char' can represent integers with absolute values less than 2^7 */ { ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); @@ -212,7 +228,11 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer than binary representation * (*ret_len will be set to the actual length, i.e. at most * BN_num_bits(scalar) + 1) */ - if (r == NULL) goto err; + if (r == NULL) + { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); + goto err; + } if (scalar->d == NULL || scalar->top == 0) { @@ -425,7 +445,10 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]); if (!wsize || !wNAF_len || !wNAF || !val_sub) + { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); goto err; + } wNAF[0] = NULL; /* preliminary pivot */ @@ -538,6 +561,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, wNAF[i] = OPENSSL_malloc(wNAF_len[i]); if (wNAF[i] == NULL) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); OPENSSL_free(tmp_wNAF); goto err; } @@ -564,7 +588,11 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, * 'val_sub[i]' is a pointer to the subarray for the i-th point, * or to a subarray of 'pre_comp->points' if we already have precomputation. */ val = OPENSSL_malloc((num_val + 1) * sizeof val[0]); - if (val == NULL) goto err; + if (val == NULL) + { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); + goto err; + } val[num_val] = NULL; /* pivot element */ /* allocate points for precomputation */ diff --git a/crypto/openssl-0.9/crypto/engine/eng_padlock.c b/crypto/openssl-0.9/crypto/engine/eng_padlock.c index e1d66eac58..8531bde1db 100644 --- a/crypto/openssl-0.9/crypto/engine/eng_padlock.c +++ b/crypto/openssl-0.9/crypto/engine/eng_padlock.c @@ -436,7 +436,7 @@ static inline void *name(size_t cnt, \ rep_xcrypt "\n" \ " popl %%ebx" \ : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \ - : "0"(cdata), "1"(cnt), "2"(out), "3"(inp), "m"(*cdata) \ + : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \ : "edx", "cc", "memory"); \ return iv; \ } diff --git a/crypto/openssl-0.9/crypto/engine/eng_table.c b/crypto/openssl-0.9/crypto/engine/eng_table.c index a83c3899ee..0c1656168d 100644 --- a/crypto/openssl-0.9/crypto/engine/eng_table.c +++ b/crypto/openssl-0.9/crypto/engine/eng_table.c @@ -147,7 +147,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, lh_insert(&(*table)->piles, fnd); } /* A registration shouldn't add duplciate entries */ - sk_ENGINE_delete_ptr(fnd->sk, e); + (void)sk_ENGINE_delete_ptr(fnd->sk, e); /* if 'setdefault', this ENGINE goes to the head of the list */ if(!sk_ENGINE_push(fnd->sk, e)) goto end; @@ -178,7 +178,7 @@ static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) /* Iterate the 'c->sk' stack removing any occurance of 'e' */ while((n = sk_ENGINE_find(pile->sk, e)) >= 0) { - sk_ENGINE_delete(pile->sk, n); + (void)sk_ENGINE_delete(pile->sk, n); /* "touch" this ENGINE_CIPHER */ pile->uptodate = 1; } diff --git a/crypto/openssl-0.9/crypto/evp/c_allc.c b/crypto/openssl-0.9/crypto/evp/c_allc.c index 9ba4d0c6e0..7054d8125d 100644 --- a/crypto/openssl-0.9/crypto/evp/c_allc.c +++ b/crypto/openssl-0.9/crypto/evp/c_allc.c @@ -107,6 +107,15 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher_alias(SN_idea_cbc,"idea"); #endif +#ifndef OPENSSL_NO_SEED + EVP_add_cipher(EVP_seed_ecb()); + EVP_add_cipher(EVP_seed_cfb()); + EVP_add_cipher(EVP_seed_ofb()); + EVP_add_cipher(EVP_seed_cbc()); + EVP_add_cipher_alias(SN_seed_cbc,"SEED"); + EVP_add_cipher_alias(SN_seed_cbc,"seed"); +#endif + #ifndef OPENSSL_NO_RC2 EVP_add_cipher(EVP_rc2_ecb()); EVP_add_cipher(EVP_rc2_cfb()); diff --git a/crypto/openssl-0.9/crypto/evp/evp.h b/crypto/openssl-0.9/crypto/evp/evp.h index 636f426c69..bdd3b7ecaa 100644 --- a/crypto/openssl-0.9/crypto/evp/evp.h +++ b/crypto/openssl-0.9/crypto/evp/evp.h @@ -766,6 +766,14 @@ const EVP_CIPHER *EVP_camellia_256_cfb128(void); const EVP_CIPHER *EVP_camellia_256_ofb(void); #endif +#ifndef OPENSSL_NO_SEED +const EVP_CIPHER *EVP_seed_ecb(void); +const EVP_CIPHER *EVP_seed_cbc(void); +const EVP_CIPHER *EVP_seed_cfb128(void); +# define EVP_seed_cfb EVP_seed_cfb128 +const EVP_CIPHER *EVP_seed_ofb(void); +#endif + void OPENSSL_add_all_algorithms_noconf(void); void OPENSSL_add_all_algorithms_conf(void); @@ -963,6 +971,7 @@ void ERR_load_EVP_strings(void); #define EVP_R_UNSUPPORTED_SALT_TYPE 126 #define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 #define EVP_R_WRONG_PUBLIC_KEY_TYPE 110 +#define EVP_R_SEED_KEY_SETUP_FAILED 162 #ifdef __cplusplus } diff --git a/crypto/openssl-0.9/crypto/evp/evp_lib.c b/crypto/openssl-0.9/crypto/evp/evp_lib.c index f92db23af6..edb28ef38e 100644 --- a/crypto/openssl-0.9/crypto/evp/evp_lib.c +++ b/crypto/openssl-0.9/crypto/evp/evp_lib.c @@ -225,7 +225,7 @@ int EVP_CIPHER_key_length(const EVP_CIPHER *cipher) int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) { - return ctx->cipher->key_len; + return ctx->key_len; } int EVP_CIPHER_nid(const EVP_CIPHER *cipher) diff --git a/crypto/openssl-0.9/crypto/evp/evp_locl.h b/crypto/openssl-0.9/crypto/evp/evp_locl.h index 20139d20e4..073b0adcff 100644 --- a/crypto/openssl-0.9/crypto/evp/evp_locl.h +++ b/crypto/openssl-0.9/crypto/evp/evp_locl.h @@ -92,7 +92,7 @@ static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const uns #define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \ static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ {\ - cprefix##_cfb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ + cprefix##_cfb##cbits##_encrypt(in, out, (long)(cbits==1?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ return 1;\ } diff --git a/crypto/openssl-0.9/crypto/ex_data.c b/crypto/openssl-0.9/crypto/ex_data.c index 8914218fe8..3b11e7a556 100644 --- a/crypto/openssl-0.9/crypto/ex_data.c +++ b/crypto/openssl-0.9/crypto/ex_data.c @@ -354,7 +354,7 @@ static int def_add_index(EX_CLASS_ITEM *item, long argl, void *argp, } } toret = item->meth_num++; - sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a); + (void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a); err: CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); return toret; diff --git a/crypto/openssl-0.9/crypto/mem_clr.c b/crypto/openssl-0.9/crypto/mem_clr.c index 75cbfb374e..add1f78020 100644 --- a/crypto/openssl-0.9/crypto/mem_clr.c +++ b/crypto/openssl-0.9/crypto/mem_clr.c @@ -64,12 +64,14 @@ unsigned char cleanse_ctr = 0; void OPENSSL_cleanse(void *ptr, size_t len) { unsigned char *p = ptr; - size_t loop = len; + size_t loop = len, ctr = cleanse_ctr; while(loop--) { - *(p++) = cleanse_ctr; - cleanse_ctr += (17 + (unsigned char)((unsigned long)p & 0xF)); + *(p++) = (unsigned char)ctr; + ctr += (17 + ((size_t)p & 0xF)); } - if(memchr(ptr, cleanse_ctr, len)) - cleanse_ctr += 63; + p=memchr(ptr, (unsigned char)ctr, len); + if(p) + ctr += (63 + (size_t)p); + cleanse_ctr = (unsigned char)ctr; } diff --git a/crypto/openssl-0.9/crypto/objects/obj_dat.h b/crypto/openssl-0.9/crypto/objects/obj_dat.h index a116bb7f28..a9528d5392 100644 --- a/crypto/openssl-0.9/crypto/objects/obj_dat.h +++ b/crypto/openssl-0.9/crypto/objects/obj_dat.h @@ -62,12 +62,12 @@ * [including the GNU Public Licence.] */ -#define NUM_NID 772 -#define NUM_SN 768 -#define NUM_LN 768 -#define NUM_OBJ 724 +#define NUM_NID 780 +#define NUM_SN 773 +#define NUM_LN 773 +#define NUM_OBJ 729 -static unsigned char lvalues[5116]={ +static unsigned char lvalues[5154]={ 0x00, /* [ 0] OBJ_undef */ 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 1] OBJ_rsadsi */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 7] OBJ_pkcs */ @@ -792,6 +792,11 @@ static unsigned char lvalues[5116]={ 0x55,0x1D,0x09, /* [5106] OBJ_subject_directory_attributes */ 0x55,0x1D,0x1C, /* [5109] OBJ_issuing_distribution_point */ 0x55,0x1D,0x1D, /* [5112] OBJ_certificate_issuer */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44, /* [5115] OBJ_kisa */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03, /* [5121] OBJ_seed_ecb */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04, /* [5129] OBJ_seed_cbc */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06, /* [5137] OBJ_seed_ofb128 */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05, /* [5145] OBJ_seed_cfb128 */ }; static ASN1_OBJECT nid_objs[NUM_NID]={ @@ -1996,6 +2001,14 @@ static ASN1_OBJECT nid_objs[NUM_NID]={ NID_issuing_distribution_point,3,&(lvalues[5109]),0}, {"certificateIssuer","X509v3 Certificate Issuer", NID_certificate_issuer,3,&(lvalues[5112]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"KISA","kisa",NID_kisa,6,&(lvalues[5115]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"SEED-ECB","seed-ecb",NID_seed_ecb,8,&(lvalues[5121]),0}, +{"SEED-CBC","seed-cbc",NID_seed_cbc,8,&(lvalues[5129]),0}, +{"SEED-OFB","seed-ofb",NID_seed_ofb128,8,&(lvalues[5137]),0}, +{"SEED-CFB","seed-cfb",NID_seed_cfb128,8,&(lvalues[5145]),0}, }; static ASN1_OBJECT *sn_objs[NUM_SN]={ @@ -2085,6 +2098,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={ &(nid_objs[183]),/* "ISO-US" */ &(nid_objs[645]),/* "ITU-T" */ &(nid_objs[646]),/* "JOINT-ISO-ITU-T" */ +&(nid_objs[773]),/* "KISA" */ &(nid_objs[15]),/* "L" */ &(nid_objs[ 3]),/* "MD2" */ &(nid_objs[257]),/* "MD4" */ @@ -2147,6 +2161,10 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={ &(nid_objs[668]),/* "RSA-SHA256" */ &(nid_objs[669]),/* "RSA-SHA384" */ &(nid_objs[670]),/* "RSA-SHA512" */ +&(nid_objs[777]),/* "SEED-CBC" */ +&(nid_objs[779]),/* "SEED-CFB" */ +&(nid_objs[776]),/* "SEED-ECB" */ +&(nid_objs[778]),/* "SEED-OFB" */ &(nid_objs[41]),/* "SHA" */ &(nid_objs[64]),/* "SHA1" */ &(nid_objs[675]),/* "SHA224" */ @@ -3221,6 +3239,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={ &(nid_objs[492]),/* "janetMailbox" */ &(nid_objs[646]),/* "joint-iso-itu-t" */ &(nid_objs[150]),/* "keyBag" */ +&(nid_objs[773]),/* "kisa" */ &(nid_objs[477]),/* "lastModifiedBy" */ &(nid_objs[476]),/* "lastModifiedTime" */ &(nid_objs[157]),/* "localKeyID" */ @@ -3371,6 +3390,10 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={ &(nid_objs[733]),/* "sect571k1" */ &(nid_objs[734]),/* "sect571r1" */ &(nid_objs[635]),/* "secure device signature" */ +&(nid_objs[777]),/* "seed-cbc" */ +&(nid_objs[779]),/* "seed-cfb" */ +&(nid_objs[776]),/* "seed-ecb" */ +&(nid_objs[778]),/* "seed-ofb" */ &(nid_objs[105]),/* "serialNumber" */ &(nid_objs[625]),/* "set-addPolicy" */ &(nid_objs[515]),/* "set-attr" */ @@ -3811,6 +3834,7 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={ &(nid_objs[745]),/* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 13 4 12 */ &(nid_objs[124]),/* OBJ_rle_compression 1 1 1 1 666 1 */ &(nid_objs[125]),/* OBJ_zlib_compression 1 1 1 1 666 2 */ +&(nid_objs[773]),/* OBJ_kisa 1 2 410 200004 */ &(nid_objs[ 1]),/* OBJ_rsadsi 1 2 840 113549 */ &(nid_objs[185]),/* OBJ_X9cm 1 2 840 10040 4 */ &(nid_objs[127]),/* OBJ_id_pkix 1 3 6 1 5 5 7 */ @@ -3861,6 +3885,10 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={ &(nid_objs[768]),/* OBJ_camellia_256_ofb128 0 3 4401 5 3 1 9 43 */ &(nid_objs[759]),/* OBJ_camellia_256_cfb128 0 3 4401 5 3 1 9 44 */ &(nid_objs[437]),/* OBJ_pilot 0 9 2342 19200300 100 */ +&(nid_objs[776]),/* OBJ_seed_ecb 1 2 410 200004 1 3 */ +&(nid_objs[777]),/* OBJ_seed_cbc 1 2 410 200004 1 4 */ +&(nid_objs[779]),/* OBJ_seed_cfb128 1 2 410 200004 1 5 */ +&(nid_objs[778]),/* OBJ_seed_ofb128 1 2 410 200004 1 6 */ &(nid_objs[186]),/* OBJ_pkcs1 1 2 840 113549 1 1 */ &(nid_objs[27]),/* OBJ_pkcs3 1 2 840 113549 1 3 */ &(nid_objs[187]),/* OBJ_pkcs5 1 2 840 113549 1 5 */ diff --git a/crypto/openssl-0.9/crypto/objects/obj_mac.h b/crypto/openssl-0.9/crypto/objects/obj_mac.h index f447bbe69a..68b6e31a97 100644 --- a/crypto/openssl-0.9/crypto/objects/obj_mac.h +++ b/crypto/openssl-0.9/crypto/objects/obj_mac.h @@ -3406,3 +3406,28 @@ #define LN_camellia_256_cfb8 "camellia-256-cfb8" #define NID_camellia_256_cfb8 765 +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa OBJ_member_body,410L,200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb OBJ_kisa,1L,3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc OBJ_kisa,1L,4L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 OBJ_kisa,1L,5L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 OBJ_kisa,1L,6L + diff --git a/crypto/openssl-0.9/crypto/ocsp/ocsp.h b/crypto/openssl-0.9/crypto/ocsp/ocsp.h index 53f3364af0..8163411c92 100644 --- a/crypto/openssl-0.9/crypto/ocsp/ocsp.h +++ b/crypto/openssl-0.9/crypto/ocsp/ocsp.h @@ -469,7 +469,7 @@ int OCSP_basic_sign(OCSP_BASICRESP *brsp, ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, void *data, STACK_OF(ASN1_OBJECT) *sk); #define ASN1_STRING_encode_of(type,s,i2d,data,sk) \ -((ASN1_STRING *(*)(ASN1_STRING *,I2D_OF(type),type *,STACK_OF(ASN1_OBJECT) *))openssl_fcast(ASN1_STRING_encode))(s,i2d,data,sk) + ASN1_STRING_encode(s, CHECKED_I2D_OF(type, i2d), data, sk) X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim); diff --git a/crypto/openssl-0.9/crypto/opensslv.h b/crypto/openssl-0.9/crypto/opensslv.h index 8a5b34e4f0..b237c2f67d 100644 --- a/crypto/openssl-0.9/crypto/opensslv.h +++ b/crypto/openssl-0.9/crypto/opensslv.h @@ -25,11 +25,11 @@ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -#define OPENSSL_VERSION_NUMBER 0x0090805fL +#define OPENSSL_VERSION_NUMBER 0x00908070L #ifdef OPENSSL_FIPS -#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8e-fips 23 Feb 2007" +#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8f-fips 11 Oct 2007" #else -#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8e 23 Feb 2007" +#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8f 11 Oct 2007" #endif #define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT diff --git a/crypto/openssl-0.9/crypto/pem/pem.h b/crypto/openssl-0.9/crypto/pem/pem.h index c28706ddc0..4e24cc5b52 100644 --- a/crypto/openssl-0.9/crypto/pem/pem.h +++ b/crypto/openssl-0.9/crypto/pem/pem.h @@ -220,19 +220,28 @@ typedef struct pem_ctx_st #define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ { \ -return(((type *(*)(D2I_OF(type),char *,FILE *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read))(d2i_##asn1, str,fp,x,cb,u)); \ + return (type*)PEM_ASN1_read(CHECKED_D2I_OF(type, d2i_##asn1), \ + str, fp, \ + CHECKED_PPTR_OF(type, x), \ + cb, u); \ } #define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ int PEM_write_##name(FILE *fp, type *x) \ { \ -return(((int (*)(I2D_OF(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL)); \ + return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \ + str, fp, \ + CHECKED_PTR_OF(type, x), \ + NULL, NULL, 0, NULL, NULL); \ } #define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ int PEM_write_##name(FILE *fp, const type *x) \ { \ -return(((int (*)(I2D_OF_const(type),const char *,FILE *, const type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL)); \ + return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \ + str, fp, \ + CHECKED_PTR_OF(const type, x), \ + NULL, NULL, 0, NULL, NULL); \ } #define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ @@ -240,7 +249,10 @@ int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ unsigned char *kstr, int klen, pem_password_cb *cb, \ void *u) \ { \ - return(((int (*)(I2D_OF(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u)); \ + return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \ + str, fp, \ + CHECKED_PTR_OF(type, x), \ + enc, kstr, klen, cb, u); \ } #define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ @@ -248,7 +260,10 @@ int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ unsigned char *kstr, int klen, pem_password_cb *cb, \ void *u) \ { \ - return(((int (*)(I2D_OF_const(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u)); \ + return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \ + str, fp, \ + CHECKED_PTR_OF(const type, x), \ + enc, kstr, klen, cb, u); \ } #endif @@ -256,33 +271,48 @@ int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ #define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ { \ -return(((type *(*)(D2I_OF(type),const char *,BIO *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read_bio))(d2i_##asn1, str,bp,x,cb,u)); \ + return (type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i_##asn1), \ + str, bp, \ + CHECKED_PPTR_OF(type, x), \ + cb, u); \ } #define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ int PEM_write_bio_##name(BIO *bp, type *x) \ { \ -return(((int (*)(I2D_OF(type),const char *,BIO *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL)); \ + return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \ + str, bp, \ + CHECKED_PTR_OF(type, x), \ + NULL, NULL, 0, NULL, NULL); \ } #define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ int PEM_write_bio_##name(BIO *bp, const type *x) \ { \ -return(((int (*)(I2D_OF_const(type),const char *,BIO *,const type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL)); \ + return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \ + str, bp, \ + CHECKED_PTR_OF(const type, x), \ + NULL, NULL, 0, NULL, NULL); \ } #define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ { \ - return(((int (*)(I2D_OF(type),const char *,BIO *,type *,const EVP_CIPHER *,unsigned char *,int,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u)); \ + return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \ + str, bp, \ + CHECKED_PTR_OF(type, x), \ + enc, kstr, klen, cb, u); \ } #define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ { \ - return(((int (*)(I2D_OF_const(type),const char *,BIO *,type *,const EVP_CIPHER *,unsigned char *,int,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u)); \ + return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \ + str, bp, \ + CHECKED_PTR_OF(const type, x), \ + enc, kstr, klen, cb, u); \ } #define IMPLEMENT_PEM_write(name, type, str, asn1) \ @@ -545,13 +575,22 @@ int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char pem_password_cb *cb, void *u); void * PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, pem_password_cb *cb, void *u); + #define PEM_ASN1_read_bio_of(type,d2i,name,bp,x,cb,u) \ -((type *(*)(D2I_OF(type),const char *,BIO *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read_bio))(d2i,name,bp,x,cb,u) + ((type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i), \ + name, bp, \ + CHECKED_PPTR_OF(type, x), \ + cb, u)) + int PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp,char *x, const EVP_CIPHER *enc,unsigned char *kstr,int klen, pem_password_cb *cb, void *u); + #define PEM_ASN1_write_bio_of(type,i2d,name,bp,x,enc,kstr,klen,cb,u) \ - ((int (*)(I2D_OF(type),const char *,BIO *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d,name,bp,x,enc,kstr,klen,cb,u) + (PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d), \ + name, bp, \ + CHECKED_PTR_OF(type, x), \ + enc, kstr, klen, cb, u)) STACK_OF(X509_INFO) * PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); int PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc, diff --git a/crypto/openssl-0.9/crypto/pkcs7/pk7_mime.c b/crypto/openssl-0.9/crypto/pkcs7/pk7_mime.c index 134746c186..25566a4c21 100644 --- a/crypto/openssl-0.9/crypto/pkcs7/pk7_mime.c +++ b/crypto/openssl-0.9/crypto/pkcs7/pk7_mime.c @@ -121,7 +121,7 @@ static int B64_write_PKCS7(BIO *bio, PKCS7 *p7) } bio = BIO_push(b64, bio); i2d_PKCS7_bio(bio, p7); - BIO_flush(bio); + (void)BIO_flush(bio); bio = BIO_pop(bio); BIO_free(b64); return 1; @@ -138,7 +138,7 @@ static PKCS7 *B64_read_PKCS7(BIO *bio) bio = BIO_push(b64, bio); if(!(p7 = d2i_PKCS7_bio(bio, NULL))) PKCS7err(PKCS7_F_B64_READ_PKCS7,PKCS7_R_DECODE_ERROR); - BIO_flush(bio); + (void)BIO_flush(bio); bio = BIO_pop(bio); BIO_free(b64); return p7; diff --git a/crypto/openssl-0.9/crypto/pkcs7/pk7_smime.c b/crypto/openssl-0.9/crypto/pkcs7/pk7_smime.c index fab85137b7..5c6b0fe24b 100644 --- a/crypto/openssl-0.9/crypto/pkcs7/pk7_smime.c +++ b/crypto/openssl-0.9/crypto/pkcs7/pk7_smime.c @@ -426,7 +426,7 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, SMIME_crlf_copy(in, p7bio, flags); - BIO_flush(p7bio); + (void)BIO_flush(p7bio); if (!PKCS7_dataFinal(p7,p7bio)) { PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR); diff --git a/crypto/openssl-0.9/crypto/pqueue/pq_compat.h b/crypto/openssl-0.9/crypto/pqueue/pq_compat.h index 28c58a0261..fd36578882 100644 --- a/crypto/openssl-0.9/crypto/pqueue/pq_compat.h +++ b/crypto/openssl-0.9/crypto/pqueue/pq_compat.h @@ -57,7 +57,7 @@ * */ -#include "opensslconf.h" +#include #include /* diff --git a/crypto/openssl-0.9/crypto/rand/randfile.c b/crypto/openssl-0.9/crypto/rand/randfile.c index d69bdf8b8a..cec5880a8f 100644 --- a/crypto/openssl-0.9/crypto/rand/randfile.c +++ b/crypto/openssl-0.9/crypto/rand/randfile.c @@ -102,10 +102,8 @@ int RAND_load_file(const char *file, long bytes) if (file == NULL) return(0); - i=stat(file,&sb); - /* If the state fails, put some crap in anyway */ + if (stat(file,&sb) < 0) return(0); RAND_add(&sb,sizeof(sb),0.0); - if (i < 0) return(0); if (bytes == 0) return(ret); in=fopen(file,"rb"); diff --git a/crypto/openssl-0.9/crypto/rsa/rsa.h b/crypto/openssl-0.9/crypto/rsa/rsa.h index b19c556930..6b5e4f8a9a 100644 --- a/crypto/openssl-0.9/crypto/rsa/rsa.h +++ b/crypto/openssl-0.9/crypto/rsa/rsa.h @@ -195,13 +195,27 @@ struct rsa_st * default (ignoring RSA_FLAG_BLINDING), * but other engines might not need it */ -#define RSA_FLAG_NO_EXP_CONSTTIME 0x0100 /* new with 0.9.7h; the built-in RSA +#define RSA_FLAG_NO_CONSTTIME 0x0100 /* new with 0.9.8f; the built-in RSA + * implementation now uses constant time + * operations by default in private key operations, + * e.g., constant time modular exponentiation, + * modular inverse without leaking branches, + * division without leaking branches. This + * flag disables these constant time + * operations and results in faster RSA + * private key operations. + */ +#ifndef OPENSSL_NO_DEPRECATED +#define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME /* deprecated name for the flag*/ + /* new with 0.9.7h; the built-in RSA * implementation now uses constant time * modular exponentiation for secret exponents * by default. This flag causes the * faster variable sliding window method to * be used for all exponents. */ +#endif + #define RSA_PKCS1_PADDING 1 #define RSA_SSLV23_PADDING 2 diff --git a/crypto/openssl-0.9/crypto/rsa/rsa_eay.c b/crypto/openssl-0.9/crypto/rsa/rsa_eay.c index e7b7a9c4fc..9e79374e68 100644 --- a/crypto/openssl-0.9/crypto/rsa/rsa_eay.c +++ b/crypto/openssl-0.9/crypto/rsa/rsa_eay.c @@ -429,11 +429,11 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, BIGNUM local_d; BIGNUM *d = NULL; - if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { BN_init(&local_d); d = &local_d; - BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME); + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d = rsa->d; @@ -551,10 +551,10 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from, BIGNUM local_d; BIGNUM *d = NULL; - if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { d = &local_d; - BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME); + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d = rsa->d; @@ -715,8 +715,9 @@ err: static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { BIGNUM *r1,*m1,*vrfy; - BIGNUM local_dmp1, local_dmq1; - BIGNUM *dmp1, *dmq1; + BIGNUM local_dmp1,local_dmq1,local_c,local_r1; + BIGNUM *dmp1,*dmq1,*c,*pr1; + int bn_flags; int ret=0; BN_CTX_start(ctx); @@ -724,26 +725,72 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) m1 = BN_CTX_get(ctx); vrfy = BN_CTX_get(ctx); + /* Make sure mod_inverse in montgomerey intialization use correct + * BN_FLG_CONSTTIME flag. + */ + bn_flags = rsa->p->flags; + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + rsa->p->flags |= BN_FLG_CONSTTIME; + } MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + /* We restore bn_flags back */ + rsa->p->flags = bn_flags; + + /* Make sure mod_inverse in montgomerey intialization use correct + * BN_FLG_CONSTTIME flag. + */ + bn_flags = rsa->q->flags; + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + rsa->q->flags |= BN_FLG_CONSTTIME; + } MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + /* We restore bn_flags back */ + rsa->q->flags = bn_flags; + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); - if (!BN_mod(r1,I,rsa->q,ctx)) goto err; - if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) + /* compute I mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + c = &local_c; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + if (!BN_mod(r1,c,rsa->q,ctx)) goto err; + } + else + { + if (!BN_mod(r1,I,rsa->q,ctx)) goto err; + } + + /* compute r1^dmq1 mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { dmq1 = &local_dmq1; - BN_with_flags(dmq1, rsa->dmq1, BN_FLG_EXP_CONSTTIME); + BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); } else dmq1 = rsa->dmq1; if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx, rsa->_method_mod_q)) goto err; - if (!BN_mod(r1,I,rsa->p,ctx)) goto err; - if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) + /* compute I mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + c = &local_c; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + if (!BN_mod(r1,c,rsa->p,ctx)) goto err; + } + else + { + if (!BN_mod(r1,I,rsa->p,ctx)) goto err; + } + + /* compute r1^dmp1 mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { dmp1 = &local_dmp1; - BN_with_flags(dmp1, rsa->dmp1, BN_FLG_EXP_CONSTTIME); + BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); } else dmp1 = rsa->dmp1; @@ -757,7 +804,17 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) if (!BN_add(r0,r0,rsa->p)) goto err; if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err; - if (!BN_mod(r0,r1,rsa->p,ctx)) goto err; + + /* Turn BN_FLG_CONSTTIME flag on before division operation */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + pr1 = &local_r1; + BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); + } + else + pr1 = r1; + if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err; + /* If p < q it is occasionally possible for the correction of * adding 'p' if r0 is negative above to leave the result still * negative. This can break the private key operations: the following @@ -790,10 +847,10 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) BIGNUM local_d; BIGNUM *d = NULL; - if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME)) + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { d = &local_d; - BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME); + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else d = rsa->d; diff --git a/crypto/openssl-0.9/crypto/rsa/rsa_gen.c b/crypto/openssl-0.9/crypto/rsa/rsa_gen.c index 742f8b18e5..767f7ab682 100644 --- a/crypto/openssl-0.9/crypto/rsa/rsa_gen.c +++ b/crypto/openssl-0.9/crypto/rsa/rsa_gen.c @@ -85,6 +85,8 @@ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) { BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; + BIGNUM local_r0,local_d,local_p; + BIGNUM *pr0,*d,*p; int bitsp,bitsq,ok= -1,n=0; BN_CTX *ctx=NULL; @@ -165,16 +167,39 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */ if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */ if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */ - if (!BN_mod_inverse(rsa->d,rsa->e,r0,ctx)) goto err; /* d */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + pr0 = &local_r0; + BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); + } + else + pr0 = r0; + if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */ + + /* set up d for correct BN_FLG_CONSTTIME flag */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } + else + d = rsa->d; /* calculate d mod (p-1) */ - if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) goto err; + if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err; /* calculate d mod (q-1) */ - if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) goto err; + if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err; /* calculate inverse of q mod p */ - if (!BN_mod_inverse(rsa->iqmp,rsa->q,rsa->p,ctx)) goto err; + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + p = &local_p; + BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); + } + else + p = rsa->p; + if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err; ok=1; err: diff --git a/crypto/openssl-0.9/crypto/rsa/rsa_lib.c b/crypto/openssl-0.9/crypto/rsa/rsa_lib.c index cca32c098d..104aa4c1f2 100644 --- a/crypto/openssl-0.9/crypto/rsa/rsa_lib.c +++ b/crypto/openssl-0.9/crypto/rsa/rsa_lib.c @@ -361,7 +361,8 @@ err: BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) { - BIGNUM *e; + BIGNUM local_n; + BIGNUM *e,*n; BN_CTX *ctx; BN_BLINDING *ret = NULL; @@ -400,7 +401,16 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0); } - ret = BN_BLINDING_create_param(NULL, e, rsa->n, ctx, + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + /* Set BN_FLG_CONSTTIME flag */ + n = &local_n; + BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); + } + else + n = rsa->n; + + ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp, rsa->_method_mod_n); if (ret == NULL) { diff --git a/crypto/openssl-0.9/crypto/stack/safestack.h b/crypto/openssl-0.9/crypto/stack/safestack.h index d496f365c2..53df649ecf 100644 --- a/crypto/openssl-0.9/crypto/stack/safestack.h +++ b/crypto/openssl-0.9/crypto/stack/safestack.h @@ -57,11 +57,20 @@ #include -typedef void (*openssl_fptr)(void); -#define openssl_fcast(f) ((openssl_fptr)f) - #ifdef DEBUG_SAFESTACK +#ifndef CHECKED_PTR_OF +#define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +#endif + +#define CHECKED_SK_FREE_FUNC(type, p) \ + ((void (*)(void *)) ((1 ? p : (void (*)(type *))0))) + +#define CHECKED_SK_CMP_FUNC(type, p) \ + ((int (*)(const char * const *, const char * const *)) \ + ((1 ? p : (int (*)(const type * const *, const type * const *))0))) + #define STACK_OF(type) struct stack_st_##type #define PREDECLARE_STACK_OF(type) STACK_OF(type); @@ -76,76 +85,71 @@ STACK_OF(type) \ /* SKM_sk_... stack macros are internal to safestack.h: * never use them directly, use sk__... instead */ #define SKM_sk_new(type, cmp) \ - ((STACK_OF(type) * (*)(int (*)(const type * const *, const type * const *)))openssl_fcast(sk_new))(cmp) + ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp))) #define SKM_sk_new_null(type) \ - ((STACK_OF(type) * (*)(void))openssl_fcast(sk_new_null))() + ((STACK_OF(type) *)sk_new_null()) #define SKM_sk_free(type, st) \ - ((void (*)(STACK_OF(type) *))openssl_fcast(sk_free))(st) + sk_free(CHECKED_PTR_OF(STACK_OF(type), st)) #define SKM_sk_num(type, st) \ - ((int (*)(const STACK_OF(type) *))openssl_fcast(sk_num))(st) + sk_num(CHECKED_PTR_OF(STACK_OF(type), st)) #define SKM_sk_value(type, st,i) \ - ((type * (*)(const STACK_OF(type) *, int))openssl_fcast(sk_value))(st, i) + ((type *)sk_value(CHECKED_PTR_OF(STACK_OF(type), st), i)) #define SKM_sk_set(type, st,i,val) \ - ((type * (*)(STACK_OF(type) *, int, type *))openssl_fcast(sk_set))(st, i, val) + sk_set(CHECKED_PTR_OF(STACK_OF(type), st), i, CHECKED_PTR_OF(type, val)) #define SKM_sk_zero(type, st) \ - ((void (*)(STACK_OF(type) *))openssl_fcast(sk_zero))(st) + sk_zero(CHECKED_PTR_OF(STACK_OF(type), st)) #define SKM_sk_push(type, st,val) \ - ((int (*)(STACK_OF(type) *, type *))openssl_fcast(sk_push))(st, val) + sk_push(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val)) #define SKM_sk_unshift(type, st,val) \ - ((int (*)(STACK_OF(type) *, type *))openssl_fcast(sk_unshift))(st, val) + sk_unshift(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val)) #define SKM_sk_find(type, st,val) \ - ((int (*)(STACK_OF(type) *, type *))openssl_fcast(sk_find))(st, val) + sk_find(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val)) #define SKM_sk_delete(type, st,i) \ - ((type * (*)(STACK_OF(type) *, int))openssl_fcast(sk_delete))(st, i) + (type *)sk_delete(CHECKED_PTR_OF(STACK_OF(type), st), i) #define SKM_sk_delete_ptr(type, st,ptr) \ - ((type * (*)(STACK_OF(type) *, type *))openssl_fcast(sk_delete_ptr))(st, ptr) + (type *)sk_delete_ptr(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, ptr)) #define SKM_sk_insert(type, st,val,i) \ - ((int (*)(STACK_OF(type) *, type *, int))openssl_fcast(sk_insert))(st, val, i) + sk_insert(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val), i) #define SKM_sk_set_cmp_func(type, st,cmp) \ - ((int (*(*)(STACK_OF(type) *, int (*)(const type * const *, const type * const *))) \ - (const type * const *, const type * const *))openssl_fcast(sk_set_cmp_func))\ - (st, cmp) + ((int (*)(const type * const *,const type * const *)) \ + sk_set_cmp_func(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_SK_CMP_FUNC(type, cmp))) #define SKM_sk_dup(type, st) \ - ((STACK_OF(type) *(*)(STACK_OF(type) *))openssl_fcast(sk_dup))(st) + (STACK_OF(type) *)sk_dup(CHECKED_PTR_OF(STACK_OF(type), st)) #define SKM_sk_pop_free(type, st,free_func) \ - ((void (*)(STACK_OF(type) *, void (*)(type *)))openssl_fcast(sk_pop_free))\ - (st, free_func) + sk_pop_free(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_SK_FREE_FUNC(type, free_func)) #define SKM_sk_shift(type, st) \ - ((type * (*)(STACK_OF(type) *))openssl_fcast(sk_shift))(st) + (type *)sk_shift(CHECKED_PTR_OF(STACK_OF(type), st)) #define SKM_sk_pop(type, st) \ - ((type * (*)(STACK_OF(type) *))openssl_fcast(sk_pop))(st) + (type *)sk_pop(CHECKED_PTR_OF(STACK_OF(type), st)) #define SKM_sk_sort(type, st) \ - ((void (*)(STACK_OF(type) *))openssl_fcast(sk_sort))(st) + sk_sort(CHECKED_PTR_OF(STACK_OF(type), st)) #define SKM_sk_is_sorted(type, st) \ - ((int (*)(const STACK_OF(type) *))openssl_fcast(sk_is_sorted))(st) + sk_is_sorted(CHECKED_PTR_OF(STACK_OF(type), st)) #define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ -((STACK_OF(type) * (*) (STACK_OF(type) **,const unsigned char **, long , \ - type *(*)(type **, const unsigned char **,long), \ - void (*)(type *), int ,int )) openssl_fcast(d2i_ASN1_SET)) \ - (st,pp,length, d2i_func, free_func, ex_tag,ex_class) + (STACK_OF(type) *)d2i_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), \ + pp, length, \ + CHECKED_D2I_OF(type, d2i_func), \ + CHECKED_SK_FREE_FUNC(type, free_func), \ + ex_tag, ex_class) + #define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \ - ((int (*)(STACK_OF(type) *,unsigned char **, \ - int (*)(type *,unsigned char **), int , int , int)) openssl_fcast(i2d_ASN1_SET)) \ - (st,pp,i2d_func,ex_tag,ex_class,is_set) + i2d_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), pp, \ + CHECKED_I2D_OF(type, i2d_func), \ + ex_tag, ex_class, is_set) #define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \ - ((unsigned char *(*)(STACK_OF(type) *, \ - int (*)(type *,unsigned char **), unsigned char **,int *)) openssl_fcast(ASN1_seq_pack)) \ - (st, i2d_func, buf, len) + ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \ + CHECKED_I2D_OF(type, i2d_func), buf, len) + #define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \ - ((STACK_OF(type) * (*)(const unsigned char *,int, \ - type *(*)(type **,const unsigned char **, long), \ - void (*)(type *)))openssl_fcast(ASN1_seq_unpack)) \ - (buf,len,d2i_func, free_func) + (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func)) #define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \ - ((STACK_OF(type) * (*)(X509_ALGOR *, \ - type *(*)(type **, const unsigned char **, long), \ - void (*)(type *), \ - const char *, int, \ - ASN1_STRING *, int))PKCS12_decrypt_d2i) \ - (algor,d2i_func,free_func,pass,passlen,oct,seq) + (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \ + CHECKED_D2I_OF(type, d2i_func), \ + CHECKED_SK_FREE_FUNC(type, free_func), \ + pass, passlen, oct, seq) #else diff --git a/crypto/openssl-0.9/crypto/store/str_lib.c b/crypto/openssl-0.9/crypto/store/str_lib.c index c0ad763e9a..32ae5bd395 100644 --- a/crypto/openssl-0.9/crypto/store/str_lib.c +++ b/crypto/openssl-0.9/crypto/store/str_lib.c @@ -236,7 +236,7 @@ const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth) #define check_store(s,fncode,fnname,fnerrcode) \ do \ { \ - if ((s) == NULL || (s)->meth) \ + if ((s) == NULL || (s)->meth == NULL) \ { \ STOREerr((fncode), ERR_R_PASSED_NULL_PARAMETER); \ return 0; \ diff --git a/crypto/openssl-0.9/crypto/x509/x509_txt.c b/crypto/openssl-0.9/crypto/x509/x509_txt.c index a80c87eef3..73a8ec726f 100644 --- a/crypto/openssl-0.9/crypto/x509/x509_txt.c +++ b/crypto/openssl-0.9/crypto/x509/x509_txt.c @@ -129,7 +129,7 @@ const char *X509_verify_cert_error_string(long n) case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: return("proxy path length constraint exceeded"); case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: - return("proxy cerificates not allowed, please set the appropriate flag"); + return("proxy certificates not allowed, please set the appropriate flag"); case X509_V_ERR_INVALID_PURPOSE: return ("unsupported certificate purpose"); case X509_V_ERR_CERT_UNTRUSTED: diff --git a/crypto/openssl-0.9/crypto/x509/x509_vfy.c b/crypto/openssl-0.9/crypto/x509/x509_vfy.c index 07df21f6b9..9a62ebcf67 100644 --- a/crypto/openssl-0.9/crypto/x509/x509_vfy.c +++ b/crypto/openssl-0.9/crypto/x509/x509_vfy.c @@ -164,7 +164,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) goto end; } CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509); - sk_X509_delete_ptr(sktmp,xtmp); + (void)sk_X509_delete_ptr(sktmp,xtmp); ctx->last_untrusted++; x=xtmp; num++; @@ -214,7 +214,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) */ X509_free(x); x = xtmp; - sk_X509_set(ctx->chain, i - 1, x); + (void)sk_X509_set(ctx->chain, i - 1, x); ctx->last_untrusted=0; } } diff --git a/crypto/openssl-0.9/crypto/x509/x509_vpm.c b/crypto/openssl-0.9/crypto/x509/x509_vpm.c index 5e69259a79..e9db6d62a7 100644 --- a/crypto/openssl-0.9/crypto/x509/x509_vpm.c +++ b/crypto/openssl-0.9/crypto/x509/x509_vpm.c @@ -385,7 +385,7 @@ int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) { ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); X509_VERIFY_PARAM_free(ptmp); - sk_X509_VERIFY_PARAM_delete(param_table, idx); + (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); } } if (!sk_X509_VERIFY_PARAM_push(param_table, param)) diff --git a/crypto/openssl-0.9/crypto/x509v3/pcy_tree.c b/crypto/openssl-0.9/crypto/x509v3/pcy_tree.c index 27d29f25a8..4fda1d419a 100644 --- a/crypto/openssl-0.9/crypto/x509v3/pcy_tree.c +++ b/crypto/openssl-0.9/crypto/x509v3/pcy_tree.c @@ -345,7 +345,7 @@ static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) { node->parent->nchild--; OPENSSL_free(node); - sk_X509_POLICY_NODE_delete(curr->nodes, i); + (void)sk_X509_POLICY_NODE_delete(curr->nodes, i); } } @@ -358,7 +358,7 @@ static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) { node->parent->nchild--; OPENSSL_free(node); - sk_X509_POLICY_NODE_delete(curr->nodes, i); + (void)sk_X509_POLICY_NODE_delete(curr->nodes, i); } } if (curr->anyPolicy && !curr->anyPolicy->nchild) diff --git a/crypto/openssl-0.9/crypto/x509v3/v3_pci.c b/crypto/openssl-0.9/crypto/x509v3/v3_pci.c index 5158b1dfb3..601211f416 100644 --- a/crypto/openssl-0.9/crypto/x509v3/v3_pci.c +++ b/crypto/openssl-0.9/crypto/x509v3/v3_pci.c @@ -286,12 +286,6 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); goto err; } - pci->proxyPolicy = PROXY_POLICY_new(); - if (!pci->proxyPolicy) - { - X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); - goto err; - } pci->proxyPolicy->policyLanguage = language; language = NULL; pci->proxyPolicy->policy = policy; policy = NULL; @@ -301,11 +295,6 @@ err: if (language) { ASN1_OBJECT_free(language); language = NULL; } if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; } if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; } - if (pci && pci->proxyPolicy) - { - PROXY_POLICY_free(pci->proxyPolicy); - pci->proxyPolicy = NULL; - } if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; } end: sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); diff --git a/crypto/openssl-0.9/engines/e_ubsec.c b/crypto/openssl-0.9/engines/e_ubsec.c index 8b6c98bafa..e8389de6a1 100644 --- a/crypto/openssl-0.9/engines/e_ubsec.c +++ b/crypto/openssl-0.9/engines/e_ubsec.c @@ -822,11 +822,11 @@ static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, int v_len, d_len; int to_return = 0; int fd; - BIGNUM v; + BIGNUM v, *pv = &v; BN_init(&v); - if(!bn_wexpand(&v, dsa->p->top)) { + if(!bn_wexpand(pv, dsa->p->top)) { UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL); goto err; } diff --git a/crypto/openssl-0.9/ssl/d1_both.c b/crypto/openssl-0.9/ssl/d1_both.c index b746a50dd7..22bd28a4bb 100644 --- a/crypto/openssl-0.9/ssl/d1_both.c +++ b/crypto/openssl-0.9/ssl/d1_both.c @@ -138,38 +138,40 @@ static void dtls1_set_message_header_int(SSL *s, unsigned char mt, unsigned long frag_len); static int dtls1_retransmit_buffered_messages(SSL *s); static long dtls1_get_message_fragment(SSL *s, int st1, int stn, - long max, int *ok); -static void dtls1_process_handshake_fragment(SSL *s, int frag_len); + long max, int *ok); static hm_fragment * dtls1_hm_fragment_new(unsigned long frag_len) - { - hm_fragment *frag = NULL; - unsigned char *buf = NULL; - - frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); - if ( frag == NULL) - return NULL; - - buf = (unsigned char *)OPENSSL_malloc(frag_len - + DTLS1_HM_HEADER_LENGTH); - if ( buf == NULL) - { - OPENSSL_free(frag); - return NULL; - } - - frag->fragment = buf; - - return frag; - } + { + hm_fragment *frag = NULL; + unsigned char *buf = NULL; + + frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); + if ( frag == NULL) + return NULL; + + if (frag_len) + { + buf = (unsigned char *)OPENSSL_malloc(frag_len); + if ( buf == NULL) + { + OPENSSL_free(frag); + return NULL; + } + } + + /* zero length fragment gets zero frag->fragment */ + frag->fragment = buf; + + return frag; + } static void dtls1_hm_fragment_free(hm_fragment *frag) - { - OPENSSL_free(frag->fragment); - OPENSSL_free(frag); - } + { + if (frag->fragment) OPENSSL_free(frag->fragment); + OPENSSL_free(frag); + } /* 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) @@ -180,7 +182,7 @@ int dtls1_do_write(SSL *s, int type) /* AHA! Figure out the MTU, and stick to the right size */ 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); @@ -207,7 +209,7 @@ int dtls1_do_write(SSL *s, int type) 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)); @@ -254,11 +256,11 @@ int dtls1_do_write(SSL *s, int type) s->init_off -= DTLS1_HM_HEADER_LENGTH; s->init_num += DTLS1_HM_HEADER_LENGTH; - /* write atleast DTLS1_HM_HEADER_LENGTH bytes */ + /* write atleast DTLS1_HM_HEADER_LENGTH bytes */ if ( len <= DTLS1_HM_HEADER_LENGTH) len += DTLS1_HM_HEADER_LENGTH; } - + dtls1_fix_message_header(s, frag_off, len - DTLS1_HM_HEADER_LENGTH); @@ -286,18 +288,40 @@ int dtls1_do_write(SSL *s, int type) } else { - + /* bad if this assert fails, only part of the handshake * message got sent. but why would this happen? */ - OPENSSL_assert(len == (unsigned int)ret); - + OPENSSL_assert(len == (unsigned int)ret); + if (type == SSL3_RT_HANDSHAKE && ! s->d1->retransmitting) + { /* should not be done for 'Hello Request's, but in that case * we'll ignore the result anyway */ - ssl3_finish_mac(s, - (unsigned char *)&s->init_buf->data[s->init_off + - DTLS1_HM_HEADER_LENGTH], ret - DTLS1_HM_HEADER_LENGTH); - + unsigned char *p = &s->init_buf->data[s->init_off]; + const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + int len; + + if (frag_off == 0 && s->client_version != DTLS1_BAD_VER) + { + /* reconstruct message header is if it + * is being sent in single fragment */ + *p++ = msg_hdr->type; + l2n3(msg_hdr->msg_len,p); + s2n (msg_hdr->seq,p); + l2n3(0,p); + l2n3(msg_hdr->msg_len,p); + p -= DTLS1_HM_HEADER_LENGTH; + len = ret; + } + else + { + p += DTLS1_HM_HEADER_LENGTH; + len = ret - DTLS1_HM_HEADER_LENGTH; + } + + ssl3_finish_mac(s, p, len); + } + if (ret == s->init_num) { if (s->msg_callback) @@ -307,7 +331,7 @@ int dtls1_do_write(SSL *s, int type) s->init_off = 0; /* done writing this message */ s->init_num = 0; - + return(1); } s->init_off+=ret; @@ -327,6 +351,7 @@ int dtls1_do_write(SSL *s, int type) long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) { int i, al; + struct hm_header_st *msg_hdr; /* s3->tmp is used to store messages that are unexpected, caused * by the absence of an optional handshake message */ @@ -344,25 +369,56 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) s->init_num = (int)s->s3->tmp.message_size; return s->init_num; } - + + msg_hdr = &s->d1->r_msg_hdr; do { - if ( s->d1->r_msg_hdr.frag_off == 0) + if ( msg_hdr->frag_off == 0) { /* s->d1->r_message_header.msg_len = 0; */ - memset(&(s->d1->r_msg_hdr), 0x00, sizeof(struct hm_header_st)); + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); } i = dtls1_get_message_fragment(s, st1, stn, max, ok); if ( i == DTLS1_HM_BAD_FRAGMENT || - i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ + i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ continue; else if ( i <= 0 && !*ok) return i; - if (s->d1->r_msg_hdr.msg_len == (unsigned int)s->init_num - DTLS1_HM_HEADER_LENGTH) + /* Note that s->init_sum is used as a counter summing + * up fragments' lengths: as soon as they sum up to + * handshake packet length, we assume we have got all + * the fragments. Overlapping fragments would cause + * premature termination, so we don't expect overlaps. + * Well, handling overlaps would require something more + * drastic. Indeed, as it is now there is no way to + * tell if out-of-order fragment from the middle was + * the last. '>=' is the best/least we can do to control + * the potential damage caused by malformed overlaps. */ + if ((unsigned int)s->init_num >= msg_hdr->msg_len) { - memset(&(s->d1->r_msg_hdr), 0x00, sizeof(struct hm_header_st)); + unsigned char *p = s->init_buf->data; + unsigned long msg_len = msg_hdr->msg_len; + + /* reconstruct message header as if it was + * sent in single fragment */ + *(p++) = msg_hdr->type; + l2n3(msg_len,p); + s2n (msg_hdr->seq,p); + l2n3(0,p); + l2n3(msg_len,p); + if (s->client_version != DTLS1_BAD_VER) + p -= DTLS1_HM_HEADER_LENGTH, + msg_len += DTLS1_HM_HEADER_LENGTH; + + ssl3_finish_mac(s, p, msg_len); + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + p, msg_len, + s, s->msg_callback_arg); + + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); s->d1->handshake_read_seq++; /* we just read a handshake message from the other side: @@ -379,11 +435,11 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) * first data segment, but is there a better way? */ dtls1_clear_record_buffer(s); - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - return s->init_num - DTLS1_HM_HEADER_LENGTH; + s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + return s->init_num; } else - s->d1->r_msg_hdr.frag_off = i; + msg_hdr->frag_off = i; } while(1) ; f_err: @@ -393,161 +449,183 @@ f_err: } -static int -dtls1_retrieve_buffered_fragment(SSL *s, unsigned long *copied) - { - /* (0) check whether the desired fragment is available - * if so: - * (1) copy over the fragment to s->init_buf->data[] - * (2) update s->init_num - */ - pitem *item; - hm_fragment *frag; - unsigned long overlap; - unsigned char *p; - - item = pqueue_peek(s->d1->buffered_messages); - if ( item == NULL) - return 0; - - frag = (hm_fragment *)item->data; - - if ( s->d1->handshake_read_seq == frag->msg_header.seq && - frag->msg_header.frag_off <= (unsigned int)s->init_num - DTLS1_HM_HEADER_LENGTH) - { - pqueue_pop(s->d1->buffered_messages); - overlap = s->init_num - DTLS1_HM_HEADER_LENGTH - - frag->msg_header.frag_off; - - p = frag->fragment; - - memcpy(&s->init_buf->data[s->init_num], - p + DTLS1_HM_HEADER_LENGTH + overlap, - frag->msg_header.frag_len - overlap); - - OPENSSL_free(frag->fragment); - OPENSSL_free(frag); - pitem_free(item); - - *copied = frag->msg_header.frag_len - overlap; - return *copied; - } - else - return 0; - } +static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max) + { + size_t frag_off,frag_len,msg_len; + msg_len = msg_hdr->msg_len; + frag_off = msg_hdr->frag_off; + frag_len = msg_hdr->frag_len; -static int -dtls1_buffer_handshake_fragment(SSL *s, struct hm_header_st* msg_hdr) -{ - hm_fragment *frag = NULL; - pitem *item = NULL; - PQ_64BIT seq64; + /* sanity checking */ + if ( (frag_off+frag_len) > msg_len) + { + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } - frag = dtls1_hm_fragment_new(msg_hdr->frag_len); - if ( frag == NULL) - goto err; + if ( (frag_off+frag_len) > (unsigned long)max) + { + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } - memcpy(frag->fragment, &(s->init_buf->data[s->init_num]), - msg_hdr->frag_len + DTLS1_HM_HEADER_LENGTH); + if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */ + { + /* msg_len is limited to 2^24, but is effectively checked + * against max above */ + if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH)) + { + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB); + return SSL_AD_INTERNAL_ERROR; + } - memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + s->s3->tmp.message_size = msg_len; + s->d1->r_msg_hdr.msg_len = msg_len; + s->s3->tmp.message_type = msg_hdr->type; + s->d1->r_msg_hdr.type = msg_hdr->type; + s->d1->r_msg_hdr.seq = msg_hdr->seq; + } + else if (msg_len != s->d1->r_msg_hdr.msg_len) + { + /* They must be playing with us! BTW, failure to enforce + * upper limit would open possibility for buffer overrun. */ + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + return 0; /* no error */ + } - pq_64bit_init(&seq64); - pq_64bit_assign_word(&seq64, msg_hdr->seq); - item = pitem_new(seq64, frag); - if ( item == NULL) - goto err; +static int +dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) + { + /* (0) check whether the desired fragment is available + * if so: + * (1) copy over the fragment to s->init_buf->data[] + * (2) update s->init_num + */ + pitem *item; + hm_fragment *frag; + int al; - pq_64bit_free(&seq64); + *ok = 0; + item = pqueue_peek(s->d1->buffered_messages); + if ( item == NULL) + return 0; - pqueue_insert(s->d1->buffered_messages, item); - return 1; + frag = (hm_fragment *)item->data; -err: - if ( frag != NULL) dtls1_hm_fragment_free(frag); - if ( item != NULL) OPENSSL_free(item); - return 0; -} + if ( s->d1->handshake_read_seq == frag->msg_header.seq) + { + pqueue_pop(s->d1->buffered_messages); + al=dtls1_preprocess_fragment(s,&frag->msg_header,max); -static void -dtls1_process_handshake_fragment(SSL *s, int frag_len) - { - unsigned char *p; + if (al==0) /* no alert */ + { + unsigned char *p = s->init_buf->data+DTLS1_HM_HEADER_LENGTH; + memcpy(&p[frag->msg_header.frag_off], + frag->fragment,frag->msg_header.frag_len); + } - p = (unsigned char *)s->init_buf->data; + dtls1_hm_fragment_free(frag); + pitem_free(item); - ssl3_finish_mac(s, &p[s->init_num - frag_len], frag_len); - } + if (al==0) + { + *ok = 1; + return frag->msg_header.frag_len; + } + + ssl3_send_alert(s,SSL3_AL_FATAL,al); + s->init_num = 0; + *ok = 0; + return -1; + } + else + return 0; + } static int -dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st *msg_hdr, int *ok) - { - int i; - unsigned char *p; - - /* make sure there's enough room to read this fragment */ - if ( (int)msg_hdr->frag_len && !BUF_MEM_grow_clean(s->init_buf, - (int)msg_hdr->frag_len + DTLS1_HM_HEADER_LENGTH + s->init_num)) - { - SSLerr(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE,ERR_R_BUF_LIB); - goto err; - } - - p = (unsigned char *)s->init_buf->data; - - /* read the body of the fragment (header has already been read */ - if ( msg_hdr->frag_len > 0) +dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) +{ + int i=-1; + hm_fragment *frag = NULL; + pitem *item = NULL; + PQ_64BIT seq64; + unsigned long frag_len = msg_hdr->frag_len; + + if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) + goto err; + + if (msg_hdr->seq <= s->d1->handshake_read_seq) { - i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, - &p[s->init_num], - msg_hdr->frag_len,0); - if (i <= 0) + unsigned char devnull [256]; + + while (frag_len) { - *ok = 0; - return i; + i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, + devnull, + frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0); + if (i<=0) goto err; + frag_len -= i; } } - if ( msg_hdr->seq > s->d1->handshake_read_seq) - dtls1_buffer_handshake_fragment(s, msg_hdr); - else - OPENSSL_assert(msg_hdr->seq < s->d1->handshake_read_seq); + frag = dtls1_hm_fragment_new(frag_len); + if ( frag == NULL) + goto err; + + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + + if (frag_len) + { + /* read the body of the fragment (header has already been read */ + i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, + frag->fragment,frag_len,0); + if (i<=0 || (unsigned long)i!=frag_len) + goto err; + } + + pq_64bit_init(&seq64); + pq_64bit_assign_word(&seq64, msg_hdr->seq); + + item = pitem_new(seq64, frag); + pq_64bit_free(&seq64); + if ( item == NULL) + goto err; + + pqueue_insert(s->d1->buffered_messages, item); + return DTLS1_HM_FRAGMENT_RETRY; - return DTLS1_HM_FRAGMENT_RETRY; err: - *ok = 0; - return -1; - } + if ( frag != NULL) dtls1_hm_fragment_free(frag); + if ( item != NULL) OPENSSL_free(item); + *ok = 0; + return i; + } static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) { - unsigned char *p; + unsigned char wire[DTLS1_HM_HEADER_LENGTH]; unsigned long l, frag_off, frag_len; int i,al; struct hm_header_st msg_hdr; - unsigned long overlap; - - /* see if we have the required fragment already */ - if (dtls1_retrieve_buffered_fragment(s, &l)) - { - /* compute MAC, remove fragment headers */ - dtls1_process_handshake_fragment(s, l); - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - s->state = stn; - return 1; - } - - /* get a handshake fragment from the record layer */ - p = (unsigned char *)s->init_buf->data; - - /* read handshake message header */ - i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num], + + /* see if we have the required fragment already */ + if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) + { + if (*ok) s->init_num += frag_len; + return frag_len; + } + + /* read handshake message header */ + i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,wire, DTLS1_HM_HEADER_LENGTH, 0); if (i <= 0) /* nbio, or an error */ { @@ -555,130 +633,61 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) *ok = 0; return i; } - OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH); - p += s->init_num; - /* parse the message fragment header */ - - dtls1_get_message_header(p, &msg_hdr); + /* parse the message fragment header */ + dtls1_get_message_header(wire, &msg_hdr); - /* - * if this is a future (or stale) message it gets buffered - * (or dropped)--no further processing at this time - */ - if ( msg_hdr.seq != s->d1->handshake_read_seq) - return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); + /* + * if this is a future (or stale) message it gets buffered + * (or dropped)--no further processing at this time + */ + if ( msg_hdr.seq != s->d1->handshake_read_seq) + return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); - l = msg_hdr.msg_len; - frag_off = msg_hdr.frag_off; + l = msg_hdr.msg_len; + frag_off = msg_hdr.frag_off; frag_len = msg_hdr.frag_len; - /* sanity checking */ - if ( frag_off + frag_len > l) - { - al=SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); - goto f_err; - } - if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && - p[0] == SSL3_MT_HELLO_REQUEST) - { - /* The server may always send 'Hello Request' messages -- - * we are doing a handshake anyway now, so ignore them - * if their format is correct. Does not count for - * 'Finished' MAC. */ - if (p[1] == 0 && p[2] == 0 &&p[3] == 0) - { - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, DTLS1_HM_HEADER_LENGTH, s, - s->msg_callback_arg); - - s->init_num = 0; - return dtls1_get_message_fragment(s, st1, stn, - max, ok); - } - else /* Incorrectly formated Hello request */ - { - al=SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - } - - /* XDTLS: do a sanity check on the fragment */ - - s->init_num += i; - - if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */ + wire[0] == SSL3_MT_HELLO_REQUEST) { - /* BUF_MEM_grow takes an 'int' parameter */ - if (l > (INT_MAX-DTLS1_HM_HEADER_LENGTH)) - { - al=SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); - goto f_err; - } - if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l - + DTLS1_HM_HEADER_LENGTH)) + /* The server may always send 'Hello Request' messages -- + * we are doing a handshake anyway now, so ignore them + * if their format is correct. Does not count for + * 'Finished' MAC. */ + if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,ERR_R_BUF_LIB); - goto err; + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + wire, DTLS1_HM_HEADER_LENGTH, s, + s->msg_callback_arg); + + s->init_num = 0; + return dtls1_get_message_fragment(s, st1, stn, + max, ok); } - /* Only do this test when we're reading the expected message. - * Stale messages will be dropped and future messages will be buffered */ - if ( l > (unsigned long)max) + else /* Incorrectly formated Hello request */ { - al=SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); + al=SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE); goto f_err; } - - s->s3->tmp.message_size=l; } - if ( frag_len > (unsigned long)max) - { - al=SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); - goto f_err; - } - if ( frag_len + s->init_num > (INT_MAX - DTLS1_HM_HEADER_LENGTH)) - { - al=SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); - goto f_err; - } - - if ( frag_len & !BUF_MEM_grow_clean(s->init_buf, (int)frag_len - + DTLS1_HM_HEADER_LENGTH + s->init_num)) - { - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,ERR_R_BUF_LIB); - goto err; - } - - if ( s->d1->r_msg_hdr.frag_off == 0) - { - s->s3->tmp.message_type = msg_hdr.type; - s->d1->r_msg_hdr.type = msg_hdr.type; - s->d1->r_msg_hdr.msg_len = l; - /* s->d1->r_msg_hdr.seq = seq_num; */ - } + if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max))) + goto f_err; /* XDTLS: ressurect this when restart is in place */ s->state=stn; - - /* next state (stn) */ - p = (unsigned char *)s->init_buf->data; if ( frag_len > 0) { + unsigned char *p=s->init_buf->data+DTLS1_HM_HEADER_LENGTH; + i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, - &p[s->init_num], - frag_len,0); - /* XDTLS: fix this--message fragments cannot span multiple packets */ + &p[frag_off],frag_len,0); + /* XDTLS: fix this--message fragments cannot span multiple packets */ if (i <= 0) { s->rwstate=SSL_READING; @@ -689,70 +698,23 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) else i = 0; - /* XDTLS: an incorrectly formatted fragment should cause the - * handshake to fail */ + /* XDTLS: an incorrectly formatted fragment should cause the + * handshake to fail */ OPENSSL_assert(i == (int)frag_len); -#if 0 - /* Successfully read a fragment. - * It may be (1) out of order, or - * (2) it's a repeat, in which case we dump it - * (3) the one we are expecting next (maybe with overlap) - * If it is next one, it may overlap with previously read bytes - */ - - /* case (1): buffer the future fragment - * (we can treat fragments from a future message the same - * as future fragments from the message being currently read, since - * they are sematically simply out of order. - */ - if ( msg_hdr.seq > s->d1->handshake_read_seq || - frag_off > s->init_num - DTLS1_HM_HEADER_LENGTH) - { - dtls1_buffer_handshake_fragment(s, &msg_hdr); - return DTLS1_HM_FRAGMENT_RETRY; - } - - /* case (2): drop the entire fragment, and try again */ - if ( msg_hdr.seq < s->d1->handshake_read_seq || - frag_off + frag_len < s->init_num - DTLS1_HM_HEADER_LENGTH) - { - s->init_num -= DTLS1_HM_HEADER_LENGTH; - return DTLS1_HM_FRAGMENT_RETRY; - } -#endif + *ok = 1; - /* case (3): received a immediately useful fragment. Determine the - * possible overlap and copy the fragment. - */ - overlap = (s->init_num - DTLS1_HM_HEADER_LENGTH) - frag_off; - - /* retain the header for the first fragment */ - if ( s->init_num > DTLS1_HM_HEADER_LENGTH) - { - memmove(&(s->init_buf->data[s->init_num]), - &(s->init_buf->data[s->init_num + DTLS1_HM_HEADER_LENGTH + overlap]), - frag_len - overlap); - - s->init_num += frag_len - overlap; - } - else - s->init_num += frag_len; - - dtls1_process_handshake_fragment(s, frag_len - overlap); - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, - (size_t)s->init_num, s, - s->msg_callback_arg); - *ok=1; - - return s->init_num; + /* Note that s->init_num is *not* used as current offset in + * s->init_buf->data, but as a counter summing up fragments' + * lengths: as soon as they sum up to handshake packet + * length, we assume we have got all the fragments. */ + s->init_num += frag_len; + return frag_len; f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); - s->init_num = 0; -err: + s->init_num = 0; + *ok=0; return(-1); } @@ -790,7 +752,7 @@ int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen) /* buffer the message to handle re-xmits */ dtls1_buffer_message(s, 0); - + s->state=b; } @@ -816,9 +778,14 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b) *p++=SSL3_MT_CCS; s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; s->d1->next_handshake_write_seq++; - s2n(s->d1->handshake_write_seq,p); - s->init_num=DTLS1_CCS_HEADER_LENGTH; + + if (s->client_version == DTLS1_BAD_VER) + { + s2n(s->d1->handshake_write_seq,p); + s->init_num+=2; + } + s->init_off=0; dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, @@ -915,316 +882,278 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) } int dtls1_read_failed(SSL *s, int code) - { - DTLS1_STATE *state; - BIO *bio; - int send_alert = 0; - - if ( code > 0) - { - fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__); - return 1; - } - - bio = SSL_get_rbio(s); - if ( ! BIO_dgram_recv_timedout(bio)) - { - /* not a timeout, none of our business, - let higher layers handle this. in fact it's probably an error */ - return code; - } - - if ( ! SSL_in_init(s)) /* done, no need to send a retransmit */ - { - BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); - return code; - } - - state = s->d1; - state->timeout.num_alerts++; - if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) - { - /* fail the connection, enough alerts have been sent */ - SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED); - return 0; - } - - state->timeout.read_timeouts++; - if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) - { - send_alert = 1; - state->timeout.read_timeouts = 1; - } - - + { + DTLS1_STATE *state; + BIO *bio; + int send_alert = 0; + + if ( code > 0) + { + fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__); + return 1; + } + + bio = SSL_get_rbio(s); + if ( ! BIO_dgram_recv_timedout(bio)) + { + /* not a timeout, none of our business, + let higher layers handle this. in fact it's probably an error */ + return code; + } + + if ( ! SSL_in_init(s)) /* done, no need to send a retransmit */ + { + BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); + return code; + } + + state = s->d1; + state->timeout.num_alerts++; + if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) + { + /* fail the connection, enough alerts have been sent */ + SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED); + return 0; + } + + state->timeout.read_timeouts++; + if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) + { + send_alert = 1; + state->timeout.read_timeouts = 1; + } + + #if 0 /* for now, each alert contains only one record number */ - item = pqueue_peek(state->rcvd_records); - if ( item ) - { - /* send an alert immediately for all the missing records */ - } - else + item = pqueue_peek(state->rcvd_records); + if ( item ) + { + /* send an alert immediately for all the missing records */ + } + else #endif #if 0 /* no more alert sending, just retransmit the last set of messages */ - if ( send_alert) - ssl3_send_alert(s,SSL3_AL_WARNING, - DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); + if ( send_alert) + ssl3_send_alert(s,SSL3_AL_WARNING, + DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); #endif - return dtls1_retransmit_buffered_messages(s) ; - } + return dtls1_retransmit_buffered_messages(s) ; + } static int dtls1_retransmit_buffered_messages(SSL *s) - { - pqueue sent = s->d1->sent_messages; - piterator iter; - pitem *item; - hm_fragment *frag; - int found = 0; - - iter = pqueue_iterator(sent); - - for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) - { - frag = (hm_fragment *)item->data; - if ( dtls1_retransmit_message(s, frag->msg_header.seq, 0, &found) <= 0 && - found) - { - fprintf(stderr, "dtls1_retransmit_message() failed\n"); - return -1; - } - } - - return 1; - } + { + pqueue sent = s->d1->sent_messages; + piterator iter; + pitem *item; + hm_fragment *frag; + int found = 0; -#if 0 -static dtls1_message_buffer * -dtls1_message_buffer_new(unsigned int len) - { - dtls1_message_buffer *msg_buf; - - msg_buf = (dtls1_message_buffer *) - OPENSSL_malloc(sizeof(dtls1_message_buffer)); - if ( msg_buf == NULL) - return NULL; - - memset(msg_buf, 0x00, sizeof(dtls1_message_buffer)); - - msg_buf->data = (unsigned char *) OPENSSL_malloc(len); - if ( msg_buf->data == NULL) - { - OPENSSL_free(msg_buf); - return NULL; - } - - memset(msg_buf->data, 0x00, len); - return msg_buf; - } -#endif + iter = pqueue_iterator(sent); -#if 0 -static void -dtls1_message_buffer_free(dtls1_message_buffer *msg_buf) - { - if (msg_buf != NULL) - { - OPENSSL_free(msg_buf->data); - OPENSSL_free(msg_buf); - } - } -#endif + for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) + { + frag = (hm_fragment *)item->data; + if ( dtls1_retransmit_message(s, frag->msg_header.seq, 0, &found) <= 0 && + found) + { + fprintf(stderr, "dtls1_retransmit_message() failed\n"); + return -1; + } + } + + return 1; + } int dtls1_buffer_message(SSL *s, int is_ccs) - { - pitem *item; - hm_fragment *frag; + { + pitem *item; + hm_fragment *frag; PQ_64BIT seq64; - /* this function is called immediately after a message has - * been serialized */ - OPENSSL_assert(s->init_off == 0); - - frag = dtls1_hm_fragment_new(s->init_num); - - memcpy(frag->fragment, s->init_buf->data, s->init_num); - - if ( is_ccs) - { - OPENSSL_assert(s->d1->w_msg_hdr.msg_len + - DTLS1_CCS_HEADER_LENGTH == (unsigned int)s->init_num); - } - else - { - OPENSSL_assert(s->d1->w_msg_hdr.msg_len + - DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num); - } - - frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; - frag->msg_header.seq = s->d1->w_msg_hdr.seq; - frag->msg_header.type = s->d1->w_msg_hdr.type; - frag->msg_header.frag_off = 0; - frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; - frag->msg_header.is_ccs = is_ccs; - - pq_64bit_init(&seq64); - pq_64bit_assign_word(&seq64, frag->msg_header.seq); - - item = pitem_new(seq64, frag); - pq_64bit_free(&seq64); - if ( item == NULL) - { - dtls1_hm_fragment_free(frag); - return 0; - } + /* this function is called immediately after a message has + * been serialized */ + OPENSSL_assert(s->init_off == 0); + + frag = dtls1_hm_fragment_new(s->init_num); + + memcpy(frag->fragment, s->init_buf->data, s->init_num); + + if ( is_ccs) + { + OPENSSL_assert(s->d1->w_msg_hdr.msg_len + + DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num); + } + else + { + OPENSSL_assert(s->d1->w_msg_hdr.msg_len + + DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num); + } + + frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; + frag->msg_header.seq = s->d1->w_msg_hdr.seq; + frag->msg_header.type = s->d1->w_msg_hdr.type; + frag->msg_header.frag_off = 0; + frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; + frag->msg_header.is_ccs = is_ccs; + + pq_64bit_init(&seq64); + pq_64bit_assign_word(&seq64, frag->msg_header.seq); + + item = pitem_new(seq64, frag); + pq_64bit_free(&seq64); + if ( item == NULL) + { + dtls1_hm_fragment_free(frag); + return 0; + } #if 0 - fprintf( stderr, "buffered messge: \ttype = %xx\n", msg_buf->type); - fprintf( stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len); - fprintf( stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num); + fprintf( stderr, "buffered messge: \ttype = %xx\n", msg_buf->type); + fprintf( stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len); + fprintf( stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num); #endif - pqueue_insert(s->d1->sent_messages, item); - return 1; - } + pqueue_insert(s->d1->sent_messages, item); + return 1; + } int dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, - int *found) - { - int ret; - /* XDTLS: for now assuming that read/writes are blocking */ - pitem *item; - hm_fragment *frag ; - unsigned long header_length; + int *found) + { + int ret; + /* XDTLS: for now assuming that read/writes are blocking */ + pitem *item; + hm_fragment *frag ; + unsigned long header_length; PQ_64BIT seq64; - /* - OPENSSL_assert(s->init_num == 0); - OPENSSL_assert(s->init_off == 0); - */ - - /* XDTLS: the requested message ought to be found, otherwise error */ - pq_64bit_init(&seq64); - pq_64bit_assign_word(&seq64, seq); - - item = pqueue_find(s->d1->sent_messages, seq64); - pq_64bit_free(&seq64); - if ( item == NULL) - { - fprintf(stderr, "retransmit: message %d non-existant\n", seq); - *found = 0; - return 0; - } - - *found = 1; - frag = (hm_fragment *)item->data; - - if ( frag->msg_header.is_ccs) - header_length = DTLS1_CCS_HEADER_LENGTH; - else - header_length = DTLS1_HM_HEADER_LENGTH; - - memcpy(s->init_buf->data, frag->fragment, - frag->msg_header.msg_len + header_length); - s->init_num = frag->msg_header.msg_len + header_length; - - dtls1_set_message_header_int(s, frag->msg_header.type, - frag->msg_header.msg_len, frag->msg_header.seq, 0, - frag->msg_header.frag_len); - - s->d1->retransmitting = 1; - ret = dtls1_do_write(s, frag->msg_header.is_ccs ? - SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); - s->d1->retransmitting = 0; - - BIO_flush(SSL_get_wbio(s)); - return ret; - } + /* + OPENSSL_assert(s->init_num == 0); + OPENSSL_assert(s->init_off == 0); + */ + + /* XDTLS: the requested message ought to be found, otherwise error */ + pq_64bit_init(&seq64); + pq_64bit_assign_word(&seq64, seq); + + item = pqueue_find(s->d1->sent_messages, seq64); + pq_64bit_free(&seq64); + if ( item == NULL) + { + fprintf(stderr, "retransmit: message %d non-existant\n", seq); + *found = 0; + return 0; + } + + *found = 1; + frag = (hm_fragment *)item->data; + + if ( frag->msg_header.is_ccs) + header_length = DTLS1_CCS_HEADER_LENGTH; + else + header_length = DTLS1_HM_HEADER_LENGTH; + + memcpy(s->init_buf->data, frag->fragment, + frag->msg_header.msg_len + header_length); + s->init_num = frag->msg_header.msg_len + header_length; + + dtls1_set_message_header_int(s, frag->msg_header.type, + frag->msg_header.msg_len, frag->msg_header.seq, 0, + frag->msg_header.frag_len); + + s->d1->retransmitting = 1; + ret = dtls1_do_write(s, frag->msg_header.is_ccs ? + SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); + s->d1->retransmitting = 0; + + (void)BIO_flush(SSL_get_wbio(s)); + return ret; + } /* call this function when the buffered messages are no longer needed */ void dtls1_clear_record_buffer(SSL *s) - { - pitem *item; - - for(item = pqueue_pop(s->d1->sent_messages); - item != NULL; item = pqueue_pop(s->d1->sent_messages)) - { - dtls1_hm_fragment_free((hm_fragment *)item->data); - pitem_free(item); - } - } + { + pitem *item; + + for(item = pqueue_pop(s->d1->sent_messages); + item != NULL; item = pqueue_pop(s->d1->sent_messages)) + { + dtls1_hm_fragment_free((hm_fragment *)item->data); + pitem_free(item); + } + } unsigned char * dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt, - unsigned long len, unsigned long frag_off, unsigned long frag_len) - { - if ( frag_off == 0) - { - s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; - s->d1->next_handshake_write_seq++; - } - - dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, - frag_off, frag_len); - - return p += DTLS1_HM_HEADER_LENGTH; - } + unsigned long len, unsigned long frag_off, unsigned long frag_len) + { + if ( frag_off == 0) + { + s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; + s->d1->next_handshake_write_seq++; + } + + dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, + frag_off, frag_len); + + return p += DTLS1_HM_HEADER_LENGTH; + } /* don't actually do the writing, wait till the MTU has been retrieved */ static void dtls1_set_message_header_int(SSL *s, unsigned char mt, - unsigned long len, unsigned short seq_num, unsigned long frag_off, - unsigned long frag_len) - { - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - - msg_hdr->type = mt; - msg_hdr->msg_len = len; - msg_hdr->seq = seq_num; - msg_hdr->frag_off = frag_off; - msg_hdr->frag_len = frag_len; -} + unsigned long len, unsigned short seq_num, unsigned long frag_off, + unsigned long frag_len) + { + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + msg_hdr->type = mt; + msg_hdr->msg_len = len; + msg_hdr->seq = seq_num; + msg_hdr->frag_off = frag_off; + msg_hdr->frag_len = frag_len; + } static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, - unsigned long frag_len) - { - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - - msg_hdr->frag_off = frag_off; - msg_hdr->frag_len = frag_len; - } + unsigned long frag_len) + { + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + msg_hdr->frag_off = frag_off; + msg_hdr->frag_len = frag_len; + } static unsigned char * dtls1_write_message_header(SSL *s, unsigned char *p) - { - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - - *p++ = msg_hdr->type; - l2n3(msg_hdr->msg_len, p); - - s2n(msg_hdr->seq, p); - l2n3(msg_hdr->frag_off, p); - l2n3(msg_hdr->frag_len, p); - - return p; - } + { + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + *p++ = msg_hdr->type; + l2n3(msg_hdr->msg_len, p); + + s2n(msg_hdr->seq, p); + l2n3(msg_hdr->frag_off, p); + l2n3(msg_hdr->frag_len, p); + + return p; + } static unsigned int dtls1_min_mtu(void) - { - return - g_probable_mtu[(sizeof(g_probable_mtu) / - sizeof(g_probable_mtu[0])) - 1]; - } + { + return (g_probable_mtu[(sizeof(g_probable_mtu) / + sizeof(g_probable_mtu[0])) - 1]); + } static unsigned int dtls1_guess_mtu(unsigned int curr_mtu) @@ -1237,27 +1166,26 @@ dtls1_guess_mtu(unsigned int curr_mtu) 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 dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) - { - memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - msg_hdr->type = *(data++); - n2l3(data, msg_hdr->msg_len); - - n2s(data, msg_hdr->seq); - n2l3(data, msg_hdr->frag_off); - n2l3(data, msg_hdr->frag_len); - } + { + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); + msg_hdr->type = *(data++); + n2l3(data, msg_hdr->msg_len); + + n2s(data, msg_hdr->seq); + n2l3(data, msg_hdr->frag_off); + n2l3(data, msg_hdr->frag_len); + } void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr) - { - memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st)); - - ccs_hdr->type = *(data++); - n2s(data, ccs_hdr->seq); -} + { + memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st)); + + ccs_hdr->type = *(data++); + } diff --git a/crypto/openssl-0.9/ssl/d1_clnt.c b/crypto/openssl-0.9/ssl/d1_clnt.c index e8b60a45d2..5e59dc845a 100644 --- a/crypto/openssl-0.9/ssl/d1_clnt.c +++ b/crypto/openssl-0.9/ssl/d1_clnt.c @@ -214,17 +214,21 @@ int dtls1_connect(SSL *s) /* don't push the buffering BIO quite yet */ - ssl3_init_finished_mac(s); - s->state=SSL3_ST_CW_CLNT_HELLO_A; s->ctx->stats.sess_connect++; s->init_num=0; + /* mark client_random uninitialized */ + memset(s->s3->client_random,0,sizeof(s->s3->client_random)); break; case SSL3_ST_CW_CLNT_HELLO_A: case SSL3_ST_CW_CLNT_HELLO_B: s->shutdown=0; + + /* every DTLS ClientHello resets Finished MAC */ + ssl3_init_finished_mac(s); + ret=dtls1_client_hello(s); if (ret <= 0) goto end; @@ -422,6 +426,9 @@ int dtls1_connect(SSL *s) s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A; } s->init_num=0; + /* mark client_random uninitialized */ + memset (s->s3->client_random,0,sizeof(s->s3->client_random)); + break; case SSL3_ST_CR_FINISHED_A: @@ -544,9 +551,15 @@ int dtls1_client_hello(SSL *s) /* else use the pre-loaded session */ p=s->s3->client_random; - Time=(unsigned long)time(NULL); /* Time */ - l2n(Time,p); - RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time)); + /* if client_random is initialized, reuse it, we are + * required to use same upon reply to HelloVerify */ + for (i=0;p[i]=='\0' && is3->client_random);i++) ; + if (i==sizeof(s->s3->client_random)) + { + Time=(unsigned long)time(NULL); /* Time */ + l2n(Time,p); + RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4); + } /* Do the message type and length last */ d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); @@ -732,7 +745,7 @@ int dtls1_send_client_key_exchange(SSL *s) s->session->master_key_length=sizeof tmp_buf; q=p; - /* Fix buf for TLS and beyond */ + /* Fix buf for TLS and [incidentally] DTLS */ if (s->version > SSL3_VERSION) p+=2; n=RSA_public_encrypt(sizeof tmp_buf, @@ -747,7 +760,7 @@ int dtls1_send_client_key_exchange(SSL *s) goto err; } - /* Fix buf for TLS and beyond */ + /* Fix buf for TLS and [incidentally] DTLS */ if (s->version > SSL3_VERSION) { s2n(n,q); diff --git a/crypto/openssl-0.9/ssl/d1_lib.c b/crypto/openssl-0.9/ssl/d1_lib.c index d07a212fac..fc088b4148 100644 --- a/crypto/openssl-0.9/ssl/d1_lib.c +++ b/crypto/openssl-0.9/ssl/d1_lib.c @@ -188,3 +188,23 @@ void dtls1_clear(SSL *s) ssl3_clear(s); s->version=DTLS1_VERSION; } + +/* + * As it's impossible to use stream ciphers in "datagram" mode, this + * simple filter is designed to disengage them in DTLS. Unfortunately + * there is no universal way to identify stream SSL_CIPHER, so we have + * to explicitly list their SSL_* codes. Currently RC4 is the only one + * available, but if new ones emerge, they will have to be added... + */ +SSL_CIPHER *dtls1_get_cipher(unsigned int u) + { + SSL_CIPHER *ciph = ssl3_get_cipher(u); + + if (ciph != NULL) + { + if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4) + return NULL; + } + + return ciph; + } diff --git a/crypto/openssl-0.9/ssl/d1_pkt.c b/crypto/openssl-0.9/ssl/d1_pkt.c index 8270419a8d..b1248770b5 100644 --- a/crypto/openssl-0.9/ssl/d1_pkt.c +++ b/crypto/openssl-0.9/ssl/d1_pkt.c @@ -120,6 +120,7 @@ #include #include #include +#include static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, int len, int peek); @@ -486,9 +487,9 @@ int dtls1_get_record(SSL *s) SSL3_RECORD *rr; SSL_SESSION *sess; unsigned char *p; - short version; + unsigned short version; DTLS1_BITMAP *bitmap; - unsigned int is_next_epoch; + unsigned int is_next_epoch; rr= &(s->s3->rrec); sess=s->session; @@ -524,7 +525,7 @@ again: ssl_minor= *(p++); version=(ssl_major<<8)|ssl_minor; - /* sequence number is 64 bits, with top 2 bytes = epoch */ + /* sequence number is 64 bits, with top 2 bytes = epoch */ n2s(p,rr->epoch); memcpy(&(s->s3->read_sequence[2]), p, 6); @@ -535,7 +536,7 @@ again: /* Lets check version */ if (!s->first_packet) { - if (version != s->version) + if (version != s->version && version != DTLS1_BAD_VER) { SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); /* Send back error using their @@ -546,7 +547,8 @@ again: } } - if ((version & 0xff00) != (DTLS1_VERSION & 0xff00)) + if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) && + (version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) { SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); goto err; @@ -559,6 +561,7 @@ again: goto f_err; } + s->client_version = version; /* now s->rstate == SSL_ST_READ_BODY */ } @@ -973,47 +976,40 @@ start: } if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) - { - struct ccs_header_st ccs_hdr; + { + struct ccs_header_st ccs_hdr; dtls1_get_ccs_header(rr->data, &ccs_hdr); - if ( ccs_hdr.seq == s->d1->handshake_read_seq) - { - /* 'Change Cipher Spec' is just a single byte, so we know - * exactly what the record payload has to look like */ - /* XDTLS: check that epoch is consistent */ - if ( (rr->length != DTLS1_CCS_HEADER_LENGTH) || - (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) - { - i=SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto err; - } - - rr->length=0; - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, - rr->data, 1, s, s->msg_callback_arg); - - s->s3->change_cipher_spec=1; - if (!ssl3_do_change_cipher_spec(s)) - goto err; - - /* do this whenever CCS is processed */ - dtls1_reset_seq_numbers(s, SSL3_CC_READ); - - /* handshake read seq is reset upon handshake completion */ - s->d1->handshake_read_seq++; - - goto start; - } - else + /* 'Change Cipher Spec' is just a single byte, so we know + * exactly what the record payload has to look like */ + /* XDTLS: check that epoch is consistent */ + if ( (s->client_version == DTLS1_BAD_VER && rr->length != 3) || + (s->client_version != DTLS1_BAD_VER && rr->length != DTLS1_CCS_HEADER_LENGTH) || + (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) { - rr->length = 0; - goto start; + i=SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC); + goto err; } + + rr->length=0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, + rr->data, 1, s, s->msg_callback_arg); + + s->s3->change_cipher_spec=1; + if (!ssl3_do_change_cipher_spec(s)) + goto err; + + /* do this whenever CCS is processed */ + dtls1_reset_seq_numbers(s, SSL3_CC_READ); + + /* handshake read seq is reset upon handshake completion */ + s->d1->handshake_read_seq++; + + goto start; } /* Unexpected handshake message (Client Hello, or protocol violation) */ @@ -1341,8 +1337,12 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, *(p++)=type&0xff; wr->type=type; - *(p++)=(s->version>>8); - *(p++)=s->version&0xff; + if (s->client_version == DTLS1_BAD_VER) + *(p++) = DTLS1_BAD_VER>>8, + *(p++) = DTLS1_BAD_VER&0xff; + else + *(p++)=(s->version>>8), + *(p++)=s->version&0xff; /* field where we are to write out packet epoch, seq num and len */ pseq=p; @@ -1397,8 +1397,14 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, /* ssl3_enc can only have an error on read */ - wr->length += bs; /* bs != 0 in case of CBC. The enc fn provides - * the randomness */ + if (bs) /* bs != 0 in case of CBC */ + { + RAND_pseudo_bytes(p,bs); + /* master IV and last CBC residue stand for + * the rest of randomness */ + wr->length += bs; + } + s->method->ssl3_enc->enc(s,1); /* record length after mac and block padding */ diff --git a/crypto/openssl-0.9/ssl/d1_srvr.c b/crypto/openssl-0.9/ssl/d1_srvr.c index 475e6095fd..927b01f3c4 100644 --- a/crypto/openssl-0.9/ssl/d1_srvr.c +++ b/crypto/openssl-0.9/ssl/d1_srvr.c @@ -285,6 +285,10 @@ int dtls1_accept(SSL *s) s->d1->send_cookie = 0; s->state=SSL3_ST_SW_FLUSH; s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A; + + /* HelloVerifyRequests resets Finished MAC */ + if (s->client_version != DTLS1_BAD_VER) + ssl3_init_finished_mac(s); break; case SSL3_ST_SW_SRVR_HELLO_A: @@ -620,20 +624,24 @@ int dtls1_send_hello_verify_request(SSL *s) buf = (unsigned char *)s->init_buf->data; msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]); - *(p++) = s->version >> 8; - *(p++) = s->version & 0xFF; + if (s->client_version == DTLS1_BAD_VER) + *(p++) = DTLS1_BAD_VER>>8, + *(p++) = DTLS1_BAD_VER&0xff; + else + *(p++) = s->version >> 8, + *(p++) = s->version & 0xFF; - *(p++) = (unsigned char) s->d1->cookie_len; - if ( s->ctx->app_gen_cookie_cb != NULL && - s->ctx->app_gen_cookie_cb(s, s->d1->cookie, - &(s->d1->cookie_len)) == 0) - { + if (s->ctx->app_gen_cookie_cb != NULL && + s->ctx->app_gen_cookie_cb(s, s->d1->cookie, + &(s->d1->cookie_len)) == 0) + { SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,ERR_R_INTERNAL_ERROR); - return 0; - } - /* else the cookie is assumed to have - * been initialized by the application */ + return 0; + } + /* else the cookie is assumed to have + * been initialized by the application */ + *(p++) = (unsigned char) s->d1->cookie_len; memcpy(p, s->d1->cookie, s->d1->cookie_len); p += s->d1->cookie_len; msg_len = p - msg; @@ -672,8 +680,12 @@ int dtls1_send_server_hello(SSL *s) /* Do the message type and length last */ d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); - *(p++)=s->version>>8; - *(p++)=s->version&0xff; + if (s->client_version == DTLS1_BAD_VER) + *(p++)=DTLS1_BAD_VER>>8, + *(p++)=DTLS1_BAD_VER&0xff; + else + *(p++)=s->version>>8, + *(p++)=s->version&0xff; /* Random stuff */ memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); @@ -1009,6 +1021,7 @@ int dtls1_send_certificate_request(SSL *s) STACK_OF(X509_NAME) *sk=NULL; X509_NAME *name; BUF_MEM *buf; + unsigned int msg_len; if (s->state == SSL3_ST_SW_CERT_REQ_A) { @@ -1086,6 +1099,10 @@ int dtls1_send_certificate_request(SSL *s) #endif /* XDTLS: set message header ? */ + msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH; + dtls1_set_message_header(s, (void *)s->init_buf->data, + SSL3_MT_CERTIFICATE_REQUEST, msg_len, 0, msg_len); + /* buffer the message to handle re-xmits */ dtls1_buffer_message(s, 0); diff --git a/crypto/openssl-0.9/ssl/dtls1.h b/crypto/openssl-0.9/ssl/dtls1.h index b377cc5f6b..a663cf85f2 100644 --- a/crypto/openssl-0.9/ssl/dtls1.h +++ b/crypto/openssl-0.9/ssl/dtls1.h @@ -67,9 +67,8 @@ extern "C" { #endif -#define DTLS1_VERSION 0x0100 -#define DTLS1_VERSION_MAJOR 0x01 -#define DTLS1_VERSION_MINOR 0x00 +#define DTLS1_VERSION 0xFEFF +#define DTLS1_BAD_VER 0x0100 #define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110 @@ -83,7 +82,7 @@ extern "C" { #define DTLS1_HM_BAD_FRAGMENT -2 #define DTLS1_HM_FRAGMENT_RETRY -3 -#define DTLS1_CCS_HEADER_LENGTH 3 +#define DTLS1_CCS_HEADER_LENGTH 1 #define DTLS1_AL_HEADER_LENGTH 7 diff --git a/crypto/openssl-0.9/ssl/s23_clnt.c b/crypto/openssl-0.9/ssl/s23_clnt.c index 769dabdbb8..a596e7b2ec 100644 --- a/crypto/openssl-0.9/ssl/s23_clnt.c +++ b/crypto/openssl-0.9/ssl/s23_clnt.c @@ -223,6 +223,15 @@ static int ssl23_client_hello(SSL *s) { version = SSL2_VERSION; } +#ifndef OPENSSL_NO_TLSEXT + if (version != SSL2_VERSION) + { + /* have to disable SSL 2.0 compatibility if we need TLS extensions */ + + if (s->tlsext_hostname != NULL) + ssl2_compat = 0; + } +#endif buf=(unsigned char *)s->init_buf->data; if (s->state == SSL23_ST_CW_CLNT_HELLO_A) @@ -360,6 +369,13 @@ static int ssl23_client_hello(SSL *s) *(p++)=comp->id; } *(p++)=0; /* Add the NULL method */ +#ifndef OPENSSL_NO_TLSEXT + if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) + { + SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); + return -1; + } +#endif l = p-d; *p = 42; diff --git a/crypto/openssl-0.9/ssl/s2_clnt.c b/crypto/openssl-0.9/ssl/s2_clnt.c index ce60de630a..e2a90a3ca2 100644 --- a/crypto/openssl-0.9/ssl/s2_clnt.c +++ b/crypto/openssl-0.9/ssl/s2_clnt.c @@ -466,11 +466,11 @@ static int get_server_hello(SSL *s) return(-1); } - sk_SSL_CIPHER_set_cmp_func(sk,ssl_cipher_ptr_id_cmp); + (void)sk_SSL_CIPHER_set_cmp_func(sk,ssl_cipher_ptr_id_cmp); /* get the array of ciphers we will accept */ cl=SSL_get_ciphers(s); - sk_SSL_CIPHER_set_cmp_func(cl,ssl_cipher_ptr_id_cmp); + (void)sk_SSL_CIPHER_set_cmp_func(cl,ssl_cipher_ptr_id_cmp); /* * If server preference flag set, choose the first diff --git a/crypto/openssl-0.9/ssl/s2_srvr.c b/crypto/openssl-0.9/ssl/s2_srvr.c index 27d71a2e09..0daf2b129d 100644 --- a/crypto/openssl-0.9/ssl/s2_srvr.c +++ b/crypto/openssl-0.9/ssl/s2_srvr.c @@ -607,7 +607,7 @@ static int get_client_hello(SSL *s) else { i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_spec_length]), - s->s2->tmp.session_id_length); + s->s2->tmp.session_id_length, NULL); if (i == 1) { /* previous session */ s->hit=1; @@ -657,7 +657,7 @@ static int get_client_hello(SSL *s) { if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0) { - sk_SSL_CIPHER_delete(prio,z); + (void)sk_SSL_CIPHER_delete(prio,z); z--; } } diff --git a/crypto/openssl-0.9/ssl/s3_clnt.c b/crypto/openssl-0.9/ssl/s3_clnt.c index 278be82294..4d4d63a6f1 100644 --- a/crypto/openssl-0.9/ssl/s3_clnt.c +++ b/crypto/openssl-0.9/ssl/s3_clnt.c @@ -137,6 +137,9 @@ static SSL_METHOD *ssl3_get_client_method(int ver); static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b); +#ifndef OPENSSL_NO_TLSEXT +static int ssl3_check_finished(SSL *s); +#endif #ifndef OPENSSL_NO_ECDH static int curve_id2nid(int curve_id); @@ -264,6 +267,17 @@ int ssl3_connect(SSL *s) case SSL3_ST_CR_CERT_A: 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; + s->state=SSL3_ST_CR_FINISHED_A; + s->init_num=0; + break; + } +#endif /* Check if it is anon DH/ECDH */ if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) { @@ -416,11 +430,28 @@ int ssl3_connect(SSL *s) } else { +#ifndef OPENSSL_NO_TLSEXT + /* Allow NewSessionTicket if ticket expected */ + if (s->tlsext_ticket_expected) + s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A; + else +#endif + s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A; } s->init_num=0; break; +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_CR_SESSION_TICKET_A: + case SSL3_ST_CR_SESSION_TICKET_B: + ret=ssl3_get_new_session_ticket(s); + if (ret <= 0) goto end; + s->state=SSL3_ST_CR_FINISHED_A; + s->init_num=0; + break; +#endif + case SSL3_ST_CR_FINISHED_A: case SSL3_ST_CR_FINISHED_B: @@ -600,7 +631,13 @@ int ssl3_client_hello(SSL *s) } #endif *(p++)=0; /* Add the NULL method */ - +#ifndef OPENSSL_NO_TLSEXT + if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) + { + SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); + goto err; + } +#endif l=(p-d); d=buf; *(d++)=SSL3_MT_CLIENT_HELLO; @@ -634,7 +671,7 @@ int ssl3_get_server_hello(SSL *s) SSL3_ST_CR_SRVR_HELLO_A, SSL3_ST_CR_SRVR_HELLO_B, -1, - 300, /* ?? */ + 20000, /* ?? */ &ok); if (!ok) return((int)n); @@ -784,6 +821,24 @@ int ssl3_get_server_hello(SSL *s) s->s3->tmp.new_compression=comp; } #endif +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions*/ + if (s->version > SSL3_VERSION) + { + if (!ssl_parse_serverhello_tlsext(s,&p,d,n, &al)) + { + /* 'al' set by ssl_parse_serverhello_tlsext */ + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_PARSE_TLSEXT); + goto f_err; + } + if (ssl_check_serverhello_tlsext(s) <= 0) + { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT); + goto err; + } + } +#endif + if (p != (d+n)) { @@ -821,7 +876,9 @@ int ssl3_get_server_certificate(SSL *s) if (!ok) return((int)n); - if (s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) + if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) || + ((s->s3->tmp.new_cipher->algorithms & SSL_aKRB5) && + (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE))) { s->s3->tmp.reuse_message=1; return(1); @@ -1588,6 +1645,74 @@ static int ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b) { return(X509_NAME_cmp(*a,*b)); } +#ifndef OPENSSL_NO_TLSEXT +int ssl3_get_new_session_ticket(SSL *s) + { + int ok,al,ret=0, ticklen; + long n; + const unsigned char *p; + unsigned char *d; + + n=s->method->ssl_get_message(s, + SSL3_ST_CR_SESSION_TICKET_A, + SSL3_ST_CR_SESSION_TICKET_B, + -1, + 16384, + &ok); + + if (!ok) + 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) + { + /* need at least ticket_lifetime_hint + ticket length */ + al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH); + goto f_err; + } + p=d=(unsigned char *)s->init_msg; + n2l(p, s->session->tlsext_tick_lifetime_hint); + n2s(p, ticklen); + /* ticket_lifetime_hint + ticket_length + ticket */ + if (ticklen + 6 != n) + { + al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH); + goto f_err; + } + if (s->session->tlsext_tick) + { + OPENSSL_free(s->session->tlsext_tick); + s->session->tlsext_ticklen = 0; + } + s->session->tlsext_tick = OPENSSL_malloc(ticklen); + if (!s->session->tlsext_tick) + { + SSLerr(SSL_F_SSL3_NEW_SESSION_TICKET,ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(s->session->tlsext_tick, p, ticklen); + s->session->tlsext_ticklen = ticklen; + + ret=1; + return(ret); +f_err: + ssl3_send_alert(s,SSL3_AL_FATAL,al); +err: + return(-1); + } +#endif int ssl3_get_server_done(SSL *s) { @@ -2292,18 +2417,18 @@ int ssl3_check_cert_and_algorithm(SSL *s) sc=s->session->sess_cert; - if (sc == NULL) - { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,ERR_R_INTERNAL_ERROR); - goto err; - } - algs=s->s3->tmp.new_cipher->algorithms; /* we don't have a certificate */ if (algs & (SSL_aDH|SSL_aNULL|SSL_aKRB5)) return(1); + if (sc == NULL) + { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,ERR_R_INTERNAL_ERROR); + goto err; + } + #ifndef OPENSSL_NO_RSA rsa=s->session->sess_cert->peer_rsa_tmp; #endif @@ -2456,3 +2581,33 @@ static int curve_id2nid(int curve_id) return nid_list[curve_id]; } #endif + +/* 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 +static int ssl3_check_finished(SSL *s) + { + int ok; + long n; + 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 diff --git a/crypto/openssl-0.9/ssl/s3_lib.c b/crypto/openssl-0.9/ssl/s3_lib.c index 28eaf9ddeb..95e893737c 100644 --- a/crypto/openssl-0.9/ssl/s3_lib.c +++ b/crypto/openssl-0.9/ssl/s3_lib.c @@ -542,11 +542,8 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ #endif #ifndef OPENSSL_NO_KRB5 -/* The Kerberos ciphers -** 20000107 VRS: And the first shall be last, -** in hopes of avoiding the lynx ssl renegotiation problem. -*/ -/* Cipher 1E VRS */ +/* The Kerberos ciphers */ +/* Cipher 1E */ { 1, SSL3_TXT_KRB5_DES_64_CBC_SHA, @@ -560,7 +557,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 1F VRS */ +/* Cipher 1F */ { 1, SSL3_TXT_KRB5_DES_192_CBC3_SHA, @@ -574,7 +571,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 20 VRS */ +/* Cipher 20 */ { 1, SSL3_TXT_KRB5_RC4_128_SHA, @@ -588,7 +585,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 21 VRS */ +/* Cipher 21 */ { 1, SSL3_TXT_KRB5_IDEA_128_CBC_SHA, @@ -602,7 +599,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 22 VRS */ +/* Cipher 22 */ { 1, SSL3_TXT_KRB5_DES_64_CBC_MD5, @@ -616,7 +613,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 23 VRS */ +/* Cipher 23 */ { 1, SSL3_TXT_KRB5_DES_192_CBC3_MD5, @@ -630,7 +627,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 24 VRS */ +/* Cipher 24 */ { 1, SSL3_TXT_KRB5_RC4_128_MD5, @@ -644,7 +641,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 25 VRS */ +/* Cipher 25 */ { 1, SSL3_TXT_KRB5_IDEA_128_CBC_MD5, @@ -658,7 +655,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 26 VRS */ +/* Cipher 26 */ { 1, SSL3_TXT_KRB5_DES_40_CBC_SHA, @@ -672,7 +669,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 27 VRS */ +/* Cipher 27 */ { 1, SSL3_TXT_KRB5_RC2_40_CBC_SHA, @@ -686,7 +683,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 28 VRS */ +/* Cipher 28 */ { 1, SSL3_TXT_KRB5_RC4_40_SHA, @@ -700,7 +697,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 29 VRS */ +/* Cipher 29 */ { 1, SSL3_TXT_KRB5_DES_40_CBC_MD5, @@ -714,7 +711,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 2A VRS */ +/* Cipher 2A */ { 1, SSL3_TXT_KRB5_RC2_40_CBC_MD5, @@ -728,7 +725,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 2B VRS */ +/* Cipher 2B */ { 1, SSL3_TXT_KRB5_RC4_40_MD5, @@ -742,8 +739,8 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, #endif /* OPENSSL_NO_KRB5 */ -/* New AES ciphersuites */ +/* New AES ciphersuites */ /* Cipher 2F */ { 1, @@ -1165,6 +1162,95 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ }, #endif /* OPENSSL_NO_CAMELLIA */ +#ifndef OPENSSL_NO_SEED + /* SEED ciphersuites from RFC4162 */ + + /* Cipher 96 */ + { + 1, + TLS1_TXT_RSA_WITH_SEED_SHA, + TLS1_CK_RSA_WITH_SEED_SHA, + SSL_kRSA|SSL_aRSA|SSL_SEED|SSL_SHA1|SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + 0, + 128, + 128, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + + /* Cipher 97 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_DSS_WITH_SEED_SHA, + TLS1_CK_DH_DSS_WITH_SEED_SHA, + SSL_kDHd|SSL_aDH|SSL_SEED|SSL_SHA1|SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + 0, + 128, + 128, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + + /* Cipher 98 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_RSA_WITH_SEED_SHA, + TLS1_CK_DH_RSA_WITH_SEED_SHA, + SSL_kDHr|SSL_aDH|SSL_SEED|SSL_SHA1|SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + 0, + 128, + 128, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + + /* Cipher 99 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_SEED_SHA, + TLS1_CK_DHE_DSS_WITH_SEED_SHA, + SSL_kEDH|SSL_aDSS|SSL_SEED|SSL_SHA1|SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + 0, + 128, + 128, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + + /* Cipher 9A */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_SEED_SHA, + TLS1_CK_DHE_RSA_WITH_SEED_SHA, + SSL_kEDH|SSL_aRSA|SSL_SEED|SSL_SHA1|SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + 0, + 128, + 128, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + + /* Cipher 9B */ + { + 1, + TLS1_TXT_ADH_WITH_SEED_SHA, + TLS1_CK_ADH_WITH_SEED_SHA, + SSL_kEDH|SSL_aNULL|SSL_SEED|SSL_SHA1|SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + 0, + 128, + 128, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + +#endif /* OPENSSL_NO_SEED */ + #ifndef OPENSSL_NO_ECDH /* Cipher C001 */ { @@ -1818,6 +1904,39 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) } break; #endif /* !OPENSSL_NO_ECDH */ +#ifndef OPENSSL_NO_TLSEXT + case SSL_CTRL_SET_TLSEXT_HOSTNAME: + if (larg == TLSEXT_NAMETYPE_host_name) + { + if (s->tlsext_hostname != NULL) + OPENSSL_free(s->tlsext_hostname); + s->tlsext_hostname = NULL; + + ret = 1; + if (parg == NULL) + break; + if (strlen((char *)parg) > TLSEXT_MAXLEN_host_name) + { + SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME); + return 0; + } + if ((s->tlsext_hostname = BUF_strdup((char *)parg)) == NULL) + { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + else + { + SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE); + return 0; + } + break; + case SSL_CTRL_SET_TLSEXT_DEBUG_ARG: + s->tlsext_debug_arg=parg; + ret = 1; + break; +#endif /* !OPENSSL_NO_TLSEXT */ default: break; } @@ -1868,6 +1987,12 @@ long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp)(void)) s->cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp; } break; +#endif +#ifndef OPENSSL_NO_TLSEXT + case SSL_CTRL_SET_TLSEXT_DEBUG_CB: + s->tlsext_debug_cb=(void (*)(SSL *,int ,int, + unsigned char *, int, void *))fp; + break; #endif default: break; @@ -2002,6 +2127,36 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) } break; #endif /* !OPENSSL_NO_ECDH */ +#ifndef OPENSSL_NO_TLSEXT + case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG: + ctx->tlsext_servername_arg=parg; + break; + case SSL_CTRL_SET_TLSEXT_TICKET_KEYS: + case SSL_CTRL_GET_TLSEXT_TICKET_KEYS: + { + unsigned char *keys = parg; + if (!keys) + return 48; + if (larg != 48) + { + SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_TICKET_KEYS_LENGTH); + return 0; + } + if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS) + { + memcpy(ctx->tlsext_tick_key_name, keys, 16); + memcpy(ctx->tlsext_tick_hmac_key, keys + 16, 16); + memcpy(ctx->tlsext_tick_aes_key, keys + 32, 16); + } + else + { + memcpy(keys, ctx->tlsext_tick_key_name, 16); + memcpy(keys + 16, ctx->tlsext_tick_hmac_key, 16); + memcpy(keys + 32, ctx->tlsext_tick_aes_key, 16); + } + return 1; + } +#endif /* !OPENSSL_NO_TLSEXT */ /* A Thawte special :-) */ case SSL_CTRL_EXTRA_CHAIN_CERT: if (ctx->extra_certs == NULL) @@ -2046,6 +2201,11 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp; } break; +#endif +#ifndef OPENSSL_NO_TLSEXT + case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB: + ctx->tlsext_servername_callback=(int (*)(SSL *,int *,void *))fp; + break; #endif default: return(0); @@ -2092,6 +2252,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, SSL_CIPHER *c,*ret=NULL; STACK_OF(SSL_CIPHER) *prio, *allow; int i,j,ok; + CERT *cert; unsigned long alg,mask,emask; diff --git a/crypto/openssl-0.9/ssl/s3_srvr.c b/crypto/openssl-0.9/ssl/s3_srvr.c index 9414cf09fb..6dba5c1977 100644 --- a/crypto/openssl-0.9/ssl/s3_srvr.c +++ b/crypto/openssl-0.9/ssl/s3_srvr.c @@ -132,6 +132,7 @@ #include #include #include +#include #include #ifndef OPENSSL_NO_DH #include @@ -143,7 +144,6 @@ #include static SSL_METHOD *ssl3_get_server_method(int ver); - #ifndef OPENSSL_NO_ECDH static int nid2curve_id(int nid); #endif @@ -494,11 +494,26 @@ int ssl3_accept(SSL *s) if (ret <= 0) goto end; if (s->hit) s->state=SSL_ST_OK; +#ifndef OPENSSL_NO_TLSEXT + else if (s->tlsext_ticket_expected) + s->state=SSL3_ST_SW_SESSION_TICKET_A; +#endif else s->state=SSL3_ST_SW_CHANGE_A; s->init_num=0; break; +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_SW_SESSION_TICKET_A: + case SSL3_ST_SW_SESSION_TICKET_B: + ret=ssl3_send_newsession_ticket(s); + if (ret <= 0) goto end; + s->state=SSL3_ST_SW_CHANGE_A; + s->init_num=0; + break; + +#endif + case SSL3_ST_SW_CHANGE_A: case SSL3_ST_SW_CHANGE_B: @@ -699,7 +714,8 @@ int ssl3_get_client_hello(SSL *s) s->client_version=(((int)p[0])<<8)|(int)p[1]; p+=2; - if (s->client_version < s->version) + if ((s->version == DTLS1_VERSION && s->client_version > s->version) || + (s->version != DTLS1_VERSION && s->client_version < s->version)) { SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); if ((s->client_version>>8) == SSL3_VERSION_MAJOR) @@ -727,14 +743,14 @@ int ssl3_get_client_hello(SSL *s) * might be written that become totally unsecure when compiled with * an earlier library version) */ - if (j == 0 || (s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) + if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { if (!ssl_get_new_session(s,1)) goto err; } else { - i=ssl_get_prev_session(s,p,j); + i=ssl_get_prev_session(s, p, j, d + n); if (i == 1) { /* previous session */ s->hit=1; @@ -750,7 +766,7 @@ int ssl3_get_client_hello(SSL *s) p+=j; - if (SSL_version(s) == DTLS1_VERSION) + if (s->version == DTLS1_VERSION) { /* cookie stuff */ cookie_len = *(p++); @@ -897,6 +913,22 @@ int ssl3_get_client_hello(SSL *s) goto f_err; } +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions*/ + if (s->version > SSL3_VERSION) + { + if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al)) + { + /* 'al' set by ssl_parse_clienthello_tlsext */ + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT); + goto f_err; + } + } + if (ssl_check_clienthello_tlsext(s) <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } +#endif /* Worst case, we will use the NULL compression, but if we have other * options, we will now look for them. We have i-1 compression * algorithms from the client, starting at q. */ @@ -1088,7 +1120,13 @@ int ssl3_send_server_hello(SSL *s) else *(p++)=s->s3->tmp.new_compression->id; #endif - +#ifndef OPENSSL_NO_TLSEXT + if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) + { + SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR); + return -1; + } +#endif /* do the header */ l=(p-d); d=buf; @@ -1711,8 +1749,9 @@ int ssl3_get_client_key_exchange(SSL *s) rsa=pkey->pkey.rsa; } - /* TLS */ - if (s->version > SSL3_VERSION) + /* TLS and [incidentally] DTLS, including pre-0.9.8f */ + if (s->version > SSL3_VERSION && + s->client_version != DTLS1_BAD_VER) { n2s(p,i); if (n != i+2) @@ -1997,7 +2036,7 @@ int ssl3_get_client_key_exchange(SSL *s) SSL_R_DATA_LENGTH_TOO_LONG); goto err; } - if (!((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff)))) + if (!((pms[0] == (s->client_version>>8)) && (pms[1] == (s->client_version & 0xff)))) { /* The premaster secret must contain the same version number as the * ClientHello to detect version rollback attacks (strangely, the @@ -2007,8 +2046,7 @@ int ssl3_get_client_key_exchange(SSL *s) * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. * (Perhaps we should have a separate BUG value for the Kerberos cipher) */ - if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) && - (p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff)))) + if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_AD_DECODE_ERROR); @@ -2616,3 +2654,90 @@ static int nid2curve_id(int nid) } } #endif +#ifndef OPENSSL_NO_TLSEXT +int ssl3_send_newsession_ticket(SSL *s) + { + if (s->state == SSL3_ST_SW_SESSION_TICKET_A) + { + unsigned char *p, *senc, *macstart; + int len, slen; + unsigned int hlen; + EVP_CIPHER_CTX ctx; + HMAC_CTX hctx; + + /* get session encoding length */ + slen = i2d_SSL_SESSION(s->session, NULL); + /* Some length values are 16 bits, so forget it if session is + * too long + */ + if (slen > 0xFF00) + return -1; + /* Grow buffer if need be: the length calculation is as + * follows 1 (size of message name) + 3 (message length + * bytes) + 4 (ticket lifetime hint) + 2 (ticket length) + + * 16 (key name) + max_iv_len (iv length) + + * session_length + max_enc_block_size (max encrypted session + * length) + max_md_size (HMAC). + */ + if (!BUF_MEM_grow(s->init_buf, + 26 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + + EVP_MAX_MD_SIZE + slen)) + return -1; + senc = OPENSSL_malloc(slen); + if (!senc) + return -1; + p = senc; + i2d_SSL_SESSION(s->session, &p); + + p=(unsigned char *)s->init_buf->data; + /* do the header */ + *(p++)=SSL3_MT_NEWSESSION_TICKET; + /* Skip message length for now */ + p += 3; + l2n(s->session->tlsext_tick_lifetime_hint, p); + /* Skip ticket length for now */ + p += 2; + /* Output key name */ + macstart = p; + memcpy(p, s->ctx->tlsext_tick_key_name, 16); + p += 16; + /* Generate and output IV */ + RAND_pseudo_bytes(p, 16); + EVP_CIPHER_CTX_init(&ctx); + /* Encrypt session data */ + EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + s->ctx->tlsext_tick_aes_key, p); + p += 16; + EVP_EncryptUpdate(&ctx, p, &len, senc, slen); + p += len; + EVP_EncryptFinal(&ctx, p, &len); + p += len; + EVP_CIPHER_CTX_cleanup(&ctx); + + HMAC_CTX_init(&hctx); + HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16, + tlsext_tick_md(), NULL); + HMAC_Update(&hctx, macstart, p - macstart); + HMAC_Final(&hctx, p, &hlen); + HMAC_CTX_cleanup(&hctx); + + p += hlen; + /* Now write out lengths: p points to end of data written */ + /* Total length */ + len = p - (unsigned char *)s->init_buf->data; + p=(unsigned char *)s->init_buf->data + 1; + l2n3(len - 4, p); /* Message length */ + p += 4; + s2n(len - 10, p); /* Ticket length */ + + /* number of bytes to write */ + s->init_num= len; + s->state=SSL3_ST_SW_SESSION_TICKET_B; + s->init_off=0; + OPENSSL_free(senc); + } + + /* SSL3_ST_SW_SESSION_TICKET_B */ + return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); + } +#endif diff --git a/crypto/openssl-0.9/ssl/ssl.h b/crypto/openssl-0.9/ssl/ssl.h index 2e067e7a78..52caf88b16 100644 --- a/crypto/openssl-0.9/ssl/ssl.h +++ b/crypto/openssl-0.9/ssl/ssl.h @@ -281,6 +281,7 @@ extern "C" { #define SSL_TXT_RC4 "RC4" #define SSL_TXT_RC2 "RC2" #define SSL_TXT_IDEA "IDEA" +#define SSL_TXT_SEED "SEED" #define SSL_TXT_AES "AES" #define SSL_TXT_CAMELLIA "CAMELLIA" #define SSL_TXT_MD5 "MD5" @@ -316,11 +317,7 @@ extern "C" { /* The following cipher list is used by default. * It also is substituted when an application-defined cipher list string * starts with 'DEFAULT'. */ -#ifdef OPENSSL_NO_CAMELLIA -# define SSL_DEFAULT_CIPHER_LIST "ALL:!ADH:+RC4:@STRENGTH" /* low priority for RC4 */ -#else -# define SSL_DEFAULT_CIPHER_LIST "AES:CAMELLIA:ALL:!ADH:+RC4:@STRENGTH" /* low priority for RC4 */ -#endif +#define SSL_DEFAULT_CIPHER_LIST "AES:ALL:!aNULL:!eNULL:+RC4:@STRENGTH" /* low priority for RC4 */ /* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ #define SSL_SENT_SHUTDOWN 1 @@ -477,6 +474,13 @@ typedef struct ssl_session_st /* These are used to make removal of session-ids more * efficient and to implement a maximum cache size. */ struct ssl_session_st *prev,*next; +#ifndef OPENSSL_NO_TLSEXT + char *tlsext_hostname; + /* RFC4507 info */ + unsigned char *tlsext_tick; /* Session ticket */ + size_t tlsext_ticklen; /* Session ticket length */ + long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */ +#endif } SSL_SESSION; @@ -505,6 +509,8 @@ typedef struct ssl_session_st #define SSL_OP_NO_QUERY_MTU 0x00001000L /* Turn on Cookie Exchange (on relevant for servers) */ #define SSL_OP_COOKIE_EXCHANGE 0x00002000L +/* Don't use RFC4507 ticket extension */ +#define SSL_OP_NO_TICKET 0x00004000L /* As server, disallow session resumption on renegotiation */ #define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L @@ -752,6 +758,17 @@ struct ssl_ctx_st #endif int quiet_shutdown; + +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions servername callback */ + int (*tlsext_servername_callback)(SSL*, int *, void *); + void *tlsext_servername_arg; + /* RFC 4507 session ticket keys */ + unsigned char tlsext_tick_key_name[16]; + unsigned char tlsext_tick_hmac_key[16]; + unsigned char tlsext_tick_aes_key[16]; +#endif + }; #define SSL_SESS_CACHE_OFF 0x0000 @@ -973,6 +990,26 @@ struct ssl_st int first_packet; int client_version; /* what was passed, used for * SSLv3/TLS rollback check */ + unsigned int max_send_fragment; +#ifndef OPENSSL_NO_TLSEXT + /* TLS extension debug callback */ + void (*tlsext_debug_cb)(SSL *s, int client_server, int type, + unsigned char *data, int len, + void *arg); + void *tlsext_debug_arg; + char *tlsext_hostname; + int servername_done; /* no further mod of servername + 0 : call the servername extension callback. + 1 : prepare 2, allow last ack just after in server callback. + 2 : don't call servername callback, no ack in server hello + */ + /* RFC4507 session ticket expected to be received or sent */ + int tlsext_ticket_expected; + SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */ +#define session_ctx initial_ctx +#else +#define session_ctx ctx +#endif }; #ifdef __cplusplus @@ -1118,6 +1155,9 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); #define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR /* fatal */ #define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED #define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +#define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION +#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE +#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME #define SSL_ERROR_NONE 0 #define SSL_ERROR_SSL 1 @@ -1176,6 +1216,17 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); #define SSL_CTRL_GET_MAX_CERT_LIST 50 #define SSL_CTRL_SET_MAX_CERT_LIST 51 +/* see tls1.h for macros based on these */ +#ifndef OPENSSL_NO_TLSEXT +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54 +#define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 +#define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56 +#define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 +#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 +#endif + #define SSL_session_reused(ssl) \ SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL) #define SSL_num_renegotiations(ssl) \ @@ -1448,6 +1499,7 @@ int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, SSL_SESSION *SSL_get_session(const SSL *ssl); SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx); void SSL_set_info_callback(SSL *ssl, void (*cb)(const SSL *ssl,int type,int val)); void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,int type,int val); @@ -1564,6 +1616,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253 #define SSL_F_DTLS1_GET_RECORD 254 #define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 +#define SSL_F_DTLS1_PREPROCESS_FRAGMENT 277 #define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 #define SSL_F_DTLS1_PROCESS_RECORD 257 #define SSL_F_DTLS1_READ_BYTES 258 @@ -1624,10 +1677,12 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL3_GET_FINISHED 140 #define SSL_F_SSL3_GET_KEY_EXCHANGE 141 #define SSL_F_SSL3_GET_MESSAGE 142 +#define SSL_F_SSL3_GET_NEW_SESSION_TICKET 283 #define SSL_F_SSL3_GET_RECORD 143 #define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144 #define SSL_F_SSL3_GET_SERVER_DONE 145 #define SSL_F_SSL3_GET_SERVER_HELLO 146 +#define SSL_F_SSL3_NEW_SESSION_TICKET 284 #define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147 #define SSL_F_SSL3_PEEK 235 #define SSL_F_SSL3_READ_BYTES 148 @@ -1643,8 +1698,10 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL3_SETUP_KEY_BLOCK 157 #define SSL_F_SSL3_WRITE_BYTES 158 #define SSL_F_SSL3_WRITE_PENDING 159 +#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 272 #define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 #define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 +#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 273 #define SSL_F_SSL_BAD_METHOD 160 #define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 #define SSL_F_SSL_CERT_DUP 221 @@ -1652,6 +1709,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_CERT_INSTANTIATE 214 #define SSL_F_SSL_CERT_NEW 162 #define SSL_F_SSL_CHECK_PRIVATE_KEY 163 +#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 274 #define SSL_F_SSL_CIPHER_PROCESS_RULESTR 230 #define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 #define SSL_F_SSL_CLEAR 164 @@ -1684,6 +1742,8 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 #define SSL_F_SSL_NEW 186 #define SSL_F_SSL_PEEK 270 +#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 275 +#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 276 #define SSL_F_SSL_READ 223 #define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187 #define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188 @@ -1766,6 +1826,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 #define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 #define SSL_R_CIPHER_TABLE_SRC_ERROR 139 +#define SSL_R_CLIENTHELLO_TLSEXT 157 #define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 #define SSL_R_COMPRESSION_FAILURE 141 #define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 @@ -1793,6 +1854,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_INVALID_CHALLENGE_LENGTH 158 #define SSL_R_INVALID_COMMAND 280 #define SSL_R_INVALID_PURPOSE 278 +#define SSL_R_INVALID_TICKET_KEYS_LENGTH 275 #define SSL_R_INVALID_TRUST 279 #define SSL_R_KEY_ARG_TOO_LONG 284 #define SSL_R_KRB5 285 @@ -1850,6 +1912,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 #define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE 297 #define SSL_R_PACKET_LENGTH_TOO_LONG 198 +#define SSL_R_PARSE_TLSEXT 223 #define SSL_R_PATH_TOO_LONG 270 #define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 #define SSL_R_PEER_ERROR 200 @@ -1873,11 +1936,14 @@ void ERR_load_SSL_strings(void); #define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 216 #define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 217 #define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 218 +#define SSL_R_SERVERHELLO_TLSEXT 224 #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 #define SSL_R_SHORT_READ 219 #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 #define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 225 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 226 #define SSL_R_SSL3_SESSION_ID_TOO_LONG 300 #define SSL_R_SSL3_SESSION_ID_TOO_SHORT 222 #define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 @@ -1912,6 +1978,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 #define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 #define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232 +#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 227 #define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233 #define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234 #define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235 diff --git a/crypto/openssl-0.9/ssl/ssl3.h b/crypto/openssl-0.9/ssl/ssl3.h index bacaff157e..f484df3f65 100644 --- a/crypto/openssl-0.9/ssl/ssl3.h +++ b/crypto/openssl-0.9/ssl/ssl3.h @@ -481,6 +481,8 @@ typedef struct ssl3_state_st #define SSL3_ST_CR_CHANGE_B (0x1C1|SSL_ST_CONNECT) #define SSL3_ST_CR_FINISHED_A (0x1D0|SSL_ST_CONNECT) #define SSL3_ST_CR_FINISHED_B (0x1D1|SSL_ST_CONNECT) +#define SSL3_ST_CR_SESSION_TICKET_A (0x1E0|SSL_ST_CONNECT) +#define SSL3_ST_CR_SESSION_TICKET_B (0x1E1|SSL_ST_CONNECT) /* server */ /* extra state */ @@ -522,10 +524,13 @@ typedef struct ssl3_state_st #define SSL3_ST_SW_CHANGE_B (0x1D1|SSL_ST_ACCEPT) #define SSL3_ST_SW_FINISHED_A (0x1E0|SSL_ST_ACCEPT) #define SSL3_ST_SW_FINISHED_B (0x1E1|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SESSION_TICKET_A (0x1F0|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT) #define SSL3_MT_HELLO_REQUEST 0 #define SSL3_MT_CLIENT_HELLO 1 #define SSL3_MT_SERVER_HELLO 2 +#define SSL3_MT_NEWSESSION_TICKET 4 #define SSL3_MT_CERTIFICATE 11 #define SSL3_MT_SERVER_KEY_EXCHANGE 12 #define SSL3_MT_CERTIFICATE_REQUEST 13 diff --git a/crypto/openssl-0.9/ssl/ssl_algs.c b/crypto/openssl-0.9/ssl/ssl_algs.c index 3d93c5ab78..4717c0e6e1 100644 --- a/crypto/openssl-0.9/ssl/ssl_algs.c +++ b/crypto/openssl-0.9/ssl/ssl_algs.c @@ -83,13 +83,14 @@ int SSL_library_init(void) EVP_add_cipher(EVP_aes_256_cbc()); #endif - -/* The Camellia algorithm is registered in the management table of EVP. */ #ifndef OPENSSL_NO_CAMELLIA EVP_add_cipher(EVP_camellia_128_cbc()); EVP_add_cipher(EVP_camellia_256_cbc()); #endif +#ifndef OPENSSL_NO_SEED + EVP_add_cipher(EVP_seed_cbc()); +#endif #ifndef OPENSSL_NO_MD2 EVP_add_digest(EVP_md2()); diff --git a/crypto/openssl-0.9/ssl/ssl_asn1.c b/crypto/openssl-0.9/ssl/ssl_asn1.c index d129acc329..8d9fb6d7d3 100644 --- a/crypto/openssl-0.9/ssl/ssl_asn1.c +++ b/crypto/openssl-0.9/ssl/ssl_asn1.c @@ -78,6 +78,11 @@ typedef struct ssl_session_asn1_st ASN1_INTEGER time; ASN1_INTEGER timeout; ASN1_INTEGER verify_result; +#ifndef OPENSSL_NO_TLSEXT + ASN1_OCTET_STRING tlsext_hostname; + ASN1_INTEGER tlsext_tick_lifetime; + ASN1_OCTET_STRING tlsext_tick; +#endif /* OPENSSL_NO_TLSEXT */ } SSL_SESSION_ASN1; int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) @@ -86,6 +91,10 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) int v1=0,v2=0,v3=0,v4=0,v5=0; unsigned char buf[4],ibuf1[LSIZE2],ibuf2[LSIZE2]; unsigned char ibuf3[LSIZE2],ibuf4[LSIZE2],ibuf5[LSIZE2]; +#ifndef OPENSSL_NO_TLSEXT + int v6=0,v9=0,v10=0; + unsigned char ibuf6[LSIZE2]; +#endif long l; SSL_SESSION_ASN1 a; M_ASN1_I2D_vars(in); @@ -178,7 +187,32 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) ASN1_INTEGER_set(&a.verify_result,in->verify_result); } - +#ifndef OPENSSL_NO_TLSEXT + if (in->tlsext_hostname) + { + a.tlsext_hostname.length=strlen(in->tlsext_hostname); + a.tlsext_hostname.type=V_ASN1_OCTET_STRING; + a.tlsext_hostname.data=(unsigned char *)in->tlsext_hostname; + } + if (in->tlsext_tick) + { + a.tlsext_tick.length= in->tlsext_ticklen; + a.tlsext_tick.type=V_ASN1_OCTET_STRING; + a.tlsext_tick.data=(unsigned char *)in->tlsext_tick; + /* If we have a ticket set session ID to empty because + * it will be bogus. + */ + if (in->tlsext_ticklen) + a.session_id.length=0; + } + if (in->tlsext_tick_lifetime_hint != 0) + { + a.tlsext_tick_lifetime.length=LSIZE2; + a.tlsext_tick_lifetime.type=V_ASN1_INTEGER; + a.tlsext_tick_lifetime.data=ibuf6; + ASN1_INTEGER_set(&a.tlsext_tick_lifetime,in->tlsext_tick_lifetime_hint); + } +#endif /* OPENSSL_NO_TLSEXT */ M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER); M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER); M_ASN1_I2D_len(&(a.cipher), i2d_ASN1_OCTET_STRING); @@ -200,6 +234,14 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) if (in->verify_result != X509_V_OK) M_ASN1_I2D_len_EXP_opt(&(a.verify_result),i2d_ASN1_INTEGER,5,v5); +#ifndef OPENSSL_NO_TLSEXT + if (in->tlsext_tick_lifetime_hint) + M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9); + if (in->tlsext_tick) + M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10); + if (in->tlsext_hostname) + M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6); +#endif /* OPENSSL_NO_TLSEXT */ M_ASN1_I2D_seq_total(); M_ASN1_I2D_put(&(a.version), i2d_ASN1_INTEGER); @@ -223,6 +265,14 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) v4); if (in->verify_result != X509_V_OK) M_ASN1_I2D_put_EXP_opt(&a.verify_result,i2d_ASN1_INTEGER,5,v5); +#ifndef OPENSSL_NO_TLSEXT + if (in->tlsext_hostname) + M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6); + if (in->tlsext_tick_lifetime_hint) + M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9); + if (in->tlsext_tick) + M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING,10,v10); +#endif /* OPENSSL_NO_TLSEXT */ M_ASN1_I2D_finish(); } @@ -394,5 +444,54 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, else ret->verify_result=X509_V_OK; +#ifndef OPENSSL_NO_TLSEXT + os.length=0; + os.data=NULL; + M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,6); + if (os.data) + { + ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } + else + ret->tlsext_hostname=NULL; + ai.length=0; + M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,9); + if (ai.data != NULL) + { + ret->tlsext_tick_lifetime_hint=ASN1_INTEGER_get(aip); + OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; + } + else + ret->tlsext_tick_lifetime_hint=0; + os.length=0; + os.data=NULL; + M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,10); + if (os.data) + { + ret->tlsext_tick = os.data; + ret->tlsext_ticklen = os.length; + os.data = NULL; + os.length = 0; +#if 0 + /* There are two ways to detect a resumed ticket sesion. + * One is to set a random session ID and then the server + * must return a match in ServerHello. This allows the normal + * client session ID matching to work. + */ + if (ret->session_id_length == 0) + { + ret->session_id_length=SSL3_MAX_SSL_SESSION_ID_LENGTH; + RAND_pseudo_bytes(ret->session_id, + ret->session_id_length); + } +#endif + } + else + ret->tlsext_tick=NULL; +#endif /* OPENSSL_NO_TLSEXT */ + M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION); } diff --git a/crypto/openssl-0.9/ssl/ssl_cert.c b/crypto/openssl-0.9/ssl/ssl_cert.c index fb080093e5..a32b2d4446 100644 --- a/crypto/openssl-0.9/ssl/ssl_cert.c +++ b/crypto/openssl-0.9/ssl/ssl_cert.c @@ -762,7 +762,7 @@ err: if(x != NULL) X509_free(x); - sk_X509_NAME_set_cmp_func(stack,oldcmp); + (void)sk_X509_NAME_set_cmp_func(stack,oldcmp); return ret; } diff --git a/crypto/openssl-0.9/ssl/ssl_ciph.c b/crypto/openssl-0.9/ssl/ssl_ciph.c index 9bb770da27..725f7f3c1f 100644 --- a/crypto/openssl-0.9/ssl/ssl_ciph.c +++ b/crypto/openssl-0.9/ssl/ssl_ciph.c @@ -127,11 +127,10 @@ #define SSL_ENC_NULL_IDX 6 #define SSL_ENC_AES128_IDX 7 #define SSL_ENC_AES256_IDX 8 -#define SSL_ENC_NUM_IDX 9 #define SSL_ENC_CAMELLIA128_IDX 9 #define SSL_ENC_CAMELLIA256_IDX 10 -#undef SSL_ENC_NUM_IDX -#define SSL_ENC_NUM_IDX 11 +#define SSL_ENC_SEED_IDX 11 +#define SSL_ENC_NUM_IDX 12 static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={ @@ -196,10 +195,11 @@ static const SSL_CIPHER cipher_aliases[]={ #ifndef OPENSSL_NO_IDEA {0,SSL_TXT_IDEA,0,SSL_IDEA, 0,0,0,0,SSL_ENC_MASK,0}, #endif + {0,SSL_TXT_SEED,0,SSL_SEED, 0,0,0,0,SSL_ENC_MASK,0}, {0,SSL_TXT_eNULL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0}, {0,SSL_TXT_eFZA,0,SSL_eFZA, 0,0,0,0,SSL_ENC_MASK,0}, {0,SSL_TXT_AES, 0,SSL_AES, 0,0,0,0,SSL_ENC_MASK,0}, - {0,SSL_TXT_CAMELLIA, 0,SSL_CAMELLIA, 0,0,0,0,SSL_ENC_MASK,0}, + {0,SSL_TXT_CAMELLIA,0,SSL_CAMELLIA, 0,0,0,0,SSL_ENC_MASK,0}, {0,SSL_TXT_MD5, 0,SSL_MD5, 0,0,0,0,SSL_MAC_MASK,0}, {0,SSL_TXT_SHA1,0,SSL_SHA1, 0,0,0,0,SSL_MAC_MASK,0}, @@ -248,6 +248,8 @@ void ssl_load_ciphers(void) EVP_get_cipherbyname(SN_camellia_128_cbc); ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX]= EVP_get_cipherbyname(SN_camellia_256_cbc); + ssl_cipher_methods[SSL_ENC_SEED_IDX]= + EVP_get_cipherbyname(SN_seed_cbc); ssl_digest_methods[SSL_MD_MD5_IDX]= EVP_get_digestbyname(SN_md5); @@ -374,6 +376,9 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, default: i=-1; break; } break; + case SSL_SEED: + i=SSL_ENC_SEED_IDX; + break; default: i= -1; @@ -439,7 +444,7 @@ struct disabled_masks { /* This is a kludge no longer needed with OpenSSL 0.9.9, unsigned long m256; /* applies to 256-bit algorithms only */ }; -struct disabled_masks ssl_cipher_get_disabled(void) +static struct disabled_masks ssl_cipher_get_disabled(void) { unsigned long mask; unsigned long m256; @@ -471,6 +476,7 @@ struct disabled_masks ssl_cipher_get_disabled(void) mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0; mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0; mask |= (ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL) ? SSL_eFZA:0; + mask |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED:0; mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0; mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0; @@ -1070,7 +1076,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, if (*cipher_list_by_id != NULL) sk_SSL_CIPHER_free(*cipher_list_by_id); *cipher_list_by_id = tmp_cipher_list; - sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp); + (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp); return(cipherstack); } @@ -1200,7 +1206,10 @@ char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len) default: enc="Camellia(?""?""?)"; break; } break; - + case SSL_SEED: + enc="SEED(128)"; + break; + default: enc="unknown"; break; diff --git a/crypto/openssl-0.9/ssl/ssl_err.c b/crypto/openssl-0.9/ssl/ssl_err.c index e7f4d93c7d..62f06d5f10 100644 --- a/crypto/openssl-0.9/ssl/ssl_err.c +++ b/crypto/openssl-0.9/ssl/ssl_err.c @@ -1,6 +1,6 @@ /* ssl/ssl_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -87,6 +87,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT), "DTLS1_GET_MESSAGE_FRAGMENT"}, {ERR_FUNC(SSL_F_DTLS1_GET_RECORD), "DTLS1_GET_RECORD"}, {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"}, +{ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"}, {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, {ERR_FUNC(SSL_F_DTLS1_READ_BYTES), "DTLS1_READ_BYTES"}, @@ -147,10 +148,12 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL3_GET_FINISHED), "SSL3_GET_FINISHED"}, {ERR_FUNC(SSL_F_SSL3_GET_KEY_EXCHANGE), "SSL3_GET_KEY_EXCHANGE"}, {ERR_FUNC(SSL_F_SSL3_GET_MESSAGE), "SSL3_GET_MESSAGE"}, +{ERR_FUNC(SSL_F_SSL3_GET_NEW_SESSION_TICKET), "SSL3_GET_NEW_SESSION_TICKET"}, {ERR_FUNC(SSL_F_SSL3_GET_RECORD), "SSL3_GET_RECORD"}, {ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE), "SSL3_GET_SERVER_CERTIFICATE"}, {ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE), "SSL3_GET_SERVER_DONE"}, {ERR_FUNC(SSL_F_SSL3_GET_SERVER_HELLO), "SSL3_GET_SERVER_HELLO"}, +{ERR_FUNC(SSL_F_SSL3_NEW_SESSION_TICKET), "SSL3_NEW_SESSION_TICKET"}, {ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN), "SSL3_OUTPUT_CERT_CHAIN"}, {ERR_FUNC(SSL_F_SSL3_PEEK), "SSL3_PEEK"}, {ERR_FUNC(SSL_F_SSL3_READ_BYTES), "SSL3_READ_BYTES"}, @@ -166,8 +169,10 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK), "SSL3_SETUP_KEY_BLOCK"}, {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "SSL3_WRITE_BYTES"}, {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "SSL3_WRITE_PENDING"}, +{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT), "SSL_ADD_CLIENTHELLO_TLSEXT"}, {ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK), "SSL_add_dir_cert_subjects_to_stack"}, {ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK), "SSL_add_file_cert_subjects_to_stack"}, +{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT), "SSL_ADD_SERVERHELLO_TLSEXT"}, {ERR_FUNC(SSL_F_SSL_BAD_METHOD), "SSL_BAD_METHOD"}, {ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "SSL_BYTES_TO_CIPHER_LIST"}, {ERR_FUNC(SSL_F_SSL_CERT_DUP), "SSL_CERT_DUP"}, @@ -175,6 +180,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE), "SSL_CERT_INSTANTIATE"}, {ERR_FUNC(SSL_F_SSL_CERT_NEW), "SSL_CERT_NEW"}, {ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY), "SSL_check_private_key"}, +{ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT), "SSL_CHECK_SERVERHELLO_TLSEXT"}, {ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR), "SSL_CIPHER_PROCESS_RULESTR"}, {ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT), "SSL_CIPHER_STRENGTH_SORT"}, {ERR_FUNC(SSL_F_SSL_CLEAR), "SSL_clear"}, @@ -207,6 +213,8 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"}, {ERR_FUNC(SSL_F_SSL_NEW), "SSL_new"}, {ERR_FUNC(SSL_F_SSL_PEEK), "SSL_peek"}, +{ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT), "SSL_PREPARE_CLIENTHELLO_TLSEXT"}, +{ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT), "SSL_PREPARE_SERVERHELLO_TLSEXT"}, {ERR_FUNC(SSL_F_SSL_READ), "SSL_read"}, {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"}, {ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"}, @@ -292,6 +300,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"}, {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),"cipher or hash unavailable"}, {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"}, +{ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT) ,"clienthello tlsext"}, {ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG),"compressed length too long"}, {ERR_REASON(SSL_R_COMPRESSION_FAILURE) ,"compression failure"}, {ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE),"compression id not within private range"}, @@ -319,6 +328,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"}, {ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"}, {ERR_REASON(SSL_R_INVALID_PURPOSE) ,"invalid purpose"}, +{ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),"invalid ticket keys length"}, {ERR_REASON(SSL_R_INVALID_TRUST) ,"invalid trust"}, {ERR_REASON(SSL_R_KEY_ARG_TOO_LONG) ,"key arg too long"}, {ERR_REASON(SSL_R_KRB5) ,"krb5"}, @@ -376,6 +386,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED),"old session cipher not returned"}, {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE),"only tls allowed in fips mode"}, {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG),"packet length too long"}, +{ERR_REASON(SSL_R_PARSE_TLSEXT) ,"parse tlsext"}, {ERR_REASON(SSL_R_PATH_TOO_LONG) ,"path too long"}, {ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE),"peer did not return a certificate"}, {ERR_REASON(SSL_R_PEER_ERROR) ,"peer error"}, @@ -399,11 +410,14 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO),"reuse cert length not zero"}, {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO),"reuse cert type not zero"}, {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO),"reuse cipher list not zero"}, +{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"}, {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"}, {ERR_REASON(SSL_R_SHORT_READ) ,"short read"}, {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"}, {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"}, {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG),"ssl2 connection id too long"}, +{ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME),"ssl3 ext invalid servername"}, +{ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE),"ssl3 ext invalid servername type"}, {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG),"ssl3 session id too long"}, {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT),"ssl3 session id too short"}, {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE),"sslv3 alert bad certificate"}, @@ -438,6 +452,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA),"tlsv1 alert unknown ca"}, {ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED),"tlsv1 alert user cancelled"}, {ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER),"tls client cert req with anon cipher"}, +{ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls invalid ecpointformat list"}, {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),"tls peer did not respond with certificate list"}, {ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG),"tls rsa encrypted value length is wrong"}, {ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER),"tried to use unsupported cipher"}, diff --git a/crypto/openssl-0.9/ssl/ssl_lib.c b/crypto/openssl-0.9/ssl/ssl_lib.c index 4e81922d75..73707aab9b 100644 --- a/crypto/openssl-0.9/ssl/ssl_lib.c +++ b/crypto/openssl-0.9/ssl/ssl_lib.c @@ -125,6 +125,7 @@ #include #include #include +#include #ifndef OPENSSL_NO_DH #include #endif @@ -306,7 +307,13 @@ SSL *SSL_new(SSL_CTX *ctx) CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); s->ctx=ctx; - +#ifndef OPENSSL_NO_TLSEXT + s->tlsext_debug_cb = 0; + s->tlsext_debug_arg = NULL; + s->tlsext_ticket_expected = 0; + CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); + s->initial_ctx=ctx; +#endif s->verify_result=X509_V_OK; s->method=ctx->method; @@ -492,7 +499,9 @@ void SSL_free(SSL *s) /* Free up if allocated */ if (s->ctx) SSL_CTX_free(s->ctx); - +#ifndef OPENSSL_NO_TLSEXT + if (s->initial_ctx) SSL_CTX_free(s->initial_ctx); +#endif if (s->client_CA != NULL) sk_X509_NAME_pop_free(s->client_CA,X509_NAME_free); @@ -1201,7 +1210,6 @@ int SSL_set_cipher_list(SSL *s,const char *str) char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len) { char *p; - const char *cp; STACK_OF(SSL_CIPHER) *sk; SSL_CIPHER *c; int i; @@ -1214,20 +1222,21 @@ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len) sk=s->session->ciphers; for (i=0; iname; *cp; ) + n=strlen(c->name); + if (n+1 > len) { - if (len-- <= 0) - { - *p='\0'; - return(buf); - } - else - *(p++)= *(cp++); + if (p != buf) + --p; + *p='\0'; + return buf; } + strcpy(p,c->name); + p+=n; *(p++)=':'; + len-=n+1; } p[-1]='\0'; return(buf); @@ -1304,6 +1313,29 @@ err: return(NULL); } +#ifndef OPENSSL_NO_TLSEXT +/** return a servername extension value if provided in Client Hello, or NULL. + * So far, only host_name types are defined (RFC 3546). + */ + +const char *SSL_get_servername(const SSL *s, const int type) + { + if (type != TLSEXT_NAMETYPE_host_name) + return NULL; + + return s->session && !s->tlsext_hostname ? + s->session->tlsext_hostname : + s->tlsext_hostname; + } + +int SSL_get_servername_type(const SSL *s) + { + if (s->session && (!s->tlsext_hostname ? s->session->tlsext_hostname : s->tlsext_hostname)) + return TLSEXT_NAMETYPE_host_name; + return -1; + } +#endif + unsigned long SSL_SESSION_hash(const SSL_SESSION *a) { unsigned long l; @@ -1453,6 +1485,17 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth) ret->extra_certs=NULL; ret->comp_methods=SSL_COMP_get_compression_methods(); +#ifndef OPENSSL_NO_TLSEXT + ret->tlsext_servername_callback = 0; + ret->tlsext_servername_arg = NULL; + /* Setup RFC4507 ticket keys */ + if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0) + || (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0) + || (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0)) + ret->options |= SSL_OP_NO_TICKET; + +#endif + return(ret); err: SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE); @@ -2402,6 +2445,24 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) return(ssl->ctx); } +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx) + { + if (ssl->ctx == ctx) + return ssl->ctx; +#ifndef OPENSSL_NO_TLSEXT + if (ctx == NULL) + ctx = ssl->initial_ctx; +#endif + if (ssl->cert != NULL) + ssl_cert_free(ssl->cert); + ssl->cert = ssl_cert_dup(ctx->cert); + CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); + if (ssl->ctx != NULL) + SSL_CTX_free(ssl->ctx); /* decrement reference count */ + ssl->ctx = ctx; + return(ssl->ctx); + } + #ifndef OPENSSL_NO_STDIO int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) { diff --git a/crypto/openssl-0.9/ssl/ssl_locl.h b/crypto/openssl-0.9/ssl/ssl_locl.h index 786d9886b4..e9fba49c53 100644 --- a/crypto/openssl-0.9/ssl/ssl_locl.h +++ b/crypto/openssl-0.9/ssl/ssl_locl.h @@ -278,7 +278,7 @@ #define SSL_FZA (SSL_aFZA|SSL_kFZA|SSL_eFZA) #define SSL_KRB5 (SSL_kKRB5|SSL_aKRB5) -#define SSL_ENC_MASK 0x0C3F8000L +#define SSL_ENC_MASK 0x1C3F8000L #define SSL_DES 0x00008000L #define SSL_3DES 0x00010000L #define SSL_RC4 0x00020000L @@ -288,6 +288,7 @@ #define SSL_eNULL 0x00200000L #define SSL_AES 0x04000000L #define SSL_CAMELLIA 0x08000000L +#define SSL_SEED 0x10000000L #define SSL_MAC_MASK 0x00c00000L #define SSL_MD5 0x00400000L @@ -299,7 +300,7 @@ #define SSL_SSLV3 0x02000000L #define SSL_TLSV1 SSL_SSLV3 /* for now */ -/* we have used 0fffffff - 4 bits left to go. */ +/* we have used 1fffffff - 3 bits left to go. */ /* * Export and cipher strength information. For each cipher we have to decide @@ -694,7 +695,7 @@ SSL_METHOD *func_name(void) \ ssl3_put_cipher_by_char, \ ssl3_pending, \ ssl3_num_ciphers, \ - ssl3_get_cipher, \ + dtls1_get_cipher, \ s_get_meth, \ dtls1_default_timeout, \ &DTLSv1_enc_data, \ @@ -715,7 +716,7 @@ SESS_CERT *ssl_sess_cert_new(void); void ssl_sess_cert_free(SESS_CERT *sc); int ssl_set_peer_cert_type(SESS_CERT *c, int type); int ssl_get_new_session(SSL *s, int session); -int ssl_get_prev_session(SSL *s, unsigned char *session,int len); +int ssl_get_prev_session(SSL *s, unsigned char *session,int len, const unsigned char *limit); int ssl_cipher_id_cmp(const SSL_CIPHER *a,const SSL_CIPHER *b); int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap, const SSL_CIPHER * const *bp); @@ -775,6 +776,7 @@ SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); int ssl3_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p); void ssl3_init_finished_mac(SSL *s); int ssl3_send_server_certificate(SSL *s); +int ssl3_send_newsession_ticket(SSL *s); int ssl3_get_finished(SSL *s,int state_a,int state_b); int ssl3_setup_key_block(SSL *s); int ssl3_send_change_cipher_spec(SSL *s,int state_a,int state_b); @@ -859,12 +861,15 @@ void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); void dtls1_reset_seq_numbers(SSL *s, int rw); long dtls1_default_timeout(void); +SSL_CIPHER *dtls1_get_cipher(unsigned int u); + /* some client-only functions */ int ssl3_client_hello(SSL *s); int ssl3_get_server_hello(SSL *s); int ssl3_get_certificate_request(SSL *s); +int ssl3_get_new_session_ticket(SSL *s); int ssl3_get_server_done(SSL *s); int ssl3_send_client_verify(SSL *s); int ssl3_send_client_certificate(SSL *s); @@ -946,5 +951,24 @@ int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs); SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); +#ifndef OPENSSL_NO_TLSEXT +unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); +unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); +int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al); +int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al); +int ssl_prepare_clienthello_tlsext(SSL *s); +int ssl_prepare_serverhello_tlsext(SSL *s); +int ssl_check_clienthello_tlsext(SSL *s); +int ssl_check_serverhello_tlsext(SSL *s); +#ifdef OPENSSL_NO_SHA256 +#define tlsext_tick_md EVP_sha1 +#else +#define tlsext_tick_md EVP_sha256 +#endif +int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, + const unsigned char *limit, SSL_SESSION **ret); +EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ; +void ssl_clear_hash_ctx(EVP_MD_CTX **hash); +#endif #endif diff --git a/crypto/openssl-0.9/ssl/ssl_sess.c b/crypto/openssl-0.9/ssl/ssl_sess.c index f80eee6e37..d30a24f2fe 100644 --- a/crypto/openssl-0.9/ssl/ssl_sess.c +++ b/crypto/openssl-0.9/ssl/ssl_sess.c @@ -122,6 +122,9 @@ SSL_SESSION *SSL_SESSION_new(void) ss->prev=NULL; ss->next=NULL; ss->compress_meth=0; +#ifndef OPENSSL_NO_TLSEXT + ss->tlsext_hostname = NULL; +#endif CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); return(ss); } @@ -216,6 +219,14 @@ int ssl_get_new_session(SSL *s, int session) SSL_SESSION_free(ss); return(0); } +#ifndef OPENSSL_NO_TLSEXT + /* If RFC4507 ticket use empty session ID */ + if (s->tlsext_ticket_expected) + { + ss->session_id_length = 0; + goto sess_id_done; + } +#endif /* Choose which callback will set the session ID */ CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); if(s->generate_session_id) @@ -257,6 +268,17 @@ int ssl_get_new_session(SSL *s, int session) SSL_SESSION_free(ss); return(0); } +#ifndef OPENSSL_NO_TLSEXT + sess_id_done: + if (s->tlsext_hostname) { + ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname); + if (ss->tlsext_hostname == NULL) { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); + SSL_SESSION_free(ss); + return 0; + } + } +#endif } else { @@ -278,21 +300,39 @@ int ssl_get_new_session(SSL *s, int session) return(1); } -int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len) +int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, + const unsigned char *limit) { /* This is used only by servers. */ - SSL_SESSION *ret=NULL,data; + SSL_SESSION *ret=NULL; int fatal = 0; - - data.ssl_version=s->version; - data.session_id_length=len; +#ifndef OPENSSL_NO_TLSEXT + int r; +#endif + if (len > SSL_MAX_SSL_SESSION_ID_LENGTH) goto err; - memcpy(data.session_id,session_id,len); - +#ifndef OPENSSL_NO_TLSEXT + r = tls1_process_ticket(s, session_id, len, limit, &ret); + if (r == -1) + { + fatal = 1; + goto err; + } + else if (r == 0) + goto err; + else if (!ret && !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) +#else if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) +#endif { + SSL_SESSION data; + data.ssl_version=s->version; + data.session_id_length=len; + if (len == 0) + return 0; + memcpy(data.session_id,session_id,len); CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,&data); if (ret != NULL) @@ -334,33 +374,35 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len) /* Now ret is non-NULL, and we own one of its reference counts. */ - if((s->verify_mode&SSL_VERIFY_PEER) - && (!s->sid_ctx_length || ret->sid_ctx_length != s->sid_ctx_length - || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length))) - { + if (ret->sid_ctx_length != s->sid_ctx_length + || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length)) + { /* We've found the session named by the client, but we don't * want to use it in this context. */ - - if (s->sid_ctx_length == 0) - { - /* application should have used SSL[_CTX]_set_session_id_context - * -- we could tolerate this and just pretend we never heard - * of this session, but then applications could effectively - * disable the session cache by accident without anyone noticing */ - SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); - fatal = 1; - goto err; - } - else - { #if 0 /* The client cannot always know when a session is not appropriate, - * so we shouldn't generate an error message. */ + * so we shouldn't generate an error message. */ - SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); #endif - goto err; /* treat like cache miss */ - } + goto err; /* treat like cache miss */ + } + + if((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) + { + /* We can't be sure if this session is being used out of + * context, which is especially important for SSL_VERIFY_PEER. + * The application should have used SSL[_CTX]_set_session_id_context. + * + * For this error case, we generate an error instead of treating + * the event like a cache miss (otherwise it would be easy for + * applications to effectively disable the session cache by + * accident without anyone noticing). + */ + + SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); + fatal = 1; + goto err; } if (ret->cipher == NULL) @@ -546,6 +588,10 @@ void SSL_SESSION_free(SSL_SESSION *ss) if (ss->sess_cert != NULL) ssl_sess_cert_free(ss->sess_cert); if (ss->peer != NULL) X509_free(ss->peer); if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers); +#ifndef OPENSSL_NO_TLSEXT + if (ss->tlsext_hostname != NULL) OPENSSL_free(ss->tlsext_hostname); + if (ss->tlsext_tick != NULL) OPENSSL_free(ss->tlsext_tick); +#endif OPENSSL_cleanse(ss,sizeof(*ss)); OPENSSL_free(ss); } diff --git a/crypto/openssl-0.9/ssl/ssl_txt.c b/crypto/openssl-0.9/ssl/ssl_txt.c index 4eb0867155..06b86750fd 100644 --- a/crypto/openssl-0.9/ssl/ssl_txt.c +++ b/crypto/openssl-0.9/ssl/ssl_txt.c @@ -151,6 +151,21 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) if (BIO_printf(bp,"%02X",x->krb5_client_princ[i]) <= 0) goto err; } #endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_TLSEXT + if (x->tlsext_tick_lifetime_hint) + { + if (BIO_printf(bp, + "\n TLS session ticket lifetime hint: %ld (seconds)", + x->tlsext_tick_lifetime_hint) <=0) + goto err; + } + if (x->tlsext_tick) + { + if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0) goto err; + if (BIO_dump_indent(bp, (char *)x->tlsext_tick, x->tlsext_ticklen, 4) <= 0) + goto err; + } +#endif #ifndef OPENSSL_NO_COMP if (x->compress_meth != 0) { diff --git a/crypto/openssl-0.9/ssl/t1_enc.c b/crypto/openssl-0.9/ssl/t1_enc.c index 68448b98ca..ed5a4a7255 100644 --- a/crypto/openssl-0.9/ssl/t1_enc.c +++ b/crypto/openssl-0.9/ssl/t1_enc.c @@ -738,15 +738,35 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) md_size=EVP_MD_size(hash); buf[0]=rec->type; - buf[1]=TLS1_VERSION_MAJOR; - buf[2]=TLS1_VERSION_MINOR; + if (ssl->version == DTLS1_VERSION && ssl->client_version == DTLS1_BAD_VER) + { + buf[1]=TLS1_VERSION_MAJOR; + buf[2]=TLS1_VERSION_MINOR; + } + else { + buf[1]=(unsigned char)(ssl->version>>8); + buf[2]=(unsigned char)(ssl->version); + } + buf[3]=rec->length>>8; buf[4]=rec->length&0xff; /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ HMAC_CTX_init(&hmac); HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL); - HMAC_Update(&hmac,seq,8); + + if (ssl->version == DTLS1_VERSION && ssl->client_version != DTLS1_BAD_VER) + { + unsigned char dtlsseq[8],*p=dtlsseq; + + s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p); + memcpy (p,&seq[2],6); + + HMAC_Update(&hmac,dtlsseq,8); + } + else + HMAC_Update(&hmac,seq,8); + HMAC_Update(&hmac,buf,5); HMAC_Update(&hmac,rec->input,rec->length); HMAC_Final(&hmac,md,&md_size); @@ -763,8 +783,8 @@ printf("rec="); {unsigned int z; for (z=0; zlength; z++) printf("%02X ",buf[z]); printf("\n"); } #endif - if ( SSL_version(ssl) != DTLS1_VERSION) - { + if ( SSL_version(ssl) != DTLS1_VERSION) + { for (i=7; i>=0; i--) { ++seq[i]; diff --git a/crypto/openssl-0.9/ssl/t1_lib.c b/crypto/openssl-0.9/ssl/t1_lib.c index 1ecbbcb8fb..fabc634d68 100644 --- a/crypto/openssl-0.9/ssl/t1_lib.c +++ b/crypto/openssl-0.9/ssl/t1_lib.c @@ -58,10 +58,18 @@ #include #include +#include +#include #include "ssl_locl.h" const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT; +#ifndef OPENSSL_NO_TLSEXT +static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, + const unsigned char *sess_id, int sesslen, + SSL_SESSION **psess); +#endif + SSL3_ENC_METHOD TLSv1_enc_data={ tls1_enc, tls1_mac, @@ -117,3 +125,506 @@ long tls1_callback_ctrl(SSL *s, int cmd, void *(*fp)()) return(0); } #endif + +#ifndef OPENSSL_NO_TLSEXT +unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) + { + int extdatalen=0; + unsigned char *ret = p; + + ret+=2; + + if (ret>=limit) return NULL; /* this really never occurs, but ... */ + + if (s->tlsext_hostname != NULL) + { + /* Add TLS extension servername to the Client Hello message */ + unsigned long size_str; + long lenmax; + + /* check for enough space. + 4 for the servername type and entension length + 2 for servernamelist length + 1 for the hostname type + 2 for hostname length + + hostname length + */ + + if ((lenmax = limit - ret - 9) < 0 + || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) + return NULL; + + /* extension type and length */ + s2n(TLSEXT_TYPE_server_name,ret); + s2n(size_str+5,ret); + + /* length of servername list */ + s2n(size_str+3,ret); + + /* hostname type, length and hostname */ + *(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name; + s2n(size_str,ret); + memcpy(ret, s->tlsext_hostname, size_str); + ret+=size_str; + + } + + if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) + { + int ticklen; + if (s->session && s->session->tlsext_tick) + ticklen = s->session->tlsext_ticklen; + else + ticklen = 0; + /* Check for enough room 2 for extension type, 2 for len + * rest for ticket + */ + if (limit - ret - 4 - ticklen < 0) + return NULL; + s2n(TLSEXT_TYPE_session_ticket,ret); + s2n(ticklen,ret); + if (ticklen) + { + memcpy(ret, s->session->tlsext_tick, ticklen); + ret += ticklen; + } + } + + if ((extdatalen = ret-p-2)== 0) + return p; + + s2n(extdatalen,p); + return ret; + } + +unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) + { + int extdatalen=0; + unsigned char *ret = p; + + ret+=2; + if (ret>=limit) return NULL; /* this really never occurs, but ... */ + + if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL) + { + if (limit - ret - 4 < 0) return NULL; + + s2n(TLSEXT_TYPE_server_name,ret); + s2n(0,ret); + } + + if (s->tlsext_ticket_expected + && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) + { + if (limit - ret - 4 < 0) return NULL; + s2n(TLSEXT_TYPE_session_ticket,ret); + s2n(0,ret); + } + + if ((extdatalen = ret-p-2)== 0) + return p; + + s2n(extdatalen,p); + return ret; + } + +int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) + { + unsigned short type; + unsigned short size; + unsigned short len; + unsigned char *data = *p; + s->servername_done = 0; + + if (data >= (d+n-2)) + return 1; + n2s(data,len); + + if (data > (d+n-len)) + return 1; + + while (data <= (d+n-4)) + { + n2s(data,type); + n2s(data,size); + + if (data+size > (d+n)) + return 1; + + if (s->tlsext_debug_cb) + s->tlsext_debug_cb(s, 0, type, data, size, + s->tlsext_debug_arg); +/* The servername extension is treated as follows: + + - Only the hostname type is supported with a maximum length of 255. + - The servername is rejected if too long or if it contains zeros, + in which case an fatal alert is generated. + - The servername field is maintained together with the session cache. + - When a session is resumed, the servername call back invoked in order + to allow the application to position itself to the right context. + - The servername is acknowledged if it is new for a session or when + it is identical to a previously used for the same session. + Applications can control the behaviour. They can at any time + set a 'desirable' servername for a new SSL object. This can be the + case for example with HTTPS when a Host: header field is received and + a renegotiation is requested. In this case, a possible servername + presented in the new client hello is only acknowledged if it matches + the value of the Host: field. + - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION + if they provide for changing an explicit servername context for the session, + i.e. when the session has been established with a servername extension. + - On session reconnect, the servername extension may be absent. + +*/ + + if (type == TLSEXT_TYPE_server_name) + { + unsigned char *sdata; + int servname_type; + int dsize; + + if (size < 2) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + n2s(data,dsize); + size -= 2; + if (dsize > size ) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + sdata = data; + while (dsize > 3) + { + servname_type = *(sdata++); + n2s(sdata,len); + dsize -= 3; + + if (len > dsize) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + if (s->servername_done == 0) + switch (servname_type) + { + case TLSEXT_NAMETYPE_host_name: + if (s->session->tlsext_hostname == NULL) + { + if (len > TLSEXT_MAXLEN_host_name || + ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL)) + { + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + memcpy(s->session->tlsext_hostname, sdata, len); + s->session->tlsext_hostname[len]='\0'; + if (strlen(s->session->tlsext_hostname) != len) { + OPENSSL_free(s->session->tlsext_hostname); + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + s->servername_done = 1; + + } + else + s->servername_done = strlen(s->session->tlsext_hostname) == len + && strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0; + + break; + + default: + break; + } + + dsize -= len; + } + if (dsize != 0) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + } + /* session ticket processed earlier */ + + data+=size; + } + + *p = data; + return 1; + } + +int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) + { + unsigned short type; + unsigned short size; + unsigned short len; + unsigned char *data = *p; + + int tlsext_servername = 0; + + if (data >= (d+n-2)) + return 1; + + n2s(data,len); + + while(data <= (d+n-4)) + { + n2s(data,type); + n2s(data,size); + + if (data+size > (d+n)) + return 1; + + if (s->tlsext_debug_cb) + s->tlsext_debug_cb(s, 1, type, data, size, + s->tlsext_debug_arg); + + if (type == TLSEXT_TYPE_server_name) + { + if (s->tlsext_hostname == NULL || size > 0) + { + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + tlsext_servername = 1; + } + else if (type == TLSEXT_TYPE_session_ticket) + { + if ((SSL_get_options(s) & SSL_OP_NO_TICKET) + || (size > 0)) + { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + s->tlsext_ticket_expected = 1; + } + + data+=size; + } + + if (data != d+n) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + if (!s->hit && tlsext_servername == 1) + { + if (s->tlsext_hostname) + { + if (s->session->tlsext_hostname == NULL) + { + s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname); + if (!s->session->tlsext_hostname) + { + *al = SSL_AD_UNRECOGNIZED_NAME; + return 0; + } + } + else + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + } + } + + *p = data; + return 1; + } + +int ssl_check_clienthello_tlsext(SSL *s) + { + int ret=SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + + if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) + ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg); + else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) + ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg); + + switch (ret) + { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s,SSL3_AL_FATAL,al); + return -1; + + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s,SSL3_AL_WARNING,al); + return 1; + + case SSL_TLSEXT_ERR_NOACK: + s->servername_done=0; + default: + return 1; + } + } + +int ssl_check_serverhello_tlsext(SSL *s) + { + int ret=SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + + if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) + ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg); + else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) + ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg); + + switch (ret) + { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s,SSL3_AL_FATAL,al); + return -1; + + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s,SSL3_AL_WARNING,al); + return 1; + + case SSL_TLSEXT_ERR_NOACK: + s->servername_done=0; + default: + return 1; + } + } + +/* Since the server cache lookup is done early on in the processing of client + * hello and other operations depend on the result we need to handle any TLS + * session ticket extension at the same time. + */ + +int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, + const unsigned char *limit, SSL_SESSION **ret) + { + /* Point after session ID in client hello */ + const unsigned char *p = session_id + len; + unsigned short i; + if ((s->version <= SSL3_VERSION) || !limit) + return 1; + if (p >= limit) + return -1; + /* Skip past cipher list */ + n2s(p, i); + p+= i; + if (p >= limit) + return -1; + /* Skip past compression algorithm list */ + i = *(p++); + p += i; + if (p > limit) + return -1; + /* Now at start of extensions */ + if ((p + 2) >= limit) + return 1; + n2s(p, i); + while ((p + 4) <= limit) + { + unsigned short type, size; + n2s(p, type); + n2s(p, size); + if (p + size > limit) + return 1; + if (type == TLSEXT_TYPE_session_ticket) + { + /* If tickets disabled indicate cache miss which will + * trigger a full handshake + */ + if (SSL_get_options(s) & SSL_OP_NO_TICKET) + return 0; + /* If zero length not client will accept a ticket + * and indicate cache miss to trigger full handshake + */ + if (size == 0) + { + s->tlsext_ticket_expected = 1; + return 0; /* Cache miss */ + } + return tls_decrypt_ticket(s, p, size, session_id, len, + ret); + } + p += size; + } + return 1; + } + +static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, + const unsigned char *sess_id, int sesslen, + SSL_SESSION **psess) + { + SSL_SESSION *sess; + unsigned char *sdec; + const unsigned char *p; + int slen, mlen; + unsigned char tick_hmac[EVP_MAX_MD_SIZE]; + HMAC_CTX hctx; + EVP_CIPHER_CTX ctx; + /* Attempt to process session ticket, first conduct sanity and + * integrity checks on ticket. + */ + mlen = EVP_MD_size(tlsext_tick_md()); + eticklen -= mlen; + /* Need at least keyname + iv + some encrypted data */ + if (eticklen < 48) + goto tickerr; + /* Check key name matches */ + if (memcmp(etick, s->ctx->tlsext_tick_key_name, 16)) + goto tickerr; + /* Check HMAC of encrypted ticket */ + HMAC_CTX_init(&hctx); + HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16, + tlsext_tick_md(), NULL); + HMAC_Update(&hctx, etick, eticklen); + HMAC_Final(&hctx, tick_hmac, NULL); + HMAC_CTX_cleanup(&hctx); + if (memcmp(tick_hmac, etick + eticklen, mlen)) + goto tickerr; + /* Set p to start of IV */ + p = etick + 16; + EVP_CIPHER_CTX_init(&ctx); + /* Attempt to decrypt session data */ + EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + s->ctx->tlsext_tick_aes_key, p); + /* Move p after IV to start of encrypted ticket, update length */ + p += 16; + eticklen -= 32; + sdec = OPENSSL_malloc(eticklen); + if (!sdec) + { + EVP_CIPHER_CTX_cleanup(&ctx); + return -1; + } + EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen); + if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) + goto tickerr; + slen += mlen; + EVP_CIPHER_CTX_cleanup(&ctx); + p = sdec; + + sess = d2i_SSL_SESSION(NULL, &p, slen); + OPENSSL_free(sdec); + if (sess) + { + /* The session ID if non-empty is used by some clients to + * detect that the ticket has been accepted. So we copy it to + * the session structure. If it is empty set length to zero + * as required by standard. + */ + if (sesslen) + memcpy(sess->session_id, sess_id, sesslen); + sess->session_id_length = sesslen; + *psess = sess; + return 1; + } + /* If session decrypt failure indicate a cache miss and set state to + * send a new ticket + */ + tickerr: + s->tlsext_ticket_expected = 1; + return 0; + } + +#endif diff --git a/crypto/openssl-0.9/ssl/tls1.h b/crypto/openssl-0.9/ssl/tls1.h index e5f9aa1ef6..00399f9886 100644 --- a/crypto/openssl-0.9/ssl/tls1.h +++ b/crypto/openssl-0.9/ssl/tls1.h @@ -96,6 +96,60 @@ extern "C" { #define TLS1_AD_INTERNAL_ERROR 80 /* fatal */ #define TLS1_AD_USER_CANCELLED 90 #define TLS1_AD_NO_RENEGOTIATION 100 +/* codes 110-114 are from RFC3546 */ +#define TLS1_AD_UNSUPPORTED_EXTENSION 110 +#define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +#define TLS1_AD_UNRECOGNIZED_NAME 112 +#define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 /* fatal */ + +/* ExtensionType values from RFC 3546 */ +#define TLSEXT_TYPE_server_name 0 +#define TLSEXT_TYPE_max_fragment_length 1 +#define TLSEXT_TYPE_client_certificate_url 2 +#define TLSEXT_TYPE_trusted_ca_keys 3 +#define TLSEXT_TYPE_truncated_hmac 4 +#define TLSEXT_TYPE_status_request 5 +#define TLSEXT_TYPE_elliptic_curves 10 +#define TLSEXT_TYPE_ec_point_formats 11 +#define TLSEXT_TYPE_session_ticket 35 + +/* NameType value from RFC 3546 */ +#define TLSEXT_NAMETYPE_host_name 0 + +#ifndef OPENSSL_NO_TLSEXT + +#define TLSEXT_MAXLEN_host_name 255 + +const char *SSL_get_servername(const SSL *s, const int type) ; +int SSL_get_servername_type(const SSL *s) ; + +#define SSL_set_tlsext_host_name(s,name) \ +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) + +#define SSL_set_tlsext_debug_callback(ssl, cb) \ +SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb) + +#define SSL_set_tlsext_debug_arg(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg) + +#define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \ +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb) + +#define SSL_TLSEXT_ERR_OK 0 +#define SSL_TLSEXT_ERR_ALERT_WARNING 1 +#define SSL_TLSEXT_ERR_ALERT_FATAL 2 +#define SSL_TLSEXT_ERR_NOACK 3 + +#define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \ +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg) + +#define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLXEXT_TICKET_KEYS,(keylen),(keys)) +#define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLXEXT_TICKET_KEYS,(keylen),(keys)) +#endif /* Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see @@ -140,6 +194,14 @@ extern "C" { #define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000088 #define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA 0x03000089 +/* SEED ciphersuites from RFC4162 */ +#define TLS1_CK_RSA_WITH_SEED_SHA 0x03000096 +#define TLS1_CK_DH_DSS_WITH_SEED_SHA 0x03000097 +#define TLS1_CK_DH_RSA_WITH_SEED_SHA 0x03000098 +#define TLS1_CK_DHE_DSS_WITH_SEED_SHA 0x03000099 +#define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A +#define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B + /* ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in draft 13 */ #define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001 #define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002 @@ -232,7 +294,7 @@ extern "C" { #define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" #define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" -/* Camellia ciphersuites form RFC4132 */ +/* Camellia ciphersuites from RFC4132 */ #define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" #define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" #define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA "DH-RSA-CAMELLIA128-SHA" @@ -247,6 +309,13 @@ extern "C" { #define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "DHE-RSA-CAMELLIA256-SHA" #define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA "ADH-CAMELLIA256-SHA" +/* SEED ciphersuites from RFC4162 */ +#define TLS1_TXT_RSA_WITH_SEED_SHA "SEED-SHA" +#define TLS1_TXT_DH_DSS_WITH_SEED_SHA "DH-DSS-SEED-SHA" +#define TLS1_TXT_DH_RSA_WITH_SEED_SHA "DH-RSA-SEED-SHA" +#define TLS1_TXT_DHE_DSS_WITH_SEED_SHA "DHE-DSS-SEED-SHA" +#define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" +#define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" #define TLS_CT_RSA_SIGN 1 #define TLS_CT_DSS_SIGN 2 -- 2.41.0