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