Add ctrl and utility functions to retrieve raw cipher list sent by client in
authorDr. Stephen Henson <steve@openssl.org>
Wed, 12 Sep 2012 13:57:48 +0000 (13:57 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 12 Sep 2012 13:57:48 +0000 (13:57 +0000)
client hello message. Previously this could only be retrieved on an initial
connection and it was impossible to determine the cipher IDs of any uknown
ciphersuites.

CHANGES
ssl/s2_lib.c
ssl/s3_lib.c
ssl/ssl.h
ssl/ssl_cert.c
ssl/ssl_ciph.c
ssl/ssl_lib.c
ssl/ssl_locl.h

diff --git a/CHANGES b/CHANGES
index 3dda962cbe942a021fb88e54ca8c13e882c59125..8e358c69fae276c0f42f5605b708366c6d7485ff 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,10 @@
 
  Changes between 1.0.x and 1.1.0  [xx XXX xxxx]
 
+  *) Add functions to retrieve and manipulate the raw cipherlist sent by a
+     client to OpenSSL.
+     [Steve Henson]
+
   *) New Suite B modes for TLS code. These use and enforce the requirements
      of RFC6460: restrict ciphersuites, only permit Suite B algorithms and
      only use Suite B curves. The Suite B modes can be set by using the
index 99146041091087eb2757c316b773be8fc3725c88..b37792fcc39f17ee6860858bf3e6f0d0d15916ec 100644 (file)
@@ -424,10 +424,7 @@ const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p)
                ((unsigned long)p[1]<<8L)|(unsigned long)p[2];
        c.id=id;
        cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS);
-       if ((cp == NULL) || (cp->valid == 0))
-               return NULL;
-       else
-               return cp;
+       return cp;
        }
 
 int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
index f1e703b873893d31b8ed43976769dd6580a23b9f..c8e6d18ab8645a524ea64374e33b4d20b4b4bcd0 100644 (file)
@@ -3965,10 +3965,7 @@ const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p)
 #ifdef DEBUG_PRINT_UNKNOWN_CIPHERSUITES
 if (cp == NULL) fprintf(stderr, "Unknown cipher ID %x\n", (p[0] << 8) | p[1]);
 #endif
-       if (cp == NULL || cp->valid == 0)
-               return NULL;
-       else
-               return cp;
+       return cp;
        }
 
 int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
index 8300bdaf2bc087e8a7a25fe77282b6d55868a8e5..891667827ad2b2fe8fe507bd76affef1a2d3893b 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -1709,6 +1709,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 #define SSL_CTRL_SET_CHAIN_CERT_STORE          107
 #define SSL_CTRL_GET_PEER_SIGNATURE_NID                108
 #define SSL_CTRL_GET_SERVER_TMP_KEY            109
+#define SSL_CTRL_GET_RAW_CIPHERLIST            110
 
 #define DTLSv1_get_timeout(ssl, arg) \
        SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
@@ -1839,6 +1840,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 #define SSL_get_server_tmp_key(s, pk) \
        SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk)
 
+#define SSL_get0_raw_cipherlist(s, plst) \
+       SSL_ctrl(s,SSL_CTRL_GET_RAW_CIPHERLIST,0,plst)
+
 #ifndef OPENSSL_NO_BIO
 BIO_METHOD *BIO_f_ssl(void);
 BIO *BIO_new_ssl(SSL_CTX *ctx,int client);
@@ -2241,6 +2245,8 @@ void *SSL_COMP_get_compression_methods(void);
 int SSL_COMP_add_compression_method(int id,void *cm);
 #endif
 
+const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr);
+
 /* TLS extensions functions */
 int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
 
index 6dfde2f8da5950354922f2200e48106d7e035922..a0da7d3741ac112fba250bac6b48168fcf9f2029 100644 (file)
@@ -409,6 +409,8 @@ CERT *ssl_cert_dup(CERT *cert)
                ret->chain_store = cert->chain_store;
                }
 
+       ret->ciphers_raw = NULL;
+
        return(ret);
        
 #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
