xref: /onnv-gate/usr/src/common/openssl/ssl/ssl_ciph.c (revision 6125:38a604bf8269)
10Sstevel@tonic-gate /* ssl/ssl_ciph.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate  * All rights reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * This package is an SSL implementation written
60Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
110Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
130Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate  * the code are not to be removed.
180Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate  * as the author of the parts of the library used.
200Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate  *
230Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate  * are met:
260Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate  *    must display the following acknowledgement:
330Sstevel@tonic-gate  *    "This product includes cryptographic software written by
340Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate  *    being used are not cryptographic related :-).
370Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate  *
410Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate  * SUCH DAMAGE.
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
550Sstevel@tonic-gate  * copied and put under another distribution licence
560Sstevel@tonic-gate  * [including the GNU Public Licence.]
570Sstevel@tonic-gate  */
582139Sjp161948 /* ====================================================================
592139Sjp161948  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
602139Sjp161948  * ECC cipher suite support in OpenSSL originally developed by
612139Sjp161948  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
622139Sjp161948  */
630Sstevel@tonic-gate #include <stdio.h>
640Sstevel@tonic-gate #include <openssl/objects.h>
650Sstevel@tonic-gate #include <openssl/comp.h>
660Sstevel@tonic-gate #include "ssl_locl.h"
670Sstevel@tonic-gate 
680Sstevel@tonic-gate #define SSL_ENC_DES_IDX		0
690Sstevel@tonic-gate #define SSL_ENC_3DES_IDX	1
700Sstevel@tonic-gate #define SSL_ENC_RC4_IDX		2
710Sstevel@tonic-gate #define SSL_ENC_RC2_IDX		3
720Sstevel@tonic-gate #define SSL_ENC_IDEA_IDX	4
730Sstevel@tonic-gate #define SSL_ENC_eFZA_IDX	5
740Sstevel@tonic-gate #define SSL_ENC_NULL_IDX	6
750Sstevel@tonic-gate #define SSL_ENC_AES128_IDX	7
760Sstevel@tonic-gate #define SSL_ENC_AES256_IDX	8
770Sstevel@tonic-gate #define SSL_ENC_NUM_IDX		9
780Sstevel@tonic-gate 
790Sstevel@tonic-gate static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={
800Sstevel@tonic-gate 	NULL,NULL,NULL,NULL,NULL,NULL,
810Sstevel@tonic-gate 	};
820Sstevel@tonic-gate 
832139Sjp161948 #define SSL_COMP_NULL_IDX	0
842139Sjp161948 #define SSL_COMP_ZLIB_IDX	1
852139Sjp161948 #define SSL_COMP_NUM_IDX	2
862139Sjp161948 
870Sstevel@tonic-gate static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL;
880Sstevel@tonic-gate 
890Sstevel@tonic-gate #define SSL_MD_MD5_IDX	0
900Sstevel@tonic-gate #define SSL_MD_SHA1_IDX	1
910Sstevel@tonic-gate #define SSL_MD_NUM_IDX	2
920Sstevel@tonic-gate static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={
930Sstevel@tonic-gate 	NULL,NULL,
940Sstevel@tonic-gate 	};
950Sstevel@tonic-gate 
960Sstevel@tonic-gate #define CIPHER_ADD	1
970Sstevel@tonic-gate #define CIPHER_KILL	2
980Sstevel@tonic-gate #define CIPHER_DEL	3
990Sstevel@tonic-gate #define CIPHER_ORD	4
1000Sstevel@tonic-gate #define CIPHER_SPECIAL	5
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate typedef struct cipher_order_st
1030Sstevel@tonic-gate 	{
1040Sstevel@tonic-gate 	SSL_CIPHER *cipher;
1050Sstevel@tonic-gate 	int active;
1060Sstevel@tonic-gate 	int dead;
1070Sstevel@tonic-gate 	struct cipher_order_st *next,*prev;
1080Sstevel@tonic-gate 	} CIPHER_ORDER;
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate static const SSL_CIPHER cipher_aliases[]={
1110Sstevel@tonic-gate 	/* Don't include eNULL unless specifically enabled. */
1122139Sjp161948 	/* Don't include ECC in ALL because these ciphers are not yet official. */
1132139Sjp161948 	{0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL & ~SSL_kECDH & ~SSL_kECDHE, SSL_ALL ,0,0,0,SSL_ALL,SSL_ALL}, /* must be first */
1142139Sjp161948 	/* TODO: COMPLEMENT OF ALL and COMPLEMENT OF DEFAULT do not have ECC cipher suites handled properly. */
1152139Sjp161948 	{0,SSL_TXT_CMPALL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0},  /* COMPLEMENT OF ALL */
1160Sstevel@tonic-gate 	{0,SSL_TXT_CMPDEF,0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK,0},
1172139Sjp161948 	{0,SSL_TXT_kKRB5,0,SSL_kKRB5,0,0,0,0,SSL_MKEY_MASK,0},  /* VRS Kerberos5 */
1180Sstevel@tonic-gate 	{0,SSL_TXT_kRSA,0,SSL_kRSA,  0,0,0,0,SSL_MKEY_MASK,0},
1190Sstevel@tonic-gate 	{0,SSL_TXT_kDHr,0,SSL_kDHr,  0,0,0,0,SSL_MKEY_MASK,0},
1200Sstevel@tonic-gate 	{0,SSL_TXT_kDHd,0,SSL_kDHd,  0,0,0,0,SSL_MKEY_MASK,0},
1210Sstevel@tonic-gate 	{0,SSL_TXT_kEDH,0,SSL_kEDH,  0,0,0,0,SSL_MKEY_MASK,0},
1220Sstevel@tonic-gate 	{0,SSL_TXT_kFZA,0,SSL_kFZA,  0,0,0,0,SSL_MKEY_MASK,0},
1230Sstevel@tonic-gate 	{0,SSL_TXT_DH,	0,SSL_DH,    0,0,0,0,SSL_MKEY_MASK,0},
1242139Sjp161948 	{0,SSL_TXT_ECC,	0,(SSL_kECDH|SSL_kECDHE), 0,0,0,0,SSL_MKEY_MASK,0},
1250Sstevel@tonic-gate 	{0,SSL_TXT_EDH,	0,SSL_EDH,   0,0,0,0,SSL_MKEY_MASK|SSL_AUTH_MASK,0},
1260Sstevel@tonic-gate 	{0,SSL_TXT_aKRB5,0,SSL_aKRB5,0,0,0,0,SSL_AUTH_MASK,0},  /* VRS Kerberos5 */
1270Sstevel@tonic-gate 	{0,SSL_TXT_aRSA,0,SSL_aRSA,  0,0,0,0,SSL_AUTH_MASK,0},
1280Sstevel@tonic-gate 	{0,SSL_TXT_aDSS,0,SSL_aDSS,  0,0,0,0,SSL_AUTH_MASK,0},
1290Sstevel@tonic-gate 	{0,SSL_TXT_aFZA,0,SSL_aFZA,  0,0,0,0,SSL_AUTH_MASK,0},
1300Sstevel@tonic-gate 	{0,SSL_TXT_aNULL,0,SSL_aNULL,0,0,0,0,SSL_AUTH_MASK,0},
1310Sstevel@tonic-gate 	{0,SSL_TXT_aDH, 0,SSL_aDH,   0,0,0,0,SSL_AUTH_MASK,0},
1320Sstevel@tonic-gate 	{0,SSL_TXT_DSS,	0,SSL_DSS,   0,0,0,0,SSL_AUTH_MASK,0},
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate 	{0,SSL_TXT_DES,	0,SSL_DES,   0,0,0,0,SSL_ENC_MASK,0},
1350Sstevel@tonic-gate 	{0,SSL_TXT_3DES,0,SSL_3DES,  0,0,0,0,SSL_ENC_MASK,0},
1360Sstevel@tonic-gate 	{0,SSL_TXT_RC4,	0,SSL_RC4,   0,0,0,0,SSL_ENC_MASK,0},
1370Sstevel@tonic-gate 	{0,SSL_TXT_RC2,	0,SSL_RC2,   0,0,0,0,SSL_ENC_MASK,0},
1380Sstevel@tonic-gate #ifndef OPENSSL_NO_IDEA
1390Sstevel@tonic-gate 	{0,SSL_TXT_IDEA,0,SSL_IDEA,  0,0,0,0,SSL_ENC_MASK,0},
1400Sstevel@tonic-gate #endif
1410Sstevel@tonic-gate 	{0,SSL_TXT_eNULL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0},
1420Sstevel@tonic-gate 	{0,SSL_TXT_eFZA,0,SSL_eFZA,  0,0,0,0,SSL_ENC_MASK,0},
1430Sstevel@tonic-gate 	{0,SSL_TXT_AES,	0,SSL_AES,   0,0,0,0,SSL_ENC_MASK,0},
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate 	{0,SSL_TXT_MD5,	0,SSL_MD5,   0,0,0,0,SSL_MAC_MASK,0},
1460Sstevel@tonic-gate 	{0,SSL_TXT_SHA1,0,SSL_SHA1,  0,0,0,0,SSL_MAC_MASK,0},
1470Sstevel@tonic-gate 	{0,SSL_TXT_SHA,	0,SSL_SHA,   0,0,0,0,SSL_MAC_MASK,0},
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate 	{0,SSL_TXT_NULL,0,SSL_NULL,  0,0,0,0,SSL_ENC_MASK,0},
1500Sstevel@tonic-gate 	{0,SSL_TXT_KRB5,0,SSL_KRB5,  0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0},
1510Sstevel@tonic-gate 	{0,SSL_TXT_RSA,	0,SSL_RSA,   0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0},
1520Sstevel@tonic-gate 	{0,SSL_TXT_ADH,	0,SSL_ADH,   0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0},
1530Sstevel@tonic-gate 	{0,SSL_TXT_FZA,	0,SSL_FZA,   0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK|SSL_ENC_MASK,0},
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate 	{0,SSL_TXT_SSLV2, 0,SSL_SSLV2, 0,0,0,0,SSL_SSL_MASK,0},
1560Sstevel@tonic-gate 	{0,SSL_TXT_SSLV3, 0,SSL_SSLV3, 0,0,0,0,SSL_SSL_MASK,0},
1570Sstevel@tonic-gate 	{0,SSL_TXT_TLSV1, 0,SSL_TLSV1, 0,0,0,0,SSL_SSL_MASK,0},
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 	{0,SSL_TXT_EXP   ,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK},
1600Sstevel@tonic-gate 	{0,SSL_TXT_EXPORT,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK},
1610Sstevel@tonic-gate 	{0,SSL_TXT_EXP40, 0, 0, SSL_EXP40, 0,0,0,0,SSL_STRONG_MASK},
1620Sstevel@tonic-gate 	{0,SSL_TXT_EXP56, 0, 0, SSL_EXP56, 0,0,0,0,SSL_STRONG_MASK},
1630Sstevel@tonic-gate 	{0,SSL_TXT_LOW,   0, 0,   SSL_LOW, 0,0,0,0,SSL_STRONG_MASK},
1640Sstevel@tonic-gate 	{0,SSL_TXT_MEDIUM,0, 0,SSL_MEDIUM, 0,0,0,0,SSL_STRONG_MASK},
1650Sstevel@tonic-gate 	{0,SSL_TXT_HIGH,  0, 0,  SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK},
1660Sstevel@tonic-gate 	};
1670Sstevel@tonic-gate 
ssl_load_ciphers(void)1682139Sjp161948 void ssl_load_ciphers(void)
1690Sstevel@tonic-gate 	{
1700Sstevel@tonic-gate 	ssl_cipher_methods[SSL_ENC_DES_IDX]=
1710Sstevel@tonic-gate 		EVP_get_cipherbyname(SN_des_cbc);
1720Sstevel@tonic-gate 	ssl_cipher_methods[SSL_ENC_3DES_IDX]=
1730Sstevel@tonic-gate 		EVP_get_cipherbyname(SN_des_ede3_cbc);
1740Sstevel@tonic-gate 	ssl_cipher_methods[SSL_ENC_RC4_IDX]=
1750Sstevel@tonic-gate 		EVP_get_cipherbyname(SN_rc4);
1760Sstevel@tonic-gate 	ssl_cipher_methods[SSL_ENC_RC2_IDX]=
1770Sstevel@tonic-gate 		EVP_get_cipherbyname(SN_rc2_cbc);
1780Sstevel@tonic-gate #ifndef OPENSSL_NO_IDEA
1790Sstevel@tonic-gate 	ssl_cipher_methods[SSL_ENC_IDEA_IDX]=
1800Sstevel@tonic-gate 		EVP_get_cipherbyname(SN_idea_cbc);
1810Sstevel@tonic-gate #else
1820Sstevel@tonic-gate 	ssl_cipher_methods[SSL_ENC_IDEA_IDX]= NULL;
1830Sstevel@tonic-gate #endif
1840Sstevel@tonic-gate 	ssl_cipher_methods[SSL_ENC_AES128_IDX]=
1850Sstevel@tonic-gate 	  EVP_get_cipherbyname(SN_aes_128_cbc);
1860Sstevel@tonic-gate 	ssl_cipher_methods[SSL_ENC_AES256_IDX]=
1870Sstevel@tonic-gate 	  EVP_get_cipherbyname(SN_aes_256_cbc);
188*6125Sbubbva 
1890Sstevel@tonic-gate 	ssl_digest_methods[SSL_MD_MD5_IDX]=
1900Sstevel@tonic-gate 		EVP_get_digestbyname(SN_md5);
1910Sstevel@tonic-gate 	ssl_digest_methods[SSL_MD_SHA1_IDX]=
1920Sstevel@tonic-gate 		EVP_get_digestbyname(SN_sha1);
1930Sstevel@tonic-gate 	}
1940Sstevel@tonic-gate 
1952139Sjp161948 
1962139Sjp161948 #ifndef OPENSSL_NO_COMP
1972139Sjp161948 
sk_comp_cmp(const SSL_COMP * const * a,const SSL_COMP * const * b)1982139Sjp161948 static int sk_comp_cmp(const SSL_COMP * const *a,
1992139Sjp161948 			const SSL_COMP * const *b)
2002139Sjp161948 	{
2012139Sjp161948 	return((*a)->id-(*b)->id);
2022139Sjp161948 	}
2032139Sjp161948 
load_builtin_compressions(void)2042139Sjp161948 static void load_builtin_compressions(void)
2052139Sjp161948 	{
2062139Sjp161948 	if (ssl_comp_methods != NULL)
2072139Sjp161948 		return;
2082139Sjp161948 
2092139Sjp161948 	CRYPTO_w_lock(CRYPTO_LOCK_SSL);
2102139Sjp161948 	if (ssl_comp_methods == NULL)
2112139Sjp161948 		{
2122139Sjp161948 		SSL_COMP *comp = NULL;
2132139Sjp161948 
2142139Sjp161948 		MemCheck_off();
2152139Sjp161948 		ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp);
2162139Sjp161948 		if (ssl_comp_methods != NULL)
2172139Sjp161948 			{
2182139Sjp161948 			comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
2192139Sjp161948 			if (comp != NULL)
2202139Sjp161948 				{
2212139Sjp161948 				comp->method=COMP_zlib();
2222139Sjp161948 				if (comp->method
2232139Sjp161948 					&& comp->method->type == NID_undef)
2242139Sjp161948 					OPENSSL_free(comp);
2252139Sjp161948 				else
2262139Sjp161948 					{
2272139Sjp161948 					comp->id=SSL_COMP_ZLIB_IDX;
2282139Sjp161948 					comp->name=comp->method->name;
2292139Sjp161948 					sk_SSL_COMP_push(ssl_comp_methods,comp);
2302139Sjp161948 					}
2312139Sjp161948 				}
2322139Sjp161948 			}
2332139Sjp161948 		MemCheck_on();
2342139Sjp161948 		}
2352139Sjp161948 	CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
2362139Sjp161948 	}
2372139Sjp161948 #endif
2382139Sjp161948 
ssl_cipher_get_evp(const SSL_SESSION * s,const EVP_CIPHER ** enc,const EVP_MD ** md,SSL_COMP ** comp)2392139Sjp161948 int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
2400Sstevel@tonic-gate 	     const EVP_MD **md, SSL_COMP **comp)
2410Sstevel@tonic-gate 	{
2420Sstevel@tonic-gate 	int i;
2430Sstevel@tonic-gate 	SSL_CIPHER *c;
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate 	c=s->cipher;
2460Sstevel@tonic-gate 	if (c == NULL) return(0);
2470Sstevel@tonic-gate 	if (comp != NULL)
2480Sstevel@tonic-gate 		{
2490Sstevel@tonic-gate 		SSL_COMP ctmp;
2502139Sjp161948 #ifndef OPENSSL_NO_COMP
2512139Sjp161948 		load_builtin_compressions();
2522139Sjp161948 #endif
2530Sstevel@tonic-gate 
2542139Sjp161948 		*comp=NULL;
2552139Sjp161948 		ctmp.id=s->compress_meth;
2562139Sjp161948 		if (ssl_comp_methods != NULL)
2570Sstevel@tonic-gate 			{
2580Sstevel@tonic-gate 			i=sk_SSL_COMP_find(ssl_comp_methods,&ctmp);
2590Sstevel@tonic-gate 			if (i >= 0)
2600Sstevel@tonic-gate 				*comp=sk_SSL_COMP_value(ssl_comp_methods,i);
2610Sstevel@tonic-gate 			else
2620Sstevel@tonic-gate 				*comp=NULL;
2630Sstevel@tonic-gate 			}
2640Sstevel@tonic-gate 		}
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate 	if ((enc == NULL) || (md == NULL)) return(0);
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 	switch (c->algorithms & SSL_ENC_MASK)
2690Sstevel@tonic-gate 		{
2700Sstevel@tonic-gate 	case SSL_DES:
2710Sstevel@tonic-gate 		i=SSL_ENC_DES_IDX;
2720Sstevel@tonic-gate 		break;
2730Sstevel@tonic-gate 	case SSL_3DES:
2740Sstevel@tonic-gate 		i=SSL_ENC_3DES_IDX;
2750Sstevel@tonic-gate 		break;
2760Sstevel@tonic-gate 	case SSL_RC4:
2770Sstevel@tonic-gate 		i=SSL_ENC_RC4_IDX;
2780Sstevel@tonic-gate 		break;
2790Sstevel@tonic-gate 	case SSL_RC2:
2800Sstevel@tonic-gate 		i=SSL_ENC_RC2_IDX;
2810Sstevel@tonic-gate 		break;
2820Sstevel@tonic-gate 	case SSL_IDEA:
2830Sstevel@tonic-gate 		i=SSL_ENC_IDEA_IDX;
2840Sstevel@tonic-gate 		break;
2850Sstevel@tonic-gate 	case SSL_eNULL:
2860Sstevel@tonic-gate 		i=SSL_ENC_NULL_IDX;
2870Sstevel@tonic-gate 		break;
2880Sstevel@tonic-gate 	case SSL_AES:
2890Sstevel@tonic-gate 		switch(c->alg_bits)
2900Sstevel@tonic-gate 			{
2910Sstevel@tonic-gate 		case 128: i=SSL_ENC_AES128_IDX; break;
2920Sstevel@tonic-gate 		case 256: i=SSL_ENC_AES256_IDX; break;
2930Sstevel@tonic-gate 		default: i=-1; break;
2940Sstevel@tonic-gate 			}
2950Sstevel@tonic-gate 		break;
2960Sstevel@tonic-gate 	default:
2970Sstevel@tonic-gate 		i= -1;
2980Sstevel@tonic-gate 		break;
2990Sstevel@tonic-gate 		}
3000Sstevel@tonic-gate 
3010Sstevel@tonic-gate 	if ((i < 0) || (i > SSL_ENC_NUM_IDX))
3020Sstevel@tonic-gate 		*enc=NULL;
3030Sstevel@tonic-gate 	else
3040Sstevel@tonic-gate 		{
3050Sstevel@tonic-gate 		if (i == SSL_ENC_NULL_IDX)
3060Sstevel@tonic-gate 			*enc=EVP_enc_null();
3070Sstevel@tonic-gate 		else
3080Sstevel@tonic-gate 			*enc=ssl_cipher_methods[i];
3090Sstevel@tonic-gate 		}
3100Sstevel@tonic-gate 
3110Sstevel@tonic-gate 	switch (c->algorithms & SSL_MAC_MASK)
3120Sstevel@tonic-gate 		{
3130Sstevel@tonic-gate 	case SSL_MD5:
3140Sstevel@tonic-gate 		i=SSL_MD_MD5_IDX;
3150Sstevel@tonic-gate 		break;
3160Sstevel@tonic-gate 	case SSL_SHA1:
3170Sstevel@tonic-gate 		i=SSL_MD_SHA1_IDX;
3180Sstevel@tonic-gate 		break;
3190Sstevel@tonic-gate 	default:
3200Sstevel@tonic-gate 		i= -1;
3210Sstevel@tonic-gate 		break;
3220Sstevel@tonic-gate 		}
3230Sstevel@tonic-gate 	if ((i < 0) || (i > SSL_MD_NUM_IDX))
3240Sstevel@tonic-gate 		*md=NULL;
3250Sstevel@tonic-gate 	else
3260Sstevel@tonic-gate 		*md=ssl_digest_methods[i];
3270Sstevel@tonic-gate 
3280Sstevel@tonic-gate 	if ((*enc != NULL) && (*md != NULL))
3290Sstevel@tonic-gate 		return(1);
3300Sstevel@tonic-gate 	else
3310Sstevel@tonic-gate 		return(0);
3320Sstevel@tonic-gate 	}
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate #define ITEM_SEP(a) \
3350Sstevel@tonic-gate 	(((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
3360Sstevel@tonic-gate 
ll_append_tail(CIPHER_ORDER ** head,CIPHER_ORDER * curr,CIPHER_ORDER ** tail)3370Sstevel@tonic-gate static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
3380Sstevel@tonic-gate 	     CIPHER_ORDER **tail)
3390Sstevel@tonic-gate 	{
3400Sstevel@tonic-gate 	if (curr == *tail) return;
3410Sstevel@tonic-gate 	if (curr == *head)
3420Sstevel@tonic-gate 		*head=curr->next;
3430Sstevel@tonic-gate 	if (curr->prev != NULL)
3440Sstevel@tonic-gate 		curr->prev->next=curr->next;
3450Sstevel@tonic-gate 	if (curr->next != NULL) /* should always be true */
3460Sstevel@tonic-gate 		curr->next->prev=curr->prev;
3470Sstevel@tonic-gate 	(*tail)->next=curr;
3480Sstevel@tonic-gate 	curr->prev= *tail;
3490Sstevel@tonic-gate 	curr->next=NULL;
3500Sstevel@tonic-gate 	*tail=curr;
3510Sstevel@tonic-gate 	}
3520Sstevel@tonic-gate 
ssl_cipher_get_disabled(void)3530Sstevel@tonic-gate static unsigned long ssl_cipher_get_disabled(void)
3540Sstevel@tonic-gate 	{
3550Sstevel@tonic-gate 	unsigned long mask;
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate 	mask = SSL_kFZA;
3580Sstevel@tonic-gate #ifdef OPENSSL_NO_RSA
3590Sstevel@tonic-gate 	mask |= SSL_aRSA|SSL_kRSA;
3600Sstevel@tonic-gate #endif
3610Sstevel@tonic-gate #ifdef OPENSSL_NO_DSA
3620Sstevel@tonic-gate 	mask |= SSL_aDSS;
3630Sstevel@tonic-gate #endif
3640Sstevel@tonic-gate #ifdef OPENSSL_NO_DH
3650Sstevel@tonic-gate 	mask |= SSL_kDHr|SSL_kDHd|SSL_kEDH|SSL_aDH;
3660Sstevel@tonic-gate #endif
3670Sstevel@tonic-gate #ifdef OPENSSL_NO_KRB5
3680Sstevel@tonic-gate 	mask |= SSL_kKRB5|SSL_aKRB5;
3690Sstevel@tonic-gate #endif
3702139Sjp161948 #ifdef OPENSSL_NO_ECDH
3712139Sjp161948 	mask |= SSL_kECDH|SSL_kECDHE;
3722139Sjp161948 #endif
3730Sstevel@tonic-gate #ifdef SSL_FORBID_ENULL
3740Sstevel@tonic-gate 	mask |= SSL_eNULL;
3750Sstevel@tonic-gate #endif
3760Sstevel@tonic-gate 
3770Sstevel@tonic-gate 	mask |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0;
3780Sstevel@tonic-gate 	mask |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0;
3790Sstevel@tonic-gate 	mask |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0;
3800Sstevel@tonic-gate 	mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0;
3810Sstevel@tonic-gate 	mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0;
3820Sstevel@tonic-gate 	mask |= (ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL) ? SSL_eFZA:0;
3830Sstevel@tonic-gate 	mask |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES:0;
3840Sstevel@tonic-gate 
3850Sstevel@tonic-gate 	mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
3860Sstevel@tonic-gate 	mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
3870Sstevel@tonic-gate 
3880Sstevel@tonic-gate 	return(mask);
3890Sstevel@tonic-gate 	}
3900Sstevel@tonic-gate 
ssl_cipher_collect_ciphers(const SSL_METHOD * ssl_method,int num_of_ciphers,unsigned long mask,CIPHER_ORDER * co_list,CIPHER_ORDER ** head_p,CIPHER_ORDER ** tail_p)3910Sstevel@tonic-gate static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
3920Sstevel@tonic-gate 		int num_of_ciphers, unsigned long mask, CIPHER_ORDER *co_list,
3930Sstevel@tonic-gate 		CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
3940Sstevel@tonic-gate 	{
3950Sstevel@tonic-gate 	int i, co_list_num;
3960Sstevel@tonic-gate 	SSL_CIPHER *c;
3970Sstevel@tonic-gate 
3980Sstevel@tonic-gate 	/*
3990Sstevel@tonic-gate 	 * We have num_of_ciphers descriptions compiled in, depending on the
4000Sstevel@tonic-gate 	 * method selected (SSLv2 and/or SSLv3, TLSv1 etc).
4010Sstevel@tonic-gate 	 * These will later be sorted in a linked list with at most num
4020Sstevel@tonic-gate 	 * entries.
4030Sstevel@tonic-gate 	 */
4040Sstevel@tonic-gate 
4050Sstevel@tonic-gate 	/* Get the initial list of ciphers */
4060Sstevel@tonic-gate 	co_list_num = 0;	/* actual count of ciphers */
4070Sstevel@tonic-gate 	for (i = 0; i < num_of_ciphers; i++)
4080Sstevel@tonic-gate 		{
4090Sstevel@tonic-gate 		c = ssl_method->get_cipher(i);
4100Sstevel@tonic-gate 		/* drop those that use any of that is not available */
4110Sstevel@tonic-gate 		if ((c != NULL) && c->valid && !(c->algorithms & mask))
4120Sstevel@tonic-gate 			{
4130Sstevel@tonic-gate 			co_list[co_list_num].cipher = c;
4140Sstevel@tonic-gate 			co_list[co_list_num].next = NULL;
4150Sstevel@tonic-gate 			co_list[co_list_num].prev = NULL;
4160Sstevel@tonic-gate 			co_list[co_list_num].active = 0;
4170Sstevel@tonic-gate 			co_list_num++;
4180Sstevel@tonic-gate #ifdef KSSL_DEBUG
4190Sstevel@tonic-gate 			printf("\t%d: %s %lx %lx\n",i,c->name,c->id,c->algorithms);
4200Sstevel@tonic-gate #endif	/* KSSL_DEBUG */
4210Sstevel@tonic-gate 			/*
4220Sstevel@tonic-gate 			if (!sk_push(ca_list,(char *)c)) goto err;
4230Sstevel@tonic-gate 			*/
4240Sstevel@tonic-gate 			}
4250Sstevel@tonic-gate 		}
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate 	/*
4280Sstevel@tonic-gate 	 * Prepare linked list from list entries
4290Sstevel@tonic-gate 	 */
4300Sstevel@tonic-gate 	for (i = 1; i < co_list_num - 1; i++)
4310Sstevel@tonic-gate 		{
4320Sstevel@tonic-gate 		co_list[i].prev = &(co_list[i-1]);
4330Sstevel@tonic-gate 		co_list[i].next = &(co_list[i+1]);
4340Sstevel@tonic-gate 		}
4350Sstevel@tonic-gate 	if (co_list_num > 0)
4360Sstevel@tonic-gate 		{
4370Sstevel@tonic-gate 		(*head_p) = &(co_list[0]);
4380Sstevel@tonic-gate 		(*head_p)->prev = NULL;
4390Sstevel@tonic-gate 		(*head_p)->next = &(co_list[1]);
4400Sstevel@tonic-gate 		(*tail_p) = &(co_list[co_list_num - 1]);
4410Sstevel@tonic-gate 		(*tail_p)->prev = &(co_list[co_list_num - 2]);
4420Sstevel@tonic-gate 		(*tail_p)->next = NULL;
4430Sstevel@tonic-gate 		}
4440Sstevel@tonic-gate 	}
4450Sstevel@tonic-gate 
ssl_cipher_collect_aliases(SSL_CIPHER ** ca_list,int num_of_group_aliases,unsigned long mask,CIPHER_ORDER * head)4460Sstevel@tonic-gate static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list,
4470Sstevel@tonic-gate 			int num_of_group_aliases, unsigned long mask,
4480Sstevel@tonic-gate 			CIPHER_ORDER *head)
4490Sstevel@tonic-gate 	{
4500Sstevel@tonic-gate 	CIPHER_ORDER *ciph_curr;
4510Sstevel@tonic-gate 	SSL_CIPHER **ca_curr;
4520Sstevel@tonic-gate 	int i;
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate 	/*
4550Sstevel@tonic-gate 	 * First, add the real ciphers as already collected
4560Sstevel@tonic-gate 	 */
4570Sstevel@tonic-gate 	ciph_curr = head;
4580Sstevel@tonic-gate 	ca_curr = ca_list;
4590Sstevel@tonic-gate 	while (ciph_curr != NULL)
4600Sstevel@tonic-gate 		{
4610Sstevel@tonic-gate 		*ca_curr = ciph_curr->cipher;
4620Sstevel@tonic-gate 		ca_curr++;
4630Sstevel@tonic-gate 		ciph_curr = ciph_curr->next;
4640Sstevel@tonic-gate 		}
4650Sstevel@tonic-gate 
4660Sstevel@tonic-gate 	/*
4670Sstevel@tonic-gate 	 * Now we add the available ones from the cipher_aliases[] table.
4680Sstevel@tonic-gate 	 * They represent either an algorithm, that must be fully
4690Sstevel@tonic-gate 	 * supported (not match any bit in mask) or represent a cipher
4700Sstevel@tonic-gate 	 * strength value (will be added in any case because algorithms=0).
4710Sstevel@tonic-gate 	 */
4720Sstevel@tonic-gate 	for (i = 0; i < num_of_group_aliases; i++)
4730Sstevel@tonic-gate 		{
4740Sstevel@tonic-gate 		if ((i == 0) ||		/* always fetch "ALL" */
4750Sstevel@tonic-gate 		    !(cipher_aliases[i].algorithms & mask))
4760Sstevel@tonic-gate 			{
4770Sstevel@tonic-gate 			*ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
4780Sstevel@tonic-gate 			ca_curr++;
4790Sstevel@tonic-gate 			}
4800Sstevel@tonic-gate 		}
4810Sstevel@tonic-gate 
4820Sstevel@tonic-gate 	*ca_curr = NULL;	/* end of list */
4830Sstevel@tonic-gate 	}
4840Sstevel@tonic-gate 
ssl_cipher_apply_rule(unsigned long algorithms,unsigned long mask,unsigned long algo_strength,unsigned long mask_strength,int rule,int strength_bits,CIPHER_ORDER * co_list,CIPHER_ORDER ** head_p,CIPHER_ORDER ** tail_p)4850Sstevel@tonic-gate static void ssl_cipher_apply_rule(unsigned long algorithms, unsigned long mask,
4860Sstevel@tonic-gate 		unsigned long algo_strength, unsigned long mask_strength,
4870Sstevel@tonic-gate 		int rule, int strength_bits, CIPHER_ORDER *co_list,
4880Sstevel@tonic-gate 		CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
4890Sstevel@tonic-gate 	{
4900Sstevel@tonic-gate 	CIPHER_ORDER *head, *tail, *curr, *curr2, *tail2;
4910Sstevel@tonic-gate 	SSL_CIPHER *cp;
4920Sstevel@tonic-gate 	unsigned long ma, ma_s;
4930Sstevel@tonic-gate 
4940Sstevel@tonic-gate #ifdef CIPHER_DEBUG
4950Sstevel@tonic-gate 	printf("Applying rule %d with %08lx %08lx %08lx %08lx (%d)\n",
4960Sstevel@tonic-gate 		rule, algorithms, mask, algo_strength, mask_strength,
4970Sstevel@tonic-gate 		strength_bits);
4980Sstevel@tonic-gate #endif
4990Sstevel@tonic-gate 
5000Sstevel@tonic-gate 	curr = head = *head_p;
5010Sstevel@tonic-gate 	curr2 = head;
5020Sstevel@tonic-gate 	tail2 = tail = *tail_p;
5030Sstevel@tonic-gate 	for (;;)
5040Sstevel@tonic-gate 		{
5050Sstevel@tonic-gate 		if ((curr == NULL) || (curr == tail2)) break;
5060Sstevel@tonic-gate 		curr = curr2;
5070Sstevel@tonic-gate 		curr2 = curr->next;
5080Sstevel@tonic-gate 
5090Sstevel@tonic-gate 		cp = curr->cipher;
5100Sstevel@tonic-gate 
5110Sstevel@tonic-gate 		/*
5120Sstevel@tonic-gate 		 * Selection criteria is either the number of strength_bits
5130Sstevel@tonic-gate 		 * or the algorithm used.
5140Sstevel@tonic-gate 		 */
5150Sstevel@tonic-gate 		if (strength_bits == -1)
5160Sstevel@tonic-gate 			{
5170Sstevel@tonic-gate 			ma = mask & cp->algorithms;
5180Sstevel@tonic-gate 			ma_s = mask_strength & cp->algo_strength;
5190Sstevel@tonic-gate 
5200Sstevel@tonic-gate #ifdef CIPHER_DEBUG
5210Sstevel@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);
5220Sstevel@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);
5230Sstevel@tonic-gate #endif
5240Sstevel@tonic-gate 			/*
5250Sstevel@tonic-gate 			 * Select: if none of the mask bit was met from the
5260Sstevel@tonic-gate 			 * cipher or not all of the bits were met, the
5270Sstevel@tonic-gate 			 * selection does not apply.
5280Sstevel@tonic-gate 			 */
5290Sstevel@tonic-gate 			if (((ma == 0) && (ma_s == 0)) ||
5300Sstevel@tonic-gate 			    ((ma & algorithms) != ma) ||
5310Sstevel@tonic-gate 			    ((ma_s & algo_strength) != ma_s))
5320Sstevel@tonic-gate 				continue; /* does not apply */
5330Sstevel@tonic-gate 			}
5340Sstevel@tonic-gate 		else if (strength_bits != cp->strength_bits)
5350Sstevel@tonic-gate 			continue;	/* does not apply */
5360Sstevel@tonic-gate 
5370Sstevel@tonic-gate #ifdef CIPHER_DEBUG
5380Sstevel@tonic-gate 		printf("Action = %d\n", rule);
5390Sstevel@tonic-gate #endif
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate 		/* add the cipher if it has not been added yet. */
5420Sstevel@tonic-gate 		if (rule == CIPHER_ADD)
5430Sstevel@tonic-gate 			{
5440Sstevel@tonic-gate 			if (!curr->active)
5450Sstevel@tonic-gate 				{
5460Sstevel@tonic-gate 				ll_append_tail(&head, curr, &tail);
5470Sstevel@tonic-gate 				curr->active = 1;
5480Sstevel@tonic-gate 				}
5490Sstevel@tonic-gate 			}
5500Sstevel@tonic-gate 		/* Move the added cipher to this location */
5510Sstevel@tonic-gate 		else if (rule == CIPHER_ORD)
5520Sstevel@tonic-gate 			{
5530Sstevel@tonic-gate 			if (curr->active)
5540Sstevel@tonic-gate 				{
5550Sstevel@tonic-gate 				ll_append_tail(&head, curr, &tail);
5560Sstevel@tonic-gate 				}
5570Sstevel@tonic-gate 			}
5580Sstevel@tonic-gate 		else if	(rule == CIPHER_DEL)
5590Sstevel@tonic-gate 			curr->active = 0;
5600Sstevel@tonic-gate 		else if (rule == CIPHER_KILL)
5610Sstevel@tonic-gate 			{
5620Sstevel@tonic-gate 			if (head == curr)
5630Sstevel@tonic-gate 				head = curr->next;
5640Sstevel@tonic-gate 			else
5650Sstevel@tonic-gate 				curr->prev->next = curr->next;
5660Sstevel@tonic-gate 			if (tail == curr)
5670Sstevel@tonic-gate 				tail = curr->prev;
5680Sstevel@tonic-gate 			curr->active = 0;
5690Sstevel@tonic-gate 			if (curr->next != NULL)
5700Sstevel@tonic-gate 				curr->next->prev = curr->prev;
5710Sstevel@tonic-gate 			if (curr->prev != NULL)
5720Sstevel@tonic-gate 				curr->prev->next = curr->next;
5730Sstevel@tonic-gate 			curr->next = NULL;
5740Sstevel@tonic-gate 			curr->prev = NULL;
5750Sstevel@tonic-gate 			}
5760Sstevel@tonic-gate 		}
5770Sstevel@tonic-gate 
5780Sstevel@tonic-gate 	*head_p = head;
5790Sstevel@tonic-gate 	*tail_p = tail;
5800Sstevel@tonic-gate 	}
5810Sstevel@tonic-gate 
ssl_cipher_strength_sort(CIPHER_ORDER * co_list,CIPHER_ORDER ** head_p,CIPHER_ORDER ** tail_p)5820Sstevel@tonic-gate static int ssl_cipher_strength_sort(CIPHER_ORDER *co_list,
5830Sstevel@tonic-gate 				    CIPHER_ORDER **head_p,
5840Sstevel@tonic-gate 				    CIPHER_ORDER **tail_p)
5850Sstevel@tonic-gate 	{
5860Sstevel@tonic-gate 	int max_strength_bits, i, *number_uses;
5870Sstevel@tonic-gate 	CIPHER_ORDER *curr;
5880Sstevel@tonic-gate 
5890Sstevel@tonic-gate 	/*
5900Sstevel@tonic-gate 	 * This routine sorts the ciphers with descending strength. The sorting
5910Sstevel@tonic-gate 	 * must keep the pre-sorted sequence, so we apply the normal sorting
5920Sstevel@tonic-gate 	 * routine as '+' movement to the end of the list.
5930Sstevel@tonic-gate 	 */
5940Sstevel@tonic-gate 	max_strength_bits = 0;
5950Sstevel@tonic-gate 	curr = *head_p;
5960Sstevel@tonic-gate 	while (curr != NULL)
5970Sstevel@tonic-gate 		{
5980Sstevel@tonic-gate 		if (curr->active &&
5990Sstevel@tonic-gate 		    (curr->cipher->strength_bits > max_strength_bits))
6000Sstevel@tonic-gate 		    max_strength_bits = curr->cipher->strength_bits;
6010Sstevel@tonic-gate 		curr = curr->next;
6020Sstevel@tonic-gate 		}
6030Sstevel@tonic-gate 
6040Sstevel@tonic-gate 	number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
6050Sstevel@tonic-gate 	if (!number_uses)
6060Sstevel@tonic-gate 	{
6070Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT,ERR_R_MALLOC_FAILURE);
6080Sstevel@tonic-gate 		return(0);
6090Sstevel@tonic-gate 	}
6100Sstevel@tonic-gate 	memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int));
6110Sstevel@tonic-gate 
6120Sstevel@tonic-gate 	/*
6130Sstevel@tonic-gate 	 * Now find the strength_bits values actually used
6140Sstevel@tonic-gate 	 */
6150Sstevel@tonic-gate 	curr = *head_p;
6160Sstevel@tonic-gate 	while (curr != NULL)
6170Sstevel@tonic-gate 		{
6180Sstevel@tonic-gate 		if (curr->active)
6190Sstevel@tonic-gate 			number_uses[curr->cipher->strength_bits]++;
6200Sstevel@tonic-gate 		curr = curr->next;
6210Sstevel@tonic-gate 		}
6220Sstevel@tonic-gate 	/*
6230Sstevel@tonic-gate 	 * Go through the list of used strength_bits values in descending
6240Sstevel@tonic-gate 	 * order.
6250Sstevel@tonic-gate 	 */
6260Sstevel@tonic-gate 	for (i = max_strength_bits; i >= 0; i--)
6270Sstevel@tonic-gate 		if (number_uses[i] > 0)
6280Sstevel@tonic-gate 			ssl_cipher_apply_rule(0, 0, 0, 0, CIPHER_ORD, i,
6290Sstevel@tonic-gate 					co_list, head_p, tail_p);
6300Sstevel@tonic-gate 
6310Sstevel@tonic-gate 	OPENSSL_free(number_uses);
6320Sstevel@tonic-gate 	return(1);
6330Sstevel@tonic-gate 	}
6340Sstevel@tonic-gate 
ssl_cipher_process_rulestr(const char * rule_str,CIPHER_ORDER * co_list,CIPHER_ORDER ** head_p,CIPHER_ORDER ** tail_p,SSL_CIPHER ** ca_list)6350Sstevel@tonic-gate static int ssl_cipher_process_rulestr(const char *rule_str,
6360Sstevel@tonic-gate 		CIPHER_ORDER *co_list, CIPHER_ORDER **head_p,
6370Sstevel@tonic-gate 		CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list)
6380Sstevel@tonic-gate 	{
6390Sstevel@tonic-gate 	unsigned long algorithms, mask, algo_strength, mask_strength;
6400Sstevel@tonic-gate 	const char *l, *start, *buf;
6410Sstevel@tonic-gate 	int j, multi, found, rule, retval, ok, buflen;
6420Sstevel@tonic-gate 	char ch;
6430Sstevel@tonic-gate 
6440Sstevel@tonic-gate 	retval = 1;
6450Sstevel@tonic-gate 	l = rule_str;
6460Sstevel@tonic-gate 	for (;;)
6470Sstevel@tonic-gate 		{
6480Sstevel@tonic-gate 		ch = *l;
6490Sstevel@tonic-gate 
6500Sstevel@tonic-gate 		if (ch == '\0')
6510Sstevel@tonic-gate 			break;		/* done */
6520Sstevel@tonic-gate 		if (ch == '-')
6530Sstevel@tonic-gate 			{ rule = CIPHER_DEL; l++; }
6540Sstevel@tonic-gate 		else if (ch == '+')
6550Sstevel@tonic-gate 			{ rule = CIPHER_ORD; l++; }
6560Sstevel@tonic-gate 		else if (ch == '!')
6570Sstevel@tonic-gate 			{ rule = CIPHER_KILL; l++; }
6580Sstevel@tonic-gate 		else if (ch == '@')
6590Sstevel@tonic-gate 			{ rule = CIPHER_SPECIAL; l++; }
6600Sstevel@tonic-gate 		else
6610Sstevel@tonic-gate 			{ rule = CIPHER_ADD; }
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate 		if (ITEM_SEP(ch))
6640Sstevel@tonic-gate 			{
6650Sstevel@tonic-gate 			l++;
6660Sstevel@tonic-gate 			continue;
6670Sstevel@tonic-gate 			}
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 		algorithms = mask = algo_strength = mask_strength = 0;
6700Sstevel@tonic-gate 
6710Sstevel@tonic-gate 		start=l;
6720Sstevel@tonic-gate 		for (;;)
6730Sstevel@tonic-gate 			{
6740Sstevel@tonic-gate 			ch = *l;
6750Sstevel@tonic-gate 			buf = l;
6760Sstevel@tonic-gate 			buflen = 0;
6770Sstevel@tonic-gate #ifndef CHARSET_EBCDIC
6780Sstevel@tonic-gate 			while (	((ch >= 'A') && (ch <= 'Z')) ||
6790Sstevel@tonic-gate 				((ch >= '0') && (ch <= '9')) ||
6800Sstevel@tonic-gate 				((ch >= 'a') && (ch <= 'z')) ||
6810Sstevel@tonic-gate 				 (ch == '-'))
6820Sstevel@tonic-gate #else
6830Sstevel@tonic-gate 			while (	isalnum(ch) || (ch == '-'))
6840Sstevel@tonic-gate #endif
6850Sstevel@tonic-gate 				 {
6860Sstevel@tonic-gate 				 ch = *(++l);
6870Sstevel@tonic-gate 				 buflen++;
6880Sstevel@tonic-gate 				 }
6890Sstevel@tonic-gate 
6900Sstevel@tonic-gate 			if (buflen == 0)
6910Sstevel@tonic-gate 				{
6920Sstevel@tonic-gate 				/*
6930Sstevel@tonic-gate 				 * We hit something we cannot deal with,
6940Sstevel@tonic-gate 				 * it is no command or separator nor
6950Sstevel@tonic-gate 				 * alphanumeric, so we call this an error.
6960Sstevel@tonic-gate 				 */
6970Sstevel@tonic-gate 				SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
6980Sstevel@tonic-gate 				       SSL_R_INVALID_COMMAND);
6990Sstevel@tonic-gate 				retval = found = 0;
7000Sstevel@tonic-gate 				l++;
7010Sstevel@tonic-gate 				break;
7020Sstevel@tonic-gate 				}
7030Sstevel@tonic-gate 
7040Sstevel@tonic-gate 			if (rule == CIPHER_SPECIAL)
7050Sstevel@tonic-gate 				{
7060Sstevel@tonic-gate 				found = 0; /* unused -- avoid compiler warning */
7070Sstevel@tonic-gate 				break;	/* special treatment */
7080Sstevel@tonic-gate 				}
7090Sstevel@tonic-gate 
7100Sstevel@tonic-gate 			/* check for multi-part specification */
7110Sstevel@tonic-gate 			if (ch == '+')
7120Sstevel@tonic-gate 				{
7130Sstevel@tonic-gate 				multi=1;
7140Sstevel@tonic-gate 				l++;
7150Sstevel@tonic-gate 				}
7160Sstevel@tonic-gate 			else
7170Sstevel@tonic-gate 				multi=0;
7180Sstevel@tonic-gate 
7190Sstevel@tonic-gate 			/*
7200Sstevel@tonic-gate 			 * Now search for the cipher alias in the ca_list. Be careful
7210Sstevel@tonic-gate 			 * with the strncmp, because the "buflen" limitation
7220Sstevel@tonic-gate 			 * will make the rule "ADH:SOME" and the cipher
7230Sstevel@tonic-gate 			 * "ADH-MY-CIPHER" look like a match for buflen=3.
7240Sstevel@tonic-gate 			 * So additionally check whether the cipher name found
7250Sstevel@tonic-gate 			 * has the correct length. We can save a strlen() call:
7260Sstevel@tonic-gate 			 * just checking for the '\0' at the right place is
7270Sstevel@tonic-gate 			 * sufficient, we have to strncmp() anyway. (We cannot
7280Sstevel@tonic-gate 			 * use strcmp(), because buf is not '\0' terminated.)
7290Sstevel@tonic-gate 			 */
7300Sstevel@tonic-gate 			 j = found = 0;
7310Sstevel@tonic-gate 			 while (ca_list[j])
7320Sstevel@tonic-gate 				{
7330Sstevel@tonic-gate 				if (!strncmp(buf, ca_list[j]->name, buflen) &&
7340Sstevel@tonic-gate 				    (ca_list[j]->name[buflen] == '\0'))
7350Sstevel@tonic-gate 					{
7360Sstevel@tonic-gate 					found = 1;
7370Sstevel@tonic-gate 					break;
7380Sstevel@tonic-gate 					}
7390Sstevel@tonic-gate 				else
7400Sstevel@tonic-gate 					j++;
7410Sstevel@tonic-gate 				}
7420Sstevel@tonic-gate 			if (!found)
7430Sstevel@tonic-gate 				break;	/* ignore this entry */
7440Sstevel@tonic-gate 
7452139Sjp161948 			/* New algorithms:
7462139Sjp161948 			 *  1 - any old restrictions apply outside new mask
7472139Sjp161948 			 *  2 - any new restrictions apply outside old mask
7482139Sjp161948 			 *  3 - enforce old & new where masks intersect
7492139Sjp161948 			 */
7502139Sjp161948 			algorithms = (algorithms & ~ca_list[j]->mask) |		/* 1 */
7512139Sjp161948 			             (ca_list[j]->algorithms & ~mask) |		/* 2 */
7522139Sjp161948 			             (algorithms & ca_list[j]->algorithms);	/* 3 */
7530Sstevel@tonic-gate 			mask |= ca_list[j]->mask;
7542139Sjp161948 			algo_strength = (algo_strength & ~ca_list[j]->mask_strength) |
7552139Sjp161948 			                (ca_list[j]->algo_strength & ~mask_strength) |
7562139Sjp161948 			                (algo_strength & ca_list[j]->algo_strength);
7570Sstevel@tonic-gate 			mask_strength |= ca_list[j]->mask_strength;
7580Sstevel@tonic-gate 
7590Sstevel@tonic-gate 			if (!multi) break;
7600Sstevel@tonic-gate 			}
7610Sstevel@tonic-gate 
7620Sstevel@tonic-gate 		/*
7630Sstevel@tonic-gate 		 * Ok, we have the rule, now apply it
7640Sstevel@tonic-gate 		 */
7650Sstevel@tonic-gate 		if (rule == CIPHER_SPECIAL)
7660Sstevel@tonic-gate 			{	/* special command */
7670Sstevel@tonic-gate 			ok = 0;
7680Sstevel@tonic-gate 			if ((buflen == 8) &&
7690Sstevel@tonic-gate 				!strncmp(buf, "STRENGTH", 8))
7700Sstevel@tonic-gate 				ok = ssl_cipher_strength_sort(co_list,
7710Sstevel@tonic-gate 					head_p, tail_p);
7720Sstevel@tonic-gate 			else
7730Sstevel@tonic-gate 				SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
7740Sstevel@tonic-gate 					SSL_R_INVALID_COMMAND);
7750Sstevel@tonic-gate 			if (ok == 0)
7760Sstevel@tonic-gate 				retval = 0;
7770Sstevel@tonic-gate 			/*
7780Sstevel@tonic-gate 			 * We do not support any "multi" options
7790Sstevel@tonic-gate 			 * together with "@", so throw away the
7800Sstevel@tonic-gate 			 * rest of the command, if any left, until
7810Sstevel@tonic-gate 			 * end or ':' is found.
7820Sstevel@tonic-gate 			 */
7830Sstevel@tonic-gate 			while ((*l != '\0') && ITEM_SEP(*l))
7840Sstevel@tonic-gate 				l++;
7850Sstevel@tonic-gate 			}
7860Sstevel@tonic-gate 		else if (found)
7870Sstevel@tonic-gate 			{
7880Sstevel@tonic-gate 			ssl_cipher_apply_rule(algorithms, mask,
7890Sstevel@tonic-gate 				algo_strength, mask_strength, rule, -1,
7900Sstevel@tonic-gate 				co_list, head_p, tail_p);
7910Sstevel@tonic-gate 			}
7920Sstevel@tonic-gate 		else
7930Sstevel@tonic-gate 			{
7940Sstevel@tonic-gate 			while ((*l != '\0') && ITEM_SEP(*l))
7950Sstevel@tonic-gate 				l++;
7960Sstevel@tonic-gate 			}
7970Sstevel@tonic-gate 		if (*l == '\0') break; /* done */
7980Sstevel@tonic-gate 		}
7990Sstevel@tonic-gate 
8000Sstevel@tonic-gate 	return(retval);
8010Sstevel@tonic-gate 	}
8020Sstevel@tonic-gate 
STACK_OF(SSL_CIPHER)8030Sstevel@tonic-gate STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
8040Sstevel@tonic-gate 		STACK_OF(SSL_CIPHER) **cipher_list,
8050Sstevel@tonic-gate 		STACK_OF(SSL_CIPHER) **cipher_list_by_id,
8060Sstevel@tonic-gate 		const char *rule_str)
8070Sstevel@tonic-gate 	{
8080Sstevel@tonic-gate 	int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
8090Sstevel@tonic-gate 	unsigned long disabled_mask;
8102139Sjp161948 	STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
8110Sstevel@tonic-gate 	const char *rule_p;
8120Sstevel@tonic-gate 	CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
8130Sstevel@tonic-gate 	SSL_CIPHER **ca_list = NULL;
8140Sstevel@tonic-gate 
8150Sstevel@tonic-gate 	/*
8160Sstevel@tonic-gate 	 * Return with error if nothing to do.
8170Sstevel@tonic-gate 	 */
8182139Sjp161948 	if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)
8192139Sjp161948 		return NULL;
8200Sstevel@tonic-gate 
8210Sstevel@tonic-gate 	/*
8220Sstevel@tonic-gate 	 * To reduce the work to do we only want to process the compiled
8230Sstevel@tonic-gate 	 * in algorithms, so we first get the mask of disabled ciphers.
8240Sstevel@tonic-gate 	 */
8250Sstevel@tonic-gate 	disabled_mask = ssl_cipher_get_disabled();
8260Sstevel@tonic-gate 
8270Sstevel@tonic-gate 	/*
8280Sstevel@tonic-gate 	 * Now we have to collect the available ciphers from the compiled
8290Sstevel@tonic-gate 	 * in ciphers. We cannot get more than the number compiled in, so
8300Sstevel@tonic-gate 	 * it is used for allocation.
8310Sstevel@tonic-gate 	 */
8320Sstevel@tonic-gate 	num_of_ciphers = ssl_method->num_ciphers();
8330Sstevel@tonic-gate #ifdef KSSL_DEBUG
8340Sstevel@tonic-gate 	printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers);
8350Sstevel@tonic-gate #endif    /* KSSL_DEBUG */
8360Sstevel@tonic-gate 	co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);
8370Sstevel@tonic-gate 	if (co_list == NULL)
8380Sstevel@tonic-gate 		{
8390Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
8400Sstevel@tonic-gate 		return(NULL);	/* Failure */
8410Sstevel@tonic-gate 		}
8420Sstevel@tonic-gate 
8430Sstevel@tonic-gate 	ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask,
8440Sstevel@tonic-gate 				   co_list, &head, &tail);
8450Sstevel@tonic-gate 
8460Sstevel@tonic-gate 	/*
8470Sstevel@tonic-gate 	 * We also need cipher aliases for selecting based on the rule_str.
8480Sstevel@tonic-gate 	 * There might be two types of entries in the rule_str: 1) names
8490Sstevel@tonic-gate 	 * of ciphers themselves 2) aliases for groups of ciphers.
8500Sstevel@tonic-gate 	 * For 1) we need the available ciphers and for 2) the cipher
8510Sstevel@tonic-gate 	 * groups of cipher_aliases added together in one list (otherwise
8520Sstevel@tonic-gate 	 * we would be happy with just the cipher_aliases table).
8530Sstevel@tonic-gate 	 */
8540Sstevel@tonic-gate 	num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER);
8550Sstevel@tonic-gate 	num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
8560Sstevel@tonic-gate 	ca_list =
8570Sstevel@tonic-gate 		(SSL_CIPHER **)OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);
8580Sstevel@tonic-gate 	if (ca_list == NULL)
8590Sstevel@tonic-gate 		{
8600Sstevel@tonic-gate 		OPENSSL_free(co_list);
8610Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
8620Sstevel@tonic-gate 		return(NULL);	/* Failure */
8630Sstevel@tonic-gate 		}
8640Sstevel@tonic-gate 	ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mask,
8650Sstevel@tonic-gate 				   head);
8660Sstevel@tonic-gate 
8670Sstevel@tonic-gate 	/*
8680Sstevel@tonic-gate 	 * If the rule_string begins with DEFAULT, apply the default rule
8690Sstevel@tonic-gate 	 * before using the (possibly available) additional rules.
8700Sstevel@tonic-gate 	 */
8710Sstevel@tonic-gate 	ok = 1;
8720Sstevel@tonic-gate 	rule_p = rule_str;
8730Sstevel@tonic-gate 	if (strncmp(rule_str,"DEFAULT",7) == 0)
8740Sstevel@tonic-gate 		{
8750Sstevel@tonic-gate 		ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
8760Sstevel@tonic-gate 			co_list, &head, &tail, ca_list);
8770Sstevel@tonic-gate 		rule_p += 7;
8780Sstevel@tonic-gate 		if (*rule_p == ':')
8790Sstevel@tonic-gate 			rule_p++;
8800Sstevel@tonic-gate 		}
8810Sstevel@tonic-gate 
8820Sstevel@tonic-gate 	if (ok && (strlen(rule_p) > 0))
8830Sstevel@tonic-gate 		ok = ssl_cipher_process_rulestr(rule_p, co_list, &head, &tail,
8840Sstevel@tonic-gate 						ca_list);
8850Sstevel@tonic-gate 
8860Sstevel@tonic-gate 	OPENSSL_free(ca_list);	/* Not needed anymore */
8870Sstevel@tonic-gate 
8880Sstevel@tonic-gate 	if (!ok)
8890Sstevel@tonic-gate 		{	/* Rule processing failure */
8900Sstevel@tonic-gate 		OPENSSL_free(co_list);
8910Sstevel@tonic-gate 		return(NULL);
8920Sstevel@tonic-gate 		}
8930Sstevel@tonic-gate 	/*
8940Sstevel@tonic-gate 	 * Allocate new "cipherstack" for the result, return with error
8950Sstevel@tonic-gate 	 * if we cannot get one.
8960Sstevel@tonic-gate 	 */
8970Sstevel@tonic-gate 	if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL)
8980Sstevel@tonic-gate 		{
8990Sstevel@tonic-gate 		OPENSSL_free(co_list);
9000Sstevel@tonic-gate 		return(NULL);
9010Sstevel@tonic-gate 		}
9020Sstevel@tonic-gate 
9030Sstevel@tonic-gate 	/*
9040Sstevel@tonic-gate 	 * The cipher selection for the list is done. The ciphers are added
9050Sstevel@tonic-gate 	 * to the resulting precedence to the STACK_OF(SSL_CIPHER).
9060Sstevel@tonic-gate 	 */
9070Sstevel@tonic-gate 	for (curr = head; curr != NULL; curr = curr->next)
9080Sstevel@tonic-gate 		{
9090Sstevel@tonic-gate 		if (curr->active)
9100Sstevel@tonic-gate 			{
9110Sstevel@tonic-gate 			sk_SSL_CIPHER_push(cipherstack, curr->cipher);
9120Sstevel@tonic-gate #ifdef CIPHER_DEBUG
9130Sstevel@tonic-gate 			printf("<%s>\n",curr->cipher->name);
9140Sstevel@tonic-gate #endif
9150Sstevel@tonic-gate 			}
9160Sstevel@tonic-gate 		}
9170Sstevel@tonic-gate 	OPENSSL_free(co_list);	/* Not needed any longer */
9180Sstevel@tonic-gate 
9192139Sjp161948 	tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
9202139Sjp161948 	if (tmp_cipher_list == NULL)
9210Sstevel@tonic-gate 		{
9220Sstevel@tonic-gate 		sk_SSL_CIPHER_free(cipherstack);
9232139Sjp161948 		return NULL;
9240Sstevel@tonic-gate 		}
9252139Sjp161948 	if (*cipher_list != NULL)
9262139Sjp161948 		sk_SSL_CIPHER_free(*cipher_list);
9272139Sjp161948 	*cipher_list = cipherstack;
9282139Sjp161948 	if (*cipher_list_by_id != NULL)
9292139Sjp161948 		sk_SSL_CIPHER_free(*cipher_list_by_id);
9302139Sjp161948 	*cipher_list_by_id = tmp_cipher_list;
9310Sstevel@tonic-gate 	sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp);
9320Sstevel@tonic-gate 
9330Sstevel@tonic-gate 	return(cipherstack);
9340Sstevel@tonic-gate 	}
9350Sstevel@tonic-gate 
SSL_CIPHER_description(SSL_CIPHER * cipher,char * buf,int len)9360Sstevel@tonic-gate char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len)
9370Sstevel@tonic-gate 	{
9380Sstevel@tonic-gate 	int is_export,pkl,kl;
9392139Sjp161948 	const char *ver,*exp_str;
9402139Sjp161948 	const char *kx,*au,*enc,*mac;
9410Sstevel@tonic-gate 	unsigned long alg,alg2,alg_s;
9420Sstevel@tonic-gate #ifdef KSSL_DEBUG
9432139Sjp161948 	static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx\n";
9440Sstevel@tonic-gate #else
9452139Sjp161948 	static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n";
9460Sstevel@tonic-gate #endif /* KSSL_DEBUG */
9470Sstevel@tonic-gate 
9480Sstevel@tonic-gate 	alg=cipher->algorithms;
9490Sstevel@tonic-gate 	alg_s=cipher->algo_strength;
9500Sstevel@tonic-gate 	alg2=cipher->algorithm2;
9510Sstevel@tonic-gate 
9520Sstevel@tonic-gate 	is_export=SSL_C_IS_EXPORT(cipher);
9530Sstevel@tonic-gate 	pkl=SSL_C_EXPORT_PKEYLENGTH(cipher);
9540Sstevel@tonic-gate 	kl=SSL_C_EXPORT_KEYLENGTH(cipher);
9550Sstevel@tonic-gate 	exp_str=is_export?" export":"";
9562139Sjp161948 
9570Sstevel@tonic-gate 	if (alg & SSL_SSLV2)
9580Sstevel@tonic-gate 		ver="SSLv2";
9590Sstevel@tonic-gate 	else if (alg & SSL_SSLV3)
9600Sstevel@tonic-gate 		ver="SSLv3";
9610Sstevel@tonic-gate 	else
9620Sstevel@tonic-gate 		ver="unknown";
9630Sstevel@tonic-gate 
9640Sstevel@tonic-gate 	switch (alg&SSL_MKEY_MASK)
9650Sstevel@tonic-gate 		{
9660Sstevel@tonic-gate 	case SSL_kRSA:
9670Sstevel@tonic-gate 		kx=is_export?(pkl == 512 ? "RSA(512)" : "RSA(1024)"):"RSA";
9680Sstevel@tonic-gate 		break;
9690Sstevel@tonic-gate 	case SSL_kDHr:
9700Sstevel@tonic-gate 		kx="DH/RSA";
9710Sstevel@tonic-gate 		break;
9720Sstevel@tonic-gate 	case SSL_kDHd:
9730Sstevel@tonic-gate 		kx="DH/DSS";
9740Sstevel@tonic-gate 		break;
9750Sstevel@tonic-gate         case SSL_kKRB5:         /* VRS */
9760Sstevel@tonic-gate         case SSL_KRB5:          /* VRS */
9770Sstevel@tonic-gate             kx="KRB5";
9780Sstevel@tonic-gate             break;
9790Sstevel@tonic-gate 	case SSL_kFZA:
9800Sstevel@tonic-gate 		kx="Fortezza";
9810Sstevel@tonic-gate 		break;
9820Sstevel@tonic-gate 	case SSL_kEDH:
9830Sstevel@tonic-gate 		kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH";
9840Sstevel@tonic-gate 		break;
9852139Sjp161948 	case SSL_kECDH:
9862139Sjp161948 	case SSL_kECDHE:
9872139Sjp161948 		kx=is_export?"ECDH(<=163)":"ECDH";
9882139Sjp161948 		break;
9890Sstevel@tonic-gate 	default:
9900Sstevel@tonic-gate 		kx="unknown";
9910Sstevel@tonic-gate 		}
9920Sstevel@tonic-gate 
9930Sstevel@tonic-gate 	switch (alg&SSL_AUTH_MASK)
9940Sstevel@tonic-gate 		{
9950Sstevel@tonic-gate 	case SSL_aRSA:
9960Sstevel@tonic-gate 		au="RSA";
9970Sstevel@tonic-gate 		break;
9980Sstevel@tonic-gate 	case SSL_aDSS:
9990Sstevel@tonic-gate 		au="DSS";
10000Sstevel@tonic-gate 		break;
10010Sstevel@tonic-gate 	case SSL_aDH:
10020Sstevel@tonic-gate 		au="DH";
10030Sstevel@tonic-gate 		break;
10040Sstevel@tonic-gate         case SSL_aKRB5:         /* VRS */
10050Sstevel@tonic-gate         case SSL_KRB5:          /* VRS */
10060Sstevel@tonic-gate             au="KRB5";
10070Sstevel@tonic-gate             break;
10080Sstevel@tonic-gate 	case SSL_aFZA:
10090Sstevel@tonic-gate 	case SSL_aNULL:
10100Sstevel@tonic-gate 		au="None";
10110Sstevel@tonic-gate 		break;
10122139Sjp161948 	case SSL_aECDSA:
10132139Sjp161948 		au="ECDSA";
10142139Sjp161948 		break;
10150Sstevel@tonic-gate 	default:
10160Sstevel@tonic-gate 		au="unknown";
10170Sstevel@tonic-gate 		break;
10180Sstevel@tonic-gate 		}
10190Sstevel@tonic-gate 
10200Sstevel@tonic-gate 	switch (alg&SSL_ENC_MASK)
10210Sstevel@tonic-gate 		{
10220Sstevel@tonic-gate 	case SSL_DES:
10230Sstevel@tonic-gate 		enc=(is_export && kl == 5)?"DES(40)":"DES(56)";
10240Sstevel@tonic-gate 		break;
10250Sstevel@tonic-gate 	case SSL_3DES:
10260Sstevel@tonic-gate 		enc="3DES(168)";
10270Sstevel@tonic-gate 		break;
10280Sstevel@tonic-gate 	case SSL_RC4:
10290Sstevel@tonic-gate 		enc=is_export?(kl == 5 ? "RC4(40)" : "RC4(56)")
10300Sstevel@tonic-gate 		  :((alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)");
10310Sstevel@tonic-gate 		break;
10320Sstevel@tonic-gate 	case SSL_RC2:
10330Sstevel@tonic-gate 		enc=is_export?(kl == 5 ? "RC2(40)" : "RC2(56)"):"RC2(128)";
10340Sstevel@tonic-gate 		break;
10350Sstevel@tonic-gate 	case SSL_IDEA:
10360Sstevel@tonic-gate 		enc="IDEA(128)";
10370Sstevel@tonic-gate 		break;
10380Sstevel@tonic-gate 	case SSL_eFZA:
10390Sstevel@tonic-gate 		enc="Fortezza";
10400Sstevel@tonic-gate 		break;
10410Sstevel@tonic-gate 	case SSL_eNULL:
10420Sstevel@tonic-gate 		enc="None";
10430Sstevel@tonic-gate 		break;
10440Sstevel@tonic-gate 	case SSL_AES:
10450Sstevel@tonic-gate 		switch(cipher->strength_bits)
10460Sstevel@tonic-gate 			{
10470Sstevel@tonic-gate 		case 128: enc="AES(128)"; break;
10480Sstevel@tonic-gate 		case 192: enc="AES(192)"; break;
10490Sstevel@tonic-gate 		case 256: enc="AES(256)"; break;
10500Sstevel@tonic-gate 		default: enc="AES(?""?""?)"; break;
10510Sstevel@tonic-gate 			}
10520Sstevel@tonic-gate 		break;
10530Sstevel@tonic-gate 	default:
10540Sstevel@tonic-gate 		enc="unknown";
10550Sstevel@tonic-gate 		break;
10560Sstevel@tonic-gate 		}
10570Sstevel@tonic-gate 
10580Sstevel@tonic-gate 	switch (alg&SSL_MAC_MASK)
10590Sstevel@tonic-gate 		{
10600Sstevel@tonic-gate 	case SSL_MD5:
10610Sstevel@tonic-gate 		mac="MD5";
10620Sstevel@tonic-gate 		break;
10630Sstevel@tonic-gate 	case SSL_SHA1:
10640Sstevel@tonic-gate 		mac="SHA1";
10650Sstevel@tonic-gate 		break;
10660Sstevel@tonic-gate 	default:
10670Sstevel@tonic-gate 		mac="unknown";
10680Sstevel@tonic-gate 		break;
10690Sstevel@tonic-gate 		}
10700Sstevel@tonic-gate 
10710Sstevel@tonic-gate 	if (buf == NULL)
10720Sstevel@tonic-gate 		{
10730Sstevel@tonic-gate 		len=128;
10740Sstevel@tonic-gate 		buf=OPENSSL_malloc(len);
10750Sstevel@tonic-gate 		if (buf == NULL) return("OPENSSL_malloc Error");
10760Sstevel@tonic-gate 		}
10770Sstevel@tonic-gate 	else if (len < 128)
10780Sstevel@tonic-gate 		return("Buffer too small");
10790Sstevel@tonic-gate 
10800Sstevel@tonic-gate #ifdef KSSL_DEBUG
10810Sstevel@tonic-gate 	BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str,alg);
10820Sstevel@tonic-gate #else
10830Sstevel@tonic-gate 	BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str);
10840Sstevel@tonic-gate #endif /* KSSL_DEBUG */
10850Sstevel@tonic-gate 	return(buf);
10860Sstevel@tonic-gate 	}
10870Sstevel@tonic-gate 
SSL_CIPHER_get_version(const SSL_CIPHER * c)10882139Sjp161948 char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
10890Sstevel@tonic-gate 	{
10900Sstevel@tonic-gate 	int i;
10910Sstevel@tonic-gate 
10920Sstevel@tonic-gate 	if (c == NULL) return("(NONE)");
10930Sstevel@tonic-gate 	i=(int)(c->id>>24L);
10940Sstevel@tonic-gate 	if (i == 3)
10950Sstevel@tonic-gate 		return("TLSv1/SSLv3");
10960Sstevel@tonic-gate 	else if (i == 2)
10970Sstevel@tonic-gate 		return("SSLv2");
10980Sstevel@tonic-gate 	else
10990Sstevel@tonic-gate 		return("unknown");
11000Sstevel@tonic-gate 	}
11010Sstevel@tonic-gate 
11020Sstevel@tonic-gate /* return the actual cipher being used */
SSL_CIPHER_get_name(const SSL_CIPHER * c)11032139Sjp161948 const char *SSL_CIPHER_get_name(const SSL_CIPHER *c)
11040Sstevel@tonic-gate 	{
11050Sstevel@tonic-gate 	if (c != NULL)
11060Sstevel@tonic-gate 		return(c->name);
11070Sstevel@tonic-gate 	return("(NONE)");
11080Sstevel@tonic-gate 	}
11090Sstevel@tonic-gate 
11100Sstevel@tonic-gate /* number of bits for symmetric cipher */
SSL_CIPHER_get_bits(const SSL_CIPHER * c,int * alg_bits)11112139Sjp161948 int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
11120Sstevel@tonic-gate 	{
11130Sstevel@tonic-gate 	int ret=0;
11140Sstevel@tonic-gate 
11150Sstevel@tonic-gate 	if (c != NULL)
11160Sstevel@tonic-gate 		{
11170Sstevel@tonic-gate 		if (alg_bits != NULL) *alg_bits = c->alg_bits;
11180Sstevel@tonic-gate 		ret = c->strength_bits;
11190Sstevel@tonic-gate 		}
11200Sstevel@tonic-gate 	return(ret);
11210Sstevel@tonic-gate 	}
11220Sstevel@tonic-gate 
ssl3_comp_find(STACK_OF (SSL_COMP)* sk,int n)11230Sstevel@tonic-gate SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)
11240Sstevel@tonic-gate 	{
11250Sstevel@tonic-gate 	SSL_COMP *ctmp;
11260Sstevel@tonic-gate 	int i,nn;
11270Sstevel@tonic-gate 
11280Sstevel@tonic-gate 	if ((n == 0) || (sk == NULL)) return(NULL);
11290Sstevel@tonic-gate 	nn=sk_SSL_COMP_num(sk);
11300Sstevel@tonic-gate 	for (i=0; i<nn; i++)
11310Sstevel@tonic-gate 		{
11320Sstevel@tonic-gate 		ctmp=sk_SSL_COMP_value(sk,i);
11330Sstevel@tonic-gate 		if (ctmp->id == n)
11340Sstevel@tonic-gate 			return(ctmp);
11350Sstevel@tonic-gate 		}
11360Sstevel@tonic-gate 	return(NULL);
11370Sstevel@tonic-gate 	}
11380Sstevel@tonic-gate 
11392139Sjp161948 #ifdef OPENSSL_NO_COMP
SSL_COMP_get_compression_methods(void)11402139Sjp161948 void *SSL_COMP_get_compression_methods(void)
11410Sstevel@tonic-gate 	{
11422139Sjp161948 	return NULL;
11432139Sjp161948 	}
SSL_COMP_add_compression_method(int id,void * cm)11442139Sjp161948 int SSL_COMP_add_compression_method(int id, void *cm)
11452139Sjp161948 	{
11462139Sjp161948 	return 1;
11470Sstevel@tonic-gate 	}
11480Sstevel@tonic-gate 
SSL_COMP_get_name(const void * comp)11492139Sjp161948 const char *SSL_COMP_get_name(const void *comp)
11502139Sjp161948 	{
11512139Sjp161948 	return NULL;
11522139Sjp161948 	}
11532139Sjp161948 #else
STACK_OF(SSL_COMP)11540Sstevel@tonic-gate STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
11550Sstevel@tonic-gate 	{
11562139Sjp161948 	load_builtin_compressions();
11570Sstevel@tonic-gate 	return(ssl_comp_methods);
11580Sstevel@tonic-gate 	}
11590Sstevel@tonic-gate 
SSL_COMP_add_compression_method(int id,COMP_METHOD * cm)11600Sstevel@tonic-gate int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)
11610Sstevel@tonic-gate 	{
11620Sstevel@tonic-gate 	SSL_COMP *comp;
11630Sstevel@tonic-gate 
11640Sstevel@tonic-gate         if (cm == NULL || cm->type == NID_undef)
11650Sstevel@tonic-gate                 return 1;
11660Sstevel@tonic-gate 
11672139Sjp161948 	/* According to draft-ietf-tls-compression-04.txt, the
11682139Sjp161948 	   compression number ranges should be the following:
11692139Sjp161948 
11702139Sjp161948 	   0 to 63:    methods defined by the IETF
11712139Sjp161948 	   64 to 192:  external party methods assigned by IANA
11722139Sjp161948 	   193 to 255: reserved for private use */
11732139Sjp161948 	if (id < 193 || id > 255)
11742139Sjp161948 		{
11752139Sjp161948 		SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE);
11762139Sjp161948 		return 0;
11772139Sjp161948 		}
11782139Sjp161948 
11790Sstevel@tonic-gate 	MemCheck_off();
11800Sstevel@tonic-gate 	comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
11810Sstevel@tonic-gate 	comp->id=id;
11820Sstevel@tonic-gate 	comp->method=cm;
11832139Sjp161948 	load_builtin_compressions();
11842139Sjp161948 	if (ssl_comp_methods
11852139Sjp161948 		&& !sk_SSL_COMP_find(ssl_comp_methods,comp))
11860Sstevel@tonic-gate 		{
11872139Sjp161948 		OPENSSL_free(comp);
11882139Sjp161948 		MemCheck_on();
11892139Sjp161948 		SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_DUPLICATE_COMPRESSION_ID);
11902139Sjp161948 		return(1);
11912139Sjp161948 		}
11922139Sjp161948 	else if ((ssl_comp_methods == NULL)
11932139Sjp161948 		|| !sk_SSL_COMP_push(ssl_comp_methods,comp))
11942139Sjp161948 		{
11952139Sjp161948 		OPENSSL_free(comp);
11960Sstevel@tonic-gate 		MemCheck_on();
11970Sstevel@tonic-gate 		SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,ERR_R_MALLOC_FAILURE);
11980Sstevel@tonic-gate 		return(1);
11990Sstevel@tonic-gate 		}
12000Sstevel@tonic-gate 	else
12010Sstevel@tonic-gate 		{
12020Sstevel@tonic-gate 		MemCheck_on();
12030Sstevel@tonic-gate 		return(0);
12040Sstevel@tonic-gate 		}
12050Sstevel@tonic-gate 	}
12062139Sjp161948 
SSL_COMP_get_name(const COMP_METHOD * comp)12072139Sjp161948 const char *SSL_COMP_get_name(const COMP_METHOD *comp)
12082139Sjp161948 	{
12092139Sjp161948 	if (comp)
12102139Sjp161948 		return comp->name;
12112139Sjp161948 	return NULL;
12122139Sjp161948 	}
12132139Sjp161948 
12142139Sjp161948 #endif
1215