174664626SKris Kennaway /* ssl/ssl_ciph.c */ 274664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 374664626SKris Kennaway * All rights reserved. 474664626SKris Kennaway * 574664626SKris Kennaway * This package is an SSL implementation written 674664626SKris Kennaway * by Eric Young (eay@cryptsoft.com). 774664626SKris Kennaway * The implementation was written so as to conform with Netscapes SSL. 874664626SKris Kennaway * 974664626SKris Kennaway * This library is free for commercial and non-commercial use as long as 1074664626SKris Kennaway * the following conditions are aheared to. The following conditions 1174664626SKris Kennaway * apply to all code found in this distribution, be it the RC4, RSA, 1274664626SKris Kennaway * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1374664626SKris Kennaway * included with this distribution is covered by the same copyright terms 1474664626SKris Kennaway * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1574664626SKris Kennaway * 1674664626SKris Kennaway * Copyright remains Eric Young's, and as such any Copyright notices in 1774664626SKris Kennaway * the code are not to be removed. 1874664626SKris Kennaway * If this package is used in a product, Eric Young should be given attribution 1974664626SKris Kennaway * as the author of the parts of the library used. 2074664626SKris Kennaway * This can be in the form of a textual message at program startup or 2174664626SKris Kennaway * in documentation (online or textual) provided with the package. 2274664626SKris Kennaway * 2374664626SKris Kennaway * Redistribution and use in source and binary forms, with or without 2474664626SKris Kennaway * modification, are permitted provided that the following conditions 2574664626SKris Kennaway * are met: 2674664626SKris Kennaway * 1. Redistributions of source code must retain the copyright 2774664626SKris Kennaway * notice, this list of conditions and the following disclaimer. 2874664626SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 2974664626SKris Kennaway * notice, this list of conditions and the following disclaimer in the 3074664626SKris Kennaway * documentation and/or other materials provided with the distribution. 3174664626SKris Kennaway * 3. All advertising materials mentioning features or use of this software 3274664626SKris Kennaway * must display the following acknowledgement: 3374664626SKris Kennaway * "This product includes cryptographic software written by 3474664626SKris Kennaway * Eric Young (eay@cryptsoft.com)" 3574664626SKris Kennaway * The word 'cryptographic' can be left out if the rouines from the library 3674664626SKris Kennaway * being used are not cryptographic related :-). 3774664626SKris Kennaway * 4. If you include any Windows specific code (or a derivative thereof) from 3874664626SKris Kennaway * the apps directory (application code) you must include an acknowledgement: 3974664626SKris Kennaway * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4074664626SKris Kennaway * 4174664626SKris Kennaway * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4274664626SKris Kennaway * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4374664626SKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4474664626SKris Kennaway * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4574664626SKris Kennaway * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4674664626SKris Kennaway * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4774664626SKris Kennaway * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4874664626SKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4974664626SKris Kennaway * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5074664626SKris Kennaway * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5174664626SKris Kennaway * SUCH DAMAGE. 5274664626SKris Kennaway * 5374664626SKris Kennaway * The licence and distribution terms for any publically available version or 5474664626SKris Kennaway * derivative of this code cannot be changed. i.e. this code cannot simply be 5574664626SKris Kennaway * copied and put under another distribution licence 5674664626SKris Kennaway * [including the GNU Public Licence.] 5774664626SKris Kennaway */ 5874664626SKris Kennaway 5974664626SKris Kennaway #include <stdio.h> 6074664626SKris Kennaway #include <openssl/objects.h> 6174664626SKris Kennaway #include <openssl/comp.h> 6274664626SKris Kennaway #include "ssl_locl.h" 6374664626SKris Kennaway 6474664626SKris Kennaway #define SSL_ENC_DES_IDX 0 6574664626SKris Kennaway #define SSL_ENC_3DES_IDX 1 6674664626SKris Kennaway #define SSL_ENC_RC4_IDX 2 6774664626SKris Kennaway #define SSL_ENC_RC2_IDX 3 6874664626SKris Kennaway #define SSL_ENC_IDEA_IDX 4 6974664626SKris Kennaway #define SSL_ENC_eFZA_IDX 5 7074664626SKris Kennaway #define SSL_ENC_NULL_IDX 6 7174664626SKris Kennaway #define SSL_ENC_NUM_IDX 7 7274664626SKris Kennaway 7374664626SKris Kennaway static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={ 7474664626SKris Kennaway NULL,NULL,NULL,NULL,NULL,NULL, 7574664626SKris Kennaway }; 7674664626SKris Kennaway 7774664626SKris Kennaway static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL; 7874664626SKris Kennaway 7974664626SKris Kennaway #define SSL_MD_MD5_IDX 0 8074664626SKris Kennaway #define SSL_MD_SHA1_IDX 1 8174664626SKris Kennaway #define SSL_MD_NUM_IDX 2 8274664626SKris Kennaway static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={ 8374664626SKris Kennaway NULL,NULL, 8474664626SKris Kennaway }; 8574664626SKris Kennaway 8674664626SKris Kennaway #define CIPHER_ADD 1 8774664626SKris Kennaway #define CIPHER_KILL 2 8874664626SKris Kennaway #define CIPHER_DEL 3 8974664626SKris Kennaway #define CIPHER_ORD 4 90f579bf8eSKris Kennaway #define CIPHER_SPECIAL 5 9174664626SKris Kennaway 9274664626SKris Kennaway typedef struct cipher_order_st 9374664626SKris Kennaway { 9474664626SKris Kennaway SSL_CIPHER *cipher; 9574664626SKris Kennaway int active; 9674664626SKris Kennaway int dead; 9774664626SKris Kennaway struct cipher_order_st *next,*prev; 9874664626SKris Kennaway } CIPHER_ORDER; 9974664626SKris Kennaway 100f579bf8eSKris Kennaway static const SSL_CIPHER cipher_aliases[]={ 10174664626SKris Kennaway /* Don't include eNULL unless specifically enabled */ 102f579bf8eSKris Kennaway {0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL, SSL_ALL ,0,0,0,SSL_ALL,SSL_ALL}, /* must be first */ 103f579bf8eSKris Kennaway {0,SSL_TXT_kRSA,0,SSL_kRSA, 0,0,0,0,SSL_MKEY_MASK,0}, 104f579bf8eSKris Kennaway {0,SSL_TXT_kDHr,0,SSL_kDHr, 0,0,0,0,SSL_MKEY_MASK,0}, 105f579bf8eSKris Kennaway {0,SSL_TXT_kDHd,0,SSL_kDHd, 0,0,0,0,SSL_MKEY_MASK,0}, 106f579bf8eSKris Kennaway {0,SSL_TXT_kEDH,0,SSL_kEDH, 0,0,0,0,SSL_MKEY_MASK,0}, 107f579bf8eSKris Kennaway {0,SSL_TXT_kFZA,0,SSL_kFZA, 0,0,0,0,SSL_MKEY_MASK,0}, 108f579bf8eSKris Kennaway {0,SSL_TXT_DH, 0,SSL_DH, 0,0,0,0,SSL_MKEY_MASK,0}, 109f579bf8eSKris Kennaway {0,SSL_TXT_EDH, 0,SSL_EDH, 0,0,0,0,SSL_MKEY_MASK|SSL_AUTH_MASK,0}, 11074664626SKris Kennaway 111f579bf8eSKris Kennaway {0,SSL_TXT_aRSA,0,SSL_aRSA, 0,0,0,0,SSL_AUTH_MASK,0}, 112f579bf8eSKris Kennaway {0,SSL_TXT_aDSS,0,SSL_aDSS, 0,0,0,0,SSL_AUTH_MASK,0}, 113f579bf8eSKris Kennaway {0,SSL_TXT_aFZA,0,SSL_aFZA, 0,0,0,0,SSL_AUTH_MASK,0}, 114f579bf8eSKris Kennaway {0,SSL_TXT_aNULL,0,SSL_aNULL,0,0,0,0,SSL_AUTH_MASK,0}, 115f579bf8eSKris Kennaway {0,SSL_TXT_aDH, 0,SSL_aDH, 0,0,0,0,SSL_AUTH_MASK,0}, 116f579bf8eSKris Kennaway {0,SSL_TXT_DSS, 0,SSL_DSS, 0,0,0,0,SSL_AUTH_MASK,0}, 11774664626SKris Kennaway 118f579bf8eSKris Kennaway {0,SSL_TXT_DES, 0,SSL_DES, 0,0,0,0,SSL_ENC_MASK,0}, 119f579bf8eSKris Kennaway {0,SSL_TXT_3DES,0,SSL_3DES, 0,0,0,0,SSL_ENC_MASK,0}, 120f579bf8eSKris Kennaway {0,SSL_TXT_RC4, 0,SSL_RC4, 0,0,0,0,SSL_ENC_MASK,0}, 121f579bf8eSKris Kennaway {0,SSL_TXT_RC2, 0,SSL_RC2, 0,0,0,0,SSL_ENC_MASK,0}, 122f579bf8eSKris Kennaway {0,SSL_TXT_IDEA,0,SSL_IDEA, 0,0,0,0,SSL_ENC_MASK,0}, 123f579bf8eSKris Kennaway {0,SSL_TXT_eNULL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0}, 124f579bf8eSKris Kennaway {0,SSL_TXT_eFZA,0,SSL_eFZA, 0,0,0,0,SSL_ENC_MASK,0}, 12574664626SKris Kennaway 126f579bf8eSKris Kennaway {0,SSL_TXT_MD5, 0,SSL_MD5, 0,0,0,0,SSL_MAC_MASK,0}, 127f579bf8eSKris Kennaway {0,SSL_TXT_SHA1,0,SSL_SHA1, 0,0,0,0,SSL_MAC_MASK,0}, 128f579bf8eSKris Kennaway {0,SSL_TXT_SHA, 0,SSL_SHA, 0,0,0,0,SSL_MAC_MASK,0}, 12974664626SKris Kennaway 130f579bf8eSKris Kennaway {0,SSL_TXT_NULL,0,SSL_NULL, 0,0,0,0,SSL_ENC_MASK,0}, 131f579bf8eSKris Kennaway {0,SSL_TXT_RSA, 0,SSL_RSA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, 132f579bf8eSKris Kennaway {0,SSL_TXT_ADH, 0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, 133f579bf8eSKris Kennaway {0,SSL_TXT_FZA, 0,SSL_FZA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK|SSL_ENC_MASK,0}, 13474664626SKris Kennaway 135f579bf8eSKris Kennaway {0,SSL_TXT_SSLV2, 0,SSL_SSLV2, 0,0,0,0,SSL_SSL_MASK,0}, 136f579bf8eSKris Kennaway {0,SSL_TXT_SSLV3, 0,SSL_SSLV3, 0,0,0,0,SSL_SSL_MASK,0}, 137f579bf8eSKris Kennaway {0,SSL_TXT_TLSV1, 0,SSL_TLSV1, 0,0,0,0,SSL_SSL_MASK,0}, 138f579bf8eSKris Kennaway 139f579bf8eSKris Kennaway {0,SSL_TXT_EXP ,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK}, 140f579bf8eSKris Kennaway {0,SSL_TXT_EXPORT,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK}, 141f579bf8eSKris Kennaway {0,SSL_TXT_EXP40, 0, 0, SSL_EXP40, 0,0,0,0,SSL_STRONG_MASK}, 142f579bf8eSKris Kennaway {0,SSL_TXT_EXP56, 0, 0, SSL_EXP56, 0,0,0,0,SSL_STRONG_MASK}, 143f579bf8eSKris Kennaway {0,SSL_TXT_LOW, 0, 0, SSL_LOW, 0,0,0,0,SSL_STRONG_MASK}, 144f579bf8eSKris Kennaway {0,SSL_TXT_MEDIUM,0, 0,SSL_MEDIUM, 0,0,0,0,SSL_STRONG_MASK}, 145f579bf8eSKris Kennaway {0,SSL_TXT_HIGH, 0, 0, SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK}, 14674664626SKris Kennaway }; 14774664626SKris Kennaway 14874664626SKris Kennaway static int init_ciphers=1; 14974664626SKris Kennaway 15074664626SKris Kennaway static void load_ciphers(void) 15174664626SKris Kennaway { 15274664626SKris Kennaway init_ciphers=0; 15374664626SKris Kennaway ssl_cipher_methods[SSL_ENC_DES_IDX]= 15474664626SKris Kennaway EVP_get_cipherbyname(SN_des_cbc); 15574664626SKris Kennaway ssl_cipher_methods[SSL_ENC_3DES_IDX]= 15674664626SKris Kennaway EVP_get_cipherbyname(SN_des_ede3_cbc); 15774664626SKris Kennaway ssl_cipher_methods[SSL_ENC_RC4_IDX]= 15874664626SKris Kennaway EVP_get_cipherbyname(SN_rc4); 15974664626SKris Kennaway ssl_cipher_methods[SSL_ENC_RC2_IDX]= 16074664626SKris Kennaway EVP_get_cipherbyname(SN_rc2_cbc); 16174664626SKris Kennaway ssl_cipher_methods[SSL_ENC_IDEA_IDX]= 16274664626SKris Kennaway EVP_get_cipherbyname(SN_idea_cbc); 16374664626SKris Kennaway 16474664626SKris Kennaway ssl_digest_methods[SSL_MD_MD5_IDX]= 16574664626SKris Kennaway EVP_get_digestbyname(SN_md5); 16674664626SKris Kennaway ssl_digest_methods[SSL_MD_SHA1_IDX]= 16774664626SKris Kennaway EVP_get_digestbyname(SN_sha1); 16874664626SKris Kennaway } 16974664626SKris Kennaway 17074664626SKris Kennaway int ssl_cipher_get_evp(SSL_SESSION *s, const EVP_CIPHER **enc, 17174664626SKris Kennaway const EVP_MD **md, SSL_COMP **comp) 17274664626SKris Kennaway { 17374664626SKris Kennaway int i; 17474664626SKris Kennaway SSL_CIPHER *c; 17574664626SKris Kennaway 17674664626SKris Kennaway c=s->cipher; 17774664626SKris Kennaway if (c == NULL) return(0); 17874664626SKris Kennaway if (comp != NULL) 17974664626SKris Kennaway { 18074664626SKris Kennaway SSL_COMP ctmp; 18174664626SKris Kennaway 18274664626SKris Kennaway if (s->compress_meth == 0) 18374664626SKris Kennaway *comp=NULL; 18474664626SKris Kennaway else if (ssl_comp_methods == NULL) 18574664626SKris Kennaway { 18674664626SKris Kennaway /* bad */ 18774664626SKris Kennaway *comp=NULL; 18874664626SKris Kennaway } 18974664626SKris Kennaway else 19074664626SKris Kennaway { 19174664626SKris Kennaway 19274664626SKris Kennaway ctmp.id=s->compress_meth; 19374664626SKris Kennaway i=sk_SSL_COMP_find(ssl_comp_methods,&ctmp); 19474664626SKris Kennaway if (i >= 0) 19574664626SKris Kennaway *comp=sk_SSL_COMP_value(ssl_comp_methods,i); 19674664626SKris Kennaway else 19774664626SKris Kennaway *comp=NULL; 19874664626SKris Kennaway } 19974664626SKris Kennaway } 20074664626SKris Kennaway 20174664626SKris Kennaway if ((enc == NULL) || (md == NULL)) return(0); 20274664626SKris Kennaway 20374664626SKris Kennaway switch (c->algorithms & SSL_ENC_MASK) 20474664626SKris Kennaway { 20574664626SKris Kennaway case SSL_DES: 20674664626SKris Kennaway i=SSL_ENC_DES_IDX; 20774664626SKris Kennaway break; 20874664626SKris Kennaway case SSL_3DES: 20974664626SKris Kennaway i=SSL_ENC_3DES_IDX; 21074664626SKris Kennaway break; 21174664626SKris Kennaway case SSL_RC4: 21274664626SKris Kennaway i=SSL_ENC_RC4_IDX; 21374664626SKris Kennaway break; 21474664626SKris Kennaway case SSL_RC2: 21574664626SKris Kennaway i=SSL_ENC_RC2_IDX; 21674664626SKris Kennaway break; 21774664626SKris Kennaway case SSL_IDEA: 21874664626SKris Kennaway i=SSL_ENC_IDEA_IDX; 21974664626SKris Kennaway break; 22074664626SKris Kennaway case SSL_eNULL: 22174664626SKris Kennaway i=SSL_ENC_NULL_IDX; 22274664626SKris Kennaway break; 22374664626SKris Kennaway default: 22474664626SKris Kennaway i= -1; 22574664626SKris Kennaway break; 22674664626SKris Kennaway } 22774664626SKris Kennaway 22874664626SKris Kennaway if ((i < 0) || (i > SSL_ENC_NUM_IDX)) 22974664626SKris Kennaway *enc=NULL; 23074664626SKris Kennaway else 23174664626SKris Kennaway { 23274664626SKris Kennaway if (i == SSL_ENC_NULL_IDX) 23374664626SKris Kennaway *enc=EVP_enc_null(); 23474664626SKris Kennaway else 23574664626SKris Kennaway *enc=ssl_cipher_methods[i]; 23674664626SKris Kennaway } 23774664626SKris Kennaway 23874664626SKris Kennaway switch (c->algorithms & SSL_MAC_MASK) 23974664626SKris Kennaway { 24074664626SKris Kennaway case SSL_MD5: 24174664626SKris Kennaway i=SSL_MD_MD5_IDX; 24274664626SKris Kennaway break; 24374664626SKris Kennaway case SSL_SHA1: 24474664626SKris Kennaway i=SSL_MD_SHA1_IDX; 24574664626SKris Kennaway break; 24674664626SKris Kennaway default: 24774664626SKris Kennaway i= -1; 24874664626SKris Kennaway break; 24974664626SKris Kennaway } 25074664626SKris Kennaway if ((i < 0) || (i > SSL_MD_NUM_IDX)) 25174664626SKris Kennaway *md=NULL; 25274664626SKris Kennaway else 25374664626SKris Kennaway *md=ssl_digest_methods[i]; 25474664626SKris Kennaway 25574664626SKris Kennaway if ((*enc != NULL) && (*md != NULL)) 25674664626SKris Kennaway return(1); 25774664626SKris Kennaway else 25874664626SKris Kennaway return(0); 25974664626SKris Kennaway } 26074664626SKris Kennaway 26174664626SKris Kennaway #define ITEM_SEP(a) \ 26274664626SKris Kennaway (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) 26374664626SKris Kennaway 26474664626SKris Kennaway static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, 26574664626SKris Kennaway CIPHER_ORDER **tail) 26674664626SKris Kennaway { 26774664626SKris Kennaway if (curr == *tail) return; 26874664626SKris Kennaway if (curr == *head) 26974664626SKris Kennaway *head=curr->next; 27074664626SKris Kennaway if (curr->prev != NULL) 27174664626SKris Kennaway curr->prev->next=curr->next; 27274664626SKris Kennaway if (curr->next != NULL) /* should always be true */ 27374664626SKris Kennaway curr->next->prev=curr->prev; 27474664626SKris Kennaway (*tail)->next=curr; 27574664626SKris Kennaway curr->prev= *tail; 27674664626SKris Kennaway curr->next=NULL; 27774664626SKris Kennaway *tail=curr; 27874664626SKris Kennaway } 27974664626SKris Kennaway 280f579bf8eSKris Kennaway static unsigned long ssl_cipher_get_disabled(void) 28174664626SKris Kennaway { 282f579bf8eSKris Kennaway unsigned long mask; 28374664626SKris Kennaway 28474664626SKris Kennaway mask = SSL_kFZA; 28574664626SKris Kennaway #ifdef NO_RSA 28674664626SKris Kennaway mask |= SSL_aRSA|SSL_kRSA; 28774664626SKris Kennaway #endif 28874664626SKris Kennaway #ifdef NO_DSA 28974664626SKris Kennaway mask |= SSL_aDSS; 29074664626SKris Kennaway #endif 29174664626SKris Kennaway #ifdef NO_DH 29274664626SKris Kennaway mask |= SSL_kDHr|SSL_kDHd|SSL_kEDH|SSL_aDH; 29374664626SKris Kennaway #endif 29474664626SKris Kennaway 29574664626SKris Kennaway #ifdef SSL_FORBID_ENULL 29674664626SKris Kennaway mask |= SSL_eNULL; 29774664626SKris Kennaway #endif 29874664626SKris Kennaway 29974664626SKris Kennaway mask |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0; 30074664626SKris Kennaway mask |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0; 30174664626SKris Kennaway mask |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0; 30274664626SKris Kennaway mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0; 30374664626SKris Kennaway mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0; 30474664626SKris Kennaway mask |= (ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL) ? SSL_eFZA:0; 30574664626SKris Kennaway 30674664626SKris Kennaway mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0; 30774664626SKris Kennaway mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0; 30874664626SKris Kennaway 309f579bf8eSKris Kennaway return(mask); 310f579bf8eSKris Kennaway } 311f579bf8eSKris Kennaway 312f579bf8eSKris Kennaway static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, 313f579bf8eSKris Kennaway int num_of_ciphers, unsigned long mask, CIPHER_ORDER *list, 314f579bf8eSKris Kennaway CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) 315f579bf8eSKris Kennaway { 316f579bf8eSKris Kennaway int i, list_num; 317f579bf8eSKris Kennaway SSL_CIPHER *c; 318f579bf8eSKris Kennaway 319f579bf8eSKris Kennaway /* 320f579bf8eSKris Kennaway * We have num_of_ciphers descriptions compiled in, depending on the 321f579bf8eSKris Kennaway * method selected (SSLv2 and/or SSLv3, TLSv1 etc). 322f579bf8eSKris Kennaway * These will later be sorted in a linked list with at most num 323f579bf8eSKris Kennaway * entries. 324f579bf8eSKris Kennaway */ 32574664626SKris Kennaway 32674664626SKris Kennaway /* Get the initial list of ciphers */ 327f579bf8eSKris Kennaway list_num = 0; /* actual count of ciphers */ 328f579bf8eSKris Kennaway for (i = 0; i < num_of_ciphers; i++) 32974664626SKris Kennaway { 330f579bf8eSKris Kennaway c = ssl_method->get_cipher(i); 33174664626SKris Kennaway /* drop those that use any of that is not available */ 33274664626SKris Kennaway if ((c != NULL) && c->valid && !(c->algorithms & mask)) 33374664626SKris Kennaway { 33474664626SKris Kennaway list[list_num].cipher = c; 33574664626SKris Kennaway list[list_num].next = NULL; 33674664626SKris Kennaway list[list_num].prev = NULL; 33774664626SKris Kennaway list[list_num].active = 0; 33874664626SKris Kennaway list_num++; 339f579bf8eSKris Kennaway /* 34074664626SKris Kennaway if (!sk_push(ca_list,(char *)c)) goto err; 341f579bf8eSKris Kennaway */ 34274664626SKris Kennaway } 34374664626SKris Kennaway } 34474664626SKris Kennaway 345f579bf8eSKris Kennaway /* 346f579bf8eSKris Kennaway * Prepare linked list from list entries 347f579bf8eSKris Kennaway */ 34874664626SKris Kennaway for (i = 1; i < list_num - 1; i++) 34974664626SKris Kennaway { 35074664626SKris Kennaway list[i].prev = &(list[i-1]); 35174664626SKris Kennaway list[i].next = &(list[i+1]); 35274664626SKris Kennaway } 35374664626SKris Kennaway if (list_num > 0) 35474664626SKris Kennaway { 355f579bf8eSKris Kennaway (*head_p) = &(list[0]); 356f579bf8eSKris Kennaway (*head_p)->prev = NULL; 357f579bf8eSKris Kennaway (*head_p)->next = &(list[1]); 358f579bf8eSKris Kennaway (*tail_p) = &(list[list_num - 1]); 359f579bf8eSKris Kennaway (*tail_p)->prev = &(list[list_num - 2]); 360f579bf8eSKris Kennaway (*tail_p)->next = NULL; 361f579bf8eSKris Kennaway } 36274664626SKris Kennaway } 36374664626SKris Kennaway 364f579bf8eSKris Kennaway static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list, 365f579bf8eSKris Kennaway int num_of_group_aliases, unsigned long mask, 366f579bf8eSKris Kennaway CIPHER_ORDER *head) 36774664626SKris Kennaway { 368f579bf8eSKris Kennaway CIPHER_ORDER *ciph_curr; 369f579bf8eSKris Kennaway SSL_CIPHER **ca_curr; 370f579bf8eSKris Kennaway int i; 371f579bf8eSKris Kennaway 372f579bf8eSKris Kennaway /* 373f579bf8eSKris Kennaway * First, add the real ciphers as already collected 374f579bf8eSKris Kennaway */ 375f579bf8eSKris Kennaway ciph_curr = head; 376f579bf8eSKris Kennaway ca_curr = ca_list; 377f579bf8eSKris Kennaway while (ciph_curr != NULL) 378f579bf8eSKris Kennaway { 379f579bf8eSKris Kennaway *ca_curr = ciph_curr->cipher; 380f579bf8eSKris Kennaway ca_curr++; 381f579bf8eSKris Kennaway ciph_curr = ciph_curr->next; 38274664626SKris Kennaway } 38374664626SKris Kennaway 384f579bf8eSKris Kennaway /* 385f579bf8eSKris Kennaway * Now we add the available ones from the cipher_aliases[] table. 386f579bf8eSKris Kennaway * They represent either an algorithm, that must be fully 387f579bf8eSKris Kennaway * supported (not match any bit in mask) or represent a cipher 388f579bf8eSKris Kennaway * strength value (will be added in any case because algorithms=0). 389f579bf8eSKris Kennaway */ 390f579bf8eSKris Kennaway for (i = 0; i < num_of_group_aliases; i++) 39174664626SKris Kennaway { 392f579bf8eSKris Kennaway if ((i == 0) || /* always fetch "ALL" */ 393f579bf8eSKris Kennaway !(cipher_aliases[i].algorithms & mask)) 39474664626SKris Kennaway { 395f579bf8eSKris Kennaway *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); 396f579bf8eSKris Kennaway ca_curr++; 39774664626SKris Kennaway } 398f579bf8eSKris Kennaway } 39974664626SKris Kennaway 400f579bf8eSKris Kennaway *ca_curr = NULL; /* end of list */ 401f579bf8eSKris Kennaway } 402f579bf8eSKris Kennaway 403f579bf8eSKris Kennaway static void ssl_cipher_apply_rule(unsigned long algorithms, unsigned long mask, 404f579bf8eSKris Kennaway unsigned long algo_strength, unsigned long mask_strength, 405f579bf8eSKris Kennaway int rule, int strength_bits, CIPHER_ORDER *list, 406f579bf8eSKris Kennaway CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) 40774664626SKris Kennaway { 408f579bf8eSKris Kennaway CIPHER_ORDER *head, *tail, *curr, *curr2, *tail2; 409f579bf8eSKris Kennaway SSL_CIPHER *cp; 410f579bf8eSKris Kennaway unsigned long ma, ma_s; 411f579bf8eSKris Kennaway 412f579bf8eSKris Kennaway #ifdef CIPHER_DEBUG 413f579bf8eSKris Kennaway printf("Applying rule %d with %08lx %08lx %08lx %08lx (%d)\n", 414f579bf8eSKris Kennaway rule, algorithms, mask, algo_strength, mask_strength, 415f579bf8eSKris Kennaway strength_bits); 41674664626SKris Kennaway #endif 41774664626SKris Kennaway 418f579bf8eSKris Kennaway curr = head = *head_p; 41974664626SKris Kennaway curr2 = head; 420f579bf8eSKris Kennaway tail2 = tail = *tail_p; 42174664626SKris Kennaway for (;;) 42274664626SKris Kennaway { 42374664626SKris Kennaway if ((curr == NULL) || (curr == tail2)) break; 42474664626SKris Kennaway curr = curr2; 42574664626SKris Kennaway curr2 = curr->next; 42674664626SKris Kennaway 42774664626SKris Kennaway cp = curr->cipher; 428f579bf8eSKris Kennaway 429f579bf8eSKris Kennaway /* 430f579bf8eSKris Kennaway * Selection criteria is either the number of strength_bits 431f579bf8eSKris Kennaway * or the algorithm used. 432f579bf8eSKris Kennaway */ 433f579bf8eSKris Kennaway if (strength_bits == -1) 43474664626SKris Kennaway { 435f579bf8eSKris Kennaway ma = mask & cp->algorithms; 436f579bf8eSKris Kennaway ma_s = mask_strength & cp->algo_strength; 437f579bf8eSKris Kennaway 438f579bf8eSKris Kennaway #ifdef CIPHER_DEBUG 439f579bf8eSKris Kennaway printf("\nName: %s:\nAlgo = %08lx Algo_strength = %08lx\nMask = %08lx Mask_strength %08lx\n", cp->name, cp->algorithms, cp->algo_strength, mask, mask_strength); 440f579bf8eSKris Kennaway printf("ma = %08lx ma_s %08lx, ma&algo=%08lx, ma_s&algos=%08lx\n", ma, ma_s, ma&algorithms, ma_s&algo_strength); 441f579bf8eSKris Kennaway #endif 442f579bf8eSKris Kennaway /* 443f579bf8eSKris Kennaway * Select: if none of the mask bit was met from the 444f579bf8eSKris Kennaway * cipher or not all of the bits were met, the 445f579bf8eSKris Kennaway * selection does not apply. 446f579bf8eSKris Kennaway */ 447f579bf8eSKris Kennaway if (((ma == 0) && (ma_s == 0)) || 448f579bf8eSKris Kennaway ((ma & algorithms) != ma) || 449f579bf8eSKris Kennaway ((ma_s & algo_strength) != ma_s)) 450f579bf8eSKris Kennaway continue; /* does not apply */ 45174664626SKris Kennaway } 452f579bf8eSKris Kennaway else if (strength_bits != cp->strength_bits) 453f579bf8eSKris Kennaway continue; /* does not apply */ 454f579bf8eSKris Kennaway 455f579bf8eSKris Kennaway #ifdef CIPHER_DEBUG 456f579bf8eSKris Kennaway printf("Action = %d\n", rule); 457f579bf8eSKris Kennaway #endif 45874664626SKris Kennaway 45974664626SKris Kennaway /* add the cipher if it has not been added yet. */ 460f579bf8eSKris Kennaway if (rule == CIPHER_ADD) 46174664626SKris Kennaway { 46274664626SKris Kennaway if (!curr->active) 46374664626SKris Kennaway { 46474664626SKris Kennaway ll_append_tail(&head, curr, &tail); 46574664626SKris Kennaway curr->active = 1; 46674664626SKris Kennaway } 46774664626SKris Kennaway } 46874664626SKris Kennaway /* Move the added cipher to this location */ 469f579bf8eSKris Kennaway else if (rule == CIPHER_ORD) 47074664626SKris Kennaway { 47174664626SKris Kennaway if (curr->active) 47274664626SKris Kennaway { 47374664626SKris Kennaway ll_append_tail(&head, curr, &tail); 47474664626SKris Kennaway } 47574664626SKris Kennaway } 476f579bf8eSKris Kennaway else if (rule == CIPHER_DEL) 47774664626SKris Kennaway curr->active = 0; 478f579bf8eSKris Kennaway else if (rule == CIPHER_KILL) 47974664626SKris Kennaway { 48074664626SKris Kennaway if (head == curr) 48174664626SKris Kennaway head = curr->next; 48274664626SKris Kennaway else 48374664626SKris Kennaway curr->prev->next = curr->next; 48474664626SKris Kennaway if (tail == curr) 48574664626SKris Kennaway tail = curr->prev; 48674664626SKris Kennaway curr->active = 0; 48774664626SKris Kennaway if (curr->next != NULL) 48874664626SKris Kennaway curr->next->prev = curr->prev; 48974664626SKris Kennaway if (curr->prev != NULL) 49074664626SKris Kennaway curr->prev->next = curr->next; 49174664626SKris Kennaway curr->next = NULL; 49274664626SKris Kennaway curr->prev = NULL; 49374664626SKris Kennaway } 49474664626SKris Kennaway } 495f579bf8eSKris Kennaway 496f579bf8eSKris Kennaway *head_p = head; 497f579bf8eSKris Kennaway *tail_p = tail; 49874664626SKris Kennaway } 49974664626SKris Kennaway 500f579bf8eSKris Kennaway static int ssl_cipher_strength_sort(CIPHER_ORDER *list, CIPHER_ORDER **head_p, 501f579bf8eSKris Kennaway CIPHER_ORDER **tail_p) 502f579bf8eSKris Kennaway { 503f579bf8eSKris Kennaway int max_strength_bits, i, *number_uses; 504f579bf8eSKris Kennaway CIPHER_ORDER *curr; 505f579bf8eSKris Kennaway 506f579bf8eSKris Kennaway /* 507f579bf8eSKris Kennaway * This routine sorts the ciphers with descending strength. The sorting 508f579bf8eSKris Kennaway * must keep the pre-sorted sequence, so we apply the normal sorting 509f579bf8eSKris Kennaway * routine as '+' movement to the end of the list. 510f579bf8eSKris Kennaway */ 511f579bf8eSKris Kennaway max_strength_bits = 0; 512f579bf8eSKris Kennaway curr = *head_p; 513f579bf8eSKris Kennaway while (curr != NULL) 514f579bf8eSKris Kennaway { 515f579bf8eSKris Kennaway if (curr->active && 516f579bf8eSKris Kennaway (curr->cipher->strength_bits > max_strength_bits)) 517f579bf8eSKris Kennaway max_strength_bits = curr->cipher->strength_bits; 518f579bf8eSKris Kennaway curr = curr->next; 519f579bf8eSKris Kennaway } 520f579bf8eSKris Kennaway 521ddd58736SKris Kennaway number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int)); 522f579bf8eSKris Kennaway if (!number_uses) 523f579bf8eSKris Kennaway { 524f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT,ERR_R_MALLOC_FAILURE); 525f579bf8eSKris Kennaway return(0); 526f579bf8eSKris Kennaway } 527f579bf8eSKris Kennaway memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int)); 528f579bf8eSKris Kennaway 529f579bf8eSKris Kennaway /* 530f579bf8eSKris Kennaway * Now find the strength_bits values actually used 531f579bf8eSKris Kennaway */ 532f579bf8eSKris Kennaway curr = *head_p; 533f579bf8eSKris Kennaway while (curr != NULL) 534f579bf8eSKris Kennaway { 535f579bf8eSKris Kennaway if (curr->active) 536f579bf8eSKris Kennaway number_uses[curr->cipher->strength_bits]++; 537f579bf8eSKris Kennaway curr = curr->next; 538f579bf8eSKris Kennaway } 539f579bf8eSKris Kennaway /* 540f579bf8eSKris Kennaway * Go through the list of used strength_bits values in descending 541f579bf8eSKris Kennaway * order. 542f579bf8eSKris Kennaway */ 543f579bf8eSKris Kennaway for (i = max_strength_bits; i >= 0; i--) 544f579bf8eSKris Kennaway if (number_uses[i] > 0) 545f579bf8eSKris Kennaway ssl_cipher_apply_rule(0, 0, 0, 0, CIPHER_ORD, i, 546f579bf8eSKris Kennaway list, head_p, tail_p); 547f579bf8eSKris Kennaway 548ddd58736SKris Kennaway OPENSSL_free(number_uses); 549f579bf8eSKris Kennaway return(1); 550f579bf8eSKris Kennaway } 551f579bf8eSKris Kennaway 552f579bf8eSKris Kennaway static int ssl_cipher_process_rulestr(const char *rule_str, 553f579bf8eSKris Kennaway CIPHER_ORDER *list, CIPHER_ORDER **head_p, 554f579bf8eSKris Kennaway CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list) 555f579bf8eSKris Kennaway { 556f579bf8eSKris Kennaway unsigned long algorithms, mask, algo_strength, mask_strength; 557f579bf8eSKris Kennaway const char *l, *start, *buf; 558f579bf8eSKris Kennaway int j, multi, found, rule, retval, ok, buflen; 559f579bf8eSKris Kennaway char ch; 560f579bf8eSKris Kennaway 561f579bf8eSKris Kennaway retval = 1; 562f579bf8eSKris Kennaway l = rule_str; 563f579bf8eSKris Kennaway for (;;) 564f579bf8eSKris Kennaway { 565f579bf8eSKris Kennaway ch = *l; 566f579bf8eSKris Kennaway 567f579bf8eSKris Kennaway if (ch == '\0') 568f579bf8eSKris Kennaway break; /* done */ 569f579bf8eSKris Kennaway if (ch == '-') 570f579bf8eSKris Kennaway { rule = CIPHER_DEL; l++; } 571f579bf8eSKris Kennaway else if (ch == '+') 572f579bf8eSKris Kennaway { rule = CIPHER_ORD; l++; } 573f579bf8eSKris Kennaway else if (ch == '!') 574f579bf8eSKris Kennaway { rule = CIPHER_KILL; l++; } 575f579bf8eSKris Kennaway else if (ch == '@') 576f579bf8eSKris Kennaway { rule = CIPHER_SPECIAL; l++; } 577f579bf8eSKris Kennaway else 578f579bf8eSKris Kennaway { rule = CIPHER_ADD; } 579f579bf8eSKris Kennaway 580f579bf8eSKris Kennaway if (ITEM_SEP(ch)) 581f579bf8eSKris Kennaway { 582f579bf8eSKris Kennaway l++; 583f579bf8eSKris Kennaway continue; 584f579bf8eSKris Kennaway } 585f579bf8eSKris Kennaway 586f579bf8eSKris Kennaway algorithms = mask = algo_strength = mask_strength = 0; 587f579bf8eSKris Kennaway 588f579bf8eSKris Kennaway start=l; 589f579bf8eSKris Kennaway for (;;) 590f579bf8eSKris Kennaway { 591f579bf8eSKris Kennaway ch = *l; 592f579bf8eSKris Kennaway buf = l; 593f579bf8eSKris Kennaway buflen = 0; 594f579bf8eSKris Kennaway #ifndef CHARSET_EBCDIC 595f579bf8eSKris Kennaway while ( ((ch >= 'A') && (ch <= 'Z')) || 596f579bf8eSKris Kennaway ((ch >= '0') && (ch <= '9')) || 597f579bf8eSKris Kennaway ((ch >= 'a') && (ch <= 'z')) || 598f579bf8eSKris Kennaway (ch == '-')) 599f579bf8eSKris Kennaway #else 600f579bf8eSKris Kennaway while ( isalnum(ch) || (ch == '-')) 601f579bf8eSKris Kennaway #endif 602f579bf8eSKris Kennaway { 603f579bf8eSKris Kennaway ch = *(++l); 604f579bf8eSKris Kennaway buflen++; 605f579bf8eSKris Kennaway } 606f579bf8eSKris Kennaway 607f579bf8eSKris Kennaway if (buflen == 0) 608f579bf8eSKris Kennaway { 609f579bf8eSKris Kennaway /* 610f579bf8eSKris Kennaway * We hit something we cannot deal with, 611f579bf8eSKris Kennaway * it is no command or separator nor 612f579bf8eSKris Kennaway * alphanumeric, so we call this an error. 613f579bf8eSKris Kennaway */ 614f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, 615f579bf8eSKris Kennaway SSL_R_INVALID_COMMAND); 616f579bf8eSKris Kennaway retval = found = 0; 617f579bf8eSKris Kennaway l++; 618f579bf8eSKris Kennaway break; 619f579bf8eSKris Kennaway } 620f579bf8eSKris Kennaway 621f579bf8eSKris Kennaway if (rule == CIPHER_SPECIAL) 622f579bf8eSKris Kennaway { 623f579bf8eSKris Kennaway found = 0; /* unused -- avoid compiler warning */ 624f579bf8eSKris Kennaway break; /* special treatment */ 625f579bf8eSKris Kennaway } 626f579bf8eSKris Kennaway 627f579bf8eSKris Kennaway /* check for multi-part specification */ 628f579bf8eSKris Kennaway if (ch == '+') 629f579bf8eSKris Kennaway { 630f579bf8eSKris Kennaway multi=1; 631f579bf8eSKris Kennaway l++; 632f579bf8eSKris Kennaway } 633f579bf8eSKris Kennaway else 634f579bf8eSKris Kennaway multi=0; 635f579bf8eSKris Kennaway 636f579bf8eSKris Kennaway /* 637f579bf8eSKris Kennaway * Now search for the cipher alias in the ca_list. Be careful 638f579bf8eSKris Kennaway * with the strncmp, because the "buflen" limitation 639f579bf8eSKris Kennaway * will make the rule "ADH:SOME" and the cipher 640f579bf8eSKris Kennaway * "ADH-MY-CIPHER" look like a match for buflen=3. 641f579bf8eSKris Kennaway * So additionally check whether the cipher name found 642f579bf8eSKris Kennaway * has the correct length. We can save a strlen() call: 643f579bf8eSKris Kennaway * just checking for the '\0' at the right place is 644f579bf8eSKris Kennaway * sufficient, we have to strncmp() anyway. 645f579bf8eSKris Kennaway */ 646f579bf8eSKris Kennaway j = found = 0; 647f579bf8eSKris Kennaway while (ca_list[j]) 648f579bf8eSKris Kennaway { 649f579bf8eSKris Kennaway if ((ca_list[j]->name[buflen] == '\0') && 650f579bf8eSKris Kennaway !strncmp(buf, ca_list[j]->name, buflen)) 651f579bf8eSKris Kennaway { 652f579bf8eSKris Kennaway found = 1; 653f579bf8eSKris Kennaway break; 654f579bf8eSKris Kennaway } 655f579bf8eSKris Kennaway else 656f579bf8eSKris Kennaway j++; 657f579bf8eSKris Kennaway } 658f579bf8eSKris Kennaway if (!found) 659f579bf8eSKris Kennaway break; /* ignore this entry */ 660f579bf8eSKris Kennaway 661f579bf8eSKris Kennaway algorithms |= ca_list[j]->algorithms; 662f579bf8eSKris Kennaway mask |= ca_list[j]->mask; 663f579bf8eSKris Kennaway algo_strength |= ca_list[j]->algo_strength; 664f579bf8eSKris Kennaway mask_strength |= ca_list[j]->mask_strength; 665f579bf8eSKris Kennaway 666f579bf8eSKris Kennaway if (!multi) break; 667f579bf8eSKris Kennaway } 668f579bf8eSKris Kennaway 669f579bf8eSKris Kennaway /* 670f579bf8eSKris Kennaway * Ok, we have the rule, now apply it 671f579bf8eSKris Kennaway */ 672f579bf8eSKris Kennaway if (rule == CIPHER_SPECIAL) 673f579bf8eSKris Kennaway { /* special command */ 674f579bf8eSKris Kennaway ok = 0; 675f579bf8eSKris Kennaway if ((buflen == 8) && 676f579bf8eSKris Kennaway !strncmp(buf, "STRENGTH", 8)) 677f579bf8eSKris Kennaway ok = ssl_cipher_strength_sort(list, 678f579bf8eSKris Kennaway head_p, tail_p); 679f579bf8eSKris Kennaway else 680f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, 681f579bf8eSKris Kennaway SSL_R_INVALID_COMMAND); 682f579bf8eSKris Kennaway if (ok == 0) 683f579bf8eSKris Kennaway retval = 0; 684f579bf8eSKris Kennaway /* 685f579bf8eSKris Kennaway * We do not support any "multi" options 686f579bf8eSKris Kennaway * together with "@", so throw away the 687f579bf8eSKris Kennaway * rest of the command, if any left, until 688f579bf8eSKris Kennaway * end or ':' is found. 689f579bf8eSKris Kennaway */ 690f579bf8eSKris Kennaway while ((*l != '\0') && ITEM_SEP(*l)) 691f579bf8eSKris Kennaway l++; 692f579bf8eSKris Kennaway } 693f579bf8eSKris Kennaway else if (found) 694f579bf8eSKris Kennaway { 695f579bf8eSKris Kennaway ssl_cipher_apply_rule(algorithms, mask, 696f579bf8eSKris Kennaway algo_strength, mask_strength, rule, -1, 697f579bf8eSKris Kennaway list, head_p, tail_p); 698f579bf8eSKris Kennaway } 699f579bf8eSKris Kennaway else 700f579bf8eSKris Kennaway { 701f579bf8eSKris Kennaway while ((*l != '\0') && ITEM_SEP(*l)) 702f579bf8eSKris Kennaway l++; 703f579bf8eSKris Kennaway } 704f579bf8eSKris Kennaway if (*l == '\0') break; /* done */ 705f579bf8eSKris Kennaway } 706f579bf8eSKris Kennaway 707f579bf8eSKris Kennaway return(retval); 708f579bf8eSKris Kennaway } 709f579bf8eSKris Kennaway 710f579bf8eSKris Kennaway STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, 711f579bf8eSKris Kennaway STACK_OF(SSL_CIPHER) **cipher_list, 712f579bf8eSKris Kennaway STACK_OF(SSL_CIPHER) **cipher_list_by_id, 713f579bf8eSKris Kennaway const char *rule_str) 714f579bf8eSKris Kennaway { 715f579bf8eSKris Kennaway int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; 716f579bf8eSKris Kennaway unsigned long disabled_mask; 717f579bf8eSKris Kennaway STACK_OF(SSL_CIPHER) *cipherstack; 718f579bf8eSKris Kennaway const char *rule_p; 719f579bf8eSKris Kennaway CIPHER_ORDER *list = NULL, *head = NULL, *tail = NULL, *curr; 720f579bf8eSKris Kennaway SSL_CIPHER **ca_list = NULL; 721f579bf8eSKris Kennaway 722f579bf8eSKris Kennaway /* 723f579bf8eSKris Kennaway * Return with error if nothing to do. 724f579bf8eSKris Kennaway */ 725f579bf8eSKris Kennaway if (rule_str == NULL) return(NULL); 726f579bf8eSKris Kennaway 727f579bf8eSKris Kennaway if (init_ciphers) load_ciphers(); 728f579bf8eSKris Kennaway 729f579bf8eSKris Kennaway /* 730f579bf8eSKris Kennaway * To reduce the work to do we only want to process the compiled 731f579bf8eSKris Kennaway * in algorithms, so we first get the mask of disabled ciphers. 732f579bf8eSKris Kennaway */ 733f579bf8eSKris Kennaway disabled_mask = ssl_cipher_get_disabled(); 734f579bf8eSKris Kennaway 735f579bf8eSKris Kennaway /* 736f579bf8eSKris Kennaway * Now we have to collect the available ciphers from the compiled 737f579bf8eSKris Kennaway * in ciphers. We cannot get more than the number compiled in, so 738f579bf8eSKris Kennaway * it is used for allocation. 739f579bf8eSKris Kennaway */ 740f579bf8eSKris Kennaway num_of_ciphers = ssl_method->num_ciphers(); 741ddd58736SKris Kennaway list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers); 742f579bf8eSKris Kennaway if (list == NULL) 743f579bf8eSKris Kennaway { 744f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE); 745f579bf8eSKris Kennaway return(NULL); /* Failure */ 746f579bf8eSKris Kennaway } 747f579bf8eSKris Kennaway 748f579bf8eSKris Kennaway ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask, 749f579bf8eSKris Kennaway list, &head, &tail); 750f579bf8eSKris Kennaway 751f579bf8eSKris Kennaway /* 752f579bf8eSKris Kennaway * We also need cipher aliases for selecting based on the rule_str. 753f579bf8eSKris Kennaway * There might be two types of entries in the rule_str: 1) names 754f579bf8eSKris Kennaway * of ciphers themselves 2) aliases for groups of ciphers. 755f579bf8eSKris Kennaway * For 1) we need the available ciphers and for 2) the cipher 756f579bf8eSKris Kennaway * groups of cipher_aliases added together in one list (otherwise 757f579bf8eSKris Kennaway * we would be happy with just the cipher_aliases table). 758f579bf8eSKris Kennaway */ 759f579bf8eSKris Kennaway num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); 760f579bf8eSKris Kennaway num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; 761f579bf8eSKris Kennaway ca_list = 762ddd58736SKris Kennaway (SSL_CIPHER **)OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max); 763f579bf8eSKris Kennaway if (ca_list == NULL) 764f579bf8eSKris Kennaway { 765ddd58736SKris Kennaway OPENSSL_free(list); 766f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE); 767f579bf8eSKris Kennaway return(NULL); /* Failure */ 768f579bf8eSKris Kennaway } 769f579bf8eSKris Kennaway ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mask, 770f579bf8eSKris Kennaway head); 771f579bf8eSKris Kennaway 772f579bf8eSKris Kennaway /* 773f579bf8eSKris Kennaway * If the rule_string begins with DEFAULT, apply the default rule 774f579bf8eSKris Kennaway * before using the (possibly available) additional rules. 775f579bf8eSKris Kennaway */ 776f579bf8eSKris Kennaway ok = 1; 777f579bf8eSKris Kennaway rule_p = rule_str; 778f579bf8eSKris Kennaway if (strncmp(rule_str,"DEFAULT",7) == 0) 779f579bf8eSKris Kennaway { 780f579bf8eSKris Kennaway ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, 781f579bf8eSKris Kennaway list, &head, &tail, ca_list); 782f579bf8eSKris Kennaway rule_p += 7; 783f579bf8eSKris Kennaway if (*rule_p == ':') 784f579bf8eSKris Kennaway rule_p++; 785f579bf8eSKris Kennaway } 786f579bf8eSKris Kennaway 787f579bf8eSKris Kennaway if (ok && (strlen(rule_p) > 0)) 788f579bf8eSKris Kennaway ok = ssl_cipher_process_rulestr(rule_p, list, &head, &tail, 789f579bf8eSKris Kennaway ca_list); 790f579bf8eSKris Kennaway 791ddd58736SKris Kennaway OPENSSL_free(ca_list); /* Not needed anymore */ 792f579bf8eSKris Kennaway 793f579bf8eSKris Kennaway if (!ok) 794f579bf8eSKris Kennaway { /* Rule processing failure */ 795ddd58736SKris Kennaway OPENSSL_free(list); 796f579bf8eSKris Kennaway return(NULL); 797f579bf8eSKris Kennaway } 798f579bf8eSKris Kennaway /* 799f579bf8eSKris Kennaway * Allocate new "cipherstack" for the result, return with error 800f579bf8eSKris Kennaway * if we cannot get one. 801f579bf8eSKris Kennaway */ 802ddd58736SKris Kennaway if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) 803f579bf8eSKris Kennaway { 804ddd58736SKris Kennaway OPENSSL_free(list); 805f579bf8eSKris Kennaway return(NULL); 806f579bf8eSKris Kennaway } 807f579bf8eSKris Kennaway 808f579bf8eSKris Kennaway /* 809f579bf8eSKris Kennaway * The cipher selection for the list is done. The ciphers are added 810f579bf8eSKris Kennaway * to the resulting precedence to the STACK_OF(SSL_CIPHER). 811f579bf8eSKris Kennaway */ 81274664626SKris Kennaway for (curr = head; curr != NULL; curr = curr->next) 81374664626SKris Kennaway { 81474664626SKris Kennaway if (curr->active) 81574664626SKris Kennaway { 816f579bf8eSKris Kennaway sk_SSL_CIPHER_push(cipherstack, curr->cipher); 81774664626SKris Kennaway #ifdef CIPHER_DEBUG 81874664626SKris Kennaway printf("<%s>\n",curr->cipher->name); 81974664626SKris Kennaway #endif 82074664626SKris Kennaway } 82174664626SKris Kennaway } 822ddd58736SKris Kennaway OPENSSL_free(list); /* Not needed any longer */ 82374664626SKris Kennaway 824f579bf8eSKris Kennaway /* 825f579bf8eSKris Kennaway * The following passage is a little bit odd. If pointer variables 826f579bf8eSKris Kennaway * were supplied to hold STACK_OF(SSL_CIPHER) return information, 827f579bf8eSKris Kennaway * the old memory pointed to is free()ed. Then, however, the 828f579bf8eSKris Kennaway * cipher_list entry will be assigned just a copy of the returned 829f579bf8eSKris Kennaway * cipher stack. For cipher_list_by_id a copy of the cipher stack 830f579bf8eSKris Kennaway * will be created. See next comment... 831f579bf8eSKris Kennaway */ 83274664626SKris Kennaway if (cipher_list != NULL) 83374664626SKris Kennaway { 83474664626SKris Kennaway if (*cipher_list != NULL) 83574664626SKris Kennaway sk_SSL_CIPHER_free(*cipher_list); 836f579bf8eSKris Kennaway *cipher_list = cipherstack; 83774664626SKris Kennaway } 83874664626SKris Kennaway 83974664626SKris Kennaway if (cipher_list_by_id != NULL) 84074664626SKris Kennaway { 84174664626SKris Kennaway if (*cipher_list_by_id != NULL) 84274664626SKris Kennaway sk_SSL_CIPHER_free(*cipher_list_by_id); 843f579bf8eSKris Kennaway *cipher_list_by_id = sk_SSL_CIPHER_dup(cipherstack); 84474664626SKris Kennaway } 84574664626SKris Kennaway 846f579bf8eSKris Kennaway /* 847f579bf8eSKris Kennaway * Now it is getting really strange. If something failed during 848f579bf8eSKris Kennaway * the previous pointer assignment or if one of the pointers was 849f579bf8eSKris Kennaway * not requested, the error condition is met. That might be 850f579bf8eSKris Kennaway * discussable. The strange thing is however that in this case 851f579bf8eSKris Kennaway * the memory "ret" pointed to is "free()ed" and hence the pointer 852f579bf8eSKris Kennaway * cipher_list becomes wild. The memory reserved for 853f579bf8eSKris Kennaway * cipher_list_by_id however is not "free()ed" and stays intact. 854f579bf8eSKris Kennaway */ 85574664626SKris Kennaway if ( (cipher_list_by_id == NULL) || 85674664626SKris Kennaway (*cipher_list_by_id == NULL) || 85774664626SKris Kennaway (cipher_list == NULL) || 85874664626SKris Kennaway (*cipher_list == NULL)) 859f579bf8eSKris Kennaway { 860f579bf8eSKris Kennaway sk_SSL_CIPHER_free(cipherstack); 861f579bf8eSKris Kennaway return(NULL); 862f579bf8eSKris Kennaway } 863f579bf8eSKris Kennaway 86474664626SKris Kennaway sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp); 86574664626SKris Kennaway 866f579bf8eSKris Kennaway return(cipherstack); 86774664626SKris Kennaway } 86874664626SKris Kennaway 86974664626SKris Kennaway char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len) 87074664626SKris Kennaway { 87174664626SKris Kennaway int is_export,pkl,kl; 87274664626SKris Kennaway char *ver,*exp; 87374664626SKris Kennaway char *kx,*au,*enc,*mac; 874f579bf8eSKris Kennaway unsigned long alg,alg2,alg_s; 87574664626SKris Kennaway static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n"; 87674664626SKris Kennaway 87774664626SKris Kennaway alg=cipher->algorithms; 878f579bf8eSKris Kennaway alg_s=cipher->algo_strength; 87974664626SKris Kennaway alg2=cipher->algorithm2; 88074664626SKris Kennaway 881f579bf8eSKris Kennaway is_export=SSL_C_IS_EXPORT(cipher); 882f579bf8eSKris Kennaway pkl=SSL_C_EXPORT_PKEYLENGTH(cipher); 883f579bf8eSKris Kennaway kl=SSL_C_EXPORT_KEYLENGTH(cipher); 88474664626SKris Kennaway exp=is_export?" export":""; 88574664626SKris Kennaway 88674664626SKris Kennaway if (alg & SSL_SSLV2) 88774664626SKris Kennaway ver="SSLv2"; 88874664626SKris Kennaway else if (alg & SSL_SSLV3) 88974664626SKris Kennaway ver="SSLv3"; 89074664626SKris Kennaway else 89174664626SKris Kennaway ver="unknown"; 89274664626SKris Kennaway 89374664626SKris Kennaway switch (alg&SSL_MKEY_MASK) 89474664626SKris Kennaway { 89574664626SKris Kennaway case SSL_kRSA: 89674664626SKris Kennaway kx=is_export?(pkl == 512 ? "RSA(512)" : "RSA(1024)"):"RSA"; 89774664626SKris Kennaway break; 89874664626SKris Kennaway case SSL_kDHr: 89974664626SKris Kennaway kx="DH/RSA"; 90074664626SKris Kennaway break; 90174664626SKris Kennaway case SSL_kDHd: 90274664626SKris Kennaway kx="DH/DSS"; 90374664626SKris Kennaway break; 90474664626SKris Kennaway case SSL_kFZA: 90574664626SKris Kennaway kx="Fortezza"; 90674664626SKris Kennaway break; 90774664626SKris Kennaway case SSL_kEDH: 90874664626SKris Kennaway kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH"; 90974664626SKris Kennaway break; 91074664626SKris Kennaway default: 91174664626SKris Kennaway kx="unknown"; 91274664626SKris Kennaway } 91374664626SKris Kennaway 91474664626SKris Kennaway switch (alg&SSL_AUTH_MASK) 91574664626SKris Kennaway { 91674664626SKris Kennaway case SSL_aRSA: 91774664626SKris Kennaway au="RSA"; 91874664626SKris Kennaway break; 91974664626SKris Kennaway case SSL_aDSS: 92074664626SKris Kennaway au="DSS"; 92174664626SKris Kennaway break; 92274664626SKris Kennaway case SSL_aDH: 92374664626SKris Kennaway au="DH"; 92474664626SKris Kennaway break; 92574664626SKris Kennaway case SSL_aFZA: 92674664626SKris Kennaway case SSL_aNULL: 92774664626SKris Kennaway au="None"; 92874664626SKris Kennaway break; 92974664626SKris Kennaway default: 93074664626SKris Kennaway au="unknown"; 93174664626SKris Kennaway break; 93274664626SKris Kennaway } 93374664626SKris Kennaway 93474664626SKris Kennaway switch (alg&SSL_ENC_MASK) 93574664626SKris Kennaway { 93674664626SKris Kennaway case SSL_DES: 93774664626SKris Kennaway enc=(is_export && kl == 5)?"DES(40)":"DES(56)"; 93874664626SKris Kennaway break; 93974664626SKris Kennaway case SSL_3DES: 94074664626SKris Kennaway enc="3DES(168)"; 94174664626SKris Kennaway break; 94274664626SKris Kennaway case SSL_RC4: 94374664626SKris Kennaway enc=is_export?(kl == 5 ? "RC4(40)" : "RC4(56)") 94474664626SKris Kennaway :((alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)"); 94574664626SKris Kennaway break; 94674664626SKris Kennaway case SSL_RC2: 94774664626SKris Kennaway enc=is_export?(kl == 5 ? "RC2(40)" : "RC2(56)"):"RC2(128)"; 94874664626SKris Kennaway break; 94974664626SKris Kennaway case SSL_IDEA: 95074664626SKris Kennaway enc="IDEA(128)"; 95174664626SKris Kennaway break; 95274664626SKris Kennaway case SSL_eFZA: 95374664626SKris Kennaway enc="Fortezza"; 95474664626SKris Kennaway break; 95574664626SKris Kennaway case SSL_eNULL: 95674664626SKris Kennaway enc="None"; 95774664626SKris Kennaway break; 95874664626SKris Kennaway default: 95974664626SKris Kennaway enc="unknown"; 96074664626SKris Kennaway break; 96174664626SKris Kennaway } 96274664626SKris Kennaway 96374664626SKris Kennaway switch (alg&SSL_MAC_MASK) 96474664626SKris Kennaway { 96574664626SKris Kennaway case SSL_MD5: 96674664626SKris Kennaway mac="MD5"; 96774664626SKris Kennaway break; 96874664626SKris Kennaway case SSL_SHA1: 96974664626SKris Kennaway mac="SHA1"; 97074664626SKris Kennaway break; 97174664626SKris Kennaway default: 97274664626SKris Kennaway mac="unknown"; 97374664626SKris Kennaway break; 97474664626SKris Kennaway } 97574664626SKris Kennaway 97674664626SKris Kennaway if (buf == NULL) 97774664626SKris Kennaway { 978ddd58736SKris Kennaway len=128; 979ddd58736SKris Kennaway buf=OPENSSL_malloc(len); 980ddd58736SKris Kennaway if (buf == NULL) return("OPENSSL_malloc Error"); 98174664626SKris Kennaway } 98274664626SKris Kennaway else if (len < 128) 98374664626SKris Kennaway return("Buffer too small"); 98474664626SKris Kennaway 985ddd58736SKris Kennaway BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp); 98674664626SKris Kennaway return(buf); 98774664626SKris Kennaway } 98874664626SKris Kennaway 98974664626SKris Kennaway char *SSL_CIPHER_get_version(SSL_CIPHER *c) 99074664626SKris Kennaway { 99174664626SKris Kennaway int i; 99274664626SKris Kennaway 99374664626SKris Kennaway if (c == NULL) return("(NONE)"); 99474664626SKris Kennaway i=(int)(c->id>>24L); 99574664626SKris Kennaway if (i == 3) 99674664626SKris Kennaway return("TLSv1/SSLv3"); 99774664626SKris Kennaway else if (i == 2) 99874664626SKris Kennaway return("SSLv2"); 99974664626SKris Kennaway else 100074664626SKris Kennaway return("unknown"); 100174664626SKris Kennaway } 100274664626SKris Kennaway 100374664626SKris Kennaway /* return the actual cipher being used */ 100474664626SKris Kennaway const char *SSL_CIPHER_get_name(SSL_CIPHER *c) 100574664626SKris Kennaway { 100674664626SKris Kennaway if (c != NULL) 100774664626SKris Kennaway return(c->name); 100874664626SKris Kennaway return("(NONE)"); 100974664626SKris Kennaway } 101074664626SKris Kennaway 1011f579bf8eSKris Kennaway /* number of bits for symmetric cipher */ 101274664626SKris Kennaway int SSL_CIPHER_get_bits(SSL_CIPHER *c, int *alg_bits) 101374664626SKris Kennaway { 1014f579bf8eSKris Kennaway int ret=0; 101574664626SKris Kennaway 101674664626SKris Kennaway if (c != NULL) 101774664626SKris Kennaway { 1018f579bf8eSKris Kennaway if (alg_bits != NULL) *alg_bits = c->alg_bits; 1019f579bf8eSKris Kennaway ret = c->strength_bits; 102074664626SKris Kennaway } 102174664626SKris Kennaway return(ret); 102274664626SKris Kennaway } 102374664626SKris Kennaway 102474664626SKris Kennaway SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) 102574664626SKris Kennaway { 102674664626SKris Kennaway SSL_COMP *ctmp; 102774664626SKris Kennaway int i,nn; 102874664626SKris Kennaway 102974664626SKris Kennaway if ((n == 0) || (sk == NULL)) return(NULL); 103074664626SKris Kennaway nn=sk_SSL_COMP_num(sk); 103174664626SKris Kennaway for (i=0; i<nn; i++) 103274664626SKris Kennaway { 103374664626SKris Kennaway ctmp=sk_SSL_COMP_value(sk,i); 103474664626SKris Kennaway if (ctmp->id == n) 103574664626SKris Kennaway return(ctmp); 103674664626SKris Kennaway } 103774664626SKris Kennaway return(NULL); 103874664626SKris Kennaway } 103974664626SKris Kennaway 1040ddd58736SKris Kennaway static int sk_comp_cmp(const SSL_COMP * const *a, 1041ddd58736SKris Kennaway const SSL_COMP * const *b) 104274664626SKris Kennaway { 104374664626SKris Kennaway return((*a)->id-(*b)->id); 104474664626SKris Kennaway } 104574664626SKris Kennaway 104674664626SKris Kennaway STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) 104774664626SKris Kennaway { 104874664626SKris Kennaway return(ssl_comp_methods); 104974664626SKris Kennaway } 105074664626SKris Kennaway 105174664626SKris Kennaway int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) 105274664626SKris Kennaway { 105374664626SKris Kennaway SSL_COMP *comp; 105474664626SKris Kennaway STACK_OF(SSL_COMP) *sk; 105574664626SKris Kennaway 1056ddd58736SKris Kennaway comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); 105774664626SKris Kennaway comp->id=id; 105874664626SKris Kennaway comp->method=cm; 105974664626SKris Kennaway if (ssl_comp_methods == NULL) 106074664626SKris Kennaway sk=ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp); 106174664626SKris Kennaway else 106274664626SKris Kennaway sk=ssl_comp_methods; 106374664626SKris Kennaway if ((sk == NULL) || !sk_SSL_COMP_push(sk,comp)) 106474664626SKris Kennaway { 106574664626SKris Kennaway SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,ERR_R_MALLOC_FAILURE); 106674664626SKris Kennaway return(0); 106774664626SKris Kennaway } 106874664626SKris Kennaway else 106974664626SKris Kennaway return(1); 107074664626SKris Kennaway } 107174664626SKris Kennaway 1072