@@ -511,6 +513,8 @@ void ssl_cert_free(CERT *c)
                X509_STORE_free(c->verify_store);
        if (c->chain_store)
                X509_STORE_free(c->chain_store);
+       if (c->ciphers_raw)
+               OPENSSL_free(c->ciphers_raw);
        OPENSSL_free(c);
        }
 
index 5e1f27c8d899a0574a2a4ce3500e1a7f0b502fc1..35ed940c3a68a232e9cfd3f330f2d8d1aeb08855 100644 (file)
@@ -1933,3 +1933,16 @@ int ssl_cipher_get_cert_index(const SSL_CIPHER *c)
        return -1;
        }
 
+const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr)
+       {
+       const SSL_CIPHER *c;
+       c = ssl->method->get_cipher_by_char(ptr);
+       if (c == NULL || c->valid == 0)
+               return NULL;
+       return c;
+       }
+
+const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr)
+       {
+       return ssl->method->get_cipher_by_char(ptr);
+       }
index 0efb961f016507bd27ad8bdd4ccbb7b0056fb549..1d346cffb374c7c21d182f7e9e71877820f29f8f 100644 (file)
@@ -1132,6 +1132,17 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
                return(s->cert->cert_flags|=larg);
        case SSL_CTRL_CLEAR_CERT_FLAGS:
                return(s->cert->cert_flags &=~larg);
+
+       case SSL_CTRL_GET_RAW_CIPHERLIST:
+               if (parg)
+                       {
+                       if (s->cert->ciphers_raw == NULL)
+                               return 0;
+                       *(unsigned char **)parg = s->cert->ciphers_raw;
+                       return (int)s->cert->ciphers_rawlen;
+                       }
+               else
+                       return ssl_put_cipher_by_char(s,NULL,NULL);
        default:
                return(s->method->ssl_ctrl(s,cmd,larg,parg));
                }
@@ -1471,6 +1482,16 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
                sk_SSL_CIPHER_zero(sk);
                }
 
+       if (s->cert->ciphers_raw)
+               OPENSSL_free(s->cert->ciphers_raw);
+       s->cert->ciphers_raw = BUF_memdup(p, num);
+       if (s->cert->ciphers_raw == NULL)
+               {
+               SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
+               goto err;
+               }
+       s->cert->ciphers_rawlen = (size_t)num;
+
        for (i=0; i<num; i+=n)
                {
                /* Check for SCSV */
index cb72ba3294e53f20f7cea9f57945e1667ff44378..6f68816184e793935d5a399b2006ecd3077c1da5 100644 (file)
@@ -586,6 +586,10 @@ typedef struct cert_st
        X509_STORE *chain_store;
        X509_STORE *verify_store;
 
+       /* Raw values of the cipher list from a client */
+       unsigned char *ciphers_raw;
+       size_t ciphers_rawlen;
+
        int references; /* >1 only if SSL_copy_session_id is used */
        } CERT;
 
@@ -642,8 +646,6 @@ struct tls_sigalgs_st
 #define FP_ICC  (int (*)(const void *,const void *))
 #define ssl_put_cipher_by_char(ssl,ciph,ptr) \
                ((ssl)->method->put_cipher_by_char((ciph),(ptr)))
-#define ssl_get_cipher_by_char(ssl,ptr) \
-               ((ssl)->method->get_cipher_by_char(ptr))
 
 /* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff
  * It is a bit of a mess of functions, but hell, think of it as
@@ -921,6 +923,7 @@ int ssl_cipher_get_evp(const SSL_SESSION *s,const EVP_CIPHER **enc,
                       const EVP_MD **md,int *mac_pkey_type,int *mac_secret_size, SSL_COMP **comp);
 int ssl_get_handshake_digest(int i,long *mask,const EVP_MD **md);
 int ssl_cipher_get_cert_index(const SSL_CIPHER *c);
+const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr);
 int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain);
 int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain);
 int ssl_cert_add0_chain_cert(CERT *c, X509 *x);