Add ctrl and utility functions to retrieve raw cipher list sent by client in
authorDr. Stephen Henson <steve@openssl.org>
Wed, 26 Dec 2012 16:25:06 +0000 (16:25 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 26 Dec 2012 16:25:06 +0000 (16:25 +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.
(backport from HEAD)

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 4cb7aaac55e615dff72eda9711e570d13bb1b937..0c64d156a111b6ba88d64f72574db70915063135 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -8,6 +8,10 @@
      OID NID.
      [Steve Henson]
 
+  *) 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 088ca05e670d5877aa6edc4f528de6bf63dab39c..f8b3e4a32ae819872f2c8231b51545d7cfd63c01 100644 (file)
@@ -3955,10 +3955,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 0611bf27d31c9be9c92cbc3195f2e41d0663d8ca..5a39e98bb3e399a451afd335647907eb957b7a39 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -1699,6 +1699,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)
@@ -1829,6 +1830,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);
@@ -2231,6 +2235,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 bac2515789ba965648a9aa6770c134452c44a32d..12c0bf2c3d807b7800638b14b46156e9ac4a7758 100644 (file)
@@ -1934,3 +1934,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 6c108aa17e636b2422b8ec9a49b7d79ae6c2cd9f..6e1b27c5fae8a2904b7db63a40745883f37e4449 100644 (file)
@@ -1131,6 +1131,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));
                }
@@ -1470,6 +1481,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 a4689f745fe3c6df7ec1db2c4c5961ca111f173e..500bb6ef76bf91da75a874dda7df85793d26f41b 100644 (file)
@@ -588,6 +588,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;
 
@@ -644,8 +648,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
@@ -923,6 +925,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);