1*0Sstevel@tonic-gate /* ssl/ssl_ciph.c */ 2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*0Sstevel@tonic-gate * All rights reserved. 4*0Sstevel@tonic-gate * 5*0Sstevel@tonic-gate * This package is an SSL implementation written 6*0Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 7*0Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 10*0Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 11*0Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 12*0Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*0Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 14*0Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*0Sstevel@tonic-gate * 16*0Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 17*0Sstevel@tonic-gate * the code are not to be removed. 18*0Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 19*0Sstevel@tonic-gate * as the author of the parts of the library used. 20*0Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 21*0Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 24*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 25*0Sstevel@tonic-gate * are met: 26*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 27*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 28*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 29*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 30*0Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 31*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 32*0Sstevel@tonic-gate * must display the following acknowledgement: 33*0Sstevel@tonic-gate * "This product includes cryptographic software written by 34*0Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 35*0Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 36*0Sstevel@tonic-gate * being used are not cryptographic related :-). 37*0Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 38*0Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 39*0Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*0Sstevel@tonic-gate * 41*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*0Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*0Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*0Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*0Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*0Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*0Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*0Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*0Sstevel@tonic-gate * SUCH DAMAGE. 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 54*0Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 55*0Sstevel@tonic-gate * copied and put under another distribution licence 56*0Sstevel@tonic-gate * [including the GNU Public Licence.] 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate /* 60*0Sstevel@tonic-gate * The portions of this code that are #ifdef SOLARIS_OPENSSL are 61*0Sstevel@tonic-gate * 62*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 63*0Sstevel@tonic-gate * Use is subject to license terms. 64*0Sstevel@tonic-gate * 65*0Sstevel@tonic-gate */ 66*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate #include <stdio.h> 70*0Sstevel@tonic-gate #include <openssl/objects.h> 71*0Sstevel@tonic-gate #include <openssl/comp.h> 72*0Sstevel@tonic-gate #include "ssl_locl.h" 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate #define SSL_ENC_DES_IDX 0 75*0Sstevel@tonic-gate #define SSL_ENC_3DES_IDX 1 76*0Sstevel@tonic-gate #define SSL_ENC_RC4_IDX 2 77*0Sstevel@tonic-gate #define SSL_ENC_RC2_IDX 3 78*0Sstevel@tonic-gate #define SSL_ENC_IDEA_IDX 4 79*0Sstevel@tonic-gate #define SSL_ENC_eFZA_IDX 5 80*0Sstevel@tonic-gate #define SSL_ENC_NULL_IDX 6 81*0Sstevel@tonic-gate #define SSL_ENC_AES128_IDX 7 82*0Sstevel@tonic-gate #define SSL_ENC_AES256_IDX 8 83*0Sstevel@tonic-gate #define SSL_ENC_NUM_IDX 9 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={ 86*0Sstevel@tonic-gate NULL,NULL,NULL,NULL,NULL,NULL, 87*0Sstevel@tonic-gate }; 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL; 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate #define SSL_MD_MD5_IDX 0 92*0Sstevel@tonic-gate #define SSL_MD_SHA1_IDX 1 93*0Sstevel@tonic-gate #define SSL_MD_NUM_IDX 2 94*0Sstevel@tonic-gate static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={ 95*0Sstevel@tonic-gate NULL,NULL, 96*0Sstevel@tonic-gate }; 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate #define CIPHER_ADD 1 99*0Sstevel@tonic-gate #define CIPHER_KILL 2 100*0Sstevel@tonic-gate #define CIPHER_DEL 3 101*0Sstevel@tonic-gate #define CIPHER_ORD 4 102*0Sstevel@tonic-gate #define CIPHER_SPECIAL 5 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate typedef struct cipher_order_st 105*0Sstevel@tonic-gate { 106*0Sstevel@tonic-gate SSL_CIPHER *cipher; 107*0Sstevel@tonic-gate int active; 108*0Sstevel@tonic-gate int dead; 109*0Sstevel@tonic-gate struct cipher_order_st *next,*prev; 110*0Sstevel@tonic-gate } CIPHER_ORDER; 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate static const SSL_CIPHER cipher_aliases[]={ 113*0Sstevel@tonic-gate /* Don't include eNULL unless specifically enabled. */ 114*0Sstevel@tonic-gate {0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL, SSL_ALL ,0,0,0,SSL_ALL,SSL_ALL}, /* must be first */ 115*0Sstevel@tonic-gate {0,SSL_TXT_CMPALL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0}, /* COMPLEMENT OF ALL */ 116*0Sstevel@tonic-gate {0,SSL_TXT_CMPDEF,0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK,0}, 117*0Sstevel@tonic-gate {0,SSL_TXT_kKRB5,0,SSL_kKRB5,0,0,0,0,SSL_MKEY_MASK,0}, /* VRS Kerberos5 */ 118*0Sstevel@tonic-gate {0,SSL_TXT_kRSA,0,SSL_kRSA, 0,0,0,0,SSL_MKEY_MASK,0}, 119*0Sstevel@tonic-gate {0,SSL_TXT_kDHr,0,SSL_kDHr, 0,0,0,0,SSL_MKEY_MASK,0}, 120*0Sstevel@tonic-gate {0,SSL_TXT_kDHd,0,SSL_kDHd, 0,0,0,0,SSL_MKEY_MASK,0}, 121*0Sstevel@tonic-gate {0,SSL_TXT_kEDH,0,SSL_kEDH, 0,0,0,0,SSL_MKEY_MASK,0}, 122*0Sstevel@tonic-gate {0,SSL_TXT_kFZA,0,SSL_kFZA, 0,0,0,0,SSL_MKEY_MASK,0}, 123*0Sstevel@tonic-gate {0,SSL_TXT_DH, 0,SSL_DH, 0,0,0,0,SSL_MKEY_MASK,0}, 124*0Sstevel@tonic-gate {0,SSL_TXT_EDH, 0,SSL_EDH, 0,0,0,0,SSL_MKEY_MASK|SSL_AUTH_MASK,0}, 125*0Sstevel@tonic-gate 126*0Sstevel@tonic-gate {0,SSL_TXT_aKRB5,0,SSL_aKRB5,0,0,0,0,SSL_AUTH_MASK,0}, /* VRS Kerberos5 */ 127*0Sstevel@tonic-gate {0,SSL_TXT_aRSA,0,SSL_aRSA, 0,0,0,0,SSL_AUTH_MASK,0}, 128*0Sstevel@tonic-gate {0,SSL_TXT_aDSS,0,SSL_aDSS, 0,0,0,0,SSL_AUTH_MASK,0}, 129*0Sstevel@tonic-gate {0,SSL_TXT_aFZA,0,SSL_aFZA, 0,0,0,0,SSL_AUTH_MASK,0}, 130*0Sstevel@tonic-gate {0,SSL_TXT_aNULL,0,SSL_aNULL,0,0,0,0,SSL_AUTH_MASK,0}, 131*0Sstevel@tonic-gate {0,SSL_TXT_aDH, 0,SSL_aDH, 0,0,0,0,SSL_AUTH_MASK,0}, 132*0Sstevel@tonic-gate {0,SSL_TXT_DSS, 0,SSL_DSS, 0,0,0,0,SSL_AUTH_MASK,0}, 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate {0,SSL_TXT_DES, 0,SSL_DES, 0,0,0,0,SSL_ENC_MASK,0}, 135*0Sstevel@tonic-gate {0,SSL_TXT_3DES,0,SSL_3DES, 0,0,0,0,SSL_ENC_MASK,0}, 136*0Sstevel@tonic-gate {0,SSL_TXT_RC4, 0,SSL_RC4, 0,0,0,0,SSL_ENC_MASK,0}, 137*0Sstevel@tonic-gate {0,SSL_TXT_RC2, 0,SSL_RC2, 0,0,0,0,SSL_ENC_MASK,0}, 138*0Sstevel@tonic-gate #ifndef OPENSSL_NO_IDEA 139*0Sstevel@tonic-gate {0,SSL_TXT_IDEA,0,SSL_IDEA, 0,0,0,0,SSL_ENC_MASK,0}, 140*0Sstevel@tonic-gate #endif 141*0Sstevel@tonic-gate {0,SSL_TXT_eNULL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0}, 142*0Sstevel@tonic-gate {0,SSL_TXT_eFZA,0,SSL_eFZA, 0,0,0,0,SSL_ENC_MASK,0}, 143*0Sstevel@tonic-gate {0,SSL_TXT_AES, 0,SSL_AES, 0,0,0,0,SSL_ENC_MASK,0}, 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate {0,SSL_TXT_MD5, 0,SSL_MD5, 0,0,0,0,SSL_MAC_MASK,0}, 146*0Sstevel@tonic-gate {0,SSL_TXT_SHA1,0,SSL_SHA1, 0,0,0,0,SSL_MAC_MASK,0}, 147*0Sstevel@tonic-gate {0,SSL_TXT_SHA, 0,SSL_SHA, 0,0,0,0,SSL_MAC_MASK,0}, 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate {0,SSL_TXT_NULL,0,SSL_NULL, 0,0,0,0,SSL_ENC_MASK,0}, 150*0Sstevel@tonic-gate {0,SSL_TXT_KRB5,0,SSL_KRB5, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, 151*0Sstevel@tonic-gate {0,SSL_TXT_RSA, 0,SSL_RSA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, 152*0Sstevel@tonic-gate {0,SSL_TXT_ADH, 0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, 153*0Sstevel@tonic-gate {0,SSL_TXT_FZA, 0,SSL_FZA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK|SSL_ENC_MASK,0}, 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate {0,SSL_TXT_SSLV2, 0,SSL_SSLV2, 0,0,0,0,SSL_SSL_MASK,0}, 156*0Sstevel@tonic-gate {0,SSL_TXT_SSLV3, 0,SSL_SSLV3, 0,0,0,0,SSL_SSL_MASK,0}, 157*0Sstevel@tonic-gate {0,SSL_TXT_TLSV1, 0,SSL_TLSV1, 0,0,0,0,SSL_SSL_MASK,0}, 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate {0,SSL_TXT_EXP ,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK}, 160*0Sstevel@tonic-gate {0,SSL_TXT_EXPORT,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK}, 161*0Sstevel@tonic-gate {0,SSL_TXT_EXP40, 0, 0, SSL_EXP40, 0,0,0,0,SSL_STRONG_MASK}, 162*0Sstevel@tonic-gate {0,SSL_TXT_EXP56, 0, 0, SSL_EXP56, 0,0,0,0,SSL_STRONG_MASK}, 163*0Sstevel@tonic-gate {0,SSL_TXT_LOW, 0, 0, SSL_LOW, 0,0,0,0,SSL_STRONG_MASK}, 164*0Sstevel@tonic-gate {0,SSL_TXT_MEDIUM,0, 0,SSL_MEDIUM, 0,0,0,0,SSL_STRONG_MASK}, 165*0Sstevel@tonic-gate {0,SSL_TXT_HIGH, 0, 0, SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK}, 166*0Sstevel@tonic-gate }; 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate static int init_ciphers=1; 169*0Sstevel@tonic-gate 170*0Sstevel@tonic-gate static void load_ciphers(void) 171*0Sstevel@tonic-gate { 172*0Sstevel@tonic-gate init_ciphers=0; 173*0Sstevel@tonic-gate ssl_cipher_methods[SSL_ENC_DES_IDX]= 174*0Sstevel@tonic-gate EVP_get_cipherbyname(SN_des_cbc); 175*0Sstevel@tonic-gate ssl_cipher_methods[SSL_ENC_3DES_IDX]= 176*0Sstevel@tonic-gate EVP_get_cipherbyname(SN_des_ede3_cbc); 177*0Sstevel@tonic-gate ssl_cipher_methods[SSL_ENC_RC4_IDX]= 178*0Sstevel@tonic-gate EVP_get_cipherbyname(SN_rc4); 179*0Sstevel@tonic-gate ssl_cipher_methods[SSL_ENC_RC2_IDX]= 180*0Sstevel@tonic-gate EVP_get_cipherbyname(SN_rc2_cbc); 181*0Sstevel@tonic-gate #ifndef OPENSSL_NO_IDEA 182*0Sstevel@tonic-gate ssl_cipher_methods[SSL_ENC_IDEA_IDX]= 183*0Sstevel@tonic-gate EVP_get_cipherbyname(SN_idea_cbc); 184*0Sstevel@tonic-gate #else 185*0Sstevel@tonic-gate ssl_cipher_methods[SSL_ENC_IDEA_IDX]= NULL; 186*0Sstevel@tonic-gate #endif 187*0Sstevel@tonic-gate ssl_cipher_methods[SSL_ENC_AES128_IDX]= 188*0Sstevel@tonic-gate EVP_get_cipherbyname(SN_aes_128_cbc); 189*0Sstevel@tonic-gate #ifdef CRYPTO_UNLIMITED 190*0Sstevel@tonic-gate ssl_cipher_methods[SSL_ENC_AES256_IDX]= 191*0Sstevel@tonic-gate EVP_get_cipherbyname(SN_aes_256_cbc); 192*0Sstevel@tonic-gate #endif 193*0Sstevel@tonic-gate ssl_digest_methods[SSL_MD_MD5_IDX]= 194*0Sstevel@tonic-gate EVP_get_digestbyname(SN_md5); 195*0Sstevel@tonic-gate ssl_digest_methods[SSL_MD_SHA1_IDX]= 196*0Sstevel@tonic-gate EVP_get_digestbyname(SN_sha1); 197*0Sstevel@tonic-gate } 198*0Sstevel@tonic-gate 199*0Sstevel@tonic-gate int ssl_cipher_get_evp(SSL_SESSION *s, const EVP_CIPHER **enc, 200*0Sstevel@tonic-gate const EVP_MD **md, SSL_COMP **comp) 201*0Sstevel@tonic-gate { 202*0Sstevel@tonic-gate int i; 203*0Sstevel@tonic-gate SSL_CIPHER *c; 204*0Sstevel@tonic-gate 205*0Sstevel@tonic-gate c=s->cipher; 206*0Sstevel@tonic-gate if (c == NULL) return(0); 207*0Sstevel@tonic-gate if (comp != NULL) 208*0Sstevel@tonic-gate { 209*0Sstevel@tonic-gate SSL_COMP ctmp; 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate if (s->compress_meth == 0) 212*0Sstevel@tonic-gate *comp=NULL; 213*0Sstevel@tonic-gate else if (ssl_comp_methods == NULL) 214*0Sstevel@tonic-gate { 215*0Sstevel@tonic-gate /* bad */ 216*0Sstevel@tonic-gate *comp=NULL; 217*0Sstevel@tonic-gate } 218*0Sstevel@tonic-gate else 219*0Sstevel@tonic-gate { 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate ctmp.id=s->compress_meth; 222*0Sstevel@tonic-gate i=sk_SSL_COMP_find(ssl_comp_methods,&ctmp); 223*0Sstevel@tonic-gate if (i >= 0) 224*0Sstevel@tonic-gate *comp=sk_SSL_COMP_value(ssl_comp_methods,i); 225*0Sstevel@tonic-gate else 226*0Sstevel@tonic-gate *comp=NULL; 227*0Sstevel@tonic-gate } 228*0Sstevel@tonic-gate } 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate if ((enc == NULL) || (md == NULL)) return(0); 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate switch (c->algorithms & SSL_ENC_MASK) 233*0Sstevel@tonic-gate { 234*0Sstevel@tonic-gate case SSL_DES: 235*0Sstevel@tonic-gate i=SSL_ENC_DES_IDX; 236*0Sstevel@tonic-gate break; 237*0Sstevel@tonic-gate case SSL_3DES: 238*0Sstevel@tonic-gate i=SSL_ENC_3DES_IDX; 239*0Sstevel@tonic-gate break; 240*0Sstevel@tonic-gate case SSL_RC4: 241*0Sstevel@tonic-gate i=SSL_ENC_RC4_IDX; 242*0Sstevel@tonic-gate break; 243*0Sstevel@tonic-gate case SSL_RC2: 244*0Sstevel@tonic-gate i=SSL_ENC_RC2_IDX; 245*0Sstevel@tonic-gate break; 246*0Sstevel@tonic-gate case SSL_IDEA: 247*0Sstevel@tonic-gate i=SSL_ENC_IDEA_IDX; 248*0Sstevel@tonic-gate break; 249*0Sstevel@tonic-gate case SSL_eNULL: 250*0Sstevel@tonic-gate i=SSL_ENC_NULL_IDX; 251*0Sstevel@tonic-gate break; 252*0Sstevel@tonic-gate case SSL_AES: 253*0Sstevel@tonic-gate switch(c->alg_bits) 254*0Sstevel@tonic-gate { 255*0Sstevel@tonic-gate case 128: i=SSL_ENC_AES128_IDX; break; 256*0Sstevel@tonic-gate case 256: i=SSL_ENC_AES256_IDX; break; 257*0Sstevel@tonic-gate default: i=-1; break; 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate break; 260*0Sstevel@tonic-gate default: 261*0Sstevel@tonic-gate i= -1; 262*0Sstevel@tonic-gate break; 263*0Sstevel@tonic-gate } 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate if ((i < 0) || (i > SSL_ENC_NUM_IDX)) 266*0Sstevel@tonic-gate *enc=NULL; 267*0Sstevel@tonic-gate else 268*0Sstevel@tonic-gate { 269*0Sstevel@tonic-gate if (i == SSL_ENC_NULL_IDX) 270*0Sstevel@tonic-gate *enc=EVP_enc_null(); 271*0Sstevel@tonic-gate else 272*0Sstevel@tonic-gate *enc=ssl_cipher_methods[i]; 273*0Sstevel@tonic-gate } 274*0Sstevel@tonic-gate 275*0Sstevel@tonic-gate switch (c->algorithms & SSL_MAC_MASK) 276*0Sstevel@tonic-gate { 277*0Sstevel@tonic-gate case SSL_MD5: 278*0Sstevel@tonic-gate i=SSL_MD_MD5_IDX; 279*0Sstevel@tonic-gate break; 280*0Sstevel@tonic-gate case SSL_SHA1: 281*0Sstevel@tonic-gate i=SSL_MD_SHA1_IDX; 282*0Sstevel@tonic-gate break; 283*0Sstevel@tonic-gate default: 284*0Sstevel@tonic-gate i= -1; 285*0Sstevel@tonic-gate break; 286*0Sstevel@tonic-gate } 287*0Sstevel@tonic-gate if ((i < 0) || (i > SSL_MD_NUM_IDX)) 288*0Sstevel@tonic-gate *md=NULL; 289*0Sstevel@tonic-gate else 290*0Sstevel@tonic-gate *md=ssl_digest_methods[i]; 291*0Sstevel@tonic-gate 292*0Sstevel@tonic-gate if ((*enc != NULL) && (*md != NULL)) 293*0Sstevel@tonic-gate return(1); 294*0Sstevel@tonic-gate else 295*0Sstevel@tonic-gate return(0); 296*0Sstevel@tonic-gate } 297*0Sstevel@tonic-gate 298*0Sstevel@tonic-gate #define ITEM_SEP(a) \ 299*0Sstevel@tonic-gate (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, 302*0Sstevel@tonic-gate CIPHER_ORDER **tail) 303*0Sstevel@tonic-gate { 304*0Sstevel@tonic-gate if (curr == *tail) return; 305*0Sstevel@tonic-gate if (curr == *head) 306*0Sstevel@tonic-gate *head=curr->next; 307*0Sstevel@tonic-gate if (curr->prev != NULL) 308*0Sstevel@tonic-gate curr->prev->next=curr->next; 309*0Sstevel@tonic-gate if (curr->next != NULL) /* should always be true */ 310*0Sstevel@tonic-gate curr->next->prev=curr->prev; 311*0Sstevel@tonic-gate (*tail)->next=curr; 312*0Sstevel@tonic-gate curr->prev= *tail; 313*0Sstevel@tonic-gate curr->next=NULL; 314*0Sstevel@tonic-gate *tail=curr; 315*0Sstevel@tonic-gate } 316*0Sstevel@tonic-gate 317*0Sstevel@tonic-gate static unsigned long ssl_cipher_get_disabled(void) 318*0Sstevel@tonic-gate { 319*0Sstevel@tonic-gate unsigned long mask; 320*0Sstevel@tonic-gate 321*0Sstevel@tonic-gate mask = SSL_kFZA; 322*0Sstevel@tonic-gate #ifdef OPENSSL_NO_RSA 323*0Sstevel@tonic-gate mask |= SSL_aRSA|SSL_kRSA; 324*0Sstevel@tonic-gate #endif 325*0Sstevel@tonic-gate #ifdef OPENSSL_NO_DSA 326*0Sstevel@tonic-gate mask |= SSL_aDSS; 327*0Sstevel@tonic-gate #endif 328*0Sstevel@tonic-gate #ifdef OPENSSL_NO_DH 329*0Sstevel@tonic-gate mask |= SSL_kDHr|SSL_kDHd|SSL_kEDH|SSL_aDH; 330*0Sstevel@tonic-gate #endif 331*0Sstevel@tonic-gate #ifdef OPENSSL_NO_KRB5 332*0Sstevel@tonic-gate mask |= SSL_kKRB5|SSL_aKRB5; 333*0Sstevel@tonic-gate #endif 334*0Sstevel@tonic-gate 335*0Sstevel@tonic-gate #ifdef SSL_FORBID_ENULL 336*0Sstevel@tonic-gate mask |= SSL_eNULL; 337*0Sstevel@tonic-gate #endif 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate mask |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0; 340*0Sstevel@tonic-gate mask |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0; 341*0Sstevel@tonic-gate mask |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0; 342*0Sstevel@tonic-gate mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0; 343*0Sstevel@tonic-gate mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0; 344*0Sstevel@tonic-gate mask |= (ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL) ? SSL_eFZA:0; 345*0Sstevel@tonic-gate mask |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES:0; 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0; 348*0Sstevel@tonic-gate mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0; 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate return(mask); 351*0Sstevel@tonic-gate } 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gate static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, 354*0Sstevel@tonic-gate int num_of_ciphers, unsigned long mask, CIPHER_ORDER *co_list, 355*0Sstevel@tonic-gate CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) 356*0Sstevel@tonic-gate { 357*0Sstevel@tonic-gate int i, co_list_num; 358*0Sstevel@tonic-gate SSL_CIPHER *c; 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gate /* 361*0Sstevel@tonic-gate * We have num_of_ciphers descriptions compiled in, depending on the 362*0Sstevel@tonic-gate * method selected (SSLv2 and/or SSLv3, TLSv1 etc). 363*0Sstevel@tonic-gate * These will later be sorted in a linked list with at most num 364*0Sstevel@tonic-gate * entries. 365*0Sstevel@tonic-gate */ 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate /* Get the initial list of ciphers */ 368*0Sstevel@tonic-gate co_list_num = 0; /* actual count of ciphers */ 369*0Sstevel@tonic-gate for (i = 0; i < num_of_ciphers; i++) 370*0Sstevel@tonic-gate { 371*0Sstevel@tonic-gate c = ssl_method->get_cipher(i); 372*0Sstevel@tonic-gate /* drop those that use any of that is not available */ 373*0Sstevel@tonic-gate if ((c != NULL) && c->valid && !(c->algorithms & mask)) 374*0Sstevel@tonic-gate { 375*0Sstevel@tonic-gate co_list[co_list_num].cipher = c; 376*0Sstevel@tonic-gate co_list[co_list_num].next = NULL; 377*0Sstevel@tonic-gate co_list[co_list_num].prev = NULL; 378*0Sstevel@tonic-gate co_list[co_list_num].active = 0; 379*0Sstevel@tonic-gate co_list_num++; 380*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 381*0Sstevel@tonic-gate printf("\t%d: %s %lx %lx\n",i,c->name,c->id,c->algorithms); 382*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 383*0Sstevel@tonic-gate /* 384*0Sstevel@tonic-gate if (!sk_push(ca_list,(char *)c)) goto err; 385*0Sstevel@tonic-gate */ 386*0Sstevel@tonic-gate } 387*0Sstevel@tonic-gate } 388*0Sstevel@tonic-gate 389*0Sstevel@tonic-gate /* 390*0Sstevel@tonic-gate * Prepare linked list from list entries 391*0Sstevel@tonic-gate */ 392*0Sstevel@tonic-gate for (i = 1; i < co_list_num - 1; i++) 393*0Sstevel@tonic-gate { 394*0Sstevel@tonic-gate co_list[i].prev = &(co_list[i-1]); 395*0Sstevel@tonic-gate co_list[i].next = &(co_list[i+1]); 396*0Sstevel@tonic-gate } 397*0Sstevel@tonic-gate if (co_list_num > 0) 398*0Sstevel@tonic-gate { 399*0Sstevel@tonic-gate (*head_p) = &(co_list[0]); 400*0Sstevel@tonic-gate (*head_p)->prev = NULL; 401*0Sstevel@tonic-gate (*head_p)->next = &(co_list[1]); 402*0Sstevel@tonic-gate (*tail_p) = &(co_list[co_list_num - 1]); 403*0Sstevel@tonic-gate (*tail_p)->prev = &(co_list[co_list_num - 2]); 404*0Sstevel@tonic-gate (*tail_p)->next = NULL; 405*0Sstevel@tonic-gate } 406*0Sstevel@tonic-gate } 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gate static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list, 409*0Sstevel@tonic-gate int num_of_group_aliases, unsigned long mask, 410*0Sstevel@tonic-gate CIPHER_ORDER *head) 411*0Sstevel@tonic-gate { 412*0Sstevel@tonic-gate CIPHER_ORDER *ciph_curr; 413*0Sstevel@tonic-gate SSL_CIPHER **ca_curr; 414*0Sstevel@tonic-gate int i; 415*0Sstevel@tonic-gate 416*0Sstevel@tonic-gate /* 417*0Sstevel@tonic-gate * First, add the real ciphers as already collected 418*0Sstevel@tonic-gate */ 419*0Sstevel@tonic-gate ciph_curr = head; 420*0Sstevel@tonic-gate ca_curr = ca_list; 421*0Sstevel@tonic-gate while (ciph_curr != NULL) 422*0Sstevel@tonic-gate { 423*0Sstevel@tonic-gate *ca_curr = ciph_curr->cipher; 424*0Sstevel@tonic-gate ca_curr++; 425*0Sstevel@tonic-gate ciph_curr = ciph_curr->next; 426*0Sstevel@tonic-gate } 427*0Sstevel@tonic-gate 428*0Sstevel@tonic-gate /* 429*0Sstevel@tonic-gate * Now we add the available ones from the cipher_aliases[] table. 430*0Sstevel@tonic-gate * They represent either an algorithm, that must be fully 431*0Sstevel@tonic-gate * supported (not match any bit in mask) or represent a cipher 432*0Sstevel@tonic-gate * strength value (will be added in any case because algorithms=0). 433*0Sstevel@tonic-gate */ 434*0Sstevel@tonic-gate for (i = 0; i < num_of_group_aliases; i++) 435*0Sstevel@tonic-gate { 436*0Sstevel@tonic-gate if ((i == 0) || /* always fetch "ALL" */ 437*0Sstevel@tonic-gate !(cipher_aliases[i].algorithms & mask)) 438*0Sstevel@tonic-gate { 439*0Sstevel@tonic-gate *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); 440*0Sstevel@tonic-gate ca_curr++; 441*0Sstevel@tonic-gate } 442*0Sstevel@tonic-gate } 443*0Sstevel@tonic-gate 444*0Sstevel@tonic-gate *ca_curr = NULL; /* end of list */ 445*0Sstevel@tonic-gate } 446*0Sstevel@tonic-gate 447*0Sstevel@tonic-gate static void ssl_cipher_apply_rule(unsigned long algorithms, unsigned long mask, 448*0Sstevel@tonic-gate unsigned long algo_strength, unsigned long mask_strength, 449*0Sstevel@tonic-gate int rule, int strength_bits, CIPHER_ORDER *co_list, 450*0Sstevel@tonic-gate CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) 451*0Sstevel@tonic-gate { 452*0Sstevel@tonic-gate CIPHER_ORDER *head, *tail, *curr, *curr2, *tail2; 453*0Sstevel@tonic-gate SSL_CIPHER *cp; 454*0Sstevel@tonic-gate unsigned long ma, ma_s; 455*0Sstevel@tonic-gate 456*0Sstevel@tonic-gate #ifdef CIPHER_DEBUG 457*0Sstevel@tonic-gate printf("Applying rule %d with %08lx %08lx %08lx %08lx (%d)\n", 458*0Sstevel@tonic-gate rule, algorithms, mask, algo_strength, mask_strength, 459*0Sstevel@tonic-gate strength_bits); 460*0Sstevel@tonic-gate #endif 461*0Sstevel@tonic-gate 462*0Sstevel@tonic-gate curr = head = *head_p; 463*0Sstevel@tonic-gate curr2 = head; 464*0Sstevel@tonic-gate tail2 = tail = *tail_p; 465*0Sstevel@tonic-gate for (;;) 466*0Sstevel@tonic-gate { 467*0Sstevel@tonic-gate if ((curr == NULL) || (curr == tail2)) break; 468*0Sstevel@tonic-gate curr = curr2; 469*0Sstevel@tonic-gate curr2 = curr->next; 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate cp = curr->cipher; 472*0Sstevel@tonic-gate 473*0Sstevel@tonic-gate /* 474*0Sstevel@tonic-gate * Selection criteria is either the number of strength_bits 475*0Sstevel@tonic-gate * or the algorithm used. 476*0Sstevel@tonic-gate */ 477*0Sstevel@tonic-gate if (strength_bits == -1) 478*0Sstevel@tonic-gate { 479*0Sstevel@tonic-gate ma = mask & cp->algorithms; 480*0Sstevel@tonic-gate ma_s = mask_strength & cp->algo_strength; 481*0Sstevel@tonic-gate 482*0Sstevel@tonic-gate #ifdef CIPHER_DEBUG 483*0Sstevel@tonic-gate printf("\nName: %s:\nAlgo = %08lx Algo_strength = %08lx\nMask = %08lx Mask_strength %08lx\n", cp->name, cp->algorithms, cp->algo_strength, mask, mask_strength); 484*0Sstevel@tonic-gate printf("ma = %08lx ma_s %08lx, ma&algo=%08lx, ma_s&algos=%08lx\n", ma, ma_s, ma&algorithms, ma_s&algo_strength); 485*0Sstevel@tonic-gate #endif 486*0Sstevel@tonic-gate /* 487*0Sstevel@tonic-gate * Select: if none of the mask bit was met from the 488*0Sstevel@tonic-gate * cipher or not all of the bits were met, the 489*0Sstevel@tonic-gate * selection does not apply. 490*0Sstevel@tonic-gate */ 491*0Sstevel@tonic-gate if (((ma == 0) && (ma_s == 0)) || 492*0Sstevel@tonic-gate ((ma & algorithms) != ma) || 493*0Sstevel@tonic-gate ((ma_s & algo_strength) != ma_s)) 494*0Sstevel@tonic-gate continue; /* does not apply */ 495*0Sstevel@tonic-gate } 496*0Sstevel@tonic-gate else if (strength_bits != cp->strength_bits) 497*0Sstevel@tonic-gate continue; /* does not apply */ 498*0Sstevel@tonic-gate 499*0Sstevel@tonic-gate #ifdef CIPHER_DEBUG 500*0Sstevel@tonic-gate printf("Action = %d\n", rule); 501*0Sstevel@tonic-gate #endif 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gate /* add the cipher if it has not been added yet. */ 504*0Sstevel@tonic-gate if (rule == CIPHER_ADD) 505*0Sstevel@tonic-gate { 506*0Sstevel@tonic-gate if (!curr->active) 507*0Sstevel@tonic-gate { 508*0Sstevel@tonic-gate ll_append_tail(&head, curr, &tail); 509*0Sstevel@tonic-gate curr->active = 1; 510*0Sstevel@tonic-gate } 511*0Sstevel@tonic-gate } 512*0Sstevel@tonic-gate /* Move the added cipher to this location */ 513*0Sstevel@tonic-gate else if (rule == CIPHER_ORD) 514*0Sstevel@tonic-gate { 515*0Sstevel@tonic-gate if (curr->active) 516*0Sstevel@tonic-gate { 517*0Sstevel@tonic-gate ll_append_tail(&head, curr, &tail); 518*0Sstevel@tonic-gate } 519*0Sstevel@tonic-gate } 520*0Sstevel@tonic-gate else if (rule == CIPHER_DEL) 521*0Sstevel@tonic-gate curr->active = 0; 522*0Sstevel@tonic-gate else if (rule == CIPHER_KILL) 523*0Sstevel@tonic-gate { 524*0Sstevel@tonic-gate if (head == curr) 525*0Sstevel@tonic-gate head = curr->next; 526*0Sstevel@tonic-gate else 527*0Sstevel@tonic-gate curr->prev->next = curr->next; 528*0Sstevel@tonic-gate if (tail == curr) 529*0Sstevel@tonic-gate tail = curr->prev; 530*0Sstevel@tonic-gate curr->active = 0; 531*0Sstevel@tonic-gate if (curr->next != NULL) 532*0Sstevel@tonic-gate curr->next->prev = curr->prev; 533*0Sstevel@tonic-gate if (curr->prev != NULL) 534*0Sstevel@tonic-gate curr->prev->next = curr->next; 535*0Sstevel@tonic-gate curr->next = NULL; 536*0Sstevel@tonic-gate curr->prev = NULL; 537*0Sstevel@tonic-gate } 538*0Sstevel@tonic-gate } 539*0Sstevel@tonic-gate 540*0Sstevel@tonic-gate *head_p = head; 541*0Sstevel@tonic-gate *tail_p = tail; 542*0Sstevel@tonic-gate } 543*0Sstevel@tonic-gate 544*0Sstevel@tonic-gate static int ssl_cipher_strength_sort(CIPHER_ORDER *co_list, 545*0Sstevel@tonic-gate CIPHER_ORDER **head_p, 546*0Sstevel@tonic-gate CIPHER_ORDER **tail_p) 547*0Sstevel@tonic-gate { 548*0Sstevel@tonic-gate int max_strength_bits, i, *number_uses; 549*0Sstevel@tonic-gate CIPHER_ORDER *curr; 550*0Sstevel@tonic-gate 551*0Sstevel@tonic-gate /* 552*0Sstevel@tonic-gate * This routine sorts the ciphers with descending strength. The sorting 553*0Sstevel@tonic-gate * must keep the pre-sorted sequence, so we apply the normal sorting 554*0Sstevel@tonic-gate * routine as '+' movement to the end of the list. 555*0Sstevel@tonic-gate */ 556*0Sstevel@tonic-gate max_strength_bits = 0; 557*0Sstevel@tonic-gate curr = *head_p; 558*0Sstevel@tonic-gate while (curr != NULL) 559*0Sstevel@tonic-gate { 560*0Sstevel@tonic-gate if (curr->active && 561*0Sstevel@tonic-gate (curr->cipher->strength_bits > max_strength_bits)) 562*0Sstevel@tonic-gate max_strength_bits = curr->cipher->strength_bits; 563*0Sstevel@tonic-gate curr = curr->next; 564*0Sstevel@tonic-gate } 565*0Sstevel@tonic-gate 566*0Sstevel@tonic-gate number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int)); 567*0Sstevel@tonic-gate if (!number_uses) 568*0Sstevel@tonic-gate { 569*0Sstevel@tonic-gate SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT,ERR_R_MALLOC_FAILURE); 570*0Sstevel@tonic-gate return(0); 571*0Sstevel@tonic-gate } 572*0Sstevel@tonic-gate memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int)); 573*0Sstevel@tonic-gate 574*0Sstevel@tonic-gate /* 575*0Sstevel@tonic-gate * Now find the strength_bits values actually used 576*0Sstevel@tonic-gate */ 577*0Sstevel@tonic-gate curr = *head_p; 578*0Sstevel@tonic-gate while (curr != NULL) 579*0Sstevel@tonic-gate { 580*0Sstevel@tonic-gate if (curr->active) 581*0Sstevel@tonic-gate number_uses[curr->cipher->strength_bits]++; 582*0Sstevel@tonic-gate curr = curr->next; 583*0Sstevel@tonic-gate } 584*0Sstevel@tonic-gate /* 585*0Sstevel@tonic-gate * Go through the list of used strength_bits values in descending 586*0Sstevel@tonic-gate * order. 587*0Sstevel@tonic-gate */ 588*0Sstevel@tonic-gate for (i = max_strength_bits; i >= 0; i--) 589*0Sstevel@tonic-gate if (number_uses[i] > 0) 590*0Sstevel@tonic-gate ssl_cipher_apply_rule(0, 0, 0, 0, CIPHER_ORD, i, 591*0Sstevel@tonic-gate co_list, head_p, tail_p); 592*0Sstevel@tonic-gate 593*0Sstevel@tonic-gate OPENSSL_free(number_uses); 594*0Sstevel@tonic-gate return(1); 595*0Sstevel@tonic-gate } 596*0Sstevel@tonic-gate 597*0Sstevel@tonic-gate static int ssl_cipher_process_rulestr(const char *rule_str, 598*0Sstevel@tonic-gate CIPHER_ORDER *co_list, CIPHER_ORDER **head_p, 599*0Sstevel@tonic-gate CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list) 600*0Sstevel@tonic-gate { 601*0Sstevel@tonic-gate unsigned long algorithms, mask, algo_strength, mask_strength; 602*0Sstevel@tonic-gate const char *l, *start, *buf; 603*0Sstevel@tonic-gate int j, multi, found, rule, retval, ok, buflen; 604*0Sstevel@tonic-gate char ch; 605*0Sstevel@tonic-gate 606*0Sstevel@tonic-gate retval = 1; 607*0Sstevel@tonic-gate l = rule_str; 608*0Sstevel@tonic-gate for (;;) 609*0Sstevel@tonic-gate { 610*0Sstevel@tonic-gate ch = *l; 611*0Sstevel@tonic-gate 612*0Sstevel@tonic-gate if (ch == '\0') 613*0Sstevel@tonic-gate break; /* done */ 614*0Sstevel@tonic-gate if (ch == '-') 615*0Sstevel@tonic-gate { rule = CIPHER_DEL; l++; } 616*0Sstevel@tonic-gate else if (ch == '+') 617*0Sstevel@tonic-gate { rule = CIPHER_ORD; l++; } 618*0Sstevel@tonic-gate else if (ch == '!') 619*0Sstevel@tonic-gate { rule = CIPHER_KILL; l++; } 620*0Sstevel@tonic-gate else if (ch == '@') 621*0Sstevel@tonic-gate { rule = CIPHER_SPECIAL; l++; } 622*0Sstevel@tonic-gate else 623*0Sstevel@tonic-gate { rule = CIPHER_ADD; } 624*0Sstevel@tonic-gate 625*0Sstevel@tonic-gate if (ITEM_SEP(ch)) 626*0Sstevel@tonic-gate { 627*0Sstevel@tonic-gate l++; 628*0Sstevel@tonic-gate continue; 629*0Sstevel@tonic-gate } 630*0Sstevel@tonic-gate 631*0Sstevel@tonic-gate algorithms = mask = algo_strength = mask_strength = 0; 632*0Sstevel@tonic-gate 633*0Sstevel@tonic-gate start=l; 634*0Sstevel@tonic-gate for (;;) 635*0Sstevel@tonic-gate { 636*0Sstevel@tonic-gate ch = *l; 637*0Sstevel@tonic-gate buf = l; 638*0Sstevel@tonic-gate buflen = 0; 639*0Sstevel@tonic-gate #ifndef CHARSET_EBCDIC 640*0Sstevel@tonic-gate while ( ((ch >= 'A') && (ch <= 'Z')) || 641*0Sstevel@tonic-gate ((ch >= '0') && (ch <= '9')) || 642*0Sstevel@tonic-gate ((ch >= 'a') && (ch <= 'z')) || 643*0Sstevel@tonic-gate (ch == '-')) 644*0Sstevel@tonic-gate #else 645*0Sstevel@tonic-gate while ( isalnum(ch) || (ch == '-')) 646*0Sstevel@tonic-gate #endif 647*0Sstevel@tonic-gate { 648*0Sstevel@tonic-gate ch = *(++l); 649*0Sstevel@tonic-gate buflen++; 650*0Sstevel@tonic-gate } 651*0Sstevel@tonic-gate 652*0Sstevel@tonic-gate if (buflen == 0) 653*0Sstevel@tonic-gate { 654*0Sstevel@tonic-gate /* 655*0Sstevel@tonic-gate * We hit something we cannot deal with, 656*0Sstevel@tonic-gate * it is no command or separator nor 657*0Sstevel@tonic-gate * alphanumeric, so we call this an error. 658*0Sstevel@tonic-gate */ 659*0Sstevel@tonic-gate SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, 660*0Sstevel@tonic-gate SSL_R_INVALID_COMMAND); 661*0Sstevel@tonic-gate retval = found = 0; 662*0Sstevel@tonic-gate l++; 663*0Sstevel@tonic-gate break; 664*0Sstevel@tonic-gate } 665*0Sstevel@tonic-gate 666*0Sstevel@tonic-gate if (rule == CIPHER_SPECIAL) 667*0Sstevel@tonic-gate { 668*0Sstevel@tonic-gate found = 0; /* unused -- avoid compiler warning */ 669*0Sstevel@tonic-gate break; /* special treatment */ 670*0Sstevel@tonic-gate } 671*0Sstevel@tonic-gate 672*0Sstevel@tonic-gate /* check for multi-part specification */ 673*0Sstevel@tonic-gate if (ch == '+') 674*0Sstevel@tonic-gate { 675*0Sstevel@tonic-gate multi=1; 676*0Sstevel@tonic-gate l++; 677*0Sstevel@tonic-gate } 678*0Sstevel@tonic-gate else 679*0Sstevel@tonic-gate multi=0; 680*0Sstevel@tonic-gate 681*0Sstevel@tonic-gate /* 682*0Sstevel@tonic-gate * Now search for the cipher alias in the ca_list. Be careful 683*0Sstevel@tonic-gate * with the strncmp, because the "buflen" limitation 684*0Sstevel@tonic-gate * will make the rule "ADH:SOME" and the cipher 685*0Sstevel@tonic-gate * "ADH-MY-CIPHER" look like a match for buflen=3. 686*0Sstevel@tonic-gate * So additionally check whether the cipher name found 687*0Sstevel@tonic-gate * has the correct length. We can save a strlen() call: 688*0Sstevel@tonic-gate * just checking for the '\0' at the right place is 689*0Sstevel@tonic-gate * sufficient, we have to strncmp() anyway. (We cannot 690*0Sstevel@tonic-gate * use strcmp(), because buf is not '\0' terminated.) 691*0Sstevel@tonic-gate */ 692*0Sstevel@tonic-gate j = found = 0; 693*0Sstevel@tonic-gate while (ca_list[j]) 694*0Sstevel@tonic-gate { 695*0Sstevel@tonic-gate if (!strncmp(buf, ca_list[j]->name, buflen) && 696*0Sstevel@tonic-gate (ca_list[j]->name[buflen] == '\0')) 697*0Sstevel@tonic-gate { 698*0Sstevel@tonic-gate found = 1; 699*0Sstevel@tonic-gate break; 700*0Sstevel@tonic-gate } 701*0Sstevel@tonic-gate else 702*0Sstevel@tonic-gate j++; 703*0Sstevel@tonic-gate } 704*0Sstevel@tonic-gate if (!found) 705*0Sstevel@tonic-gate break; /* ignore this entry */ 706*0Sstevel@tonic-gate 707*0Sstevel@tonic-gate algorithms |= ca_list[j]->algorithms; 708*0Sstevel@tonic-gate mask |= ca_list[j]->mask; 709*0Sstevel@tonic-gate algo_strength |= ca_list[j]->algo_strength; 710*0Sstevel@tonic-gate mask_strength |= ca_list[j]->mask_strength; 711*0Sstevel@tonic-gate 712*0Sstevel@tonic-gate if (!multi) break; 713*0Sstevel@tonic-gate } 714*0Sstevel@tonic-gate 715*0Sstevel@tonic-gate /* 716*0Sstevel@tonic-gate * Ok, we have the rule, now apply it 717*0Sstevel@tonic-gate */ 718*0Sstevel@tonic-gate if (rule == CIPHER_SPECIAL) 719*0Sstevel@tonic-gate { /* special command */ 720*0Sstevel@tonic-gate ok = 0; 721*0Sstevel@tonic-gate if ((buflen == 8) && 722*0Sstevel@tonic-gate !strncmp(buf, "STRENGTH", 8)) 723*0Sstevel@tonic-gate ok = ssl_cipher_strength_sort(co_list, 724*0Sstevel@tonic-gate head_p, tail_p); 725*0Sstevel@tonic-gate else 726*0Sstevel@tonic-gate SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, 727*0Sstevel@tonic-gate SSL_R_INVALID_COMMAND); 728*0Sstevel@tonic-gate if (ok == 0) 729*0Sstevel@tonic-gate retval = 0; 730*0Sstevel@tonic-gate /* 731*0Sstevel@tonic-gate * We do not support any "multi" options 732*0Sstevel@tonic-gate * together with "@", so throw away the 733*0Sstevel@tonic-gate * rest of the command, if any left, until 734*0Sstevel@tonic-gate * end or ':' is found. 735*0Sstevel@tonic-gate */ 736*0Sstevel@tonic-gate while ((*l != '\0') && ITEM_SEP(*l)) 737*0Sstevel@tonic-gate l++; 738*0Sstevel@tonic-gate } 739*0Sstevel@tonic-gate else if (found) 740*0Sstevel@tonic-gate { 741*0Sstevel@tonic-gate ssl_cipher_apply_rule(algorithms, mask, 742*0Sstevel@tonic-gate algo_strength, mask_strength, rule, -1, 743*0Sstevel@tonic-gate co_list, head_p, tail_p); 744*0Sstevel@tonic-gate } 745*0Sstevel@tonic-gate else 746*0Sstevel@tonic-gate { 747*0Sstevel@tonic-gate while ((*l != '\0') && ITEM_SEP(*l)) 748*0Sstevel@tonic-gate l++; 749*0Sstevel@tonic-gate } 750*0Sstevel@tonic-gate if (*l == '\0') break; /* done */ 751*0Sstevel@tonic-gate } 752*0Sstevel@tonic-gate 753*0Sstevel@tonic-gate return(retval); 754*0Sstevel@tonic-gate } 755*0Sstevel@tonic-gate 756*0Sstevel@tonic-gate STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, 757*0Sstevel@tonic-gate STACK_OF(SSL_CIPHER) **cipher_list, 758*0Sstevel@tonic-gate STACK_OF(SSL_CIPHER) **cipher_list_by_id, 759*0Sstevel@tonic-gate const char *rule_str) 760*0Sstevel@tonic-gate { 761*0Sstevel@tonic-gate int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; 762*0Sstevel@tonic-gate unsigned long disabled_mask; 763*0Sstevel@tonic-gate STACK_OF(SSL_CIPHER) *cipherstack; 764*0Sstevel@tonic-gate const char *rule_p; 765*0Sstevel@tonic-gate CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; 766*0Sstevel@tonic-gate SSL_CIPHER **ca_list = NULL; 767*0Sstevel@tonic-gate 768*0Sstevel@tonic-gate /* 769*0Sstevel@tonic-gate * Return with error if nothing to do. 770*0Sstevel@tonic-gate */ 771*0Sstevel@tonic-gate if (rule_str == NULL) return(NULL); 772*0Sstevel@tonic-gate 773*0Sstevel@tonic-gate if (init_ciphers) 774*0Sstevel@tonic-gate { 775*0Sstevel@tonic-gate CRYPTO_w_lock(CRYPTO_LOCK_SSL); 776*0Sstevel@tonic-gate if (init_ciphers) load_ciphers(); 777*0Sstevel@tonic-gate CRYPTO_w_unlock(CRYPTO_LOCK_SSL); 778*0Sstevel@tonic-gate } 779*0Sstevel@tonic-gate 780*0Sstevel@tonic-gate /* 781*0Sstevel@tonic-gate * To reduce the work to do we only want to process the compiled 782*0Sstevel@tonic-gate * in algorithms, so we first get the mask of disabled ciphers. 783*0Sstevel@tonic-gate */ 784*0Sstevel@tonic-gate disabled_mask = ssl_cipher_get_disabled(); 785*0Sstevel@tonic-gate 786*0Sstevel@tonic-gate /* 787*0Sstevel@tonic-gate * Now we have to collect the available ciphers from the compiled 788*0Sstevel@tonic-gate * in ciphers. We cannot get more than the number compiled in, so 789*0Sstevel@tonic-gate * it is used for allocation. 790*0Sstevel@tonic-gate */ 791*0Sstevel@tonic-gate num_of_ciphers = ssl_method->num_ciphers(); 792*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 793*0Sstevel@tonic-gate printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers); 794*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 795*0Sstevel@tonic-gate co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers); 796*0Sstevel@tonic-gate if (co_list == NULL) 797*0Sstevel@tonic-gate { 798*0Sstevel@tonic-gate SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE); 799*0Sstevel@tonic-gate return(NULL); /* Failure */ 800*0Sstevel@tonic-gate } 801*0Sstevel@tonic-gate 802*0Sstevel@tonic-gate ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask, 803*0Sstevel@tonic-gate co_list, &head, &tail); 804*0Sstevel@tonic-gate 805*0Sstevel@tonic-gate /* 806*0Sstevel@tonic-gate * We also need cipher aliases for selecting based on the rule_str. 807*0Sstevel@tonic-gate * There might be two types of entries in the rule_str: 1) names 808*0Sstevel@tonic-gate * of ciphers themselves 2) aliases for groups of ciphers. 809*0Sstevel@tonic-gate * For 1) we need the available ciphers and for 2) the cipher 810*0Sstevel@tonic-gate * groups of cipher_aliases added together in one list (otherwise 811*0Sstevel@tonic-gate * we would be happy with just the cipher_aliases table). 812*0Sstevel@tonic-gate */ 813*0Sstevel@tonic-gate num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); 814*0Sstevel@tonic-gate num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; 815*0Sstevel@tonic-gate ca_list = 816*0Sstevel@tonic-gate (SSL_CIPHER **)OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max); 817*0Sstevel@tonic-gate if (ca_list == NULL) 818*0Sstevel@tonic-gate { 819*0Sstevel@tonic-gate OPENSSL_free(co_list); 820*0Sstevel@tonic-gate SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE); 821*0Sstevel@tonic-gate return(NULL); /* Failure */ 822*0Sstevel@tonic-gate } 823*0Sstevel@tonic-gate ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mask, 824*0Sstevel@tonic-gate head); 825*0Sstevel@tonic-gate 826*0Sstevel@tonic-gate /* 827*0Sstevel@tonic-gate * If the rule_string begins with DEFAULT, apply the default rule 828*0Sstevel@tonic-gate * before using the (possibly available) additional rules. 829*0Sstevel@tonic-gate */ 830*0Sstevel@tonic-gate ok = 1; 831*0Sstevel@tonic-gate rule_p = rule_str; 832*0Sstevel@tonic-gate if (strncmp(rule_str,"DEFAULT",7) == 0) 833*0Sstevel@tonic-gate { 834*0Sstevel@tonic-gate ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, 835*0Sstevel@tonic-gate co_list, &head, &tail, ca_list); 836*0Sstevel@tonic-gate rule_p += 7; 837*0Sstevel@tonic-gate if (*rule_p == ':') 838*0Sstevel@tonic-gate rule_p++; 839*0Sstevel@tonic-gate } 840*0Sstevel@tonic-gate 841*0Sstevel@tonic-gate if (ok && (strlen(rule_p) > 0)) 842*0Sstevel@tonic-gate ok = ssl_cipher_process_rulestr(rule_p, co_list, &head, &tail, 843*0Sstevel@tonic-gate ca_list); 844*0Sstevel@tonic-gate 845*0Sstevel@tonic-gate OPENSSL_free(ca_list); /* Not needed anymore */ 846*0Sstevel@tonic-gate 847*0Sstevel@tonic-gate if (!ok) 848*0Sstevel@tonic-gate { /* Rule processing failure */ 849*0Sstevel@tonic-gate OPENSSL_free(co_list); 850*0Sstevel@tonic-gate return(NULL); 851*0Sstevel@tonic-gate } 852*0Sstevel@tonic-gate /* 853*0Sstevel@tonic-gate * Allocate new "cipherstack" for the result, return with error 854*0Sstevel@tonic-gate * if we cannot get one. 855*0Sstevel@tonic-gate */ 856*0Sstevel@tonic-gate if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) 857*0Sstevel@tonic-gate { 858*0Sstevel@tonic-gate OPENSSL_free(co_list); 859*0Sstevel@tonic-gate return(NULL); 860*0Sstevel@tonic-gate } 861*0Sstevel@tonic-gate 862*0Sstevel@tonic-gate /* 863*0Sstevel@tonic-gate * The cipher selection for the list is done. The ciphers are added 864*0Sstevel@tonic-gate * to the resulting precedence to the STACK_OF(SSL_CIPHER). 865*0Sstevel@tonic-gate */ 866*0Sstevel@tonic-gate for (curr = head; curr != NULL; curr = curr->next) 867*0Sstevel@tonic-gate { 868*0Sstevel@tonic-gate if (curr->active) 869*0Sstevel@tonic-gate { 870*0Sstevel@tonic-gate sk_SSL_CIPHER_push(cipherstack, curr->cipher); 871*0Sstevel@tonic-gate #ifdef CIPHER_DEBUG 872*0Sstevel@tonic-gate printf("<%s>\n",curr->cipher->name); 873*0Sstevel@tonic-gate #endif 874*0Sstevel@tonic-gate } 875*0Sstevel@tonic-gate } 876*0Sstevel@tonic-gate OPENSSL_free(co_list); /* Not needed any longer */ 877*0Sstevel@tonic-gate 878*0Sstevel@tonic-gate /* 879*0Sstevel@tonic-gate * The following passage is a little bit odd. If pointer variables 880*0Sstevel@tonic-gate * were supplied to hold STACK_OF(SSL_CIPHER) return information, 881*0Sstevel@tonic-gate * the old memory pointed to is free()ed. Then, however, the 882*0Sstevel@tonic-gate * cipher_list entry will be assigned just a copy of the returned 883*0Sstevel@tonic-gate * cipher stack. For cipher_list_by_id a copy of the cipher stack 884*0Sstevel@tonic-gate * will be created. See next comment... 885*0Sstevel@tonic-gate */ 886*0Sstevel@tonic-gate if (cipher_list != NULL) 887*0Sstevel@tonic-gate { 888*0Sstevel@tonic-gate if (*cipher_list != NULL) 889*0Sstevel@tonic-gate sk_SSL_CIPHER_free(*cipher_list); 890*0Sstevel@tonic-gate *cipher_list = cipherstack; 891*0Sstevel@tonic-gate } 892*0Sstevel@tonic-gate 893*0Sstevel@tonic-gate if (cipher_list_by_id != NULL) 894*0Sstevel@tonic-gate { 895*0Sstevel@tonic-gate if (*cipher_list_by_id != NULL) 896*0Sstevel@tonic-gate sk_SSL_CIPHER_free(*cipher_list_by_id); 897*0Sstevel@tonic-gate *cipher_list_by_id = sk_SSL_CIPHER_dup(cipherstack); 898*0Sstevel@tonic-gate } 899*0Sstevel@tonic-gate 900*0Sstevel@tonic-gate /* 901*0Sstevel@tonic-gate * Now it is getting really strange. If something failed during 902*0Sstevel@tonic-gate * the previous pointer assignment or if one of the pointers was 903*0Sstevel@tonic-gate * not requested, the error condition is met. That might be 904*0Sstevel@tonic-gate * discussable. The strange thing is however that in this case 905*0Sstevel@tonic-gate * the memory "ret" pointed to is "free()ed" and hence the pointer 906*0Sstevel@tonic-gate * cipher_list becomes wild. The memory reserved for 907*0Sstevel@tonic-gate * cipher_list_by_id however is not "free()ed" and stays intact. 908*0Sstevel@tonic-gate */ 909*0Sstevel@tonic-gate if ( (cipher_list_by_id == NULL) || 910*0Sstevel@tonic-gate (*cipher_list_by_id == NULL) || 911*0Sstevel@tonic-gate (cipher_list == NULL) || 912*0Sstevel@tonic-gate (*cipher_list == NULL)) 913*0Sstevel@tonic-gate { 914*0Sstevel@tonic-gate sk_SSL_CIPHER_free(cipherstack); 915*0Sstevel@tonic-gate return(NULL); 916*0Sstevel@tonic-gate } 917*0Sstevel@tonic-gate 918*0Sstevel@tonic-gate sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp); 919*0Sstevel@tonic-gate 920*0Sstevel@tonic-gate return(cipherstack); 921*0Sstevel@tonic-gate } 922*0Sstevel@tonic-gate 923*0Sstevel@tonic-gate char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len) 924*0Sstevel@tonic-gate { 925*0Sstevel@tonic-gate int is_export,pkl,kl; 926*0Sstevel@tonic-gate char *ver,*exp_str; 927*0Sstevel@tonic-gate char *kx,*au,*enc,*mac; 928*0Sstevel@tonic-gate unsigned long alg,alg2,alg_s; 929*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 930*0Sstevel@tonic-gate static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx\n"; 931*0Sstevel@tonic-gate #else 932*0Sstevel@tonic-gate static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n"; 933*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 934*0Sstevel@tonic-gate 935*0Sstevel@tonic-gate alg=cipher->algorithms; 936*0Sstevel@tonic-gate alg_s=cipher->algo_strength; 937*0Sstevel@tonic-gate alg2=cipher->algorithm2; 938*0Sstevel@tonic-gate 939*0Sstevel@tonic-gate is_export=SSL_C_IS_EXPORT(cipher); 940*0Sstevel@tonic-gate pkl=SSL_C_EXPORT_PKEYLENGTH(cipher); 941*0Sstevel@tonic-gate kl=SSL_C_EXPORT_KEYLENGTH(cipher); 942*0Sstevel@tonic-gate exp_str=is_export?" export":""; 943*0Sstevel@tonic-gate 944*0Sstevel@tonic-gate if (alg & SSL_SSLV2) 945*0Sstevel@tonic-gate ver="SSLv2"; 946*0Sstevel@tonic-gate else if (alg & SSL_SSLV3) 947*0Sstevel@tonic-gate ver="SSLv3"; 948*0Sstevel@tonic-gate else 949*0Sstevel@tonic-gate ver="unknown"; 950*0Sstevel@tonic-gate 951*0Sstevel@tonic-gate switch (alg&SSL_MKEY_MASK) 952*0Sstevel@tonic-gate { 953*0Sstevel@tonic-gate case SSL_kRSA: 954*0Sstevel@tonic-gate kx=is_export?(pkl == 512 ? "RSA(512)" : "RSA(1024)"):"RSA"; 955*0Sstevel@tonic-gate break; 956*0Sstevel@tonic-gate case SSL_kDHr: 957*0Sstevel@tonic-gate kx="DH/RSA"; 958*0Sstevel@tonic-gate break; 959*0Sstevel@tonic-gate case SSL_kDHd: 960*0Sstevel@tonic-gate kx="DH/DSS"; 961*0Sstevel@tonic-gate break; 962*0Sstevel@tonic-gate case SSL_kKRB5: /* VRS */ 963*0Sstevel@tonic-gate case SSL_KRB5: /* VRS */ 964*0Sstevel@tonic-gate kx="KRB5"; 965*0Sstevel@tonic-gate break; 966*0Sstevel@tonic-gate case SSL_kFZA: 967*0Sstevel@tonic-gate kx="Fortezza"; 968*0Sstevel@tonic-gate break; 969*0Sstevel@tonic-gate case SSL_kEDH: 970*0Sstevel@tonic-gate kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH"; 971*0Sstevel@tonic-gate break; 972*0Sstevel@tonic-gate default: 973*0Sstevel@tonic-gate kx="unknown"; 974*0Sstevel@tonic-gate } 975*0Sstevel@tonic-gate 976*0Sstevel@tonic-gate switch (alg&SSL_AUTH_MASK) 977*0Sstevel@tonic-gate { 978*0Sstevel@tonic-gate case SSL_aRSA: 979*0Sstevel@tonic-gate au="RSA"; 980*0Sstevel@tonic-gate break; 981*0Sstevel@tonic-gate case SSL_aDSS: 982*0Sstevel@tonic-gate au="DSS"; 983*0Sstevel@tonic-gate break; 984*0Sstevel@tonic-gate case SSL_aDH: 985*0Sstevel@tonic-gate au="DH"; 986*0Sstevel@tonic-gate break; 987*0Sstevel@tonic-gate case SSL_aKRB5: /* VRS */ 988*0Sstevel@tonic-gate case SSL_KRB5: /* VRS */ 989*0Sstevel@tonic-gate au="KRB5"; 990*0Sstevel@tonic-gate break; 991*0Sstevel@tonic-gate case SSL_aFZA: 992*0Sstevel@tonic-gate case SSL_aNULL: 993*0Sstevel@tonic-gate au="None"; 994*0Sstevel@tonic-gate break; 995*0Sstevel@tonic-gate default: 996*0Sstevel@tonic-gate au="unknown"; 997*0Sstevel@tonic-gate break; 998*0Sstevel@tonic-gate } 999*0Sstevel@tonic-gate 1000*0Sstevel@tonic-gate switch (alg&SSL_ENC_MASK) 1001*0Sstevel@tonic-gate { 1002*0Sstevel@tonic-gate case SSL_DES: 1003*0Sstevel@tonic-gate enc=(is_export && kl == 5)?"DES(40)":"DES(56)"; 1004*0Sstevel@tonic-gate break; 1005*0Sstevel@tonic-gate case SSL_3DES: 1006*0Sstevel@tonic-gate enc="3DES(168)"; 1007*0Sstevel@tonic-gate break; 1008*0Sstevel@tonic-gate case SSL_RC4: 1009*0Sstevel@tonic-gate enc=is_export?(kl == 5 ? "RC4(40)" : "RC4(56)") 1010*0Sstevel@tonic-gate :((alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)"); 1011*0Sstevel@tonic-gate break; 1012*0Sstevel@tonic-gate case SSL_RC2: 1013*0Sstevel@tonic-gate enc=is_export?(kl == 5 ? "RC2(40)" : "RC2(56)"):"RC2(128)"; 1014*0Sstevel@tonic-gate break; 1015*0Sstevel@tonic-gate case SSL_IDEA: 1016*0Sstevel@tonic-gate enc="IDEA(128)"; 1017*0Sstevel@tonic-gate break; 1018*0Sstevel@tonic-gate case SSL_eFZA: 1019*0Sstevel@tonic-gate enc="Fortezza"; 1020*0Sstevel@tonic-gate break; 1021*0Sstevel@tonic-gate case SSL_eNULL: 1022*0Sstevel@tonic-gate enc="None"; 1023*0Sstevel@tonic-gate break; 1024*0Sstevel@tonic-gate case SSL_AES: 1025*0Sstevel@tonic-gate switch(cipher->strength_bits) 1026*0Sstevel@tonic-gate { 1027*0Sstevel@tonic-gate case 128: enc="AES(128)"; break; 1028*0Sstevel@tonic-gate case 192: enc="AES(192)"; break; 1029*0Sstevel@tonic-gate case 256: enc="AES(256)"; break; 1030*0Sstevel@tonic-gate default: enc="AES(?""?""?)"; break; 1031*0Sstevel@tonic-gate } 1032*0Sstevel@tonic-gate break; 1033*0Sstevel@tonic-gate default: 1034*0Sstevel@tonic-gate enc="unknown"; 1035*0Sstevel@tonic-gate break; 1036*0Sstevel@tonic-gate } 1037*0Sstevel@tonic-gate 1038*0Sstevel@tonic-gate switch (alg&SSL_MAC_MASK) 1039*0Sstevel@tonic-gate { 1040*0Sstevel@tonic-gate case SSL_MD5: 1041*0Sstevel@tonic-gate mac="MD5"; 1042*0Sstevel@tonic-gate break; 1043*0Sstevel@tonic-gate case SSL_SHA1: 1044*0Sstevel@tonic-gate mac="SHA1"; 1045*0Sstevel@tonic-gate break; 1046*0Sstevel@tonic-gate default: 1047*0Sstevel@tonic-gate mac="unknown"; 1048*0Sstevel@tonic-gate break; 1049*0Sstevel@tonic-gate } 1050*0Sstevel@tonic-gate 1051*0Sstevel@tonic-gate if (buf == NULL) 1052*0Sstevel@tonic-gate { 1053*0Sstevel@tonic-gate len=128; 1054*0Sstevel@tonic-gate buf=OPENSSL_malloc(len); 1055*0Sstevel@tonic-gate if (buf == NULL) return("OPENSSL_malloc Error"); 1056*0Sstevel@tonic-gate } 1057*0Sstevel@tonic-gate else if (len < 128) 1058*0Sstevel@tonic-gate return("Buffer too small"); 1059*0Sstevel@tonic-gate 1060*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 1061*0Sstevel@tonic-gate BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str,alg); 1062*0Sstevel@tonic-gate #else 1063*0Sstevel@tonic-gate BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str); 1064*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 1065*0Sstevel@tonic-gate return(buf); 1066*0Sstevel@tonic-gate } 1067*0Sstevel@tonic-gate 1068*0Sstevel@tonic-gate char *SSL_CIPHER_get_version(SSL_CIPHER *c) 1069*0Sstevel@tonic-gate { 1070*0Sstevel@tonic-gate int i; 1071*0Sstevel@tonic-gate 1072*0Sstevel@tonic-gate if (c == NULL) return("(NONE)"); 1073*0Sstevel@tonic-gate i=(int)(c->id>>24L); 1074*0Sstevel@tonic-gate if (i == 3) 1075*0Sstevel@tonic-gate return("TLSv1/SSLv3"); 1076*0Sstevel@tonic-gate else if (i == 2) 1077*0Sstevel@tonic-gate return("SSLv2"); 1078*0Sstevel@tonic-gate else 1079*0Sstevel@tonic-gate return("unknown"); 1080*0Sstevel@tonic-gate } 1081*0Sstevel@tonic-gate 1082*0Sstevel@tonic-gate /* return the actual cipher being used */ 1083*0Sstevel@tonic-gate const char *SSL_CIPHER_get_name(SSL_CIPHER *c) 1084*0Sstevel@tonic-gate { 1085*0Sstevel@tonic-gate if (c != NULL) 1086*0Sstevel@tonic-gate return(c->name); 1087*0Sstevel@tonic-gate return("(NONE)"); 1088*0Sstevel@tonic-gate } 1089*0Sstevel@tonic-gate 1090*0Sstevel@tonic-gate /* number of bits for symmetric cipher */ 1091*0Sstevel@tonic-gate int SSL_CIPHER_get_bits(SSL_CIPHER *c, int *alg_bits) 1092*0Sstevel@tonic-gate { 1093*0Sstevel@tonic-gate int ret=0; 1094*0Sstevel@tonic-gate 1095*0Sstevel@tonic-gate if (c != NULL) 1096*0Sstevel@tonic-gate { 1097*0Sstevel@tonic-gate if (alg_bits != NULL) *alg_bits = c->alg_bits; 1098*0Sstevel@tonic-gate ret = c->strength_bits; 1099*0Sstevel@tonic-gate } 1100*0Sstevel@tonic-gate return(ret); 1101*0Sstevel@tonic-gate } 1102*0Sstevel@tonic-gate 1103*0Sstevel@tonic-gate SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) 1104*0Sstevel@tonic-gate { 1105*0Sstevel@tonic-gate SSL_COMP *ctmp; 1106*0Sstevel@tonic-gate int i,nn; 1107*0Sstevel@tonic-gate 1108*0Sstevel@tonic-gate if ((n == 0) || (sk == NULL)) return(NULL); 1109*0Sstevel@tonic-gate nn=sk_SSL_COMP_num(sk); 1110*0Sstevel@tonic-gate for (i=0; i<nn; i++) 1111*0Sstevel@tonic-gate { 1112*0Sstevel@tonic-gate ctmp=sk_SSL_COMP_value(sk,i); 1113*0Sstevel@tonic-gate if (ctmp->id == n) 1114*0Sstevel@tonic-gate return(ctmp); 1115*0Sstevel@tonic-gate } 1116*0Sstevel@tonic-gate return(NULL); 1117*0Sstevel@tonic-gate } 1118*0Sstevel@tonic-gate 1119*0Sstevel@tonic-gate static int sk_comp_cmp(const SSL_COMP * const *a, 1120*0Sstevel@tonic-gate const SSL_COMP * const *b) 1121*0Sstevel@tonic-gate { 1122*0Sstevel@tonic-gate return((*a)->id-(*b)->id); 1123*0Sstevel@tonic-gate } 1124*0Sstevel@tonic-gate 1125*0Sstevel@tonic-gate STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) 1126*0Sstevel@tonic-gate { 1127*0Sstevel@tonic-gate return(ssl_comp_methods); 1128*0Sstevel@tonic-gate } 1129*0Sstevel@tonic-gate 1130*0Sstevel@tonic-gate int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) 1131*0Sstevel@tonic-gate { 1132*0Sstevel@tonic-gate SSL_COMP *comp; 1133*0Sstevel@tonic-gate STACK_OF(SSL_COMP) *sk; 1134*0Sstevel@tonic-gate 1135*0Sstevel@tonic-gate if (cm == NULL || cm->type == NID_undef) 1136*0Sstevel@tonic-gate return 1; 1137*0Sstevel@tonic-gate 1138*0Sstevel@tonic-gate MemCheck_off(); 1139*0Sstevel@tonic-gate comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); 1140*0Sstevel@tonic-gate comp->id=id; 1141*0Sstevel@tonic-gate comp->method=cm; 1142*0Sstevel@tonic-gate if (ssl_comp_methods == NULL) 1143*0Sstevel@tonic-gate sk=ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp); 1144*0Sstevel@tonic-gate else 1145*0Sstevel@tonic-gate sk=ssl_comp_methods; 1146*0Sstevel@tonic-gate if ((sk == NULL) || !sk_SSL_COMP_push(sk,comp)) 1147*0Sstevel@tonic-gate { 1148*0Sstevel@tonic-gate MemCheck_on(); 1149*0Sstevel@tonic-gate SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,ERR_R_MALLOC_FAILURE); 1150*0Sstevel@tonic-gate return(1); 1151*0Sstevel@tonic-gate } 1152*0Sstevel@tonic-gate else 1153*0Sstevel@tonic-gate { 1154*0Sstevel@tonic-gate MemCheck_on(); 1155*0Sstevel@tonic-gate return(0); 1156*0Sstevel@tonic-gate } 1157*0Sstevel@tonic-gate } 1158