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