New option to enable/disable connection to unpatched servers
authorDr. Stephen Henson <steve@openssl.org>
Wed, 16 Dec 2009 20:28:30 +0000 (20:28 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 16 Dec 2009 20:28:30 +0000 (20:28 +0000)
12 files changed:
CHANGES
apps/s_client.c
crypto/evp/evp.h
crypto/evp/evp_err.c
crypto/evp/evp_pbe.c
demos/pkcs12/pkread.c
ssl/d1_clnt.c
ssl/d1_srvr.c
ssl/ssl.h
ssl/ssl3.h
ssl/ssl_lib.c
ssl/t1_lib.c

diff --git a/CHANGES b/CHANGES
index c1f39f1..a597ba0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
      [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]
index a3db16d..34ad2ce 100644 (file)
@@ -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.
         */
index 8c77419..60a947a 100644 (file)
@@ -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
index 04485f0..8a7ca3e 100644 (file)
@@ -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"},
index cd6e40d..c9d932d 100644 (file)
@@ -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))
                {
index 02e16cd..85ba4e2 100644 (file)
@@ -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]);
index 57c1033..5317a51 100644 (file)
@@ -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         
index 007542f..fb64d49 100644 (file)
@@ -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
index fff0684..f7f8be7 100644 (file)
--- 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
index d929569..414ad2d 100644 (file)
@@ -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
index 6dc739d..9552333 100644 (file)
@@ -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:
index 8f1a6b2..26b8bf9 100644 (file)
@@ -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;