1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libssl/src/ssl_ciph.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1342 @@
1.4 +/* ssl/ssl_ciph.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
1.61 + *
1.62 + * Redistribution and use in source and binary forms, with or without
1.63 + * modification, are permitted provided that the following conditions
1.64 + * are met:
1.65 + *
1.66 + * 1. Redistributions of source code must retain the above copyright
1.67 + * notice, this list of conditions and the following disclaimer.
1.68 + *
1.69 + * 2. Redistributions in binary form must reproduce the above copyright
1.70 + * notice, this list of conditions and the following disclaimer in
1.71 + * the documentation and/or other materials provided with the
1.72 + * distribution.
1.73 + *
1.74 + * 3. All advertising materials mentioning features or use of this
1.75 + * software must display the following acknowledgment:
1.76 + * "This product includes software developed by the OpenSSL Project
1.77 + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
1.78 + *
1.79 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
1.80 + * endorse or promote products derived from this software without
1.81 + * prior written permission. For written permission, please contact
1.82 + * openssl-core@openssl.org.
1.83 + *
1.84 + * 5. Products derived from this software may not be called "OpenSSL"
1.85 + * nor may "OpenSSL" appear in their names without prior written
1.86 + * permission of the OpenSSL Project.
1.87 + *
1.88 + * 6. Redistributions of any form whatsoever must retain the following
1.89 + * acknowledgment:
1.90 + * "This product includes software developed by the OpenSSL Project
1.91 + * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
1.92 + *
1.93 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
1.94 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.95 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1.96 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
1.97 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1.98 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1.99 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1.100 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.101 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1.102 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.103 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1.104 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1.105 + * ====================================================================
1.106 + *
1.107 + * This product includes cryptographic software written by Eric Young
1.108 + * (eay@cryptsoft.com). This product includes software written by Tim
1.109 + * Hudson (tjh@cryptsoft.com).
1.110 + *
1.111 + */
1.112 +/* ====================================================================
1.113 +*/
1.114 +/* ====================================================================
1.115 + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
1.116 + * ECC cipher suite support in OpenSSL originally developed by
1.117 + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
1.118 + */
1.119 + /*
1.120 + © Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
1.121 + */
1.122 +
1.123 +#include <stdio.h>
1.124 +#include <openssl/objects.h>
1.125 +#include <openssl/comp.h>
1.126 +#include "ssl_locl.h"
1.127 +
1.128 +#define SSL_ENC_DES_IDX 0
1.129 +#define SSL_ENC_3DES_IDX 1
1.130 +#define SSL_ENC_RC4_IDX 2
1.131 +#define SSL_ENC_RC2_IDX 3
1.132 +#define SSL_ENC_IDEA_IDX 4
1.133 +#define SSL_ENC_eFZA_IDX 5
1.134 +#define SSL_ENC_NULL_IDX 6
1.135 +#define SSL_ENC_AES128_IDX 7
1.136 +#define SSL_ENC_AES256_IDX 8
1.137 +#define SSL_ENC_NUM_IDX 9
1.138 +
1.139 +#ifndef EMULATOR
1.140 +static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={
1.141 + NULL,NULL,NULL,NULL,NULL,NULL,
1.142 + };
1.143 +#else
1.144 + GET_STATIC_ARRAY_FROM_TLS(ssl_cipher_methods,ssl_ciph,const EVP_CIPHER *)
1.145 +
1.146 + #define ssl_cipher_methods (GET_WSD_VAR_NAME(ssl_cipher_methods,ssl_ciph,s)())
1.147 +#endif
1.148 +
1.149 +#define SSL_COMP_NULL_IDX 0
1.150 +#define SSL_COMP_ZLIB_IDX 1
1.151 +#define SSL_COMP_NUM_IDX 2
1.152 +
1.153 +#ifndef EMULATOR
1.154 +static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL;
1.155 +#else
1.156 + GET_STATIC_VAR_FROM_TLS(ssl_comp_methods,ssl_ciph,STACK_OF(SSL_COMP) *)
1.157 +
1.158 + #define ssl_comp_methods (*GET_WSD_VAR_NAME(ssl_comp_methods,ssl_ciph,s)())
1.159 +#endif
1.160 +
1.161 +#define SSL_MD_MD5_IDX 0
1.162 +#define SSL_MD_SHA1_IDX 1
1.163 +#define SSL_MD_NUM_IDX 2
1.164 +#ifndef EMULATOR
1.165 +static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={
1.166 + NULL,NULL,
1.167 + };
1.168 +#else /* EMULATOR */
1.169 + GET_STATIC_ARRAY_FROM_TLS(ssl_digest_methods,ssl_ciph,const EVP_MD *)
1.170 +
1.171 + #define ssl_digest_methods (GET_WSD_VAR_NAME(ssl_digest_methods,ssl_ciph,s)())
1.172 +#endif
1.173 +#define CIPHER_ADD 1
1.174 +#define CIPHER_KILL 2
1.175 +#define CIPHER_DEL 3
1.176 +#define CIPHER_ORD 4
1.177 +#define CIPHER_SPECIAL 5
1.178 +
1.179 +typedef struct cipher_order_st
1.180 + {
1.181 + SSL_CIPHER *cipher;
1.182 + int active;
1.183 + int dead;
1.184 + struct cipher_order_st *next,*prev;
1.185 + } CIPHER_ORDER;
1.186 +
1.187 +static const SSL_CIPHER cipher_aliases[]={
1.188 + /* Don't include eNULL unless specifically enabled. */
1.189 + /* Don't include ECC in ALL because these ciphers are not yet official. */
1.190 + {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 */
1.191 + /* TODO: COMPLEMENT OF ALL and COMPLEMENT OF DEFAULT do not have ECC cipher suites handled properly. */
1.192 + {0,SSL_TXT_CMPALL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0}, /* COMPLEMENT OF ALL */
1.193 + {0,SSL_TXT_CMPDEF,0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK,0},
1.194 + {0,SSL_TXT_kKRB5,0,SSL_kKRB5,0,0,0,0,SSL_MKEY_MASK,0}, /* VRS Kerberos5 */
1.195 + {0,SSL_TXT_kRSA,0,SSL_kRSA, 0,0,0,0,SSL_MKEY_MASK,0},
1.196 + {0,SSL_TXT_kDHr,0,SSL_kDHr, 0,0,0,0,SSL_MKEY_MASK,0},
1.197 + {0,SSL_TXT_kDHd,0,SSL_kDHd, 0,0,0,0,SSL_MKEY_MASK,0},
1.198 + {0,SSL_TXT_kEDH,0,SSL_kEDH, 0,0,0,0,SSL_MKEY_MASK,0},
1.199 + {0,SSL_TXT_kFZA,0,SSL_kFZA, 0,0,0,0,SSL_MKEY_MASK,0},
1.200 + {0,SSL_TXT_DH, 0,SSL_DH, 0,0,0,0,SSL_MKEY_MASK,0},
1.201 + {0,SSL_TXT_ECC, 0,(SSL_kECDH|SSL_kECDHE), 0,0,0,0,SSL_MKEY_MASK,0},
1.202 + {0,SSL_TXT_EDH, 0,SSL_EDH, 0,0,0,0,SSL_MKEY_MASK|SSL_AUTH_MASK,0},
1.203 + {0,SSL_TXT_aKRB5,0,SSL_aKRB5,0,0,0,0,SSL_AUTH_MASK,0}, /* VRS Kerberos5 */
1.204 + {0,SSL_TXT_aRSA,0,SSL_aRSA, 0,0,0,0,SSL_AUTH_MASK,0},
1.205 + {0,SSL_TXT_aDSS,0,SSL_aDSS, 0,0,0,0,SSL_AUTH_MASK,0},
1.206 + {0,SSL_TXT_aFZA,0,SSL_aFZA, 0,0,0,0,SSL_AUTH_MASK,0},
1.207 + {0,SSL_TXT_aNULL,0,SSL_aNULL,0,0,0,0,SSL_AUTH_MASK,0},
1.208 + {0,SSL_TXT_aDH, 0,SSL_aDH, 0,0,0,0,SSL_AUTH_MASK,0},
1.209 + {0,SSL_TXT_DSS, 0,SSL_DSS, 0,0,0,0,SSL_AUTH_MASK,0},
1.210 +
1.211 + {0,SSL_TXT_DES, 0,SSL_DES, 0,0,0,0,SSL_ENC_MASK,0},
1.212 + {0,SSL_TXT_3DES,0,SSL_3DES, 0,0,0,0,SSL_ENC_MASK,0},
1.213 + {0,SSL_TXT_RC4, 0,SSL_RC4, 0,0,0,0,SSL_ENC_MASK,0},
1.214 + {0,SSL_TXT_RC2, 0,SSL_RC2, 0,0,0,0,SSL_ENC_MASK,0},
1.215 +#ifndef OPENSSL_NO_IDEA
1.216 + {0,SSL_TXT_IDEA,0,SSL_IDEA, 0,0,0,0,SSL_ENC_MASK,0},
1.217 +#endif
1.218 + {0,SSL_TXT_eNULL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0},
1.219 + {0,SSL_TXT_eFZA,0,SSL_eFZA, 0,0,0,0,SSL_ENC_MASK,0},
1.220 + {0,SSL_TXT_AES, 0,SSL_AES, 0,0,0,0,SSL_ENC_MASK,0},
1.221 +
1.222 + {0,SSL_TXT_MD5, 0,SSL_MD5, 0,0,0,0,SSL_MAC_MASK,0},
1.223 + {0,SSL_TXT_SHA1,0,SSL_SHA1, 0,0,0,0,SSL_MAC_MASK,0},
1.224 + {0,SSL_TXT_SHA, 0,SSL_SHA, 0,0,0,0,SSL_MAC_MASK,0},
1.225 +
1.226 + {0,SSL_TXT_NULL,0,SSL_NULL, 0,0,0,0,SSL_ENC_MASK,0},
1.227 + {0,SSL_TXT_KRB5,0,SSL_KRB5, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0},
1.228 + {0,SSL_TXT_RSA, 0,SSL_RSA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0},
1.229 + {0,SSL_TXT_ADH, 0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0},
1.230 + {0,SSL_TXT_FZA, 0,SSL_FZA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK|SSL_ENC_MASK,0},
1.231 +
1.232 + {0,SSL_TXT_SSLV2, 0,SSL_SSLV2, 0,0,0,0,SSL_SSL_MASK,0},
1.233 + {0,SSL_TXT_SSLV3, 0,SSL_SSLV3, 0,0,0,0,SSL_SSL_MASK,0},
1.234 + {0,SSL_TXT_TLSV1, 0,SSL_TLSV1, 0,0,0,0,SSL_SSL_MASK,0},
1.235 +
1.236 + {0,SSL_TXT_EXP ,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK},
1.237 + {0,SSL_TXT_EXPORT,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK},
1.238 + {0,SSL_TXT_EXP40, 0, 0, SSL_EXP40, 0,0,0,0,SSL_STRONG_MASK},
1.239 + {0,SSL_TXT_EXP56, 0, 0, SSL_EXP56, 0,0,0,0,SSL_STRONG_MASK},
1.240 + {0,SSL_TXT_LOW, 0, 0, SSL_LOW, 0,0,0,0,SSL_STRONG_MASK},
1.241 + {0,SSL_TXT_MEDIUM,0, 0,SSL_MEDIUM, 0,0,0,0,SSL_STRONG_MASK},
1.242 + {0,SSL_TXT_HIGH, 0, 0, SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK},
1.243 + };
1.244 +
1.245 +void ssl_load_ciphers(void)
1.246 + {
1.247 + ssl_cipher_methods[SSL_ENC_DES_IDX]=
1.248 + EVP_get_cipherbyname(SN_des_cbc);
1.249 + ssl_cipher_methods[SSL_ENC_3DES_IDX]=
1.250 + EVP_get_cipherbyname(SN_des_ede3_cbc);
1.251 + ssl_cipher_methods[SSL_ENC_RC4_IDX]=
1.252 + EVP_get_cipherbyname(SN_rc4);
1.253 + ssl_cipher_methods[SSL_ENC_RC2_IDX]=
1.254 + EVP_get_cipherbyname(SN_rc2_cbc);
1.255 +#ifndef OPENSSL_NO_IDEA
1.256 + ssl_cipher_methods[SSL_ENC_IDEA_IDX]=
1.257 + EVP_get_cipherbyname(SN_idea_cbc);
1.258 +#else
1.259 + ssl_cipher_methods[SSL_ENC_IDEA_IDX]= NULL;
1.260 +#endif
1.261 + ssl_cipher_methods[SSL_ENC_AES128_IDX]=
1.262 + EVP_get_cipherbyname(SN_aes_128_cbc);
1.263 + ssl_cipher_methods[SSL_ENC_AES256_IDX]=
1.264 + EVP_get_cipherbyname(SN_aes_256_cbc);
1.265 +
1.266 + ssl_digest_methods[SSL_MD_MD5_IDX]=
1.267 + EVP_get_digestbyname(SN_md5);
1.268 + ssl_digest_methods[SSL_MD_SHA1_IDX]=
1.269 + EVP_get_digestbyname(SN_sha1);
1.270 + }
1.271 +
1.272 +
1.273 +#ifndef OPENSSL_NO_COMP
1.274 +
1.275 +static int sk_comp_cmp(const SSL_COMP * const *a,
1.276 + const SSL_COMP * const *b)
1.277 + {
1.278 + return((*a)->id-(*b)->id);
1.279 + }
1.280 +
1.281 +static void load_builtin_compressions(void)
1.282 + {
1.283 + int got_write_lock = 0;
1.284 +
1.285 + CRYPTO_r_lock(CRYPTO_LOCK_SSL);
1.286 + if (ssl_comp_methods == NULL)
1.287 + {
1.288 + CRYPTO_r_unlock(CRYPTO_LOCK_SSL);
1.289 + CRYPTO_w_lock(CRYPTO_LOCK_SSL);
1.290 + got_write_lock = 1;
1.291 +
1.292 + if (ssl_comp_methods == NULL)
1.293 + {
1.294 + SSL_COMP *comp = NULL;
1.295 +
1.296 + MemCheck_off();
1.297 + ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp);
1.298 + if (ssl_comp_methods != NULL)
1.299 + {
1.300 + comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
1.301 + if (comp != NULL)
1.302 + {
1.303 + comp->method=COMP_zlib();
1.304 + if (comp->method
1.305 + && comp->method->type == NID_undef)
1.306 + OPENSSL_free(comp);
1.307 + else
1.308 + {
1.309 + comp->id=SSL_COMP_ZLIB_IDX;
1.310 + comp->name=comp->method->name;
1.311 + sk_SSL_COMP_push(ssl_comp_methods,comp);
1.312 + }
1.313 + }
1.314 + }
1.315 + MemCheck_on();
1.316 + }
1.317 + }
1.318 +
1.319 + if (got_write_lock)
1.320 + CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
1.321 + else
1.322 + CRYPTO_r_unlock(CRYPTO_LOCK_SSL);
1.323 +}
1.324 +#endif
1.325 +
1.326 +int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
1.327 + const EVP_MD **md, SSL_COMP **comp)
1.328 + {
1.329 + int i;
1.330 + SSL_CIPHER *c;
1.331 +
1.332 + c=s->cipher;
1.333 + if (c == NULL) return(0);
1.334 + if (comp != NULL)
1.335 + {
1.336 + SSL_COMP ctmp;
1.337 +#ifndef OPENSSL_NO_COMP
1.338 + load_builtin_compressions();
1.339 +#endif
1.340 +
1.341 + *comp=NULL;
1.342 + ctmp.id=s->compress_meth;
1.343 + if (ssl_comp_methods != NULL)
1.344 + {
1.345 + i=sk_SSL_COMP_find(ssl_comp_methods,&ctmp);
1.346 + if (i >= 0)
1.347 + *comp=sk_SSL_COMP_value(ssl_comp_methods,i);
1.348 + else
1.349 + *comp=NULL;
1.350 + }
1.351 + }
1.352 +
1.353 + if ((enc == NULL) || (md == NULL)) return(0);
1.354 +
1.355 + switch (c->algorithms & SSL_ENC_MASK)
1.356 + {
1.357 + case SSL_DES:
1.358 + i=SSL_ENC_DES_IDX;
1.359 + break;
1.360 + case SSL_3DES:
1.361 + i=SSL_ENC_3DES_IDX;
1.362 + break;
1.363 + case SSL_RC4:
1.364 + i=SSL_ENC_RC4_IDX;
1.365 + break;
1.366 + case SSL_RC2:
1.367 + i=SSL_ENC_RC2_IDX;
1.368 + break;
1.369 + case SSL_IDEA:
1.370 + i=SSL_ENC_IDEA_IDX;
1.371 + break;
1.372 + case SSL_eNULL:
1.373 + i=SSL_ENC_NULL_IDX;
1.374 + break;
1.375 + case SSL_AES:
1.376 + switch(c->alg_bits)
1.377 + {
1.378 + case 128: i=SSL_ENC_AES128_IDX; break;
1.379 + case 256: i=SSL_ENC_AES256_IDX; break;
1.380 + default: i=-1; break;
1.381 + }
1.382 + break;
1.383 + default:
1.384 + i= -1;
1.385 + break;
1.386 + }
1.387 +
1.388 + if ((i < 0) || (i > SSL_ENC_NUM_IDX))
1.389 + *enc=NULL;
1.390 + else
1.391 + {
1.392 + if (i == SSL_ENC_NULL_IDX)
1.393 + *enc=EVP_enc_null();
1.394 + else
1.395 + *enc=ssl_cipher_methods[i];
1.396 + }
1.397 +
1.398 + switch (c->algorithms & SSL_MAC_MASK)
1.399 + {
1.400 + case SSL_MD5:
1.401 + i=SSL_MD_MD5_IDX;
1.402 + break;
1.403 + case SSL_SHA1:
1.404 + i=SSL_MD_SHA1_IDX;
1.405 + break;
1.406 + default:
1.407 + i= -1;
1.408 + break;
1.409 + }
1.410 + if ((i < 0) || (i > SSL_MD_NUM_IDX))
1.411 + *md=NULL;
1.412 + else
1.413 + *md=ssl_digest_methods[i];
1.414 +
1.415 + if ((*enc != NULL) && (*md != NULL))
1.416 + return(1);
1.417 + else
1.418 + return(0);
1.419 + }
1.420 +
1.421 +#define ITEM_SEP(a) \
1.422 + (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
1.423 +
1.424 +static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
1.425 + CIPHER_ORDER **tail)
1.426 + {
1.427 + if (curr == *tail) return;
1.428 + if (curr == *head)
1.429 + *head=curr->next;
1.430 + if (curr->prev != NULL)
1.431 + curr->prev->next=curr->next;
1.432 + if (curr->next != NULL) /* should always be true */
1.433 + curr->next->prev=curr->prev;
1.434 + (*tail)->next=curr;
1.435 + curr->prev= *tail;
1.436 + curr->next=NULL;
1.437 + *tail=curr;
1.438 + }
1.439 +
1.440 +static unsigned long ssl_cipher_get_disabled(void)
1.441 + {
1.442 + unsigned long mask;
1.443 +
1.444 + mask = SSL_kFZA;
1.445 +#ifdef OPENSSL_NO_RSA
1.446 + mask |= SSL_aRSA|SSL_kRSA;
1.447 +#endif
1.448 +#ifdef OPENSSL_NO_DSA
1.449 + mask |= SSL_aDSS;
1.450 +#endif
1.451 +#ifdef OPENSSL_NO_DH
1.452 + mask |= SSL_kDHr|SSL_kDHd|SSL_kEDH|SSL_aDH;
1.453 +#endif
1.454 +#ifdef OPENSSL_NO_KRB5
1.455 + mask |= SSL_kKRB5|SSL_aKRB5;
1.456 +#endif
1.457 +#ifdef OPENSSL_NO_ECDH
1.458 + mask |= SSL_kECDH|SSL_kECDHE;
1.459 +#endif
1.460 +#ifdef SSL_FORBID_ENULL
1.461 + mask |= SSL_eNULL;
1.462 +#endif
1.463 +
1.464 + mask |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0;
1.465 + mask |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0;
1.466 + mask |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0;
1.467 + mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0;
1.468 + mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0;
1.469 + mask |= (ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL) ? SSL_eFZA:0;
1.470 + mask |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES:0;
1.471 +
1.472 + mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
1.473 + mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
1.474 +
1.475 + return(mask);
1.476 + }
1.477 +
1.478 +static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
1.479 + int num_of_ciphers, unsigned long mask, CIPHER_ORDER *co_list,
1.480 + CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
1.481 + {
1.482 + int i, co_list_num;
1.483 + SSL_CIPHER *c;
1.484 +
1.485 + /*
1.486 + * We have num_of_ciphers descriptions compiled in, depending on the
1.487 + * method selected (SSLv2 and/or SSLv3, TLSv1 etc).
1.488 + * These will later be sorted in a linked list with at most num
1.489 + * entries.
1.490 + */
1.491 +
1.492 + /* Get the initial list of ciphers */
1.493 + co_list_num = 0; /* actual count of ciphers */
1.494 + for (i = 0; i < num_of_ciphers; i++)
1.495 + {
1.496 + c = ssl_method->get_cipher(i);
1.497 + /* drop those that use any of that is not available */
1.498 + if ((c != NULL) && c->valid && !(c->algorithms & mask))
1.499 + {
1.500 + co_list[co_list_num].cipher = c;
1.501 + co_list[co_list_num].next = NULL;
1.502 + co_list[co_list_num].prev = NULL;
1.503 + co_list[co_list_num].active = 0;
1.504 + co_list_num++;
1.505 +#ifdef KSSL_DEBUG
1.506 + printf("\t%d: %s %lx %lx\n",i,c->name,c->id,c->algorithms);
1.507 +#endif /* KSSL_DEBUG */
1.508 + /*
1.509 + if (!sk_push(ca_list,(char *)c)) goto err;
1.510 + */
1.511 + }
1.512 + }
1.513 +
1.514 + /*
1.515 + * Prepare linked list from list entries
1.516 + */
1.517 + for (i = 1; i < co_list_num - 1; i++)
1.518 + {
1.519 + co_list[i].prev = &(co_list[i-1]);
1.520 + co_list[i].next = &(co_list[i+1]);
1.521 + }
1.522 + if (co_list_num > 0)
1.523 + {
1.524 + (*head_p) = &(co_list[0]);
1.525 + (*head_p)->prev = NULL;
1.526 + (*head_p)->next = &(co_list[1]);
1.527 + (*tail_p) = &(co_list[co_list_num - 1]);
1.528 + (*tail_p)->prev = &(co_list[co_list_num - 2]);
1.529 + (*tail_p)->next = NULL;
1.530 + }
1.531 + }
1.532 +
1.533 +static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list,
1.534 + int num_of_group_aliases, unsigned long mask,
1.535 + CIPHER_ORDER *head)
1.536 + {
1.537 + CIPHER_ORDER *ciph_curr;
1.538 + SSL_CIPHER **ca_curr;
1.539 + int i;
1.540 +
1.541 + /*
1.542 + * First, add the real ciphers as already collected
1.543 + */
1.544 + ciph_curr = head;
1.545 + ca_curr = ca_list;
1.546 + while (ciph_curr != NULL)
1.547 + {
1.548 + *ca_curr = ciph_curr->cipher;
1.549 + ca_curr++;
1.550 + ciph_curr = ciph_curr->next;
1.551 + }
1.552 +
1.553 + /*
1.554 + * Now we add the available ones from the cipher_aliases[] table.
1.555 + * They represent either an algorithm, that must be fully
1.556 + * supported (not match any bit in mask) or represent a cipher
1.557 + * strength value (will be added in any case because algorithms=0).
1.558 + */
1.559 + for (i = 0; i < num_of_group_aliases; i++)
1.560 + {
1.561 + if ((i == 0) || /* always fetch "ALL" */
1.562 + !(cipher_aliases[i].algorithms & mask))
1.563 + {
1.564 + *ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
1.565 + ca_curr++;
1.566 + }
1.567 + }
1.568 +
1.569 + *ca_curr = NULL; /* end of list */
1.570 + }
1.571 +
1.572 +static void ssl_cipher_apply_rule(unsigned long cipher_id, unsigned long ssl_version,
1.573 + unsigned long algorithms, unsigned long mask,
1.574 + unsigned long algo_strength, unsigned long mask_strength,
1.575 + int rule, int strength_bits, CIPHER_ORDER *co_list,
1.576 + CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
1.577 + {
1.578 + CIPHER_ORDER *head, *tail, *curr, *curr2, *tail2;
1.579 + SSL_CIPHER *cp;
1.580 + unsigned long ma, ma_s;
1.581 +
1.582 +#ifdef CIPHER_DEBUG
1.583 + printf("Applying rule %d with %08lx %08lx %08lx %08lx (%d)\n",
1.584 + rule, algorithms, mask, algo_strength, mask_strength,
1.585 + strength_bits);
1.586 +#endif
1.587 +
1.588 + curr = head = *head_p;
1.589 + curr2 = head;
1.590 + tail2 = tail = *tail_p;
1.591 + for (;;)
1.592 + {
1.593 + if ((curr == NULL) || (curr == tail2)) break;
1.594 + curr = curr2;
1.595 + curr2 = curr->next;
1.596 +
1.597 + cp = curr->cipher;
1.598 +
1.599 + /* If explicit cipher suite, match only that one for its own protocol version.
1.600 + * Usual selection criteria will be used for similar ciphersuites from other version! */
1.601 +
1.602 + if (cipher_id && (cp->algorithms & SSL_SSL_MASK) == ssl_version)
1.603 + {
1.604 + if (cp->id != cipher_id)
1.605 + continue;
1.606 + }
1.607 +
1.608 + /*
1.609 + * Selection criteria is either the number of strength_bits
1.610 + * or the algorithm used.
1.611 + */
1.612 + else if (strength_bits == -1)
1.613 + {
1.614 + ma = mask & cp->algorithms;
1.615 + ma_s = mask_strength & cp->algo_strength;
1.616 +
1.617 +#ifdef CIPHER_DEBUG
1.618 + printf("\nName: %s:\nAlgo = %08lx Algo_strength = %08lx\nMask = %08lx Mask_strength %08lx\n", cp->name, cp->algorithms, cp->algo_strength, mask, mask_strength);
1.619 + printf("ma = %08lx ma_s %08lx, ma&algo=%08lx, ma_s&algos=%08lx\n", ma, ma_s, ma&algorithms, ma_s&algo_strength);
1.620 +#endif
1.621 + /*
1.622 + * Select: if none of the mask bit was met from the
1.623 + * cipher or not all of the bits were met, the
1.624 + * selection does not apply.
1.625 + */
1.626 + if (((ma == 0) && (ma_s == 0)) ||
1.627 + ((ma & algorithms) != ma) ||
1.628 + ((ma_s & algo_strength) != ma_s))
1.629 + continue; /* does not apply */
1.630 + }
1.631 + else if (strength_bits != cp->strength_bits)
1.632 + continue; /* does not apply */
1.633 +
1.634 +#ifdef CIPHER_DEBUG
1.635 + printf("Action = %d\n", rule);
1.636 +#endif
1.637 +
1.638 + /* add the cipher if it has not been added yet. */
1.639 + if (rule == CIPHER_ADD)
1.640 + {
1.641 + if (!curr->active)
1.642 + {
1.643 + int add_this_cipher = 1;
1.644 +
1.645 + if (((cp->algorithms & (SSL_kECDHE|SSL_kECDH|SSL_aECDSA)) != 0))
1.646 + {
1.647 + /* Make sure "ECCdraft" ciphersuites are activated only if
1.648 + * *explicitly* requested, but not implicitly (such as
1.649 + * as part of the "AES" alias). */
1.650 +
1.651 + add_this_cipher = (mask & (SSL_kECDHE|SSL_kECDH|SSL_aECDSA)) != 0 || cipher_id != 0;
1.652 + }
1.653 +
1.654 + if (add_this_cipher)
1.655 + {
1.656 + ll_append_tail(&head, curr, &tail);
1.657 + curr->active = 1;
1.658 + }
1.659 + }
1.660 + }
1.661 + /* Move the added cipher to this location */
1.662 + else if (rule == CIPHER_ORD)
1.663 + {
1.664 + if (curr->active)
1.665 + {
1.666 + ll_append_tail(&head, curr, &tail);
1.667 + }
1.668 + }
1.669 + else if (rule == CIPHER_DEL)
1.670 + curr->active = 0;
1.671 + else if (rule == CIPHER_KILL)
1.672 + {
1.673 + if (head == curr)
1.674 + head = curr->next;
1.675 + else
1.676 + curr->prev->next = curr->next;
1.677 + if (tail == curr)
1.678 + tail = curr->prev;
1.679 + curr->active = 0;
1.680 + if (curr->next != NULL)
1.681 + curr->next->prev = curr->prev;
1.682 + if (curr->prev != NULL)
1.683 + curr->prev->next = curr->next;
1.684 + curr->next = NULL;
1.685 + curr->prev = NULL;
1.686 + }
1.687 + }
1.688 +
1.689 + *head_p = head;
1.690 + *tail_p = tail;
1.691 + }
1.692 +
1.693 +static int ssl_cipher_strength_sort(CIPHER_ORDER *co_list,
1.694 + CIPHER_ORDER **head_p,
1.695 + CIPHER_ORDER **tail_p)
1.696 + {
1.697 + int max_strength_bits, i, *number_uses;
1.698 + CIPHER_ORDER *curr;
1.699 +
1.700 + /*
1.701 + * This routine sorts the ciphers with descending strength. The sorting
1.702 + * must keep the pre-sorted sequence, so we apply the normal sorting
1.703 + * routine as '+' movement to the end of the list.
1.704 + */
1.705 + max_strength_bits = 0;
1.706 + curr = *head_p;
1.707 + while (curr != NULL)
1.708 + {
1.709 + if (curr->active &&
1.710 + (curr->cipher->strength_bits > max_strength_bits))
1.711 + max_strength_bits = curr->cipher->strength_bits;
1.712 + curr = curr->next;
1.713 + }
1.714 +
1.715 + number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
1.716 + if (!number_uses)
1.717 + {
1.718 + SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT,ERR_R_MALLOC_FAILURE);
1.719 + return(0);
1.720 + }
1.721 + memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int));
1.722 +
1.723 + /*
1.724 + * Now find the strength_bits values actually used
1.725 + */
1.726 + curr = *head_p;
1.727 + while (curr != NULL)
1.728 + {
1.729 + if (curr->active)
1.730 + number_uses[curr->cipher->strength_bits]++;
1.731 + curr = curr->next;
1.732 + }
1.733 + /*
1.734 + * Go through the list of used strength_bits values in descending
1.735 + * order.
1.736 + */
1.737 + for (i = max_strength_bits; i >= 0; i--)
1.738 + if (number_uses[i] > 0)
1.739 + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i,
1.740 + co_list, head_p, tail_p);
1.741 +
1.742 + OPENSSL_free(number_uses);
1.743 + return(1);
1.744 + }
1.745 +
1.746 +static int ssl_cipher_process_rulestr(const char *rule_str,
1.747 + CIPHER_ORDER *co_list, CIPHER_ORDER **head_p,
1.748 + CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list)
1.749 + {
1.750 + unsigned long algorithms, mask, algo_strength, mask_strength;
1.751 + const char *l, *start, *buf;
1.752 + int j, multi, found, rule, retval, ok, buflen;
1.753 + unsigned long cipher_id = 0, ssl_version = 0;
1.754 + char ch;
1.755 +
1.756 + retval = 1;
1.757 + l = rule_str;
1.758 + for (;;)
1.759 + {
1.760 + ch = *l;
1.761 +
1.762 + if (ch == '\0')
1.763 + break; /* done */
1.764 + if (ch == '-')
1.765 + { rule = CIPHER_DEL; l++; }
1.766 + else if (ch == '+')
1.767 + { rule = CIPHER_ORD; l++; }
1.768 + else if (ch == '!')
1.769 + { rule = CIPHER_KILL; l++; }
1.770 + else if (ch == '@')
1.771 + { rule = CIPHER_SPECIAL; l++; }
1.772 + else
1.773 + { rule = CIPHER_ADD; }
1.774 +
1.775 + if (ITEM_SEP(ch))
1.776 + {
1.777 + l++;
1.778 + continue;
1.779 + }
1.780 +
1.781 + algorithms = mask = algo_strength = mask_strength = 0;
1.782 +
1.783 + start=l;
1.784 + for (;;)
1.785 + {
1.786 + ch = *l;
1.787 + buf = l;
1.788 + buflen = 0;
1.789 +#ifndef CHARSET_EBCDIC
1.790 + while ( ((ch >= 'A') && (ch <= 'Z')) ||
1.791 + ((ch >= '0') && (ch <= '9')) ||
1.792 + ((ch >= 'a') && (ch <= 'z')) ||
1.793 + (ch == '-'))
1.794 +#else
1.795 + while ( isalnum(ch) || (ch == '-'))
1.796 +#endif
1.797 + {
1.798 + ch = *(++l);
1.799 + buflen++;
1.800 + }
1.801 +
1.802 + if (buflen == 0)
1.803 + {
1.804 + /*
1.805 + * We hit something we cannot deal with,
1.806 + * it is no command or separator nor
1.807 + * alphanumeric, so we call this an error.
1.808 + */
1.809 + SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
1.810 + SSL_R_INVALID_COMMAND);
1.811 + retval = found = 0;
1.812 + l++;
1.813 + break;
1.814 + }
1.815 +
1.816 + if (rule == CIPHER_SPECIAL)
1.817 + {
1.818 + found = 0; /* unused -- avoid compiler warning */
1.819 + break; /* special treatment */
1.820 + }
1.821 +
1.822 + /* check for multi-part specification */
1.823 + if (ch == '+')
1.824 + {
1.825 + multi=1;
1.826 + l++;
1.827 + }
1.828 + else
1.829 + multi=0;
1.830 +
1.831 + /*
1.832 + * Now search for the cipher alias in the ca_list. Be careful
1.833 + * with the strncmp, because the "buflen" limitation
1.834 + * will make the rule "ADH:SOME" and the cipher
1.835 + * "ADH-MY-CIPHER" look like a match for buflen=3.
1.836 + * So additionally check whether the cipher name found
1.837 + * has the correct length. We can save a strlen() call:
1.838 + * just checking for the '\0' at the right place is
1.839 + * sufficient, we have to strncmp() anyway. (We cannot
1.840 + * use strcmp(), because buf is not '\0' terminated.)
1.841 + */
1.842 + j = found = 0;
1.843 + cipher_id = 0;
1.844 + ssl_version = 0;
1.845 +
1.846 + while (ca_list[j])
1.847 + {
1.848 + if (!strncmp(buf, ca_list[j]->name, buflen) &&
1.849 + (ca_list[j]->name[buflen] == '\0'))
1.850 + {
1.851 + found = 1;
1.852 + break;
1.853 + }
1.854 + else
1.855 + j++;
1.856 + }
1.857 + if (!found)
1.858 + break; /* ignore this entry */
1.859 +
1.860 + /* New algorithms:
1.861 + * 1 - any old restrictions apply outside new mask
1.862 + * 2 - any new restrictions apply outside old mask
1.863 + * 3 - enforce old & new where masks intersect
1.864 + */
1.865 + algorithms = (algorithms & ~ca_list[j]->mask) | /* 1 */
1.866 + (ca_list[j]->algorithms & ~mask) | /* 2 */
1.867 + (algorithms & ca_list[j]->algorithms); /* 3 */
1.868 + mask |= ca_list[j]->mask;
1.869 + algo_strength = (algo_strength & ~ca_list[j]->mask_strength) |
1.870 + (ca_list[j]->algo_strength & ~mask_strength) |
1.871 + (algo_strength & ca_list[j]->algo_strength);
1.872 + mask_strength |= ca_list[j]->mask_strength;
1.873 +
1.874 + /* explicit ciphersuite found */
1.875 + if (ca_list[j]->valid)
1.876 + {
1.877 + cipher_id = ca_list[j]->id;
1.878 + ssl_version = ca_list[j]->algorithms & SSL_SSL_MASK;
1.879 + break;
1.880 + }
1.881 +
1.882 + if (!multi) break;
1.883 + }
1.884 +
1.885 + /*
1.886 + * Ok, we have the rule, now apply it
1.887 + */
1.888 + if (rule == CIPHER_SPECIAL)
1.889 + { /* special command */
1.890 + ok = 0;
1.891 + if ((buflen == 8) &&
1.892 + !strncmp(buf, "STRENGTH", 8))
1.893 + ok = ssl_cipher_strength_sort(co_list,
1.894 + head_p, tail_p);
1.895 + else
1.896 + SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
1.897 + SSL_R_INVALID_COMMAND);
1.898 + if (ok == 0)
1.899 + retval = 0;
1.900 + /*
1.901 + * We do not support any "multi" options
1.902 + * together with "@", so throw away the
1.903 + * rest of the command, if any left, until
1.904 + * end or ':' is found.
1.905 + */
1.906 + while ((*l != '\0') && !ITEM_SEP(*l))
1.907 + l++;
1.908 + }
1.909 + else if (found)
1.910 + {
1.911 + ssl_cipher_apply_rule(cipher_id, ssl_version, algorithms, mask,
1.912 + algo_strength, mask_strength, rule, -1,
1.913 + co_list, head_p, tail_p);
1.914 + }
1.915 + else
1.916 + {
1.917 + while ((*l != '\0') && !ITEM_SEP(*l))
1.918 + l++;
1.919 + }
1.920 + if (*l == '\0') break; /* done */
1.921 + }
1.922 +
1.923 + return(retval);
1.924 + }
1.925 +
1.926 +STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
1.927 + STACK_OF(SSL_CIPHER) **cipher_list,
1.928 + STACK_OF(SSL_CIPHER) **cipher_list_by_id,
1.929 + const char *rule_str)
1.930 + {
1.931 + int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
1.932 + unsigned long disabled_mask;
1.933 + STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
1.934 + const char *rule_p;
1.935 + CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
1.936 + SSL_CIPHER **ca_list = NULL;
1.937 +
1.938 + /*
1.939 + * Return with error if nothing to do.
1.940 + */
1.941 + if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)
1.942 + return NULL;
1.943 +
1.944 + /*
1.945 + * To reduce the work to do we only want to process the compiled
1.946 + * in algorithms, so we first get the mask of disabled ciphers.
1.947 + */
1.948 + disabled_mask = ssl_cipher_get_disabled();
1.949 +
1.950 + /*
1.951 + * Now we have to collect the available ciphers from the compiled
1.952 + * in ciphers. We cannot get more than the number compiled in, so
1.953 + * it is used for allocation.
1.954 + */
1.955 + num_of_ciphers = ssl_method->num_ciphers();
1.956 +#ifdef KSSL_DEBUG
1.957 + printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers);
1.958 +#endif /* KSSL_DEBUG */
1.959 + co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);
1.960 + if (co_list == NULL)
1.961 + {
1.962 + SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
1.963 + return(NULL); /* Failure */
1.964 + }
1.965 +
1.966 + ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask,
1.967 + co_list, &head, &tail);
1.968 +
1.969 + /*
1.970 + * We also need cipher aliases for selecting based on the rule_str.
1.971 + * There might be two types of entries in the rule_str: 1) names
1.972 + * of ciphers themselves 2) aliases for groups of ciphers.
1.973 + * For 1) we need the available ciphers and for 2) the cipher
1.974 + * groups of cipher_aliases added together in one list (otherwise
1.975 + * we would be happy with just the cipher_aliases table).
1.976 + */
1.977 + num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER);
1.978 + num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
1.979 + ca_list =
1.980 + (SSL_CIPHER **)OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);
1.981 + if (ca_list == NULL)
1.982 + {
1.983 + OPENSSL_free(co_list);
1.984 + SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
1.985 + return(NULL); /* Failure */
1.986 + }
1.987 + ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mask,
1.988 + head);
1.989 +
1.990 + /*
1.991 + * If the rule_string begins with DEFAULT, apply the default rule
1.992 + * before using the (possibly available) additional rules.
1.993 + */
1.994 + ok = 1;
1.995 + rule_p = rule_str;
1.996 + if (strncmp(rule_str,"DEFAULT",7) == 0)
1.997 + {
1.998 + ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
1.999 + co_list, &head, &tail, ca_list);
1.1000 + rule_p += 7;
1.1001 + if (*rule_p == ':')
1.1002 + rule_p++;
1.1003 + }
1.1004 +
1.1005 + if (ok && (strlen(rule_p) > 0))
1.1006 + ok = ssl_cipher_process_rulestr(rule_p, co_list, &head, &tail,
1.1007 + ca_list);
1.1008 +
1.1009 + OPENSSL_free(ca_list); /* Not needed anymore */
1.1010 +
1.1011 + if (!ok)
1.1012 + { /* Rule processing failure */
1.1013 + OPENSSL_free(co_list);
1.1014 + return(NULL);
1.1015 + }
1.1016 + /*
1.1017 + * Allocate new "cipherstack" for the result, return with error
1.1018 + * if we cannot get one.
1.1019 + */
1.1020 + if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL)
1.1021 + {
1.1022 + OPENSSL_free(co_list);
1.1023 + return(NULL);
1.1024 + }
1.1025 +
1.1026 + /*
1.1027 + * The cipher selection for the list is done. The ciphers are added
1.1028 + * to the resulting precedence to the STACK_OF(SSL_CIPHER).
1.1029 + */
1.1030 + for (curr = head; curr != NULL; curr = curr->next)
1.1031 + {
1.1032 + if (curr->active)
1.1033 + {
1.1034 + sk_SSL_CIPHER_push(cipherstack, curr->cipher);
1.1035 +#ifdef CIPHER_DEBUG
1.1036 + printf("<%s>\n",curr->cipher->name);
1.1037 +#endif
1.1038 + }
1.1039 + }
1.1040 + OPENSSL_free(co_list); /* Not needed any longer */
1.1041 +
1.1042 + tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
1.1043 + if (tmp_cipher_list == NULL)
1.1044 + {
1.1045 + sk_SSL_CIPHER_free(cipherstack);
1.1046 + return NULL;
1.1047 + }
1.1048 + if (*cipher_list != NULL)
1.1049 + sk_SSL_CIPHER_free(*cipher_list);
1.1050 + *cipher_list = cipherstack;
1.1051 + if (*cipher_list_by_id != NULL)
1.1052 + sk_SSL_CIPHER_free(*cipher_list_by_id);
1.1053 + *cipher_list_by_id = tmp_cipher_list;
1.1054 + (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp);
1.1055 +
1.1056 + return(cipherstack);
1.1057 + }
1.1058 +
1.1059 +EXPORT_C char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len)
1.1060 + {
1.1061 + int is_export,pkl,kl;
1.1062 + const char *ver,*exp_str;
1.1063 + const char *kx,*au,*enc,*mac;
1.1064 + unsigned long alg,alg2,alg_s;
1.1065 +#ifndef EMULATOR
1.1066 +#ifdef KSSL_DEBUG
1.1067 + static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx\n";
1.1068 +#else
1.1069 + static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n";
1.1070 +#endif /* KSSL_DEBUG */
1.1071 +#else /* EMULATOR */
1.1072 +#ifdef KSSL_DEBUG
1.1073 + static const char *const format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx\n";
1.1074 +#else
1.1075 + static const char *const format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n";
1.1076 +#endif /* KSSL_DEBUG */
1.1077 +
1.1078 +#endif /* EMULATOR */
1.1079 + alg=cipher->algorithms;
1.1080 + alg_s=cipher->algo_strength;
1.1081 + alg2=cipher->algorithm2;
1.1082 +
1.1083 + is_export=SSL_C_IS_EXPORT(cipher);
1.1084 + pkl=SSL_C_EXPORT_PKEYLENGTH(cipher);
1.1085 + kl=SSL_C_EXPORT_KEYLENGTH(cipher);
1.1086 + exp_str=is_export?" export":"";
1.1087 +
1.1088 + if (alg & SSL_SSLV2)
1.1089 + ver="SSLv2";
1.1090 + else if (alg & SSL_SSLV3)
1.1091 + ver="SSLv3";
1.1092 + else
1.1093 + ver="unknown";
1.1094 +
1.1095 + switch (alg&SSL_MKEY_MASK)
1.1096 + {
1.1097 + case SSL_kRSA:
1.1098 + kx=is_export?(pkl == 512 ? "RSA(512)" : "RSA(1024)"):"RSA";
1.1099 + break;
1.1100 + case SSL_kDHr:
1.1101 + kx="DH/RSA";
1.1102 + break;
1.1103 + case SSL_kDHd:
1.1104 + kx="DH/DSS";
1.1105 + break;
1.1106 + case SSL_kKRB5: /* VRS */
1.1107 + case SSL_KRB5: /* VRS */
1.1108 + kx="KRB5";
1.1109 + break;
1.1110 + case SSL_kFZA:
1.1111 + kx="Fortezza";
1.1112 + break;
1.1113 + case SSL_kEDH:
1.1114 + kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH";
1.1115 + break;
1.1116 + case SSL_kECDH:
1.1117 + case SSL_kECDHE:
1.1118 + kx=is_export?"ECDH(<=163)":"ECDH";
1.1119 + break;
1.1120 + default:
1.1121 + kx="unknown";
1.1122 + }
1.1123 +
1.1124 + switch (alg&SSL_AUTH_MASK)
1.1125 + {
1.1126 + case SSL_aRSA:
1.1127 + au="RSA";
1.1128 + break;
1.1129 + case SSL_aDSS:
1.1130 + au="DSS";
1.1131 + break;
1.1132 + case SSL_aDH:
1.1133 + au="DH";
1.1134 + break;
1.1135 + case SSL_aKRB5: /* VRS */
1.1136 + case SSL_KRB5: /* VRS */
1.1137 + au="KRB5";
1.1138 + break;
1.1139 + case SSL_aFZA:
1.1140 + case SSL_aNULL:
1.1141 + au="None";
1.1142 + break;
1.1143 + case SSL_aECDSA:
1.1144 + au="ECDSA";
1.1145 + break;
1.1146 + default:
1.1147 + au="unknown";
1.1148 + break;
1.1149 + }
1.1150 +
1.1151 + switch (alg&SSL_ENC_MASK)
1.1152 + {
1.1153 + case SSL_DES:
1.1154 + enc=(is_export && kl == 5)?"DES(40)":"DES(56)";
1.1155 + break;
1.1156 + case SSL_3DES:
1.1157 + enc="3DES(168)";
1.1158 + break;
1.1159 + case SSL_RC4:
1.1160 + enc=is_export?(kl == 5 ? "RC4(40)" : "RC4(56)")
1.1161 + :((alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)");
1.1162 + break;
1.1163 + case SSL_RC2:
1.1164 + enc=is_export?(kl == 5 ? "RC2(40)" : "RC2(56)"):"RC2(128)";
1.1165 + break;
1.1166 + case SSL_IDEA:
1.1167 + enc="IDEA(128)";
1.1168 + break;
1.1169 + case SSL_eFZA:
1.1170 + enc="Fortezza";
1.1171 + break;
1.1172 + case SSL_eNULL:
1.1173 + enc="None";
1.1174 + break;
1.1175 + case SSL_AES:
1.1176 + switch(cipher->strength_bits)
1.1177 + {
1.1178 + case 128: enc="AES(128)"; break;
1.1179 + case 192: enc="AES(192)"; break;
1.1180 + case 256: enc="AES(256)"; break;
1.1181 + default: enc="AES(?""?""?)"; break;
1.1182 + }
1.1183 + break;
1.1184 + default:
1.1185 + enc="unknown";
1.1186 + break;
1.1187 + }
1.1188 +
1.1189 + switch (alg&SSL_MAC_MASK)
1.1190 + {
1.1191 + case SSL_MD5:
1.1192 + mac="MD5";
1.1193 + break;
1.1194 + case SSL_SHA1:
1.1195 + mac="SHA1";
1.1196 + break;
1.1197 + default:
1.1198 + mac="unknown";
1.1199 + break;
1.1200 + }
1.1201 +
1.1202 + if (buf == NULL)
1.1203 + {
1.1204 + len=128;
1.1205 + buf=OPENSSL_malloc(len);
1.1206 + if (buf == NULL) return("OPENSSL_malloc Error");
1.1207 + }
1.1208 + else if (len < 128)
1.1209 + return("Buffer too small");
1.1210 +
1.1211 +#ifdef KSSL_DEBUG
1.1212 + BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str,alg);
1.1213 +#else
1.1214 + BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str);
1.1215 +#endif /* KSSL_DEBUG */
1.1216 + return(buf);
1.1217 + }
1.1218 +
1.1219 +EXPORT_C char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
1.1220 + {
1.1221 + int i;
1.1222 +
1.1223 + if (c == NULL) return("(NONE)");
1.1224 + i=(int)(c->id>>24L);
1.1225 + if (i == 3)
1.1226 + return("TLSv1/SSLv3");
1.1227 + else if (i == 2)
1.1228 + return("SSLv2");
1.1229 + else
1.1230 + return("unknown");
1.1231 + }
1.1232 +
1.1233 +/* return the actual cipher being used */
1.1234 +EXPORT_C const char *SSL_CIPHER_get_name(const SSL_CIPHER *c)
1.1235 + {
1.1236 + if (c != NULL)
1.1237 + return(c->name);
1.1238 + return("(NONE)");
1.1239 + }
1.1240 +
1.1241 +/* number of bits for symmetric cipher */
1.1242 +EXPORT_C int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
1.1243 + {
1.1244 + int ret=0;
1.1245 +
1.1246 + if (c != NULL)
1.1247 + {
1.1248 + if (alg_bits != NULL) *alg_bits = c->alg_bits;
1.1249 + ret = c->strength_bits;
1.1250 + }
1.1251 + return(ret);
1.1252 + }
1.1253 +
1.1254 +SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)
1.1255 + {
1.1256 + SSL_COMP *ctmp;
1.1257 + int i,nn;
1.1258 +
1.1259 + if ((n == 0) || (sk == NULL)) return(NULL);
1.1260 + nn=sk_SSL_COMP_num(sk);
1.1261 + for (i=0; i<nn; i++)
1.1262 + {
1.1263 + ctmp=sk_SSL_COMP_value(sk,i);
1.1264 + if (ctmp->id == n)
1.1265 + return(ctmp);
1.1266 + }
1.1267 + return(NULL);
1.1268 + }
1.1269 +
1.1270 +#ifdef OPENSSL_NO_COMP
1.1271 +EXPORT_C void *SSL_COMP_get_compression_methods(void)
1.1272 + {
1.1273 + return NULL;
1.1274 + }
1.1275 +EXPORT_C int SSL_COMP_add_compression_method(int id, void *cm)
1.1276 + {
1.1277 + return 1;
1.1278 + }
1.1279 +
1.1280 +EXPORT_C const char *SSL_COMP_get_name(const void *comp)
1.1281 + {
1.1282 + return NULL;
1.1283 + }
1.1284 +#else
1.1285 +EXPORT_C STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
1.1286 + {
1.1287 + load_builtin_compressions();
1.1288 + return(ssl_comp_methods);
1.1289 + }
1.1290 +
1.1291 +EXPORT_C int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)
1.1292 + {
1.1293 + SSL_COMP *comp;
1.1294 +
1.1295 + if (cm == NULL || cm->type == NID_undef)
1.1296 + return 1;
1.1297 +
1.1298 + /* According to draft-ietf-tls-compression-04.txt, the
1.1299 + compression number ranges should be the following:
1.1300 +
1.1301 + 0 to 63: methods defined by the IETF
1.1302 + 64 to 192: external party methods assigned by IANA
1.1303 + 193 to 255: reserved for private use */
1.1304 + if (id < 193 || id > 255)
1.1305 + {
1.1306 + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE);
1.1307 + return 0;
1.1308 + }
1.1309 +
1.1310 + MemCheck_off();
1.1311 + comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
1.1312 + comp->id=id;
1.1313 + comp->method=cm;
1.1314 + load_builtin_compressions();
1.1315 + if (ssl_comp_methods
1.1316 + && !sk_SSL_COMP_find(ssl_comp_methods,comp))
1.1317 + {
1.1318 + OPENSSL_free(comp);
1.1319 + MemCheck_on();
1.1320 + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_DUPLICATE_COMPRESSION_ID);
1.1321 + return(1);
1.1322 + }
1.1323 + else if ((ssl_comp_methods == NULL)
1.1324 + || !sk_SSL_COMP_push(ssl_comp_methods,comp))
1.1325 + {
1.1326 + OPENSSL_free(comp);
1.1327 + MemCheck_on();
1.1328 + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,ERR_R_MALLOC_FAILURE);
1.1329 + return(1);
1.1330 + }
1.1331 + else
1.1332 + {
1.1333 + MemCheck_on();
1.1334 + return(0);
1.1335 + }
1.1336 + }
1.1337 +
1.1338 +EXPORT_C const char *SSL_COMP_get_name(const COMP_METHOD *comp)
1.1339 + {
1.1340 + if (comp)
1.1341 + return comp->name;
1.1342 + return NULL;
1.1343 + }
1.1344 +
1.1345 +#endif