ssl3con.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,928 行 · 第 1/5 页

C
1,928
字号
/* * SSL3 Protocol * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. * * $Id: ssl3con.c,v 1.9.2.1 2000/11/21 03:24:52 nelsonb%netscape.com Exp $ */#include "cert.h"#include "ssl.h"#include "cryptohi.h"	/* for DSAU_ stuff */#include "keyhi.h"#include "secder.h"#include "secitem.h"#include "sslimpl.h"#include "sslproto.h"#include "sslerr.h"#include "prtime.h"#include "prinrval.h"#include "prerror.h"#include "pratom.h"#include "prthread.h"#include "pk11func.h"#include "secmod.h"#include "nsslocks.h"#include <stdio.h>#ifndef PK11_SETATTRS#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \		(x)->pValue=(v); (x)->ulValueLen = (l);#endifstatic PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,                                       PK11SlotInfo * serverKeySlot);static SECStatus ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms);static SECStatus ssl3_HandshakeFailure(      sslSocket *ss);static SECStatus ssl3_InitState(             sslSocket *ss);static sslSessionID *ssl3_NewSessionID(      sslSocket *ss, PRBool is_server);static SECStatus ssl3_SendCertificate(       sslSocket *ss);static SECStatus ssl3_SendEmptyCertificate(  sslSocket *ss);static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);static SECStatus ssl3_SendFinished(          sslSocket *ss, PRInt32 flags);static SECStatus ssl3_SendServerHello(       sslSocket *ss);static SECStatus ssl3_SendServerHelloDone(   sslSocket *ss);static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss);static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,			     int maxOutputLen, const unsigned char *input,			     int inputLen);#define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */#define MIN_SEND_BUF_LENGTH  4000#define MAX_CIPHER_SUITES 20/* This list of SSL3 cipher suites is sorted in descending order of * precedence (desirability).  It only includes cipher suites we implement. * This table is modified by SSL3_SetPolicy(). */static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {   /*      cipher_suite                         policy      enabled is_present*/ { SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_FORTEZZA_DMS_WITH_RC4_128_SHA,      SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_RSA_WITH_RC4_128_MD5,               SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,     SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_RSA_WITH_3DES_EDE_CBC_SHA,          SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_RSA_FIPS_WITH_DES_CBC_SHA,          SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_RSA_WITH_DES_CBC_SHA,               SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,     SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,    SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_RSA_EXPORT_WITH_RC4_40_MD5,         SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,     SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_FORTEZZA_DMS_WITH_NULL_SHA,         SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_RSA_WITH_NULL_MD5,                  SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}};static const /*SSL3CompressionMethod*/ uint8 compressions [] = {    compression_null};static const int compressionMethodsCount =		sizeof(compressions) / sizeof(compressions[0]);static const /*SSL3ClientCertificateType */ uint8 certificate_types [] = {    ct_RSA_sign,    ct_DSS_sign,};static const /*SSL3ClientCertificateType */ uint8 fortezza_certificate_types [] = {    ct_Fortezza,};/* * make sure there is room in the write buffer for padding and * other compression and cryptographic expansions */#define SSL3_BUFFER_FUDGE     100#undef BPB#define BPB 8 /* Bits Per Byte */#define SET_ERROR_CODE		/* reminder */#define SEND_ALERT		/* reminder */#define TEST_FOR_FAILURE	/* reminder */#define DEAL_WITH_FAILURE	/* reminder *//* This is a hack to make sure we don't do double handshakes for US policy */PRBool ssl3_global_policy_some_restricted = PR_FALSE;/* This global item is used only in servers.  It is is initialized by** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest().*/CERTDistNames *ssl3_server_ca_list = NULL;/* statistics from ssl3_SendClientHello (sch) */long ssl3_sch_sid_cache_hits;long ssl3_sch_sid_cache_misses;long ssl3_sch_sid_cache_not_ok;/* statistics from ssl3_HandleServerHello (hsh) */long ssl3_hsh_sid_cache_hits;long ssl3_hsh_sid_cache_misses;long ssl3_hsh_sid_cache_not_ok;/* statistics from ssl3_HandleClientHello (hch) */long ssl3_hch_sid_cache_hits;long ssl3_hch_sid_cache_misses;long ssl3_hch_sid_cache_not_ok;/* indexed by SSL3BulkCipher */static const ssl3BulkCipherDef bulk_cipher_defs[] = {    /* cipher          calg        keySz secretSz  type  ivSz BlkSz keygen */    {cipher_null,      calg_null,      0,  0, type_stream,  0, 0, kg_null},    {cipher_rc4,       calg_rc4,      16, 16, type_stream,  0, 0, kg_strong},    {cipher_rc4_40,    calg_rc4,      16,  5, type_stream,  0, 0, kg_export},    {cipher_rc4_56,    calg_rc4,      16,  7, type_stream,  0, 0, kg_export},    {cipher_rc2,       calg_rc2,      16, 16, type_block,   8, 8, kg_strong},    {cipher_rc2_40,    calg_rc2,      16,  5, type_block,   8, 8, kg_export},    {cipher_des,       calg_des,       8,  8, type_block,   8, 8, kg_strong},    {cipher_3des,      calg_3des,     24, 24, type_block,   8, 8, kg_strong},    {cipher_des40,     calg_des,       8,  5, type_block,   8, 8, kg_export},    {cipher_idea,      calg_idea,     16, 16, type_block,   8, 8, kg_strong},    {cipher_fortezza,  calg_fortezza, 10, 10, type_block,  24, 8, kg_null},    {cipher_missing,   calg_null,      0,  0, type_stream,  0, 0, kg_null},};static const ssl3KEADef kea_defs[] = { /* indexed by SSL3KeyExchangeAlgorithm */    /* kea              exchKeyType signKeyType is_limited limit  tls_keygen */    {kea_null,           kt_null,     sign_null, PR_FALSE,   0, PR_FALSE},    {kea_rsa,            kt_rsa,      sign_rsa,  PR_FALSE,   0, PR_FALSE},    {kea_rsa_export,     kt_rsa,      sign_rsa,  PR_TRUE,  512, PR_FALSE},    {kea_rsa_export_1024,kt_rsa,      sign_rsa,  PR_TRUE, 1024, PR_FALSE},    {kea_dh_dss,         kt_dh,       sign_dsa,  PR_FALSE,   0, PR_FALSE},    {kea_dh_dss_export,  kt_dh,       sign_dsa,  PR_TRUE,  512, PR_FALSE},    {kea_dh_rsa,         kt_dh,       sign_rsa,  PR_FALSE,   0, PR_FALSE},    {kea_dh_rsa_export,  kt_dh,       sign_rsa,  PR_TRUE,  512, PR_FALSE},    {kea_dhe_dss,        kt_dh,       sign_dsa,  PR_FALSE,   0, PR_FALSE},    {kea_dhe_dss_export, kt_dh,       sign_dsa,  PR_TRUE,  512, PR_FALSE},    {kea_dhe_rsa,        kt_dh,       sign_rsa,  PR_FALSE,   0, PR_FALSE},    {kea_dhe_rsa_export, kt_dh,       sign_rsa,  PR_TRUE,  512, PR_FALSE},    {kea_dh_anon,        kt_dh,       sign_null, PR_FALSE,   0, PR_FALSE},    {kea_dh_anon_export, kt_dh,       sign_null, PR_TRUE,  512, PR_FALSE},    {kea_fortezza,       kt_fortezza, sign_dsa,  PR_FALSE,   0, PR_FALSE},    {kea_rsa_fips,       kt_rsa,      sign_rsa,  PR_FALSE,   0, PR_TRUE },};static const CK_MECHANISM_TYPE kea_alg_defs[] = {    0x80000000L,    CKM_RSA_PKCS,    CKM_DH_PKCS_DERIVE,    CKM_KEA_KEY_DERIVE};static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */    /* mac      malg        pad_size  mac_size                       */    { mac_null, malg_null,      0,     0          },    { mac_md5,  malg_md5,      48,     MD5_LENGTH },    { mac_sha,  malg_sha,      40,     SHA1_LENGTH},    {hmac_md5,  malg_md5_hmac, 48,     MD5_LENGTH },    {hmac_sha,  malg_sha_hmac, 40,     SHA1_LENGTH},};/* must use ssl_LookupCipherSuiteDef to access */static const ssl3CipherSuiteDef cipher_suite_defs[] = {/*  cipher_suite                    bulk_cipher_alg mac_alg key_exchange_alg */    {SSL_NULL_WITH_NULL_NULL,       cipher_null,   mac_null, kea_null},    {SSL_RSA_WITH_NULL_MD5,         cipher_null,   mac_md5, kea_rsa},    {SSL_RSA_WITH_NULL_SHA,         cipher_null,   mac_sha, kea_rsa},    {SSL_RSA_EXPORT_WITH_RC4_40_MD5,cipher_rc4_40, mac_md5, kea_rsa_export},    {SSL_RSA_WITH_RC4_128_MD5,      cipher_rc4,    mac_md5, kea_rsa},    {SSL_RSA_WITH_RC4_128_SHA,      cipher_rc4,    mac_sha, kea_rsa},    {SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,                                    cipher_rc2_40, mac_md5, kea_rsa_export},#if 0 /* not implemented */    {SSL_RSA_WITH_IDEA_CBC_SHA,     cipher_idea,   mac_sha, kea_rsa},    {SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,                                    cipher_des40,  mac_sha, kea_rsa_export},#endif    {SSL_RSA_WITH_DES_CBC_SHA,      cipher_des,    mac_sha, kea_rsa},    {SSL_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des,   mac_sha, kea_rsa},#if 0 /* not implemented */    {SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,                                    cipher_des40,  mac_sha, kea_dh_dss_export},    {SSL_DH_DSS_DES_CBC_SHA,        cipher_des,    mac_sha, kea_dh_dss},    {SSL_DH_DSS_3DES_CBC_SHA,       cipher_3des,   mac_sha, kea_dh_dss},    {SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,                                    cipher_des40,  mac_sha, kea_dh_rsa_export},    {SSL_DH_RSA_DES_CBC_SHA,        cipher_des,    mac_sha, kea_dh_rsa},    {SSL_DH_RSA_3DES_CBC_SHA,       cipher_des,    mac_sha, kea_dh_rsa},    {SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,                                    cipher_des40,  mac_sha, kea_dh_dss_export},    {SSL_DHE_DSS_DES_CBC_SHA,       cipher_des,    mac_sha, kea_dh_dss},    {SSL_DHE_DSS_3DES_CBC_SHA,      cipher_3des,   mac_sha, kea_dh_dss},    {SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,                                    cipher_des40,  mac_sha, kea_dh_rsa_export},    {SSL_DHE_RSA_DES_CBC_SHA,       cipher_des,    mac_sha, kea_dh_rsa},    {SSL_DHE_RSA_3DES_CBC_SHA,      cipher_des,    mac_sha, kea_dh_rsa},    {SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4_40, mac_md5, kea_dh_anon_export},    {SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4,    mac_md5, kea_dh_anon_export},    {SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA,                                    cipher_des40,  mac_sha, kea_dh_anon_export},    {SSL_DH_ANON_DES_CBC_SHA,       cipher_des,    mac_sha, kea_dh_anon},    {SSL_DH_ANON_3DES_CBC_SHA,      cipher_3des,   mac_sha, kea_dh_anon},#endif    {SSL_FORTEZZA_DMS_WITH_NULL_SHA, cipher_null,  mac_sha, kea_fortezza},    {SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA,                                  cipher_fortezza, mac_sha, kea_fortezza},    {SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_fortezza},    {TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,                                    cipher_des,    mac_sha,kea_rsa_export_1024},    {TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,                                    cipher_rc4_56, mac_sha,kea_rsa_export_1024},    {SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa_fips},    {SSL_RSA_FIPS_WITH_DES_CBC_SHA, cipher_des,    mac_sha, kea_rsa_fips},};/* indexed by SSL3BulkCipher */const char * const ssl3_cipherName[] = {    "NULL",    "RC4",    "RC4-40",    "RC4-56",    "RC2-CBC",    "RC2-CBC-40",    "DES-CBC",    "3DES-EDE-CBC",    "DES-CBC-40",    "IDEA-CBC",    "FORTEZZA",    "missing"};#if defined(TRACE)static char *ssl3_DecodeHandshakeType(int msgType){    char * rv;    static char line[40];    switch(msgType) {    case hello_request:	        rv = "hello_request (0)";               break;    case client_hello:	        rv = "client_hello  (1)";               break;    case server_hello:	        rv = "server_hello  (2)";               break;    case certificate:	        rv = "certificate  (11)";               break;    case server_key_exchange:	rv = "server_key_exchange (12)";        break;    case certificate_request:	rv = "certificate_request (13)";        break;    case server_hello_done:	rv = "server_hello_done   (14)";        break;    case certificate_verify:	rv = "certificate_verify  (15)";        break;    case client_key_exchange:	rv = "client_key_exchange (16)";        break;    case finished:	        rv = "finished     (20)";               break;    default:        sprintf(line, "*UNKNOWN* handshake type! (%d)", msgType);	rv = line;    }    return rv;}static char *ssl3_DecodeContentType(int msgType){    char * rv;    static char line[40];    switch(msgType) {    case content_change_cipher_spec:                                rv = "change_cipher_spec (20)";         break;    case content_alert:	        rv = "alert      (21)";                 break;    case content_handshake:	rv = "handshake  (22)";                 break;    case content_application_data:                                rv = "application_data (23)";           break;    default:        sprintf(line, "*UNKNOWN* record type! (%d)", msgType);	rv = line;    }    return rv;}#endif/* return pointer to ssl3CipherSuiteDef for suite, or NULL *//* XXX This does a linear search.  A binary search would be better. */static const ssl3CipherSuiteDef *ssl_LookupCipherSuiteDef(ssl3CipherSuite suite){    int cipher_suite_def_len =	sizeof(cipher_suite_defs) / sizeof(cipher_suite_defs[0]);    int i;    for (i = 0; i < cipher_suite_def_len; i++) {	if (cipher_suite_defs[i].cipher_suite == suite)	    return &cipher_suite_defs[i];    }    PORT_Assert(PR_FALSE);  /* We should never get here. */    PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);    return NULL;}/* Find the cipher configuration struct associate with suite *//* XXX This does a linear search.  A binary search would be better. */static ssl3CipherSuiteCfg *ssl_LookupCipherSuiteCfg(ssl3CipherSuite suite, ssl3CipherSuiteCfg *suites){    int i;    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {	if (suites[i].cipher_suite == suite)	    return &suites[i];    }    /* return NULL and let the caller handle it.  */    PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);    return NULL;}/* Initialize the suite->isPresent value for config_match * Returns count of enabled ciphers supported by extant tokens, * regardless of policy or user preference. * If this returns zero, the user cannot do SSL v3. */intssl3_config_match_init(sslSocket *ss){    ssl3CipherSuiteCfg *      suite;    const ssl3CipherSuiteDef *cipher_def;    CipherAlgorithm           cipher_alg;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?