Add ctrl and utility functions to retrieve raw cipher list sent by client in

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.
This commit is contained in:
Dr. Stephen Henson 2012-09-12 13:57:48 +00:00
parent 24edfa9df9
commit 94a209d8e1
8 changed files with 55 additions and 10 deletions

View File

@ -4,6 +4,10 @@
Changes between 1.0.x and 1.1.0 [xx XXX xxxx] 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 *) New Suite B modes for TLS code. These use and enforce the requirements
of RFC6460: restrict ciphersuites, only permit Suite B algorithms and 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 only use Suite B curves. The Suite B modes can be set by using the

View 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]; ((unsigned long)p[1]<<8L)|(unsigned long)p[2];
c.id=id; c.id=id;
cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS); cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS);
if ((cp == NULL) || (cp->valid == 0)) return cp;
return NULL;
else
return cp;
} }
int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)

View File

@ -3965,10 +3965,7 @@ const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p)
#ifdef DEBUG_PRINT_UNKNOWN_CIPHERSUITES #ifdef DEBUG_PRINT_UNKNOWN_CIPHERSUITES
if (cp == NULL) fprintf(stderr, "Unknown cipher ID %x\n", (p[0] << 8) | p[1]); if (cp == NULL) fprintf(stderr, "Unknown cipher ID %x\n", (p[0] << 8) | p[1]);
#endif #endif
if (cp == NULL || cp->valid == 0) return cp;
return NULL;
else
return cp;
} }
int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)

View File

@ -1709,6 +1709,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_SET_CHAIN_CERT_STORE 107 #define SSL_CTRL_SET_CHAIN_CERT_STORE 107
#define SSL_CTRL_GET_PEER_SIGNATURE_NID 108 #define SSL_CTRL_GET_PEER_SIGNATURE_NID 108
#define SSL_CTRL_GET_SERVER_TMP_KEY 109 #define SSL_CTRL_GET_SERVER_TMP_KEY 109
#define SSL_CTRL_GET_RAW_CIPHERLIST 110
#define DTLSv1_get_timeout(ssl, arg) \ #define DTLSv1_get_timeout(ssl, arg) \
SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)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) \ #define SSL_get_server_tmp_key(s, pk) \
SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,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 #ifndef OPENSSL_NO_BIO
BIO_METHOD *BIO_f_ssl(void); BIO_METHOD *BIO_f_ssl(void);
BIO *BIO_new_ssl(SSL_CTX *ctx,int client); 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); int SSL_COMP_add_compression_method(int id,void *cm);
#endif #endif
const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr);
/* TLS extensions functions */ /* TLS extensions functions */
int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);

View File

@ -409,6 +409,8 @@ CERT *ssl_cert_dup(CERT *cert)
ret->chain_store = cert->chain_store; ret->chain_store = cert->chain_store;
} }
ret->ciphers_raw = NULL;
return(ret); return(ret);
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH) #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); X509_STORE_free(c->verify_store);
if (c->chain_store) if (c->chain_store)
X509_STORE_free(c->chain_store); X509_STORE_free(c->chain_store);
if (c->ciphers_raw)
OPENSSL_free(c->ciphers_raw);
OPENSSL_free(c); OPENSSL_free(c);
} }

View File

@ -1933,3 +1933,16 @@ int ssl_cipher_get_cert_index(const SSL_CIPHER *c)
return -1; 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);
}

View File

@ -1132,6 +1132,17 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
return(s->cert->cert_flags|=larg); return(s->cert->cert_flags|=larg);
case SSL_CTRL_CLEAR_CERT_FLAGS: case SSL_CTRL_CLEAR_CERT_FLAGS:
return(s->cert->cert_flags &=~larg); 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: default:
return(s->method->ssl_ctrl(s,cmd,larg,parg)); 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); 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) for (i=0; i<num; i+=n)
{ {
/* Check for SCSV */ /* Check for SCSV */

View File

@ -586,6 +586,10 @@ typedef struct cert_st
X509_STORE *chain_store; X509_STORE *chain_store;
X509_STORE *verify_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 */ int references; /* >1 only if SSL_copy_session_id is used */
} CERT; } CERT;
@ -642,8 +646,6 @@ struct tls_sigalgs_st
#define FP_ICC (int (*)(const void *,const void *)) #define FP_ICC (int (*)(const void *,const void *))
#define ssl_put_cipher_by_char(ssl,ciph,ptr) \ #define ssl_put_cipher_by_char(ssl,ciph,ptr) \
((ssl)->method->put_cipher_by_char((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 /* 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 * 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); 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_get_handshake_digest(int i,long *mask,const EVP_MD **md);
int ssl_cipher_get_cert_index(const SSL_CIPHER *c); 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_set0_chain(CERT *c, STACK_OF(X509) *chain);
int ssl_cert_set1_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); int ssl_cert_add0_chain_cert(CERT *c, X509 *x);