Back to index

lightning-sunbird  0.9+nobinonly
ssl3con.c
Go to the documentation of this file.
00001 /*
00002  * SSL3 Protocol
00003  *
00004  * ***** BEGIN LICENSE BLOCK *****
00005  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006  *
00007  * The contents of this file are subject to the Mozilla Public License Version
00008  * 1.1 (the "License"); you may not use this file except in compliance with
00009  * the License. You may obtain a copy of the License at
00010  * http://www.mozilla.org/MPL/
00011  *
00012  * Software distributed under the License is distributed on an "AS IS" basis,
00013  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00014  * for the specific language governing rights and limitations under the
00015  * License.
00016  *
00017  * The Original Code is the Netscape security libraries.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   Dr Stephen Henson <stephen.henson@gemplus.com>
00026  *   Dr Vipul Gupta <vipul.gupta@sun.com> and
00027  *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
00028  *
00029  * Alternatively, the contents of this file may be used under the terms of
00030  * either the GNU General Public License Version 2 or later (the "GPL"), or
00031  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00032  * in which case the provisions of the GPL or the LGPL are applicable instead
00033  * of those above. If you wish to allow use of your version of this file only
00034  * under the terms of either the GPL or the LGPL, and not to allow others to
00035  * use your version of this file under the terms of the MPL, indicate your
00036  * decision by deleting the provisions above and replace them with the notice
00037  * and other provisions required by the GPL or the LGPL. If you do not delete
00038  * the provisions above, a recipient may use your version of this file under
00039  * the terms of any one of the MPL, the GPL or the LGPL.
00040  *
00041  * ***** END LICENSE BLOCK ***** */
00042 /* $Id: ssl3con.c,v 1.76.2.21 2007/08/28 03:39:12 nelson%bolyard.com Exp $ */
00043 
00044 #include "nssrenam.h"
00045 #include "cert.h"
00046 #include "ssl.h"
00047 #include "cryptohi.h"       /* for DSAU_ stuff */
00048 #include "keyhi.h"
00049 #include "secder.h"
00050 #include "secitem.h"
00051 
00052 #include "sslimpl.h"
00053 #include "sslproto.h"
00054 #include "sslerr.h"
00055 #include "prtime.h"
00056 #include "prinrval.h"
00057 #include "prerror.h"
00058 #include "pratom.h"
00059 #include "prthread.h"
00060 
00061 #include "pk11func.h"
00062 #include "secmod.h"
00063 #include "nsslocks.h"
00064 #include "ec.h"
00065 #include "blapi.h"
00066 
00067 #include <stdio.h>
00068 
00069 #ifndef PK11_SETATTRS
00070 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
00071               (x)->pValue=(v); (x)->ulValueLen = (l);
00072 #endif
00073 
00074 static void      ssl3_CleanupPeerCerts(sslSocket *ss);
00075 static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
00076                                        PK11SlotInfo * serverKeySlot);
00077 static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms);
00078 static SECStatus ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss);
00079 static SECStatus ssl3_HandshakeFailure(      sslSocket *ss);
00080 static SECStatus ssl3_InitState(             sslSocket *ss);
00081 static sslSessionID *ssl3_NewSessionID(      sslSocket *ss, PRBool is_server);
00082 static SECStatus ssl3_SendCertificate(       sslSocket *ss);
00083 static SECStatus ssl3_SendEmptyCertificate(  sslSocket *ss);
00084 static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);
00085 static SECStatus ssl3_SendFinished(          sslSocket *ss, PRInt32 flags);
00086 static SECStatus ssl3_SendServerHello(       sslSocket *ss);
00087 static SECStatus ssl3_SendServerHelloDone(   sslSocket *ss);
00088 static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss);
00089 static SECStatus ssl3_NewHandshakeHashes(    sslSocket *ss);
00090 static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss, unsigned char *b, 
00091                                              unsigned int l);
00092 
00093 static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,
00094                           int maxOutputLen, const unsigned char *input,
00095                           int inputLen);
00096 
00097 #define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */
00098 #define MIN_SEND_BUF_LENGTH  4000
00099 
00100 #define MAX_CIPHER_SUITES 20
00101 
00102 /* This list of SSL3 cipher suites is sorted in descending order of
00103  * precedence (desirability).  It only includes cipher suites we implement.
00104  * This table is modified by SSL3_SetPolicy(). The ordering of cipher suites
00105  * in this table must match the ordering in SSL_ImplementedCiphers (sslenum.c)
00106  */
00107 static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
00108    /*      cipher_suite                         policy      enabled is_present*/
00109 #ifdef NSS_ENABLE_ECC
00110  { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,   SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00111  { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,     SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00112 #endif /* NSS_ENABLE_ECC */
00113  { TLS_DHE_RSA_WITH_AES_256_CBC_SHA,         SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00114  { TLS_DHE_DSS_WITH_AES_256_CBC_SHA,         SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00115 #ifdef NSS_ENABLE_ECC
00116  { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,      SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00117  { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,    SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00118 #endif /* NSS_ENABLE_ECC */
00119  { TLS_RSA_WITH_AES_256_CBC_SHA,             SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00120 
00121 #ifdef NSS_ENABLE_ECC
00122  { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,       SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00123  { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,   SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00124  { TLS_ECDHE_RSA_WITH_RC4_128_SHA,         SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00125  { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,     SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00126 #endif /* NSS_ENABLE_ECC */
00127  { TLS_DHE_DSS_WITH_RC4_128_SHA,           SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00128  { TLS_DHE_RSA_WITH_AES_128_CBC_SHA,       SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00129  { TLS_DHE_DSS_WITH_AES_128_CBC_SHA,         SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00130 #ifdef NSS_ENABLE_ECC
00131  { TLS_ECDH_RSA_WITH_RC4_128_SHA,          SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00132  { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,      SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00133  { TLS_ECDH_ECDSA_WITH_RC4_128_SHA,        SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00134  { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,    SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00135 #endif /* NSS_ENABLE_ECC */
00136  { SSL_RSA_WITH_RC4_128_MD5,               SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
00137  { SSL_RSA_WITH_RC4_128_SHA,               SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00138  { TLS_RSA_WITH_AES_128_CBC_SHA,             SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00139 
00140 #ifdef NSS_ENABLE_ECC
00141  { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,  SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00142  { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,    SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00143 #endif /* NSS_ENABLE_ECC */
00144  { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,      SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00145  { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,      SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00146 #ifdef NSS_ENABLE_ECC
00147  { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,     SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00148  { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,   SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00149 #endif /* NSS_ENABLE_ECC */
00150  { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,     SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
00151  { SSL_RSA_WITH_3DES_EDE_CBC_SHA,          SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
00152 
00153 
00154  { SSL_DHE_RSA_WITH_DES_CBC_SHA,           SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00155  { SSL_DHE_DSS_WITH_DES_CBC_SHA,           SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00156  { SSL_RSA_FIPS_WITH_DES_CBC_SHA,          SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
00157  { SSL_RSA_WITH_DES_CBC_SHA,               SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
00158  { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,     SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
00159  { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,    SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
00160 
00161  { SSL_RSA_EXPORT_WITH_RC4_40_MD5,         SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
00162  { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,     SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
00163 
00164 #ifdef NSS_ENABLE_ECC
00165  { TLS_ECDHE_ECDSA_WITH_NULL_SHA,          SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
00166  { TLS_ECDHE_RSA_WITH_NULL_SHA,            SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
00167  { TLS_ECDH_RSA_WITH_NULL_SHA,             SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
00168  { TLS_ECDH_ECDSA_WITH_NULL_SHA,           SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
00169 #endif /* NSS_ENABLE_ECC */
00170  { SSL_RSA_WITH_NULL_SHA,                  SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00171  { SSL_RSA_WITH_NULL_MD5,                  SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
00172 
00173 };
00174 
00175 static const /*SSL3CompressionMethod*/ uint8 compressions [] = {
00176     compression_null
00177 };
00178 
00179 static const int compressionMethodsCount =
00180               sizeof(compressions) / sizeof(compressions[0]);
00181 
00182 static const /*SSL3ClientCertificateType */ uint8 certificate_types [] = {
00183     ct_RSA_sign,
00184     ct_DSS_sign,
00185 #ifdef NSS_ENABLE_ECC
00186     ct_ECDSA_sign,
00187 #endif /* NSS_ENABLE_ECC */
00188 };
00189 
00190 
00191 /*
00192  * make sure there is room in the write buffer for padding and
00193  * other compression and cryptographic expansions
00194  */
00195 #define SSL3_BUFFER_FUDGE     100
00196 
00197 #define EXPORT_RSA_KEY_LENGTH 64   /* bytes */
00198 
00199 
00200 /* This is a hack to make sure we don't do double handshakes for US policy */
00201 PRBool ssl3_global_policy_some_restricted = PR_FALSE;
00202 
00203 /* This global item is used only in servers.  It is is initialized by
00204 ** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest().
00205 */
00206 CERTDistNames *ssl3_server_ca_list = NULL;
00207 static SSL3Statistics ssl3stats;
00208 
00209 /* indexed by SSL3BulkCipher */
00210 static const ssl3BulkCipherDef bulk_cipher_defs[] = {
00211     /* cipher          calg        keySz secretSz  type  ivSz BlkSz keygen */
00212     {cipher_null,      calg_null,      0,  0, type_stream,  0, 0, kg_null},
00213     {cipher_rc4,       calg_rc4,      16, 16, type_stream,  0, 0, kg_strong},
00214     {cipher_rc4_40,    calg_rc4,      16,  5, type_stream,  0, 0, kg_export},
00215     {cipher_rc4_56,    calg_rc4,      16,  7, type_stream,  0, 0, kg_export},
00216     {cipher_rc2,       calg_rc2,      16, 16, type_block,   8, 8, kg_strong},
00217     {cipher_rc2_40,    calg_rc2,      16,  5, type_block,   8, 8, kg_export},
00218     {cipher_des,       calg_des,       8,  8, type_block,   8, 8, kg_strong},
00219     {cipher_3des,      calg_3des,     24, 24, type_block,   8, 8, kg_strong},
00220     {cipher_des40,     calg_des,       8,  5, type_block,   8, 8, kg_export},
00221     {cipher_idea,      calg_idea,     16, 16, type_block,   8, 8, kg_strong},
00222     {cipher_aes_128,   calg_aes,      16, 16, type_block,  16,16, kg_strong},
00223     {cipher_aes_256,   calg_aes,      32, 32, type_block,  16,16, kg_strong},
00224     {cipher_missing,   calg_null,      0,  0, type_stream,  0, 0, kg_null},
00225 };
00226 
00227 static const ssl3KEADef kea_defs[] = 
00228 { /* indexed by SSL3KeyExchangeAlgorithm */
00229     /* kea              exchKeyType signKeyType is_limited limit  tls_keygen */
00230     {kea_null,           kt_null,     sign_null, PR_FALSE,   0, PR_FALSE},
00231     {kea_rsa,            kt_rsa,      sign_rsa,  PR_FALSE,   0, PR_FALSE},
00232     {kea_rsa_export,     kt_rsa,      sign_rsa,  PR_TRUE,  512, PR_FALSE},
00233     {kea_rsa_export_1024,kt_rsa,      sign_rsa,  PR_TRUE, 1024, PR_FALSE},
00234     {kea_dh_dss,         kt_dh,       sign_dsa,  PR_FALSE,   0, PR_FALSE},
00235     {kea_dh_dss_export,  kt_dh,       sign_dsa,  PR_TRUE,  512, PR_FALSE},
00236     {kea_dh_rsa,         kt_dh,       sign_rsa,  PR_FALSE,   0, PR_FALSE},
00237     {kea_dh_rsa_export,  kt_dh,       sign_rsa,  PR_TRUE,  512, PR_FALSE},
00238     {kea_dhe_dss,        kt_dh,       sign_dsa,  PR_FALSE,   0, PR_FALSE},
00239     {kea_dhe_dss_export, kt_dh,       sign_dsa,  PR_TRUE,  512, PR_FALSE},
00240     {kea_dhe_rsa,        kt_dh,       sign_rsa,  PR_FALSE,   0, PR_FALSE},
00241     {kea_dhe_rsa_export, kt_dh,       sign_rsa,  PR_TRUE,  512, PR_FALSE},
00242     {kea_dh_anon,        kt_dh,       sign_null, PR_FALSE,   0, PR_FALSE},
00243     {kea_dh_anon_export, kt_dh,       sign_null, PR_TRUE,  512, PR_FALSE},
00244     {kea_rsa_fips,       kt_rsa,      sign_rsa,  PR_FALSE,   0, PR_TRUE },
00245 #ifdef NSS_ENABLE_ECC
00246     {kea_ecdh_ecdsa,     kt_ecdh,     sign_ecdsa,  PR_FALSE, 0, PR_FALSE},
00247     {kea_ecdhe_ecdsa,    kt_ecdh,     sign_ecdsa,  PR_FALSE,   0, PR_FALSE},
00248     {kea_ecdh_rsa,       kt_ecdh,     sign_rsa,  PR_FALSE,   0, PR_FALSE},
00249     {kea_ecdhe_rsa,      kt_ecdh,     sign_rsa,  PR_FALSE,   0, PR_FALSE},
00250     {kea_ecdh_anon,      kt_ecdh,     sign_null,  PR_FALSE,   0, PR_FALSE},
00251 #endif /* NSS_ENABLE_ECC */
00252 };
00253 
00254 /* must use ssl_LookupCipherSuiteDef to access */
00255 static const ssl3CipherSuiteDef cipher_suite_defs[] = 
00256 {
00257 /*  cipher_suite                    bulk_cipher_alg mac_alg key_exchange_alg */
00258 
00259     {SSL_NULL_WITH_NULL_NULL,       cipher_null,   mac_null, kea_null},
00260     {SSL_RSA_WITH_NULL_MD5,         cipher_null,   mac_md5, kea_rsa},
00261     {SSL_RSA_WITH_NULL_SHA,         cipher_null,   mac_sha, kea_rsa},
00262     {SSL_RSA_EXPORT_WITH_RC4_40_MD5,cipher_rc4_40, mac_md5, kea_rsa_export},
00263     {SSL_RSA_WITH_RC4_128_MD5,      cipher_rc4,    mac_md5, kea_rsa},
00264     {SSL_RSA_WITH_RC4_128_SHA,      cipher_rc4,    mac_sha, kea_rsa},
00265     {SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
00266                                     cipher_rc2_40, mac_md5, kea_rsa_export},
00267 #if 0 /* not implemented */
00268     {SSL_RSA_WITH_IDEA_CBC_SHA,     cipher_idea,   mac_sha, kea_rsa},
00269     {SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
00270                                     cipher_des40,  mac_sha, kea_rsa_export},
00271 #endif
00272     {SSL_RSA_WITH_DES_CBC_SHA,      cipher_des,    mac_sha, kea_rsa},
00273     {SSL_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des,   mac_sha, kea_rsa},
00274     {SSL_DHE_DSS_WITH_DES_CBC_SHA,  cipher_des,    mac_sha, kea_dhe_dss},
00275     {SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
00276                                     cipher_3des,   mac_sha, kea_dhe_dss},
00277     {TLS_DHE_DSS_WITH_RC4_128_SHA,  cipher_rc4,    mac_sha, kea_dhe_dss},
00278 #if 0 /* not implemented */
00279     {SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
00280                                     cipher_des40,  mac_sha, kea_dh_dss_export},
00281     {SSL_DH_DSS_DES_CBC_SHA,        cipher_des,    mac_sha, kea_dh_dss},
00282     {SSL_DH_DSS_3DES_CBC_SHA,       cipher_3des,   mac_sha, kea_dh_dss},
00283     {SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
00284                                     cipher_des40,  mac_sha, kea_dh_rsa_export},
00285     {SSL_DH_RSA_DES_CBC_SHA,        cipher_des,    mac_sha, kea_dh_rsa},
00286     {SSL_DH_RSA_3DES_CBC_SHA,       cipher_3des,   mac_sha, kea_dh_rsa},
00287     {SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
00288                                     cipher_des40,  mac_sha, kea_dh_dss_export},
00289     {SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
00290                                     cipher_des40,  mac_sha, kea_dh_rsa_export},
00291 #endif
00292     {SSL_DHE_RSA_WITH_DES_CBC_SHA,  cipher_des,    mac_sha, kea_dhe_rsa},
00293     {SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
00294                                     cipher_3des,   mac_sha, kea_dhe_rsa},
00295 #if 0
00296     {SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4_40, mac_md5, kea_dh_anon_export},
00297     {SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4,    mac_md5, kea_dh_anon_export},
00298     {SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA,
00299                                     cipher_des40,  mac_sha, kea_dh_anon_export},
00300     {SSL_DH_ANON_DES_CBC_SHA,       cipher_des,    mac_sha, kea_dh_anon},
00301     {SSL_DH_ANON_3DES_CBC_SHA,      cipher_3des,   mac_sha, kea_dh_anon},
00302 #endif
00303 
00304 
00305 /* New TLS cipher suites */
00306     {TLS_RSA_WITH_AES_128_CBC_SHA,        cipher_aes_128, mac_sha, kea_rsa},
00307     {TLS_DHE_DSS_WITH_AES_128_CBC_SHA,    cipher_aes_128, mac_sha, kea_dhe_dss},
00308     {TLS_DHE_RSA_WITH_AES_128_CBC_SHA,    cipher_aes_128, mac_sha, kea_dhe_rsa},
00309     {TLS_RSA_WITH_AES_256_CBC_SHA,        cipher_aes_256, mac_sha, kea_rsa},
00310     {TLS_DHE_DSS_WITH_AES_256_CBC_SHA,    cipher_aes_256, mac_sha, kea_dhe_dss},
00311     {TLS_DHE_RSA_WITH_AES_256_CBC_SHA,    cipher_aes_256, mac_sha, kea_dhe_rsa},
00312 #if 0
00313     {TLS_DH_DSS_WITH_AES_128_CBC_SHA,     cipher_aes_128, mac_sha, kea_dh_dss},
00314     {TLS_DH_RSA_WITH_AES_128_CBC_SHA,     cipher_aes_128, mac_sha, kea_dh_rsa},
00315     {TLS_DH_ANON_WITH_AES_128_CBC_SHA,    cipher_aes_128, mac_sha, kea_dh_anon},
00316     {TLS_DH_DSS_WITH_AES_256_CBC_SHA,     cipher_aes_256, mac_sha, kea_dh_dss},
00317     {TLS_DH_RSA_WITH_AES_256_CBC_SHA,     cipher_aes_256, mac_sha, kea_dh_rsa},
00318     {TLS_DH_ANON_WITH_AES_256_CBC_SHA,    cipher_aes_256, mac_sha, kea_dh_anon},
00319 #endif
00320 
00321     {TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
00322                                     cipher_des,    mac_sha,kea_rsa_export_1024},
00323     {TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
00324                                     cipher_rc4_56, mac_sha,kea_rsa_export_1024},
00325 
00326     {SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa_fips},
00327     {SSL_RSA_FIPS_WITH_DES_CBC_SHA, cipher_des,    mac_sha, kea_rsa_fips},
00328 
00329 #ifdef NSS_ENABLE_ECC
00330     {TLS_ECDH_ECDSA_WITH_NULL_SHA,        cipher_null, mac_sha, kea_ecdh_ecdsa},
00331     {TLS_ECDH_ECDSA_WITH_RC4_128_SHA,      cipher_rc4, mac_sha, kea_ecdh_ecdsa},
00332     {TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_ecdsa},
00333     {TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_ecdsa},
00334     {TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_ecdsa},
00335 
00336     {TLS_ECDHE_ECDSA_WITH_NULL_SHA,        cipher_null, mac_sha, kea_ecdhe_ecdsa},
00337     {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,      cipher_rc4, mac_sha, kea_ecdhe_ecdsa},
00338     {TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_ecdsa},
00339     {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_ecdsa},
00340     {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_ecdsa},
00341 
00342     {TLS_ECDH_RSA_WITH_NULL_SHA,         cipher_null,    mac_sha, kea_ecdh_rsa},
00343     {TLS_ECDH_RSA_WITH_RC4_128_SHA,      cipher_rc4,     mac_sha, kea_ecdh_rsa},
00344     {TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des,    mac_sha, kea_ecdh_rsa},
00345     {TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,  cipher_aes_128, mac_sha, kea_ecdh_rsa},
00346     {TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,  cipher_aes_256, mac_sha, kea_ecdh_rsa},
00347 
00348     {TLS_ECDHE_RSA_WITH_NULL_SHA,         cipher_null,    mac_sha, kea_ecdhe_rsa},
00349     {TLS_ECDHE_RSA_WITH_RC4_128_SHA,      cipher_rc4,     mac_sha, kea_ecdhe_rsa},
00350     {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des,    mac_sha, kea_ecdhe_rsa},
00351     {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,  cipher_aes_128, mac_sha, kea_ecdhe_rsa},
00352     {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,  cipher_aes_256, mac_sha, kea_ecdhe_rsa},
00353 
00354 #if 0
00355     {TLS_ECDH_anon_WITH_NULL_SHA,         cipher_null,    mac_sha, kea_ecdh_anon},
00356     {TLS_ECDH_anon_WITH_RC4_128_SHA,      cipher_rc4,     mac_sha, kea_ecdh_anon},
00357     {TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, cipher_3des,    mac_sha, kea_ecdh_anon},
00358     {TLS_ECDH_anon_WITH_AES_128_CBC_SHA,  cipher_aes_128, mac_sha, kea_ecdh_anon},
00359     {TLS_ECDH_anon_WITH_AES_256_CBC_SHA,  cipher_aes_256, mac_sha, kea_ecdh_anon},
00360 #endif
00361 #endif /* NSS_ENABLE_ECC */
00362 };
00363 
00364 static const CK_MECHANISM_TYPE kea_alg_defs[] = {
00365     0x80000000L,
00366     CKM_RSA_PKCS,
00367     CKM_DH_PKCS_DERIVE,
00368     CKM_KEA_KEY_DERIVE,
00369     CKM_ECDH1_DERIVE
00370 };
00371 
00372 typedef struct SSLCipher2MechStr {
00373     SSLCipherAlgorithm  calg;
00374     CK_MECHANISM_TYPE   cmech;
00375 } SSLCipher2Mech;
00376 
00377 /* indexed by type SSLCipherAlgorithm */
00378 static const SSLCipher2Mech alg2Mech[] = {
00379     /* calg,          cmech  */
00380     { calg_null     , (CK_MECHANISM_TYPE)0x80000000L    },
00381     { calg_rc4      , CKM_RC4                           },
00382     { calg_rc2      , CKM_RC2_CBC                },
00383     { calg_des      , CKM_DES_CBC                },
00384     { calg_3des     , CKM_DES3_CBC               },
00385     { calg_idea     , CKM_IDEA_CBC               },
00386     { calg_fortezza , CKM_SKIPJACK_CBC64                },
00387     { calg_aes      , CKM_AES_CBC                },
00388 /*  { calg_init     , (CK_MECHANISM_TYPE)0x7fffffffL    }  */
00389 };
00390 
00391 #define mmech_null     (CK_MECHANISM_TYPE)0x80000000L
00392 #define mmech_md5      CKM_SSL3_MD5_MAC
00393 #define mmech_sha      CKM_SSL3_SHA1_MAC
00394 #define mmech_md5_hmac CKM_MD5_HMAC
00395 #define mmech_sha_hmac CKM_SHA_1_HMAC
00396 
00397 static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */
00398     /* mac      mmech       pad_size  mac_size                       */
00399     { mac_null, mmech_null,       0,  0          },
00400     { mac_md5,  mmech_md5,       48,  MD5_LENGTH },
00401     { mac_sha,  mmech_sha,       40,  SHA1_LENGTH},
00402     {hmac_md5,  mmech_md5_hmac,  48,  MD5_LENGTH },
00403     {hmac_sha,  mmech_sha_hmac,  40,  SHA1_LENGTH},
00404 };
00405 
00406 /* indexed by SSL3BulkCipher */
00407 const char * const ssl3_cipherName[] = {
00408     "NULL",
00409     "RC4",
00410     "RC4-40",
00411     "RC4-56",
00412     "RC2-CBC",
00413     "RC2-CBC-40",
00414     "DES-CBC",
00415     "3DES-EDE-CBC",
00416     "DES-CBC-40",
00417     "IDEA-CBC",
00418     "AES-128",
00419     "AES-256",
00420     "missing"
00421 };
00422 
00423 #ifdef NSS_ENABLE_ECC
00424 /* The ECCWrappedKeyInfo structure defines how various pieces of 
00425  * information are laid out within wrappedSymmetricWrappingkey 
00426  * for ECDH key exchange. Since wrappedSymmetricWrappingkey is 
00427  * a 512-byte buffer (see sslimpl.h), the variable length field 
00428  * in ECCWrappedKeyInfo can be at most (512 - 8) = 504 bytes.
00429  *
00430  * XXX For now, NSS only supports named elliptic curves of size 571 bits 
00431  * or smaller. The public value will fit within 145 bytes and EC params
00432  * will fit within 12 bytes. We'll need to revisit this when NSS
00433  * supports arbitrary curves.
00434  */
00435 #define MAX_EC_WRAPPED_KEY_BUFLEN  504
00436 
00437 typedef struct ECCWrappedKeyInfoStr {
00438     PRUint16 size;            /* EC public key size in bits */
00439     PRUint16 encodedParamLen; /* length (in bytes) of DER encoded EC params */
00440     PRUint16 pubValueLen;     /* length (in bytes) of EC public value */
00441     PRUint16 wrappedKeyLen;   /* length (in bytes) of the wrapped key */
00442     PRUint8 var[MAX_EC_WRAPPED_KEY_BUFLEN]; /* this buffer contains the */
00443     /* EC public-key params, the EC public value and the wrapped key  */
00444 } ECCWrappedKeyInfo;
00445 #endif /* NSS_ENABLE_ECC */
00446 
00447 #if defined(TRACE)
00448 
00449 static char *
00450 ssl3_DecodeHandshakeType(int msgType)
00451 {
00452     char * rv;
00453     static char line[40];
00454 
00455     switch(msgType) {
00456     case hello_request:             rv = "hello_request (0)";               break;
00457     case client_hello:              rv = "client_hello  (1)";               break;
00458     case server_hello:              rv = "server_hello  (2)";               break;
00459     case certificate:               rv = "certificate  (11)";               break;
00460     case server_key_exchange:      rv = "server_key_exchange (12)";        break;
00461     case certificate_request:      rv = "certificate_request (13)";        break;
00462     case server_hello_done: rv = "server_hello_done   (14)";        break;
00463     case certificate_verify:       rv = "certificate_verify  (15)";        break;
00464     case client_key_exchange:      rv = "client_key_exchange (16)";        break;
00465     case finished:           rv = "finished     (20)";               break;
00466     default:
00467         sprintf(line, "*UNKNOWN* handshake type! (%d)", msgType);
00468        rv = line;
00469     }
00470     return rv;
00471 }
00472 
00473 static char *
00474 ssl3_DecodeContentType(int msgType)
00475 {
00476     char * rv;
00477     static char line[40];
00478 
00479     switch(msgType) {
00480     case content_change_cipher_spec:
00481                                 rv = "change_cipher_spec (20)";         break;
00482     case content_alert:             rv = "alert      (21)";                 break;
00483     case content_handshake: rv = "handshake  (22)";                 break;
00484     case content_application_data:
00485                                 rv = "application_data (23)";           break;
00486     default:
00487         sprintf(line, "*UNKNOWN* record type! (%d)", msgType);
00488        rv = line;
00489     }
00490     return rv;
00491 }
00492 
00493 #endif
00494 
00495 SSL3Statistics * 
00496 SSL_GetStatistics(void)
00497 {
00498     return &ssl3stats;
00499 }
00500 
00501 typedef struct tooLongStr {
00502 #if defined(IS_LITTLE_ENDIAN)
00503     PRInt32 low;
00504     PRInt32 high;
00505 #else
00506     PRInt32 high;
00507     PRInt32 low;
00508 #endif
00509 } tooLong;
00510 
00511 static void SSL_AtomicIncrementLong(long * x)
00512 {
00513     if ((sizeof *x) == sizeof(PRInt32)) {
00514         PR_AtomicIncrement((PRInt32 *)x);
00515     } else {
00516        tooLong * tl = (tooLong *)x;
00517        PR_AtomicIncrement(&tl->low) || PR_AtomicIncrement(&tl->high);
00518     }
00519 }
00520 
00521 /* return pointer to ssl3CipherSuiteDef for suite, or NULL */
00522 /* XXX This does a linear search.  A binary search would be better. */
00523 static const ssl3CipherSuiteDef *
00524 ssl_LookupCipherSuiteDef(ssl3CipherSuite suite)
00525 {
00526     int cipher_suite_def_len =
00527        sizeof(cipher_suite_defs) / sizeof(cipher_suite_defs[0]);
00528     int i;
00529 
00530     for (i = 0; i < cipher_suite_def_len; i++) {
00531        if (cipher_suite_defs[i].cipher_suite == suite)
00532            return &cipher_suite_defs[i];
00533     }
00534     PORT_Assert(PR_FALSE);  /* We should never get here. */
00535     PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
00536     return NULL;
00537 }
00538 
00539 /* Find the cipher configuration struct associate with suite */
00540 /* XXX This does a linear search.  A binary search would be better. */
00541 static ssl3CipherSuiteCfg *
00542 ssl_LookupCipherSuiteCfg(ssl3CipherSuite suite, ssl3CipherSuiteCfg *suites)
00543 {
00544     int i;
00545 
00546     for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
00547        if (suites[i].cipher_suite == suite)
00548            return &suites[i];
00549     }
00550     /* return NULL and let the caller handle it.  */
00551     PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
00552     return NULL;
00553 }
00554 
00555 
00556 /* Initialize the suite->isPresent value for config_match
00557  * Returns count of enabled ciphers supported by extant tokens,
00558  * regardless of policy or user preference.
00559  * If this returns zero, the user cannot do SSL v3.
00560  */
00561 int
00562 ssl3_config_match_init(sslSocket *ss)
00563 {
00564     ssl3CipherSuiteCfg *      suite;
00565     const ssl3CipherSuiteDef *cipher_def;
00566     SSLCipherAlgorithm        cipher_alg;
00567     CK_MECHANISM_TYPE         cipher_mech;
00568     SSL3KEAType               exchKeyType;
00569     int                       i;
00570     int                       numPresent         = 0;
00571     int                       numEnabled         = 0;
00572     PRBool                    isServer;
00573     sslServerCerts           *svrAuth;
00574 
00575     PORT_Assert(ss);
00576     if (!ss) {
00577        PORT_SetError(SEC_ERROR_INVALID_ARGS);
00578        return 0;
00579     }
00580     if (!ss->opt.enableSSL3 && !ss->opt.enableTLS) {
00581        return 0;
00582     }
00583     isServer = (PRBool)(ss->sec.isServer != 0);
00584 
00585     for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
00586        suite = &ss->cipherSuites[i];
00587        if (suite->enabled) {
00588            ++numEnabled;
00589            /* We need the cipher defs to see if we have a token that can handle
00590             * this cipher.  It isn't part of the static definition.
00591             */
00592            cipher_def = ssl_LookupCipherSuiteDef(suite->cipher_suite);
00593            if (!cipher_def) {
00594               suite->isPresent = PR_FALSE;
00595               continue;
00596            }
00597            cipher_alg=bulk_cipher_defs[cipher_def->bulk_cipher_alg ].calg;
00598            PORT_Assert(  alg2Mech[cipher_alg].calg == cipher_alg);
00599            cipher_mech = alg2Mech[cipher_alg].cmech;
00600            exchKeyType =
00601                   kea_defs[cipher_def->key_exchange_alg].exchKeyType;
00602 #ifndef NSS_ENABLE_ECC
00603            svrAuth = ss->serverCerts + exchKeyType;
00604 #else
00605            /* XXX SSLKEAType isn't really a good choice for 
00606             * indexing certificates. It doesn't work for
00607             * (EC)DHE-* ciphers. Here we use a hack to ensure
00608             * that the server uses an RSA cert for (EC)DHE-RSA.
00609             */
00610            switch (cipher_def->key_exchange_alg) {
00611            case kea_ecdhe_rsa:
00612 #if NSS_SERVER_DHE_IMPLEMENTED
00613            /* XXX NSS does not yet implement the server side of _DHE_
00614             * cipher suites.  Correcting the computation for svrAuth,
00615             * as the case below does, causes NSS SSL servers to begin to
00616             * negotiate cipher suites they do not implement.  So, until
00617             * server side _DHE_ is implemented, keep this disabled.
00618             */
00619            case kea_dhe_rsa:
00620 #endif
00621               svrAuth = ss->serverCerts + kt_rsa;
00622               break;
00623            case kea_ecdh_ecdsa:
00624            case kea_ecdh_rsa:
00625                /* 
00626                * XXX We ought to have different indices for 
00627                * ECDSA- and RSA-signed EC certificates so
00628                * we could support both key exchange mechanisms
00629                * simultaneously. For now, both of them use
00630                * whatever is in the certificate slot for kt_ecdh
00631                */
00632            default:
00633               svrAuth = ss->serverCerts + exchKeyType;
00634               break;
00635            }
00636 #endif /* NSS_ENABLE_ECC */
00637 
00638            /* Mark the suites that are backed by real tokens, certs and keys */
00639            suite->isPresent = (PRBool)
00640               (((exchKeyType == kt_null) ||
00641                  ((!isServer || (svrAuth->serverKeyPair &&
00642                                  svrAuth->SERVERKEY &&
00643                                svrAuth->serverCertChain)) &&
00644                   PK11_TokenExists(kea_alg_defs[exchKeyType]))) &&
00645               ((cipher_alg == calg_null) || PK11_TokenExists(cipher_mech)));
00646            if (suite->isPresent)
00647               ++numPresent;
00648        }
00649     }
00650     PORT_Assert(numPresent > 0 || numEnabled == 0);
00651     if (numPresent <= 0) {
00652        PORT_SetError(SSL_ERROR_NO_CIPHERS_SUPPORTED);
00653     }
00654     return numPresent;
00655 }
00656 
00657 
00658 /* return PR_TRUE if suite matches policy and enabled state */
00659 /* It would be a REALLY BAD THING (tm) if we ever permitted the use
00660 ** of a cipher that was NOT_ALLOWED.  So, if this is ever called with
00661 ** policy == SSL_NOT_ALLOWED, report no match.
00662 */
00663 /* adjust suite enabled to the availability of a token that can do the
00664  * cipher suite. */
00665 static PRBool
00666 config_match(ssl3CipherSuiteCfg *suite, int policy, PRBool enabled)
00667 {
00668     PORT_Assert(policy != SSL_NOT_ALLOWED && enabled != PR_FALSE);
00669     if (policy == SSL_NOT_ALLOWED || !enabled)
00670        return PR_FALSE;
00671     return (PRBool)(suite->enabled &&
00672                     suite->isPresent &&
00673                    suite->policy != SSL_NOT_ALLOWED &&
00674                   suite->policy <= policy);
00675 }
00676 
00677 /* return number of cipher suites that match policy and enabled state */
00678 /* called from ssl3_SendClientHello and ssl3_ConstructV2CipherSpecsHack */
00679 static int
00680 count_cipher_suites(sslSocket *ss, int policy, PRBool enabled)
00681 {
00682     int i, count = 0;
00683 
00684     if (!ss->opt.enableSSL3 && !ss->opt.enableTLS) {
00685        return 0;
00686     }
00687     for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
00688        if (config_match(&ss->cipherSuites[i], policy, enabled))
00689            count++;
00690     }
00691     if (count <= 0) {
00692        PORT_SetError(SSL_ERROR_SSL_DISABLED);
00693     }
00694     return count;
00695 }
00696 
00697 static PRBool
00698 anyRestrictedEnabled(sslSocket *ss)
00699 {
00700     int i;
00701 
00702     if (!ss->opt.enableSSL3 && !ss->opt.enableTLS) {
00703        return PR_FALSE;
00704     }
00705     for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
00706        ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
00707        if (suite->policy == SSL_RESTRICTED &&
00708            suite->enabled &&
00709            suite->isPresent)
00710            return PR_TRUE;
00711     }
00712     return PR_FALSE;
00713 }
00714 
00715 /*
00716  * Null compression, mac and encryption functions
00717  */
00718 
00719 static SECStatus
00720 Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen,
00721            const unsigned char *input, int inputLen)
00722 {
00723     *outputLen = inputLen;
00724     if (input != output)
00725        PORT_Memcpy(output, input, inputLen);
00726     return SECSuccess;
00727 }
00728 
00729 /*
00730  * SSL3 Utility functions
00731  */
00732 
00733 SECStatus
00734 ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion)
00735 {
00736     SSL3ProtocolVersion version;
00737     SSL3ProtocolVersion maxVersion;
00738 
00739     if (ss->opt.enableTLS) {
00740        maxVersion = SSL_LIBRARY_VERSION_3_1_TLS;
00741     } else if (ss->opt.enableSSL3) {
00742        maxVersion = SSL_LIBRARY_VERSION_3_0;
00743     } else {
00744        /* what are we doing here? */
00745        PORT_Assert(ss->opt.enableSSL3 || ss->opt.enableTLS);
00746        PORT_SetError(SSL_ERROR_SSL_DISABLED);
00747        return SECFailure;
00748     }
00749 
00750     ss->version = version = PR_MIN(maxVersion, peerVersion);
00751 
00752     if ((version == SSL_LIBRARY_VERSION_3_1_TLS && ss->opt.enableTLS) ||
00753        (version == SSL_LIBRARY_VERSION_3_0     && ss->opt.enableSSL3)) {
00754        return SECSuccess;
00755     }
00756 
00757     PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
00758     return SECFailure;
00759 
00760 }
00761 
00762 static SECStatus
00763 ssl3_GetNewRandom(SSL3Random *random)
00764 {
00765     PRIntervalTime gmt = PR_IntervalToSeconds(PR_IntervalNow());
00766     SECStatus rv;
00767 
00768     random->rand[0] = (unsigned char)(gmt >> 24);
00769     random->rand[1] = (unsigned char)(gmt >> 16);
00770     random->rand[2] = (unsigned char)(gmt >>  8);
00771     random->rand[3] = (unsigned char)(gmt);
00772 
00773     /* first 4 bytes are reserverd for time */
00774     rv = PK11_GenerateRandom(&random->rand[4], SSL3_RANDOM_LENGTH - 4);
00775     if (rv != SECSuccess) {
00776        ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
00777     }
00778     return rv;
00779 }
00780 
00781 /* Called by ssl3_SendServerKeyExchange and ssl3_SendCertificateVerify */
00782 SECStatus
00783 ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf, 
00784                 PRBool isTLS)
00785 {
00786     SECStatus rv            = SECFailure;
00787     PRBool    doDerEncode       = PR_FALSE;
00788     int       signatureLen;
00789     SECItem   hashItem;
00790 
00791     buf->data    = NULL;
00792     signatureLen = PK11_SignatureLen(key);
00793     if (signatureLen <= 0) {
00794        PORT_SetError(SEC_ERROR_INVALID_KEY);
00795         goto done;
00796     }
00797 
00798     buf->len  = (unsigned)signatureLen;
00799     buf->data = (unsigned char *)PORT_Alloc(signatureLen);
00800     if (!buf->data)
00801         goto done;   /* error code was set. */
00802 
00803     switch (key->keyType) {
00804     case rsaKey:
00805        hashItem.data = hash->md5;
00806        hashItem.len = sizeof(SSL3Hashes);
00807        break;
00808     case dsaKey:
00809        doDerEncode = isTLS;
00810        hashItem.data = hash->sha;
00811        hashItem.len = sizeof(hash->sha);
00812        break;
00813 #ifdef NSS_ENABLE_ECC
00814     case ecKey:
00815        doDerEncode = PR_TRUE;
00816        hashItem.data = hash->sha;
00817        hashItem.len = sizeof(hash->sha);
00818        break;
00819 #endif /* NSS_ENABLE_ECC */
00820     default:
00821        PORT_SetError(SEC_ERROR_INVALID_KEY);
00822        goto done;
00823     }
00824     PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len));
00825 
00826     rv = PK11_Sign(key, buf, &hashItem);
00827     if (rv != SECSuccess) {
00828        ssl_MapLowLevelError(SSL_ERROR_SIGN_HASHES_FAILURE);
00829     } else if (doDerEncode) {
00830        SECItem   derSig     = {siBuffer, NULL, 0};
00831 
00832        /* This also works for an ECDSA signature */
00833        rv = DSAU_EncodeDerSigWithLen(&derSig, buf, buf->len);
00834        if (rv == SECSuccess) {
00835            PORT_Free(buf->data);   /* discard unencoded signature. */
00836            *buf = derSig;          /* give caller encoded signature. */
00837        } else if (derSig.data) {
00838            PORT_Free(derSig.data);
00839        }
00840     }
00841 
00842     PRINT_BUF(60, (NULL, "signed hashes", (unsigned char*)buf->data, buf->len));
00843 done:
00844     if (rv != SECSuccess && buf->data) {
00845        PORT_Free(buf->data);
00846        buf->data = NULL;
00847     }
00848     return rv;
00849 }
00850 
00851 /* Called from ssl3_HandleServerKeyExchange, ssl3_HandleCertificateVerify */
00852 SECStatus
00853 ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert, 
00854                         SECItem *buf, PRBool isTLS, void *pwArg)
00855 {
00856     SECKEYPublicKey * key;
00857     SECItem *         signature    = NULL;
00858     SECStatus         rv;
00859     SECItem           hashItem;
00860 #ifdef NSS_ENABLE_ECC
00861     unsigned int      len;
00862 #endif /* NSS_ENABLE_ECC */
00863 
00864 
00865     PRINT_BUF(60, (NULL, "check signed hashes",
00866                   buf->data, buf->len));
00867 
00868     key = CERT_ExtractPublicKey(cert);
00869     if (key == NULL) {
00870        /* CERT_ExtractPublicKey doesn't set error code */
00871        PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
00872        return SECFailure;
00873     }
00874 
00875     switch (key->keyType) {
00876     case rsaKey:
00877        hashItem.data = hash->md5;
00878        hashItem.len = sizeof(SSL3Hashes);
00879        break;
00880     case dsaKey:
00881        hashItem.data = hash->sha;
00882        hashItem.len = sizeof(hash->sha);
00883        if (isTLS) {
00884            signature = DSAU_DecodeDerSig(buf);
00885            if (!signature) {
00886               PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
00887               return SECFailure;
00888            }
00889            buf = signature;
00890        }
00891        break;
00892 
00893 #ifdef NSS_ENABLE_ECC
00894     case ecKey:
00895        hashItem.data = hash->sha;
00896        hashItem.len = sizeof(hash->sha);
00897        /*
00898         * ECDSA signatures always encode the integers r and s 
00899         * using ASN (unlike DSA where ASN encoding is used
00900         * with TLS but not with SSL3)
00901         */
00902        len = SECKEY_SignatureLen(key);
00903        if (len == 0) {
00904            SECKEY_DestroyPublicKey(key);
00905            PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
00906            return SECFailure;
00907        }
00908        signature = DSAU_DecodeDerSigToLen(buf, len);
00909        if (!signature) {
00910            PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
00911            return SECFailure;
00912        }
00913        buf = signature;
00914        break;
00915 #endif /* NSS_ENABLE_ECC */
00916 
00917     default:
00918        SECKEY_DestroyPublicKey(key);
00919        PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
00920        return SECFailure;
00921     }
00922 
00923     PRINT_BUF(60, (NULL, "hash(es) to be verified",
00924                   hashItem.data, hashItem.len));
00925 
00926     rv = PK11_Verify(key, buf, &hashItem, pwArg);
00927     SECKEY_DestroyPublicKey(key);
00928     if (signature) {
00929        SECITEM_FreeItem(signature, PR_TRUE);
00930     }
00931     if (rv != SECSuccess) {
00932        ssl_MapLowLevelError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
00933     }
00934     return rv;
00935 }
00936 
00937 
00938 /* Caller must set hiLevel error code. */
00939 /* Called from ssl3_ComputeExportRSAKeyHash
00940  *             ssl3_ComputeDHKeyHash
00941  * which are called from ssl3_HandleServerKeyExchange. 
00942  */
00943 SECStatus
00944 ssl3_ComputeCommonKeyHash(PRUint8 * hashBuf, unsigned int bufLen,
00945                           SSL3Hashes *hashes, PRBool bypassPKCS11)
00946 {
00947     SECStatus     rv               = SECSuccess;
00948 
00949     if (bypassPKCS11) {
00950        MD5_HashBuf (hashes->md5, hashBuf, bufLen);
00951        SHA1_HashBuf(hashes->sha, hashBuf, bufLen);
00952     } else {
00953        rv = PK11_HashBuf(SEC_OID_MD5, hashes->md5, hashBuf, bufLen);
00954        if (rv != SECSuccess) {
00955            ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
00956            rv = SECFailure;
00957            goto done;
00958        }
00959 
00960        rv = PK11_HashBuf(SEC_OID_SHA1, hashes->sha, hashBuf, bufLen);
00961        if (rv != SECSuccess) {
00962            ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
00963            rv = SECFailure;
00964        }
00965     }
00966 done:
00967     return rv;
00968 }
00969 
00970 /* Caller must set hiLevel error code. 
00971 ** Called from ssl3_SendServerKeyExchange and 
00972 **             ssl3_HandleServerKeyExchange.
00973 */
00974 static SECStatus
00975 ssl3_ComputeExportRSAKeyHash(SECItem modulus, SECItem publicExponent,
00976                           SSL3Random *client_rand, SSL3Random *server_rand,
00977                           SSL3Hashes *hashes, PRBool bypassPKCS11)
00978 {
00979     PRUint8     * hashBuf;
00980     PRUint8     * pBuf;
00981     SECStatus     rv               = SECSuccess;
00982     unsigned int  bufLen;
00983     PRUint8       buf[2*SSL3_RANDOM_LENGTH + 2 + 4096/8 + 2 + 4096/8];
00984 
00985     bufLen = 2*SSL3_RANDOM_LENGTH + 2 + modulus.len + 2 + publicExponent.len;
00986     if (bufLen <= sizeof buf) {
00987        hashBuf = buf;
00988     } else {
00989        hashBuf = PORT_Alloc(bufLen);
00990        if (!hashBuf) {
00991            return SECFailure;
00992        }
00993     }
00994 
00995     memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH); 
00996        pBuf = hashBuf + SSL3_RANDOM_LENGTH;
00997     memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
00998        pBuf += SSL3_RANDOM_LENGTH;
00999     pBuf[0]  = (PRUint8)(modulus.len >> 8);
01000     pBuf[1]  = (PRUint8)(modulus.len);
01001        pBuf += 2;
01002     memcpy(pBuf, modulus.data, modulus.len);
01003        pBuf += modulus.len;
01004     pBuf[0] = (PRUint8)(publicExponent.len >> 8);
01005     pBuf[1] = (PRUint8)(publicExponent.len);
01006        pBuf += 2;
01007     memcpy(pBuf, publicExponent.data, publicExponent.len);
01008        pBuf += publicExponent.len;
01009     PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
01010 
01011     rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
01012 
01013     PRINT_BUF(95, (NULL, "RSAkey hash: ", hashBuf, bufLen));
01014     PRINT_BUF(95, (NULL, "RSAkey hash: MD5 result", hashes->md5, MD5_LENGTH));
01015     PRINT_BUF(95, (NULL, "RSAkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
01016 
01017     if (hashBuf != buf && hashBuf != NULL)
01018        PORT_Free(hashBuf);
01019     return rv;
01020 }
01021 
01022 /* Caller must set hiLevel error code. */
01023 /* Called from ssl3_HandleServerKeyExchange. */
01024 static SECStatus
01025 ssl3_ComputeDHKeyHash(SECItem dh_p, SECItem dh_g, SECItem dh_Ys,
01026                           SSL3Random *client_rand, SSL3Random *server_rand,
01027                           SSL3Hashes *hashes, PRBool bypassPKCS11)
01028 {
01029     PRUint8     * hashBuf;
01030     PRUint8     * pBuf;
01031     SECStatus     rv               = SECSuccess;
01032     unsigned int  bufLen;
01033     PRUint8       buf[2*SSL3_RANDOM_LENGTH + 2 + 4096/8 + 2 + 4096/8];
01034 
01035     bufLen = 2*SSL3_RANDOM_LENGTH + 2 + dh_p.len + 2 + dh_g.len + 2 + dh_Ys.len;
01036     if (bufLen <= sizeof buf) {
01037        hashBuf = buf;
01038     } else {
01039        hashBuf = PORT_Alloc(bufLen);
01040        if (!hashBuf) {
01041            return SECFailure;
01042        }
01043     }
01044 
01045     memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH); 
01046        pBuf = hashBuf + SSL3_RANDOM_LENGTH;
01047     memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
01048        pBuf += SSL3_RANDOM_LENGTH;
01049     pBuf[0]  = (PRUint8)(dh_p.len >> 8);
01050     pBuf[1]  = (PRUint8)(dh_p.len);
01051        pBuf += 2;
01052     memcpy(pBuf, dh_p.data, dh_p.len);
01053        pBuf += dh_p.len;
01054     pBuf[0] = (PRUint8)(dh_g.len >> 8);
01055     pBuf[1] = (PRUint8)(dh_g.len);
01056        pBuf += 2;
01057     memcpy(pBuf, dh_g.data, dh_g.len);
01058        pBuf += dh_g.len;
01059     pBuf[0] = (PRUint8)(dh_Ys.len >> 8);
01060     pBuf[1] = (PRUint8)(dh_Ys.len);
01061        pBuf += 2;
01062     memcpy(pBuf, dh_Ys.data, dh_Ys.len);
01063        pBuf += dh_Ys.len;
01064     PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
01065 
01066     rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
01067 
01068     PRINT_BUF(95, (NULL, "DHkey hash: ", hashBuf, bufLen));
01069     PRINT_BUF(95, (NULL, "DHkey hash: MD5 result", hashes->md5, MD5_LENGTH));
01070     PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
01071 
01072     if (hashBuf != buf && hashBuf != NULL)
01073        PORT_Free(hashBuf);
01074     return rv;
01075 }
01076 
01077 static void
01078 ssl3_BumpSequenceNumber(SSL3SequenceNumber *num)
01079 {
01080     num->low++;
01081     if (num->low == 0)
01082        num->high++;
01083 }
01084 
01085 /* Called twice, only from ssl3_DestroyCipherSpec (immediately below). */
01086 static void
01087 ssl3_CleanupKeyMaterial(ssl3KeyMaterial *mat)
01088 {
01089     if (mat->write_key != NULL) {
01090        PK11_FreeSymKey(mat->write_key);
01091        mat->write_key = NULL;
01092     }
01093     if (mat->write_mac_key != NULL) {
01094        PK11_FreeSymKey(mat->write_mac_key);
01095        mat->write_mac_key = NULL;
01096     }
01097     if (mat->write_mac_context != NULL) {
01098        PK11_DestroyContext(mat->write_mac_context, PR_TRUE);
01099        mat->write_mac_context = NULL;
01100     }
01101 }
01102 
01103 /* Called from ssl3_SendChangeCipherSpecs() and 
01104 **            ssl3_HandleChangeCipherSpecs()
01105 **             ssl3_DestroySSL3Info
01106 ** Caller must hold SpecWriteLock.
01107 */
01108 static void
01109 ssl3_DestroyCipherSpec(ssl3CipherSpec *spec)
01110 {
01111     PRBool freeit = (PRBool)(!spec->bypassCiphers);
01112 /*  PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); Don't have ss! */
01113     if (spec->destroy) {
01114        spec->destroy(spec->encodeContext, freeit);
01115        spec->destroy(spec->decodeContext, freeit);
01116        spec->encodeContext = NULL; /* paranoia */
01117        spec->decodeContext = NULL;
01118     }
01119     if (spec->master_secret != NULL) {
01120        PK11_FreeSymKey(spec->master_secret);
01121        spec->master_secret = NULL;
01122     }
01123     spec->msItem.data = NULL;
01124     spec->msItem.len  = 0;
01125     ssl3_CleanupKeyMaterial(&spec->client);
01126     ssl3_CleanupKeyMaterial(&spec->server);
01127     spec->bypassCiphers = PR_FALSE;
01128     spec->destroy=NULL;
01129 }
01130 
01131 /* Fill in the pending cipher spec with info from the selected ciphersuite.
01132 ** This is as much initialization as we can do without having key material.
01133 ** Called from ssl3_HandleServerHello(), ssl3_SendServerHello()
01134 ** Caller must hold the ssl3 handshake lock.
01135 ** Acquires & releases SpecWriteLock.
01136 */
01137 static SECStatus
01138 ssl3_SetupPendingCipherSpec(sslSocket *ss)
01139 {
01140     ssl3CipherSpec *          pwSpec;
01141     ssl3CipherSpec *          cwSpec;
01142     ssl3CipherSuite           suite     = ss->ssl3.hs.cipher_suite;
01143     SSL3MACAlgorithm          mac;
01144     SSL3BulkCipher            cipher;
01145     SSL3KeyExchangeAlgorithm  kea;
01146     const ssl3CipherSuiteDef *suite_def;
01147     PRBool                    isTLS;
01148 
01149     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
01150 
01151     ssl_GetSpecWriteLock(ss);  /*******************************/
01152 
01153     pwSpec = ss->ssl3.pwSpec;
01154     PORT_Assert(pwSpec == ss->ssl3.prSpec);
01155 
01156     /* This hack provides maximal interoperability with SSL 3 servers. */
01157     cwSpec = ss->ssl3.cwSpec;
01158     if (cwSpec->mac_def->mac == mac_null) {
01159        /* SSL records are not being MACed. */
01160        cwSpec->version = ss->version;
01161     }
01162 
01163     pwSpec->version  = ss->version;
01164     isTLS  = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0);
01165 
01166     SSL_TRC(3, ("%d: SSL3[%d]: Set XXX Pending Cipher Suite to 0x%04x",
01167               SSL_GETPID(), ss->fd, suite));
01168 
01169     suite_def = ssl_LookupCipherSuiteDef(suite);
01170     if (suite_def == NULL) {
01171        ssl_ReleaseSpecWriteLock(ss);
01172        return SECFailure;   /* error code set by ssl_LookupCipherSuiteDef */
01173     }
01174 
01175 
01176     cipher = suite_def->bulk_cipher_alg;
01177     kea    = suite_def->key_exchange_alg;
01178     mac    = suite_def->mac_alg;
01179     if (isTLS)
01180        mac += 2;
01181 
01182     ss->ssl3.hs.suite_def = suite_def;
01183     ss->ssl3.hs.kea_def   = &kea_defs[kea];
01184     PORT_Assert(ss->ssl3.hs.kea_def->kea == kea);
01185 
01186     pwSpec->cipher_def   = &bulk_cipher_defs[cipher];
01187     PORT_Assert(pwSpec->cipher_def->cipher == cipher);
01188 
01189     pwSpec->mac_def = &mac_defs[mac];
01190     PORT_Assert(pwSpec->mac_def->mac == mac);
01191 
01192     ss->sec.keyBits       = pwSpec->cipher_def->key_size        * BPB;
01193     ss->sec.secretKeyBits = pwSpec->cipher_def->secret_key_size * BPB;
01194     ss->sec.cipherType    = cipher;
01195 
01196     pwSpec->encodeContext = NULL;
01197     pwSpec->decodeContext = NULL;
01198 
01199     pwSpec->mac_size = pwSpec->mac_def->mac_size;
01200 
01201     ssl_ReleaseSpecWriteLock(ss);  /*******************************/
01202     return SECSuccess;
01203 }
01204 
01205 /* Initialize encryption and MAC contexts for pending spec.
01206  * Master Secret already is derived in spec->msItem
01207  * Caller holds Spec write lock.
01208  */
01209 static SECStatus
01210 ssl3_InitPendingContextsBypass(sslSocket *ss)
01211 {
01212       ssl3CipherSpec  *  pwSpec;
01213 const ssl3BulkCipherDef *cipher_def;
01214       void *             serverContext = NULL;
01215       void *             clientContext = NULL;
01216       BLapiInitContextFunc initFn = (BLapiInitContextFunc)NULL;
01217       int                mode     = 0;
01218       unsigned int       optArg1  = 0;
01219       unsigned int       optArg2  = 0;
01220       PRBool             server_encrypts = ss->sec.isServer;
01221       CK_ULONG           macLength;
01222       SSLCipherAlgorithm calg;
01223       SECStatus          rv;
01224 
01225     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
01226 
01227     PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
01228 
01229     pwSpec        = ss->ssl3.pwSpec;
01230     cipher_def    = pwSpec->cipher_def;
01231     macLength     = pwSpec->mac_size;
01232 
01233     /* MAC setup is done when computing the mac, not here.
01234      * Now setup the crypto contexts.
01235      */
01236 
01237     calg = cipher_def->calg;
01238 
01239     serverContext = pwSpec->server.cipher_context;
01240     clientContext = pwSpec->client.cipher_context;
01241 
01242     switch (calg) {
01243     case ssl_calg_null:
01244        pwSpec->encode  = Null_Cipher;
01245        pwSpec->decode  = Null_Cipher;
01246         pwSpec->destroy = NULL;
01247        goto success;
01248 
01249     case ssl_calg_rc4:
01250        initFn = (BLapiInitContextFunc)RC4_InitContext;
01251        pwSpec->encode  = (SSLCipher) RC4_Encrypt;
01252        pwSpec->decode  = (SSLCipher) RC4_Decrypt;
01253        pwSpec->destroy = (SSLDestroy) RC4_DestroyContext;
01254        break;
01255     case ssl_calg_rc2:
01256        initFn = (BLapiInitContextFunc)RC2_InitContext;
01257        mode = NSS_RC2_CBC;
01258        optArg1 = cipher_def->key_size;
01259        pwSpec->encode  = (SSLCipher) RC2_Encrypt;
01260        pwSpec->decode  = (SSLCipher) RC2_Decrypt;
01261        pwSpec->destroy = (SSLDestroy) RC2_DestroyContext;
01262        break;
01263     case ssl_calg_des:
01264        initFn = (BLapiInitContextFunc)DES_InitContext;
01265        mode = NSS_DES_CBC;
01266        optArg1 = server_encrypts;
01267        pwSpec->encode  = (SSLCipher) DES_Encrypt;
01268        pwSpec->decode  = (SSLCipher) DES_Decrypt;
01269        pwSpec->destroy = (SSLDestroy) DES_DestroyContext;
01270        break;
01271     case ssl_calg_3des:
01272        initFn = (BLapiInitContextFunc)DES_InitContext;
01273        mode = NSS_DES_EDE3_CBC;
01274        optArg1 = server_encrypts;
01275        pwSpec->encode  = (SSLCipher) DES_Encrypt;
01276        pwSpec->decode  = (SSLCipher) DES_Decrypt;
01277        pwSpec->destroy = (SSLDestroy) DES_DestroyContext;
01278        break;
01279     case ssl_calg_aes:
01280        initFn = (BLapiInitContextFunc)AES_InitContext;
01281        mode = NSS_AES_CBC;
01282        optArg1 = server_encrypts;
01283        optArg2 = AES_BLOCK_SIZE;
01284        pwSpec->encode  = (SSLCipher) AES_Encrypt;
01285        pwSpec->decode  = (SSLCipher) AES_Decrypt;
01286        pwSpec->destroy = (SSLDestroy) AES_DestroyContext;
01287        break;
01288 
01289     case ssl_calg_idea:
01290     case ssl_calg_fortezza :
01291     default:
01292        PORT_Assert(0);
01293        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
01294        goto bail_out;
01295     }
01296     rv = (*initFn)(serverContext,
01297                  pwSpec->server.write_key_item.data,
01298                  pwSpec->server.write_key_item.len,
01299                  pwSpec->server.write_iv_item.data,
01300                  mode, optArg1, optArg2);
01301     if (rv != SECSuccess) {
01302        PORT_Assert(0);
01303        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
01304        goto bail_out;
01305     }
01306 
01307     if (calg == ssl_calg_des || calg == ssl_calg_3des || calg == ssl_calg_aes) {
01308        /* For block ciphers, if the server is encrypting, then the client
01309         * is decrypting, and vice versa.
01310         */
01311        optArg1 = !optArg1;
01312     }
01313 
01314     rv = (*initFn)(clientContext,
01315                  pwSpec->client.write_key_item.data,
01316                  pwSpec->client.write_key_item.len,
01317                  pwSpec->client.write_iv_item.data,
01318                  mode, optArg1, optArg2);
01319     if (rv != SECSuccess) {
01320        PORT_Assert(0);
01321        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
01322        goto bail_out;
01323     }
01324 
01325     pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext;
01326     pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext;
01327 
01328 success:
01329     return SECSuccess;
01330 
01331 bail_out:
01332     return SECFailure;
01333 }
01334 
01335 /* This function should probably be moved to pk11wrap and be named 
01336  * PK11_ParamFromIVAndEffectiveKeyBits
01337  */
01338 static SECItem *
01339 ssl3_ParamFromIV(CK_MECHANISM_TYPE mtype, SECItem *iv, CK_ULONG ulEffectiveBits)
01340 {
01341     SECItem * param = PK11_ParamFromIV(mtype, iv);
01342     if (param && param->data  && param->len >= sizeof(CK_RC2_PARAMS)) {
01343        switch (mtype) {
01344        case CKM_RC2_KEY_GEN:
01345        case CKM_RC2_ECB:
01346        case CKM_RC2_CBC:
01347        case CKM_RC2_MAC:
01348        case CKM_RC2_MAC_GENERAL:
01349        case CKM_RC2_CBC_PAD:
01350            *(CK_RC2_PARAMS *)param->data = ulEffectiveBits;
01351        default: break;
01352        }
01353     }
01354     return param;
01355 }
01356 
01357 /* Initialize encryption and MAC contexts for pending spec.
01358  * Master Secret already is derived.
01359  * Caller holds Spec write lock.
01360  */
01361 static SECStatus
01362 ssl3_InitPendingContextsPKCS11(sslSocket *ss)
01363 {
01364       ssl3CipherSpec  *  pwSpec;
01365 const ssl3BulkCipherDef *cipher_def;
01366       PK11Context *      serverContext = NULL;
01367       PK11Context *      clientContext = NULL;
01368       SECItem *          param;
01369       CK_MECHANISM_TYPE  mechanism;
01370       CK_MECHANISM_TYPE  mac_mech;
01371       CK_ULONG           macLength;
01372       CK_ULONG           effKeyBits;
01373       SECItem            iv;
01374       SECItem            mac_param;
01375       SSLCipherAlgorithm calg;
01376 
01377     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
01378 
01379     PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
01380 
01381     pwSpec        = ss->ssl3.pwSpec;
01382     cipher_def    = pwSpec->cipher_def;
01383     macLength     = pwSpec->mac_size;
01384 
01385     /* 
01386     ** Now setup the MAC contexts, 
01387     **   crypto contexts are setup below.
01388     */
01389 
01390     pwSpec->client.write_mac_context = NULL;
01391     pwSpec->server.write_mac_context = NULL;
01392     mac_mech       = pwSpec->mac_def->mmech;
01393     mac_param.data = (unsigned char *)&macLength;
01394     mac_param.len  = sizeof(macLength);
01395     mac_param.type = 0;
01396 
01397     pwSpec->client.write_mac_context = PK11_CreateContextBySymKey(
01398            mac_mech, CKA_SIGN, pwSpec->client.write_mac_key, &mac_param);
01399     if (pwSpec->client.write_mac_context == NULL)  {
01400        ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
01401        goto fail;
01402     }
01403     pwSpec->server.write_mac_context = PK11_CreateContextBySymKey(
01404            mac_mech, CKA_SIGN, pwSpec->server.write_mac_key, &mac_param);
01405     if (pwSpec->server.write_mac_context == NULL) {
01406        ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
01407        goto fail;
01408     }
01409 
01410     /* 
01411     ** Now setup the crypto contexts.
01412     */
01413 
01414     calg = cipher_def->calg;
01415     PORT_Assert(alg2Mech[calg].calg == calg);
01416 
01417     if (calg == calg_null) {
01418        pwSpec->encode  = Null_Cipher;
01419        pwSpec->decode  = Null_Cipher;
01420        pwSpec->destroy = NULL;
01421        return SECSuccess;
01422     }
01423     mechanism = alg2Mech[calg].cmech;
01424     effKeyBits = cipher_def->key_size * BPB;
01425 
01426     /*
01427      * build the server context
01428      */
01429     iv.data = pwSpec->server.write_iv;
01430     iv.len  = cipher_def->iv_size;
01431     param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits);
01432     if (param == NULL) {
01433        ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
01434        goto fail;
01435     }
01436     serverContext = PK11_CreateContextBySymKey(mechanism,
01437                             (ss->sec.isServer ? CKA_ENCRYPT : CKA_DECRYPT),
01438                             pwSpec->server.write_key, param);
01439     iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len);
01440     if (iv.data)
01441        PORT_Memcpy(pwSpec->server.write_iv, iv.data, iv.len);
01442     SECITEM_FreeItem(param, PR_TRUE);
01443     if (serverContext == NULL) {
01444        ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
01445        goto fail;
01446     }
01447 
01448     /*
01449      * build the client context
01450      */
01451     iv.data = pwSpec->client.write_iv;
01452     iv.len  = cipher_def->iv_size;
01453 
01454     param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits);
01455     if (param == NULL) {
01456        ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
01457        goto fail;
01458     }
01459     clientContext = PK11_CreateContextBySymKey(mechanism,
01460                             (ss->sec.isServer ? CKA_DECRYPT : CKA_ENCRYPT),
01461                             pwSpec->client.write_key, param);
01462     iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len);
01463     if (iv.data)
01464        PORT_Memcpy(pwSpec->client.write_iv, iv.data, iv.len);
01465     SECITEM_FreeItem(param,PR_TRUE);
01466     if (clientContext == NULL) {
01467        ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
01468        goto fail;
01469     }
01470     pwSpec->encode  = (SSLCipher) PK11_CipherOp;
01471     pwSpec->decode  = (SSLCipher) PK11_CipherOp;
01472     pwSpec->destroy = (SSLDestroy) PK11_DestroyContext;
01473 
01474     pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext;
01475     pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext;
01476 
01477     serverContext = NULL;
01478     clientContext = NULL;
01479 
01480     return SECSuccess;
01481 
01482 fail:
01483     if (serverContext != NULL) PK11_DestroyContext(serverContext, PR_TRUE);
01484     if (clientContext != NULL) PK11_DestroyContext(clientContext, PR_TRUE);
01485     if (pwSpec->client.write_mac_context != NULL) {
01486        PK11_DestroyContext(pwSpec->client.write_mac_context,PR_TRUE);
01487        pwSpec->client.write_mac_context = NULL;
01488     }
01489     if (pwSpec->server.write_mac_context != NULL) {
01490        PK11_DestroyContext(pwSpec->server.write_mac_context,PR_TRUE);
01491        pwSpec->server.write_mac_context = NULL;
01492     }
01493 
01494     return SECFailure;
01495 }
01496 
01497 /* Complete the initialization of all keys, ciphers, MACs and their contexts
01498  * for the pending Cipher Spec.
01499  * Called from: ssl3_SendClientKeyExchange       (for Full handshake)
01500  *              ssl3_HandleRSAClientKeyExchange  (for Full handshake)
01501  *              ssl3_HandleServerHello           (for session restart)
01502  *              ssl3_HandleClientHello           (for session restart)
01503  * Sets error code, but caller probably should override to disambiguate.
01504  * NULL pms means re-use old master_secret.
01505  *
01506  * This code is common to the bypass and PKCS11 execution paths.
01507  * For the bypass case,  pms is NULL.
01508  */
01509 SECStatus
01510 ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms)
01511 {
01512     ssl3CipherSpec  *  pwSpec;
01513     SECStatus          rv;
01514 
01515     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
01516 
01517     ssl_GetSpecWriteLock(ss);      /**************************************/
01518 
01519     PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
01520 
01521     pwSpec        = ss->ssl3.pwSpec;
01522 
01523     if (pms || (!pwSpec->msItem.len && !pwSpec->master_secret)) {
01524        rv = ssl3_DeriveMasterSecret(ss, pms);
01525        if (rv != SECSuccess) {
01526            goto done;  /* err code set by ssl3_DeriveMasterSecret */
01527        }
01528     }
01529     if (ss->opt.bypassPKCS11 && pwSpec->msItem.len && pwSpec->msItem.data) {
01530        /* Double Bypass succeeded in extracting the master_secret */
01531        const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
01532        PRBool             isTLS   = (PRBool)(kea_def->tls_keygen ||
01533                                 (pwSpec->version > SSL_LIBRARY_VERSION_3_0));
01534        pwSpec->bypassCiphers = PR_TRUE;
01535        rv = ssl3_KeyAndMacDeriveBypass( pwSpec, 
01536                           (const unsigned char *)&ss->ssl3.hs.client_random,
01537                           (const unsigned char *)&ss->ssl3.hs.server_random,
01538                           isTLS, 
01539                           (PRBool)(kea_def->is_limited));
01540        if (rv == SECSuccess) {
01541            rv = ssl3_InitPendingContextsBypass(ss);
01542        }
01543     } else if (pwSpec->master_secret) {
01544        rv = ssl3_DeriveConnectionKeysPKCS11(ss);
01545        if (rv == SECSuccess) {
01546            rv = ssl3_InitPendingContextsPKCS11(ss);
01547        }
01548     } else {
01549        PORT_Assert(pwSpec->master_secret);
01550        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
01551        rv = SECFailure;
01552     }
01553 
01554 done:
01555     ssl_ReleaseSpecWriteLock(ss);  /******************************/
01556     if (rv != SECSuccess)
01557        ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
01558     return rv;
01559 }
01560 
01561 /*
01562  * 60 bytes is 3 times the maximum length MAC size that is supported.
01563  */
01564 static const unsigned char mac_pad_1 [60] = {
01565     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
01566     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
01567     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
01568     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
01569     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
01570     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
01571     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
01572     0x36, 0x36, 0x36, 0x36
01573 };
01574 static const unsigned char mac_pad_2 [60] = {
01575     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
01576     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
01577     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
01578     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
01579     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
01580     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
01581     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
01582     0x5c, 0x5c, 0x5c, 0x5c
01583 };
01584 
01585 /* Called from: ssl3_SendRecord()
01586 **            ssl3_HandleRecord()
01587 ** Caller must already hold the SpecReadLock. (wish we could assert that!)
01588 */
01589 static SECStatus
01590 ssl3_ComputeRecordMAC(
01591     ssl3CipherSpec *   spec,
01592     PRBool             useServerMacKey,
01593     SSL3ContentType    type,
01594     SSL3ProtocolVersion version,
01595     SSL3SequenceNumber seq_num,
01596     const SSL3Opaque * input,
01597     int                inputLength,
01598     unsigned char *    outbuf,
01599     unsigned int *     outLength)
01600 {
01601     const ssl3MACDef * mac_def;
01602     SECStatus          rv;
01603     PRBool             isTLS;
01604     unsigned int       tempLen;
01605     unsigned char      temp[MAX_MAC_LENGTH];
01606 
01607     temp[0] = (unsigned char)(seq_num.high >> 24);
01608     temp[1] = (unsigned char)(seq_num.high >> 16);
01609     temp[2] = (unsigned char)(seq_num.high >>  8);
01610     temp[3] = (unsigned char)(seq_num.high >>  0);
01611     temp[4] = (unsigned char)(seq_num.low  >> 24);
01612     temp[5] = (unsigned char)(seq_num.low  >> 16);
01613     temp[6] = (unsigned char)(seq_num.low  >>  8);
01614     temp[7] = (unsigned char)(seq_num.low  >>  0);
01615     temp[8] = type;
01616 
01617     /* TLS MAC includes the record's version field, SSL's doesn't.
01618     ** We decide which MAC defintiion to use based on the version of 
01619     ** the protocol that was negotiated when the spec became current,
01620     ** NOT based on the version value in the record itself.
01621     ** But, we use the record'v version value in the computation.
01622     */
01623     if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
01624        temp[9]  = MSB(inputLength);
01625        temp[10] = LSB(inputLength);
01626        tempLen  = 11;
01627        isTLS    = PR_FALSE;
01628     } else {
01629        /* New TLS hash includes version. */
01630        temp[9]  = MSB(version);
01631        temp[10] = LSB(version);
01632        temp[11] = MSB(inputLength);
01633        temp[12] = LSB(inputLength);
01634        tempLen  = 13;
01635        isTLS    = PR_TRUE;
01636     }
01637 
01638     PRINT_BUF(95, (NULL, "frag hash1: temp", temp, tempLen));
01639     PRINT_BUF(95, (NULL, "frag hash1: input", input, inputLength));
01640 
01641     mac_def = spec->mac_def;
01642     if (mac_def->mac == mac_null) {
01643        *outLength = 0;
01644        return SECSuccess;
01645     }
01646     if (! spec->bypassCiphers) {
01647        PK11Context *mac_context = 
01648            (useServerMacKey ? spec->server.write_mac_context
01649                             : spec->client.write_mac_context);
01650        rv  = PK11_DigestBegin(mac_context);
01651        rv |= PK11_DigestOp(mac_context, temp, tempLen);
01652        rv |= PK11_DigestOp(mac_context, input, inputLength);
01653        rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size);
01654     } else {
01655        /* bypass version */
01656        const SECHashObject *hashObj = NULL;
01657        unsigned int       pad_bytes;
01658        PRUint64           write_mac_context[MAX_MAC_CONTEXT_LLONGS];
01659 
01660        switch (mac_def->mac) {
01661        case ssl_mac_null:
01662            *outLength = 0;
01663            return SECSuccess;
01664        case ssl_mac_md5:
01665            pad_bytes = 48;
01666            hashObj = HASH_GetRawHashObject(HASH_AlgMD5);
01667            break;
01668        case ssl_mac_sha:
01669            pad_bytes = 40;
01670            hashObj = HASH_GetRawHashObject(HASH_AlgSHA1);
01671            break;
01672        case ssl_hmac_md5: /* used with TLS */
01673            hashObj = HASH_GetRawHashObject(HASH_AlgMD5);
01674            break;
01675        case ssl_hmac_sha: /* used with TLS */
01676            hashObj = HASH_GetRawHashObject(HASH_AlgSHA1);
01677            break;
01678        default:
01679            break;
01680        }
01681        if (!hashObj) {
01682            PORT_Assert(0);
01683            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
01684            return SECFailure;
01685        }
01686 
01687        if (!isTLS) {
01688            /* compute "inner" part of SSL3 MAC */
01689            hashObj->begin(write_mac_context);
01690            if (useServerMacKey)
01691               hashObj->update(write_mac_context, 
01692                             spec->server.write_mac_key_item.data,
01693                             spec->server.write_mac_key_item.len);
01694            else
01695               hashObj->update(write_mac_context, 
01696                             spec->client.write_mac_key_item.data,
01697                             spec->client.write_mac_key_item.len);
01698            hashObj->update(write_mac_context, mac_pad_1, pad_bytes);
01699            hashObj->update(write_mac_context, temp,  tempLen);
01700            hashObj->update(write_mac_context, input, inputLength);
01701            hashObj->end(write_mac_context,    temp, &tempLen, sizeof temp);
01702 
01703            /* compute "outer" part of SSL3 MAC */
01704            hashObj->begin(write_mac_context);
01705            if (useServerMacKey)
01706               hashObj->update(write_mac_context, 
01707                             spec->server.write_mac_key_item.data,
01708                             spec->server.write_mac_key_item.len);
01709            else
01710               hashObj->update(write_mac_context, 
01711                             spec->client.write_mac_key_item.data,
01712                             spec->client.write_mac_key_item.len);
01713            hashObj->update(write_mac_context, mac_pad_2, pad_bytes);
01714            hashObj->update(write_mac_context, temp, tempLen);
01715            hashObj->end(write_mac_context, outbuf, outLength, spec->mac_size);
01716            rv = SECSuccess;
01717        } else { /* is TLS */
01718 #define cx ((HMACContext *)write_mac_context)
01719            if (useServerMacKey) {
01720               rv = HMAC_Init(cx, hashObj, 
01721                             spec->server.write_mac_key_item.data,
01722                             spec->server.write_mac_key_item.len, PR_FALSE);
01723            } else {
01724               rv = HMAC_Init(cx, hashObj, 
01725                             spec->client.write_mac_key_item.data,
01726                             spec->client.write_mac_key_item.len, PR_FALSE);
01727            }
01728            if (rv == SECSuccess) {
01729               HMAC_Begin(cx);
01730               HMAC_Update(cx, temp, tempLen);
01731               HMAC_Update(cx, input, inputLength);
01732               rv = HMAC_Finish(cx, outbuf, outLength, spec->mac_size);
01733               HMAC_Destroy(cx, PR_FALSE);
01734            }
01735 #undef cx
01736        }
01737     }
01738 
01739     PORT_Assert(rv != SECSuccess || *outLength == (unsigned)spec->mac_size);
01740 
01741     PRINT_BUF(95, (NULL, "frag hash2: result", outbuf, *outLength));
01742 
01743     if (rv != SECSuccess) {
01744        rv = SECFailure;
01745        ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
01746     }
01747     return rv;
01748 }
01749 
01750 static PRBool
01751 ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
01752     PK11SlotInfo *slot = NULL;
01753     PRBool isPresent = PR_TRUE;
01754 
01755     /* we only care if we are doing client auth */
01756     if (!sid || !sid->u.ssl3.clAuthValid) {
01757        return PR_TRUE;
01758     }
01759 
01760     /* get the slot */
01761     slot = SECMOD_LookupSlot(sid->u.ssl3.clAuthModuleID,
01762                             sid->u.ssl3.clAuthSlotID);
01763     if (slot == NULL ||
01764        !PK11_IsPresent(slot) ||
01765        sid->u.ssl3.clAuthSeries     != PK11_GetSlotSeries(slot) ||
01766        sid->u.ssl3.clAuthSlotID     != PK11_GetSlotID(slot)     ||
01767        sid->u.ssl3.clAuthModuleID   != PK11_GetModuleID(slot)   ||
01768        (PK11_NeedLogin(slot) && !PK11_IsLoggedIn(slot, NULL))) {
01769        isPresent = PR_FALSE;
01770     } 
01771     if (slot) {
01772        PK11_FreeSlot(slot);
01773     }
01774     return isPresent;
01775 }
01776 
01777 static SECStatus
01778 ssl3_CompressMACEncryptRecord(sslSocket *        ss,
01779                               SSL3ContentType    type,
01780                             const SSL3Opaque * pIn,
01781                             PRUint32           contentLen)
01782 {
01783     ssl3CipherSpec *          cwSpec;
01784     const ssl3BulkCipherDef * cipher_def;
01785     sslBuffer      *          wrBuf         = &ss->sec.writeBuf;
01786     SECStatus                 rv;
01787     PRUint32                  macLen      = 0;
01788     PRUint32                  fragLen;
01789     PRUint32  p1Len, p2Len, oddLen = 0;
01790     PRInt32   cipherBytes =  0;
01791 
01792     /*
01793      * null compression is easy to do
01794     PORT_Memcpy(wrBuf->buf + SSL3_RECORD_HEADER_LENGTH, pIn, contentLen);
01795      */
01796 
01797     ssl_GetSpecReadLock(ss);       /********************************/
01798 
01799     cwSpec = ss->ssl3.cwSpec;
01800     cipher_def = cwSpec->cipher_def;
01801     /*
01802      * Add the MAC
01803      */
01804     rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer),
01805        type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen,
01806        wrBuf->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen);
01807     if (rv != SECSuccess) {
01808        ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
01809        goto spec_locked_loser;
01810     }
01811     p1Len   = contentLen;
01812     p2Len   = macLen;
01813     fragLen = contentLen + macLen; /* needs to be encrypted */
01814     PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024);
01815 
01816     /*
01817      * Pad the text (if we're doing a block cipher)
01818      * then Encrypt it
01819      */
01820     if (cipher_def->type == type_block) {
01821        unsigned char * pBuf;
01822        int             padding_length;
01823        int             i;
01824 
01825        oddLen = contentLen % cipher_def->block_size;
01826        /* Assume blockSize is a power of two */
01827        padding_length = cipher_def->block_size - 1 -
01828                      ((fragLen) & (cipher_def->block_size - 1));
01829        fragLen += padding_length + 1;
01830        PORT_Assert((fragLen % cipher_def->block_size) == 0);
01831 
01832        /* Pad according to TLS rules (also acceptable to SSL3). */
01833        pBuf = &wrBuf->buf[fragLen + SSL3_RECORD_HEADER_LENGTH - 1];
01834        for (i = padding_length + 1; i > 0; --i) {
01835            *pBuf-- = padding_length;
01836        }
01837        /* now, if contentLen is not a multiple of block size, fix it */
01838        p2Len = fragLen - p1Len;
01839     }
01840     if (p1Len < 256) {
01841        oddLen = p1Len;
01842        p1Len = 0;
01843     } else {
01844        p1Len -= oddLen;
01845     }
01846     if (oddLen) {
01847        p2Len += oddLen;
01848        PORT_Assert( (cipher_def->block_size < 2) || \
01849                    (p2Len % cipher_def->block_size) == 0);
01850        memcpy(wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len,
01851               pIn + p1Len, oddLen);
01852     }
01853     if (p1Len > 0) {
01854        rv = cwSpec->encode( cwSpec->encodeContext, 
01855            wrBuf->buf + SSL3_RECORD_HEADER_LENGTH, /* output */
01856            &cipherBytes,                           /* actual outlen */
01857            p1Len,                                  /* max outlen */
01858            pIn, p1Len);                      /* input, and inputlen */
01859        PORT_Assert(rv == SECSuccess && cipherBytes == p1Len);
01860        if (rv != SECSuccess || cipherBytes != p1Len) {
01861            PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
01862            goto spec_locked_loser;
01863        }
01864     }
01865     if (p2Len > 0) {
01866        PRInt32 cipherBytesPart2 = -1;
01867        rv = cwSpec->encode( cwSpec->encodeContext, 
01868            wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len,
01869            &cipherBytesPart2,          /* output and actual outLen */
01870            p2Len,                             /* max outlen */
01871            wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len,
01872            p2Len);                            /* input and inputLen*/
01873        PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len);
01874        if (rv != SECSuccess || cipherBytesPart2 != p2Len) {
01875            PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
01876            goto spec_locked_loser;
01877        }
01878        cipherBytes += cipherBytesPart2;
01879     }  
01880     PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024);
01881 
01882     ssl3_BumpSequenceNumber(&cwSpec->write_seq_num);
01883 
01884     wrBuf->len    = cipherBytes + SSL3_RECORD_HEADER_LENGTH;
01885     wrBuf->buf[0] = type;
01886     wrBuf->buf[1] = MSB(cwSpec->version);
01887     wrBuf->buf[2] = LSB(cwSpec->version);
01888     wrBuf->buf[3] = MSB(cipherBytes);
01889     wrBuf->buf[4] = LSB(cipherBytes);
01890 
01891     ssl_ReleaseSpecReadLock(ss); /************************************/
01892 
01893     return SECSuccess;
01894 
01895 spec_locked_loser:
01896     ssl_ReleaseSpecReadLock(ss);
01897     return SECFailure;
01898 }
01899 
01900 /* Process the plain text before sending it.
01901  * Returns the number of bytes of plaintext that were succesfully sent
01902  *     plus the number of bytes of plaintext that were copied into the
01903  *     output (write) buffer.
01904  * Returns SECFailure on a hard IO error, memory error, or crypto error.
01905  * Does NOT return SECWouldBlock.
01906  *
01907  * Notes on the use of the private ssl flags:
01908  * (no private SSL flags)
01909  *    Attempt to make and send SSL records for all plaintext
01910  *    If non-blocking and a send gets WOULD_BLOCK,
01911  *    or if the pending (ciphertext) buffer is not empty,
01912  *    then buffer remaining bytes of ciphertext into pending buf,
01913  *    and continue to do that for all succssive records until all
01914  *    bytes are used.
01915  * ssl_SEND_FLAG_FORCE_INTO_BUFFER
01916  *    As above, except this suppresses all write attempts, and forces
01917  *    all ciphertext into the pending ciphertext buffer.
01918  *
01919  */
01920 static PRInt32
01921 ssl3_SendRecord(   sslSocket *        ss,
01922                    SSL3ContentType    type,
01923                  const SSL3Opaque * pIn,   /* input buffer */
01924                  PRInt32            nIn,   /* bytes of input */
01925                  PRInt32            flags)
01926 {
01927     sslBuffer      *          wrBuf         = &ss->sec.writeBuf;
01928     SECStatus                 rv;
01929     PRInt32                   totalSent   = 0;
01930 
01931     SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
01932               SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
01933               nIn));
01934     PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn));
01935 
01936     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
01937 
01938     if (ss->ssl3.initialized == PR_FALSE) {
01939        /* This can happen on a server if the very first incoming record
01940        ** looks like a defective ssl3 record (e.g. too long), and we're
01941        ** trying to send an alert.
01942        */
01943        PR_ASSERT(type == content_alert);
01944        rv = ssl3_InitState(ss);
01945        if (rv != SECSuccess) {
01946            return SECFailure;      /* ssl3_InitState has set the error code. */
01947        }
01948     }
01949 
01950     /* check for Token Presence */
01951     if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
01952        PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
01953        return SECFailure;
01954     }
01955 
01956     while (nIn > 0) {
01957        PRUint32  contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH);
01958 
01959        if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) {
01960            PRInt32 newSpace = PR_MAX(wrBuf->space * 2, contentLen);
01961            newSpace = PR_MIN(newSpace, MAX_FRAGMENT_LENGTH);
01962            newSpace += SSL3_BUFFER_FUDGE;
01963            rv = sslBuffer_Grow(wrBuf, newSpace);
01964            if (rv != SECSuccess) {
01965               SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes",
01966                       SSL_GETPID(), ss->fd, newSpace));
01967               return SECFailure; /* sslBuffer_Grow set a memory error code. */
01968            }
01969        }
01970 
01971        rv = ssl3_CompressMACEncryptRecord( ss, type, pIn, contentLen);
01972        if (rv != SECSuccess)
01973            return SECFailure;
01974 
01975        pIn += contentLen;
01976        nIn -= contentLen;
01977        PORT_Assert( nIn >= 0 );
01978 
01979        PRINT_BUF(50, (ss, "send (encrypted) record data:", wrBuf->buf, wrBuf->len));
01980 
01981        /* If there's still some previously saved ciphertext,
01982         * or the caller doesn't want us to send the data yet,
01983         * then add all our new ciphertext to the amount previously saved.
01984         */
01985        if ((ss->pendingBuf.len > 0) ||
01986            (flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
01987 
01988            rv = ssl_SaveWriteData(ss, wrBuf->buf, wrBuf->len);
01989            if (rv != SECSuccess) {
01990               /* presumably a memory error, SEC_ERROR_NO_MEMORY */
01991               return SECFailure;
01992            }
01993            wrBuf->len = 0;  /* All cipher text is saved away. */
01994 
01995            if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
01996               PRInt32   sent;
01997               ss->handshakeBegun = 1;
01998               sent = ssl_SendSavedWriteData(ss);
01999               if (sent < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) {
02000                   ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
02001                   return SECFailure;
02002               }
02003               if (ss->pendingBuf.len) {
02004                   flags |= ssl_SEND_FLAG_FORCE_INTO_BUFFER;
02005               }
02006            }
02007        } else if (wrBuf->len > 0) {
02008            PRInt32   sent;
02009            ss->handshakeBegun = 1;
02010            sent = ssl_DefSend(ss, wrBuf->buf, wrBuf->len,
02011                             flags & ~ssl_SEND_FLAG_MASK);
02012            if (sent < 0) {
02013               if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
02014                   ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
02015                   return SECFailure;
02016               }
02017               /* we got PR_WOULD_BLOCK_ERROR, which means none was sent. */
02018               sent = 0;
02019            }
02020            wrBuf->len -= sent;
02021            if (wrBuf->len) {
02022               /* now take all the remaining unsent new ciphertext and 
02023                * append it to the buffer of previously unsent ciphertext.
02024                */
02025               rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len);
02026               if (rv != SECSuccess) {
02027                   /* presumably a memory error, SEC_ERROR_NO_MEMORY */
02028                   return SECFailure;
02029               }
02030            }
02031        }
02032        totalSent += contentLen;
02033     }
02034     return totalSent;
02035 }
02036 
02037 #define SSL3_PENDING_HIGH_WATER 1024
02038 
02039 /* Attempt to send the content of "in" in an SSL application_data record.
02040  * Returns "len" or SECFailure,   never SECWouldBlock, nor SECSuccess.
02041  */
02042 int
02043 ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
02044                       PRInt32 len, PRInt32 flags)
02045 {
02046     PRInt32   totalSent     = 0;
02047     PRInt32   discarded = 0;
02048 
02049     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
02050     if (len < 0 || !in) {
02051        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
02052        return SECFailure;
02053     }
02054 
02055     if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER &&
02056         !ssl_SocketIsBlocking(ss)) {
02057        PORT_Assert(!ssl_SocketIsBlocking(ss));
02058        PORT_SetError(PR_WOULD_BLOCK_ERROR);
02059        return SECFailure;
02060     }
02061 
02062     if (ss->appDataBuffered && len) {
02063        PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered));
02064        if (in[0] != (unsigned char)(ss->appDataBuffered)) {
02065            PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
02066            return SECFailure;
02067        }
02068        in++;
02069        len--;
02070        discarded = 1;
02071     }
02072     while (len > totalSent) {
02073        PRInt32   sent, toSend;
02074 
02075        if (totalSent > 0) {
02076            /*
02077             * The thread yield is intended to give the reader thread a
02078             * chance to get some cycles while the writer thread is in
02079             * the middle of a large application data write.  (See
02080             * Bugzilla bug 127740, comment #1.)
02081             */
02082            ssl_ReleaseXmitBufLock(ss);
02083            PR_Sleep(PR_INTERVAL_NO_WAIT); /* PR_Yield(); */
02084            ssl_GetXmitBufLock(ss);
02085        }
02086        toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH);
02087        sent = ssl3_SendRecord(ss, content_application_data, 
02088                               in + totalSent, toSend, flags);
02089        if (sent < 0) {
02090            if (totalSent > 0 && PR_GetError() == PR_WOULD_BLOCK_ERROR) {
02091               PORT_Assert(ss->lastWriteBlocked);
02092               break;
02093            }
02094            return SECFailure; /* error code set by ssl3_SendRecord */
02095        }
02096        totalSent += sent;
02097        if (ss->pendingBuf.len) {
02098            /* must be a non-blocking socket */
02099            PORT_Assert(!ssl_SocketIsBlocking(ss));
02100            PORT_Assert(ss->lastWriteBlocked);
02101            break;    
02102        }
02103     }
02104     if (ss->pendingBuf.len) {
02105        /* Must be non-blocking. */
02106        PORT_Assert(!ssl_SocketIsBlocking(ss));
02107        if (totalSent > 0) {
02108            ss->appDataBuffered = 0x100 | in[totalSent - 1];
02109        }
02110 
02111        totalSent = totalSent + discarded - 1;
02112        if (totalSent <= 0) {
02113            PORT_SetError(PR_WOULD_BLOCK_ERROR);
02114            totalSent = SECFailure;
02115        }
02116        return totalSent;
02117     } 
02118     ss->appDataBuffered = 0;
02119     return totalSent + discarded;
02120 }
02121 
02122 /* Attempt to send the content of sendBuf buffer in an SSL handshake record.
02123  * This function returns SECSuccess or SECFailure, never SECWouldBlock.
02124  * Always set sendBuf.len to 0, even when returning SECFailure.
02125  *
02126  * Called from SSL3_SendAlert(), ssl3_SendChangeCipherSpecs(),
02127  *             ssl3_AppendHandshake(), ssl3_SendClientHello(),
02128  *             ssl3_SendHelloRequest(), ssl3_SendServerHelloDone(),
02129  *             ssl3_SendFinished(),
02130  */
02131 static SECStatus
02132 ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags)
02133 {
02134     PRInt32 rv = SECSuccess;
02135 
02136     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
02137     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
02138 
02139     if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
02140        return rv;
02141 
02142     /* only this flag is allowed */
02143     PORT_Assert(!(flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER));
02144     if ((flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER) != 0) {
02145        PORT_SetError(SEC_ERROR_INVALID_ARGS);
02146        rv = SECFailure;
02147     } else {
02148        rv = ssl3_SendRecord(ss, content_handshake, ss->sec.ci.sendBuf.buf,
02149                           ss->sec.ci.sendBuf.len, flags);
02150     }
02151     if (rv < 0) { 
02152        int err = PORT_GetError();
02153        PORT_Assert(err != PR_WOULD_BLOCK_ERROR);
02154        if (err == PR_WOULD_BLOCK_ERROR) {
02155            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
02156        }
02157     } else if (rv < ss->sec.ci.sendBuf.len) {
02158        /* short write should never happen */
02159        PORT_Assert(rv >= ss->sec.ci.sendBuf.len);
02160        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
02161        rv = SECFailure;
02162     } else {
02163        rv = SECSuccess;
02164     }
02165 
02166     /* Whether we succeeded or failed, toss the old handshake data. */
02167     ss->sec.ci.sendBuf.len = 0;
02168     return rv;
02169 }
02170 
02171 /*
02172  * Called from ssl3_HandleAlert and from ssl3_HandleCertificate when
02173  * the remote client sends a negative response to our certificate request.
02174  * Returns SECFailure if the application has required client auth.
02175  *         SECSuccess otherwise.
02176  */
02177 static SECStatus
02178 ssl3_HandleNoCertificate(sslSocket *ss)
02179 {
02180     if (ss->sec.peerCert != NULL) {
02181        if (ss->sec.peerKey != NULL) {
02182            SECKEY_DestroyPublicKey(ss->sec.peerKey);
02183            ss->sec.peerKey = NULL;
02184        }
02185        CERT_DestroyCertificate(ss->sec.peerCert);
02186        ss->sec.peerCert = NULL;
02187     }
02188     ssl3_CleanupPeerCerts(ss);
02189 
02190     /* If the server has required client-auth blindly but doesn't
02191      * actually look at the certificate it won't know that no
02192      * certificate was presented so we shutdown the socket to ensure
02193      * an error.  We only do this if we haven't already completed the
02194      * first handshake because if we're redoing the handshake we 
02195      * know the server is paying attention to the certificate.
02196      */
02197     if ((ss->opt.requireCertificate == SSL_REQUIRE_ALWAYS) ||
02198        (!ss->firstHsDone && 
02199         (ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE))) {
02200        PRFileDesc * lower;
02201 
02202        ss->sec.uncache(ss->sec.ci.sid);
02203        SSL3_SendAlert(ss, alert_fatal, bad_certificate);
02204 
02205        lower = ss->fd->lower;
02206 #ifdef _WIN32
02207        lower->methods->shutdown(lower, PR_SHUTDOWN_SEND);
02208 #else
02209        lower->methods->shutdown(lower, PR_SHUTDOWN_BOTH);
02210 #endif
02211        PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
02212        return SECFailure;
02213     }
02214     return SECSuccess;
02215 }
02216 
02217 /************************************************************************
02218  * Alerts
02219  */
02220 
02221 /*
02222 ** Acquires both handshake and XmitBuf locks.
02223 ** Called from: ssl3_IllegalParameter     <-
02224 **              ssl3_HandshakeFailure     <-
02225 **              ssl3_HandleAlert   <- ssl3_HandleRecord.
02226 **              ssl3_HandleChangeCipherSpecs <- ssl3_HandleRecord
02227 **              ssl3_ConsumeHandshakeVariable <-
02228 **              ssl3_HandleHelloRequest   <-
02229 **              ssl3_HandleServerHello    <-
02230 **              ssl3_HandleServerKeyExchange <-
02231 **              ssl3_HandleCertificateRequest <-
02232 **              ssl3_HandleServerHelloDone <-
02233 **              ssl3_HandleClientHello    <-
02234 **              ssl3_HandleV2ClientHello <-
02235 **              ssl3_HandleCertificateVerify <-
02236 **              ssl3_HandleClientKeyExchange <-
02237 **              ssl3_HandleCertificate    <-
02238 **              ssl3_HandleFinished       <-
02239 **              ssl3_HandleHandshakeMessage <-
02240 **              ssl3_HandleRecord  <-
02241 **
02242 */
02243 SECStatus
02244 SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc)
02245 {
02246     uint8     bytes[2];
02247     SECStatus rv;
02248 
02249     SSL_TRC(3, ("%d: SSL3[%d]: send alert record, level=%d desc=%d",
02250               SSL_GETPID(), ss->fd, level, desc));
02251 
02252     bytes[0] = level;
02253     bytes[1] = desc;
02254 
02255     ssl_GetSSL3HandshakeLock(ss);
02256     if (level == alert_fatal) {
02257        if (ss->sec.ci.sid) {
02258            ss->sec.uncache(ss->sec.ci.sid);
02259        }
02260     }
02261     ssl_GetXmitBufLock(ss);
02262     rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
02263     if (rv == SECSuccess) {
02264        PRInt32 sent;
02265        sent = ssl3_SendRecord(ss, content_alert, bytes, 2, 
02266                             desc == no_certificate 
02267                             ? ssl_SEND_FLAG_FORCE_INTO_BUFFER : 0);
02268        rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
02269     }
02270     ssl_ReleaseXmitBufLock(ss);
02271     ssl_ReleaseSSL3HandshakeLock(ss);
02272     return rv;       /* error set by ssl3_FlushHandshake or ssl3_SendRecord */
02273 }
02274 
02275 /*
02276  * Send illegal_parameter alert.  Set generic error number.
02277  */
02278 static SECStatus
02279 ssl3_IllegalParameter(sslSocket *ss)
02280 {
02281     PRBool isTLS;
02282 
02283     isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
02284     (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
02285     PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
02286                                    : SSL_ERROR_BAD_SERVER );
02287     return SECFailure;
02288 }
02289 
02290 /*
02291  * Send handshake_Failure alert.  Set generic error number.
02292  */
02293 static SECStatus
02294 ssl3_HandshakeFailure(sslSocket *ss)
02295 {
02296     (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
02297     PORT_SetError( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
02298                                     : SSL_ERROR_BAD_SERVER );
02299     return SECFailure;
02300 }
02301 
02302 /*
02303  * Send handshake_Failure alert.  Set generic error number.
02304  */
02305 static SECStatus
02306 ssl3_DecodeError(sslSocket *ss)
02307 {
02308     (void)SSL3_SendAlert(ss, alert_fatal, 
02309                 ss->version > SSL_LIBRARY_VERSION_3_0 ? decode_error 
02310                                                  : illegal_parameter);
02311     PORT_SetError( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
02312                                     : SSL_ERROR_BAD_SERVER );
02313     return SECFailure;
02314 }
02315 
02316 /* Called from ssl3_HandleRecord.
02317 ** Caller must hold both RecvBuf and Handshake locks.
02318 */
02319 static SECStatus
02320 ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
02321 {
02322     SSL3AlertLevel       level;
02323     SSL3AlertDescription desc;
02324     int                  error;
02325 
02326     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
02327     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
02328 
02329     SSL_TRC(3, ("%d: SSL3[%d]: handle alert record", SSL_GETPID(), ss->fd));
02330 
02331     if (buf->len != 2) {
02332        (void)ssl3_DecodeError(ss);
02333        PORT_SetError(SSL_ERROR_RX_MALFORMED_ALERT);
02334        return SECFailure;
02335     }
02336     level = (SSL3AlertLevel)buf->buf[0];
02337     desc  = (SSL3AlertDescription)buf->buf[1];
02338     buf->len = 0;
02339     SSL_TRC(5, ("%d: SSL3[%d] received alert, level = %d, description = %d",
02340         SSL_GETPID(), ss->fd, level, desc));
02341 
02342     switch (desc) {
02343     case close_notify:             ss->recvdCloseNotify = 1;
02344                             error = SSL_ERROR_CLOSE_NOTIFY_ALERT;     break;
02345     case unexpected_message:       error = SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT;
02346                                                                  break;
02347     case bad_record_mac:    error = SSL_ERROR_BAD_MAC_ALERT;     break;
02348     case decryption_failed:        error = SSL_ERROR_DECRYPTION_FAILED_ALERT; 
02349                                                                  break;
02350     case record_overflow:   error = SSL_ERROR_RECORD_OVERFLOW_ALERT;  break;
02351     case decompression_failure: error = SSL_ERROR_DECOMPRESSION_FAILURE_ALERT;
02352                                                                  break;
02353     case handshake_failure:        error = SSL_ERROR_HANDSHAKE_FAILURE_ALERT;
02354                                                                  break;
02355     case no_certificate:    error = SSL_ERROR_NO_CERTIFICATE;    break;
02356     case bad_certificate:   error = SSL_ERROR_BAD_CERT_ALERT;    break;
02357     case unsupported_certificate:error = SSL_ERROR_UNSUPPORTED_CERT_ALERT;break;
02358     case certificate_revoked:      error = SSL_ERROR_REVOKED_CERT_ALERT;       break;
02359     case certificate_expired:      error = SSL_ERROR_EXPIRED_CERT_ALERT;       break;
02360     case certificate_unknown:      error = SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT;
02361                                                                  break;
02362     case illegal_parameter:        error = SSL_ERROR_ILLEGAL_PARAMETER_ALERT;break;
02363 
02364     /* All alerts below are TLS only. */
02365     case unknown_ca:               error = SSL_ERROR_UNKNOWN_CA_ALERT;       break;
02366     case access_denied:     error = SSL_ERROR_ACCESS_DENIED_ALERT;    break;
02367     case decode_error:             error = SSL_ERROR_DECODE_ERROR_ALERT;     break;
02368     case decrypt_error:     error = SSL_ERROR_DECRYPT_ERROR_ALERT;    break;
02369     case export_restriction:       error = SSL_ERROR_EXPORT_RESTRICTION_ALERT; 
02370                                                                  break;
02371     case protocol_version:  error = SSL_ERROR_PROTOCOL_VERSION_ALERT; break;
02372     case insufficient_security: error = SSL_ERROR_INSUFFICIENT_SECURITY_ALERT; 
02373                                                                  break;
02374     case internal_error:    error = SSL_ERROR_INTERNAL_ERROR_ALERT;   break;
02375     case user_canceled:     error = SSL_ERROR_USER_CANCELED_ALERT;    break;
02376     case no_renegotiation:  error = SSL_ERROR_NO_RENEGOTIATION_ALERT; break;
02377 
02378     /* Alerts for TLS client hello extensions */
02379     case unsupported_extension: 
02380                      error = SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT;    break;
02381     case certificate_unobtainable: 
02382                      error = SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT; break;
02383     case unrecognized_name: 
02384                      error = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;        break;
02385     case bad_certificate_status_response: 
02386                      error = SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT; break;
02387     case bad_certificate_hash_value: 
02388                      error = SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT;      break;
02389     default:         error = SSL_ERROR_RX_UNKNOWN_ALERT;               break;
02390     }
02391     if (level == alert_fatal) {
02392        ss->sec.uncache(ss->sec.ci.sid);
02393        if ((ss->ssl3.hs.ws == wait_server_hello) &&
02394            (desc == handshake_failure)) {
02395            /* XXX This is a hack.  We're assuming that any handshake failure
02396             * XXX on the client hello is a failure to match ciphers.
02397             */
02398            error = SSL_ERROR_NO_CYPHER_OVERLAP;
02399        }
02400        PORT_SetError(error);
02401        return SECFailure;
02402     }
02403     if ((desc == no_certificate) && (ss->ssl3.hs.ws == wait_client_cert)) {
02404        /* I'm a server. I've requested a client cert. He hasn't got one. */
02405        SECStatus rv;
02406 
02407        PORT_Assert(ss->sec.isServer);
02408        ss->ssl3.hs.ws = wait_client_key;
02409        rv = ssl3_HandleNoCertificate(ss);
02410        return rv;
02411     }
02412     return SECSuccess;
02413 }
02414 
02415 /*
02416  * Change Cipher Specs
02417  * Called from ssl3_HandleServerHelloDone,
02418  *             ssl3_HandleClientHello,
02419  * and         ssl3_HandleFinished
02420  *
02421  * Acquires and releases spec write lock, to protect switching the current
02422  * and pending write spec pointers.
02423  */
02424 
02425 static SECStatus
02426 ssl3_SendChangeCipherSpecs(sslSocket *ss)
02427 {
02428     uint8             change = change_cipher_spec_choice;
02429     ssl3CipherSpec *  pwSpec;
02430     SECStatus         rv;
02431     PRInt32           sent;
02432 
02433     SSL_TRC(3, ("%d: SSL3[%d]: send change_cipher_spec record",
02434               SSL_GETPID(), ss->fd));
02435 
02436     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
02437     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
02438 
02439     rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
02440     if (rv != SECSuccess) {
02441        return rv;    /* error code set by ssl3_FlushHandshake */
02442     }
02443     sent = ssl3_SendRecord(ss, content_change_cipher_spec, &change, 1,
02444                               ssl_SEND_FLAG_FORCE_INTO_BUFFER);
02445     if (sent < 0) {
02446        return (SECStatus)sent;     /* error code set by ssl3_SendRecord */
02447     }
02448 
02449     /* swap the pending and current write specs. */
02450     ssl_GetSpecWriteLock(ss);      /**************************************/
02451     pwSpec                     = ss->ssl3.pwSpec;
02452     pwSpec->write_seq_num.high = 0;
02453     pwSpec->write_seq_num.low  = 0;
02454 
02455     ss->ssl3.pwSpec = ss->ssl3.cwSpec;
02456     ss->ssl3.cwSpec = pwSpec;
02457 
02458     SSL_TRC(3, ("%d: SSL3[%d] Set Current Write Cipher Suite to Pending",
02459               SSL_GETPID(), ss->fd ));
02460 
02461     /* We need to free up the contexts, keys and certs ! */
02462     /* If we are really through with the old cipher spec
02463      * (Both the read and write sides have changed) destroy it.
02464      */
02465     if (ss->ssl3.prSpec == ss->ssl3.pwSpec) {
02466        ssl3_DestroyCipherSpec(ss->ssl3.pwSpec);
02467     }
02468     ssl_ReleaseSpecWriteLock(ss); /**************************************/
02469 
02470     return SECSuccess;
02471 }
02472 
02473 /* Called from ssl3_HandleRecord.
02474 ** Caller must hold both RecvBuf and Handshake locks.
02475  *
02476  * Acquires and releases spec write lock, to protect switching the current
02477  * and pending write spec pointers.
02478 */
02479 static SECStatus
02480 ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf)
02481 {
02482     ssl3CipherSpec *           prSpec;
02483     SSL3WaitState              ws      = ss->ssl3.hs.ws;
02484     SSL3ChangeCipherSpecChoice change;
02485 
02486     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
02487     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
02488 
02489     SSL_TRC(3, ("%d: SSL3[%d]: handle change_cipher_spec record",
02490               SSL_GETPID(), ss->fd));
02491 
02492     if (ws != wait_change_cipher) {
02493        (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
02494        PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
02495        return SECFailure;
02496     }
02497 
02498     if(buf->len != 1) {
02499        (void)ssl3_DecodeError(ss);
02500        PORT_SetError(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER);
02501        return SECFailure;
02502     }
02503     change = (SSL3ChangeCipherSpecChoice)buf->buf[0];
02504     if (change != change_cipher_spec_choice) {
02505        /* illegal_parameter is correct here for both SSL3 and TLS. */
02506        (void)ssl3_IllegalParameter(ss);
02507        PORT_SetError(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER);
02508        return SECFailure;
02509     }
02510     buf->len = 0;
02511 
02512     /* Swap the pending and current read specs. */
02513     ssl_GetSpecWriteLock(ss);   /*************************************/
02514     prSpec                    = ss->ssl3.prSpec;
02515     prSpec->read_seq_num.high = prSpec->read_seq_num.low = 0;
02516 
02517     ss->ssl3.prSpec  = ss->ssl3.crSpec;
02518     ss->ssl3.crSpec  = prSpec;
02519     ss->ssl3.hs.ws   = wait_finished;
02520 
02521     SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending",
02522               SSL_GETPID(), ss->fd ));
02523 
02524     /* If we are really through with the old cipher prSpec
02525      * (Both the read and write sides have changed) destroy it.
02526      */
02527     if (ss->ssl3.prSpec == ss->ssl3.pwSpec) {
02528        ssl3_DestroyCipherSpec(ss->ssl3.prSpec);
02529     }
02530     ssl_ReleaseSpecWriteLock(ss);   /*************************************/
02531     return SECSuccess;
02532 }
02533 
02534 /* This method uses PKCS11 to derive the MS from the PMS, where PMS 
02535 ** is a PKCS11 symkey. This is used in all cases except the 
02536 ** "triple bypass" with RSA key exchange.
02537 ** Called from ssl3_InitPendingCipherSpec.   prSpec is pwSpec.
02538 */
02539 static SECStatus
02540 ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
02541 {
02542     ssl3CipherSpec *  pwSpec = ss->ssl3.pwSpec;
02543     const ssl3KEADef *kea_def= ss->ssl3.hs.kea_def;
02544     unsigned char *   cr     = (unsigned char *)&ss->ssl3.hs.client_random;
02545     unsigned char *   sr     = (unsigned char *)&ss->ssl3.hs.server_random;
02546     PRBool            isTLS  = (PRBool)(kea_def->tls_keygen ||
02547                                 (pwSpec->version > SSL_LIBRARY_VERSION_3_0));
02548     /* 
02549      * Whenever isDH is true, we need to use CKM_TLS_MASTER_KEY_DERIVE_DH
02550      * which, unlike CKM_TLS_MASTER_KEY_DERIVE, converts arbitrary size
02551      * data into a 48-byte value. 
02552      */
02553     PRBool    isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) ||
02554                               (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh));
02555     SECStatus         rv = SECFailure;
02556     CK_MECHANISM_TYPE master_derive;
02557     CK_MECHANISM_TYPE key_derive;
02558     SECItem           params;
02559     CK_FLAGS          keyFlags;
02560     CK_VERSION        pms_version;
02561     CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params;
02562 
02563     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
02564     PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
02565     PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
02566     if (isTLS) {
02567        if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH;
02568        else master_derive = CKM_TLS_MASTER_KEY_DERIVE;
02569        key_derive    = CKM_TLS_KEY_AND_MAC_DERIVE;
02570        keyFlags      = CKF_SIGN | CKF_VERIFY;
02571     } else {
02572        if (isDH) master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH;
02573        else master_derive = CKM_SSL3_MASTER_KEY_DERIVE;
02574        key_derive    = CKM_SSL3_KEY_AND_MAC_DERIVE;
02575        keyFlags      = 0;
02576     }
02577 
02578     if (pms || !pwSpec->master_secret) {
02579        master_params.pVersion                     = &pms_version;
02580        master_params.RandomInfo.pClientRandom     = cr;
02581        master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
02582        master_params.RandomInfo.pServerRandom     = sr;
02583        master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
02584 
02585        params.data = (unsigned char *) &master_params;
02586        params.len  = sizeof master_params;
02587     }
02588 
02589     if (pms != NULL) {
02590 #if defined(TRACE)
02591        if (ssl_trace >= 100) {
02592            SECStatus extractRV = PK11_ExtractKeyValue(pms);
02593            if (extractRV == SECSuccess) {
02594               SECItem * keyData = PK11_GetKeyData(pms);
02595               if (keyData && keyData->data && keyData->len) {
02596                   ssl_PrintBuf(ss, "Pre-Master Secret", 
02597                              keyData->data, keyData->len);
02598               }
02599            }
02600        }
02601 #endif
02602        pwSpec->master_secret = PK11_DeriveWithFlags(pms, master_derive, 
02603                             &params, key_derive, CKA_DERIVE, 0, keyFlags);
02604        if (!isDH && pwSpec->master_secret && ss->opt.detectRollBack) {
02605            SSL3ProtocolVersion client_version;
02606            client_version = pms_version.major << 8 | pms_version.minor;
02607            if (client_version != ss->clientHelloVersion) {
02608               /* Destroy it.  Version roll-back detected. */
02609               PK11_FreeSymKey(pwSpec->master_secret);
02610               pwSpec->master_secret = NULL;
02611            }
02612        }
02613        if (pwSpec->master_secret == NULL) {
02614            /* Generate a faux master secret in the same slot as the old one. */
02615            PK11SlotInfo * slot = PK11_GetSlotFromKey((PK11SymKey *)pms);
02616            PK11SymKey *   fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot);
02617 
02618            PK11_FreeSlot(slot);
02619            if (fpms != NULL) {
02620               pwSpec->master_secret = PK11_DeriveWithFlags(fpms, 
02621                                    master_derive, &params, key_derive, 
02622                                    CKA_DERIVE, 0, keyFlags);
02623               PK11_FreeSymKey(fpms);
02624            }
02625        }
02626     }
02627     if (pwSpec->master_secret == NULL) {
02628        /* Generate a faux master secret from the internal slot. */
02629        PK11SlotInfo *  slot = PK11_GetInternalSlot();
02630        PK11SymKey *    fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot);
02631 
02632        PK11_FreeSlot(slot);
02633        if (fpms != NULL) {
02634            pwSpec->master_secret = PK11_DeriveWithFlags(fpms, 
02635                                    master_derive, &params, key_derive, 
02636                                    CKA_DERIVE, 0, keyFlags);
02637            if (pwSpec->master_secret == NULL) {
02638               pwSpec->master_secret = fpms; /* use the fpms as the master. */
02639               fpms = NULL;
02640            }
02641        }
02642        if (fpms) {
02643            PK11_FreeSymKey(fpms);
02644        }
02645     }
02646     if (pwSpec->master_secret == NULL) {
02647        ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
02648        return rv;
02649     }
02650     if (ss->opt.bypassPKCS11) {
02651        SECItem * keydata;
02652        /* In hope of doing a "double bypass", 
02653         * need to extract the master secret's value from the key object 
02654         * and store it raw in the sslSocket struct.
02655         */
02656        rv = PK11_ExtractKeyValue(pwSpec->master_secret);
02657        if (rv != SECSuccess) {
02658 #if defined(NSS_SURVIVE_DOUBLE_BYPASS_FAILURE)
02659            /* The double bypass failed.  
02660             * Attempt to revert to an all PKCS#11, non-bypass method.
02661             * Do we need any unacquired locks here?
02662             */
02663            ss->opt.bypassPKCS11 = 0;
02664            rv = ssl3_NewHandshakeHashes(ss);
02665            if (rv == SECSuccess) {
02666               rv = ssl3_UpdateHandshakeHashes(ss, ss->ssl3.hs.messages.buf, 
02667                                                   ss->ssl3.hs.messages.len);
02668            }
02669 #endif
02670            return rv;
02671        } 
02672        /* This returns the address of the secItem inside the key struct,
02673         * not a copy or a reference.  So, there's no need to free it.
02674         */
02675        keydata = PK11_GetKeyData(pwSpec->master_secret);
02676        if (keydata && keydata->len <= sizeof pwSpec->raw_master_secret) {
02677            memcpy(pwSpec->raw_master_secret, keydata->data, keydata->len);
02678            pwSpec->msItem.data = pwSpec->raw_master_secret;
02679            pwSpec->msItem.len  = keydata->len;
02680        } else {
02681            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
02682            return SECFailure;
02683        }
02684     }
02685     return SECSuccess;
02686 }
02687 
02688 
02689 /* 
02690  * Derive encryption and MAC Keys (and IVs) from master secret
02691  * Sets a useful error code when returning SECFailure.
02692  *
02693  * Called only from ssl3_InitPendingCipherSpec(),
02694  * which in turn is called from
02695  *              sendRSAClientKeyExchange        (for Full handshake)
02696  *              sendDHClientKeyExchange         (for Full handshake)
02697  *              ssl3_HandleClientKeyExchange    (for Full handshake)
02698  *              ssl3_HandleServerHello          (for session restart)
02699  *              ssl3_HandleClientHello          (for session restart)
02700  * Caller MUST hold the specWriteLock, and SSL3HandshakeLock.
02701  * ssl3_InitPendingCipherSpec does that.
02702  *
02703  */
02704 static SECStatus
02705 ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss)
02706 {
02707     ssl3CipherSpec *         pwSpec     = ss->ssl3.pwSpec;
02708     const ssl3KEADef *       kea_def    = ss->ssl3.hs.kea_def;
02709     unsigned char *   cr     = (unsigned char *)&ss->ssl3.hs.client_random;
02710     unsigned char *   sr     = (unsigned char *)&ss->ssl3.hs.server_random;
02711     PRBool            isTLS  = (PRBool)(kea_def->tls_keygen ||
02712                                 (pwSpec->version > SSL_LIBRARY_VERSION_3_0));
02713     /* following variables used in PKCS11 path */
02714     const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def;
02715     PK11SlotInfo *         slot   = NULL;
02716     PK11SymKey *           symKey = NULL;
02717     void *                 pwArg  = ss->pkcs11PinArg;
02718     int                    keySize;
02719     CK_SSL3_KEY_MAT_PARAMS key_material_params;
02720     CK_SSL3_KEY_MAT_OUT    returnedKeys;
02721     CK_MECHANISM_TYPE      key_derive;
02722     CK_MECHANISM_TYPE      bulk_mechanism;
02723     SSLCipherAlgorithm     calg;
02724     SECItem                params;
02725     PRBool         skipKeysAndIVs = (PRBool)(cipher_def->calg == calg_null);
02726 
02727     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
02728     PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
02729     PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
02730 
02731     if (!pwSpec->master_secret) {
02732        PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
02733        return SECFailure;
02734     }
02735     /*
02736      * generate the key material
02737      */
02738     key_material_params.ulMacSizeInBits = pwSpec->mac_size           * BPB;
02739     key_material_params.ulKeySizeInBits = cipher_def->secret_key_size* BPB;
02740     key_material_params.ulIVSizeInBits  = cipher_def->iv_size        * BPB;
02741 
02742     key_material_params.bIsExport = (CK_BBOOL)(kea_def->is_limited);
02743     /* was:   (CK_BBOOL)(cipher_def->keygen_mode != kg_strong); */
02744 
02745     key_material_params.RandomInfo.pClientRandom     = cr;
02746     key_material_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
02747     key_material_params.RandomInfo.pServerRandom     = sr;
02748     key_material_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
02749     key_material_params.pReturnedKeyMaterial         = &returnedKeys;
02750 
02751     returnedKeys.pIVClient = pwSpec->client.write_iv;
02752     returnedKeys.pIVServer = pwSpec->server.write_iv;
02753     keySize                = cipher_def->key_size;
02754 
02755     if (skipKeysAndIVs) {
02756        keySize                             = 0;
02757         key_material_params.ulKeySizeInBits = 0;
02758         key_material_params.ulIVSizeInBits  = 0;
02759        returnedKeys.pIVClient              = NULL;
02760        returnedKeys.pIVServer              = NULL;
02761     }
02762 
02763     calg = cipher_def->calg;
02764     PORT_Assert(     alg2Mech[calg].calg == calg);
02765     bulk_mechanism = alg2Mech[calg].cmech;
02766 
02767     params.data    = (unsigned char *)&key_material_params;
02768     params.len     = sizeof(key_material_params);
02769 
02770     if (isTLS) {
02771        key_derive    = CKM_TLS_KEY_AND_MAC_DERIVE;
02772     } else {
02773        key_derive    = CKM_SSL3_KEY_AND_MAC_DERIVE;
02774     }
02775 
02776     /* CKM_SSL3_KEY_AND_MAC_DERIVE is defined to set ENCRYPT, DECRYPT, and
02777      * DERIVE by DEFAULT */
02778     symKey = PK11_Derive(pwSpec->master_secret, key_derive, &params,
02779                          bulk_mechanism, CKA_ENCRYPT, keySize);
02780     if (!symKey) {
02781        ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
02782        return SECFailure;
02783     }
02784     /* we really should use the actual mac'ing mechanism here, but we
02785      * don't because these types are used to map keytype anyway and both
02786      * mac's map to the same keytype.
02787      */
02788     slot  = PK11_GetSlotFromKey(symKey);
02789 
02790     PK11_FreeSlot(slot); /* slot is held until the key is freed */
02791     pwSpec->client.write_mac_key =
02792        PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
02793            CKM_SSL3_SHA1_MAC, returnedKeys.hClientMacSecret, PR_TRUE, pwArg);
02794     if (pwSpec->client.write_mac_key == NULL ) {
02795        goto loser;   /* loser sets err */
02796     }
02797     pwSpec->server.write_mac_key =
02798        PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
02799            CKM_SSL3_SHA1_MAC, returnedKeys.hServerMacSecret, PR_TRUE, pwArg);
02800     if (pwSpec->server.write_mac_key == NULL ) {
02801        goto loser;   /* loser sets err */
02802     }
02803     if (!skipKeysAndIVs) {
02804        pwSpec->client.write_key =
02805               PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
02806                    bulk_mechanism, returnedKeys.hClientKey, PR_TRUE, pwArg);
02807        if (pwSpec->client.write_key == NULL ) {
02808            goto loser;      /* loser sets err */
02809        }
02810        pwSpec->server.write_key =
02811               PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
02812                    bulk_mechanism, returnedKeys.hServerKey, PR_TRUE, pwArg);
02813        if (pwSpec->server.write_key == NULL ) {
02814            goto loser;      /* loser sets err */
02815        }
02816     }
02817     PK11_FreeSymKey(symKey);
02818     return SECSuccess;
02819 
02820 
02821 loser:
02822     if (symKey) PK11_FreeSymKey(symKey);
02823     ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
02824     return SECFailure;
02825 }
02826 
02827 static SECStatus 
02828 ssl3_RestartHandshakeHashes(sslSocket *ss)
02829 {
02830     SECStatus rv = SECSuccess;
02831 
02832     if (ss->opt.bypassPKCS11) {
02833        ss->ssl3.hs.messages.len = 0;
02834        MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx);
02835        SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx);
02836     } else {
02837        rv = PK11_DigestBegin(ss->ssl3.hs.md5);
02838        if (rv != SECSuccess) {
02839            ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
02840            return rv;
02841        }
02842        rv = PK11_DigestBegin(ss->ssl3.hs.sha);
02843        if (rv != SECSuccess) {
02844            ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
02845            return rv;
02846        }
02847     }
02848     return rv;
02849 }
02850 
02851 static SECStatus
02852 ssl3_NewHandshakeHashes(sslSocket *ss)
02853 {
02854     PK11Context *md5  = NULL;
02855     PK11Context *sha  = NULL;
02856 
02857     /*
02858      * note: We should probably lookup an SSL3 slot for these
02859      * handshake hashes in hopes that we wind up with the same slots
02860      * that the master secret will wind up in ...
02861      */
02862     SSL_TRC(30,("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd));
02863     if (ss->opt.bypassPKCS11) {
02864        PORT_Assert(!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space);
02865        ss->ssl3.hs.messages.buf = NULL;
02866        ss->ssl3.hs.messages.space = 0;
02867     } else {
02868        ss->ssl3.hs.md5 = md5 = PK11_CreateDigestContext(SEC_OID_MD5);
02869        ss->ssl3.hs.sha = sha = PK11_CreateDigestContext(SEC_OID_SHA1);
02870        if (md5 == NULL) {
02871            ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
02872            goto loser;
02873        }
02874        if (sha == NULL) {
02875            ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
02876            goto loser;
02877        }
02878     }
02879     if (SECSuccess == ssl3_RestartHandshakeHashes(ss)) {
02880        return SECSuccess;
02881     }
02882 
02883 loser:
02884     if (md5 != NULL) {
02885        PK11_DestroyContext(md5, PR_TRUE);
02886        ss->ssl3.hs.md5 = NULL;
02887     }
02888     if (sha != NULL) {
02889        PK11_DestroyContext(sha, PR_TRUE);
02890        ss->ssl3.hs.sha = NULL;
02891     }
02892     return SECFailure;
02893 
02894 }
02895 
02896 /*
02897  * Handshake messages
02898  */
02899 /* Called from       ssl3_AppendHandshake()
02900 **            ssl3_StartHandshakeHash()
02901 **            ssl3_HandleV2ClientHello()
02902 **            ssl3_HandleHandshakeMessage()
02903 ** Caller must hold the ssl3Handshake lock.
02904 */
02905 static SECStatus
02906 ssl3_UpdateHandshakeHashes(sslSocket *ss, unsigned char *b, unsigned int l)
02907 {
02908     SECStatus  rv = SECSuccess;
02909 
02910     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
02911 
02912     PRINT_BUF(90, (NULL, "MD5 & SHA handshake hash input:", b, l));
02913 
02914     if (ss->opt.bypassPKCS11) {
02915        MD5_Update((MD5Context *)ss->ssl3.hs.md5_cx, b, l);
02916        SHA1_Update((SHA1Context *)ss->ssl3.hs.sha_cx, b, l);
02917 #if defined(NSS_SURVIVE_DOUBLE_BYPASS_FAILURE)
02918        rv = sslBuffer_Append(&ss->ssl3.hs.messages, b, l);
02919 #endif
02920        return rv;
02921     }
02922     rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
02923     if (rv != SECSuccess) {
02924        ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
02925        return rv;
02926     }
02927     rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
02928     if (rv != SECSuccess) {
02929        ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
02930        return rv;
02931     }
02932     return rv;
02933 }
02934 
02935 /**************************************************************************
02936  * Append Handshake functions.
02937  * All these functions set appropriate error codes.
02938  * Most rely on ssl3_AppendHandshake to set the error code.
02939  **************************************************************************/
02940 SECStatus
02941 ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes)
02942 {
02943     unsigned char *  src  = (unsigned char *)void_src;
02944     int              room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len;
02945     SECStatus        rv;
02946 
02947     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); /* protects sendBuf. */
02948 
02949     if (ss->sec.ci.sendBuf.space < MAX_SEND_BUF_LENGTH && room < bytes) {
02950        rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, PR_MAX(MIN_SEND_BUF_LENGTH,
02951                PR_MIN(MAX_SEND_BUF_LENGTH, ss->sec.ci.sendBuf.len + bytes)));
02952        if (rv != SECSuccess)
02953            return rv;       /* sslBuffer_Grow has set a memory error code. */
02954        room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len;
02955     }
02956 
02957     PRINT_BUF(60, (ss, "Append to Handshake", (unsigned char*)void_src, bytes));
02958     rv = ssl3_UpdateHandshakeHashes(ss, src, bytes);
02959     if (rv != SECSuccess)
02960        return rv;    /* error code set by ssl3_UpdateHandshakeHashes */
02961 
02962     while (bytes > room) {
02963        if (room > 0)
02964            PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, 
02965                        room);
02966        ss->sec.ci.sendBuf.len += room;
02967        rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
02968        if (rv != SECSuccess) {
02969            return rv;       /* error code set by ssl3_FlushHandshake */
02970        }
02971        bytes -= room;
02972        src += room;
02973        room = ss->sec.ci.sendBuf.space;
02974        PORT_Assert(ss->sec.ci.sendBuf.len == 0);
02975     }
02976     PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, bytes);
02977     ss->sec.ci.sendBuf.len += bytes;
02978     return SECSuccess;
02979 }
02980 
02981 SECStatus
02982 ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize)
02983 {
02984     SECStatus rv;
02985     uint8     b[4];
02986     uint8 *   p = b;
02987 
02988     switch (lenSize) {
02989       case 4:
02990        *p++ = (num >> 24) & 0xff;
02991       case 3:
02992        *p++ = (num >> 16) & 0xff;
02993       case 2:
02994        *p++ = (num >> 8) & 0xff;
02995       case 1:
02996        *p = num & 0xff;
02997     }
02998     SSL_TRC(60, ("%d: number:", SSL_GETPID()));
02999     rv = ssl3_AppendHandshake(ss, &b[0], lenSize);
03000     return rv;       /* error code set by AppendHandshake, if applicable. */
03001 }
03002 
03003 SECStatus
03004 ssl3_AppendHandshakeVariable(
03005     sslSocket *ss, const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize)
03006 {
03007     SECStatus rv;
03008 
03009     PORT_Assert((bytes < (1<<8) && lenSize == 1) ||
03010              (bytes < (1L<<16) && lenSize == 2) ||
03011              (bytes < (1L<<24) && lenSize == 3));
03012 
03013     SSL_TRC(60,("%d: append variable:", SSL_GETPID()));
03014     rv = ssl3_AppendHandshakeNumber(ss, bytes, lenSize);
03015     if (rv != SECSuccess) {
03016        return rv;    /* error code set by AppendHandshake, if applicable. */
03017     }
03018     SSL_TRC(60, ("data:"));
03019     rv = ssl3_AppendHandshake(ss, src, bytes);
03020     return rv;       /* error code set by AppendHandshake, if applicable. */
03021 }
03022 
03023 SECStatus
03024 ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length)
03025 {
03026     SECStatus rv;
03027 
03028     SSL_TRC(30,("%d: SSL3[%d]: append handshake header: type %s",
03029        SSL_GETPID(), ss->fd, ssl3_DecodeHandshakeType(t)));
03030     PRINT_BUF(60, (ss, "MD5 handshake hash:",
03031                  (unsigned char*)ss->ssl3.hs.md5_cx, MD5_LENGTH));
03032     PRINT_BUF(95, (ss, "SHA handshake hash:",
03033                  (unsigned char*)ss->ssl3.hs.sha_cx, SHA1_LENGTH));
03034 
03035     rv = ssl3_AppendHandshakeNumber(ss, t, 1);
03036     if (rv != SECSuccess) {
03037        return rv;    /* error code set by AppendHandshake, if applicable. */
03038     }
03039     rv = ssl3_AppendHandshakeNumber(ss, length, 3);
03040     return rv;              /* error code set by AppendHandshake, if applicable. */
03041 }
03042 
03043 /**************************************************************************
03044  * Consume Handshake functions.
03045  *
03046  * All data used in these functions is protected by two locks,
03047  * the RecvBufLock and the SSL3HandshakeLock
03048  **************************************************************************/
03049 
03050 /* Read up the next "bytes" number of bytes from the (decrypted) input
03051  * stream "b" (which is *length bytes long). Copy them into buffer "v".
03052  * Reduces *length by bytes.  Advances *b by bytes.
03053  *
03054  * If this function returns SECFailure, it has already sent an alert,
03055  * and has set a generic error code.  The caller should probably
03056  * override the generic error code by setting another.
03057  */
03058 SECStatus
03059 ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b,
03060                     PRUint32 *length)
03061 {
03062     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
03063     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
03064 
03065     if ((PRUint32)bytes > *length) {
03066        return ssl3_DecodeError(ss);
03067     }
03068     PORT_Memcpy(v, *b, bytes);
03069     PRINT_BUF(60, (ss, "consume bytes:", *b, bytes));
03070     *b      += bytes;
03071     *length -= bytes;
03072     return SECSuccess;
03073 }
03074 
03075 /* Read up the next "bytes" number of bytes from the (decrypted) input
03076  * stream "b" (which is *length bytes long), and interpret them as an
03077  * integer in network byte order.  Returns the received value.
03078  * Reduces *length by bytes.  Advances *b by bytes.
03079  *
03080  * Returns SECFailure (-1) on failure.
03081  * This value is indistinguishable from the equivalent received value.
03082  * Only positive numbers are to be received this way.
03083  * Thus, the largest value that may be sent this way is 0x7fffffff.
03084  * On error, an alert has been sent, and a generic error code has been set.
03085  */
03086 PRInt32
03087 ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b,
03088                          PRUint32 *length)
03089 {
03090     uint8     *buf = *b;
03091     int       i;
03092     PRInt32   num = 0;
03093 
03094     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
03095     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
03096     PORT_Assert( bytes <= sizeof num);
03097 
03098     if ((PRUint32)bytes > *length) {
03099        return ssl3_DecodeError(ss);
03100     }
03101     PRINT_BUF(60, (ss, "consume bytes:", *b, bytes));
03102 
03103     for (i = 0; i < bytes; i++)
03104        num = (num << 8) + buf[i];
03105     *b      += bytes;
03106     *length -= bytes;
03107     return num;
03108 }
03109 
03110 /* Read in two values from the incoming decrypted byte stream "b", which is
03111  * *length bytes long.  The first value is a number whose size is "bytes"
03112  * bytes long.  The second value is a byte-string whose size is the value
03113  * of the first number received.  The latter byte-string, and its length,
03114  * is returned in the SECItem i.
03115  *
03116  * Returns SECFailure (-1) on failure.
03117  * On error, an alert has been sent, and a generic error code has been set.
03118  *
03119  * RADICAL CHANGE for NSS 3.11.  All callers of this function make copies 
03120  * of the data returned in the SECItem *i, so making a copy of it here
03121  * is simply wasteful.  So, This function now just sets SECItem *i to 
03122  * point to the values in the buffer **b.
03123  */
03124 SECStatus
03125 ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes,
03126                            SSL3Opaque **b, PRUint32 *length)
03127 {
03128     PRInt32   count;
03129 
03130     PORT_Assert(bytes <= 3);
03131     i->len  = 0;
03132     i->data = NULL;
03133     count = ssl3_ConsumeHandshakeNumber(ss, bytes, b, length);
03134     if (count < 0) {               /* Can't test for SECSuccess here. */
03135        return SECFailure;
03136     }
03137     if (count > 0) {
03138        if ((PRUint32)count > *length) {
03139            return ssl3_DecodeError(ss);
03140        }
03141        i->data = *b;
03142        i->len  = count;
03143        *b      += count;
03144        *length -= count;
03145     }
03146     return SECSuccess;
03147 }
03148 
03149 /**************************************************************************
03150  * end of Consume Handshake functions.
03151  **************************************************************************/
03152 
03153 /* Extract the hashes of handshake messages to this point.
03154  * Called from ssl3_SendCertificateVerify
03155  *             ssl3_SendFinished
03156  *             ssl3_HandleHandshakeMessage
03157  *
03158  * Caller must hold the SSL3HandshakeLock.
03159  * Caller must hold a read or write lock on the Spec R/W lock.
03160  *     (There is presently no way to assert on a Read lock.)
03161  */
03162 static SECStatus
03163 ssl3_ComputeHandshakeHashes(sslSocket *     ss,
03164                             ssl3CipherSpec *spec,   /* uses ->master_secret */
03165                          SSL3Hashes *    hashes, /* output goes here. */
03166                          uint32          sender)
03167 {
03168     SECStatus     rv        = SECSuccess;
03169     PRBool        isTLS     = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0);
03170     unsigned int  outLength;
03171     SSL3Opaque    md5_inner[MAX_MAC_LENGTH];
03172     SSL3Opaque    sha_inner[MAX_MAC_LENGTH];
03173 
03174     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
03175 
03176     if (ss->opt.bypassPKCS11) {
03177        /* compute them without PKCS11 */
03178        PRUint64      md5_cx[MAX_MAC_CONTEXT_LLONGS];
03179        PRUint64      sha_cx[MAX_MAC_CONTEXT_LLONGS];
03180 
03181 #define md5cx ((MD5Context *)md5_cx)
03182 #define shacx ((SHA1Context *)sha_cx)
03183 
03184        if (!spec->msItem.data) {
03185            PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
03186            return SECFailure;
03187        }
03188 
03189        MD5_Clone (md5cx,  (MD5Context *)ss->ssl3.hs.md5_cx);
03190        SHA1_Clone(shacx, (SHA1Context *)ss->ssl3.hs.sha_cx);
03191 
03192        if (!isTLS) {
03193            /* compute hashes for SSL3. */
03194            unsigned char s[4];
03195 
03196            s[0] = (unsigned char)(sender >> 24);
03197            s[1] = (unsigned char)(sender >> 16);
03198            s[2] = (unsigned char)(sender >> 8);
03199            s[3] = (unsigned char)sender;
03200 
03201            if (sender != 0) {
03202               MD5_Update(md5cx, s, 4);
03203               PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4));
03204            }
03205 
03206            PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1, 
03207                          mac_defs[mac_md5].pad_size));
03208 
03209            MD5_Update(md5cx, spec->msItem.data, spec->msItem.len);
03210            MD5_Update(md5cx, mac_pad_1, mac_defs[mac_md5].pad_size);
03211            MD5_End(md5cx, md5_inner, &outLength, MD5_LENGTH);
03212 
03213            PRINT_BUF(95, (NULL, "MD5 inner: result", md5_inner, outLength));
03214 
03215            if (sender != 0) {
03216               SHA1_Update(shacx, s, 4);
03217               PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4));
03218            }
03219 
03220            PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1, 
03221                          mac_defs[mac_sha].pad_size));
03222 
03223            SHA1_Update(shacx, spec->msItem.data, spec->msItem.len);
03224            SHA1_Update(shacx, mac_pad_1, mac_defs[mac_sha].pad_size);
03225            SHA1_End(shacx, sha_inner, &outLength, SHA1_LENGTH);
03226 
03227            PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength));
03228            PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2, 
03229                          mac_defs[mac_md5].pad_size));
03230            PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH));
03231 
03232            MD5_Begin(md5cx);
03233            MD5_Update(md5cx, spec->msItem.data, spec->msItem.len);
03234            MD5_Update(md5cx, mac_pad_2, mac_defs[mac_md5].pad_size);
03235            MD5_Update(md5cx, md5_inner, MD5_LENGTH);
03236        }
03237        MD5_End(md5cx, hashes->md5, &outLength, MD5_LENGTH);
03238 
03239        PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->md5, MD5_LENGTH));
03240 
03241        if (!isTLS) {
03242            PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2, 
03243                          mac_defs[mac_sha].pad_size));
03244            PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH));
03245 
03246            SHA1_Begin(shacx);
03247            SHA1_Update(shacx, spec->msItem.data, spec->msItem.len);
03248            SHA1_Update(shacx, mac_pad_2, mac_defs[mac_sha].pad_size);
03249            SHA1_Update(shacx, sha_inner, SHA1_LENGTH);
03250        }
03251        SHA1_End(shacx, hashes->sha, &outLength, SHA1_LENGTH);
03252 
03253        PRINT_BUF(60, (NULL, "SHA outer: result", hashes->sha, SHA1_LENGTH));
03254 
03255        rv = SECSuccess;
03256 #undef md5cx
03257 #undef shacx
03258     } else {
03259        /* compute hases with PKCS11 */
03260        PK11Context * md5;
03261        PK11Context * sha       = NULL;
03262        unsigned char *md5StateBuf = NULL;
03263        unsigned char *shaStateBuf = NULL;
03264        unsigned int  md5StateLen, shaStateLen;
03265        unsigned char md5StackBuf[256];
03266        unsigned char shaStackBuf[512];
03267 
03268        if (!spec->master_secret) {
03269            PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
03270            return SECFailure;
03271        }
03272 
03273        md5StateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.md5, md5StackBuf,
03274                                        sizeof md5StackBuf, &md5StateLen);
03275        if (md5StateBuf == NULL) {
03276            ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
03277            goto loser;
03278        }
03279        md5 = ss->ssl3.hs.md5;
03280 
03281        shaStateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.sha, shaStackBuf,
03282                                        sizeof shaStackBuf, &shaStateLen);
03283        if (shaStateBuf == NULL) {
03284            ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
03285            goto loser;
03286        }
03287        sha = ss->ssl3.hs.sha;
03288 
03289        if (!isTLS) {
03290            /* compute hashes for SSL3. */
03291            unsigned char s[4];
03292 
03293            s[0] = (unsigned char)(sender >> 24);
03294            s[1] = (unsigned char)(sender >> 16);
03295            s[2] = (unsigned char)(sender >> 8);
03296            s[3] = (unsigned char)sender;
03297 
03298            if (sender != 0) {
03299               rv |= PK11_DigestOp(md5, s, 4);
03300               PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4));
03301            }
03302 
03303            PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1, 
03304                        mac_defs[mac_md5].pad_size));
03305 
03306            rv |= PK11_DigestKey(md5,spec->master_secret);
03307            rv |= PK11_DigestOp(md5, mac_pad_1, mac_defs[mac_md5].pad_size);
03308            rv |= PK11_DigestFinal(md5, md5_inner, &outLength, MD5_LENGTH);
03309            PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH);
03310            if (rv != SECSuccess) {
03311               ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
03312               rv = SECFailure;
03313               goto loser;
03314            }
03315 
03316            PRINT_BUF(95, (NULL, "MD5 inner: result", md5_inner, outLength));
03317 
03318            if (sender != 0) {
03319               rv |= PK11_DigestOp(sha, s, 4);
03320               PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4));
03321            }
03322 
03323            PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1, 
03324                        mac_defs[mac_sha].pad_size));
03325 
03326            rv |= PK11_DigestKey(sha, spec->master_secret);
03327            rv |= PK11_DigestOp(sha, mac_pad_1, mac_defs[mac_sha].pad_size);
03328            rv |= PK11_DigestFinal(sha, sha_inner, &outLength, SHA1_LENGTH);
03329            PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH);
03330            if (rv != SECSuccess) {
03331               ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
03332               rv = SECFailure;
03333               goto loser;
03334            }
03335 
03336            PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength));
03337 
03338            PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2, 
03339                        mac_defs[mac_md5].pad_size));
03340            PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH));
03341 
03342            rv |= PK11_DigestBegin(md5);
03343            rv |= PK11_DigestKey(md5, spec->master_secret);
03344            rv |= PK11_DigestOp(md5, mac_pad_2, mac_defs[mac_md5].pad_size);
03345            rv |= PK11_DigestOp(md5, md5_inner, MD5_LENGTH);
03346        }
03347        rv |= PK11_DigestFinal(md5, hashes->md5, &outLength, MD5_LENGTH);
03348        PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH);
03349        if (rv != SECSuccess) {
03350            ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
03351            rv = SECFailure;
03352            goto loser;
03353        }
03354 
03355        PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->md5, MD5_LENGTH));
03356 
03357        if (!isTLS) {
03358            PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2, 
03359                        mac_defs[mac_sha].pad_size));
03360            PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH));
03361 
03362            rv |= PK11_DigestBegin(sha);
03363            rv |= PK11_DigestKey(sha,spec->master_secret);
03364            rv |= PK11_DigestOp(sha, mac_pad_2, mac_defs[mac_sha].pad_size);
03365            rv |= PK11_DigestOp(sha, sha_inner, SHA1_LENGTH);
03366        }
03367        rv |= PK11_DigestFinal(sha, hashes->sha, &outLength, SHA1_LENGTH);
03368        PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH);
03369        if (rv != SECSuccess) {
03370            ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
03371            rv = SECFailure;
03372            goto loser;
03373        }
03374 
03375        PRINT_BUF(60, (NULL, "SHA outer: result", hashes->sha, SHA1_LENGTH));
03376 
03377        rv = SECSuccess;
03378 
03379     loser:
03380        if (md5StateBuf) {
03381            if (PK11_RestoreContext(ss->ssl3.hs.md5, md5StateBuf, md5StateLen)
03382                != SECSuccess) 
03383            {
03384               ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
03385               rv = SECFailure;
03386            }
03387            if (md5StateBuf != md5StackBuf) {
03388               PORT_ZFree(md5StateBuf, md5StateLen);
03389            }
03390        }
03391        if (shaStateBuf) {
03392            if (PK11_RestoreContext(ss->ssl3.hs.sha, shaStateBuf, shaStateLen)
03393                != SECSuccess) 
03394            {
03395               ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
03396               rv = SECFailure;
03397            }
03398            if (shaStateBuf != shaStackBuf) {
03399               PORT_ZFree(shaStateBuf, shaStateLen);
03400            }
03401        }
03402     }
03403     return rv;
03404 }
03405 
03406 /*
03407  * SSL 2 based implementations pass in the initial outbound buffer
03408  * so that the handshake hash can contain the included information.
03409  *
03410  * Called from ssl2_BeginClientHandshake() in sslcon.c
03411  */
03412 SECStatus
03413 ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length)
03414 {
03415     SECStatus rv;
03416 
03417     ssl_GetSSL3HandshakeLock(ss);  /**************************************/
03418 
03419     rv = ssl3_InitState(ss);
03420     if (rv != SECSuccess) {
03421        goto done;           /* ssl3_InitState has set the error code. */
03422     }
03423 
03424     PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
03425     PORT_Memcpy(
03426        &ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH - SSL_CHALLENGE_BYTES],
03427        &ss->sec.ci.clientChallenge,
03428        SSL_CHALLENGE_BYTES);
03429 
03430     rv = ssl3_UpdateHandshakeHashes(ss, buf, length);
03431     /* if it failed, ssl3_UpdateHandshakeHashes has set the error code. */
03432 
03433 done:
03434     ssl_ReleaseSSL3HandshakeLock(ss);  /**************************************/
03435     return rv;
03436 }
03437 
03438 /**************************************************************************
03439  * end of Handshake Hash functions.
03440  * Begin Send and Handle functions for handshakes.
03441  **************************************************************************/
03442 
03443 /* Called from ssl3_HandleHelloRequest(),
03444  *             ssl3_HandleFinished() (for step-up)
03445  *             ssl3_RedoHandshake()
03446  *             ssl2_BeginClientHandshake (when resuming ssl3 session)
03447  */
03448 SECStatus
03449 ssl3_SendClientHello(sslSocket *ss)
03450 {
03451     sslSessionID *   sid;
03452     ssl3CipherSpec * cwSpec;
03453     SECStatus        rv;
03454     int              i;
03455     int              length;
03456     int              num_suites;
03457     int              actual_count = 0;
03458     PRInt32          total_exten_len = 0;
03459 
03460     SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(),
03461               ss->fd));
03462 
03463     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
03464     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
03465 
03466     rv = ssl3_InitState(ss);
03467     if (rv != SECSuccess) {
03468        return rv;           /* ssl3_InitState has set the error code. */
03469     }
03470 
03471     SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
03472            SSL_GETPID(), ss->fd ));
03473     rv = ssl3_RestartHandshakeHashes(ss);
03474     if (rv != SECSuccess) {
03475        return rv;
03476     }
03477 
03478     /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup
03479      * handles expired entries and other details.
03480      * XXX If we've been called from ssl2_BeginClientHandshake, then
03481      * this lookup is duplicative and wasteful.
03482      */
03483     sid = (ss->opt.noCache) ? NULL
03484            : ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url);
03485 
03486     /* We can't resume based on a different token. If the sid exists,
03487      * make sure the token that holds the master secret still exists ...
03488      * If we previously did client-auth, make sure that the token that holds
03489      * the private key still exists, is logged in, hasn't been removed, etc.
03490      */
03491     if (sid) {
03492        PRBool sidOK = PR_TRUE;
03493        if (sid->u.ssl3.keys.msIsWrapped) {
03494            /* Session key was wrapped, which means it was using PKCS11, */
03495            PK11SlotInfo *slot = NULL;
03496            if (sid->u.ssl3.masterValid && !ss->opt.bypassPKCS11) {
03497               slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
03498                                     sid->u.ssl3.masterSlotID);
03499            }
03500            if (slot == NULL) {
03501               sidOK = PR_FALSE;
03502            } else {
03503               PK11SymKey *wrapKey = NULL;
03504               if (!PK11_IsPresent(slot) ||
03505                   ((wrapKey = PK11_GetWrapKey(slot, 
03506                                           sid->u.ssl3.masterWrapIndex,
03507                                           sid->u.ssl3.masterWrapMech,
03508                                           sid->u.ssl3.masterWrapSeries,
03509                                           ss->pkcs11PinArg)) == NULL) ) {
03510                   sidOK = PR_FALSE;
03511               }
03512               if (wrapKey) PK11_FreeSymKey(wrapKey);
03513               PK11_FreeSlot(slot);
03514               slot = NULL;
03515            }
03516        }
03517        /* If we previously did client-auth, make sure that the token that
03518        ** holds the private key still exists, is logged in, hasn't been
03519        ** removed, etc.
03520        */
03521        if (sidOK && !ssl3_ClientAuthTokenPresent(sid)) {
03522            sidOK = PR_FALSE;
03523        }
03524 
03525        if (!sidOK) {
03526            SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok );
03527            (*ss->sec.uncache)(sid);
03528            ssl_FreeSID(sid);
03529            sid = NULL;
03530        }
03531     }
03532 
03533     if (sid) {
03534        SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );
03535 
03536        rv = ssl3_NegotiateVersion(ss, sid->version);
03537        if (rv != SECSuccess)
03538            return rv;       /* error code was set */
03539 
03540        PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
03541                     sid->u.ssl3.sessionIDLength));
03542 
03543        ss->ssl3.policy = sid->u.ssl3.policy;
03544     } else {
03545        SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses );
03546 
03547        rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_3_1_TLS);
03548        if (rv != SECSuccess)
03549            return rv;       /* error code was set */
03550 
03551        sid = ssl3_NewSessionID(ss, PR_FALSE);
03552        if (!sid) {
03553            return SECFailure;      /* memory error is set */
03554         }
03555     }
03556 
03557     ssl_GetSpecWriteLock(ss);
03558     cwSpec = ss->ssl3.cwSpec;
03559     if (cwSpec->mac_def->mac == mac_null) {
03560        /* SSL records are not being MACed. */
03561        cwSpec->version = ss->version;
03562     }
03563     ssl_ReleaseSpecWriteLock(ss);
03564 
03565     if (ss->sec.ci.sid != NULL) {
03566        ssl_FreeSID(ss->sec.ci.sid);       /* decrement ref count, free if zero */
03567     }
03568     ss->sec.ci.sid = sid;
03569 
03570     ss->sec.send = ssl3_SendApplicationData;
03571 
03572     /* shouldn't get here if SSL3 is disabled, but ... */
03573     PORT_Assert(ss->opt.enableSSL3 || ss->opt.enableTLS);
03574     if (!ss->opt.enableSSL3 && !ss->opt.enableTLS) {
03575        PORT_SetError(SSL_ERROR_SSL_DISABLED);
03576        return SECFailure;
03577     }
03578 
03579     /* how many suites does our PKCS11 support (regardless of policy)? */
03580     num_suites = ssl3_config_match_init(ss);
03581     if (!num_suites)
03582        return SECFailure;   /* ssl3_config_match_init has set error code. */
03583 
03584     if (ss->opt.enableTLS && ss->version > SSL_LIBRARY_VERSION_3_0) {
03585        PRUint32 maxBytes = 65535; /* 2^16 - 1 */
03586        PRInt32  extLen;
03587 
03588        extLen = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, NULL);
03589        if (extLen < 0) {
03590            return SECFailure;
03591        }
03592        maxBytes        -= extLen;
03593        total_exten_len += extLen;
03594 
03595        if (total_exten_len > 0)
03596            total_exten_len += 2;
03597     }
03598 #if defined(NSS_ENABLE_ECC) && !defined(NSS_ECC_MORE_THAN_SUITE_B)
03599     else { /* SSL3 only */
03600        ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
03601     }
03602 #endif
03603 
03604     /* how many suites are permitted by policy and user preference? */
03605     num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE);
03606     if (!num_suites)
03607        return SECFailure;   /* count_cipher_suites has set error code. */
03608 
03609     length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH +
03610        1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength) +
03611        2 + num_suites*sizeof(ssl3CipherSuite) +
03612        1 + compressionMethodsCount + total_exten_len;
03613 
03614     rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
03615     if (rv != SECSuccess) {
03616        return rv;    /* err set by ssl3_AppendHandshake* */
03617     }
03618 
03619     ss->clientHelloVersion = ss->version;
03620     rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
03621     if (rv != SECSuccess) {
03622        return rv;    /* err set by ssl3_AppendHandshake* */
03623     }
03624     rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random);
03625     if (rv != SECSuccess) {
03626        return rv;    /* err set by GetNewRandom. */
03627     }
03628     rv = ssl3_AppendHandshake(ss, &ss->ssl3.hs.client_random,
03629                               SSL3_RANDOM_LENGTH);
03630     if (rv != SECSuccess) {
03631        return rv;    /* err set by ssl3_AppendHandshake* */
03632     }
03633 
03634     if (sid)
03635        rv = ssl3_AppendHandshakeVariable(
03636            ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
03637     else
03638        rv = ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
03639     if (rv != SECSuccess) {
03640        return rv;    /* err set by ssl3_AppendHandshake* */
03641     }
03642 
03643     rv = ssl3_AppendHandshakeNumber(ss, num_suites*sizeof(ssl3CipherSuite), 2);
03644     if (rv != SECSuccess) {
03645        return rv;    /* err set by ssl3_AppendHandshake* */
03646     }
03647 
03648 
03649     for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
03650        ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
03651        if (config_match(suite, ss->ssl3.policy, PR_TRUE)) {
03652            actual_count++;
03653            if (actual_count > num_suites) {
03654               /* set error card removal/insertion error */
03655               PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
03656               return SECFailure;
03657            }
03658            rv = ssl3_AppendHandshakeNumber(ss, suite->cipher_suite,
03659                                        sizeof(ssl3CipherSuite));
03660            if (rv != SECSuccess) {
03661               return rv;    /* err set by ssl3_AppendHandshake* */
03662            }
03663        }
03664     }
03665 
03666     /* if cards were removed or inserted between count_cipher_suites and
03667      * generating our list, detect the error here rather than send it off to
03668      * the server.. */
03669     if (actual_count != num_suites) {
03670        /* Card removal/insertion error */
03671        PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
03672        return SECFailure;
03673     }
03674 
03675     rv = ssl3_AppendHandshakeNumber(ss, compressionMethodsCount, 1);
03676     if (rv != SECSuccess) {
03677        return rv;    /* err set by ssl3_AppendHandshake* */
03678     }
03679     for (i = 0; i < compressionMethodsCount; i++) {
03680        rv = ssl3_AppendHandshakeNumber(ss, compressions[i], 1);
03681        if (rv != SECSuccess) {
03682            return rv;       /* err set by ssl3_AppendHandshake* */
03683        }
03684     }
03685 
03686     if (total_exten_len) {
03687        PRUint32 maxBytes = total_exten_len - 2;
03688        PRInt32  extLen;
03689 
03690        rv = ssl3_AppendHandshakeNumber(ss, maxBytes, 2);
03691        if (rv != SECSuccess) {
03692            return rv;       /* err set by AppendHandshake. */
03693        }
03694 
03695        extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL);
03696        if (extLen < 0) {
03697            return SECFailure;
03698        }
03699        maxBytes -= extLen;
03700        PORT_Assert(!maxBytes);
03701     }
03702 
03703 
03704     rv = ssl3_FlushHandshake(ss, 0);
03705     if (rv != SECSuccess) {
03706        return rv;    /* error code set by ssl3_FlushHandshake */
03707     }
03708 
03709     ss->ssl3.hs.ws = wait_server_hello;
03710     return rv;
03711 }
03712 
03713 
03714 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
03715  * ssl3 Hello Request.
03716  * Caller must hold Handshake and RecvBuf locks.
03717  */
03718 static SECStatus
03719 ssl3_HandleHelloRequest(sslSocket *ss)
03720 {
03721     sslSessionID *sid = ss->sec.ci.sid;
03722     SECStatus     rv;
03723 
03724     SSL_TRC(3, ("%d: SSL3[%d]: handle hello_request handshake",
03725               SSL_GETPID(), ss->fd));
03726 
03727     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
03728     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
03729 
03730     if (ss->ssl3.hs.ws == wait_server_hello)
03731        return SECSuccess;
03732     if (ss->ssl3.hs.ws != idle_handshake || ss->sec.isServer) {
03733        (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
03734        PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST);
03735        return SECFailure;
03736     }
03737     if (sid) {
03738        ss->sec.uncache(sid);
03739        ssl_FreeSID(sid);
03740        ss->sec.ci.sid = NULL;
03741     }
03742 
03743     ssl_GetXmitBufLock(ss);
03744     rv = ssl3_SendClientHello(ss);
03745     ssl_ReleaseXmitBufLock(ss);
03746 
03747     return rv;
03748 }
03749 
03750 #define UNKNOWN_WRAP_MECHANISM 0x7fffffff
03751 
03752 static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS] = {
03753     CKM_DES3_ECB,
03754     CKM_CAST5_ECB,
03755     CKM_DES_ECB,
03756     CKM_KEY_WRAP_LYNKS,
03757     CKM_IDEA_ECB,
03758     CKM_CAST3_ECB,
03759     CKM_CAST_ECB,
03760     CKM_RC5_ECB,
03761     CKM_RC2_ECB,
03762     CKM_CDMF_ECB,
03763     CKM_SKIPJACK_WRAP,
03764     CKM_SKIPJACK_CBC64,
03765     CKM_AES_ECB,
03766     UNKNOWN_WRAP_MECHANISM
03767 };
03768 
03769 static int
03770 ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech)
03771 {
03772     const CK_MECHANISM_TYPE *pMech = wrapMechanismList;
03773 
03774     while (mech != *pMech && *pMech != UNKNOWN_WRAP_MECHANISM) {
03775        ++pMech;
03776     }
03777     return (*pMech == UNKNOWN_WRAP_MECHANISM) ? -1
03778                                               : (pMech - wrapMechanismList);
03779 }
03780 
03781 static PK11SymKey *
03782 ssl_UnwrapSymWrappingKey(
03783        SSLWrappedSymWrappingKey *pWswk,
03784        SECKEYPrivateKey *        svrPrivKey,
03785        SSL3KEAType               exchKeyType,
03786        CK_MECHANISM_TYPE         masterWrapMech,
03787        void *                    pwArg)
03788 {
03789     PK11SymKey *             unwrappedWrappingKey  = NULL;
03790     SECItem                  wrappedKey;
03791 #ifdef NSS_ENABLE_ECC
03792     PK11SymKey *             Ks;
03793     SECKEYPublicKey          pubWrapKey;
03794     ECCWrappedKeyInfo        *ecWrapped;
03795 #endif /* NSS_ENABLE_ECC */
03796 
03797     /* found the wrapping key on disk. */
03798     PORT_Assert(pWswk->symWrapMechanism == masterWrapMech);
03799     PORT_Assert(pWswk->exchKeyType      == exchKeyType);
03800     if (pWswk->symWrapMechanism != masterWrapMech ||
03801        pWswk->exchKeyType      != exchKeyType) {
03802        goto loser;
03803     }
03804     wrappedKey.type = siBuffer;
03805     wrappedKey.data = pWswk->wrappedSymmetricWrappingkey;
03806     wrappedKey.len  = pWswk->wrappedSymKeyLen;
03807     PORT_Assert(wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey);
03808 
03809     switch (exchKeyType) {
03810 
03811     case kt_rsa:
03812        unwrappedWrappingKey =
03813            PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
03814                              masterWrapMech, CKA_UNWRAP, 0);
03815        break;
03816 
03817 #ifdef NSS_ENABLE_ECC
03818     case kt_ecdh:
03819         /* 
03820          * For kt_ecdh, we first create an EC public key based on
03821          * data stored with the wrappedSymmetricWrappingkey. Next,
03822          * we do an ECDH computation involving this public key and
03823          * the SSL server's (long-term) EC private key. The resulting
03824          * shared secret is treated the same way as Fortezza's Ks, i.e.,
03825          * it is used to recover the symmetric wrapping key.
03826          *
03827          * The data in wrappedSymmetricWrappingkey is laid out as defined
03828          * in the ECCWrappedKeyInfo structure.
03829          */
03830         ecWrapped = (ECCWrappedKeyInfo *) pWswk->wrappedSymmetricWrappingkey;
03831 
03832         PORT_Assert(ecWrapped->encodedParamLen + ecWrapped->pubValueLen + 
03833             ecWrapped->wrappedKeyLen <= MAX_EC_WRAPPED_KEY_BUFLEN);
03834 
03835         if (ecWrapped->encodedParamLen + ecWrapped->pubValueLen + 
03836             ecWrapped->wrappedKeyLen > MAX_EC_WRAPPED_KEY_BUFLEN) {
03837             PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
03838             goto loser;
03839         }
03840 
03841         pubWrapKey.keyType = ecKey;
03842         pubWrapKey.u.ec.size = ecWrapped->size;
03843         pubWrapKey.u.ec.DEREncodedParams.len = ecWrapped->encodedParamLen;
03844         pubWrapKey.u.ec.DEREncodedParams.data = ecWrapped->var;
03845         pubWrapKey.u.ec.publicValue.len = ecWrapped->pubValueLen;
03846         pubWrapKey.u.ec.publicValue.data = ecWrapped->var + 
03847             ecWrapped->encodedParamLen;
03848 
03849         wrappedKey.len  = ecWrapped->wrappedKeyLen;
03850         wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen + 
03851             ecWrapped->pubValueLen;
03852         
03853         /* Derive Ks using ECDH */
03854         Ks = PK11_PubDeriveWithKDF(svrPrivKey, &pubWrapKey, PR_FALSE, NULL,
03855                                NULL, CKM_ECDH1_DERIVE, masterWrapMech, 
03856                                CKA_DERIVE, 0, CKD_NULL, NULL, NULL);
03857         if (Ks == NULL) {
03858             goto loser;
03859         }
03860 
03861         /*  Use Ks to unwrap the wrapping key */
03862         unwrappedWrappingKey = PK11_UnwrapSymKey(Ks, masterWrapMech, NULL, 
03863                                            &wrappedKey, masterWrapMech, 
03864                                            CKA_UNWRAP, 0);
03865         PK11_FreeSymKey(Ks);
03866         
03867         break;
03868 #endif
03869 
03870     default:
03871        /* Assert? */
03872        SET_ERROR_CODE
03873        goto loser;
03874     }
03875 loser:
03876     return unwrappedWrappingKey;
03877 }
03878 
03879 /* Each process sharing the server session ID cache has its own array of
03880  * SymKey pointers for the symmetric wrapping keys that are used to wrap
03881  * the master secrets.  There is one key for each KEA type.  These Symkeys
03882  * correspond to the wrapped SymKeys kept in the server session cache.
03883  */
03884 
03885 typedef struct {
03886     PK11SymKey *      symWrapKey[kt_kea_size];
03887 } ssl3SymWrapKey;
03888 
03889 static PZLock *          symWrapKeysLock = NULL;
03890 static ssl3SymWrapKey    symWrapKeys[SSL_NUM_WRAP_MECHS];
03891 
03892 SECStatus
03893 SSL3_ShutdownServerCache(void)
03894 {
03895     int             i, j;
03896 
03897     if (!symWrapKeysLock)
03898        return SECSuccess;   /* was never initialized */
03899     PZ_Lock(symWrapKeysLock);
03900     /* get rid of all symWrapKeys */
03901     for (i = 0; i < SSL_NUM_WRAP_MECHS; ++i) {
03902        for (j = 0; j < kt_kea_size; ++j) {
03903            PK11SymKey **   pSymWrapKey;
03904            pSymWrapKey = &symWrapKeys[i].symWrapKey[j];
03905            if (*pSymWrapKey) {
03906               PK11_FreeSymKey(*pSymWrapKey);
03907               *pSymWrapKey = NULL;
03908            }
03909        }
03910     }
03911 
03912     PZ_Unlock(symWrapKeysLock);
03913     return SECSuccess;
03914 }
03915 
03916 void ssl_InitSymWrapKeysLock(void)
03917 {
03918     /* atomically initialize the lock */
03919     if (!symWrapKeysLock)
03920        nss_InitLock(&symWrapKeysLock, nssILockOther);
03921 }
03922 
03923 /* Try to get wrapping key for mechanism from in-memory array.
03924  * If that fails, look for one on disk.
03925  * If that fails, generate a new one, put the new one on disk,
03926  * Put the new key in the in-memory array.
03927  */
03928 static PK11SymKey *
03929 getWrappingKey( sslSocket *       ss,
03930               PK11SlotInfo *    masterSecretSlot,
03931               SSL3KEAType       exchKeyType,
03932                 CK_MECHANISM_TYPE masterWrapMech,
03933                void *            pwArg)
03934 {
03935     SECKEYPrivateKey *       svrPrivKey;
03936     SECKEYPublicKey *        svrPubKey             = NULL;
03937     PK11SymKey *             unwrappedWrappingKey  = NULL;
03938     PK11SymKey **            pSymWrapKey;
03939     CK_MECHANISM_TYPE        asymWrapMechanism = CKM_INVALID_MECHANISM;
03940     int                      length;
03941     int                      symWrapMechIndex;
03942     SECStatus                rv;
03943     SECItem                  wrappedKey;
03944     SSLWrappedSymWrappingKey wswk;
03945 
03946     svrPrivKey  = ss->serverCerts[exchKeyType].SERVERKEY;
03947     PORT_Assert(svrPrivKey != NULL);
03948     if (!svrPrivKey) {
03949        return NULL;  /* why are we here?!? */
03950     }
03951 
03952     symWrapMechIndex = ssl_FindIndexByWrapMechanism(masterWrapMech);
03953     PORT_Assert(symWrapMechIndex >= 0);
03954     if (symWrapMechIndex < 0)
03955        return NULL;  /* invalid masterWrapMech. */
03956 
03957     pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[exchKeyType];
03958 
03959     ssl_InitSymWrapKeysLock();
03960 
03961     PZ_Lock(symWrapKeysLock);
03962 
03963     unwrappedWrappingKey = *pSymWrapKey;
03964     if (unwrappedWrappingKey != NULL) {
03965        if (PK11_VerifyKeyOK(unwrappedWrappingKey)) {
03966            unwrappedWrappingKey = PK11_ReferenceSymKey(unwrappedWrappingKey);
03967            goto done;
03968        }
03969        /* slot series has changed, so this key is no good any more. */
03970        PK11_FreeSymKey(unwrappedWrappingKey);
03971        *pSymWrapKey = unwrappedWrappingKey = NULL;
03972     }
03973 
03974     /* Try to get wrapped SymWrapping key out of the (disk) cache. */
03975     /* Following call fills in wswk on success. */
03976     if (ssl_GetWrappingKey(symWrapMechIndex, exchKeyType, &wswk)) {
03977        /* found the wrapped sym wrapping key on disk. */
03978        unwrappedWrappingKey =
03979            ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, exchKeyType,
03980                                      masterWrapMech, pwArg);
03981        if (unwrappedWrappingKey) {
03982            goto install;
03983        }
03984     }
03985 
03986     if (!masterSecretSlot)  /* caller doesn't want to create a new one. */
03987        goto loser;
03988 
03989     length = PK11_GetBestKeyLength(masterSecretSlot, masterWrapMech);
03990     /* Zero length means fixed key length algorithm, or error.
03991      * It's ambiguous.
03992      */
03993     unwrappedWrappingKey = PK11_KeyGen(masterSecretSlot, masterWrapMech, NULL,
03994                                        length, pwArg);
03995     if (!unwrappedWrappingKey) {
03996        goto loser;
03997     }
03998 
03999     /* Prepare the buffer to receive the wrappedWrappingKey,
04000      * the symmetric wrapping key wrapped using the server's pub key.
04001      */
04002     PORT_Memset(&wswk, 0, sizeof wswk);   /* eliminate UMRs. */
04003 
04004     if (ss->serverCerts[exchKeyType].serverKeyPair) {
04005        svrPubKey = ss->serverCerts[exchKeyType].serverKeyPair->pubKey;
04006     }
04007     if (svrPubKey == NULL) {
04008        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
04009        goto loser;
04010     }
04011     wrappedKey.type = siBuffer;
04012     wrappedKey.len  = SECKEY_PublicKeyStrength(svrPubKey);
04013     wrappedKey.data = wswk.wrappedSymmetricWrappingkey;
04014 
04015     PORT_Assert(wrappedKey.len <= sizeof wswk.wrappedSymmetricWrappingkey);
04016     if (wrappedKey.len > sizeof wswk.wrappedSymmetricWrappingkey)
04017        goto loser;
04018 
04019     /* wrap symmetric wrapping key in server's public key. */
04020     switch (exchKeyType) {
04021 #ifdef NSS_ENABLE_ECC
04022     PK11SymKey *      Ks;
04023     SECKEYPublicKey   *pubWrapKey = NULL;
04024     SECKEYPrivateKey  *privWrapKey = NULL;
04025     ECCWrappedKeyInfo *ecWrapped;
04026 #endif /* NSS_ENABLE_ECC */
04027 
04028     case kt_rsa:
04029        asymWrapMechanism = CKM_RSA_PKCS;
04030        rv = PK11_PubWrapSymKey(asymWrapMechanism, svrPubKey,
04031                                unwrappedWrappingKey, &wrappedKey);
04032        break;
04033 
04034 #ifdef NSS_ENABLE_ECC
04035     case kt_ecdh:
04036        /*
04037         * We generate an ephemeral EC key pair. Perform an ECDH
04038         * computation involving this ephemeral EC public key and
04039         * the SSL server's (long-term) EC private key. The resulting
04040         * shared secret is treated in the same way as Fortezza's Ks, 
04041         * i.e., it is used to wrap the wrapping key. To facilitate
04042         * unwrapping in ssl_UnwrapWrappingKey, we also store all
04043         * relevant info about the ephemeral EC public key in
04044         * wswk.wrappedSymmetricWrappingkey and lay it out as 
04045         * described in the ECCWrappedKeyInfo structure.
04046         */
04047        PORT_Assert(svrPubKey->keyType == ecKey);
04048        if (svrPubKey->keyType != ecKey) {
04049            /* something is wrong in sslsecur.c if this isn't an ecKey */
04050            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
04051            rv = SECFailure;
04052            goto ec_cleanup;
04053        }
04054 
04055        privWrapKey = SECKEY_CreateECPrivateKey(
04056            &svrPubKey->u.ec.DEREncodedParams, &pubWrapKey, NULL);
04057        if ((privWrapKey == NULL) || (pubWrapKey == NULL)) {
04058            rv = SECFailure;
04059            goto ec_cleanup;
04060        }
04061        
04062        /* Set the key size in bits */
04063        if (pubWrapKey->u.ec.size == 0) {
04064            pubWrapKey->u.ec.size = SECKEY_PublicKeyStrengthInBits(svrPubKey);
04065        }
04066 
04067        PORT_Assert(pubWrapKey->u.ec.DEREncodedParams.len + 
04068            pubWrapKey->u.ec.publicValue.len < MAX_EC_WRAPPED_KEY_BUFLEN);
04069        if (pubWrapKey->u.ec.DEREncodedParams.len + 
04070            pubWrapKey->u.ec.publicValue.len >= MAX_EC_WRAPPED_KEY_BUFLEN) {
04071            PORT_SetError(SEC_ERROR_INVALID_KEY);
04072            rv = SECFailure;
04073            goto ec_cleanup;
04074        }
04075 
04076        /* Derive Ks using ECDH */
04077        Ks = PK11_PubDeriveWithKDF(svrPrivKey, pubWrapKey, PR_FALSE, NULL,
04078                                NULL, CKM_ECDH1_DERIVE, masterWrapMech, 
04079                                CKA_DERIVE, 0, CKD_NULL, NULL, NULL);
04080        if (Ks == NULL) {
04081            rv = SECFailure;
04082            goto ec_cleanup;
04083        }
04084 
04085        ecWrapped = (ECCWrappedKeyInfo *) (wswk.wrappedSymmetricWrappingkey);
04086        ecWrapped->size = pubWrapKey->u.ec.size;
04087        ecWrapped->encodedParamLen = pubWrapKey->u.ec.DEREncodedParams.len;
04088        PORT_Memcpy(ecWrapped->var, pubWrapKey->u.ec.DEREncodedParams.data, 
04089            pubWrapKey->u.ec.DEREncodedParams.len);
04090 
04091        ecWrapped->pubValueLen = pubWrapKey->u.ec.publicValue.len;
04092        PORT_Memcpy(ecWrapped->var + ecWrapped->encodedParamLen, 
04093                   pubWrapKey->u.ec.publicValue.data, 
04094                   pubWrapKey->u.ec.publicValue.len);
04095 
04096        wrappedKey.len = MAX_EC_WRAPPED_KEY_BUFLEN - 
04097            (ecWrapped->encodedParamLen + ecWrapped->pubValueLen);
04098        wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen +
04099            ecWrapped->pubValueLen;
04100 
04101        /* wrap symmetricWrapping key with the local Ks */
04102        rv = PK11_WrapSymKey(masterWrapMech, NULL, Ks,
04103                           unwrappedWrappingKey, &wrappedKey);
04104 
04105        if (rv != SECSuccess) {
04106            goto ec_cleanup;
04107        }
04108 
04109        /* Write down the length of wrapped key in the buffer
04110         * wswk.wrappedSymmetricWrappingkey at the appropriate offset
04111         */
04112        ecWrapped->wrappedKeyLen = wrappedKey.len;
04113 
04114 ec_cleanup:
04115        if (privWrapKey) SECKEY_DestroyPrivateKey(privWrapKey);
04116        if (pubWrapKey) SECKEY_DestroyPublicKey(pubWrapKey);
04117        if (Ks) PK11_FreeSymKey(Ks);
04118        asymWrapMechanism = masterWrapMech;
04119        break;
04120 #endif /* NSS_ENABLE_ECC */
04121 
04122     default:
04123        rv = SECFailure;
04124        break;
04125     }
04126 
04127     if (rv != SECSuccess) {
04128        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
04129        goto loser;
04130     }
04131 
04132     PORT_Assert(asymWrapMechanism != CKM_INVALID_MECHANISM);
04133 
04134     wswk.symWrapMechanism  = masterWrapMech;
04135     wswk.symWrapMechIndex  = symWrapMechIndex;
04136     wswk.asymWrapMechanism = asymWrapMechanism;
04137     wswk.exchKeyType       = exchKeyType;
04138     wswk.wrappedSymKeyLen  = wrappedKey.len;
04139 
04140     /* put it on disk. */
04141     /* If the wrapping key for this KEA type has already been set, 
04142      * then abandon the value we just computed and 
04143      * use the one we got from the disk.
04144      */
04145     if (ssl_SetWrappingKey(&wswk)) {
04146        /* somebody beat us to it.  The original contents of our wswk
04147         * has been replaced with the content on disk.  Now, discard
04148         * the key we just created and unwrap this new one.
04149         */
04150        PK11_FreeSymKey(unwrappedWrappingKey);
04151 
04152        unwrappedWrappingKey =
04153            ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, exchKeyType,
04154                                      masterWrapMech, pwArg);
04155     }
04156 
04157 install:
04158     if (unwrappedWrappingKey) {
04159        *pSymWrapKey = PK11_ReferenceSymKey(unwrappedWrappingKey);
04160     }
04161 
04162 loser:
04163 done:
04164     PZ_Unlock(symWrapKeysLock);
04165     return unwrappedWrappingKey;
04166 }
04167 
04168 
04169 /* Called from ssl3_SendClientKeyExchange(). */
04170 /* Presently, this always uses PKCS11.  There is no bypass for this. */
04171 static SECStatus
04172 sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
04173 {
04174     PK11SymKey *     pms           = NULL;
04175     SECStatus           rv                = SECFailure;
04176     SECItem          enc_pms       = {siBuffer, NULL, 0};
04177     PRBool              isTLS;
04178 
04179     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
04180     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
04181 
04182     /* Generate the pre-master secret ...  */
04183     ssl_GetSpecWriteLock(ss);
04184     isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
04185 
04186     pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.pwSpec, NULL);
04187     ssl_ReleaseSpecWriteLock(ss);
04188     if (pms == NULL) {
04189        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
04190        goto loser;
04191     }
04192 
04193 #if defined(TRACE)
04194     if (ssl_trace >= 100) {
04195        SECStatus extractRV = PK11_ExtractKeyValue(pms);
04196        if (extractRV == SECSuccess) {
04197            SECItem * keyData = PK11_GetKeyData(pms);
04198            if (keyData && keyData->data && keyData->len) {
04199               ssl_PrintBuf(ss, "Pre-Master Secret", 
04200                           keyData->data, keyData->len);
04201            }
04202        }
04203     }
04204 #endif
04205 
04206     /* Get the wrapped (encrypted) pre-master secret, enc_pms */
04207     enc_pms.len  = SECKEY_PublicKeyStrength(svrPubKey);
04208     enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len);
04209     if (enc_pms.data == NULL) {
04210        goto loser;   /* err set by PORT_Alloc */
04211     }
04212 
04213     /* wrap pre-master secret in server's public key. */
04214     rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, pms, &enc_pms);
04215     if (rv != SECSuccess) {
04216        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
04217        goto loser;
04218     }
04219 
04220     rv = ssl3_InitPendingCipherSpec(ss,  pms);
04221     PK11_FreeSymKey(pms); pms = NULL;
04222 
04223     if (rv != SECSuccess) {
04224        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
04225        goto loser;
04226     }
04227 
04228     rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, 
04229                                 isTLS ? enc_pms.len + 2 : enc_pms.len);
04230     if (rv != SECSuccess) {
04231        goto loser;   /* err set by ssl3_AppendHandshake* */
04232     }
04233     if (isTLS) {
04234        rv = ssl3_AppendHandshakeVariable(ss, enc_pms.data, enc_pms.len, 2);
04235     } else {
04236        rv = ssl3_AppendHandshake(ss, enc_pms.data, enc_pms.len);
04237     }
04238     if (rv != SECSuccess) {
04239        goto loser;   /* err set by ssl3_AppendHandshake* */
04240     }
04241 
04242     rv = SECSuccess;
04243 
04244 loser:
04245     if (enc_pms.data != NULL) {
04246        PORT_Free(enc_pms.data);
04247     }
04248     if (pms != NULL) {
04249        PK11_FreeSymKey(pms);
04250     }
04251     return rv;
04252 }
04253 
04254 /* Called from ssl3_SendClientKeyExchange(). */
04255 /* Presently, this always uses PKCS11.  There is no bypass for this. */
04256 static SECStatus
04257 sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
04258 {
04259     PK11SymKey *     pms           = NULL;
04260     SECStatus           rv                = SECFailure;
04261     PRBool              isTLS;
04262     CK_MECHANISM_TYPE       target;
04263 
04264     SECKEYDHParams   dhParam;             /* DH parameters */
04265     SECKEYPublicKey  *pubKey = NULL;             /* Ephemeral DH key */
04266     SECKEYPrivateKey *privKey = NULL;     /* Ephemeral DH key */
04267 
04268     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
04269     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
04270 
04271     isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
04272 
04273     /* Copy DH parameters from server key */
04274 
04275     if (svrPubKey->keyType != dhKey) {
04276        PORT_SetError(SEC_ERROR_BAD_KEY);
04277        goto loser;
04278     }
04279     dhParam.prime.data = svrPubKey->u.dh.prime.data;
04280     dhParam.prime.len = svrPubKey->u.dh.prime.len;
04281     dhParam.base.data = svrPubKey->u.dh.base.data;
04282     dhParam.base.len = svrPubKey->u.dh.base.len;
04283 
04284     /* Generate ephemeral DH keypair */
04285     privKey = SECKEY_CreateDHPrivateKey(&dhParam, &pubKey, NULL);
04286     if (!privKey || !pubKey) {
04287            ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
04288            rv = SECFailure;
04289            goto loser;
04290     }
04291     PRINT_BUF(50, (ss, "DH public value:",
04292                                    pubKey->u.dh.publicValue.data,
04293                                    pubKey->u.dh.publicValue.len));
04294 
04295     if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
04296     else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
04297 
04298     /* Determine the PMS */
04299 
04300     pms = PK11_PubDerive(privKey, svrPubKey, PR_FALSE, NULL, NULL,
04301                          CKM_DH_PKCS_DERIVE, target, CKA_DERIVE, 0, NULL);
04302 
04303     if (pms == NULL) {
04304        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
04305        goto loser;
04306     }
04307 
04308     SECKEY_DestroyPrivateKey(privKey);
04309     privKey = NULL;
04310 
04311     rv = ssl3_InitPendingCipherSpec(ss,  pms);
04312     PK11_FreeSymKey(pms); pms = NULL;
04313 
04314     if (rv != SECSuccess) {
04315        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
04316        goto loser;
04317     }
04318 
04319     rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, 
04320                                    pubKey->u.dh.publicValue.len + 2);
04321     if (rv != SECSuccess) {
04322        goto loser;   /* err set by ssl3_AppendHandshake* */
04323     }
04324     rv = ssl3_AppendHandshakeVariable(ss, 
04325                                    pubKey->u.dh.publicValue.data,
04326                                    pubKey->u.dh.publicValue.len, 2);
04327     SECKEY_DestroyPublicKey(pubKey);
04328     pubKey = NULL;
04329 
04330     if (rv != SECSuccess) {
04331        goto loser;   /* err set by ssl3_AppendHandshake* */
04332     }
04333 
04334     rv = SECSuccess;
04335 
04336 
04337 loser:
04338 
04339     if(pms) PK11_FreeSymKey(pms);
04340     if(privKey) SECKEY_DestroyPrivateKey(privKey);
04341     if(pubKey) SECKEY_DestroyPublicKey(pubKey);
04342     return rv;
04343 }
04344 
04345 
04346 
04347 
04348 
04349 /* Called from ssl3_HandleServerHelloDone(). */
04350 static SECStatus
04351 ssl3_SendClientKeyExchange(sslSocket *ss)
04352 {
04353     SECKEYPublicKey *       serverKey     = NULL;
04354     SECStatus               rv            = SECFailure;
04355     PRBool              isTLS;
04356 
04357     SSL_TRC(3, ("%d: SSL3[%d]: send client_key_exchange handshake",
04358               SSL_GETPID(), ss->fd));
04359 
04360     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
04361     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
04362 
04363     if (ss->sec.peerKey == NULL) {
04364        serverKey = CERT_ExtractPublicKey(ss->sec.peerCert);
04365        if (serverKey == NULL) {
04366            PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
04367            return SECFailure;
04368        }
04369     } else {
04370        serverKey = ss->sec.peerKey;
04371        ss->sec.peerKey = NULL; /* we're done with it now */
04372     }
04373 
04374     isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
04375     /* enforce limits on kea key sizes. */
04376     if (ss->ssl3.hs.kea_def->is_limited) {
04377        int keyLen = SECKEY_PublicKeyStrength(serverKey);       /* bytes */
04378 
04379        if (keyLen * BPB > ss->ssl3.hs.kea_def->key_size_limit) {
04380            if (isTLS)
04381               (void)SSL3_SendAlert(ss, alert_fatal, export_restriction);
04382            else
04383               (void)ssl3_HandshakeFailure(ss);
04384            PORT_SetError(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED);
04385            goto loser;
04386        }
04387     }
04388 
04389     ss->sec.keaType    = ss->ssl3.hs.kea_def->exchKeyType;
04390     ss->sec.keaKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey);
04391 
04392     switch (ss->ssl3.hs.kea_def->exchKeyType) {
04393     case kt_rsa:
04394        rv = sendRSAClientKeyExchange(ss, serverKey);
04395        break;
04396 
04397     case kt_dh:
04398        rv = sendDHClientKeyExchange(ss, serverKey);
04399        break;
04400 
04401 #ifdef NSS_ENABLE_ECC
04402     case kt_ecdh:
04403        rv = ssl3_SendECDHClientKeyExchange(ss, serverKey);
04404        break;
04405 #endif /* NSS_ENABLE_ECC */
04406 
04407     default:
04408        /* got an unknown or unsupported Key Exchange Algorithm.  */
04409        SEND_ALERT
04410        PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
04411        break;
04412     }
04413 
04414     SSL_TRC(3, ("%d: SSL3[%d]: DONE sending client_key_exchange",
04415               SSL_GETPID(), ss->fd));
04416 
04417 loser:
04418     if (serverKey) 
04419        SECKEY_DestroyPublicKey(serverKey);
04420     return rv;       /* err code already set. */
04421 }
04422 
04423 /* Called from ssl3_HandleServerHelloDone(). */
04424 static SECStatus
04425 ssl3_SendCertificateVerify(sslSocket *ss)
04426 {
04427     SECStatus     rv        = SECFailure;
04428     PRBool        isTLS;
04429     SECItem       buf           = {siBuffer, NULL, 0};
04430     SSL3Hashes    hashes;
04431 
04432     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
04433     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
04434 
04435     SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake",
04436               SSL_GETPID(), ss->fd));
04437 
04438     ssl_GetSpecReadLock(ss);
04439     rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
04440     ssl_ReleaseSpecReadLock(ss);
04441     if (rv != SECSuccess) {
04442        goto done;    /* err code was set by ssl3_ComputeHandshakeHashes */
04443     }
04444 
04445     isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
04446     rv = ssl3_SignHashes(&hashes, ss->ssl3.clientPrivateKey, &buf, isTLS);
04447     if (rv == SECSuccess) {
04448        PK11SlotInfo * slot;
04449        sslSessionID * sid   = ss->sec.ci.sid;
04450 
04451        /* Remember the info about the slot that did the signing.
04452        ** Later, when doing an SSL restart handshake, verify this.
04453        ** These calls are mere accessors, and can't fail.
04454        */
04455        slot = PK11_GetSlotFromPrivateKey(ss->ssl3.clientPrivateKey);
04456        sid->u.ssl3.clAuthSeries     = PK11_GetSlotSeries(slot);
04457        sid->u.ssl3.clAuthSlotID     = PK11_GetSlotID(slot);
04458        sid->u.ssl3.clAuthModuleID   = PK11_GetModuleID(slot);
04459        sid->u.ssl3.clAuthValid      = PR_TRUE;
04460        PK11_FreeSlot(slot);
04461     }
04462     /* If we're doing RSA key exchange, we're all done with the private key
04463      * here.  Diffie-Hellman key exchanges need the client's
04464      * private key for the key exchange.
04465      */
04466     if (ss->ssl3.hs.kea_def->exchKeyType == kt_rsa) {
04467        SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
04468        ss->ssl3.clientPrivateKey = NULL;
04469     }
04470     if (rv != SECSuccess) {
04471        goto done;    /* err code was set by ssl3_SignHashes */
04472     }
04473 
04474     rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, buf.len + 2);
04475     if (rv != SECSuccess) {
04476        goto done;    /* error code set by AppendHandshake */
04477     }
04478     rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2);
04479     if (rv != SECSuccess) {
04480        goto done;    /* error code set by AppendHandshake */
04481     }
04482 
04483 done:
04484     if (buf.data)
04485        PORT_Free(buf.data);
04486     return rv;
04487 }
04488 
04489 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
04490  * ssl3 ServerHello message.
04491  * Caller must hold Handshake and RecvBuf locks.
04492  */
04493 static SECStatus
04494 ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
04495 {
04496     sslSessionID *sid              = ss->sec.ci.sid;
04497     PRInt32       temp;            /* allow for consume number failure */
04498     PRBool        suite_found   = PR_FALSE;
04499     int           i;
04500     int           errCode   = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
04501     SECStatus     rv;
04502     SECItem       sidBytes  = {siBuffer, NULL, 0};
04503     PRBool        sid_match;
04504     PRBool        isTLS            = PR_FALSE;
04505     SSL3AlertDescription desc   = illegal_parameter;
04506     SSL3ProtocolVersion version;
04507 
04508     SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello handshake",
04509        SSL_GETPID(), ss->fd));
04510     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
04511     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
04512 
04513     rv = ssl3_InitState(ss);
04514     if (rv != SECSuccess) {
04515        errCode = PORT_GetError(); /* ssl3_InitState has set the error code. */
04516        goto alert_loser;
04517     }
04518     if (ss->ssl3.hs.ws != wait_server_hello) {
04519         errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO;
04520        desc    = unexpected_message;
04521        goto alert_loser;
04522     }
04523 
04524     temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
04525     if (temp < 0) {
04526        goto loser;   /* alert has been sent */
04527     }
04528     version = (SSL3ProtocolVersion)temp;
04529 
04530     /* this is appropriate since the negotiation is complete, and we only
04531     ** know SSL 3.x.
04532     */
04533     if (MSB(version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
04534        desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version 
04535                                              : handshake_failure;
04536        goto alert_loser;
04537     }
04538 
04539     rv = ssl3_NegotiateVersion(ss, version);
04540     if (rv != SECSuccess) {
04541        desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version 
04542                                              : handshake_failure;
04543        errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
04544        goto alert_loser;
04545     }
04546     isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
04547 
04548     rv = ssl3_ConsumeHandshake(
04549        ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length);
04550     if (rv != SECSuccess) {
04551        goto loser;   /* alert has been sent */
04552     }
04553 
04554     rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
04555     if (rv != SECSuccess) {
04556        goto loser;   /* alert has been sent */
04557     }
04558     if (sidBytes.len > SSL3_SESSIONID_BYTES) {
04559        if (isTLS)
04560            desc = decode_error;
04561        goto alert_loser;    /* malformed. */
04562     }
04563 
04564     /* find selected cipher suite in our list. */
04565     temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
04566     if (temp < 0) {
04567        goto loser;   /* alert has been sent */
04568     }
04569     ssl3_config_match_init(ss);
04570     for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
04571        ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
04572        if ((temp == suite->cipher_suite) &&
04573            (config_match(suite, ss->ssl3.policy, PR_TRUE))) {
04574            suite_found = PR_TRUE;
04575            break;    /* success */
04576        }
04577     }
04578     if (!suite_found) {
04579        desc    = handshake_failure;
04580        errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
04581        goto alert_loser;
04582     }
04583     ss->ssl3.hs.cipher_suite = (ssl3CipherSuite)temp;
04584     ss->ssl3.hs.suite_def    = ssl_LookupCipherSuiteDef((ssl3CipherSuite)temp);
04585     PORT_Assert(ss->ssl3.hs.suite_def);
04586     if (!ss->ssl3.hs.suite_def) {
04587        PORT_SetError(errCode = SEC_ERROR_LIBRARY_FAILURE);
04588        goto loser;   /* we don't send alerts for our screw-ups. */
04589     }
04590 
04591     /* find selected compression method in our list. */
04592     temp = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length);
04593     if (temp < 0) {
04594        goto loser;   /* alert has been sent */
04595     }
04596     suite_found = PR_FALSE;
04597     for (i = 0; i < compressionMethodsCount; i++) {
04598        if (temp == compressions[i])  {
04599            suite_found = PR_TRUE;
04600            break;    /* success */
04601        }
04602     }
04603     if (!suite_found) {
04604        desc    = handshake_failure;
04605        errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
04606        goto alert_loser;
04607     }
04608     ss->ssl3.hs.compression = (SSL3CompressionMethod)temp;
04609 
04610 #ifdef DISALLOW_SERVER_HELLO_EXTENSIONS
04611     if (length != 0) {      /* malformed */
04612        goto alert_loser;
04613     }
04614 #endif
04615 
04616     /* Any errors after this point are not "malformed" errors. */
04617     desc    = handshake_failure;
04618 
04619     /* we need to call ssl3_SetupPendingCipherSpec here so we can check the
04620      * key exchange algorithm. */
04621     rv = ssl3_SetupPendingCipherSpec(ss);
04622     if (rv != SECSuccess) {
04623        goto alert_loser;    /* error code is set. */
04624     }
04625 
04626     /* We may or may not have sent a session id, we may get one back or
04627      * not and if so it may match the one we sent.
04628      * Attempt to restore the master secret to see if this is so...
04629      * Don't consider failure to find a matching SID an error.
04630      */
04631     sid_match = (PRBool)(sidBytes.len > 0 &&
04632        sidBytes.len == sid->u.ssl3.sessionIDLength &&
04633        !PORT_Memcmp(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len));
04634 
04635     if (sid_match &&
04636        sid->version == ss->version &&
04637        sid->u.ssl3.cipherSuite == ss->ssl3.hs.cipher_suite) do {
04638        ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
04639 
04640        SECItem       wrappedMS;   /* wrapped master secret. */
04641 
04642        ss->sec.authAlgorithm = sid->authAlgorithm;
04643        ss->sec.authKeyBits   = sid->authKeyBits;
04644        ss->sec.keaType       = sid->keaType;
04645        ss->sec.keaKeyBits    = sid->keaKeyBits;
04646 
04647        /* 3 cases here:
04648         * a) key is wrapped (implies using PKCS11)
04649         * b) key is unwrapped, but we're still using PKCS11
04650         * c) key is unwrapped, and we're bypassing PKCS11.
04651         */
04652        if (sid->u.ssl3.keys.msIsWrapped) {
04653            PK11SlotInfo *slot;
04654            PK11SymKey *  wrapKey;     /* wrapping key */
04655            CK_FLAGS      keyFlags      = 0;
04656 
04657            if (ss->opt.bypassPKCS11) {
04658               /* we cannot restart a non-bypass session in a 
04659               ** bypass socket.
04660               */
04661               break;  
04662            }
04663            /* unwrap master secret with PKCS11 */
04664            slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
04665                                  sid->u.ssl3.masterSlotID);
04666            if (slot == NULL) {
04667               break;        /* not considered an error. */
04668            }
04669            if (!PK11_IsPresent(slot)) {
04670               PK11_FreeSlot(slot);
04671               break;        /* not considered an error. */
04672            }
04673            wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,
04674                                   sid->u.ssl3.masterWrapMech,
04675                                   sid->u.ssl3.masterWrapSeries,
04676                                   ss->pkcs11PinArg);
04677            PK11_FreeSlot(slot);
04678            if (wrapKey == NULL) {
04679               break;        /* not considered an error. */
04680            }
04681 
04682            if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
04683               keyFlags = CKF_SIGN | CKF_VERIFY;
04684            }
04685 
04686            wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
04687            wrappedMS.len  = sid->u.ssl3.keys.wrapped_master_secret_len;
04688            pwSpec->master_secret =
04689               PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech, 
04690                          NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
04691                          CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
04692            errCode = PORT_GetError();
04693            PK11_FreeSymKey(wrapKey);
04694            if (pwSpec->master_secret == NULL) {
04695               break; /* errorCode set just after call to UnwrapSymKey. */
04696            }
04697        } else if (ss->opt.bypassPKCS11) {
04698            /* MS is not wrapped */
04699            wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
04700            wrappedMS.len  = sid->u.ssl3.keys.wrapped_master_secret_len;
04701            memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
04702            pwSpec->msItem.data = pwSpec->raw_master_secret;
04703            pwSpec->msItem.len  = wrappedMS.len;
04704        } else {
04705            /* We CAN restart a bypass session in a non-bypass socket. */
04706            /* need to import the raw master secret to session object */
04707            PK11SlotInfo *slot = PK11_GetInternalSlot();
04708            wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
04709            wrappedMS.len  = sid->u.ssl3.keys.wrapped_master_secret_len;
04710            pwSpec->master_secret =  
04711               PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE, 
04712                               PK11_OriginUnwrap, CKA_ENCRYPT, 
04713                               &wrappedMS, NULL);
04714            PK11_FreeSlot(slot);
04715            if (pwSpec->master_secret == NULL) {
04716               break; 
04717            }
04718        }
04719 
04720        /* Got a Match */
04721        SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_hits );
04722        ss->ssl3.hs.ws         = wait_change_cipher;
04723        ss->ssl3.hs.isResuming = PR_TRUE;
04724 
04725        /* copy the peer cert from the SID */
04726        if (sid->peerCert != NULL) {
04727            ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
04728        }
04729 
04730 
04731        /* NULL value for PMS signifies re-use of the old MS */
04732        rv = ssl3_InitPendingCipherSpec(ss,  NULL);
04733        if (rv != SECSuccess) {
04734            goto alert_loser;       /* err code was set */
04735        }
04736        return SECSuccess;
04737     } while (0);
04738 
04739     if (sid_match)
04740        SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_not_ok );
04741     else
04742        SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_misses );
04743 
04744     /* throw the old one away */
04745     sid->u.ssl3.keys.resumable = PR_FALSE;
04746     (*ss->sec.uncache)(sid);
04747     ssl_FreeSID(sid);
04748 
04749     /* get a new sid */
04750     ss->sec.ci.sid = sid = ssl3_NewSessionID(ss, PR_FALSE);
04751     if (sid == NULL) {
04752        goto alert_loser;    /* memory error is set. */
04753     }
04754 
04755     sid->version = ss->version;
04756     sid->u.ssl3.sessionIDLength = sidBytes.len;
04757     PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len);
04758 
04759     ss->ssl3.hs.isResuming = PR_FALSE;
04760     ss->ssl3.hs.ws         = wait_server_cert;
04761     return SECSuccess;
04762 
04763 alert_loser:
04764     (void)SSL3_SendAlert(ss, alert_fatal, desc);
04765 
04766 loser:
04767     errCode = ssl_MapLowLevelError(errCode);
04768     return SECFailure;
04769 }
04770 
04771 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
04772  * ssl3 ServerKeyExchange message.
04773  * Caller must hold Handshake and RecvBuf locks.
04774  */
04775 static SECStatus
04776 ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
04777 {
04778     PRArenaPool *    arena     = NULL;
04779     SECKEYPublicKey *peerKey   = NULL;
04780     PRBool           isTLS;
04781     SECStatus        rv;
04782     int              errCode   = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
04783     SSL3AlertDescription desc  = illegal_parameter;
04784     SSL3Hashes       hashes;
04785     SECItem          signature = {siBuffer, NULL, 0};
04786 
04787     SSL_TRC(3, ("%d: SSL3[%d]: handle server_key_exchange handshake",
04788               SSL_GETPID(), ss->fd));
04789     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
04790     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
04791 
04792     if (ss->ssl3.hs.ws != wait_server_key &&
04793        ss->ssl3.hs.ws != wait_server_cert) {
04794        errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
04795        desc    = unexpected_message;
04796        goto alert_loser;
04797     }
04798     if (ss->sec.peerCert == NULL) {
04799        errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
04800        desc    = unexpected_message;
04801        goto alert_loser;
04802     }
04803 
04804     isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
04805 
04806     switch (ss->ssl3.hs.kea_def->exchKeyType) {
04807 
04808     case kt_rsa: {
04809        SECItem          modulus   = {siBuffer, NULL, 0};
04810        SECItem          exponent  = {siBuffer, NULL, 0};
04811 
04812        rv = ssl3_ConsumeHandshakeVariable(ss, &modulus, 2, &b, &length);
04813        if (rv != SECSuccess) {
04814            goto loser;             /* malformed. */
04815        }
04816        rv = ssl3_ConsumeHandshakeVariable(ss, &exponent, 2, &b, &length);
04817        if (rv != SECSuccess) {
04818            goto loser;             /* malformed. */
04819        }
04820        rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
04821        if (rv != SECSuccess) {
04822            goto loser;             /* malformed. */
04823        }
04824        if (length != 0) {
04825            if (isTLS)
04826               desc = decode_error;
04827            goto alert_loser;              /* malformed. */
04828        }
04829 
04830        /* failures after this point are not malformed handshakes. */
04831        /* TLS: send decrypt_error if signature failed. */
04832        desc = isTLS ? decrypt_error : handshake_failure;
04833 
04834        /*
04835         *  check to make sure the hash is signed by right guy
04836         */
04837        rv = ssl3_ComputeExportRSAKeyHash(modulus, exponent,
04838                                      &ss->ssl3.hs.client_random,
04839                                      &ss->ssl3.hs.server_random, 
04840                                      &hashes, ss->opt.bypassPKCS11);
04841         if (rv != SECSuccess) {
04842            errCode =
04843               ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
04844            goto alert_loser;
04845        }
04846         rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
04847                                 isTLS, ss->pkcs11PinArg);
04848        if (rv != SECSuccess)  {
04849            errCode =
04850               ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
04851            goto alert_loser;
04852        }
04853 
04854        /*
04855         * we really need to build a new key here because we can no longer
04856         * ignore calling SECKEY_DestroyPublicKey. Using the key may allocate
04857         * pkcs11 slots and ID's.
04858         */
04859        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
04860        if (arena == NULL) {
04861            goto no_memory;
04862        }
04863 
04864        peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
04865        if (peerKey == NULL) {
04866             PORT_FreeArena(arena, PR_FALSE);
04867            goto no_memory;
04868        }
04869 
04870        peerKey->arena              = arena;
04871        peerKey->keyType            = rsaKey;
04872        peerKey->pkcs11Slot         = NULL;
04873        peerKey->pkcs11ID           = CK_INVALID_HANDLE;
04874        if (SECITEM_CopyItem(arena, &peerKey->u.rsa.modulus,        &modulus) ||
04875            SECITEM_CopyItem(arena, &peerKey->u.rsa.publicExponent, &exponent))
04876        {
04877             PORT_FreeArena(arena, PR_FALSE);
04878            goto no_memory;
04879         }
04880        ss->sec.peerKey = peerKey;
04881        ss->ssl3.hs.ws = wait_cert_request;
04882        return SECSuccess;
04883     }
04884 
04885     case kt_dh: {
04886        SECItem          dh_p      = {siBuffer, NULL, 0};
04887        SECItem          dh_g      = {siBuffer, NULL, 0};
04888        SECItem          dh_Ys     = {siBuffer, NULL, 0};
04889 
04890        rv = ssl3_ConsumeHandshakeVariable(ss, &dh_p, 2, &b, &length);
04891        if (rv != SECSuccess) {
04892            goto loser;             /* malformed. */
04893        }
04894        rv = ssl3_ConsumeHandshakeVariable(ss, &dh_g, 2, &b, &length);
04895        if (rv != SECSuccess) {
04896            goto loser;             /* malformed. */
04897        }
04898        rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length);
04899        if (rv != SECSuccess) {
04900            goto loser;             /* malformed. */
04901        }
04902        rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
04903        if (rv != SECSuccess) {
04904            goto loser;             /* malformed. */
04905        }
04906        if (length != 0) {
04907            if (isTLS)
04908               desc = decode_error;
04909            goto alert_loser;              /* malformed. */
04910        }
04911 
04912        PRINT_BUF(60, (NULL, "Server DH p", dh_p.data, dh_p.len));
04913        PRINT_BUF(60, (NULL, "Server DH g", dh_g.data, dh_g.len));
04914        PRINT_BUF(60, (NULL, "Server DH Ys", dh_Ys.data, dh_Ys.len));
04915 
04916        /* failures after this point are not malformed handshakes. */
04917        /* TLS: send decrypt_error if signature failed. */
04918        desc = isTLS ? decrypt_error : handshake_failure;
04919 
04920        /*
04921         *  check to make sure the hash is signed by right guy
04922         */
04923        rv = ssl3_ComputeDHKeyHash(dh_p, dh_g, dh_Ys,
04924                                      &ss->ssl3.hs.client_random,
04925                                      &ss->ssl3.hs.server_random, 
04926                                      &hashes, ss->opt.bypassPKCS11);
04927         if (rv != SECSuccess) {
04928            errCode =
04929               ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
04930            goto alert_loser;
04931        }
04932         rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
04933                                 isTLS, ss->pkcs11PinArg);
04934        if (rv != SECSuccess)  {
04935            errCode =
04936               ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
04937            goto alert_loser;
04938        }
04939 
04940        /*
04941         * we really need to build a new key here because we can no longer
04942         * ignore calling SECKEY_DestroyPublicKey. Using the key may allocate
04943         * pkcs11 slots and ID's.
04944         */
04945        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
04946        if (arena == NULL) {
04947            goto no_memory;
04948        }
04949 
04950        ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
04951        if (peerKey == NULL) {
04952            goto no_memory;
04953        }
04954 
04955        peerKey->arena              = arena;
04956        peerKey->keyType            = dhKey;
04957        peerKey->pkcs11Slot         = NULL;
04958        peerKey->pkcs11ID           = CK_INVALID_HANDLE;
04959 
04960        if (SECITEM_CopyItem(arena, &peerKey->u.dh.prime,        &dh_p) ||
04961            SECITEM_CopyItem(arena, &peerKey->u.dh.base,         &dh_g) ||
04962            SECITEM_CopyItem(arena, &peerKey->u.dh.publicValue,  &dh_Ys))
04963        {
04964             PORT_FreeArena(arena, PR_FALSE);
04965            goto no_memory;
04966         }
04967        ss->sec.peerKey = peerKey;
04968        ss->ssl3.hs.ws = wait_cert_request;
04969        return SECSuccess;
04970     }
04971 
04972 #ifdef NSS_ENABLE_ECC
04973     case kt_ecdh:
04974        rv = ssl3_HandleECDHServerKeyExchange(ss, b, length);
04975        return rv;
04976 #endif /* NSS_ENABLE_ECC */
04977 
04978     default:
04979        desc    = handshake_failure;
04980        errCode = SEC_ERROR_UNSUPPORTED_KEYALG;
04981        break;        /* goto alert_loser; */
04982     }
04983 
04984 alert_loser:
04985     (void)SSL3_SendAlert(ss, alert_fatal, desc);
04986 loser:
04987     PORT_SetError( errCode );
04988     return SECFailure;
04989 
04990 no_memory:    /* no-memory error has already been set. */
04991     ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
04992     return SECFailure;
04993 }
04994 
04995 
04996 typedef struct dnameNode {
04997     struct dnameNode *next;
04998     SECItem           name;
04999 } dnameNode;
05000 
05001 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
05002  * ssl3 Certificate Request message.
05003  * Caller must hold Handshake and RecvBuf locks.
05004  */
05005 static SECStatus
05006 ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
05007 {
05008     PRArenaPool *        arena       = NULL;
05009     dnameNode *          node;
05010     PRInt32              remaining;
05011     PRBool               isTLS       = PR_FALSE;
05012     int                  i;
05013     int                  errCode     = SSL_ERROR_RX_MALFORMED_CERT_REQUEST;
05014     int                  nnames      = 0;
05015     SECStatus            rv;
05016     SSL3AlertDescription desc        = illegal_parameter;
05017     SECItem              cert_types  = {siBuffer, NULL, 0};
05018     CERTDistNames        ca_list;
05019 
05020     SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake",
05021               SSL_GETPID(), ss->fd));
05022     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
05023     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
05024 
05025     if (ss->ssl3.hs.ws != wait_cert_request &&
05026        ss->ssl3.hs.ws != wait_server_key) {
05027        desc    = unexpected_message;
05028        errCode = SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST;
05029        goto alert_loser;
05030     }
05031 
05032     /* clean up anything left from previous handshake. */
05033     if (ss->ssl3.clientCertChain != NULL) {
05034        CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
05035        ss->ssl3.clientCertChain = NULL;
05036     }
05037     if (ss->ssl3.clientCertificate != NULL) {
05038        CERT_DestroyCertificate(ss->ssl3.clientCertificate);
05039        ss->ssl3.clientCertificate = NULL;
05040     }
05041     if (ss->ssl3.clientPrivateKey != NULL) {
05042        SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
05043        ss->ssl3.clientPrivateKey = NULL;
05044     }
05045 
05046     isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
05047     rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length);
05048     if (rv != SECSuccess)
05049        goto loser;          /* malformed, alert has been sent */
05050 
05051     arena = ca_list.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
05052     if (arena == NULL)
05053        goto no_mem;
05054 
05055     remaining = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
05056     if (remaining < 0)
05057        goto loser;          /* malformed, alert has been sent */
05058 
05059     if ((PRUint32)remaining > length)
05060        goto alert_loser;
05061 
05062     ca_list.head = node = PORT_ArenaZNew(arena, dnameNode);
05063     if (node == NULL)
05064        goto no_mem;
05065 
05066     while (remaining > 0) {
05067        PRInt32 len;
05068 
05069        if (remaining < 2)
05070            goto alert_loser;       /* malformed */
05071 
05072        node->name.len = len = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
05073        if (len <= 0)
05074            goto loser;             /* malformed, alert has been sent */
05075 
05076        remaining -= 2;
05077        if (remaining < len)
05078            goto alert_loser;       /* malformed */
05079 
05080        node->name.data = b;
05081        b         += len;
05082        length    -= len;
05083        remaining -= len;
05084        nnames++;
05085        if (remaining <= 0)
05086            break;           /* success */
05087 
05088        node->next = PORT_ArenaZNew(arena, dnameNode);
05089        node = node->next;
05090        if (node == NULL)
05091            goto no_mem;
05092     }
05093 
05094     ca_list.nnames = nnames;
05095     ca_list.names  = PORT_ArenaNewArray(arena, SECItem, nnames);
05096     if (nnames > 0 && ca_list.names == NULL)
05097         goto no_mem;
05098 
05099     for(i = 0, node = (dnameNode*)ca_list.head;
05100        i < nnames;
05101        i++, node = node->next) {
05102        ca_list.names[i] = node->name;
05103     }
05104 
05105     if (length != 0)
05106         goto alert_loser;          /* malformed */
05107 
05108     desc = no_certificate;
05109     ss->ssl3.hs.ws = wait_hello_done;
05110 
05111     if (ss->getClientAuthData == NULL) {
05112        rv = SECFailure; /* force it to send a no_certificate alert */
05113     } else {
05114        /* XXX Should pass cert_types in this call!! */
05115        rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg,
05116                                            ss->fd, &ca_list,
05117                                            &ss->ssl3.clientCertificate,
05118                                            &ss->ssl3.clientPrivateKey);
05119     }
05120     switch (rv) {
05121     case SECWouldBlock:     /* getClientAuthData has put up a dialog box. */
05122        ssl_SetAlwaysBlock(ss);
05123        break; /* not an error */
05124 
05125     case SECSuccess:
05126         /* check what the callback function returned */
05127         if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) {
05128             /* we are missing either the key or cert */
05129             if (ss->ssl3.clientCertificate) {
05130                 /* got a cert, but no key - free it */
05131                 CERT_DestroyCertificate(ss->ssl3.clientCertificate);
05132                 ss->ssl3.clientCertificate = NULL;
05133             }
05134             if (ss->ssl3.clientPrivateKey) {
05135                 /* got a key, but no cert - free it */
05136                 SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
05137                 ss->ssl3.clientPrivateKey = NULL;
05138             }
05139             goto send_no_certificate;
05140         }
05141        /* Setting ssl3.clientCertChain non-NULL will cause
05142         * ssl3_HandleServerHelloDone to call SendCertificate.
05143         */
05144        ss->ssl3.clientCertChain = CERT_CertChainFromCert(
05145                                    ss->ssl3.clientCertificate,
05146                                    certUsageSSLClient, PR_FALSE);
05147        if (ss->ssl3.clientCertChain == NULL) {
05148            if (ss->ssl3.clientCertificate != NULL) {
05149               CERT_DestroyCertificate(ss->ssl3.clientCertificate);
05150               ss->ssl3.clientCertificate = NULL;
05151            }
05152            if (ss->ssl3.clientPrivateKey != NULL) {
05153               SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
05154               ss->ssl3.clientPrivateKey = NULL;
05155            }
05156            goto send_no_certificate;
05157        }
05158        break; /* not an error */
05159 
05160     case SECFailure:
05161     default:
05162 send_no_certificate:
05163        if (isTLS) {
05164            ss->ssl3.sendEmptyCert = PR_TRUE;
05165        } else {
05166            (void)SSL3_SendAlert(ss, alert_warning, no_certificate);
05167        }
05168        rv = SECSuccess;
05169        break;
05170     }
05171     goto done;
05172 
05173 no_mem:
05174     rv = SECFailure;
05175     PORT_SetError(SEC_ERROR_NO_MEMORY);
05176     goto done;
05177 
05178 alert_loser:
05179     if (isTLS && desc == illegal_parameter)
05180        desc = decode_error;
05181     (void)SSL3_SendAlert(ss, alert_fatal, desc);
05182 loser:
05183     PORT_SetError(errCode);
05184     rv = SECFailure;
05185 done:
05186     if (arena != NULL)
05187        PORT_FreeArena(arena, PR_FALSE);
05188     return rv;
05189 }
05190 
05191 /*
05192  * attempt to restart the handshake after asynchronously handling
05193  * a request for the client's certificate.
05194  *
05195  * inputs:
05196  *     cert   Client cert chosen by application.
05197  *            Note: ssl takes this reference, and does not bump the
05198  *            reference count.  The caller should drop its reference
05199  *            without calling CERT_DestroyCert after calling this function.
05200  *
05201  *     key    Private key associated with cert.  This function makes a
05202  *            copy of the private key, so the caller remains responsible
05203  *            for destroying its copy after this function returns.
05204  *
05205  *     certChain  DER-encoded certs, client cert and its signers.
05206  *            Note: ssl takes this reference, and does not copy the chain.
05207  *            The caller should drop its reference without destroying the
05208  *            chain.  SSL will free the chain when it is done with it.
05209  *
05210  * Return value: XXX
05211  *
05212  * XXX This code only works on the initial handshake on a connection, XXX
05213  *     It does not work on a subsequent handshake (redo).
05214  *
05215  * Caller holds 1stHandshakeLock.
05216  */
05217 SECStatus
05218 ssl3_RestartHandshakeAfterCertReq(sslSocket *         ss,
05219                             CERTCertificate *    cert,
05220                             SECKEYPrivateKey *   key,
05221                             CERTCertificateList *certChain)
05222 {
05223     SECStatus        rv          = SECSuccess;
05224 
05225     if (MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0)) {
05226        /* XXX This code only works on the initial handshake on a connection,
05227        ** XXX It does not work on a subsequent handshake (redo).
05228        */
05229        if (ss->handshake != 0) {
05230            ss->handshake               = ssl_GatherRecord1stHandshake;
05231            ss->ssl3.clientCertificate = cert;
05232            ss->ssl3.clientCertChain   = certChain;
05233            if (key == NULL) {
05234               (void)SSL3_SendAlert(ss, alert_warning, no_certificate);
05235               ss->ssl3.clientPrivateKey = NULL;
05236            } else {
05237               ss->ssl3.clientPrivateKey = SECKEY_CopyPrivateKey(key);
05238            }
05239            ssl_GetRecvBufLock(ss);
05240            if (ss->ssl3.hs.msgState.buf != NULL) {
05241               rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
05242            }
05243            ssl_ReleaseRecvBufLock(ss);
05244        }
05245     }
05246     return rv;
05247 }
05248 
05249 
05250 
05251 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
05252  * ssl3 Server Hello Done message.
05253  * Caller must hold Handshake and RecvBuf locks.
05254  */
05255 static SECStatus
05256 ssl3_HandleServerHelloDone(sslSocket *ss)
05257 {
05258     SECStatus     rv;
05259     SSL3WaitState ws          = ss->ssl3.hs.ws;
05260     PRBool        send_verify = PR_FALSE;
05261 
05262     SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello_done handshake",
05263               SSL_GETPID(), ss->fd));
05264     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
05265     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
05266 
05267     if (ws != wait_hello_done  &&
05268         ws != wait_server_cert &&
05269        ws != wait_server_key  &&
05270        ws != wait_cert_request) {
05271        SSL3_SendAlert(ss, alert_fatal, unexpected_message);
05272        PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
05273        return SECFailure;
05274     }
05275 
05276     ssl_GetXmitBufLock(ss);        /*******************************/
05277 
05278     if (ss->ssl3.sendEmptyCert) {
05279        ss->ssl3.sendEmptyCert = PR_FALSE;
05280        rv = ssl3_SendEmptyCertificate(ss);
05281        /* Don't send verify */
05282        if (rv != SECSuccess) {
05283            goto loser;      /* error code is set. */
05284        }
05285     } else
05286     if (ss->ssl3.clientCertChain  != NULL &&
05287        ss->ssl3.clientPrivateKey != NULL) {
05288        send_verify = PR_TRUE;
05289        rv = ssl3_SendCertificate(ss);
05290        if (rv != SECSuccess) {
05291            goto loser;      /* error code is set. */
05292        }
05293     }
05294 
05295     rv = ssl3_SendClientKeyExchange(ss);
05296     if (rv != SECSuccess) {
05297        goto loser;   /* err is set. */
05298     }
05299 
05300     if (send_verify) {
05301        rv = ssl3_SendCertificateVerify(ss);
05302        if (rv != SECSuccess) {
05303            goto loser;      /* err is set. */
05304         }
05305     }
05306     rv = ssl3_SendChangeCipherSpecs(ss);
05307     if (rv != SECSuccess) {
05308        goto loser;   /* err code was set. */
05309     }
05310     rv = ssl3_SendFinished(ss, 0);
05311     if (rv != SECSuccess) {
05312        goto loser;   /* err code was set. */
05313     }
05314 
05315     ssl_ReleaseXmitBufLock(ss);           /*******************************/
05316 
05317     ss->ssl3.hs.ws = wait_change_cipher;
05318     return SECSuccess;
05319 
05320 loser:
05321     ssl_ReleaseXmitBufLock(ss);
05322     return rv;
05323 }
05324 
05325 /*
05326  * Routines used by servers
05327  */
05328 static SECStatus
05329 ssl3_SendHelloRequest(sslSocket *ss)
05330 {
05331     SECStatus rv;
05332 
05333     SSL_TRC(3, ("%d: SSL3[%d]: send hello_request handshake", SSL_GETPID(),
05334               ss->fd));
05335 
05336     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
05337     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
05338 
05339     rv = ssl3_AppendHandshakeHeader(ss, hello_request, 0);
05340     if (rv != SECSuccess) {
05341        return rv;    /* err set by AppendHandshake */
05342     }
05343     rv = ssl3_FlushHandshake(ss, 0);
05344     if (rv != SECSuccess) {
05345        return rv;    /* error code set by ssl3_FlushHandshake */
05346     }
05347     ss->ssl3.hs.ws = wait_client_hello;
05348     return SECSuccess;
05349 }
05350 
05351 /* Sets memory error when returning NULL.
05352  * Called from:
05353  *     ssl3_SendClientHello()
05354  *     ssl3_HandleServerHello()
05355  *     ssl3_HandleClientHello()
05356  *     ssl3_HandleV2ClientHello()
05357  */
05358 static sslSessionID *
05359 ssl3_NewSessionID(sslSocket *ss, PRBool is_server)
05360 {
05361     sslSessionID *sid;
05362 
05363     sid = PORT_ZNew(sslSessionID);
05364     if (sid == NULL)
05365        return sid;
05366 
05367     sid->peerID             = (ss->peerID == NULL) ? NULL : PORT_Strdup(ss->peerID);
05368     sid->urlSvrName  = (ss->url    == NULL) ? NULL : PORT_Strdup(ss->url);
05369     sid->addr           = ss->sec.ci.peer;
05370     sid->port           = ss->sec.ci.port;
05371     sid->references     = 1;
05372     sid->cached         = never_cached;
05373     sid->version        = ss->version;
05374 
05375     sid->u.ssl3.keys.resumable = PR_TRUE;
05376     sid->u.ssl3.policy         = SSL_ALLOWED;
05377     sid->u.ssl3.clientWriteKey = NULL;
05378     sid->u.ssl3.serverWriteKey = NULL;
05379 
05380     if (is_server) {
05381        SECStatus rv;
05382        int       pid = SSL_GETPID();
05383 
05384        sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
05385        sid->u.ssl3.sessionID[0]    = (pid >> 8) & 0xff;
05386        sid->u.ssl3.sessionID[1]    =  pid       & 0xff;
05387        rv = PK11_GenerateRandom(sid->u.ssl3.sessionID + 2,
05388                                 SSL3_SESSIONID_BYTES -2);
05389        if (rv != SECSuccess) {
05390            ssl_FreeSID(sid);
05391            ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
05392            return NULL;
05393        }
05394     }
05395     return sid;
05396 }
05397 
05398 /* Called from:  ssl3_HandleClientHello, ssl3_HandleV2ClientHello */
05399 static SECStatus
05400 ssl3_SendServerHelloSequence(sslSocket *ss)
05401 {
05402     const ssl3KEADef *kea_def;
05403     SECStatus         rv;
05404 
05405     SSL_TRC(3, ("%d: SSL3[%d]: begin send server_hello sequence",
05406               SSL_GETPID(), ss->fd));
05407 
05408     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
05409     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
05410 
05411     rv = ssl3_SendServerHello(ss);
05412     if (rv != SECSuccess) {
05413        return rv;    /* err code is set. */
05414     }
05415     rv = ssl3_SendCertificate(ss);
05416     if (rv != SECSuccess) {
05417        return rv;    /* error code is set. */
05418     }
05419     /* We have to do this after the call to ssl3_SendServerHello,
05420      * because kea_def is set up by ssl3_SendServerHello().
05421      */
05422     kea_def = ss->ssl3.hs.kea_def;
05423     ss->ssl3.hs.usedStepDownKey = PR_FALSE;
05424 
05425     if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) {
05426        /* see if we can legally use the key in the cert. */
05427        int keyLen;  /* bytes */
05428 
05429        keyLen = PK11_GetPrivateModulusLen(
05430                          ss->serverCerts[kea_def->exchKeyType].SERVERKEY);
05431 
05432        if (keyLen > 0 &&
05433            keyLen * BPB <= kea_def->key_size_limit ) {
05434            /* XXX AND cert is not signing only!! */
05435            /* just fall through and use it. */
05436        } else if (ss->stepDownKeyPair != NULL) {
05437            ss->ssl3.hs.usedStepDownKey = PR_TRUE;
05438            rv = ssl3_SendServerKeyExchange(ss);
05439            if (rv != SECSuccess) {
05440               return rv;    /* err code was set. */
05441            }
05442        } else {
05443 #ifndef HACKED_EXPORT_SERVER
05444            PORT_SetError(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED);
05445            return rv;
05446 #endif
05447        }
05448 #ifdef NSS_ENABLE_ECC
05449     } else if ((kea_def->kea == kea_ecdhe_rsa) ||
05450               (kea_def->kea == kea_ecdhe_ecdsa)) {
05451        rv = ssl3_SendServerKeyExchange(ss);
05452        if (rv != SECSuccess) {
05453            return rv;       /* err code was set. */
05454        }
05455 #endif /* NSS_ENABLE_ECC */
05456     }
05457 
05458     if (ss->opt.requestCertificate) {
05459        rv = ssl3_SendCertificateRequest(ss);
05460        if (rv != SECSuccess) {
05461            return rv;              /* err code is set. */
05462        }
05463     }
05464     rv = ssl3_SendServerHelloDone(ss);
05465     if (rv != SECSuccess) {
05466        return rv;           /* err code is set. */
05467     }
05468 
05469     ss->ssl3.hs.ws = (ss->opt.requestCertificate) ? wait_client_cert
05470                                                : wait_client_key;
05471     return SECSuccess;
05472 }
05473 
05474 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
05475  * ssl3 Client Hello message.
05476  * Caller must hold Handshake and RecvBuf locks.
05477  */
05478 static SECStatus
05479 ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
05480 {
05481     sslSessionID *      sid      = NULL;
05482     PRInt32          tmp;
05483     unsigned int        i;
05484     int                 j;
05485     SECStatus           rv;
05486     int                 errCode  = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
05487     SSL3AlertDescription desc    = illegal_parameter;
05488     SSL3ProtocolVersion version;
05489     SECItem             sidBytes = {siBuffer, NULL, 0};
05490     SECItem             suites   = {siBuffer, NULL, 0};
05491     SECItem             comps    = {siBuffer, NULL, 0};
05492     PRBool              haveSpecWriteLock = PR_FALSE;
05493     PRBool              haveXmitBufLock   = PR_FALSE;
05494 
05495     SSL_TRC(3, ("%d: SSL3[%d]: handle client_hello handshake",
05496        SSL_GETPID(), ss->fd));
05497 
05498     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
05499     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
05500 
05501     /* Get peer name of client */
05502     rv = ssl_GetPeerInfo(ss);
05503     if (rv != SECSuccess) {
05504        return rv;           /* error code is set. */
05505     }
05506 
05507     rv = ssl3_InitState(ss);
05508     if (rv != SECSuccess) {
05509        return rv;           /* ssl3_InitState has set the error code. */
05510     }
05511 
05512     if ((ss->ssl3.hs.ws != wait_client_hello) &&
05513        (ss->ssl3.hs.ws != idle_handshake)) {
05514        desc    = unexpected_message;
05515        errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO;
05516        goto alert_loser;
05517     }
05518 
05519     tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
05520     if (tmp < 0)
05521        goto loser;          /* malformed, alert already sent */
05522     ss->clientHelloVersion = version = (SSL3ProtocolVersion)tmp;
05523     rv = ssl3_NegotiateVersion(ss, version);
05524     if (rv != SECSuccess) {
05525        desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version : handshake_failure;
05526        errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
05527        goto alert_loser;
05528     }
05529 
05530     /* grab the client random data. */
05531     rv = ssl3_ConsumeHandshake(
05532        ss, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH, &b, &length);
05533     if (rv != SECSuccess) {
05534        goto loser;          /* malformed */
05535     }
05536 
05537     /* grab the client's SID, if present. */
05538     rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
05539     if (rv != SECSuccess) {
05540        goto loser;          /* malformed */
05541     }
05542 
05543     if (sidBytes.len > 0 && !ss->opt.noCache) {
05544        SSL_TRC(7, ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
05545                     SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
05546                   ss->sec.ci.peer.pr_s6_addr32[1], 
05547                   ss->sec.ci.peer.pr_s6_addr32[2],
05548                   ss->sec.ci.peer.pr_s6_addr32[3]));
05549        if (ssl_sid_lookup) {
05550            sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sidBytes.data, 
05551                                    sidBytes.len, ss->dbHandle);
05552        } else {
05553            errCode = SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED;
05554            goto loser;
05555        }
05556     }
05557 
05558     /* grab the list of cipher suites. */
05559     rv = ssl3_ConsumeHandshakeVariable(ss, &suites, 2, &b, &length);
05560     if (rv != SECSuccess) {
05561        goto loser;          /* malformed */
05562     }
05563 
05564     /* grab the list of compression methods. */
05565     rv = ssl3_ConsumeHandshakeVariable(ss, &comps, 1, &b, &length);
05566     if (rv != SECSuccess) {
05567        goto loser;          /* malformed */
05568     }
05569 
05570     desc = handshake_failure;
05571 
05572     if (sid != NULL) {
05573        /* We've found a session cache entry for this client.
05574         * Now, if we're going to require a client-auth cert,
05575         * and we don't already have this client's cert in the session cache,
05576         * and this is the first handshake on this connection (not a redo),
05577         * then drop this old cache entry and start a new session.
05578         */
05579        if ((sid->peerCert == NULL) && ss->opt.requestCertificate &&
05580            ((ss->opt.requireCertificate == SSL_REQUIRE_ALWAYS) ||
05581             (ss->opt.requireCertificate == SSL_REQUIRE_NO_ERROR) ||
05582             ((ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE) 
05583              && !ss->firstHsDone))) {
05584 
05585            SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok );
05586            ss->sec.uncache(sid);
05587            ssl_FreeSID(sid);
05588            sid = NULL;
05589        }
05590     }
05591 
05592 #ifdef NSS_ENABLE_ECC
05593     /* Disable any ECC cipher suites for which we have no cert. */
05594     ssl3_FilterECCipherSuitesByServerCerts(ss);
05595 #endif
05596 
05597 #ifdef PARANOID
05598     /* Look for a matching cipher suite. */
05599     j = ssl3_config_match_init(ss);
05600     if (j <= 0) {           /* no ciphers are working/supported by PK11 */
05601        errCode = PORT_GetError();  /* error code is already set. */
05602        goto alert_loser;
05603     }
05604 #endif
05605 
05606     /* If we already have a session for this client, be sure to pick the
05607     ** same cipher suite we picked before.
05608     ** This is not a loop, despite appearances.
05609     */
05610     if (sid) do {
05611        ssl3CipherSuiteCfg *suite = ss->cipherSuites;
05612        /* Find the entry for the cipher suite used in the cached session. */
05613        for (j = ssl_V3_SUITES_IMPLEMENTED; j > 0; --j, ++suite) {
05614            if (suite->cipher_suite == sid->u.ssl3.cipherSuite)
05615               break;
05616        }
05617        PORT_Assert(j > 0);
05618        if (j <= 0)
05619            break;
05620 #ifdef PARANOID
05621        /* Double check that the cached cipher suite is still enabled,
05622         * implemented, and allowed by policy.  Might have been disabled.
05623         * The product policy won't change during the process lifetime.  
05624         * Implemented ("isPresent") shouldn't change for servers.
05625         */
05626        if (!config_match(suite, ss->ssl3.policy, PR_TRUE))
05627            break;
05628 #else
05629        if (!suite->enabled)
05630            break;
05631 #endif
05632        /* Double check that the cached cipher suite is in the client's list */
05633        for (i = 0; i < suites.len; i += 2) {
05634            if ((suites.data[i]     == MSB(suite->cipher_suite)) &&
05635                (suites.data[i + 1] == LSB(suite->cipher_suite))) {
05636 
05637               ss->ssl3.hs.cipher_suite = suite->cipher_suite;
05638               ss->ssl3.hs.suite_def =
05639                   ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
05640               goto suite_found;
05641            }
05642        }
05643     } while (0);
05644 
05645     /* START A NEW SESSION */
05646 
05647     /* Handle TLS hello extensions, for SSL3 & TLS, 
05648      * only if we're not restarting a previous session.
05649      */
05650     if (length) {
05651        /* Get length of hello extensions */
05652        PRInt32 extension_length;
05653        extension_length = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
05654         if (extension_length < 0) {
05655            goto loser;                           /* alert already sent */
05656        }
05657        if (extension_length != length) {
05658            ssl3_DecodeError(ss);          /* send alert */
05659            goto loser;
05660        }
05661        rv = ssl3_HandleClientHelloExtensions(ss, &b, &length);
05662        if (rv != SECSuccess) {
05663            goto loser;             /* malformed */
05664        }
05665     }
05666 
05667 #ifndef PARANOID
05668     /* Look for a matching cipher suite. */
05669     j = ssl3_config_match_init(ss);
05670     if (j <= 0) {           /* no ciphers are working/supported by PK11 */
05671        errCode = PORT_GetError();  /* error code is already set. */
05672        goto alert_loser;
05673     }
05674 #endif
05675 
05676     /* Select a cipher suite.
05677     ** NOTE: This suite selection algorithm should be the same as the one in
05678     ** ssl3_HandleV2ClientHello().  
05679     */
05680     for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
05681        ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
05682        if (!config_match(suite, ss->ssl3.policy, PR_TRUE))
05683            continue;
05684        for (i = 0; i < suites.len; i += 2) {
05685            if ((suites.data[i]     == MSB(suite->cipher_suite)) &&
05686                (suites.data[i + 1] == LSB(suite->cipher_suite))) {
05687 
05688               ss->ssl3.hs.cipher_suite = suite->cipher_suite;
05689               ss->ssl3.hs.suite_def =
05690                   ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
05691               goto suite_found;
05692            }
05693        }
05694     }
05695     errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
05696     goto alert_loser;
05697 
05698 suite_found:
05699     /* Look for a matching compression algorithm. */
05700     for (i = 0; i < comps.len; i++) {
05701        for (j = 0; j < compressionMethodsCount; j++) {
05702            if (comps.data[i] == compressions[j]) {
05703               ss->ssl3.hs.compression = 
05704                                    (SSL3CompressionMethod)compressions[j];
05705               goto compression_found;
05706            }
05707        }
05708     }
05709     errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
05710                             /* null compression must be supported */
05711     goto alert_loser;
05712 
05713 compression_found:
05714     suites.data = NULL;
05715     comps.data = NULL;
05716 
05717     ss->sec.send = ssl3_SendApplicationData;
05718 
05719     /* If there are any failures while processing the old sid,
05720      * we don't consider them to be errors.  Instead, We just behave
05721      * as if the client had sent us no sid to begin with, and make a new one.
05722      */
05723     if (sid != NULL) do {
05724        ssl3CipherSpec *pwSpec;
05725        SECItem         wrappedMS;         /* wrapped key */
05726 
05727        if (sid->version != ss->version  ||
05728            sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite) {
05729            break;    /* not an error */
05730        }
05731 
05732        if (ss->sec.ci.sid) {
05733            ss->sec.uncache(ss->sec.ci.sid);
05734            PORT_Assert(ss->sec.ci.sid != sid);  /* should be impossible, but ... */
05735            if (ss->sec.ci.sid != sid) {
05736               ssl_FreeSID(ss->sec.ci.sid);
05737            }
05738            ss->sec.ci.sid = NULL;
05739        }
05740        /* we need to resurrect the master secret.... */
05741 
05742        ssl_GetSpecWriteLock(ss);  haveSpecWriteLock = PR_TRUE;
05743        pwSpec = ss->ssl3.pwSpec;
05744        if (sid->u.ssl3.keys.msIsWrapped) {
05745            PK11SymKey *    wrapKey;       /* wrapping key */
05746            CK_FLAGS        keyFlags      = 0;
05747            if (ss->opt.bypassPKCS11) {
05748               /* we cannot restart a non-bypass session in a 
05749               ** bypass socket.
05750               */
05751               break;  
05752            }
05753 
05754            wrapKey = getWrappingKey(ss, NULL, sid->u.ssl3.exchKeyType,
05755                                  sid->u.ssl3.masterWrapMech, 
05756                                  ss->pkcs11PinArg);
05757            if (!wrapKey) {
05758               /* we have a SID cache entry, but no wrapping key for it??? */
05759               break;
05760            }
05761 
05762            if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
05763               keyFlags = CKF_SIGN | CKF_VERIFY;
05764            }
05765 
05766            wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
05767            wrappedMS.len  = sid->u.ssl3.keys.wrapped_master_secret_len;
05768 
05769            /* unwrap the master secret. */
05770            pwSpec->master_secret =
05771               PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech, 
05772                          NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
05773                          CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
05774            PK11_FreeSymKey(wrapKey);
05775            if (pwSpec->master_secret == NULL) {
05776               break; /* not an error */
05777            }
05778        } else if (ss->opt.bypassPKCS11) {
05779            wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
05780            wrappedMS.len  = sid->u.ssl3.keys.wrapped_master_secret_len;
05781            memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
05782            pwSpec->msItem.data = pwSpec->raw_master_secret;
05783            pwSpec->msItem.len  = wrappedMS.len;
05784        } else {
05785            /* We CAN restart a bypass session in a non-bypass socket. */
05786            /* need to import the raw master secret to session object */
05787            PK11SlotInfo * slot;
05788            wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
05789            wrappedMS.len  = sid->u.ssl3.keys.wrapped_master_secret_len;
05790            slot = PK11_GetInternalSlot();
05791            pwSpec->master_secret =  
05792               PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE, 
05793                               PK11_OriginUnwrap, CKA_ENCRYPT, &wrappedMS, 
05794                               NULL);
05795            PK11_FreeSlot(slot);
05796            if (pwSpec->master_secret == NULL) {
05797               break; /* not an error */
05798            }
05799        }
05800        ss->sec.ci.sid = sid;
05801        if (sid->peerCert != NULL) {
05802            ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
05803        }
05804 
05805        /*
05806         * Old SID passed all tests, so resume this old session.
05807         *
05808         * XXX make sure compression still matches
05809         */
05810        SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_hits );
05811        ss->ssl3.hs.isResuming = PR_TRUE;
05812 
05813         ss->sec.authAlgorithm = sid->authAlgorithm;
05814        ss->sec.authKeyBits   = sid->authKeyBits;
05815        ss->sec.keaType       = sid->keaType;
05816        ss->sec.keaKeyBits    = sid->keaKeyBits;
05817 
05818        /* server sids don't remember the server cert we previously sent,
05819        ** but they do remember the kea type we originally used, so we
05820        ** can locate it again, provided that the current ssl socket
05821        ** has had its server certs configured the same as the previous one.
05822        */
05823        ss->sec.localCert     = 
05824               CERT_DupCertificate(ss->serverCerts[sid->keaType].serverCert);
05825 
05826        ssl_GetXmitBufLock(ss); haveXmitBufLock = PR_TRUE;
05827 
05828        rv = ssl3_SendServerHello(ss);
05829        if (rv != SECSuccess) {
05830            errCode = PORT_GetError();
05831            goto loser;
05832        }
05833 
05834        if (haveSpecWriteLock) {
05835            ssl_ReleaseSpecWriteLock(ss);
05836            haveSpecWriteLock = PR_FALSE;
05837        }
05838 
05839        /* NULL value for PMS signifies re-use of the old MS */
05840        rv = ssl3_InitPendingCipherSpec(ss,  NULL);
05841        if (rv != SECSuccess) {
05842            errCode = PORT_GetError();
05843            goto loser;
05844        }
05845 
05846        rv = ssl3_SendChangeCipherSpecs(ss);
05847        if (rv != SECSuccess) {
05848            errCode = PORT_GetError();
05849            goto loser;
05850        }
05851        rv = ssl3_SendFinished(ss, 0);
05852        ss->ssl3.hs.ws = wait_change_cipher;
05853        if (rv != SECSuccess) {
05854            errCode = PORT_GetError();
05855            goto loser;
05856        }
05857 
05858        if (haveXmitBufLock) {
05859            ssl_ReleaseXmitBufLock(ss);
05860            haveXmitBufLock = PR_FALSE;
05861        }
05862 
05863         return SECSuccess;
05864     } while (0);
05865 
05866     if (haveSpecWriteLock) {
05867        ssl_ReleaseSpecWriteLock(ss);
05868        haveSpecWriteLock = PR_FALSE;
05869     }
05870 
05871     if (sid) {       /* we had a sid, but it's no longer valid, free it */
05872        SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok );
05873        ss->sec.uncache(sid);
05874        ssl_FreeSID(sid);
05875        sid = NULL;
05876     }
05877     SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses );
05878 
05879     sid = ssl3_NewSessionID(ss, PR_TRUE);
05880     if (sid == NULL) {
05881        errCode = PORT_GetError();
05882        goto loser;   /* memory error is set. */
05883     }
05884     ss->sec.ci.sid = sid;
05885 
05886     ss->ssl3.hs.isResuming = PR_FALSE;
05887     ssl_GetXmitBufLock(ss);
05888     rv = ssl3_SendServerHelloSequence(ss);
05889     ssl_ReleaseXmitBufLock(ss);
05890     if (rv != SECSuccess) {
05891        errCode = PORT_GetError();
05892        goto loser;
05893     }
05894 
05895     if (haveXmitBufLock) {
05896        ssl_ReleaseXmitBufLock(ss);
05897        haveXmitBufLock = PR_FALSE;
05898     }
05899 
05900     return SECSuccess;
05901 
05902 alert_loser:
05903     if (haveSpecWriteLock) {
05904        ssl_ReleaseSpecWriteLock(ss);
05905        haveSpecWriteLock = PR_FALSE;
05906     }
05907     (void)SSL3_SendAlert(ss, alert_fatal, desc);
05908     /* FALLTHRU */
05909 loser:
05910     if (haveSpecWriteLock) {
05911        ssl_ReleaseSpecWriteLock(ss);
05912        haveSpecWriteLock = PR_FALSE;
05913     }
05914 
05915     if (haveXmitBufLock) {
05916        ssl_ReleaseXmitBufLock(ss);
05917        haveXmitBufLock = PR_FALSE;
05918     }
05919 
05920     PORT_SetError(errCode);
05921     return SECFailure;
05922 }
05923 
05924 /*
05925  * ssl3_HandleV2ClientHello is used when a V2 formatted hello comes
05926  * in asking to use the V3 handshake.
05927  * Called from ssl2_HandleClientHelloMessage() in sslcon.c
05928  */
05929 SECStatus
05930 ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
05931 {
05932     sslSessionID *      sid               = NULL;
05933     unsigned char *     suites;
05934     unsigned char *     random;
05935     SSL3ProtocolVersion version;
05936     SECStatus           rv;
05937     int                 i;
05938     int                 j;
05939     int                 sid_length;
05940     int                 suite_length;
05941     int                 rand_length;
05942     int                 errCode  = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
05943     SSL3AlertDescription desc    = handshake_failure;
05944 
05945     SSL_TRC(3, ("%d: SSL3[%d]: handle v2 client_hello", SSL_GETPID(), ss->fd));
05946 
05947     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
05948 
05949     ssl_GetSSL3HandshakeLock(ss);
05950 
05951     rv = ssl3_InitState(ss);
05952     if (rv != SECSuccess) {
05953        ssl_ReleaseSSL3HandshakeLock(ss);
05954        return rv;           /* ssl3_InitState has set the error code. */
05955     }
05956 
05957     if (ss->ssl3.hs.ws != wait_client_hello) {
05958        desc    = unexpected_message;
05959        errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO;
05960        goto loser;   /* alert_loser */
05961     }
05962 
05963     version      = (buffer[1] << 8) | buffer[2];
05964     suite_length = (buffer[3] << 8) | buffer[4];
05965     sid_length   = (buffer[5] << 8) | buffer[6];
05966     rand_length  = (buffer[7] << 8) | buffer[8];
05967     ss->clientHelloVersion = version;
05968 
05969     rv = ssl3_NegotiateVersion(ss, version);
05970     if (rv != SECSuccess) {
05971        /* send back which ever alert client will understand. */
05972        desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version : handshake_failure;
05973        errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
05974        goto alert_loser;
05975     }
05976 
05977     /* if we get a non-zero SID, just ignore it. */
05978     if (length !=
05979         SSL_HL_CLIENT_HELLO_HBYTES + suite_length + sid_length + rand_length) {
05980        SSL_DBG(("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d",
05981                SSL_GETPID(), ss->fd, length,
05982                SSL_HL_CLIENT_HELLO_HBYTES + suite_length + sid_length +
05983                rand_length));
05984        goto loser;   /* malformed */      /* alert_loser */
05985     }
05986 
05987     suites = buffer + SSL_HL_CLIENT_HELLO_HBYTES;
05988     random = suites + suite_length + sid_length;
05989 
05990     if (rand_length < SSL_MIN_CHALLENGE_BYTES ||
05991        rand_length > SSL_MAX_CHALLENGE_BYTES) {
05992        goto loser;   /* malformed */      /* alert_loser */
05993     }
05994 
05995     PORT_Assert(SSL_MAX_CHALLENGE_BYTES == SSL3_RANDOM_LENGTH);
05996 
05997     PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
05998     PORT_Memcpy(
05999        &ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH - rand_length],
06000        random, rand_length);
06001 
06002     PRINT_BUF(60, (ss, "client random:", &ss->ssl3.hs.client_random.rand[0],
06003                  SSL3_RANDOM_LENGTH));
06004 #ifdef NSS_ENABLE_ECC
06005     /* Disable any ECC cipher suites for which we have no cert. */
06006     ssl3_FilterECCipherSuitesByServerCerts(ss);
06007 #endif
06008     i = ssl3_config_match_init(ss);
06009     if (i <= 0) {
06010        errCode = PORT_GetError();  /* error code is already set. */
06011        goto alert_loser;
06012     }
06013 
06014     /* Select a cipher suite.
06015     ** NOTE: This suite selection algorithm should be the same as the one in
06016     ** ssl3_HandleClientHello().  
06017     */
06018     for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
06019        ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
06020        if (!config_match(suite, ss->ssl3.policy, PR_TRUE))
06021            continue;
06022        for (i = 0; i < suite_length; i += 3) {
06023            if ((suites[i]   == 0) &&
06024               (suites[i+1] == MSB(suite->cipher_suite)) &&
06025               (suites[i+2] == LSB(suite->cipher_suite))) {
06026 
06027               ss->ssl3.hs.cipher_suite = suite->cipher_suite;
06028               ss->ssl3.hs.suite_def =
06029                   ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
06030               goto suite_found;
06031            }
06032        }
06033     }
06034     errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
06035     goto alert_loser;
06036 
06037 suite_found:
06038 
06039     ss->ssl3.hs.compression = compression_null;
06040     ss->sec.send            = ssl3_SendApplicationData;
06041 
06042     /* we don't even search for a cache hit here.  It's just a miss. */
06043     SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses );
06044     sid = ssl3_NewSessionID(ss, PR_TRUE);
06045     if (sid == NULL) {
06046        errCode = PORT_GetError();
06047        goto loser;   /* memory error is set. */
06048     }
06049     ss->sec.ci.sid = sid;
06050     /* do not worry about memory leak of sid since it now belongs to ci */
06051 
06052     /* We have to update the handshake hashes before we can send stuff */
06053     rv = ssl3_UpdateHandshakeHashes(ss, buffer, length);
06054     if (rv != SECSuccess) {
06055        errCode = PORT_GetError();
06056        goto loser;
06057     }
06058 
06059     ssl_GetXmitBufLock(ss);
06060     rv = ssl3_SendServerHelloSequence(ss);
06061     ssl_ReleaseXmitBufLock(ss);
06062     if (rv != SECSuccess) {
06063        errCode = PORT_GetError();
06064        goto loser;
06065     }
06066 
06067     /* XXX_1  The call stack to here is:
06068      * ssl_Do1stHandshake -> ssl2_HandleClientHelloMessage -> here.
06069      * ssl2_HandleClientHelloMessage returns whatever we return here.
06070      * ssl_Do1stHandshake will continue looping if it gets back either
06071      *        SECSuccess or SECWouldBlock.
06072      * SECSuccess is preferable here.  See XXX_1 in sslgathr.c.
06073      */
06074     ssl_ReleaseSSL3HandshakeLock(ss);
06075     return SECSuccess;
06076 
06077 alert_loser:
06078     SSL3_SendAlert(ss, alert_fatal, desc);
06079 loser:
06080     ssl_ReleaseSSL3HandshakeLock(ss);
06081     PORT_SetError(errCode);
06082     return SECFailure;
06083 }
06084 
06085 /* The negotiated version number has been already placed in ss->version.
06086 **
06087 ** Called from:  ssl3_HandleClientHello                     (resuming session),
06088 **     ssl3_SendServerHelloSequence <- ssl3_HandleClientHello   (new session),
06089 **     ssl3_SendServerHelloSequence <- ssl3_HandleV2ClientHello (new session)
06090 */
06091 static SECStatus
06092 ssl3_SendServerHello(sslSocket *ss)
06093 {
06094     sslSessionID *sid;
06095     SECStatus     rv;
06096     PRUint32      maxBytes = 65535;
06097     PRUint32      length;
06098     PRInt32       extensions_len = 0;
06099 
06100     SSL_TRC(3, ("%d: SSL3[%d]: send server_hello handshake", SSL_GETPID(),
06101               ss->fd));
06102 
06103     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
06104     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
06105     PORT_Assert( MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0));
06106 
06107     if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
06108        PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
06109        return SECFailure;
06110     }
06111 
06112     sid = ss->sec.ci.sid;
06113 
06114     extensions_len = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes,
06115                                           &ss->serverExtensionSenders[0]);
06116     if (extensions_len > 0)
06117        extensions_len += 2; /* Add sizeof total extension length */
06118 
06119     length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH + 1 +
06120              ((sid == NULL) ? 0: SSL3_SESSIONID_BYTES) +
06121             sizeof(ssl3CipherSuite) + 1 + extensions_len;
06122     rv = ssl3_AppendHandshakeHeader(ss, server_hello, length);
06123     if (rv != SECSuccess) {
06124        return rv;    /* err set by AppendHandshake. */
06125     }
06126 
06127     rv = ssl3_AppendHandshakeNumber(ss, ss->version, 2);
06128     if (rv != SECSuccess) {
06129        return rv;    /* err set by AppendHandshake. */
06130     }
06131     rv = ssl3_GetNewRandom(&ss->ssl3.hs.server_random);
06132     if (rv != SECSuccess) {
06133        ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
06134        return rv;
06135     }
06136     rv = ssl3_AppendHandshake(
06137        ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
06138     if (rv != SECSuccess) {
06139        return rv;    /* err set by AppendHandshake. */
06140     }
06141 
06142     if (sid)
06143        rv = ssl3_AppendHandshakeVariable(
06144            ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
06145     else
06146        rv = ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
06147     if (rv != SECSuccess) {
06148        return rv;    /* err set by AppendHandshake. */
06149     }
06150 
06151     rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.cipher_suite, 2);
06152     if (rv != SECSuccess) {
06153        return rv;    /* err set by AppendHandshake. */
06154     }
06155     rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.compression, 1);
06156     if (rv != SECSuccess) {
06157        return rv;    /* err set by AppendHandshake. */
06158     }
06159     if (extensions_len) {
06160        PRInt32 sent_len;
06161 
06162        extensions_len -= 2;
06163        rv = ssl3_AppendHandshakeNumber(ss, extensions_len, 2);
06164        if (rv != SECSuccess) 
06165            return rv;       /* err set by ssl3_SetupPendingCipherSpec */
06166        sent_len = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, extensions_len,
06167                                       &ss->serverExtensionSenders[0]);
06168         PORT_Assert(sent_len == extensions_len);
06169        if (sent_len != extensions_len) {
06170            if (sent_len >= 0)
06171               PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
06172            return SECFailure;
06173        }
06174     }
06175     rv = ssl3_SetupPendingCipherSpec(ss);
06176     if (rv != SECSuccess) {
06177        return rv;    /* err set by ssl3_SetupPendingCipherSpec */
06178     }
06179 
06180     return SECSuccess;
06181 }
06182 
06183 
06184 static SECStatus
06185 ssl3_SendServerKeyExchange(sslSocket *ss)
06186 {
06187 const ssl3KEADef *     kea_def     = ss->ssl3.hs.kea_def;
06188     SECStatus          rv          = SECFailure;
06189     int                length;
06190     PRBool             isTLS;
06191     SECItem            signed_hash = {siBuffer, NULL, 0};
06192     SSL3Hashes         hashes;
06193     SECKEYPublicKey *  sdPub;      /* public key for step-down */
06194 
06195     SSL_TRC(3, ("%d: SSL3[%d]: send server_key_exchange handshake",
06196               SSL_GETPID(), ss->fd));
06197 
06198     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
06199     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
06200 
06201     switch (kea_def->exchKeyType) {
06202     case kt_rsa:
06203        /* Perform SSL Step-Down here. */
06204        sdPub = ss->stepDownKeyPair->pubKey;
06205        PORT_Assert(sdPub != NULL);
06206        if (!sdPub) {
06207            PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
06208            return SECFailure;
06209        }
06210        rv = ssl3_ComputeExportRSAKeyHash(sdPub->u.rsa.modulus,
06211                                      sdPub->u.rsa.publicExponent,
06212                                          &ss->ssl3.hs.client_random,
06213                                          &ss->ssl3.hs.server_random,
06214                                      &hashes, ss->opt.bypassPKCS11);
06215         if (rv != SECSuccess) {
06216            ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
06217            return rv;
06218        }
06219 
06220        isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
06221        rv = ssl3_SignHashes(&hashes, ss->serverCerts[kt_rsa].SERVERKEY, 
06222                             &signed_hash, isTLS);
06223         if (rv != SECSuccess) {
06224            goto loser;             /* ssl3_SignHashes has set err. */
06225        }
06226        if (signed_hash.data == NULL) {
06227            /* how can this happen and rv == SECSuccess ?? */
06228            PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
06229            goto loser;
06230        }
06231        length = 2 + sdPub->u.rsa.modulus.len +
06232                 2 + sdPub->u.rsa.publicExponent.len +
06233                 2 + signed_hash.len;
06234 
06235        rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
06236        if (rv != SECSuccess) {
06237            goto loser;      /* err set by AppendHandshake. */
06238        }
06239 
06240        rv = ssl3_AppendHandshakeVariable(ss, sdPub->u.rsa.modulus.data,
06241                                      sdPub->u.rsa.modulus.len, 2);
06242        if (rv != SECSuccess) {
06243            goto loser;      /* err set by AppendHandshake. */
06244        }
06245 
06246        rv = ssl3_AppendHandshakeVariable(
06247                             ss, sdPub->u.rsa.publicExponent.data,
06248                             sdPub->u.rsa.publicExponent.len, 2);
06249        if (rv != SECSuccess) {
06250            goto loser;      /* err set by AppendHandshake. */
06251        }
06252 
06253        rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
06254                                          signed_hash.len, 2);
06255        if (rv != SECSuccess) {
06256            goto loser;      /* err set by AppendHandshake. */
06257        }
06258        PORT_Free(signed_hash.data);
06259        return SECSuccess;
06260 
06261 #ifdef NSS_ENABLE_ECC
06262     case kt_ecdh: {
06263        rv = ssl3_SendECDHServerKeyExchange(ss);
06264        return rv;
06265     }
06266 #endif /* NSS_ENABLE_ECC */
06267 
06268     case kt_dh:
06269     case kt_null:
06270     default:
06271        PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
06272        break;
06273     }
06274 loser:
06275     if (signed_hash.data != NULL) 
06276        PORT_Free(signed_hash.data);
06277     return SECFailure;
06278 }
06279 
06280 
06281 static SECStatus
06282 ssl3_SendCertificateRequest(sslSocket *ss)
06283 {
06284     SECItem *      name;
06285     CERTDistNames *ca_list;
06286 const uint8 *      certTypes;
06287     SECItem *      names    = NULL;
06288     SECStatus      rv;
06289     int            length;
06290     int            i;
06291     int            calen    = 0;
06292     int            nnames   = 0;
06293     int            certTypesLength;
06294 
06295     SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake",
06296               SSL_GETPID(), ss->fd));
06297 
06298     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
06299     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
06300 
06301     /* ssl3.ca_list is initialized to NULL, and never changed. */
06302     ca_list = ss->ssl3.ca_list;
06303     if (!ca_list) {
06304        ca_list = ssl3_server_ca_list;
06305     }
06306 
06307     if (ca_list != NULL) {
06308        names = ca_list->names;
06309        nnames = ca_list->nnames;
06310     }
06311 
06312     if (!nnames) {
06313        PORT_SetError(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA);
06314        return SECFailure;
06315     }
06316 
06317     for (i = 0, name = names; i < nnames; i++, name++) {
06318        calen += 2 + name->len;
06319     }
06320 
06321     certTypes       = certificate_types;
06322     certTypesLength = sizeof certificate_types;
06323 
06324     length = 1 + certTypesLength + 2 + calen;
06325 
06326     rv = ssl3_AppendHandshakeHeader(ss, certificate_request, length);
06327     if (rv != SECSuccess) {
06328        return rv;           /* err set by AppendHandshake. */
06329     }
06330     rv = ssl3_AppendHandshakeVariable(ss, certTypes, certTypesLength, 1);
06331     if (rv != SECSuccess) {
06332        return rv;           /* err set by AppendHandshake. */
06333     }
06334     rv = ssl3_AppendHandshakeNumber(ss, calen, 2);
06335     if (rv != SECSuccess) {
06336        return rv;           /* err set by AppendHandshake. */
06337     }
06338     for (i = 0, name = names; i < nnames; i++, name++) {
06339        rv = ssl3_AppendHandshakeVariable(ss, name->data, name->len, 2);
06340        if (rv != SECSuccess) {
06341            return rv;              /* err set by AppendHandshake. */
06342        }
06343     }
06344 
06345     return SECSuccess;
06346 }
06347 
06348 static SECStatus
06349 ssl3_SendServerHelloDone(sslSocket *ss)
06350 {
06351     SECStatus rv;
06352 
06353     SSL_TRC(3, ("%d: SSL3[%d]: send server_hello_done handshake",
06354               SSL_GETPID(), ss->fd));
06355 
06356     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
06357     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
06358 
06359     rv = ssl3_AppendHandshakeHeader(ss, server_hello_done, 0);
06360     if (rv != SECSuccess) {
06361        return rv;           /* err set by AppendHandshake. */
06362     }
06363     rv = ssl3_FlushHandshake(ss, 0);
06364     if (rv != SECSuccess) {
06365        return rv;    /* error code set by ssl3_FlushHandshake */
06366     }
06367     return SECSuccess;
06368 }
06369 
06370 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
06371  * ssl3 Certificate Verify message
06372  * Caller must hold Handshake and RecvBuf locks.
06373  */
06374 static SECStatus
06375 ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
06376                           SSL3Hashes *hashes)
06377 {
06378     SECItem              signed_hash = {siBuffer, NULL, 0};
06379     SECStatus            rv;
06380     int                  errCode     = SSL_ERROR_RX_MALFORMED_CERT_VERIFY;
06381     SSL3AlertDescription desc        = handshake_failure;
06382     PRBool               isTLS;
06383 
06384     SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_verify handshake",
06385               SSL_GETPID(), ss->fd));
06386     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
06387     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
06388 
06389     if (ss->ssl3.hs.ws != wait_cert_verify || ss->sec.peerCert == NULL) {
06390        desc    = unexpected_message;
06391        errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY;
06392        goto alert_loser;
06393     }
06394 
06395     rv = ssl3_ConsumeHandshakeVariable(ss, &signed_hash, 2, &b, &length);
06396     if (rv != SECSuccess) {
06397        goto loser;          /* malformed. */
06398     }
06399 
06400     isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
06401 
06402     /* XXX verify that the key & kea match */
06403     rv = ssl3_VerifySignedHashes(hashes, ss->sec.peerCert, &signed_hash,
06404                              isTLS, ss->pkcs11PinArg);
06405     if (rv != SECSuccess) {
06406        errCode = PORT_GetError();
06407        desc = isTLS ? decrypt_error : handshake_failure;
06408        goto alert_loser;
06409     }
06410 
06411     signed_hash.data = NULL;
06412 
06413     if (length != 0) {
06414        desc    = isTLS ? decode_error : illegal_parameter;
06415        goto alert_loser;    /* malformed */
06416     }
06417     ss->ssl3.hs.ws = wait_change_cipher;
06418     return SECSuccess;
06419 
06420 alert_loser:
06421     SSL3_SendAlert(ss, alert_fatal, desc);
06422 loser:
06423     PORT_SetError(errCode);
06424     return SECFailure;
06425 }
06426 
06427 
06428 /* find a slot that is able to generate a PMS and wrap it with RSA.
06429  * Then generate and return the PMS.
06430  * If the serverKeySlot parameter is non-null, this function will use
06431  * that slot to do the job, otherwise it will find a slot.
06432  *
06433  * Called from  ssl3_DeriveConnectionKeysPKCS11()  (above)
06434  *            sendRSAClientKeyExchange()         (above)
06435  *            ssl3_HandleRSAClientKeyExchange()  (below)
06436  * Caller must hold the SpecWriteLock, the SSL3HandshakeLock
06437  */
06438 static PK11SymKey *
06439 ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
06440                     PK11SlotInfo * serverKeySlot)
06441 {
06442     PK11SymKey *      pms          = NULL;
06443     PK11SlotInfo *    slot         = serverKeySlot;
06444     void *          pwArg          = ss->pkcs11PinArg;
06445     SECItem           param;
06446     CK_VERSION             version;
06447     CK_MECHANISM_TYPE mechanism_array[3];
06448 
06449     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
06450 
06451     if (slot == NULL) {
06452        SSLCipherAlgorithm calg;
06453        /* The specReadLock would suffice here, but we cannot assert on
06454        ** read locks.  Also, all the callers who call with a non-null
06455        ** slot already hold the SpecWriteLock.
06456        */
06457        PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
06458        PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
06459 
06460         calg = spec->cipher_def->calg;
06461        PORT_Assert(alg2Mech[calg].calg == calg);
06462 
06463        /* First get an appropriate slot.  */
06464        mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN;
06465        mechanism_array[1] = CKM_RSA_PKCS;
06466        mechanism_array[2] = alg2Mech[calg].cmech;
06467 
06468        slot = PK11_GetBestSlotMultiple(mechanism_array, 3, pwArg);
06469        if (slot == NULL) {
06470           /* can't find a slot with all three, find a slot with the minimum */
06471            slot = PK11_GetBestSlotMultiple(mechanism_array, 2, pwArg);
06472            if (slot == NULL) {
06473               PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND);
06474               return pms;   /* which is NULL */
06475            }
06476        }
06477     }
06478 
06479     /* Generate the pre-master secret ...  */
06480     version.major = MSB(ss->clientHelloVersion);
06481     version.minor = LSB(ss->clientHelloVersion);
06482 
06483     param.data = (unsigned char *)&version;
06484     param.len  = sizeof version;
06485 
06486     pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, &param, 0, pwArg);
06487     if (!serverKeySlot)
06488        PK11_FreeSlot(slot);
06489     if (pms == NULL) {
06490        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
06491     }
06492     return pms;
06493 }
06494 
06495 /* Note: The Bleichenbacher attack on PKCS#1 necessitates that we NEVER
06496  * return any indication of failure of the Client Key Exchange message,
06497  * where that failure is caused by the content of the client's message.
06498  * This function must not return SECFailure for any reason that is directly
06499  * or indirectly caused by the content of the client's encrypted PMS.
06500  * We must not send an alert and also not drop the connection.
06501  * Instead, we generate a random PMS.  This will cause a failure
06502  * in the processing the finished message, which is exactly where
06503  * the failure must occur.
06504  *
06505  * Called from ssl3_HandleClientKeyExchange
06506  */
06507 static SECStatus
06508 ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
06509                                 SSL3Opaque *b,
06510                             PRUint32 length,
06511                             SECKEYPrivateKey *serverKey)
06512 {
06513     PK11SymKey *      pms;
06514     unsigned char *   cr     = (unsigned char *)&ss->ssl3.hs.client_random;
06515     unsigned char *   sr     = (unsigned char *)&ss->ssl3.hs.server_random;
06516     ssl3CipherSpec *  pwSpec = ss->ssl3.pwSpec;
06517     unsigned int      outLen = 0;
06518     PRBool            isTLS  = PR_FALSE;
06519     SECStatus         rv;
06520     SECItem           enc_pms;
06521     unsigned char     rsaPmsBuf[SSL3_RSA_PMS_LENGTH];
06522     SECItem           pmsItem = {siBuffer, rsaPmsBuf, sizeof rsaPmsBuf};
06523 
06524     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
06525     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
06526 
06527     enc_pms.data = b;
06528     enc_pms.len  = length;
06529 
06530     if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
06531        PRInt32 kLen;
06532        kLen = ssl3_ConsumeHandshakeNumber(ss, 2, &enc_pms.data, &enc_pms.len);
06533        if (kLen < 0) {
06534            PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
06535            return SECFailure;
06536        }
06537        if ((unsigned)kLen < enc_pms.len) {
06538            enc_pms.len = kLen;
06539        }
06540        isTLS = PR_TRUE;
06541     } else {
06542        isTLS = (PRBool)(ss->ssl3.hs.kea_def->tls_keygen != 0);
06543     }
06544 
06545     if (ss->opt.bypassPKCS11) {
06546        /* TRIPLE BYPASS, get PMS directly from RSA decryption.
06547         * Use PK11_PrivDecryptPKCS1 to decrypt the PMS to a buffer, 
06548         * then, check for version rollback attack, then 
06549         * do the equivalent of ssl3_DeriveMasterSecret, placing the MS in 
06550         * pwSpec->msItem.  Finally call ssl3_InitPendingCipherSpec with 
06551         * ss and NULL, so that it will use the MS we've already derived here. 
06552         */
06553 
06554        rv = PK11_PrivDecryptPKCS1(serverKey, rsaPmsBuf, &outLen, 
06555                                sizeof rsaPmsBuf, enc_pms.data, enc_pms.len);
06556        if (rv != SECSuccess) {
06557            /* triple bypass failed.  Let's try for a double bypass. */
06558            goto double_bypass;
06559        } else if (ss->opt.detectRollBack) {
06560            SSL3ProtocolVersion client_version = 
06561                                     (rsaPmsBuf[0] << 8) | rsaPmsBuf[1];
06562            if (client_version != ss->clientHelloVersion) {
06563               /* Version roll-back detected. ensure failure.  */
06564               rv = PK11_GenerateRandom(rsaPmsBuf, sizeof rsaPmsBuf);
06565            }
06566        }
06567        /* have PMS, build MS without PKCS11 */
06568        rv = ssl3_MasterKeyDeriveBypass(pwSpec, cr, sr, &pmsItem, isTLS, 
06569                                    PR_TRUE);
06570        if (rv != SECSuccess) {
06571            pwSpec->msItem.data = pwSpec->raw_master_secret;
06572            pwSpec->msItem.len  = SSL3_MASTER_SECRET_LENGTH;
06573            PK11_GenerateRandom(pwSpec->msItem.data, pwSpec->msItem.len);
06574        }
06575        rv = ssl3_InitPendingCipherSpec(ss,  NULL);
06576     } else {
06577 double_bypass:
06578        /*
06579         * unwrap pms out of the incoming buffer
06580         * Note: CKM_SSL3_MASTER_KEY_DERIVE is NOT the mechanism used to do 
06581         *     the unwrap.  Rather, it is the mechanism with which the 
06582         *      unwrapped pms will be used.
06583         */
06584        pms = PK11_PubUnwrapSymKey(serverKey, &enc_pms,
06585                                CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
06586        if (pms != NULL) {
06587            PRINT_BUF(60, (ss, "decrypted premaster secret:",
06588                         PK11_GetKeyData(pms)->data,
06589                         PK11_GetKeyData(pms)->len));
06590        } else {
06591            /* unwrap failed. Generate a bogus PMS and carry on. */
06592            PK11SlotInfo *  slot   = PK11_GetSlotFromPrivateKey(serverKey);
06593 
06594            ssl_GetSpecWriteLock(ss);
06595            pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot);
06596            ssl_ReleaseSpecWriteLock(ss);
06597            PK11_FreeSlot(slot);
06598        }
06599 
06600        if (pms == NULL) {
06601            /* last gasp.  */
06602            ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
06603            return SECFailure;
06604        }
06605 
06606        /* This step will derive the MS from the PMS, among other things. */
06607        rv = ssl3_InitPendingCipherSpec(ss,  pms);
06608        PK11_FreeSymKey(pms);
06609     }
06610 
06611     if (rv != SECSuccess) {
06612        SEND_ALERT
06613        return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
06614     }
06615     return SECSuccess;
06616 }
06617 
06618 
06619 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
06620  * ssl3 ClientKeyExchange message from the remote client
06621  * Caller must hold Handshake and RecvBuf locks.
06622  */
06623 static SECStatus
06624 ssl3_HandleClientKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
06625 {
06626     SECKEYPrivateKey *serverKey         = NULL;
06627     SECStatus         rv;
06628 const ssl3KEADef *    kea_def;
06629     ssl3KeyPair     *serverKeyPair      = NULL;
06630 #ifdef NSS_ENABLE_ECC
06631     SECKEYPublicKey *serverPubKey       = NULL;
06632 #endif /* NSS_ENABLE_ECC */
06633 
06634     SSL_TRC(3, ("%d: SSL3[%d]: handle client_key_exchange handshake",
06635               SSL_GETPID(), ss->fd));
06636 
06637     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
06638     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
06639 
06640     if (ss->ssl3.hs.ws != wait_client_key) {
06641        SSL3_SendAlert(ss, alert_fatal, unexpected_message);
06642        PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH);
06643        return SECFailure;
06644     }
06645 
06646     kea_def   = ss->ssl3.hs.kea_def;
06647 
06648     if (ss->ssl3.hs.usedStepDownKey) {
06649         PORT_Assert(kea_def->is_limited /* XXX OR cert is signing only */
06650                && kea_def->exchKeyType == kt_rsa 
06651                && ss->stepDownKeyPair != NULL);
06652         if (!kea_def->is_limited  ||
06653              kea_def->exchKeyType != kt_rsa ||
06654              ss->stepDownKeyPair == NULL) {
06655               /* shouldn't happen, don't use step down if it does */
06656               goto skip;
06657         }
06658        serverKeyPair = ss->stepDownKeyPair;
06659        ss->sec.keaKeyBits = EXPORT_RSA_KEY_LENGTH * BPB;
06660     } else 
06661 skip:
06662 #ifdef NSS_ENABLE_ECC
06663     /* XXX Using SSLKEAType to index server certifiates
06664      * does not work for (EC)DHE ciphers. Until we have
06665      * an indexing mechanism general enough for all key
06666      * exchange algorithms, we'll need to deal with each
06667      * one seprately.
06668      */
06669     if ((kea_def->kea == kea_ecdhe_rsa) ||
06670                (kea_def->kea == kea_ecdhe_ecdsa)) {
06671        if (ss->ephemeralECDHKeyPair != NULL) {
06672           serverKeyPair = ss->ephemeralECDHKeyPair;
06673           if (serverKeyPair->pubKey) {
06674               ss->sec.keaKeyBits = 
06675                   SECKEY_PublicKeyStrengthInBits(serverKeyPair->pubKey);
06676           }
06677        }
06678     } else 
06679 #endif
06680     {
06681        sslServerCerts * sc = ss->serverCerts + kea_def->exchKeyType;
06682        serverKeyPair = sc->serverKeyPair;
06683        ss->sec.keaKeyBits = sc->serverKeyBits;
06684     }
06685 
06686     if (serverKeyPair) {
06687        serverKey = serverKeyPair->privKey;
06688     }
06689 
06690     if (serverKey == NULL) {
06691        SEND_ALERT
06692        PORT_SetError(SSL_ERROR_NO_SERVER_KEY_FOR_ALG);
06693        return SECFailure;
06694     }
06695 
06696     ss->sec.keaType    = kea_def->exchKeyType;
06697 
06698     switch (kea_def->exchKeyType) {
06699     case kt_rsa:
06700        rv = ssl3_HandleRSAClientKeyExchange(ss, b, length, serverKey);
06701        if (rv != SECSuccess) {
06702            SEND_ALERT
06703            return SECFailure;      /* error code set */
06704        }
06705        break;
06706 
06707 
06708 #ifdef NSS_ENABLE_ECC
06709     case kt_ecdh:
06710        /* XXX We really ought to be able to store multiple
06711         * EC certs (a requirement if we wish to support both
06712         * ECDH-RSA and ECDH-ECDSA key exchanges concurrently).
06713         * When we make that change, we'll need an index other
06714         * than kt_ecdh to pick the right EC certificate.
06715         */
06716        if (serverKeyPair) {
06717            serverPubKey = serverKeyPair->pubKey;
06718         }
06719        if (serverPubKey == NULL) {
06720            /* XXX Is this the right error code? */
06721            PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
06722            return SECFailure;
06723        }
06724        rv = ssl3_HandleECDHClientKeyExchange(ss, b, length, 
06725                                          serverPubKey, serverKey);
06726        if (rv != SECSuccess) {
06727            return SECFailure;      /* error code set */
06728        }
06729        break;
06730 #endif /* NSS_ENABLE_ECC */
06731 
06732     default:
06733        (void) ssl3_HandshakeFailure(ss);
06734        PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
06735        return SECFailure;
06736     }
06737     ss->ssl3.hs.ws = ss->sec.peerCert ? wait_cert_verify : wait_change_cipher;
06738     return SECSuccess;
06739 
06740 }
06741 
06742 /* This is TLS's equivalent of sending a no_certificate alert. */
06743 static SECStatus
06744 ssl3_SendEmptyCertificate(sslSocket *ss)
06745 {
06746     SECStatus            rv;
06747 
06748     rv = ssl3_AppendHandshakeHeader(ss, certificate, 3);
06749     if (rv == SECSuccess) {
06750        rv = ssl3_AppendHandshakeNumber(ss, 0, 3);
06751     }
06752     return rv;       /* error, if any, set by functions called above. */
06753 }
06754 
06755 #ifdef NISCC_TEST
06756 static PRInt32 connNum = 0;
06757 
06758 static SECStatus 
06759 get_fake_cert(SECItem *pCertItem, int *pIndex)
06760 {
06761     PRFileDesc *cf;
06762     char *      testdir;
06763     char *      startat;
06764     char *      stopat;
06765     const char *extension;
06766     int         fileNum;
06767     PRInt32     numBytes   = 0;
06768     PRStatus    prStatus;
06769     PRFileInfo  info;
06770     char        cfn[100];
06771 
06772     pCertItem->data = 0;
06773     if ((testdir = PR_GetEnv("NISCC_TEST")) == NULL) {
06774        return SECSuccess;
06775     }
06776     *pIndex   = (NULL != strstr(testdir, "root"));
06777     extension = (strstr(testdir, "simple") ? "" : ".der");
06778     fileNum     = PR_AtomicIncrement(&connNum) - 1;
06779     if ((startat = PR_GetEnv("START_AT")) != NULL) {
06780        fileNum += atoi(startat);
06781     }
06782     if ((stopat = PR_GetEnv("STOP_AT")) != NULL && 
06783        fileNum >= atoi(stopat)) {
06784        *pIndex = -1;
06785        return SECSuccess;
06786     }
06787     sprintf(cfn, "%s/%08d%s", testdir, fileNum, extension);
06788     cf = PR_Open(cfn, PR_RDONLY, 0);
06789     if (!cf) {
06790        goto loser;
06791     }
06792     prStatus = PR_GetOpenFileInfo(cf, &info);
06793     if (prStatus != PR_SUCCESS) {
06794        PR_Close(cf);
06795        goto loser;
06796     }
06797     pCertItem = SECITEM_AllocItem(NULL, pCertItem, info.size);
06798     if (pCertItem) {
06799        numBytes = PR_Read(cf, pCertItem->data, info.size);
06800     }
06801     PR_Close(cf);
06802     if (numBytes != info.size) {
06803        SECITEM_FreeItem(pCertItem, PR_FALSE);
06804        PORT_SetError(SEC_ERROR_IO);
06805        goto loser;
06806     }
06807     fprintf(stderr, "using %s\n", cfn);
06808     return SECSuccess;
06809 
06810 loser:
06811     fprintf(stderr, "failed to use %s\n", cfn);
06812     *pIndex = -1;
06813     return SECFailure;
06814 }
06815 #endif
06816 
06817 /*
06818  * Used by both client and server.
06819  * Called from HandleServerHelloDone and from SendServerHelloSequence.
06820  */
06821 static SECStatus
06822 ssl3_SendCertificate(sslSocket *ss)
06823 {
06824     SECStatus            rv;
06825     CERTCertificateList *certChain;
06826     int                  len              = 0;
06827     int                  i;
06828     SSL3KEAType          certIndex;
06829 #ifdef NISCC_TEST
06830     SECItem              fakeCert;
06831     int                  ndex           = -1;
06832 #endif
06833 
06834     SSL_TRC(3, ("%d: SSL3[%d]: send certificate handshake",
06835               SSL_GETPID(), ss->fd));
06836 
06837     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
06838     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
06839 
06840     if (ss->sec.localCert)
06841        CERT_DestroyCertificate(ss->sec.localCert);
06842     if (ss->sec.isServer) {
06843        sslServerCerts * sc = NULL;
06844 
06845        /* XXX SSLKEAType isn't really a good choice for 
06846         * indexing certificates (it breaks when we deal
06847         * with (EC)DHE-* cipher suites. This hack ensures
06848         * the RSA cert is picked for (EC)DHE-RSA.
06849         * Revisit this when we add server side support
06850         * for ECDHE-ECDSA or client-side authentication
06851         * using EC certificates.
06852         */
06853        if ((ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) ||
06854            (ss->ssl3.hs.kea_def->kea == kea_dhe_rsa)) {
06855            certIndex = kt_rsa;
06856        } else {
06857            certIndex = ss->ssl3.hs.kea_def->exchKeyType;
06858        }
06859        sc                    = ss->serverCerts + certIndex;
06860        certChain             = sc->serverCertChain;
06861        ss->sec.authKeyBits   = sc->serverKeyBits;
06862        ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType;
06863        ss->sec.localCert     = CERT_DupCertificate(sc->serverCert);
06864     } else {
06865        certChain          = ss->ssl3.clientCertChain;
06866        ss->sec.localCert = CERT_DupCertificate(ss->ssl3.clientCertificate);
06867     }
06868 
06869 #ifdef NISCC_TEST
06870     rv = get_fake_cert(&fakeCert, &ndex);
06871 #endif
06872 
06873     if (certChain) {
06874        for (i = 0; i < certChain->len; i++) {
06875 #ifdef NISCC_TEST
06876            if (fakeCert.len > 0 && i == ndex) {
06877               len += fakeCert.len + 3;
06878            } else {
06879               len += certChain->certs[i].len + 3;
06880            }
06881 #else
06882            len += certChain->certs[i].len + 3;
06883 #endif
06884        }
06885     }
06886 
06887     rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3);
06888     if (rv != SECSuccess) {
06889        return rv;           /* err set by AppendHandshake. */
06890     }
06891     rv = ssl3_AppendHandshakeNumber(ss, len, 3);
06892     if (rv != SECSuccess) {
06893        return rv;           /* err set by AppendHandshake. */
06894     }
06895     if (certChain) {
06896         for (i = 0; i < certChain->len; i++) {
06897 #ifdef NISCC_TEST
06898             if (fakeCert.len > 0 && i == ndex) {
06899                 rv = ssl3_AppendHandshakeVariable(ss, fakeCert.data,
06900                                                   fakeCert.len, 3);
06901                 SECITEM_FreeItem(&fakeCert, PR_FALSE);
06902             } else {
06903                 rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
06904                                                   certChain->certs[i].len, 3);
06905             }
06906 #else
06907             rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
06908                                               certChain->certs[i].len, 3);
06909 #endif
06910             if (rv != SECSuccess) {
06911                 return rv;         /* err set by AppendHandshake. */
06912             }
06913         }
06914     }
06915 
06916     return SECSuccess;
06917 }
06918 
06919 /* This is used to delete the CA certificates in the peer certificate chain
06920  * from the cert database after they've been validated.
06921  */
06922 static void
06923 ssl3_CleanupPeerCerts(sslSocket *ss)
06924 {
06925     PRArenaPool * arena = ss->ssl3.peerCertArena;
06926     ssl3CertNode *certs = (ssl3CertNode *)ss->ssl3.peerCertChain;
06927 
06928     for (; certs; certs = certs->next) {
06929        CERT_DestroyCertificate(certs->cert);
06930     }
06931     if (arena) PORT_FreeArena(arena, PR_FALSE);
06932     ss->ssl3.peerCertArena = NULL;
06933     ss->ssl3.peerCertChain = NULL;
06934 }
06935 
06936 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
06937  * ssl3 Certificate message.
06938  * Caller must hold Handshake and RecvBuf locks.
06939  */
06940 static SECStatus
06941 ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
06942 {
06943     ssl3CertNode *   c;
06944     ssl3CertNode *   certs  = NULL;
06945     PRArenaPool *    arena  = NULL;
06946     CERTCertificate *cert;
06947     PRInt32          remaining  = 0;
06948     PRInt32          size;
06949     SECStatus        rv;
06950     PRBool           isServer      = (PRBool)(!!ss->sec.isServer);
06951     PRBool           trusted       = PR_FALSE;
06952     PRBool           isTLS;
06953     SSL3AlertDescription desc      = bad_certificate;
06954     int              errCode    = SSL_ERROR_RX_MALFORMED_CERTIFICATE;
06955     SECItem          certItem;
06956 
06957     SSL_TRC(3, ("%d: SSL3[%d]: handle certificate handshake",
06958               SSL_GETPID(), ss->fd));
06959     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
06960     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
06961 
06962     if ((ss->ssl3.hs.ws != wait_server_cert) &&
06963        (ss->ssl3.hs.ws != wait_client_cert)) {
06964        desc    = unexpected_message;
06965        errCode = SSL_ERROR_RX_UNEXPECTED_CERTIFICATE;
06966        goto alert_loser;
06967     }
06968 
06969     if (ss->sec.peerCert != NULL) {
06970        if (ss->sec.peerKey) {
06971            SECKEY_DestroyPublicKey(ss->sec.peerKey);
06972            ss->sec.peerKey = NULL;
06973        }
06974        CERT_DestroyCertificate(ss->sec.peerCert);
06975        ss->sec.peerCert = NULL;
06976     }
06977 
06978     ssl3_CleanupPeerCerts(ss);
06979     isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
06980 
06981     /* It is reported that some TLS client sends a Certificate message
06982     ** with a zero-length message body.  We'll treat that case like a
06983     ** normal no_certificates message to maximize interoperability.
06984     */
06985     if (length) {
06986        remaining = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
06987        if (remaining < 0)
06988            goto loser;      /* fatal alert already sent by ConsumeHandshake. */
06989        if ((PRUint32)remaining > length)
06990            goto decode_loser;
06991     }
06992 
06993     if (!remaining) {
06994        if (!(isTLS && isServer))
06995            goto alert_loser;
06996        /* This is TLS's version of a no_certificate alert. */
06997        /* I'm a server. I've requested a client cert. He hasn't got one. */
06998        rv = ssl3_HandleNoCertificate(ss);
06999        if (rv != SECSuccess) {
07000            errCode = PORT_GetError();
07001            goto loser;
07002        }
07003        goto cert_block;
07004     }
07005 
07006     ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
07007     if ( arena == NULL ) {
07008        goto loser;   /* don't send alerts on memory errors */
07009     }
07010 
07011     /* First get the peer cert. */
07012     remaining -= 3;
07013     if (remaining < 0)
07014        goto decode_loser;
07015 
07016     size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
07017     if (size <= 0)
07018        goto loser;   /* fatal alert already sent by ConsumeHandshake. */
07019 
07020     if (remaining < size)
07021        goto decode_loser;
07022 
07023     certItem.data = b;
07024     certItem.len = size;
07025     b      += size;
07026     length -= size;
07027     remaining -= size;
07028 
07029     ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
07030                                             PR_FALSE, PR_TRUE);
07031     if (ss->sec.peerCert == NULL) {
07032        /* We should report an alert if the cert was bad, but not if the
07033         * problem was just some local problem, like memory error.
07034         */
07035        goto ambiguous_err;
07036     }
07037 
07038     /* Now get all of the CA certs. */
07039     while (remaining > 0) {
07040        remaining -= 3;
07041        if (remaining < 0)
07042            goto decode_loser;
07043 
07044        size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
07045        if (size <= 0)
07046            goto loser;      /* fatal alert already sent by ConsumeHandshake. */
07047 
07048        if (remaining < size)
07049            goto decode_loser;
07050 
07051        certItem.data = b;
07052        certItem.len = size;
07053        b      += size;
07054        length -= size;
07055        remaining -= size;
07056 
07057        c = PORT_ArenaNew(arena, ssl3CertNode);
07058        if (c == NULL) {
07059            goto loser;      /* don't send alerts on memory errors */
07060        }
07061 
07062        c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
07063                                          PR_FALSE, PR_TRUE);
07064        if (c->cert == NULL) {
07065            goto ambiguous_err;
07066        }
07067 
07068        if (c->cert->trust)
07069            trusted = PR_TRUE;
07070 
07071        c->next = certs;
07072        certs = c;
07073     }
07074 
07075     if (remaining != 0)
07076         goto decode_loser;
07077 
07078     SECKEY_UpdateCertPQG(ss->sec.peerCert);
07079 
07080     /*
07081      * Ask caller-supplied callback function to validate cert chain.
07082      */
07083     rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd,
07084                                       PR_TRUE, isServer);
07085     if (rv) {
07086        errCode = PORT_GetError();
07087        if (!ss->handleBadCert) {
07088            goto bad_cert;
07089        }
07090        rv = (SECStatus)(*ss->handleBadCert)(ss->badCertArg, ss->fd);
07091        if ( rv ) {
07092            if ( rv == SECWouldBlock ) {
07093               /* someone will handle this connection asynchronously*/
07094               SSL_DBG(("%d: SSL3[%d]: go to async cert handler",
07095                       SSL_GETPID(), ss->fd));
07096               ss->ssl3.peerCertChain = certs;
07097               certs               = NULL;
07098               ssl_SetAlwaysBlock(ss);
07099               goto cert_block;
07100            }
07101            /* cert is bad */
07102            goto bad_cert;
07103        }
07104        /* cert is good */
07105     }
07106 
07107     /* start SSL Step Up, if appropriate */
07108     cert = ss->sec.peerCert;
07109     if (!isServer &&
07110        ssl3_global_policy_some_restricted &&
07111         ss->ssl3.policy == SSL_ALLOWED &&
07112        anyRestrictedEnabled(ss) &&
07113        SECSuccess == CERT_VerifyCertNow(cert->dbhandle, cert,
07114                                         PR_FALSE, /* checkSig */
07115                                      certUsageSSLServerWithStepUp,
07116 /*XXX*/                                     ss->authCertificateArg) ) {
07117        ss->ssl3.policy         = SSL_RESTRICTED;
07118        ss->ssl3.hs.rehandshake = PR_TRUE;
07119     }
07120 
07121     ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
07122 
07123     if (!ss->sec.isServer) {
07124        /* set the server authentication and key exchange types and sizes
07125        ** from the value in the cert.  If the key exchange key is different,
07126        ** it will get fixed when we handle the server key exchange message.
07127        */
07128        SECKEYPublicKey * pubKey  = CERT_ExtractPublicKey(cert);
07129        ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType;
07130        ss->sec.keaType       = ss->ssl3.hs.kea_def->exchKeyType;
07131        if (pubKey) {
07132            ss->sec.keaKeyBits = ss->sec.authKeyBits =
07133               SECKEY_PublicKeyStrengthInBits(pubKey);
07134 #ifdef NSS_ENABLE_ECC
07135            if (ss->sec.keaType == kt_ecdh) {
07136               /* Get authKeyBits from signing key.
07137                * XXX The code below uses a quick approximation of
07138                * key size based on cert->signatureWrap.signature.data
07139                * (which contains the DER encoded signature). The field
07140                * cert->signatureWrap.signature.len contains the
07141                * length of the encoded signature in bits.
07142                */
07143               if (ss->ssl3.hs.kea_def->kea == kea_ecdh_ecdsa) {
07144                   ss->sec.authKeyBits = 
07145                      cert->signatureWrap.signature.data[3]*8;
07146                   if (cert->signatureWrap.signature.data[4] == 0x00)
07147                          ss->sec.authKeyBits -= 8;
07148                   /* 
07149                    * XXX: if cert is not signed by ecdsa we should
07150                    * destroy pubKey and goto bad_cert
07151                    */
07152               } else if (ss->ssl3.hs.kea_def->kea == kea_ecdh_rsa) {
07153                   ss->sec.authKeyBits = cert->signatureWrap.signature.len;
07154                   /* 
07155                    * XXX: if cert is not signed by rsa we should
07156                    * destroy pubKey and goto bad_cert
07157                    */
07158               }
07159            }
07160 #endif /* NSS_ENABLE_ECC */
07161            SECKEY_DestroyPublicKey(pubKey); 
07162            pubKey = NULL;
07163        }
07164     }
07165 
07166     ss->ssl3.peerCertChain = certs;  certs = NULL;  arena = NULL;
07167 
07168 cert_block:
07169     if (ss->sec.isServer) {
07170        ss->ssl3.hs.ws = wait_client_key;
07171     } else {
07172        ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */
07173        if (ss->ssl3.hs.kea_def->is_limited ||
07174            /* XXX OR server cert is signing only. */
07175 #ifdef NSS_ENABLE_ECC
07176            ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
07177            ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa ||
07178 #endif /* NSS_ENABLE_ECC */
07179            ss->ssl3.hs.kea_def->exchKeyType == kt_dh) {
07180            ss->ssl3.hs.ws = wait_server_key; /* allow server_key_exchange */
07181        }
07182     }
07183 
07184     /* rv must normally be equal to SECSuccess here.  If we called
07185      * handleBadCert, it can also be SECWouldBlock.
07186      */
07187     return rv;
07188 
07189 ambiguous_err:
07190     errCode = PORT_GetError();
07191     switch (errCode) {
07192     case PR_OUT_OF_MEMORY_ERROR:
07193     case SEC_ERROR_BAD_DATABASE:
07194     case SEC_ERROR_NO_MEMORY:
07195        if (isTLS) {
07196            desc = internal_error;
07197            goto alert_loser;
07198        }
07199        goto loser;
07200     }
07201     /* fall through to bad_cert. */
07202 
07203 bad_cert:     /* caller has set errCode. */
07204     switch (errCode) {
07205     case SEC_ERROR_LIBRARY_FAILURE:     desc = unsupported_certificate; break;
07206     case SEC_ERROR_EXPIRED_CERTIFICATE: desc = certificate_expired;     break;
07207     case SEC_ERROR_REVOKED_CERTIFICATE: desc = certificate_revoked;     break;
07208     case SEC_ERROR_INADEQUATE_KEY_USAGE:
07209     case SEC_ERROR_INADEQUATE_CERT_TYPE:
07210                                       desc = certificate_unknown;     break;
07211     case SEC_ERROR_UNTRUSTED_CERT:
07212                   desc = isTLS ? access_denied : certificate_unknown;