From 675564835cb1105289ee85e32844d38af5efef4c Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 16 Dec 2009 20:28:30 +0000 Subject: [PATCH] New option to enable/disable connection to unpatched servers --- CHANGES | 5 +++++ apps/s_client.c | 9 ++++++++- crypto/evp/evp.h | 2 ++ crypto/evp/evp_err.c | 6 ++++-- crypto/evp/evp_pbe.c | 14 ++++++++++++++ demos/pkcs12/pkread.c | 3 ++- ssl/d1_clnt.c | 2 +- ssl/d1_srvr.c | 2 +- ssl/ssl.h | 2 ++ ssl/ssl3.h | 2 ++ ssl/ssl_lib.c | 4 ++++ ssl/t1_lib.c | 5 +++-- 12 files changed, 48 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index c1f39f1e2c..a597ba0ae9 100644 --- a/CHANGES +++ b/CHANGES @@ -827,6 +827,11 @@ [NTT] Changes between 0.9.8l (?) and 0.9.8m (?) [xx XXX xxxx] + + *) Add option SSL_OP_LEGACY_SERVER_CONNECT which will allow clients to + connect (but not renegotiate) with servers which do not support RI. + Until RI is more widely deployed this option is enabled by default. + [Steve Henson] *) Add "missing" ssl ctrls to clear options and mode. [Steve Henson] diff --git a/apps/s_client.c b/apps/s_client.c index a3db16dfb0..34ad2cec78 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -382,7 +382,7 @@ int MAIN(int, char **); int MAIN(int argc, char **argv) { - int off=0; + unsigned int off=0, clr=0; SSL *con=NULL; int s,k,width,state=0; char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL; @@ -661,6 +661,10 @@ int MAIN(int argc, char **argv) off|=SSL_OP_CIPHER_SERVER_PREFERENCE; else if (strcmp(*argv,"-legacy_renegotiation") == 0) off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; + else if (strcmp(*argv,"-legacy_server_connect") == 0) + { off|=SSL_OP_LEGACY_SERVER_CONNECT; } + else if (strcmp(*argv,"-no_legacy_server_connect") == 0) + { clr|=SSL_OP_LEGACY_SERVER_CONNECT; } else if (strcmp(*argv,"-cipher") == 0) { if (--argc < 1) goto bad; @@ -871,6 +875,9 @@ bad: SSL_CTX_set_options(ctx,SSL_OP_ALL|off); else SSL_CTX_set_options(ctx,off); + + if (clr) + SSL_CTX_clear_options(ctx, clr); /* DTLS: partial reads end up discarding unread UDP bytes :-( * Setting read ahead solves this problem. */ diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 8c7741932b..60a947af50 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -1289,6 +1289,8 @@ void ERR_load_EVP_strings(void); #define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 #define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 #define EVP_R_PUBLIC_KEY_NOT_RSA 106 +#define EVP_R_UNKNOWN_CIPHER 160 +#define EVP_R_UNKNOWN_DIGEST 161 #define EVP_R_UNKNOWN_PBE_ALGORITHM 121 #define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135 #define EVP_R_UNSUPPORTED_ALGORITHM 156 diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 04485f0162..8a7ca3e8e0 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -1,6 +1,6 @@ /* crypto/evp/evp_err.c */ /* ==================================================================== - * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2009 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 @@ -85,7 +85,7 @@ static ERR_STRING_DATA EVP_str_functs[]= {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"}, {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"}, {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"}, -{ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_SIZE"}, +{ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_size"}, {ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"}, {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"}, {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"}, @@ -185,6 +185,8 @@ static ERR_STRING_DATA EVP_str_reasons[]= {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR),"private key decode error"}, {ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR),"private key encode error"}, {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"}, +{ERR_REASON(EVP_R_UNKNOWN_CIPHER) ,"unknown cipher"}, +{ERR_REASON(EVP_R_UNKNOWN_DIGEST) ,"unknown digest"}, {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"}, {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"}, {ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"}, diff --git a/crypto/evp/evp_pbe.c b/crypto/evp/evp_pbe.c index cd6e40dcaa..c9d932d205 100644 --- a/crypto/evp/evp_pbe.c +++ b/crypto/evp/evp_pbe.c @@ -174,12 +174,26 @@ int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, if (cipher_nid == -1) cipher = NULL; else + { cipher = EVP_get_cipherbynid(cipher_nid); + if (!cipher) + { + EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_CIPHER); + return 0; + } + } if (md_nid == -1) md = NULL; else + { md = EVP_get_digestbynid(md_nid); + if (!md) + { + EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_DIGEST); + return 0; + } + } if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) { diff --git a/demos/pkcs12/pkread.c b/demos/pkcs12/pkread.c index 02e16cda2a..85ba4e2f86 100644 --- a/demos/pkcs12/pkread.c +++ b/demos/pkcs12/pkread.c @@ -20,7 +20,8 @@ int main(int argc, char **argv) fprintf(stderr, "Usage: pkread p12file password opfile\n"); exit (1); } - SSLeay_add_all_algorithms(); + /*SSLeay_add_all_algorithms();*/ +OpenSSL_add_all_digests(); ERR_load_crypto_strings(); if (!(fp = fopen(argv[1], "rb"))) { fprintf(stderr, "Error opening file %s\n", argv[1]); diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c index 57c1033f55..5317a51180 100644 --- a/ssl/d1_clnt.c +++ b/ssl/d1_clnt.c @@ -698,7 +698,7 @@ int dtls1_client_hello(SSL *s) #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); + SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); goto err; } #endif diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c index 007542f534..fb64d49166 100644 --- a/ssl/d1_srvr.c +++ b/ssl/d1_srvr.c @@ -814,7 +814,7 @@ int dtls1_send_server_hello(SSL *s) #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); + SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR); return -1; } #endif diff --git a/ssl/ssl.h b/ssl/ssl.h index fff0684ce5..f7f8be7e29 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -517,6 +517,8 @@ typedef struct ssl_session_st #define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L #define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L +/* Allow initial connection to servers that don't support RI */ +#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L #define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L #define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L #define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L diff --git a/ssl/ssl3.h b/ssl/ssl3.h index d929569aef..414ad2d58a 100644 --- a/ssl/ssl3.h +++ b/ssl/ssl3.h @@ -129,7 +129,9 @@ extern "C" { #endif /* Magic Cipher Suite Value. NB: bogus value used for testing */ +#ifndef SSL3_CK_MCSV #define SSL3_CK_MCSV 0x03000FEC +#endif #define SSL3_CK_RSA_NULL_MD5 0x03000001 #define SSL3_CK_RSA_NULL_SHA 0x03000002 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 6dc739dcf6..9552333920 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1677,6 +1677,10 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) } #endif #endif + /* Default is to connect to non-RI servers. When RI is more widely + * deployed might change this. + */ + ret->options = SSL_OP_LEGACY_SERVER_CONNECT; return(ret); err: diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 8f1a6b2f6d..26b8bf98cc 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1157,8 +1157,9 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in * which doesn't support RI so for the immediate future tolerate RI * absence on initial connect only. */ - if (!renegotiate_seen && s->new_session && - !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) + if (!renegotiate_seen && + (s->new_session || !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)) + && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { /* FIXME: Spec currently doesn't give alert to use */ *al = SSL_AD_ILLEGAL_PARAMETER; -- 2.40.0