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 715c87c606SMark Murray #define SSL_ENC_AES128_IDX 7 725c87c606SMark Murray #define SSL_ENC_AES256_IDX 8 735c87c606SMark Murray #define SSL_ENC_NUM_IDX 9 7474664626SKris Kennaway 7574664626SKris Kennaway static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={ 7674664626SKris Kennaway NULL,NULL,NULL,NULL,NULL,NULL, 7774664626SKris Kennaway }; 7874664626SKris Kennaway 7974664626SKris Kennaway static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL; 8074664626SKris Kennaway 8174664626SKris Kennaway #define SSL_MD_MD5_IDX 0 8274664626SKris Kennaway #define SSL_MD_SHA1_IDX 1 8374664626SKris Kennaway #define SSL_MD_NUM_IDX 2 8474664626SKris Kennaway static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={ 8574664626SKris Kennaway NULL,NULL, 8674664626SKris Kennaway }; 8774664626SKris Kennaway 8874664626SKris Kennaway #define CIPHER_ADD 1 8974664626SKris Kennaway #define CIPHER_KILL 2 9074664626SKris Kennaway #define CIPHER_DEL 3 9174664626SKris Kennaway #define CIPHER_ORD 4 92f579bf8eSKris Kennaway #define CIPHER_SPECIAL 5 9374664626SKris Kennaway 9474664626SKris Kennaway typedef struct cipher_order_st 9574664626SKris Kennaway { 9674664626SKris Kennaway SSL_CIPHER *cipher; 9774664626SKris Kennaway int active; 9874664626SKris Kennaway int dead; 9974664626SKris Kennaway struct cipher_order_st *next,*prev; 10074664626SKris Kennaway } CIPHER_ORDER; 10174664626SKris Kennaway 102f579bf8eSKris Kennaway static const SSL_CIPHER cipher_aliases[]={ 1035c87c606SMark Murray /* Don't include eNULL unless specifically enabled. */ 104f579bf8eSKris Kennaway {0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL, SSL_ALL ,0,0,0,SSL_ALL,SSL_ALL}, /* must be first */ 1055c87c606SMark Murray {0,SSL_TXT_CMPALL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0}, /* COMPLEMENT OF ALL */ 1065c87c606SMark Murray {0,SSL_TXT_CMPDEF,0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK,0}, 1075c87c606SMark Murray {0,SSL_TXT_kKRB5,0,SSL_kKRB5,0,0,0,0,SSL_MKEY_MASK,0}, /* VRS Kerberos5 */ 108f579bf8eSKris Kennaway {0,SSL_TXT_kRSA,0,SSL_kRSA, 0,0,0,0,SSL_MKEY_MASK,0}, 109f579bf8eSKris Kennaway {0,SSL_TXT_kDHr,0,SSL_kDHr, 0,0,0,0,SSL_MKEY_MASK,0}, 110f579bf8eSKris Kennaway {0,SSL_TXT_kDHd,0,SSL_kDHd, 0,0,0,0,SSL_MKEY_MASK,0}, 111f579bf8eSKris Kennaway {0,SSL_TXT_kEDH,0,SSL_kEDH, 0,0,0,0,SSL_MKEY_MASK,0}, 112f579bf8eSKris Kennaway {0,SSL_TXT_kFZA,0,SSL_kFZA, 0,0,0,0,SSL_MKEY_MASK,0}, 113f579bf8eSKris Kennaway {0,SSL_TXT_DH, 0,SSL_DH, 0,0,0,0,SSL_MKEY_MASK,0}, 114f579bf8eSKris Kennaway {0,SSL_TXT_EDH, 0,SSL_EDH, 0,0,0,0,SSL_MKEY_MASK|SSL_AUTH_MASK,0}, 11574664626SKris Kennaway 1165c87c606SMark Murray {0,SSL_TXT_aKRB5,0,SSL_aKRB5,0,0,0,0,SSL_AUTH_MASK,0}, /* VRS Kerberos5 */ 117f579bf8eSKris Kennaway {0,SSL_TXT_aRSA,0,SSL_aRSA, 0,0,0,0,SSL_AUTH_MASK,0}, 118f579bf8eSKris Kennaway {0,SSL_TXT_aDSS,0,SSL_aDSS, 0,0,0,0,SSL_AUTH_MASK,0}, 119f579bf8eSKris Kennaway {0,SSL_TXT_aFZA,0,SSL_aFZA, 0,0,0,0,SSL_AUTH_MASK,0}, 120f579bf8eSKris Kennaway {0,SSL_TXT_aNULL,0,SSL_aNULL,0,0,0,0,SSL_AUTH_MASK,0}, 121f579bf8eSKris Kennaway {0,SSL_TXT_aDH, 0,SSL_aDH, 0,0,0,0,SSL_AUTH_MASK,0}, 122f579bf8eSKris Kennaway {0,SSL_TXT_DSS, 0,SSL_DSS, 0,0,0,0,SSL_AUTH_MASK,0}, 12374664626SKris Kennaway 124f579bf8eSKris Kennaway {0,SSL_TXT_DES, 0,SSL_DES, 0,0,0,0,SSL_ENC_MASK,0}, 125f579bf8eSKris Kennaway {0,SSL_TXT_3DES,0,SSL_3DES, 0,0,0,0,SSL_ENC_MASK,0}, 126f579bf8eSKris Kennaway {0,SSL_TXT_RC4, 0,SSL_RC4, 0,0,0,0,SSL_ENC_MASK,0}, 127f579bf8eSKris Kennaway {0,SSL_TXT_RC2, 0,SSL_RC2, 0,0,0,0,SSL_ENC_MASK,0}, 128f579bf8eSKris Kennaway {0,SSL_TXT_IDEA,0,SSL_IDEA, 0,0,0,0,SSL_ENC_MASK,0}, 129f579bf8eSKris Kennaway {0,SSL_TXT_eNULL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0}, 130f579bf8eSKris Kennaway {0,SSL_TXT_eFZA,0,SSL_eFZA, 0,0,0,0,SSL_ENC_MASK,0}, 1315c87c606SMark Murray {0,SSL_TXT_AES, 0,SSL_AES, 0,0,0,0,SSL_ENC_MASK,0}, 13274664626SKris Kennaway 133f579bf8eSKris Kennaway {0,SSL_TXT_MD5, 0,SSL_MD5, 0,0,0,0,SSL_MAC_MASK,0}, 134f579bf8eSKris Kennaway {0,SSL_TXT_SHA1,0,SSL_SHA1, 0,0,0,0,SSL_MAC_MASK,0}, 135f579bf8eSKris Kennaway {0,SSL_TXT_SHA, 0,SSL_SHA, 0,0,0,0,SSL_MAC_MASK,0}, 13674664626SKris Kennaway 137f579bf8eSKris Kennaway {0,SSL_TXT_NULL,0,SSL_NULL, 0,0,0,0,SSL_ENC_MASK,0}, 1385c87c606SMark Murray {0,SSL_TXT_KRB5,0,SSL_KRB5, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, 139f579bf8eSKris Kennaway {0,SSL_TXT_RSA, 0,SSL_RSA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, 140f579bf8eSKris Kennaway {0,SSL_TXT_ADH, 0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, 141f579bf8eSKris Kennaway {0,SSL_TXT_FZA, 0,SSL_FZA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK|SSL_ENC_MASK,0}, 14274664626SKris Kennaway 143f579bf8eSKris Kennaway {0,SSL_TXT_SSLV2, 0,SSL_SSLV2, 0,0,0,0,SSL_SSL_MASK,0}, 144f579bf8eSKris Kennaway {0,SSL_TXT_SSLV3, 0,SSL_SSLV3, 0,0,0,0,SSL_SSL_MASK,0}, 145f579bf8eSKris Kennaway {0,SSL_TXT_TLSV1, 0,SSL_TLSV1, 0,0,0,0,SSL_SSL_MASK,0}, 146f579bf8eSKris Kennaway 147f579bf8eSKris Kennaway {0,SSL_TXT_EXP ,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK}, 148f579bf8eSKris Kennaway {0,SSL_TXT_EXPORT,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK}, 149f579bf8eSKris Kennaway {0,SSL_TXT_EXP40, 0, 0, SSL_EXP40, 0,0,0,0,SSL_STRONG_MASK}, 150f579bf8eSKris Kennaway {0,SSL_TXT_EXP56, 0, 0, SSL_EXP56, 0,0,0,0,SSL_STRONG_MASK}, 151f579bf8eSKris Kennaway {0,SSL_TXT_LOW, 0, 0, SSL_LOW, 0,0,0,0,SSL_STRONG_MASK}, 152f579bf8eSKris Kennaway {0,SSL_TXT_MEDIUM,0, 0,SSL_MEDIUM, 0,0,0,0,SSL_STRONG_MASK}, 153f579bf8eSKris Kennaway {0,SSL_TXT_HIGH, 0, 0, SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK}, 15474664626SKris Kennaway }; 15574664626SKris Kennaway 15674664626SKris Kennaway static int init_ciphers=1; 15774664626SKris Kennaway 15874664626SKris Kennaway static void load_ciphers(void) 15974664626SKris Kennaway { 16074664626SKris Kennaway init_ciphers=0; 16174664626SKris Kennaway ssl_cipher_methods[SSL_ENC_DES_IDX]= 16274664626SKris Kennaway EVP_get_cipherbyname(SN_des_cbc); 16374664626SKris Kennaway ssl_cipher_methods[SSL_ENC_3DES_IDX]= 16474664626SKris Kennaway EVP_get_cipherbyname(SN_des_ede3_cbc); 16574664626SKris Kennaway ssl_cipher_methods[SSL_ENC_RC4_IDX]= 16674664626SKris Kennaway EVP_get_cipherbyname(SN_rc4); 16774664626SKris Kennaway ssl_cipher_methods[SSL_ENC_RC2_IDX]= 16874664626SKris Kennaway EVP_get_cipherbyname(SN_rc2_cbc); 16974664626SKris Kennaway ssl_cipher_methods[SSL_ENC_IDEA_IDX]= 17074664626SKris Kennaway EVP_get_cipherbyname(SN_idea_cbc); 1715c87c606SMark Murray ssl_cipher_methods[SSL_ENC_AES128_IDX]= 1725c87c606SMark Murray EVP_get_cipherbyname(SN_aes_128_cbc); 1735c87c606SMark Murray ssl_cipher_methods[SSL_ENC_AES256_IDX]= 1745c87c606SMark Murray EVP_get_cipherbyname(SN_aes_256_cbc); 17574664626SKris Kennaway 17674664626SKris Kennaway ssl_digest_methods[SSL_MD_MD5_IDX]= 17774664626SKris Kennaway EVP_get_digestbyname(SN_md5); 17874664626SKris Kennaway ssl_digest_methods[SSL_MD_SHA1_IDX]= 17974664626SKris Kennaway EVP_get_digestbyname(SN_sha1); 18074664626SKris Kennaway } 18174664626SKris Kennaway 18274664626SKris Kennaway int ssl_cipher_get_evp(SSL_SESSION *s, const EVP_CIPHER **enc, 18374664626SKris Kennaway const EVP_MD **md, SSL_COMP **comp) 18474664626SKris Kennaway { 18574664626SKris Kennaway int i; 18674664626SKris Kennaway SSL_CIPHER *c; 18774664626SKris Kennaway 18874664626SKris Kennaway c=s->cipher; 18974664626SKris Kennaway if (c == NULL) return(0); 19074664626SKris Kennaway if (comp != NULL) 19174664626SKris Kennaway { 19274664626SKris Kennaway SSL_COMP ctmp; 19374664626SKris Kennaway 19474664626SKris Kennaway if (s->compress_meth == 0) 19574664626SKris Kennaway *comp=NULL; 19674664626SKris Kennaway else if (ssl_comp_methods == NULL) 19774664626SKris Kennaway { 19874664626SKris Kennaway /* bad */ 19974664626SKris Kennaway *comp=NULL; 20074664626SKris Kennaway } 20174664626SKris Kennaway else 20274664626SKris Kennaway { 20374664626SKris Kennaway 20474664626SKris Kennaway ctmp.id=s->compress_meth; 20574664626SKris Kennaway i=sk_SSL_COMP_find(ssl_comp_methods,&ctmp); 20674664626SKris Kennaway if (i >= 0) 20774664626SKris Kennaway *comp=sk_SSL_COMP_value(ssl_comp_methods,i); 20874664626SKris Kennaway else 20974664626SKris Kennaway *comp=NULL; 21074664626SKris Kennaway } 21174664626SKris Kennaway } 21274664626SKris Kennaway 21374664626SKris Kennaway if ((enc == NULL) || (md == NULL)) return(0); 21474664626SKris Kennaway 21574664626SKris Kennaway switch (c->algorithms & SSL_ENC_MASK) 21674664626SKris Kennaway { 21774664626SKris Kennaway case SSL_DES: 21874664626SKris Kennaway i=SSL_ENC_DES_IDX; 21974664626SKris Kennaway break; 22074664626SKris Kennaway case SSL_3DES: 22174664626SKris Kennaway i=SSL_ENC_3DES_IDX; 22274664626SKris Kennaway break; 22374664626SKris Kennaway case SSL_RC4: 22474664626SKris Kennaway i=SSL_ENC_RC4_IDX; 22574664626SKris Kennaway break; 22674664626SKris Kennaway case SSL_RC2: 22774664626SKris Kennaway i=SSL_ENC_RC2_IDX; 22874664626SKris Kennaway break; 22974664626SKris Kennaway case SSL_IDEA: 23074664626SKris Kennaway i=SSL_ENC_IDEA_IDX; 23174664626SKris Kennaway break; 23274664626SKris Kennaway case SSL_eNULL: 23374664626SKris Kennaway i=SSL_ENC_NULL_IDX; 23474664626SKris Kennaway break; 2355c87c606SMark Murray case SSL_AES: 2365c87c606SMark Murray switch(c->alg_bits) 2375c87c606SMark Murray { 2385c87c606SMark Murray case 128: i=SSL_ENC_AES128_IDX; break; 2395c87c606SMark Murray case 256: i=SSL_ENC_AES256_IDX; break; 2405c87c606SMark Murray default: i=-1; break; 2415c87c606SMark Murray } 2425c87c606SMark Murray break; 24374664626SKris Kennaway default: 24474664626SKris Kennaway i= -1; 24574664626SKris Kennaway break; 24674664626SKris Kennaway } 24774664626SKris Kennaway 24874664626SKris Kennaway if ((i < 0) || (i > SSL_ENC_NUM_IDX)) 24974664626SKris Kennaway *enc=NULL; 25074664626SKris Kennaway else 25174664626SKris Kennaway { 25274664626SKris Kennaway if (i == SSL_ENC_NULL_IDX) 25374664626SKris Kennaway *enc=EVP_enc_null(); 25474664626SKris Kennaway else 25574664626SKris Kennaway *enc=ssl_cipher_methods[i]; 25674664626SKris Kennaway } 25774664626SKris Kennaway 25874664626SKris Kennaway switch (c->algorithms & SSL_MAC_MASK) 25974664626SKris Kennaway { 26074664626SKris Kennaway case SSL_MD5: 26174664626SKris Kennaway i=SSL_MD_MD5_IDX; 26274664626SKris Kennaway break; 26374664626SKris Kennaway case SSL_SHA1: 26474664626SKris Kennaway i=SSL_MD_SHA1_IDX; 26574664626SKris Kennaway break; 26674664626SKris Kennaway default: 26774664626SKris Kennaway i= -1; 26874664626SKris Kennaway break; 26974664626SKris Kennaway } 27074664626SKris Kennaway if ((i < 0) || (i > SSL_MD_NUM_IDX)) 27174664626SKris Kennaway *md=NULL; 27274664626SKris Kennaway else 27374664626SKris Kennaway *md=ssl_digest_methods[i]; 27474664626SKris Kennaway 27574664626SKris Kennaway if ((*enc != NULL) && (*md != NULL)) 27674664626SKris Kennaway return(1); 27774664626SKris Kennaway else 27874664626SKris Kennaway return(0); 27974664626SKris Kennaway } 28074664626SKris Kennaway 28174664626SKris Kennaway #define ITEM_SEP(a) \ 28274664626SKris Kennaway (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) 28374664626SKris Kennaway 28474664626SKris Kennaway static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, 28574664626SKris Kennaway CIPHER_ORDER **tail) 28674664626SKris Kennaway { 28774664626SKris Kennaway if (curr == *tail) return; 28874664626SKris Kennaway if (curr == *head) 28974664626SKris Kennaway *head=curr->next; 29074664626SKris Kennaway if (curr->prev != NULL) 29174664626SKris Kennaway curr->prev->next=curr->next; 29274664626SKris Kennaway if (curr->next != NULL) /* should always be true */ 29374664626SKris Kennaway curr->next->prev=curr->prev; 29474664626SKris Kennaway (*tail)->next=curr; 29574664626SKris Kennaway curr->prev= *tail; 29674664626SKris Kennaway curr->next=NULL; 29774664626SKris Kennaway *tail=curr; 29874664626SKris Kennaway } 29974664626SKris Kennaway 300f579bf8eSKris Kennaway static unsigned long ssl_cipher_get_disabled(void) 30174664626SKris Kennaway { 302f579bf8eSKris Kennaway unsigned long mask; 30374664626SKris Kennaway 30474664626SKris Kennaway mask = SSL_kFZA; 3055c87c606SMark Murray #ifdef OPENSSL_NO_RSA 30674664626SKris Kennaway mask |= SSL_aRSA|SSL_kRSA; 30774664626SKris Kennaway #endif 3085c87c606SMark Murray #ifdef OPENSSL_NO_DSA 30974664626SKris Kennaway mask |= SSL_aDSS; 31074664626SKris Kennaway #endif 3115c87c606SMark Murray #ifdef OPENSSL_NO_DH 31274664626SKris Kennaway mask |= SSL_kDHr|SSL_kDHd|SSL_kEDH|SSL_aDH; 31374664626SKris Kennaway #endif 3145c87c606SMark Murray #ifdef OPENSSL_NO_KRB5 3155c87c606SMark Murray mask |= SSL_kKRB5|SSL_aKRB5; 3165c87c606SMark Murray #endif 31774664626SKris Kennaway 31874664626SKris Kennaway #ifdef SSL_FORBID_ENULL 31974664626SKris Kennaway mask |= SSL_eNULL; 32074664626SKris Kennaway #endif 32174664626SKris Kennaway 32274664626SKris Kennaway mask |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0; 32374664626SKris Kennaway mask |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0; 32474664626SKris Kennaway mask |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0; 32574664626SKris Kennaway mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0; 32674664626SKris Kennaway mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0; 32774664626SKris Kennaway mask |= (ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL) ? SSL_eFZA:0; 3285c87c606SMark Murray mask |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES:0; 32974664626SKris Kennaway 33074664626SKris Kennaway mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0; 33174664626SKris Kennaway mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0; 33274664626SKris Kennaway 333f579bf8eSKris Kennaway return(mask); 334f579bf8eSKris Kennaway } 335f579bf8eSKris Kennaway 336f579bf8eSKris Kennaway static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, 337f579bf8eSKris Kennaway int num_of_ciphers, unsigned long mask, CIPHER_ORDER *list, 338f579bf8eSKris Kennaway CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) 339f579bf8eSKris Kennaway { 340f579bf8eSKris Kennaway int i, list_num; 341f579bf8eSKris Kennaway SSL_CIPHER *c; 342f579bf8eSKris Kennaway 343f579bf8eSKris Kennaway /* 344f579bf8eSKris Kennaway * We have num_of_ciphers descriptions compiled in, depending on the 345f579bf8eSKris Kennaway * method selected (SSLv2 and/or SSLv3, TLSv1 etc). 346f579bf8eSKris Kennaway * These will later be sorted in a linked list with at most num 347f579bf8eSKris Kennaway * entries. 348f579bf8eSKris Kennaway */ 34974664626SKris Kennaway 35074664626SKris Kennaway /* Get the initial list of ciphers */ 351f579bf8eSKris Kennaway list_num = 0; /* actual count of ciphers */ 352f579bf8eSKris Kennaway for (i = 0; i < num_of_ciphers; i++) 35374664626SKris Kennaway { 354f579bf8eSKris Kennaway c = ssl_method->get_cipher(i); 35574664626SKris Kennaway /* drop those that use any of that is not available */ 35674664626SKris Kennaway if ((c != NULL) && c->valid && !(c->algorithms & mask)) 35774664626SKris Kennaway { 35874664626SKris Kennaway list[list_num].cipher = c; 35974664626SKris Kennaway list[list_num].next = NULL; 36074664626SKris Kennaway list[list_num].prev = NULL; 36174664626SKris Kennaway list[list_num].active = 0; 36274664626SKris Kennaway list_num++; 3635c87c606SMark Murray #ifdef KSSL_DEBUG 3645c87c606SMark Murray printf("\t%d: %s %lx %lx\n",i,c->name,c->id,c->algorithms); 3655c87c606SMark Murray #endif /* KSSL_DEBUG */ 366f579bf8eSKris Kennaway /* 36774664626SKris Kennaway if (!sk_push(ca_list,(char *)c)) goto err; 368f579bf8eSKris Kennaway */ 36974664626SKris Kennaway } 37074664626SKris Kennaway } 37174664626SKris Kennaway 372f579bf8eSKris Kennaway /* 373f579bf8eSKris Kennaway * Prepare linked list from list entries 374f579bf8eSKris Kennaway */ 37574664626SKris Kennaway for (i = 1; i < list_num - 1; i++) 37674664626SKris Kennaway { 37774664626SKris Kennaway list[i].prev = &(list[i-1]); 37874664626SKris Kennaway list[i].next = &(list[i+1]); 37974664626SKris Kennaway } 38074664626SKris Kennaway if (list_num > 0) 38174664626SKris Kennaway { 382f579bf8eSKris Kennaway (*head_p) = &(list[0]); 383f579bf8eSKris Kennaway (*head_p)->prev = NULL; 384f579bf8eSKris Kennaway (*head_p)->next = &(list[1]); 385f579bf8eSKris Kennaway (*tail_p) = &(list[list_num - 1]); 386f579bf8eSKris Kennaway (*tail_p)->prev = &(list[list_num - 2]); 387f579bf8eSKris Kennaway (*tail_p)->next = NULL; 388f579bf8eSKris Kennaway } 38974664626SKris Kennaway } 39074664626SKris Kennaway 391f579bf8eSKris Kennaway static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list, 392f579bf8eSKris Kennaway int num_of_group_aliases, unsigned long mask, 393f579bf8eSKris Kennaway CIPHER_ORDER *head) 39474664626SKris Kennaway { 395f579bf8eSKris Kennaway CIPHER_ORDER *ciph_curr; 396f579bf8eSKris Kennaway SSL_CIPHER **ca_curr; 397f579bf8eSKris Kennaway int i; 398f579bf8eSKris Kennaway 399f579bf8eSKris Kennaway /* 400f579bf8eSKris Kennaway * First, add the real ciphers as already collected 401f579bf8eSKris Kennaway */ 402f579bf8eSKris Kennaway ciph_curr = head; 403f579bf8eSKris Kennaway ca_curr = ca_list; 404f579bf8eSKris Kennaway while (ciph_curr != NULL) 405f579bf8eSKris Kennaway { 406f579bf8eSKris Kennaway *ca_curr = ciph_curr->cipher; 407f579bf8eSKris Kennaway ca_curr++; 408f579bf8eSKris Kennaway ciph_curr = ciph_curr->next; 40974664626SKris Kennaway } 41074664626SKris Kennaway 411f579bf8eSKris Kennaway /* 412f579bf8eSKris Kennaway * Now we add the available ones from the cipher_aliases[] table. 413f579bf8eSKris Kennaway * They represent either an algorithm, that must be fully 414f579bf8eSKris Kennaway * supported (not match any bit in mask) or represent a cipher 415f579bf8eSKris Kennaway * strength value (will be added in any case because algorithms=0). 416f579bf8eSKris Kennaway */ 417f579bf8eSKris Kennaway for (i = 0; i < num_of_group_aliases; i++) 41874664626SKris Kennaway { 419f579bf8eSKris Kennaway if ((i == 0) || /* always fetch "ALL" */ 420f579bf8eSKris Kennaway !(cipher_aliases[i].algorithms & mask)) 42174664626SKris Kennaway { 422f579bf8eSKris Kennaway *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); 423f579bf8eSKris Kennaway ca_curr++; 42474664626SKris Kennaway } 425f579bf8eSKris Kennaway } 42674664626SKris Kennaway 427f579bf8eSKris Kennaway *ca_curr = NULL; /* end of list */ 428f579bf8eSKris Kennaway } 429f579bf8eSKris Kennaway 430f579bf8eSKris Kennaway static void ssl_cipher_apply_rule(unsigned long algorithms, unsigned long mask, 431f579bf8eSKris Kennaway unsigned long algo_strength, unsigned long mask_strength, 432f579bf8eSKris Kennaway int rule, int strength_bits, CIPHER_ORDER *list, 433f579bf8eSKris Kennaway CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) 43474664626SKris Kennaway { 435f579bf8eSKris Kennaway CIPHER_ORDER *head, *tail, *curr, *curr2, *tail2; 436f579bf8eSKris Kennaway SSL_CIPHER *cp; 437f579bf8eSKris Kennaway unsigned long ma, ma_s; 438f579bf8eSKris Kennaway 439f579bf8eSKris Kennaway #ifdef CIPHER_DEBUG 440f579bf8eSKris Kennaway printf("Applying rule %d with %08lx %08lx %08lx %08lx (%d)\n", 441f579bf8eSKris Kennaway rule, algorithms, mask, algo_strength, mask_strength, 442f579bf8eSKris Kennaway strength_bits); 44374664626SKris Kennaway #endif 44474664626SKris Kennaway 445f579bf8eSKris Kennaway curr = head = *head_p; 44674664626SKris Kennaway curr2 = head; 447f579bf8eSKris Kennaway tail2 = tail = *tail_p; 44874664626SKris Kennaway for (;;) 44974664626SKris Kennaway { 45074664626SKris Kennaway if ((curr == NULL) || (curr == tail2)) break; 45174664626SKris Kennaway curr = curr2; 45274664626SKris Kennaway curr2 = curr->next; 45374664626SKris Kennaway 45474664626SKris Kennaway cp = curr->cipher; 455f579bf8eSKris Kennaway 456f579bf8eSKris Kennaway /* 457f579bf8eSKris Kennaway * Selection criteria is either the number of strength_bits 458f579bf8eSKris Kennaway * or the algorithm used. 459f579bf8eSKris Kennaway */ 460f579bf8eSKris Kennaway if (strength_bits == -1) 46174664626SKris Kennaway { 462f579bf8eSKris Kennaway ma = mask & cp->algorithms; 463f579bf8eSKris Kennaway ma_s = mask_strength & cp->algo_strength; 464f579bf8eSKris Kennaway 465f579bf8eSKris Kennaway #ifdef CIPHER_DEBUG 466f579bf8eSKris 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); 467f579bf8eSKris Kennaway printf("ma = %08lx ma_s %08lx, ma&algo=%08lx, ma_s&algos=%08lx\n", ma, ma_s, ma&algorithms, ma_s&algo_strength); 468f579bf8eSKris Kennaway #endif 469f579bf8eSKris Kennaway /* 470f579bf8eSKris Kennaway * Select: if none of the mask bit was met from the 471f579bf8eSKris Kennaway * cipher or not all of the bits were met, the 472f579bf8eSKris Kennaway * selection does not apply. 473f579bf8eSKris Kennaway */ 474f579bf8eSKris Kennaway if (((ma == 0) && (ma_s == 0)) || 475f579bf8eSKris Kennaway ((ma & algorithms) != ma) || 476f579bf8eSKris Kennaway ((ma_s & algo_strength) != ma_s)) 477f579bf8eSKris Kennaway continue; /* does not apply */ 47874664626SKris Kennaway } 479f579bf8eSKris Kennaway else if (strength_bits != cp->strength_bits) 480f579bf8eSKris Kennaway continue; /* does not apply */ 481f579bf8eSKris Kennaway 482f579bf8eSKris Kennaway #ifdef CIPHER_DEBUG 483f579bf8eSKris Kennaway printf("Action = %d\n", rule); 484f579bf8eSKris Kennaway #endif 48574664626SKris Kennaway 48674664626SKris Kennaway /* add the cipher if it has not been added yet. */ 487f579bf8eSKris Kennaway if (rule == CIPHER_ADD) 48874664626SKris Kennaway { 48974664626SKris Kennaway if (!curr->active) 49074664626SKris Kennaway { 49174664626SKris Kennaway ll_append_tail(&head, curr, &tail); 49274664626SKris Kennaway curr->active = 1; 49374664626SKris Kennaway } 49474664626SKris Kennaway } 49574664626SKris Kennaway /* Move the added cipher to this location */ 496f579bf8eSKris Kennaway else if (rule == CIPHER_ORD) 49774664626SKris Kennaway { 49874664626SKris Kennaway if (curr->active) 49974664626SKris Kennaway { 50074664626SKris Kennaway ll_append_tail(&head, curr, &tail); 50174664626SKris Kennaway } 50274664626SKris Kennaway } 503f579bf8eSKris Kennaway else if (rule == CIPHER_DEL) 50474664626SKris Kennaway curr->active = 0; 505f579bf8eSKris Kennaway else if (rule == CIPHER_KILL) 50674664626SKris Kennaway { 50774664626SKris Kennaway if (head == curr) 50874664626SKris Kennaway head = curr->next; 50974664626SKris Kennaway else 51074664626SKris Kennaway curr->prev->next = curr->next; 51174664626SKris Kennaway if (tail == curr) 51274664626SKris Kennaway tail = curr->prev; 51374664626SKris Kennaway curr->active = 0; 51474664626SKris Kennaway if (curr->next != NULL) 51574664626SKris Kennaway curr->next->prev = curr->prev; 51674664626SKris Kennaway if (curr->prev != NULL) 51774664626SKris Kennaway curr->prev->next = curr->next; 51874664626SKris Kennaway curr->next = NULL; 51974664626SKris Kennaway curr->prev = NULL; 52074664626SKris Kennaway } 52174664626SKris Kennaway } 522f579bf8eSKris Kennaway 523f579bf8eSKris Kennaway *head_p = head; 524f579bf8eSKris Kennaway *tail_p = tail; 52574664626SKris Kennaway } 52674664626SKris Kennaway 527f579bf8eSKris Kennaway static int ssl_cipher_strength_sort(CIPHER_ORDER *list, CIPHER_ORDER **head_p, 528f579bf8eSKris Kennaway CIPHER_ORDER **tail_p) 529f579bf8eSKris Kennaway { 530f579bf8eSKris Kennaway int max_strength_bits, i, *number_uses; 531f579bf8eSKris Kennaway CIPHER_ORDER *curr; 532f579bf8eSKris Kennaway 533f579bf8eSKris Kennaway /* 534f579bf8eSKris Kennaway * This routine sorts the ciphers with descending strength. The sorting 535f579bf8eSKris Kennaway * must keep the pre-sorted sequence, so we apply the normal sorting 536f579bf8eSKris Kennaway * routine as '+' movement to the end of the list. 537f579bf8eSKris Kennaway */ 538f579bf8eSKris Kennaway max_strength_bits = 0; 539f579bf8eSKris Kennaway curr = *head_p; 540f579bf8eSKris Kennaway while (curr != NULL) 541f579bf8eSKris Kennaway { 542f579bf8eSKris Kennaway if (curr->active && 543f579bf8eSKris Kennaway (curr->cipher->strength_bits > max_strength_bits)) 544f579bf8eSKris Kennaway max_strength_bits = curr->cipher->strength_bits; 545f579bf8eSKris Kennaway curr = curr->next; 546f579bf8eSKris Kennaway } 547f579bf8eSKris Kennaway 548ddd58736SKris Kennaway number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int)); 549f579bf8eSKris Kennaway if (!number_uses) 550f579bf8eSKris Kennaway { 551f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT,ERR_R_MALLOC_FAILURE); 552f579bf8eSKris Kennaway return(0); 553f579bf8eSKris Kennaway } 554f579bf8eSKris Kennaway memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int)); 555f579bf8eSKris Kennaway 556f579bf8eSKris Kennaway /* 557f579bf8eSKris Kennaway * Now find the strength_bits values actually used 558f579bf8eSKris Kennaway */ 559f579bf8eSKris Kennaway curr = *head_p; 560f579bf8eSKris Kennaway while (curr != NULL) 561f579bf8eSKris Kennaway { 562f579bf8eSKris Kennaway if (curr->active) 563f579bf8eSKris Kennaway number_uses[curr->cipher->strength_bits]++; 564f579bf8eSKris Kennaway curr = curr->next; 565f579bf8eSKris Kennaway } 566f579bf8eSKris Kennaway /* 567f579bf8eSKris Kennaway * Go through the list of used strength_bits values in descending 568f579bf8eSKris Kennaway * order. 569f579bf8eSKris Kennaway */ 570f579bf8eSKris Kennaway for (i = max_strength_bits; i >= 0; i--) 571f579bf8eSKris Kennaway if (number_uses[i] > 0) 572f579bf8eSKris Kennaway ssl_cipher_apply_rule(0, 0, 0, 0, CIPHER_ORD, i, 573f579bf8eSKris Kennaway list, head_p, tail_p); 574f579bf8eSKris Kennaway 575ddd58736SKris Kennaway OPENSSL_free(number_uses); 576f579bf8eSKris Kennaway return(1); 577f579bf8eSKris Kennaway } 578f579bf8eSKris Kennaway 579f579bf8eSKris Kennaway static int ssl_cipher_process_rulestr(const char *rule_str, 580f579bf8eSKris Kennaway CIPHER_ORDER *list, CIPHER_ORDER **head_p, 581f579bf8eSKris Kennaway CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list) 582f579bf8eSKris Kennaway { 583f579bf8eSKris Kennaway unsigned long algorithms, mask, algo_strength, mask_strength; 584f579bf8eSKris Kennaway const char *l, *start, *buf; 585f579bf8eSKris Kennaway int j, multi, found, rule, retval, ok, buflen; 586f579bf8eSKris Kennaway char ch; 587f579bf8eSKris Kennaway 588f579bf8eSKris Kennaway retval = 1; 589f579bf8eSKris Kennaway l = rule_str; 590f579bf8eSKris Kennaway for (;;) 591f579bf8eSKris Kennaway { 592f579bf8eSKris Kennaway ch = *l; 593f579bf8eSKris Kennaway 594f579bf8eSKris Kennaway if (ch == '\0') 595f579bf8eSKris Kennaway break; /* done */ 596f579bf8eSKris Kennaway if (ch == '-') 597f579bf8eSKris Kennaway { rule = CIPHER_DEL; l++; } 598f579bf8eSKris Kennaway else if (ch == '+') 599f579bf8eSKris Kennaway { rule = CIPHER_ORD; l++; } 600f579bf8eSKris Kennaway else if (ch == '!') 601f579bf8eSKris Kennaway { rule = CIPHER_KILL; l++; } 602f579bf8eSKris Kennaway else if (ch == '@') 603f579bf8eSKris Kennaway { rule = CIPHER_SPECIAL; l++; } 604f579bf8eSKris Kennaway else 605f579bf8eSKris Kennaway { rule = CIPHER_ADD; } 606f579bf8eSKris Kennaway 607f579bf8eSKris Kennaway if (ITEM_SEP(ch)) 608f579bf8eSKris Kennaway { 609f579bf8eSKris Kennaway l++; 610f579bf8eSKris Kennaway continue; 611f579bf8eSKris Kennaway } 612f579bf8eSKris Kennaway 613f579bf8eSKris Kennaway algorithms = mask = algo_strength = mask_strength = 0; 614f579bf8eSKris Kennaway 615f579bf8eSKris Kennaway start=l; 616f579bf8eSKris Kennaway for (;;) 617f579bf8eSKris Kennaway { 618f579bf8eSKris Kennaway ch = *l; 619f579bf8eSKris Kennaway buf = l; 620f579bf8eSKris Kennaway buflen = 0; 621f579bf8eSKris Kennaway #ifndef CHARSET_EBCDIC 622f579bf8eSKris Kennaway while ( ((ch >= 'A') && (ch <= 'Z')) || 623f579bf8eSKris Kennaway ((ch >= '0') && (ch <= '9')) || 624f579bf8eSKris Kennaway ((ch >= 'a') && (ch <= 'z')) || 625f579bf8eSKris Kennaway (ch == '-')) 626f579bf8eSKris Kennaway #else 627f579bf8eSKris Kennaway while ( isalnum(ch) || (ch == '-')) 628f579bf8eSKris Kennaway #endif 629f579bf8eSKris Kennaway { 630f579bf8eSKris Kennaway ch = *(++l); 631f579bf8eSKris Kennaway buflen++; 632f579bf8eSKris Kennaway } 633f579bf8eSKris Kennaway 634f579bf8eSKris Kennaway if (buflen == 0) 635f579bf8eSKris Kennaway { 636f579bf8eSKris Kennaway /* 637f579bf8eSKris Kennaway * We hit something we cannot deal with, 638f579bf8eSKris Kennaway * it is no command or separator nor 639f579bf8eSKris Kennaway * alphanumeric, so we call this an error. 640f579bf8eSKris Kennaway */ 641f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, 642f579bf8eSKris Kennaway SSL_R_INVALID_COMMAND); 643f579bf8eSKris Kennaway retval = found = 0; 644f579bf8eSKris Kennaway l++; 645f579bf8eSKris Kennaway break; 646f579bf8eSKris Kennaway } 647f579bf8eSKris Kennaway 648f579bf8eSKris Kennaway if (rule == CIPHER_SPECIAL) 649f579bf8eSKris Kennaway { 650f579bf8eSKris Kennaway found = 0; /* unused -- avoid compiler warning */ 651f579bf8eSKris Kennaway break; /* special treatment */ 652f579bf8eSKris Kennaway } 653f579bf8eSKris Kennaway 654f579bf8eSKris Kennaway /* check for multi-part specification */ 655f579bf8eSKris Kennaway if (ch == '+') 656f579bf8eSKris Kennaway { 657f579bf8eSKris Kennaway multi=1; 658f579bf8eSKris Kennaway l++; 659f579bf8eSKris Kennaway } 660f579bf8eSKris Kennaway else 661f579bf8eSKris Kennaway multi=0; 662f579bf8eSKris Kennaway 663f579bf8eSKris Kennaway /* 664f579bf8eSKris Kennaway * Now search for the cipher alias in the ca_list. Be careful 665f579bf8eSKris Kennaway * with the strncmp, because the "buflen" limitation 666f579bf8eSKris Kennaway * will make the rule "ADH:SOME" and the cipher 667f579bf8eSKris Kennaway * "ADH-MY-CIPHER" look like a match for buflen=3. 668f579bf8eSKris Kennaway * So additionally check whether the cipher name found 669f579bf8eSKris Kennaway * has the correct length. We can save a strlen() call: 670f579bf8eSKris Kennaway * just checking for the '\0' at the right place is 67150ef0093SJacques Vidrine * sufficient, we have to strncmp() anyway. (We cannot 67250ef0093SJacques Vidrine * use strcmp(), because buf is not '\0' terminated.) 673f579bf8eSKris Kennaway */ 674f579bf8eSKris Kennaway j = found = 0; 675f579bf8eSKris Kennaway while (ca_list[j]) 676f579bf8eSKris Kennaway { 67750ef0093SJacques Vidrine if (!strncmp(buf, ca_list[j]->name, buflen) && 67850ef0093SJacques Vidrine (ca_list[j]->name[buflen] == '\0')) 679f579bf8eSKris Kennaway { 680f579bf8eSKris Kennaway found = 1; 681f579bf8eSKris Kennaway break; 682f579bf8eSKris Kennaway } 683f579bf8eSKris Kennaway else 684f579bf8eSKris Kennaway j++; 685f579bf8eSKris Kennaway } 686f579bf8eSKris Kennaway if (!found) 687f579bf8eSKris Kennaway break; /* ignore this entry */ 688f579bf8eSKris Kennaway 689f579bf8eSKris Kennaway algorithms |= ca_list[j]->algorithms; 690f579bf8eSKris Kennaway mask |= ca_list[j]->mask; 691f579bf8eSKris Kennaway algo_strength |= ca_list[j]->algo_strength; 692f579bf8eSKris Kennaway mask_strength |= ca_list[j]->mask_strength; 693f579bf8eSKris Kennaway 694f579bf8eSKris Kennaway if (!multi) break; 695f579bf8eSKris Kennaway } 696f579bf8eSKris Kennaway 697f579bf8eSKris Kennaway /* 698f579bf8eSKris Kennaway * Ok, we have the rule, now apply it 699f579bf8eSKris Kennaway */ 700f579bf8eSKris Kennaway if (rule == CIPHER_SPECIAL) 701f579bf8eSKris Kennaway { /* special command */ 702f579bf8eSKris Kennaway ok = 0; 703f579bf8eSKris Kennaway if ((buflen == 8) && 704f579bf8eSKris Kennaway !strncmp(buf, "STRENGTH", 8)) 705f579bf8eSKris Kennaway ok = ssl_cipher_strength_sort(list, 706f579bf8eSKris Kennaway head_p, tail_p); 707f579bf8eSKris Kennaway else 708f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, 709f579bf8eSKris Kennaway SSL_R_INVALID_COMMAND); 710f579bf8eSKris Kennaway if (ok == 0) 711f579bf8eSKris Kennaway retval = 0; 712f579bf8eSKris Kennaway /* 713f579bf8eSKris Kennaway * We do not support any "multi" options 714f579bf8eSKris Kennaway * together with "@", so throw away the 715f579bf8eSKris Kennaway * rest of the command, if any left, until 716f579bf8eSKris Kennaway * end or ':' is found. 717f579bf8eSKris Kennaway */ 718f579bf8eSKris Kennaway while ((*l != '\0') && ITEM_SEP(*l)) 719f579bf8eSKris Kennaway l++; 720f579bf8eSKris Kennaway } 721f579bf8eSKris Kennaway else if (found) 722f579bf8eSKris Kennaway { 723f579bf8eSKris Kennaway ssl_cipher_apply_rule(algorithms, mask, 724f579bf8eSKris Kennaway algo_strength, mask_strength, rule, -1, 725f579bf8eSKris Kennaway list, head_p, tail_p); 726f579bf8eSKris Kennaway } 727f579bf8eSKris Kennaway else 728f579bf8eSKris Kennaway { 729f579bf8eSKris Kennaway while ((*l != '\0') && ITEM_SEP(*l)) 730f579bf8eSKris Kennaway l++; 731f579bf8eSKris Kennaway } 732f579bf8eSKris Kennaway if (*l == '\0') break; /* done */ 733f579bf8eSKris Kennaway } 734f579bf8eSKris Kennaway 735f579bf8eSKris Kennaway return(retval); 736f579bf8eSKris Kennaway } 737f579bf8eSKris Kennaway 738f579bf8eSKris Kennaway STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, 739f579bf8eSKris Kennaway STACK_OF(SSL_CIPHER) **cipher_list, 740f579bf8eSKris Kennaway STACK_OF(SSL_CIPHER) **cipher_list_by_id, 741f579bf8eSKris Kennaway const char *rule_str) 742f579bf8eSKris Kennaway { 743f579bf8eSKris Kennaway int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; 744f579bf8eSKris Kennaway unsigned long disabled_mask; 745f579bf8eSKris Kennaway STACK_OF(SSL_CIPHER) *cipherstack; 746f579bf8eSKris Kennaway const char *rule_p; 747f579bf8eSKris Kennaway CIPHER_ORDER *list = NULL, *head = NULL, *tail = NULL, *curr; 748f579bf8eSKris Kennaway SSL_CIPHER **ca_list = NULL; 749f579bf8eSKris Kennaway 750f579bf8eSKris Kennaway /* 751f579bf8eSKris Kennaway * Return with error if nothing to do. 752f579bf8eSKris Kennaway */ 753f579bf8eSKris Kennaway if (rule_str == NULL) return(NULL); 754f579bf8eSKris Kennaway 7555c87c606SMark Murray if (init_ciphers) 7565c87c606SMark Murray { 7575c87c606SMark Murray CRYPTO_w_lock(CRYPTO_LOCK_SSL); 758f579bf8eSKris Kennaway if (init_ciphers) load_ciphers(); 7595c87c606SMark Murray CRYPTO_w_unlock(CRYPTO_LOCK_SSL); 7605c87c606SMark Murray } 761f579bf8eSKris Kennaway 762f579bf8eSKris Kennaway /* 763f579bf8eSKris Kennaway * To reduce the work to do we only want to process the compiled 764f579bf8eSKris Kennaway * in algorithms, so we first get the mask of disabled ciphers. 765f579bf8eSKris Kennaway */ 766f579bf8eSKris Kennaway disabled_mask = ssl_cipher_get_disabled(); 767f579bf8eSKris Kennaway 768f579bf8eSKris Kennaway /* 769f579bf8eSKris Kennaway * Now we have to collect the available ciphers from the compiled 770f579bf8eSKris Kennaway * in ciphers. We cannot get more than the number compiled in, so 771f579bf8eSKris Kennaway * it is used for allocation. 772f579bf8eSKris Kennaway */ 773f579bf8eSKris Kennaway num_of_ciphers = ssl_method->num_ciphers(); 7745c87c606SMark Murray #ifdef KSSL_DEBUG 7755c87c606SMark Murray printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers); 7765c87c606SMark Murray #endif /* KSSL_DEBUG */ 777ddd58736SKris Kennaway list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers); 778f579bf8eSKris Kennaway if (list == NULL) 779f579bf8eSKris Kennaway { 780f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE); 781f579bf8eSKris Kennaway return(NULL); /* Failure */ 782f579bf8eSKris Kennaway } 783f579bf8eSKris Kennaway 784f579bf8eSKris Kennaway ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask, 785f579bf8eSKris Kennaway list, &head, &tail); 786f579bf8eSKris Kennaway 787f579bf8eSKris Kennaway /* 788f579bf8eSKris Kennaway * We also need cipher aliases for selecting based on the rule_str. 789f579bf8eSKris Kennaway * There might be two types of entries in the rule_str: 1) names 790f579bf8eSKris Kennaway * of ciphers themselves 2) aliases for groups of ciphers. 791f579bf8eSKris Kennaway * For 1) we need the available ciphers and for 2) the cipher 792f579bf8eSKris Kennaway * groups of cipher_aliases added together in one list (otherwise 793f579bf8eSKris Kennaway * we would be happy with just the cipher_aliases table). 794f579bf8eSKris Kennaway */ 795f579bf8eSKris Kennaway num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); 796f579bf8eSKris Kennaway num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; 797f579bf8eSKris Kennaway ca_list = 798ddd58736SKris Kennaway (SSL_CIPHER **)OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max); 799f579bf8eSKris Kennaway if (ca_list == NULL) 800f579bf8eSKris Kennaway { 801ddd58736SKris Kennaway OPENSSL_free(list); 802f579bf8eSKris Kennaway SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE); 803f579bf8eSKris Kennaway return(NULL); /* Failure */ 804f579bf8eSKris Kennaway } 805f579bf8eSKris Kennaway ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mask, 806f579bf8eSKris Kennaway head); 807f579bf8eSKris Kennaway 808f579bf8eSKris Kennaway /* 809f579bf8eSKris Kennaway * If the rule_string begins with DEFAULT, apply the default rule 810f579bf8eSKris Kennaway * before using the (possibly available) additional rules. 811f579bf8eSKris Kennaway */ 812f579bf8eSKris Kennaway ok = 1; 813f579bf8eSKris Kennaway rule_p = rule_str; 814f579bf8eSKris Kennaway if (strncmp(rule_str,"DEFAULT",7) == 0) 815f579bf8eSKris Kennaway { 816f579bf8eSKris Kennaway ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, 817f579bf8eSKris Kennaway list, &head, &tail, ca_list); 818f579bf8eSKris Kennaway rule_p += 7; 819f579bf8eSKris Kennaway if (*rule_p == ':') 820f579bf8eSKris Kennaway rule_p++; 821f579bf8eSKris Kennaway } 822f579bf8eSKris Kennaway 823f579bf8eSKris Kennaway if (ok && (strlen(rule_p) > 0)) 824f579bf8eSKris Kennaway ok = ssl_cipher_process_rulestr(rule_p, list, &head, &tail, 825f579bf8eSKris Kennaway ca_list); 826f579bf8eSKris Kennaway 827ddd58736SKris Kennaway OPENSSL_free(ca_list); /* Not needed anymore */ 828f579bf8eSKris Kennaway 829f579bf8eSKris Kennaway if (!ok) 830f579bf8eSKris Kennaway { /* Rule processing failure */ 831ddd58736SKris Kennaway OPENSSL_free(list); 832f579bf8eSKris Kennaway return(NULL); 833f579bf8eSKris Kennaway } 834f579bf8eSKris Kennaway /* 835f579bf8eSKris Kennaway * Allocate new "cipherstack" for the result, return with error 836f579bf8eSKris Kennaway * if we cannot get one. 837f579bf8eSKris Kennaway */ 838ddd58736SKris Kennaway if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) 839f579bf8eSKris Kennaway { 840ddd58736SKris Kennaway OPENSSL_free(list); 841f579bf8eSKris Kennaway return(NULL); 842f579bf8eSKris Kennaway } 843f579bf8eSKris Kennaway 844f579bf8eSKris Kennaway /* 845f579bf8eSKris Kennaway * The cipher selection for the list is done. The ciphers are added 846f579bf8eSKris Kennaway * to the resulting precedence to the STACK_OF(SSL_CIPHER). 847f579bf8eSKris Kennaway */ 84874664626SKris Kennaway for (curr = head; curr != NULL; curr = curr->next) 84974664626SKris Kennaway { 85074664626SKris Kennaway if (curr->active) 85174664626SKris Kennaway { 852f579bf8eSKris Kennaway sk_SSL_CIPHER_push(cipherstack, curr->cipher); 85374664626SKris Kennaway #ifdef CIPHER_DEBUG 85474664626SKris Kennaway printf("<%s>\n",curr->cipher->name); 85574664626SKris Kennaway #endif 85674664626SKris Kennaway } 85774664626SKris Kennaway } 858ddd58736SKris Kennaway OPENSSL_free(list); /* Not needed any longer */ 85974664626SKris Kennaway 860f579bf8eSKris Kennaway /* 861f579bf8eSKris Kennaway * The following passage is a little bit odd. If pointer variables 862f579bf8eSKris Kennaway * were supplied to hold STACK_OF(SSL_CIPHER) return information, 863f579bf8eSKris Kennaway * the old memory pointed to is free()ed. Then, however, the 864f579bf8eSKris Kennaway * cipher_list entry will be assigned just a copy of the returned 865f579bf8eSKris Kennaway * cipher stack. For cipher_list_by_id a copy of the cipher stack 866f579bf8eSKris Kennaway * will be created. See next comment... 867f579bf8eSKris Kennaway */ 86874664626SKris Kennaway if (cipher_list != NULL) 86974664626SKris Kennaway { 87074664626SKris Kennaway if (*cipher_list != NULL) 87174664626SKris Kennaway sk_SSL_CIPHER_free(*cipher_list); 872f579bf8eSKris Kennaway *cipher_list = cipherstack; 87374664626SKris Kennaway } 87474664626SKris Kennaway 87574664626SKris Kennaway if (cipher_list_by_id != NULL) 87674664626SKris Kennaway { 87774664626SKris Kennaway if (*cipher_list_by_id != NULL) 87874664626SKris Kennaway sk_SSL_CIPHER_free(*cipher_list_by_id); 879f579bf8eSKris Kennaway *cipher_list_by_id = sk_SSL_CIPHER_dup(cipherstack); 88074664626SKris Kennaway } 88174664626SKris Kennaway 882f579bf8eSKris Kennaway /* 883f579bf8eSKris Kennaway * Now it is getting really strange. If something failed during 884f579bf8eSKris Kennaway * the previous pointer assignment or if one of the pointers was 885f579bf8eSKris Kennaway * not requested, the error condition is met. That might be 886f579bf8eSKris Kennaway * discussable. The strange thing is however that in this case 887f579bf8eSKris Kennaway * the memory "ret" pointed to is "free()ed" and hence the pointer 888f579bf8eSKris Kennaway * cipher_list becomes wild. The memory reserved for 889f579bf8eSKris Kennaway * cipher_list_by_id however is not "free()ed" and stays intact. 890f579bf8eSKris Kennaway */ 89174664626SKris Kennaway if ( (cipher_list_by_id == NULL) || 89274664626SKris Kennaway (*cipher_list_by_id == NULL) || 89374664626SKris Kennaway (cipher_list == NULL) || 89474664626SKris Kennaway (*cipher_list == NULL)) 895f579bf8eSKris Kennaway { 896f579bf8eSKris Kennaway sk_SSL_CIPHER_free(cipherstack); 897f579bf8eSKris Kennaway return(NULL); 898f579bf8eSKris Kennaway } 899f579bf8eSKris Kennaway 90074664626SKris Kennaway sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp); 90174664626SKris Kennaway 902f579bf8eSKris Kennaway return(cipherstack); 90374664626SKris Kennaway } 90474664626SKris Kennaway 90574664626SKris Kennaway char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len) 90674664626SKris Kennaway { 90774664626SKris Kennaway int is_export,pkl,kl; 90874664626SKris Kennaway char *ver,*exp; 90974664626SKris Kennaway char *kx,*au,*enc,*mac; 910f579bf8eSKris Kennaway unsigned long alg,alg2,alg_s; 9115c87c606SMark Murray #ifdef KSSL_DEBUG 9125c87c606SMark Murray static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx\n"; 9135c87c606SMark Murray #else 91474664626SKris Kennaway static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n"; 9155c87c606SMark Murray #endif /* KSSL_DEBUG */ 91674664626SKris Kennaway 91774664626SKris Kennaway alg=cipher->algorithms; 918f579bf8eSKris Kennaway alg_s=cipher->algo_strength; 91974664626SKris Kennaway alg2=cipher->algorithm2; 92074664626SKris Kennaway 921f579bf8eSKris Kennaway is_export=SSL_C_IS_EXPORT(cipher); 922f579bf8eSKris Kennaway pkl=SSL_C_EXPORT_PKEYLENGTH(cipher); 923f579bf8eSKris Kennaway kl=SSL_C_EXPORT_KEYLENGTH(cipher); 92474664626SKris Kennaway exp=is_export?" export":""; 92574664626SKris Kennaway 92674664626SKris Kennaway if (alg & SSL_SSLV2) 92774664626SKris Kennaway ver="SSLv2"; 92874664626SKris Kennaway else if (alg & SSL_SSLV3) 92974664626SKris Kennaway ver="SSLv3"; 93074664626SKris Kennaway else 93174664626SKris Kennaway ver="unknown"; 93274664626SKris Kennaway 93374664626SKris Kennaway switch (alg&SSL_MKEY_MASK) 93474664626SKris Kennaway { 93574664626SKris Kennaway case SSL_kRSA: 93674664626SKris Kennaway kx=is_export?(pkl == 512 ? "RSA(512)" : "RSA(1024)"):"RSA"; 93774664626SKris Kennaway break; 93874664626SKris Kennaway case SSL_kDHr: 93974664626SKris Kennaway kx="DH/RSA"; 94074664626SKris Kennaway break; 94174664626SKris Kennaway case SSL_kDHd: 94274664626SKris Kennaway kx="DH/DSS"; 94374664626SKris Kennaway break; 9445c87c606SMark Murray case SSL_kKRB5: /* VRS */ 9455c87c606SMark Murray case SSL_KRB5: /* VRS */ 9465c87c606SMark Murray kx="KRB5"; 9475c87c606SMark Murray break; 94874664626SKris Kennaway case SSL_kFZA: 94974664626SKris Kennaway kx="Fortezza"; 95074664626SKris Kennaway break; 95174664626SKris Kennaway case SSL_kEDH: 95274664626SKris Kennaway kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH"; 95374664626SKris Kennaway break; 95474664626SKris Kennaway default: 95574664626SKris Kennaway kx="unknown"; 95674664626SKris Kennaway } 95774664626SKris Kennaway 95874664626SKris Kennaway switch (alg&SSL_AUTH_MASK) 95974664626SKris Kennaway { 96074664626SKris Kennaway case SSL_aRSA: 96174664626SKris Kennaway au="RSA"; 96274664626SKris Kennaway break; 96374664626SKris Kennaway case SSL_aDSS: 96474664626SKris Kennaway au="DSS"; 96574664626SKris Kennaway break; 96674664626SKris Kennaway case SSL_aDH: 96774664626SKris Kennaway au="DH"; 96874664626SKris Kennaway break; 9695c87c606SMark Murray case SSL_aKRB5: /* VRS */ 9705c87c606SMark Murray case SSL_KRB5: /* VRS */ 9715c87c606SMark Murray au="KRB5"; 9725c87c606SMark Murray break; 97374664626SKris Kennaway case SSL_aFZA: 97474664626SKris Kennaway case SSL_aNULL: 97574664626SKris Kennaway au="None"; 97674664626SKris Kennaway break; 97774664626SKris Kennaway default: 97874664626SKris Kennaway au="unknown"; 97974664626SKris Kennaway break; 98074664626SKris Kennaway } 98174664626SKris Kennaway 98274664626SKris Kennaway switch (alg&SSL_ENC_MASK) 98374664626SKris Kennaway { 98474664626SKris Kennaway case SSL_DES: 98574664626SKris Kennaway enc=(is_export && kl == 5)?"DES(40)":"DES(56)"; 98674664626SKris Kennaway break; 98774664626SKris Kennaway case SSL_3DES: 98874664626SKris Kennaway enc="3DES(168)"; 98974664626SKris Kennaway break; 99074664626SKris Kennaway case SSL_RC4: 99174664626SKris Kennaway enc=is_export?(kl == 5 ? "RC4(40)" : "RC4(56)") 99274664626SKris Kennaway :((alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)"); 99374664626SKris Kennaway break; 99474664626SKris Kennaway case SSL_RC2: 99574664626SKris Kennaway enc=is_export?(kl == 5 ? "RC2(40)" : "RC2(56)"):"RC2(128)"; 99674664626SKris Kennaway break; 99774664626SKris Kennaway case SSL_IDEA: 99874664626SKris Kennaway enc="IDEA(128)"; 99974664626SKris Kennaway break; 100074664626SKris Kennaway case SSL_eFZA: 100174664626SKris Kennaway enc="Fortezza"; 100274664626SKris Kennaway break; 100374664626SKris Kennaway case SSL_eNULL: 100474664626SKris Kennaway enc="None"; 100574664626SKris Kennaway break; 10065c87c606SMark Murray case SSL_AES: 10075c87c606SMark Murray switch(cipher->strength_bits) 10085c87c606SMark Murray { 10095c87c606SMark Murray case 128: enc="AES(128)"; break; 10105c87c606SMark Murray case 192: enc="AES(192)"; break; 10115c87c606SMark Murray case 256: enc="AES(256)"; break; 10125c87c606SMark Murray default: enc="AES(?""?""?)"; break; 10135c87c606SMark Murray } 10145c87c606SMark Murray break; 101574664626SKris Kennaway default: 101674664626SKris Kennaway enc="unknown"; 101774664626SKris Kennaway break; 101874664626SKris Kennaway } 101974664626SKris Kennaway 102074664626SKris Kennaway switch (alg&SSL_MAC_MASK) 102174664626SKris Kennaway { 102274664626SKris Kennaway case SSL_MD5: 102374664626SKris Kennaway mac="MD5"; 102474664626SKris Kennaway break; 102574664626SKris Kennaway case SSL_SHA1: 102674664626SKris Kennaway mac="SHA1"; 102774664626SKris Kennaway break; 102874664626SKris Kennaway default: 102974664626SKris Kennaway mac="unknown"; 103074664626SKris Kennaway break; 103174664626SKris Kennaway } 103274664626SKris Kennaway 103374664626SKris Kennaway if (buf == NULL) 103474664626SKris Kennaway { 1035ddd58736SKris Kennaway len=128; 1036ddd58736SKris Kennaway buf=OPENSSL_malloc(len); 1037ddd58736SKris Kennaway if (buf == NULL) return("OPENSSL_malloc Error"); 103874664626SKris Kennaway } 103974664626SKris Kennaway else if (len < 128) 104074664626SKris Kennaway return("Buffer too small"); 104174664626SKris Kennaway 10425c87c606SMark Murray #ifdef KSSL_DEBUG 10435c87c606SMark Murray BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp,alg); 10445c87c606SMark Murray #else 1045ddd58736SKris Kennaway BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp); 10465c87c606SMark Murray #endif /* KSSL_DEBUG */ 104774664626SKris Kennaway return(buf); 104874664626SKris Kennaway } 104974664626SKris Kennaway 105074664626SKris Kennaway char *SSL_CIPHER_get_version(SSL_CIPHER *c) 105174664626SKris Kennaway { 105274664626SKris Kennaway int i; 105374664626SKris Kennaway 105474664626SKris Kennaway if (c == NULL) return("(NONE)"); 105574664626SKris Kennaway i=(int)(c->id>>24L); 105674664626SKris Kennaway if (i == 3) 105774664626SKris Kennaway return("TLSv1/SSLv3"); 105874664626SKris Kennaway else if (i == 2) 105974664626SKris Kennaway return("SSLv2"); 106074664626SKris Kennaway else 106174664626SKris Kennaway return("unknown"); 106274664626SKris Kennaway } 106374664626SKris Kennaway 106474664626SKris Kennaway /* return the actual cipher being used */ 106574664626SKris Kennaway const char *SSL_CIPHER_get_name(SSL_CIPHER *c) 106674664626SKris Kennaway { 106774664626SKris Kennaway if (c != NULL) 106874664626SKris Kennaway return(c->name); 106974664626SKris Kennaway return("(NONE)"); 107074664626SKris Kennaway } 107174664626SKris Kennaway 1072f579bf8eSKris Kennaway /* number of bits for symmetric cipher */ 107374664626SKris Kennaway int SSL_CIPHER_get_bits(SSL_CIPHER *c, int *alg_bits) 107474664626SKris Kennaway { 1075f579bf8eSKris Kennaway int ret=0; 107674664626SKris Kennaway 107774664626SKris Kennaway if (c != NULL) 107874664626SKris Kennaway { 1079f579bf8eSKris Kennaway if (alg_bits != NULL) *alg_bits = c->alg_bits; 1080f579bf8eSKris Kennaway ret = c->strength_bits; 108174664626SKris Kennaway } 108274664626SKris Kennaway return(ret); 108374664626SKris Kennaway } 108474664626SKris Kennaway 108574664626SKris Kennaway SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) 108674664626SKris Kennaway { 108774664626SKris Kennaway SSL_COMP *ctmp; 108874664626SKris Kennaway int i,nn; 108974664626SKris Kennaway 109074664626SKris Kennaway if ((n == 0) || (sk == NULL)) return(NULL); 109174664626SKris Kennaway nn=sk_SSL_COMP_num(sk); 109274664626SKris Kennaway for (i=0; i<nn; i++) 109374664626SKris Kennaway { 109474664626SKris Kennaway ctmp=sk_SSL_COMP_value(sk,i); 109574664626SKris Kennaway if (ctmp->id == n) 109674664626SKris Kennaway return(ctmp); 109774664626SKris Kennaway } 109874664626SKris Kennaway return(NULL); 109974664626SKris Kennaway } 110074664626SKris Kennaway 1101ddd58736SKris Kennaway static int sk_comp_cmp(const SSL_COMP * const *a, 1102ddd58736SKris Kennaway const SSL_COMP * const *b) 110374664626SKris Kennaway { 110474664626SKris Kennaway return((*a)->id-(*b)->id); 110574664626SKris Kennaway } 110674664626SKris Kennaway 110774664626SKris Kennaway STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) 110874664626SKris Kennaway { 110974664626SKris Kennaway return(ssl_comp_methods); 111074664626SKris Kennaway } 111174664626SKris Kennaway 111274664626SKris Kennaway int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) 111374664626SKris Kennaway { 111474664626SKris Kennaway SSL_COMP *comp; 111574664626SKris Kennaway STACK_OF(SSL_COMP) *sk; 111674664626SKris Kennaway 11175c87c606SMark Murray if (cm == NULL || cm->type == NID_undef) 11185c87c606SMark Murray return 1; 11195c87c606SMark Murray 11205c87c606SMark Murray MemCheck_off(); 1121ddd58736SKris Kennaway comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); 112274664626SKris Kennaway comp->id=id; 112374664626SKris Kennaway comp->method=cm; 112474664626SKris Kennaway if (ssl_comp_methods == NULL) 112574664626SKris Kennaway sk=ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp); 112674664626SKris Kennaway else 112774664626SKris Kennaway sk=ssl_comp_methods; 112874664626SKris Kennaway if ((sk == NULL) || !sk_SSL_COMP_push(sk,comp)) 112974664626SKris Kennaway { 11305c87c606SMark Murray MemCheck_on(); 113174664626SKris Kennaway SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,ERR_R_MALLOC_FAILURE); 113274664626SKris Kennaway return(0); 113374664626SKris Kennaway } 113474664626SKris Kennaway else 11355c87c606SMark Murray { 11365c87c606SMark Murray MemCheck_on(); 113774664626SKris Kennaway return(1); 113874664626SKris Kennaway } 11395c87c606SMark Murray } 1140