summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rw-r--r--ssl/s2_lib.c5
-rw-r--r--ssl/s3_lib.c5
-rw-r--r--ssl/ssl.h6
-rw-r--r--ssl/ssl_cert.c4
-rw-r--r--ssl/ssl_ciph.c13
-rw-r--r--ssl/ssl_lib.c21
-rw-r--r--ssl/ssl_locl.h7
8 files changed, 55 insertions, 10 deletions
diff --git a/CHANGES b/CHANGES
index 3dda962cbe..8e358c69fa 100644
--- 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
diff --git a/ssl/s2_lib.c b/ssl/s2_lib.c
index 9914604109..b37792fcc3 100644
--- a/ssl/s2_lib.c
+++ b/ssl/s2_lib.c
@@ -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)
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index f1e703b873..c8e6d18ab8 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -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)
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 8300bdaf2b..891667827a 100644
--- 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);
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 6dfde2f8da..a0da7d3741 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -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);
}
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index 5e1f27c8d8..35ed940c3a 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -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);
+ }
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 0efb961f01..1d346cffb3 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -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 */
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index cb72ba3294..6f68816184 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -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);