1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/ssl/sslcon.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,3696 @@ 1.4 +/* 1.5 + * SSL v2 handshake functions, and functions common to SSL2 and SSL3. 1.6 + * 1.7 + * This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 + 1.11 +#include "nssrenam.h" 1.12 +#include "cert.h" 1.13 +#include "secitem.h" 1.14 +#include "sechash.h" 1.15 +#include "cryptohi.h" /* for SGN_ funcs */ 1.16 +#include "keyhi.h" /* for SECKEY_ high level functions. */ 1.17 +#include "ssl.h" 1.18 +#include "sslimpl.h" 1.19 +#include "sslproto.h" 1.20 +#include "ssl3prot.h" 1.21 +#include "sslerr.h" 1.22 +#include "pk11func.h" 1.23 +#include "prinit.h" 1.24 +#include "prtime.h" /* for PR_Now() */ 1.25 + 1.26 +static PRBool policyWasSet; 1.27 + 1.28 +/* This ordered list is indexed by (SSL_CK_xx * 3) */ 1.29 +/* Second and third bytes are MSB and LSB of master key length. */ 1.30 +static const PRUint8 allCipherSuites[] = { 1.31 + 0, 0, 0, 1.32 + SSL_CK_RC4_128_WITH_MD5, 0x00, 0x80, 1.33 + SSL_CK_RC4_128_EXPORT40_WITH_MD5, 0x00, 0x80, 1.34 + SSL_CK_RC2_128_CBC_WITH_MD5, 0x00, 0x80, 1.35 + SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80, 1.36 + SSL_CK_IDEA_128_CBC_WITH_MD5, 0x00, 0x80, 1.37 + SSL_CK_DES_64_CBC_WITH_MD5, 0x00, 0x40, 1.38 + SSL_CK_DES_192_EDE3_CBC_WITH_MD5, 0x00, 0xC0, 1.39 + 0, 0, 0 1.40 +}; 1.41 + 1.42 +#define ssl2_NUM_SUITES_IMPLEMENTED 6 1.43 + 1.44 +/* This list is sent back to the client when the client-hello message 1.45 + * contains no overlapping ciphers, so the client can report what ciphers 1.46 + * are supported by the server. Unlike allCipherSuites (above), this list 1.47 + * is sorted by descending preference, not by cipherSuite number. 1.48 + */ 1.49 +static const PRUint8 implementedCipherSuites[ssl2_NUM_SUITES_IMPLEMENTED * 3] = { 1.50 + SSL_CK_RC4_128_WITH_MD5, 0x00, 0x80, 1.51 + SSL_CK_RC2_128_CBC_WITH_MD5, 0x00, 0x80, 1.52 + SSL_CK_DES_192_EDE3_CBC_WITH_MD5, 0x00, 0xC0, 1.53 + SSL_CK_DES_64_CBC_WITH_MD5, 0x00, 0x40, 1.54 + SSL_CK_RC4_128_EXPORT40_WITH_MD5, 0x00, 0x80, 1.55 + SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80 1.56 +}; 1.57 + 1.58 +typedef struct ssl2SpecsStr { 1.59 + PRUint8 nkm; /* do this many hashes to generate key material. */ 1.60 + PRUint8 nkd; /* size of readKey and writeKey in bytes. */ 1.61 + PRUint8 blockSize; 1.62 + PRUint8 blockShift; 1.63 + CK_MECHANISM_TYPE mechanism; 1.64 + PRUint8 keyLen; /* cipher symkey size in bytes. */ 1.65 + PRUint8 pubLen; /* publicly reveal this many bytes of key. */ 1.66 + PRUint8 ivLen; /* length of IV data at *ca. */ 1.67 +} ssl2Specs; 1.68 + 1.69 +static const ssl2Specs ssl_Specs[] = { 1.70 +/* NONE */ 1.71 + { 0, 0, 0, 0, }, 1.72 +/* SSL_CK_RC4_128_WITH_MD5 */ 1.73 + { 2, 16, 1, 0, CKM_RC4, 16, 0, 0, }, 1.74 +/* SSL_CK_RC4_128_EXPORT40_WITH_MD5 */ 1.75 + { 2, 16, 1, 0, CKM_RC4, 16, 11, 0, }, 1.76 +/* SSL_CK_RC2_128_CBC_WITH_MD5 */ 1.77 + { 2, 16, 8, 3, CKM_RC2_CBC, 16, 0, 8, }, 1.78 +/* SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 */ 1.79 + { 2, 16, 8, 3, CKM_RC2_CBC, 16, 11, 8, }, 1.80 +/* SSL_CK_IDEA_128_CBC_WITH_MD5 */ 1.81 + { 0, 0, 0, 0, }, 1.82 +/* SSL_CK_DES_64_CBC_WITH_MD5 */ 1.83 + { 1, 8, 8, 3, CKM_DES_CBC, 8, 0, 8, }, 1.84 +/* SSL_CK_DES_192_EDE3_CBC_WITH_MD5 */ 1.85 + { 3, 24, 8, 3, CKM_DES3_CBC, 24, 0, 8, }, 1.86 +}; 1.87 + 1.88 +#define SET_ERROR_CODE /* reminder */ 1.89 +#define TEST_FOR_FAILURE /* reminder */ 1.90 + 1.91 +/* 1.92 +** Put a string tag in the library so that we can examine an executable 1.93 +** and see what kind of security it supports. 1.94 +*/ 1.95 +const char *ssl_version = "SECURITY_VERSION:" 1.96 + " +us" 1.97 + " +export" 1.98 +#ifdef TRACE 1.99 + " +trace" 1.100 +#endif 1.101 +#ifdef DEBUG 1.102 + " +debug" 1.103 +#endif 1.104 + ; 1.105 + 1.106 +const char * const ssl_cipherName[] = { 1.107 + "unknown", 1.108 + "RC4", 1.109 + "RC4-Export", 1.110 + "RC2-CBC", 1.111 + "RC2-CBC-Export", 1.112 + "IDEA-CBC", 1.113 + "DES-CBC", 1.114 + "DES-EDE3-CBC", 1.115 + "unknown", 1.116 + "unknown", /* was fortezza, NO LONGER USED */ 1.117 +}; 1.118 + 1.119 + 1.120 +/* bit-masks, showing which SSLv2 suites are allowed. 1.121 + * lsb corresponds to first cipher suite in allCipherSuites[]. 1.122 + */ 1.123 +static PRUint16 allowedByPolicy; /* all off by default */ 1.124 +static PRUint16 maybeAllowedByPolicy; /* all off by default */ 1.125 +static PRUint16 chosenPreference = 0xff; /* all on by default */ 1.126 + 1.127 +/* bit values for the above two bit masks */ 1.128 +#define SSL_CB_RC4_128_WITH_MD5 (1 << SSL_CK_RC4_128_WITH_MD5) 1.129 +#define SSL_CB_RC4_128_EXPORT40_WITH_MD5 (1 << SSL_CK_RC4_128_EXPORT40_WITH_MD5) 1.130 +#define SSL_CB_RC2_128_CBC_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_WITH_MD5) 1.131 +#define SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5) 1.132 +#define SSL_CB_IDEA_128_CBC_WITH_MD5 (1 << SSL_CK_IDEA_128_CBC_WITH_MD5) 1.133 +#define SSL_CB_DES_64_CBC_WITH_MD5 (1 << SSL_CK_DES_64_CBC_WITH_MD5) 1.134 +#define SSL_CB_DES_192_EDE3_CBC_WITH_MD5 (1 << SSL_CK_DES_192_EDE3_CBC_WITH_MD5) 1.135 +#define SSL_CB_IMPLEMENTED \ 1.136 + (SSL_CB_RC4_128_WITH_MD5 | \ 1.137 + SSL_CB_RC4_128_EXPORT40_WITH_MD5 | \ 1.138 + SSL_CB_RC2_128_CBC_WITH_MD5 | \ 1.139 + SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 | \ 1.140 + SSL_CB_DES_64_CBC_WITH_MD5 | \ 1.141 + SSL_CB_DES_192_EDE3_CBC_WITH_MD5) 1.142 + 1.143 + 1.144 +/* Construct a socket's list of cipher specs from the global default values. 1.145 + */ 1.146 +static SECStatus 1.147 +ssl2_ConstructCipherSpecs(sslSocket *ss) 1.148 +{ 1.149 + PRUint8 * cs = NULL; 1.150 + unsigned int allowed; 1.151 + unsigned int count; 1.152 + int ssl3_count = 0; 1.153 + int final_count; 1.154 + int i; 1.155 + SECStatus rv; 1.156 + 1.157 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.158 + 1.159 + count = 0; 1.160 + PORT_Assert(ss != 0); 1.161 + allowed = !ss->opt.enableSSL2 ? 0 : 1.162 + (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED); 1.163 + while (allowed) { 1.164 + if (allowed & 1) 1.165 + ++count; 1.166 + allowed >>= 1; 1.167 + } 1.168 + 1.169 + /* Call ssl3_config_match_init() once here, 1.170 + * instead of inside ssl3_ConstructV2CipherSpecsHack(), 1.171 + * because the latter gets called twice below, 1.172 + * and then again in ssl2_BeginClientHandshake(). 1.173 + */ 1.174 + ssl3_config_match_init(ss); 1.175 + 1.176 + /* ask SSL3 how many cipher suites it has. */ 1.177 + rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3_count); 1.178 + if (rv < 0) 1.179 + return rv; 1.180 + count += ssl3_count; 1.181 + 1.182 + /* Allocate memory to hold cipher specs */ 1.183 + if (count > 0) 1.184 + cs = (PRUint8*) PORT_Alloc(count * 3); 1.185 + else 1.186 + PORT_SetError(SSL_ERROR_SSL_DISABLED); 1.187 + if (cs == NULL) 1.188 + return SECFailure; 1.189 + 1.190 + if (ss->cipherSpecs != NULL) { 1.191 + PORT_Free(ss->cipherSpecs); 1.192 + } 1.193 + ss->cipherSpecs = cs; 1.194 + ss->sizeCipherSpecs = count * 3; 1.195 + 1.196 + /* fill in cipher specs for SSL2 cipher suites */ 1.197 + allowed = !ss->opt.enableSSL2 ? 0 : 1.198 + (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED); 1.199 + for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) { 1.200 + const PRUint8 * hs = implementedCipherSuites + i; 1.201 + int ok = allowed & (1U << hs[0]); 1.202 + if (ok) { 1.203 + cs[0] = hs[0]; 1.204 + cs[1] = hs[1]; 1.205 + cs[2] = hs[2]; 1.206 + cs += 3; 1.207 + } 1.208 + } 1.209 + 1.210 + /* now have SSL3 add its suites onto the end */ 1.211 + rv = ssl3_ConstructV2CipherSpecsHack(ss, cs, &final_count); 1.212 + 1.213 + /* adjust for any difference between first pass and second pass */ 1.214 + ss->sizeCipherSpecs -= (ssl3_count - final_count) * 3; 1.215 + 1.216 + return rv; 1.217 +} 1.218 + 1.219 +/* This function is called immediately after ssl2_ConstructCipherSpecs() 1.220 +** at the beginning of a handshake. It detects cases where a protocol 1.221 +** (e.g. SSL2 or SSL3) is logically enabled, but all its cipher suites 1.222 +** for that protocol have been disabled. If such cases, it clears the 1.223 +** enable bit for the protocol. If no protocols remain enabled, or 1.224 +** if no cipher suites are found, it sets the error code and returns 1.225 +** SECFailure, otherwise it returns SECSuccess. 1.226 +*/ 1.227 +static SECStatus 1.228 +ssl2_CheckConfigSanity(sslSocket *ss) 1.229 +{ 1.230 + unsigned int allowed; 1.231 + int ssl3CipherCount = 0; 1.232 + SECStatus rv; 1.233 + 1.234 + /* count the SSL2 and SSL3 enabled ciphers. 1.235 + * if either is zero, clear the socket's enable for that protocol. 1.236 + */ 1.237 + if (!ss->cipherSpecs) 1.238 + goto disabled; 1.239 + 1.240 + allowed = ss->allowedByPolicy & ss->chosenPreference; 1.241 + if (! allowed) 1.242 + ss->opt.enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */ 1.243 + 1.244 + /* ssl3_config_match_init was called in ssl2_ConstructCipherSpecs(). */ 1.245 + /* Ask how many ssl3 CipherSuites were enabled. */ 1.246 + rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3CipherCount); 1.247 + if (rv != SECSuccess || ssl3CipherCount <= 0) { 1.248 + /* SSL3/TLS not really enabled if no ciphers */ 1.249 + ss->vrange.min = SSL_LIBRARY_VERSION_NONE; 1.250 + ss->vrange.max = SSL_LIBRARY_VERSION_NONE; 1.251 + } 1.252 + 1.253 + if (!ss->opt.enableSSL2 && SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { 1.254 + SSL_DBG(("%d: SSL[%d]: Can't handshake! all versions disabled.", 1.255 + SSL_GETPID(), ss->fd)); 1.256 +disabled: 1.257 + PORT_SetError(SSL_ERROR_SSL_DISABLED); 1.258 + return SECFailure; 1.259 + } 1.260 + return SECSuccess; 1.261 +} 1.262 + 1.263 +/* 1.264 + * Since this is a global (not per-socket) setting, we cannot use the 1.265 + * HandshakeLock to protect this. Probably want a global lock. 1.266 + */ 1.267 +SECStatus 1.268 +ssl2_SetPolicy(PRInt32 which, PRInt32 policy) 1.269 +{ 1.270 + PRUint32 bitMask; 1.271 + SECStatus rv = SECSuccess; 1.272 + 1.273 + which &= 0x000f; 1.274 + bitMask = 1 << which; 1.275 + 1.276 + if (!(bitMask & SSL_CB_IMPLEMENTED)) { 1.277 + PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); 1.278 + return SECFailure; 1.279 + } 1.280 + 1.281 + if (policy == SSL_ALLOWED) { 1.282 + allowedByPolicy |= bitMask; 1.283 + maybeAllowedByPolicy |= bitMask; 1.284 + } else if (policy == SSL_RESTRICTED) { 1.285 + allowedByPolicy &= ~bitMask; 1.286 + maybeAllowedByPolicy |= bitMask; 1.287 + } else { 1.288 + allowedByPolicy &= ~bitMask; 1.289 + maybeAllowedByPolicy &= ~bitMask; 1.290 + } 1.291 + allowedByPolicy &= SSL_CB_IMPLEMENTED; 1.292 + maybeAllowedByPolicy &= SSL_CB_IMPLEMENTED; 1.293 + 1.294 + policyWasSet = PR_TRUE; 1.295 + return rv; 1.296 +} 1.297 + 1.298 +SECStatus 1.299 +ssl2_GetPolicy(PRInt32 which, PRInt32 *oPolicy) 1.300 +{ 1.301 + PRUint32 bitMask; 1.302 + PRInt32 policy; 1.303 + 1.304 + which &= 0x000f; 1.305 + bitMask = 1 << which; 1.306 + 1.307 + /* Caller assures oPolicy is not null. */ 1.308 + if (!(bitMask & SSL_CB_IMPLEMENTED)) { 1.309 + PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); 1.310 + *oPolicy = SSL_NOT_ALLOWED; 1.311 + return SECFailure; 1.312 + } 1.313 + 1.314 + if (maybeAllowedByPolicy & bitMask) { 1.315 + policy = (allowedByPolicy & bitMask) ? SSL_ALLOWED : SSL_RESTRICTED; 1.316 + } else { 1.317 + policy = SSL_NOT_ALLOWED; 1.318 + } 1.319 + 1.320 + *oPolicy = policy; 1.321 + return SECSuccess; 1.322 +} 1.323 + 1.324 +/* 1.325 + * Since this is a global (not per-socket) setting, we cannot use the 1.326 + * HandshakeLock to protect this. Probably want a global lock. 1.327 + * Called from SSL_CipherPrefSetDefault in sslsock.c 1.328 + * These changes have no effect on any sslSockets already created. 1.329 + */ 1.330 +SECStatus 1.331 +ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled) 1.332 +{ 1.333 + PRUint32 bitMask; 1.334 + 1.335 + which &= 0x000f; 1.336 + bitMask = 1 << which; 1.337 + 1.338 + if (!(bitMask & SSL_CB_IMPLEMENTED)) { 1.339 + PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); 1.340 + return SECFailure; 1.341 + } 1.342 + 1.343 + if (enabled) 1.344 + chosenPreference |= bitMask; 1.345 + else 1.346 + chosenPreference &= ~bitMask; 1.347 + chosenPreference &= SSL_CB_IMPLEMENTED; 1.348 + 1.349 + return SECSuccess; 1.350 +} 1.351 + 1.352 +SECStatus 1.353 +ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled) 1.354 +{ 1.355 + PRBool rv = PR_FALSE; 1.356 + PRUint32 bitMask; 1.357 + 1.358 + which &= 0x000f; 1.359 + bitMask = 1 << which; 1.360 + 1.361 + if (!(bitMask & SSL_CB_IMPLEMENTED)) { 1.362 + PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); 1.363 + *enabled = PR_FALSE; 1.364 + return SECFailure; 1.365 + } 1.366 + 1.367 + rv = (PRBool)((chosenPreference & bitMask) != 0); 1.368 + *enabled = rv; 1.369 + return SECSuccess; 1.370 +} 1.371 + 1.372 +SECStatus 1.373 +ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled) 1.374 +{ 1.375 + PRUint32 bitMask; 1.376 + 1.377 + which &= 0x000f; 1.378 + bitMask = 1 << which; 1.379 + 1.380 + if (!(bitMask & SSL_CB_IMPLEMENTED)) { 1.381 + PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); 1.382 + return SECFailure; 1.383 + } 1.384 + 1.385 + if (enabled) 1.386 + ss->chosenPreference |= bitMask; 1.387 + else 1.388 + ss->chosenPreference &= ~bitMask; 1.389 + ss->chosenPreference &= SSL_CB_IMPLEMENTED; 1.390 + 1.391 + return SECSuccess; 1.392 +} 1.393 + 1.394 +SECStatus 1.395 +ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled) 1.396 +{ 1.397 + PRBool rv = PR_FALSE; 1.398 + PRUint32 bitMask; 1.399 + 1.400 + which &= 0x000f; 1.401 + bitMask = 1 << which; 1.402 + 1.403 + if (!(bitMask & SSL_CB_IMPLEMENTED)) { 1.404 + PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); 1.405 + *enabled = PR_FALSE; 1.406 + return SECFailure; 1.407 + } 1.408 + 1.409 + rv = (PRBool)((ss->chosenPreference & bitMask) != 0); 1.410 + *enabled = rv; 1.411 + return SECSuccess; 1.412 +} 1.413 + 1.414 + 1.415 +/* copy global default policy into socket. */ 1.416 +void 1.417 +ssl2_InitSocketPolicy(sslSocket *ss) 1.418 +{ 1.419 + ss->allowedByPolicy = allowedByPolicy; 1.420 + ss->maybeAllowedByPolicy = maybeAllowedByPolicy; 1.421 + ss->chosenPreference = chosenPreference; 1.422 +} 1.423 + 1.424 + 1.425 +/************************************************************************/ 1.426 + 1.427 +/* Called from ssl2_CreateSessionCypher(), which already holds handshake lock. 1.428 + */ 1.429 +static SECStatus 1.430 +ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey, 1.431 + int cipherChoice) 1.432 +{ 1.433 + switch (cipherChoice) { 1.434 + 1.435 + case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: 1.436 + case SSL_CK_RC2_128_CBC_WITH_MD5: 1.437 + case SSL_CK_RC4_128_EXPORT40_WITH_MD5: 1.438 + case SSL_CK_RC4_128_WITH_MD5: 1.439 + case SSL_CK_DES_64_CBC_WITH_MD5: 1.440 + case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: 1.441 + sec->hash = HASH_GetHashObject(HASH_AlgMD5); 1.442 + SECITEM_CopyItem(0, &sec->sendSecret, writeKey); 1.443 + SECITEM_CopyItem(0, &sec->rcvSecret, readKey); 1.444 + break; 1.445 + 1.446 + default: 1.447 + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); 1.448 + return SECFailure; 1.449 + } 1.450 + sec->hashcx = (*sec->hash->create)(); 1.451 + if (sec->hashcx == NULL) 1.452 + return SECFailure; 1.453 + return SECSuccess; 1.454 +} 1.455 + 1.456 +/************************************************************************ 1.457 + * All the Send functions below must acquire and release the socket's 1.458 + * xmitBufLock. 1.459 + */ 1.460 + 1.461 +/* Called from all the Send* functions below. */ 1.462 +static SECStatus 1.463 +ssl2_GetSendBuffer(sslSocket *ss, unsigned int len) 1.464 +{ 1.465 + SECStatus rv = SECSuccess; 1.466 + 1.467 + PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); 1.468 + 1.469 + if (len < 128) { 1.470 + len = 128; 1.471 + } 1.472 + if (len > ss->sec.ci.sendBuf.space) { 1.473 + rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, len); 1.474 + if (rv != SECSuccess) { 1.475 + SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d bytes", 1.476 + SSL_GETPID(), ss->fd, len)); 1.477 + rv = SECFailure; 1.478 + } 1.479 + } 1.480 + return rv; 1.481 +} 1.482 + 1.483 +/* Called from: 1.484 + * ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage() 1.485 + * ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() <- 1.486 + ssl_Do1stHandshake() 1.487 + * ssl2_HandleMessage() <- ssl_Do1stHandshake() 1.488 + * ssl2_HandleServerHelloMessage() <- ssl_Do1stHandshake() 1.489 + after ssl2_BeginClientHandshake() 1.490 + * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake() 1.491 + after ssl2_BeginServerHandshake() 1.492 + * 1.493 + * Acquires and releases the socket's xmitBufLock. 1.494 + */ 1.495 +int 1.496 +ssl2_SendErrorMessage(sslSocket *ss, int error) 1.497 +{ 1.498 + int rv; 1.499 + PRUint8 msg[SSL_HL_ERROR_HBYTES]; 1.500 + 1.501 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.502 + 1.503 + msg[0] = SSL_MT_ERROR; 1.504 + msg[1] = MSB(error); 1.505 + msg[2] = LSB(error); 1.506 + 1.507 + ssl_GetXmitBufLock(ss); /***************************************/ 1.508 + 1.509 + SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error)); 1.510 + 1.511 + ss->handshakeBegun = 1; 1.512 + rv = (*ss->sec.send)(ss, msg, sizeof(msg), 0); 1.513 + if (rv >= 0) { 1.514 + rv = SECSuccess; 1.515 + } 1.516 + ssl_ReleaseXmitBufLock(ss); /***************************************/ 1.517 + return rv; 1.518 +} 1.519 + 1.520 +/* Called from ssl2_TryToFinish(). 1.521 + * Acquires and releases the socket's xmitBufLock. 1.522 + */ 1.523 +static SECStatus 1.524 +ssl2_SendClientFinishedMessage(sslSocket *ss) 1.525 +{ 1.526 + SECStatus rv = SECSuccess; 1.527 + int sent; 1.528 + PRUint8 msg[1 + SSL_CONNECTIONID_BYTES]; 1.529 + 1.530 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.531 + 1.532 + ssl_GetXmitBufLock(ss); /***************************************/ 1.533 + 1.534 + if (ss->sec.ci.sentFinished == 0) { 1.535 + ss->sec.ci.sentFinished = 1; 1.536 + 1.537 + SSL_TRC(3, ("%d: SSL[%d]: sending client-finished", 1.538 + SSL_GETPID(), ss->fd)); 1.539 + 1.540 + msg[0] = SSL_MT_CLIENT_FINISHED; 1.541 + PORT_Memcpy(msg+1, ss->sec.ci.connectionID, 1.542 + sizeof(ss->sec.ci.connectionID)); 1.543 + 1.544 + DUMP_MSG(29, (ss, msg, 1 + sizeof(ss->sec.ci.connectionID))); 1.545 + sent = (*ss->sec.send)(ss, msg, 1 + sizeof(ss->sec.ci.connectionID), 0); 1.546 + rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; 1.547 + } 1.548 + ssl_ReleaseXmitBufLock(ss); /***************************************/ 1.549 + return rv; 1.550 +} 1.551 + 1.552 +/* Called from 1.553 + * ssl2_HandleClientSessionKeyMessage() <- ssl2_HandleClientHelloMessage() 1.554 + * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake() 1.555 + after ssl2_BeginServerHandshake() 1.556 + * Acquires and releases the socket's xmitBufLock. 1.557 + */ 1.558 +static SECStatus 1.559 +ssl2_SendServerVerifyMessage(sslSocket *ss) 1.560 +{ 1.561 + PRUint8 * msg; 1.562 + int sendLen; 1.563 + int sent; 1.564 + SECStatus rv; 1.565 + 1.566 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.567 + 1.568 + ssl_GetXmitBufLock(ss); /***************************************/ 1.569 + 1.570 + sendLen = 1 + SSL_CHALLENGE_BYTES; 1.571 + rv = ssl2_GetSendBuffer(ss, sendLen); 1.572 + if (rv != SECSuccess) { 1.573 + goto done; 1.574 + } 1.575 + 1.576 + msg = ss->sec.ci.sendBuf.buf; 1.577 + msg[0] = SSL_MT_SERVER_VERIFY; 1.578 + PORT_Memcpy(msg+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); 1.579 + 1.580 + DUMP_MSG(29, (ss, msg, sendLen)); 1.581 + sent = (*ss->sec.send)(ss, msg, sendLen, 0); 1.582 + 1.583 + rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; 1.584 + 1.585 +done: 1.586 + ssl_ReleaseXmitBufLock(ss); /***************************************/ 1.587 + return rv; 1.588 +} 1.589 + 1.590 +/* Called from ssl2_TryToFinish(). 1.591 + * Acquires and releases the socket's xmitBufLock. 1.592 + */ 1.593 +static SECStatus 1.594 +ssl2_SendServerFinishedMessage(sslSocket *ss) 1.595 +{ 1.596 + sslSessionID * sid; 1.597 + PRUint8 * msg; 1.598 + int sendLen, sent; 1.599 + SECStatus rv = SECSuccess; 1.600 + 1.601 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.602 + 1.603 + ssl_GetXmitBufLock(ss); /***************************************/ 1.604 + 1.605 + if (ss->sec.ci.sentFinished == 0) { 1.606 + ss->sec.ci.sentFinished = 1; 1.607 + PORT_Assert(ss->sec.ci.sid != 0); 1.608 + sid = ss->sec.ci.sid; 1.609 + 1.610 + SSL_TRC(3, ("%d: SSL[%d]: sending server-finished", 1.611 + SSL_GETPID(), ss->fd)); 1.612 + 1.613 + sendLen = 1 + sizeof(sid->u.ssl2.sessionID); 1.614 + rv = ssl2_GetSendBuffer(ss, sendLen); 1.615 + if (rv != SECSuccess) { 1.616 + goto done; 1.617 + } 1.618 + 1.619 + msg = ss->sec.ci.sendBuf.buf; 1.620 + msg[0] = SSL_MT_SERVER_FINISHED; 1.621 + PORT_Memcpy(msg+1, sid->u.ssl2.sessionID, 1.622 + sizeof(sid->u.ssl2.sessionID)); 1.623 + 1.624 + DUMP_MSG(29, (ss, msg, sendLen)); 1.625 + sent = (*ss->sec.send)(ss, msg, sendLen, 0); 1.626 + 1.627 + if (sent < 0) { 1.628 + /* If send failed, it is now a bogus session-id */ 1.629 + if (ss->sec.uncache) 1.630 + (*ss->sec.uncache)(sid); 1.631 + rv = (SECStatus)sent; 1.632 + } else if (!ss->opt.noCache) { 1.633 + if (sid->cached == never_cached) { 1.634 + (*ss->sec.cache)(sid); 1.635 + } 1.636 + rv = SECSuccess; 1.637 + } 1.638 + ssl_FreeSID(sid); 1.639 + ss->sec.ci.sid = 0; 1.640 + } 1.641 +done: 1.642 + ssl_ReleaseXmitBufLock(ss); /***************************************/ 1.643 + return rv; 1.644 +} 1.645 + 1.646 +/* Called from ssl2_ClientSetupSessionCypher() <- 1.647 + * ssl2_HandleServerHelloMessage() 1.648 + * after ssl2_BeginClientHandshake() 1.649 + * Acquires and releases the socket's xmitBufLock. 1.650 + */ 1.651 +static SECStatus 1.652 +ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize, 1.653 + PRUint8 *ca, int caLen, 1.654 + PRUint8 *ck, int ckLen, 1.655 + PRUint8 *ek, int ekLen) 1.656 +{ 1.657 + PRUint8 * msg; 1.658 + int sendLen; 1.659 + int sent; 1.660 + SECStatus rv; 1.661 + 1.662 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.663 + 1.664 + ssl_GetXmitBufLock(ss); /***************************************/ 1.665 + 1.666 + sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen; 1.667 + rv = ssl2_GetSendBuffer(ss, sendLen); 1.668 + if (rv != SECSuccess) 1.669 + goto done; 1.670 + 1.671 + SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key", 1.672 + SSL_GETPID(), ss->fd)); 1.673 + 1.674 + msg = ss->sec.ci.sendBuf.buf; 1.675 + msg[0] = SSL_MT_CLIENT_MASTER_KEY; 1.676 + msg[1] = cipher; 1.677 + msg[2] = MSB(keySize); 1.678 + msg[3] = LSB(keySize); 1.679 + msg[4] = MSB(ckLen); 1.680 + msg[5] = LSB(ckLen); 1.681 + msg[6] = MSB(ekLen); 1.682 + msg[7] = LSB(ekLen); 1.683 + msg[8] = MSB(caLen); 1.684 + msg[9] = LSB(caLen); 1.685 + PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES, ck, ckLen); 1.686 + PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen, ek, ekLen); 1.687 + PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen+ekLen, ca, caLen); 1.688 + 1.689 + DUMP_MSG(29, (ss, msg, sendLen)); 1.690 + sent = (*ss->sec.send)(ss, msg, sendLen, 0); 1.691 + rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; 1.692 +done: 1.693 + ssl_ReleaseXmitBufLock(ss); /***************************************/ 1.694 + return rv; 1.695 +} 1.696 + 1.697 +/* Called from ssl2_TriggerNextMessage() <- ssl2_HandleMessage() 1.698 + * Acquires and releases the socket's xmitBufLock. 1.699 + */ 1.700 +static SECStatus 1.701 +ssl2_SendCertificateRequestMessage(sslSocket *ss) 1.702 +{ 1.703 + PRUint8 * msg; 1.704 + int sent; 1.705 + int sendLen; 1.706 + SECStatus rv; 1.707 + 1.708 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.709 + 1.710 + ssl_GetXmitBufLock(ss); /***************************************/ 1.711 + 1.712 + sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES; 1.713 + rv = ssl2_GetSendBuffer(ss, sendLen); 1.714 + if (rv != SECSuccess) 1.715 + goto done; 1.716 + 1.717 + SSL_TRC(3, ("%d: SSL[%d]: sending certificate request", 1.718 + SSL_GETPID(), ss->fd)); 1.719 + 1.720 + /* Generate random challenge for client to encrypt */ 1.721 + PK11_GenerateRandom(ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); 1.722 + 1.723 + msg = ss->sec.ci.sendBuf.buf; 1.724 + msg[0] = SSL_MT_REQUEST_CERTIFICATE; 1.725 + msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION; 1.726 + PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES, 1.727 + ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); 1.728 + 1.729 + DUMP_MSG(29, (ss, msg, sendLen)); 1.730 + sent = (*ss->sec.send)(ss, msg, sendLen, 0); 1.731 + rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; 1.732 +done: 1.733 + ssl_ReleaseXmitBufLock(ss); /***************************************/ 1.734 + return rv; 1.735 +} 1.736 + 1.737 +/* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() 1.738 + * Acquires and releases the socket's xmitBufLock. 1.739 + */ 1.740 +static int 1.741 +ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert, 1.742 + SECItem *encCode) 1.743 +{ 1.744 + PRUint8 *msg; 1.745 + int rv, sendLen; 1.746 + 1.747 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.748 + 1.749 + ssl_GetXmitBufLock(ss); /***************************************/ 1.750 + 1.751 + sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len; 1.752 + rv = ssl2_GetSendBuffer(ss, sendLen); 1.753 + if (rv) 1.754 + goto done; 1.755 + 1.756 + SSL_TRC(3, ("%d: SSL[%d]: sending certificate response", 1.757 + SSL_GETPID(), ss->fd)); 1.758 + 1.759 + msg = ss->sec.ci.sendBuf.buf; 1.760 + msg[0] = SSL_MT_CLIENT_CERTIFICATE; 1.761 + msg[1] = SSL_CT_X509_CERTIFICATE; 1.762 + msg[2] = MSB(cert->len); 1.763 + msg[3] = LSB(cert->len); 1.764 + msg[4] = MSB(encCode->len); 1.765 + msg[5] = LSB(encCode->len); 1.766 + PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES, cert->data, cert->len); 1.767 + PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES + cert->len, 1.768 + encCode->data, encCode->len); 1.769 + 1.770 + DUMP_MSG(29, (ss, msg, sendLen)); 1.771 + rv = (*ss->sec.send)(ss, msg, sendLen, 0); 1.772 + if (rv >= 0) { 1.773 + rv = SECSuccess; 1.774 + } 1.775 +done: 1.776 + ssl_ReleaseXmitBufLock(ss); /***************************************/ 1.777 + return rv; 1.778 +} 1.779 + 1.780 +/******************************************************************** 1.781 +** Send functions above this line must aquire & release the socket's 1.782 +** xmitBufLock. 1.783 +** All the ssl2_Send functions below this line are called vis ss->sec.send 1.784 +** and require that the caller hold the xmitBufLock. 1.785 +*/ 1.786 + 1.787 +/* 1.788 +** Called from ssl2_SendStream, ssl2_SendBlock, but not from ssl2_SendClear. 1.789 +*/ 1.790 +static SECStatus 1.791 +ssl2_CalcMAC(PRUint8 * result, 1.792 + sslSecurityInfo * sec, 1.793 + const PRUint8 * data, 1.794 + unsigned int dataLen, 1.795 + unsigned int paddingLen) 1.796 +{ 1.797 + const PRUint8 * secret = sec->sendSecret.data; 1.798 + unsigned int secretLen = sec->sendSecret.len; 1.799 + unsigned long sequenceNumber = sec->sendSequence; 1.800 + unsigned int nout; 1.801 + PRUint8 seq[4]; 1.802 + PRUint8 padding[32];/* XXX max blocksize? */ 1.803 + 1.804 + if (!sec->hash || !sec->hash->length) 1.805 + return SECSuccess; 1.806 + if (!sec->hashcx) 1.807 + return SECFailure; 1.808 + 1.809 + /* Reset hash function */ 1.810 + (*sec->hash->begin)(sec->hashcx); 1.811 + 1.812 + /* Feed hash the data */ 1.813 + (*sec->hash->update)(sec->hashcx, secret, secretLen); 1.814 + (*sec->hash->update)(sec->hashcx, data, dataLen); 1.815 + PORT_Memset(padding, paddingLen, paddingLen); 1.816 + (*sec->hash->update)(sec->hashcx, padding, paddingLen); 1.817 + 1.818 + seq[0] = (PRUint8) (sequenceNumber >> 24); 1.819 + seq[1] = (PRUint8) (sequenceNumber >> 16); 1.820 + seq[2] = (PRUint8) (sequenceNumber >> 8); 1.821 + seq[3] = (PRUint8) (sequenceNumber); 1.822 + 1.823 + PRINT_BUF(60, (0, "calc-mac secret:", secret, secretLen)); 1.824 + PRINT_BUF(60, (0, "calc-mac data:", data, dataLen)); 1.825 + PRINT_BUF(60, (0, "calc-mac padding:", padding, paddingLen)); 1.826 + PRINT_BUF(60, (0, "calc-mac seq:", seq, 4)); 1.827 + 1.828 + (*sec->hash->update)(sec->hashcx, seq, 4); 1.829 + 1.830 + /* Get result */ 1.831 + (*sec->hash->end)(sec->hashcx, result, &nout, sec->hash->length); 1.832 + 1.833 + return SECSuccess; 1.834 +} 1.835 + 1.836 +/* 1.837 +** Maximum transmission amounts. These are tiny bit smaller than they 1.838 +** need to be (they account for the MAC length plus some padding), 1.839 +** assuming the MAC is 16 bytes long and the padding is a max of 7 bytes 1.840 +** long. This gives an additional 9 bytes of slop to work within. 1.841 +*/ 1.842 +#define MAX_STREAM_CYPHER_LEN 0x7fe0 1.843 +#define MAX_BLOCK_CYPHER_LEN 0x3fe0 1.844 + 1.845 +/* 1.846 +** Send some data in the clear. 1.847 +** Package up data with the length header and send it. 1.848 +** 1.849 +** Return count of bytes successfully written, or negative number (failure). 1.850 +*/ 1.851 +static PRInt32 1.852 +ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) 1.853 +{ 1.854 + PRUint8 * out; 1.855 + int rv; 1.856 + int amount; 1.857 + int count = 0; 1.858 + 1.859 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); 1.860 + 1.861 + SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear", 1.862 + SSL_GETPID(), ss->fd, len)); 1.863 + PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len)); 1.864 + 1.865 + while (len) { 1.866 + amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN ); 1.867 + if (amount + 2 > ss->sec.writeBuf.space) { 1.868 + rv = sslBuffer_Grow(&ss->sec.writeBuf, amount + 2); 1.869 + if (rv != SECSuccess) { 1.870 + count = rv; 1.871 + break; 1.872 + } 1.873 + } 1.874 + out = ss->sec.writeBuf.buf; 1.875 + 1.876 + /* 1.877 + ** Construct message. 1.878 + */ 1.879 + out[0] = 0x80 | MSB(amount); 1.880 + out[1] = LSB(amount); 1.881 + PORT_Memcpy(&out[2], in, amount); 1.882 + 1.883 + /* Now send the data */ 1.884 + rv = ssl_DefSend(ss, out, amount + 2, flags & ~ssl_SEND_FLAG_MASK); 1.885 + if (rv < 0) { 1.886 + if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) { 1.887 + rv = 0; 1.888 + } else { 1.889 + /* Return short write if some data already went out... */ 1.890 + if (count == 0) 1.891 + count = rv; 1.892 + break; 1.893 + } 1.894 + } 1.895 + 1.896 + if ((unsigned)rv < (amount + 2)) { 1.897 + /* Short write. Save the data and return. */ 1.898 + if (ssl_SaveWriteData(ss, out + rv, amount + 2 - rv) 1.899 + == SECFailure) { 1.900 + count = SECFailure; 1.901 + } else { 1.902 + count += amount; 1.903 + ss->sec.sendSequence++; 1.904 + } 1.905 + break; 1.906 + } 1.907 + 1.908 + ss->sec.sendSequence++; 1.909 + in += amount; 1.910 + count += amount; 1.911 + len -= amount; 1.912 + } 1.913 + 1.914 + return count; 1.915 +} 1.916 + 1.917 +/* 1.918 +** Send some data, when using a stream cipher. Stream ciphers have a 1.919 +** block size of 1. Package up the data with the length header 1.920 +** and send it. 1.921 +*/ 1.922 +static PRInt32 1.923 +ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) 1.924 +{ 1.925 + PRUint8 * out; 1.926 + int rv; 1.927 + int count = 0; 1.928 + 1.929 + int amount; 1.930 + PRUint8 macLen; 1.931 + int nout; 1.932 + int buflen; 1.933 + 1.934 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); 1.935 + 1.936 + SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher", 1.937 + SSL_GETPID(), ss->fd, len)); 1.938 + PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len)); 1.939 + 1.940 + while (len) { 1.941 + ssl_GetSpecReadLock(ss); /*************************************/ 1.942 + 1.943 + macLen = ss->sec.hash->length; 1.944 + amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN ); 1.945 + buflen = amount + 2 + macLen; 1.946 + if (buflen > ss->sec.writeBuf.space) { 1.947 + rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen); 1.948 + if (rv != SECSuccess) { 1.949 + goto loser; 1.950 + } 1.951 + } 1.952 + out = ss->sec.writeBuf.buf; 1.953 + nout = amount + macLen; 1.954 + out[0] = 0x80 | MSB(nout); 1.955 + out[1] = LSB(nout); 1.956 + 1.957 + /* Calculate MAC */ 1.958 + rv = ssl2_CalcMAC(out+2, /* put MAC here */ 1.959 + &ss->sec, 1.960 + in, amount, /* input addr & length */ 1.961 + 0); /* no padding */ 1.962 + if (rv != SECSuccess) 1.963 + goto loser; 1.964 + 1.965 + /* Encrypt MAC */ 1.966 + rv = (*ss->sec.enc)(ss->sec.writecx, out+2, &nout, macLen, out+2, macLen); 1.967 + if (rv) goto loser; 1.968 + 1.969 + /* Encrypt data from caller */ 1.970 + rv = (*ss->sec.enc)(ss->sec.writecx, out+2+macLen, &nout, amount, in, amount); 1.971 + if (rv) goto loser; 1.972 + 1.973 + ssl_ReleaseSpecReadLock(ss); /*************************************/ 1.974 + 1.975 + PRINT_BUF(50, (ss, "encrypted data:", out, buflen)); 1.976 + 1.977 + rv = ssl_DefSend(ss, out, buflen, flags & ~ssl_SEND_FLAG_MASK); 1.978 + if (rv < 0) { 1.979 + if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) { 1.980 + SSL_TRC(50, ("%d: SSL[%d]: send stream would block, " 1.981 + "saving data", SSL_GETPID(), ss->fd)); 1.982 + rv = 0; 1.983 + } else { 1.984 + SSL_TRC(10, ("%d: SSL[%d]: send stream error %d", 1.985 + SSL_GETPID(), ss->fd, PORT_GetError())); 1.986 + /* Return short write if some data already went out... */ 1.987 + if (count == 0) 1.988 + count = rv; 1.989 + goto done; 1.990 + } 1.991 + } 1.992 + 1.993 + if ((unsigned)rv < buflen) { 1.994 + /* Short write. Save the data and return. */ 1.995 + if (ssl_SaveWriteData(ss, out + rv, buflen - rv) == SECFailure) { 1.996 + count = SECFailure; 1.997 + } else { 1.998 + count += amount; 1.999 + ss->sec.sendSequence++; 1.1000 + } 1.1001 + goto done; 1.1002 + } 1.1003 + 1.1004 + ss->sec.sendSequence++; 1.1005 + in += amount; 1.1006 + count += amount; 1.1007 + len -= amount; 1.1008 + } 1.1009 + 1.1010 +done: 1.1011 + return count; 1.1012 + 1.1013 +loser: 1.1014 + ssl_ReleaseSpecReadLock(ss); 1.1015 + return SECFailure; 1.1016 +} 1.1017 + 1.1018 +/* 1.1019 +** Send some data, when using a block cipher. Package up the data with 1.1020 +** the length header and send it. 1.1021 +*/ 1.1022 +/* XXX assumes blocksize is > 7 */ 1.1023 +static PRInt32 1.1024 +ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) 1.1025 +{ 1.1026 + PRUint8 * out; /* begining of output buffer. */ 1.1027 + PRUint8 * op; /* next output byte goes here. */ 1.1028 + int rv; /* value from funcs we called. */ 1.1029 + int count = 0; /* this function's return value. */ 1.1030 + 1.1031 + unsigned int hlen; /* output record hdr len, 2 or 3 */ 1.1032 + unsigned int macLen; /* MAC is this many bytes long. */ 1.1033 + int amount; /* of plaintext to go in record. */ 1.1034 + unsigned int padding; /* add this many padding byte. */ 1.1035 + int nout; /* ciphertext size after header. */ 1.1036 + int buflen; /* size of generated record. */ 1.1037 + 1.1038 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); 1.1039 + 1.1040 + SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher", 1.1041 + SSL_GETPID(), ss->fd, len)); 1.1042 + PRINT_BUF(50, (ss, "clear data:", in, len)); 1.1043 + 1.1044 + while (len) { 1.1045 + ssl_GetSpecReadLock(ss); /*************************************/ 1.1046 + 1.1047 + macLen = ss->sec.hash->length; 1.1048 + /* Figure out how much to send, including mac and padding */ 1.1049 + amount = PR_MIN( len, MAX_BLOCK_CYPHER_LEN ); 1.1050 + nout = amount + macLen; 1.1051 + padding = nout & (ss->sec.blockSize - 1); 1.1052 + if (padding) { 1.1053 + hlen = 3; 1.1054 + padding = ss->sec.blockSize - padding; 1.1055 + nout += padding; 1.1056 + } else { 1.1057 + hlen = 2; 1.1058 + } 1.1059 + buflen = hlen + nout; 1.1060 + if (buflen > ss->sec.writeBuf.space) { 1.1061 + rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen); 1.1062 + if (rv != SECSuccess) { 1.1063 + goto loser; 1.1064 + } 1.1065 + } 1.1066 + out = ss->sec.writeBuf.buf; 1.1067 + 1.1068 + /* Construct header */ 1.1069 + op = out; 1.1070 + if (padding) { 1.1071 + *op++ = MSB(nout); 1.1072 + *op++ = LSB(nout); 1.1073 + *op++ = padding; 1.1074 + } else { 1.1075 + *op++ = 0x80 | MSB(nout); 1.1076 + *op++ = LSB(nout); 1.1077 + } 1.1078 + 1.1079 + /* Calculate MAC */ 1.1080 + rv = ssl2_CalcMAC(op, /* MAC goes here. */ 1.1081 + &ss->sec, 1.1082 + in, amount, /* intput addr, len */ 1.1083 + padding); 1.1084 + if (rv != SECSuccess) 1.1085 + goto loser; 1.1086 + op += macLen; 1.1087 + 1.1088 + /* Copy in the input data */ 1.1089 + /* XXX could eliminate the copy by folding it into the encryption */ 1.1090 + PORT_Memcpy(op, in, amount); 1.1091 + op += amount; 1.1092 + if (padding) { 1.1093 + PORT_Memset(op, padding, padding); 1.1094 + op += padding; 1.1095 + } 1.1096 + 1.1097 + /* Encrypt result */ 1.1098 + rv = (*ss->sec.enc)(ss->sec.writecx, out+hlen, &nout, buflen-hlen, 1.1099 + out+hlen, op - (out + hlen)); 1.1100 + if (rv) 1.1101 + goto loser; 1.1102 + 1.1103 + ssl_ReleaseSpecReadLock(ss); /*************************************/ 1.1104 + 1.1105 + PRINT_BUF(50, (ss, "final xmit data:", out, op - out)); 1.1106 + 1.1107 + rv = ssl_DefSend(ss, out, op - out, flags & ~ssl_SEND_FLAG_MASK); 1.1108 + if (rv < 0) { 1.1109 + if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) { 1.1110 + rv = 0; 1.1111 + } else { 1.1112 + SSL_TRC(10, ("%d: SSL[%d]: send block error %d", 1.1113 + SSL_GETPID(), ss->fd, PORT_GetError())); 1.1114 + /* Return short write if some data already went out... */ 1.1115 + if (count == 0) 1.1116 + count = rv; 1.1117 + goto done; 1.1118 + } 1.1119 + } 1.1120 + 1.1121 + if (rv < (op - out)) { 1.1122 + /* Short write. Save the data and return. */ 1.1123 + if (ssl_SaveWriteData(ss, out + rv, op - out - rv) == SECFailure) { 1.1124 + count = SECFailure; 1.1125 + } else { 1.1126 + count += amount; 1.1127 + ss->sec.sendSequence++; 1.1128 + } 1.1129 + goto done; 1.1130 + } 1.1131 + 1.1132 + ss->sec.sendSequence++; 1.1133 + in += amount; 1.1134 + count += amount; 1.1135 + len -= amount; 1.1136 + } 1.1137 + 1.1138 +done: 1.1139 + return count; 1.1140 + 1.1141 +loser: 1.1142 + ssl_ReleaseSpecReadLock(ss); 1.1143 + return SECFailure; 1.1144 +} 1.1145 + 1.1146 +/* 1.1147 +** Called from: ssl2_HandleServerHelloMessage, 1.1148 +** ssl2_HandleClientSessionKeyMessage, 1.1149 +** ssl2_HandleClientHelloMessage, 1.1150 +** 1.1151 +*/ 1.1152 +static void 1.1153 +ssl2_UseEncryptedSendFunc(sslSocket *ss) 1.1154 +{ 1.1155 + ssl_GetXmitBufLock(ss); 1.1156 + PORT_Assert(ss->sec.hashcx != 0); 1.1157 + 1.1158 + ss->gs.encrypted = 1; 1.1159 + ss->sec.send = (ss->sec.blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream; 1.1160 + ssl_ReleaseXmitBufLock(ss); 1.1161 +} 1.1162 + 1.1163 +/* Called while initializing socket in ssl_CreateSecurityInfo(). 1.1164 +** This function allows us to keep the name of ssl2_SendClear static. 1.1165 +*/ 1.1166 +void 1.1167 +ssl2_UseClearSendFunc(sslSocket *ss) 1.1168 +{ 1.1169 + ss->sec.send = ssl2_SendClear; 1.1170 +} 1.1171 + 1.1172 +/************************************************************************ 1.1173 +** END of Send functions. * 1.1174 +*************************************************************************/ 1.1175 + 1.1176 +/*********************************************************************** 1.1177 + * For SSL3, this gathers in and handles records/messages until either 1.1178 + * the handshake is complete or application data is available. 1.1179 + * 1.1180 + * For SSL2, this gathers in only the next SSLV2 record. 1.1181 + * 1.1182 + * Called from ssl_Do1stHandshake() via function pointer ss->handshake. 1.1183 + * Caller must hold handshake lock. 1.1184 + * This function acquires and releases the RecvBufLock. 1.1185 + * 1.1186 + * returns SECSuccess for success. 1.1187 + * returns SECWouldBlock when that value is returned by ssl2_GatherRecord() or 1.1188 + * ssl3_GatherCompleteHandshake(). 1.1189 + * returns SECFailure on all other errors. 1.1190 + * 1.1191 + * The gather functions called by ssl_GatherRecord1stHandshake are expected 1.1192 + * to return values interpreted as follows: 1.1193 + * 1 : the function completed without error. 1.1194 + * 0 : the function read EOF. 1.1195 + * -1 : read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error. 1.1196 + * -2 : the function wants ssl_GatherRecord1stHandshake to be called again 1.1197 + * immediately, by ssl_Do1stHandshake. 1.1198 + * 1.1199 + * This code is similar to, and easily confused with, DoRecv() in sslsecur.c 1.1200 + * 1.1201 + * This function is called from ssl_Do1stHandshake(). 1.1202 + * The following functions put ssl_GatherRecord1stHandshake into ss->handshake: 1.1203 + * ssl2_HandleMessage 1.1204 + * ssl2_HandleVerifyMessage 1.1205 + * ssl2_HandleServerHelloMessage 1.1206 + * ssl2_BeginClientHandshake 1.1207 + * ssl2_HandleClientSessionKeyMessage 1.1208 + * ssl3_RestartHandshakeAfterCertReq 1.1209 + * ssl3_RestartHandshakeAfterServerCert 1.1210 + * ssl2_HandleClientHelloMessage 1.1211 + * ssl2_BeginServerHandshake 1.1212 + */ 1.1213 +SECStatus 1.1214 +ssl_GatherRecord1stHandshake(sslSocket *ss) 1.1215 +{ 1.1216 + int rv; 1.1217 + 1.1218 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.1219 + 1.1220 + ssl_GetRecvBufLock(ss); 1.1221 + 1.1222 + /* The special case DTLS logic is needed here because the SSL/TLS 1.1223 + * version wants to auto-detect SSL2 vs. SSL3 on the initial handshake 1.1224 + * (ss->version == 0) but with DTLS it gets confused, so we force the 1.1225 + * SSL3 version. 1.1226 + */ 1.1227 + if ((ss->version >= SSL_LIBRARY_VERSION_3_0) || IS_DTLS(ss)) { 1.1228 + /* Wait for handshake to complete, or application data to arrive. */ 1.1229 + rv = ssl3_GatherCompleteHandshake(ss, 0); 1.1230 + } else { 1.1231 + /* See if we have a complete record */ 1.1232 + rv = ssl2_GatherRecord(ss, 0); 1.1233 + } 1.1234 + SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d", 1.1235 + SSL_GETPID(), ss->fd, rv)); 1.1236 + 1.1237 + ssl_ReleaseRecvBufLock(ss); 1.1238 + 1.1239 + if (rv <= 0) { 1.1240 + if (rv == SECWouldBlock) { 1.1241 + /* Progress is blocked waiting for callback completion. */ 1.1242 + SSL_TRC(10, ("%d: SSL[%d]: handshake blocked (need %d)", 1.1243 + SSL_GETPID(), ss->fd, ss->gs.remainder)); 1.1244 + return SECWouldBlock; 1.1245 + } 1.1246 + if (rv == 0) { 1.1247 + /* EOF. Loser */ 1.1248 + PORT_SetError(PR_END_OF_FILE_ERROR); 1.1249 + } 1.1250 + return SECFailure; /* rv is < 0 here. */ 1.1251 + } 1.1252 + 1.1253 + SSL_TRC(10, ("%d: SSL[%d]: got handshake record of %d bytes", 1.1254 + SSL_GETPID(), ss->fd, ss->gs.recordLen)); 1.1255 + 1.1256 + ss->handshake = 0; /* makes ssl_Do1stHandshake call ss->nextHandshake.*/ 1.1257 + return SECSuccess; 1.1258 +} 1.1259 + 1.1260 +/************************************************************************/ 1.1261 + 1.1262 +/* Called from ssl2_ServerSetupSessionCypher() 1.1263 + * ssl2_ClientSetupSessionCypher() 1.1264 + */ 1.1265 +static SECStatus 1.1266 +ssl2_FillInSID(sslSessionID * sid, 1.1267 + int cipher, 1.1268 + PRUint8 *keyData, 1.1269 + int keyLen, 1.1270 + PRUint8 *ca, 1.1271 + int caLen, 1.1272 + int keyBits, 1.1273 + int secretKeyBits, 1.1274 + SSLSignType authAlgorithm, 1.1275 + PRUint32 authKeyBits, 1.1276 + SSLKEAType keaType, 1.1277 + PRUint32 keaKeyBits) 1.1278 +{ 1.1279 + PORT_Assert(sid->references == 1); 1.1280 + PORT_Assert(sid->cached == never_cached); 1.1281 + PORT_Assert(sid->u.ssl2.masterKey.data == 0); 1.1282 + PORT_Assert(sid->u.ssl2.cipherArg.data == 0); 1.1283 + 1.1284 + sid->version = SSL_LIBRARY_VERSION_2; 1.1285 + 1.1286 + sid->u.ssl2.cipherType = cipher; 1.1287 + sid->u.ssl2.masterKey.data = (PRUint8*) PORT_Alloc(keyLen); 1.1288 + if (!sid->u.ssl2.masterKey.data) { 1.1289 + return SECFailure; 1.1290 + } 1.1291 + PORT_Memcpy(sid->u.ssl2.masterKey.data, keyData, keyLen); 1.1292 + sid->u.ssl2.masterKey.len = keyLen; 1.1293 + sid->u.ssl2.keyBits = keyBits; 1.1294 + sid->u.ssl2.secretKeyBits = secretKeyBits; 1.1295 + sid->authAlgorithm = authAlgorithm; 1.1296 + sid->authKeyBits = authKeyBits; 1.1297 + sid->keaType = keaType; 1.1298 + sid->keaKeyBits = keaKeyBits; 1.1299 + sid->lastAccessTime = sid->creationTime = ssl_Time(); 1.1300 + sid->expirationTime = sid->creationTime + ssl_sid_timeout; 1.1301 + 1.1302 + if (caLen) { 1.1303 + sid->u.ssl2.cipherArg.data = (PRUint8*) PORT_Alloc(caLen); 1.1304 + if (!sid->u.ssl2.cipherArg.data) { 1.1305 + return SECFailure; 1.1306 + } 1.1307 + sid->u.ssl2.cipherArg.len = caLen; 1.1308 + PORT_Memcpy(sid->u.ssl2.cipherArg.data, ca, caLen); 1.1309 + } 1.1310 + return SECSuccess; 1.1311 +} 1.1312 + 1.1313 +/* 1.1314 +** Construct session keys given the masterKey (tied to the session-id), 1.1315 +** the client's challenge and the server's nonce. 1.1316 +** 1.1317 +** Called from ssl2_CreateSessionCypher() <- 1.1318 +*/ 1.1319 +static SECStatus 1.1320 +ssl2_ProduceKeys(sslSocket * ss, 1.1321 + SECItem * readKey, 1.1322 + SECItem * writeKey, 1.1323 + SECItem * masterKey, 1.1324 + PRUint8 * challenge, 1.1325 + PRUint8 * nonce, 1.1326 + int cipherType) 1.1327 +{ 1.1328 + PK11Context * cx = 0; 1.1329 + unsigned nkm = 0; /* number of hashes to generate key mat. */ 1.1330 + unsigned nkd = 0; /* size of readKey and writeKey. */ 1.1331 + unsigned part; 1.1332 + unsigned i; 1.1333 + unsigned off; 1.1334 + SECStatus rv; 1.1335 + PRUint8 countChar; 1.1336 + PRUint8 km[3*16]; /* buffer for key material. */ 1.1337 + 1.1338 + readKey->data = 0; 1.1339 + writeKey->data = 0; 1.1340 + 1.1341 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.1342 + 1.1343 + rv = SECSuccess; 1.1344 + cx = PK11_CreateDigestContext(SEC_OID_MD5); 1.1345 + if (cx == NULL) { 1.1346 + ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); 1.1347 + return SECFailure; 1.1348 + } 1.1349 + 1.1350 + nkm = ssl_Specs[cipherType].nkm; 1.1351 + nkd = ssl_Specs[cipherType].nkd; 1.1352 + 1.1353 + readKey->data = (PRUint8*) PORT_Alloc(nkd); 1.1354 + if (!readKey->data) 1.1355 + goto loser; 1.1356 + readKey->len = nkd; 1.1357 + 1.1358 + writeKey->data = (PRUint8*) PORT_Alloc(nkd); 1.1359 + if (!writeKey->data) 1.1360 + goto loser; 1.1361 + writeKey->len = nkd; 1.1362 + 1.1363 + /* Produce key material */ 1.1364 + countChar = '0'; 1.1365 + for (i = 0, off = 0; i < nkm; i++, off += 16) { 1.1366 + rv = PK11_DigestBegin(cx); 1.1367 + rv |= PK11_DigestOp(cx, masterKey->data, masterKey->len); 1.1368 + rv |= PK11_DigestOp(cx, &countChar, 1); 1.1369 + rv |= PK11_DigestOp(cx, challenge, SSL_CHALLENGE_BYTES); 1.1370 + rv |= PK11_DigestOp(cx, nonce, SSL_CONNECTIONID_BYTES); 1.1371 + rv |= PK11_DigestFinal(cx, km+off, &part, MD5_LENGTH); 1.1372 + if (rv != SECSuccess) { 1.1373 + ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); 1.1374 + rv = SECFailure; 1.1375 + goto loser; 1.1376 + } 1.1377 + countChar++; 1.1378 + } 1.1379 + 1.1380 + /* Produce keys */ 1.1381 + PORT_Memcpy(readKey->data, km, nkd); 1.1382 + PORT_Memcpy(writeKey->data, km + nkd, nkd); 1.1383 + 1.1384 +loser: 1.1385 + PK11_DestroyContext(cx, PR_TRUE); 1.1386 + return rv; 1.1387 +} 1.1388 + 1.1389 +/* Called from ssl2_ServerSetupSessionCypher() 1.1390 +** <- ssl2_HandleClientSessionKeyMessage() 1.1391 +** <- ssl2_HandleClientHelloMessage() 1.1392 +** and from ssl2_ClientSetupSessionCypher() 1.1393 +** <- ssl2_HandleServerHelloMessage() 1.1394 +*/ 1.1395 +static SECStatus 1.1396 +ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient) 1.1397 +{ 1.1398 + SECItem * rk = NULL; 1.1399 + SECItem * wk = NULL; 1.1400 + SECItem * param; 1.1401 + SECStatus rv; 1.1402 + int cipherType = sid->u.ssl2.cipherType; 1.1403 + PK11SlotInfo * slot = NULL; 1.1404 + CK_MECHANISM_TYPE mechanism; 1.1405 + SECItem readKey; 1.1406 + SECItem writeKey; 1.1407 + 1.1408 + void *readcx = 0; 1.1409 + void *writecx = 0; 1.1410 + readKey.data = 0; 1.1411 + writeKey.data = 0; 1.1412 + 1.1413 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.1414 + if (ss->sec.ci.sid == 0) 1.1415 + goto sec_loser; /* don't crash if asserts are off */ 1.1416 + 1.1417 + /* Trying to cut down on all these switch statements that should be tables. 1.1418 + * So, test cipherType once, here, and then use tables below. 1.1419 + */ 1.1420 + switch (cipherType) { 1.1421 + case SSL_CK_RC4_128_EXPORT40_WITH_MD5: 1.1422 + case SSL_CK_RC4_128_WITH_MD5: 1.1423 + case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: 1.1424 + case SSL_CK_RC2_128_CBC_WITH_MD5: 1.1425 + case SSL_CK_DES_64_CBC_WITH_MD5: 1.1426 + case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: 1.1427 + break; 1.1428 + 1.1429 + default: 1.1430 + SSL_DBG(("%d: SSL[%d]: ssl2_CreateSessionCypher: unknown cipher=%d", 1.1431 + SSL_GETPID(), ss->fd, cipherType)); 1.1432 + PORT_SetError(isClient ? SSL_ERROR_BAD_SERVER : SSL_ERROR_BAD_CLIENT); 1.1433 + goto sec_loser; 1.1434 + } 1.1435 + 1.1436 + rk = isClient ? &readKey : &writeKey; 1.1437 + wk = isClient ? &writeKey : &readKey; 1.1438 + 1.1439 + /* Produce the keys for this session */ 1.1440 + rv = ssl2_ProduceKeys(ss, &readKey, &writeKey, &sid->u.ssl2.masterKey, 1.1441 + ss->sec.ci.clientChallenge, ss->sec.ci.connectionID, 1.1442 + cipherType); 1.1443 + if (rv != SECSuccess) 1.1444 + goto loser; 1.1445 + PRINT_BUF(7, (ss, "Session read-key: ", rk->data, rk->len)); 1.1446 + PRINT_BUF(7, (ss, "Session write-key: ", wk->data, wk->len)); 1.1447 + 1.1448 + PORT_Memcpy(ss->sec.ci.readKey, readKey.data, readKey.len); 1.1449 + PORT_Memcpy(ss->sec.ci.writeKey, writeKey.data, writeKey.len); 1.1450 + ss->sec.ci.keySize = readKey.len; 1.1451 + 1.1452 + /* Setup the MAC */ 1.1453 + rv = ssl2_CreateMAC(&ss->sec, rk, wk, cipherType); 1.1454 + if (rv != SECSuccess) 1.1455 + goto loser; 1.1456 + 1.1457 + /* First create the session key object */ 1.1458 + SSL_TRC(3, ("%d: SSL[%d]: using %s", SSL_GETPID(), ss->fd, 1.1459 + ssl_cipherName[cipherType])); 1.1460 + 1.1461 + 1.1462 + mechanism = ssl_Specs[cipherType].mechanism; 1.1463 + 1.1464 + /* set destructer before we call loser... */ 1.1465 + ss->sec.destroy = (void (*)(void*, PRBool)) PK11_DestroyContext; 1.1466 + slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg); 1.1467 + if (slot == NULL) 1.1468 + goto loser; 1.1469 + 1.1470 + param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg); 1.1471 + if (param == NULL) 1.1472 + goto loser; 1.1473 + readcx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap, 1.1474 + CKA_DECRYPT, rk, param, 1.1475 + ss->pkcs11PinArg); 1.1476 + SECITEM_FreeItem(param, PR_TRUE); 1.1477 + if (readcx == NULL) 1.1478 + goto loser; 1.1479 + 1.1480 + /* build the client context */ 1.1481 + param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg); 1.1482 + if (param == NULL) 1.1483 + goto loser; 1.1484 + writecx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap, 1.1485 + CKA_ENCRYPT, wk, param, 1.1486 + ss->pkcs11PinArg); 1.1487 + SECITEM_FreeItem(param,PR_TRUE); 1.1488 + if (writecx == NULL) 1.1489 + goto loser; 1.1490 + PK11_FreeSlot(slot); 1.1491 + 1.1492 + rv = SECSuccess; 1.1493 + ss->sec.enc = (SSLCipher) PK11_CipherOp; 1.1494 + ss->sec.dec = (SSLCipher) PK11_CipherOp; 1.1495 + ss->sec.readcx = (void *) readcx; 1.1496 + ss->sec.writecx = (void *) writecx; 1.1497 + ss->sec.blockSize = ssl_Specs[cipherType].blockSize; 1.1498 + ss->sec.blockShift = ssl_Specs[cipherType].blockShift; 1.1499 + ss->sec.cipherType = sid->u.ssl2.cipherType; 1.1500 + ss->sec.keyBits = sid->u.ssl2.keyBits; 1.1501 + ss->sec.secretKeyBits = sid->u.ssl2.secretKeyBits; 1.1502 + goto done; 1.1503 + 1.1504 + loser: 1.1505 + if (ss->sec.destroy) { 1.1506 + if (readcx) (*ss->sec.destroy)(readcx, PR_TRUE); 1.1507 + if (writecx) (*ss->sec.destroy)(writecx, PR_TRUE); 1.1508 + } 1.1509 + ss->sec.destroy = NULL; 1.1510 + if (slot) PK11_FreeSlot(slot); 1.1511 + 1.1512 + sec_loser: 1.1513 + rv = SECFailure; 1.1514 + 1.1515 + done: 1.1516 + if (rk) { 1.1517 + SECITEM_ZfreeItem(rk, PR_FALSE); 1.1518 + } 1.1519 + if (wk) { 1.1520 + SECITEM_ZfreeItem(wk, PR_FALSE); 1.1521 + } 1.1522 + return rv; 1.1523 +} 1.1524 + 1.1525 +/* 1.1526 +** Setup the server ciphers given information from a CLIENT-MASTER-KEY 1.1527 +** message. 1.1528 +** "ss" pointer to the ssl-socket object 1.1529 +** "cipher" the cipher type to use 1.1530 +** "keyBits" the size of the final cipher key 1.1531 +** "ck" the clear-key data 1.1532 +** "ckLen" the number of bytes of clear-key data 1.1533 +** "ek" the encrypted-key data 1.1534 +** "ekLen" the number of bytes of encrypted-key data 1.1535 +** "ca" the cipher-arg data 1.1536 +** "caLen" the number of bytes of cipher-arg data 1.1537 +** 1.1538 +** The MASTER-KEY is constructed by first decrypting the encrypted-key 1.1539 +** data. This produces the SECRET-KEY-DATA. The MASTER-KEY is composed by 1.1540 +** concatenating the clear-key data with the SECRET-KEY-DATA. This code 1.1541 +** checks to make sure that the client didn't send us an improper amount 1.1542 +** of SECRET-KEY-DATA (it restricts the length of that data to match the 1.1543 +** spec). 1.1544 +** 1.1545 +** Called from ssl2_HandleClientSessionKeyMessage(). 1.1546 +*/ 1.1547 +static SECStatus 1.1548 +ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, 1.1549 + PRUint8 *ck, unsigned int ckLen, 1.1550 + PRUint8 *ek, unsigned int ekLen, 1.1551 + PRUint8 *ca, unsigned int caLen) 1.1552 +{ 1.1553 + PRUint8 * dk = NULL; /* decrypted master key */ 1.1554 + sslSessionID * sid; 1.1555 + sslServerCerts * sc = ss->serverCerts + kt_rsa; 1.1556 + PRUint8 * kbuf = 0; /* buffer for RSA decrypted data. */ 1.1557 + unsigned int ddLen; /* length of RSA decrypted data in kbuf */ 1.1558 + unsigned int keySize; 1.1559 + unsigned int dkLen; /* decrypted key length in bytes */ 1.1560 + int modulusLen; 1.1561 + SECStatus rv; 1.1562 + PRUint16 allowed; /* cipher kinds enabled and allowed by policy */ 1.1563 + PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES]; 1.1564 + 1.1565 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.1566 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 1.1567 + PORT_Assert((sc->SERVERKEY != 0)); 1.1568 + PORT_Assert((ss->sec.ci.sid != 0)); 1.1569 + sid = ss->sec.ci.sid; 1.1570 + 1.1571 + /* Trying to cut down on all these switch statements that should be tables. 1.1572 + * So, test cipherType once, here, and then use tables below. 1.1573 + */ 1.1574 + switch (cipher) { 1.1575 + case SSL_CK_RC4_128_EXPORT40_WITH_MD5: 1.1576 + case SSL_CK_RC4_128_WITH_MD5: 1.1577 + case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: 1.1578 + case SSL_CK_RC2_128_CBC_WITH_MD5: 1.1579 + case SSL_CK_DES_64_CBC_WITH_MD5: 1.1580 + case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: 1.1581 + break; 1.1582 + 1.1583 + default: 1.1584 + SSL_DBG(("%d: SSL[%d]: ssl2_ServerSetupSessionCypher: unknown cipher=%d", 1.1585 + SSL_GETPID(), ss->fd, cipher)); 1.1586 + PORT_SetError(SSL_ERROR_BAD_CLIENT); 1.1587 + goto loser; 1.1588 + } 1.1589 + 1.1590 + allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED; 1.1591 + if (!(allowed & (1 << cipher))) { 1.1592 + /* client chose a kind we don't allow! */ 1.1593 + SSL_DBG(("%d: SSL[%d]: disallowed cipher=%d", 1.1594 + SSL_GETPID(), ss->fd, cipher)); 1.1595 + PORT_SetError(SSL_ERROR_BAD_CLIENT); 1.1596 + goto loser; 1.1597 + } 1.1598 + 1.1599 + keySize = ssl_Specs[cipher].keyLen; 1.1600 + if (keyBits != keySize * BPB) { 1.1601 + SSL_DBG(("%d: SSL[%d]: invalid master secret key length=%d (bits)!", 1.1602 + SSL_GETPID(), ss->fd, keyBits)); 1.1603 + PORT_SetError(SSL_ERROR_BAD_CLIENT); 1.1604 + goto loser; 1.1605 + } 1.1606 + 1.1607 + if (ckLen != ssl_Specs[cipher].pubLen) { 1.1608 + SSL_DBG(("%d: SSL[%d]: invalid clear key length, ckLen=%d (bytes)!", 1.1609 + SSL_GETPID(), ss->fd, ckLen)); 1.1610 + PORT_SetError(SSL_ERROR_BAD_CLIENT); 1.1611 + goto loser; 1.1612 + } 1.1613 + 1.1614 + if (caLen != ssl_Specs[cipher].ivLen) { 1.1615 + SSL_DBG(("%d: SSL[%d]: invalid key args length, caLen=%d (bytes)!", 1.1616 + SSL_GETPID(), ss->fd, caLen)); 1.1617 + PORT_SetError(SSL_ERROR_BAD_CLIENT); 1.1618 + goto loser; 1.1619 + } 1.1620 + 1.1621 + modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY); 1.1622 + if (modulusLen == -1) { 1.1623 + /* XXX If the key is bad, then PK11_PubDecryptRaw will fail below. */ 1.1624 + modulusLen = ekLen; 1.1625 + } 1.1626 + if (ekLen > modulusLen || ekLen + ckLen < keySize) { 1.1627 + SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!", 1.1628 + SSL_GETPID(), ss->fd, ekLen)); 1.1629 + PORT_SetError(SSL_ERROR_BAD_CLIENT); 1.1630 + goto loser; 1.1631 + } 1.1632 + 1.1633 + /* allocate the buffer to hold the decrypted portion of the key. */ 1.1634 + kbuf = (PRUint8*)PORT_Alloc(modulusLen); 1.1635 + if (!kbuf) { 1.1636 + goto loser; 1.1637 + } 1.1638 + dkLen = keySize - ckLen; 1.1639 + dk = kbuf + modulusLen - dkLen; 1.1640 + 1.1641 + /* Decrypt encrypted half of the key. 1.1642 + ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is 1.1643 + ** desired behavior here. 1.1644 + */ 1.1645 + rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &ddLen, modulusLen, ek, ekLen); 1.1646 + if (rv != SECSuccess) 1.1647 + goto hide_loser; 1.1648 + 1.1649 + /* Is the length of the decrypted data (ddLen) the expected value? */ 1.1650 + if (modulusLen != ddLen) 1.1651 + goto hide_loser; 1.1652 + 1.1653 + /* Cheaply verify that PKCS#1 was used to format the encryption block */ 1.1654 + if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (dk[-1] != 0x00)) { 1.1655 + SSL_DBG(("%d: SSL[%d]: strange encryption block", 1.1656 + SSL_GETPID(), ss->fd)); 1.1657 + PORT_SetError(SSL_ERROR_BAD_CLIENT); 1.1658 + goto hide_loser; 1.1659 + } 1.1660 + 1.1661 + /* Make sure we're not subject to a version rollback attack. */ 1.1662 + if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { 1.1663 + static const PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03, 1.1664 + 0x03, 0x03, 0x03, 0x03 }; 1.1665 + 1.1666 + if (PORT_Memcmp(dk - 8 - 1, threes, 8) == 0) { 1.1667 + PORT_SetError(SSL_ERROR_BAD_CLIENT); 1.1668 + goto hide_loser; 1.1669 + } 1.1670 + } 1.1671 + if (0) { 1.1672 +hide_loser: 1.1673 + /* Defense against the Bleichenbacher attack. 1.1674 + * Provide the client with NO CLUES that the decrypted master key 1.1675 + * was erroneous. Don't send any error messages. 1.1676 + * Instead, Generate a completely bogus master key . 1.1677 + */ 1.1678 + PK11_GenerateRandom(dk, dkLen); 1.1679 + } 1.1680 + 1.1681 + /* 1.1682 + ** Construct master key out of the pieces. 1.1683 + */ 1.1684 + if (ckLen) { 1.1685 + PORT_Memcpy(mkbuf, ck, ckLen); 1.1686 + } 1.1687 + PORT_Memcpy(mkbuf + ckLen, dk, dkLen); 1.1688 + 1.1689 + /* Fill in session-id */ 1.1690 + rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen, 1.1691 + keyBits, keyBits - (ckLen<<3), 1.1692 + ss->sec.authAlgorithm, ss->sec.authKeyBits, 1.1693 + ss->sec.keaType, ss->sec.keaKeyBits); 1.1694 + if (rv != SECSuccess) { 1.1695 + goto loser; 1.1696 + } 1.1697 + 1.1698 + /* Create session ciphers */ 1.1699 + rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE); 1.1700 + if (rv != SECSuccess) { 1.1701 + goto loser; 1.1702 + } 1.1703 + 1.1704 + SSL_TRC(1, ("%d: SSL[%d]: server, using %s cipher, clear=%d total=%d", 1.1705 + SSL_GETPID(), ss->fd, ssl_cipherName[cipher], 1.1706 + ckLen<<3, keySize<<3)); 1.1707 + rv = SECSuccess; 1.1708 + goto done; 1.1709 + 1.1710 + loser: 1.1711 + rv = SECFailure; 1.1712 + 1.1713 + done: 1.1714 + PORT_Free(kbuf); 1.1715 + return rv; 1.1716 +} 1.1717 + 1.1718 +/************************************************************************/ 1.1719 + 1.1720 +/* 1.1721 +** Rewrite the incoming cipher specs, comparing to list of specs we support, 1.1722 +** (ss->cipherSpecs) and eliminating anything we don't support 1.1723 +** 1.1724 +* Note: Our list may contain SSL v3 ciphers. 1.1725 +* We MUST NOT match on any of those. 1.1726 +* Fortunately, this is easy to detect because SSLv3 ciphers have zero 1.1727 +* in the first byte, and none of the SSLv2 ciphers do. 1.1728 +* 1.1729 +* Called from ssl2_HandleClientHelloMessage(). 1.1730 +* Returns the number of bytes of "qualified cipher specs", 1.1731 +* which is typically a multiple of 3, but will be zero if there are none. 1.1732 +*/ 1.1733 +static int 1.1734 +ssl2_QualifyCypherSpecs(sslSocket *ss, 1.1735 + PRUint8 * cs, /* cipher specs in client hello msg. */ 1.1736 + int csLen) 1.1737 +{ 1.1738 + PRUint8 * ms; 1.1739 + PRUint8 * hs; 1.1740 + PRUint8 * qs; 1.1741 + int mc; 1.1742 + int hc; 1.1743 + PRUint8 qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3]; 1.1744 + 1.1745 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.1746 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 1.1747 + 1.1748 + if (!ss->cipherSpecs) { 1.1749 + SECStatus rv = ssl2_ConstructCipherSpecs(ss); 1.1750 + if (rv != SECSuccess || !ss->cipherSpecs) 1.1751 + return 0; 1.1752 + } 1.1753 + 1.1754 + PRINT_BUF(10, (ss, "specs from client:", cs, csLen)); 1.1755 + qs = qualifiedSpecs; 1.1756 + ms = ss->cipherSpecs; 1.1757 + for (mc = ss->sizeCipherSpecs; mc > 0; mc -= 3, ms += 3) { 1.1758 + if (ms[0] == 0) 1.1759 + continue; 1.1760 + for (hs = cs, hc = csLen; hc > 0; hs += 3, hc -= 3) { 1.1761 + if ((hs[0] == ms[0]) && 1.1762 + (hs[1] == ms[1]) && 1.1763 + (hs[2] == ms[2])) { 1.1764 + /* Copy this cipher spec into the "keep" section */ 1.1765 + qs[0] = hs[0]; 1.1766 + qs[1] = hs[1]; 1.1767 + qs[2] = hs[2]; 1.1768 + qs += 3; 1.1769 + break; 1.1770 + } 1.1771 + } 1.1772 + } 1.1773 + hc = qs - qualifiedSpecs; 1.1774 + PRINT_BUF(10, (ss, "qualified specs from client:", qualifiedSpecs, hc)); 1.1775 + PORT_Memcpy(cs, qualifiedSpecs, hc); 1.1776 + return hc; 1.1777 +} 1.1778 + 1.1779 +/* 1.1780 +** Pick the best cipher we can find, given the array of server cipher 1.1781 +** specs. Returns cipher number (e.g. SSL_CK_*), or -1 for no overlap. 1.1782 +** If successful, stores the master key size (bytes) in *pKeyLen. 1.1783 +** 1.1784 +** This is correct only for the client side, but presently 1.1785 +** this function is only called from 1.1786 +** ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage() 1.1787 +** 1.1788 +** Note that most servers only return a single cipher suite in their 1.1789 +** ServerHello messages. So, the code below for finding the "best" cipher 1.1790 +** suite usually has only one choice. The client and server should send 1.1791 +** their cipher suite lists sorted in descending order by preference. 1.1792 +*/ 1.1793 +static int 1.1794 +ssl2_ChooseSessionCypher(sslSocket *ss, 1.1795 + int hc, /* number of cs's in hs. */ 1.1796 + PRUint8 * hs, /* server hello's cipher suites. */ 1.1797 + int * pKeyLen) /* out: sym key size in bytes. */ 1.1798 +{ 1.1799 + PRUint8 * ms; 1.1800 + unsigned int i; 1.1801 + int bestKeySize; 1.1802 + int bestRealKeySize; 1.1803 + int bestCypher; 1.1804 + int keySize; 1.1805 + int realKeySize; 1.1806 + PRUint8 * ohs = hs; 1.1807 + const PRUint8 * preferred; 1.1808 + static const PRUint8 noneSuch[3] = { 0, 0, 0 }; 1.1809 + 1.1810 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.1811 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 1.1812 + 1.1813 + if (!ss->cipherSpecs) { 1.1814 + SECStatus rv = ssl2_ConstructCipherSpecs(ss); 1.1815 + if (rv != SECSuccess || !ss->cipherSpecs) 1.1816 + goto loser; 1.1817 + } 1.1818 + 1.1819 + if (!ss->preferredCipher) { 1.1820 + unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference & 1.1821 + SSL_CB_IMPLEMENTED; 1.1822 + if (allowed) { 1.1823 + preferred = implementedCipherSuites; 1.1824 + for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) { 1.1825 + if (0 != (allowed & (1U << preferred[0]))) { 1.1826 + ss->preferredCipher = preferred; 1.1827 + break; 1.1828 + } 1.1829 + preferred += 3; 1.1830 + } 1.1831 + } 1.1832 + } 1.1833 + preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch; 1.1834 + /* 1.1835 + ** Scan list of ciphers received from peer and look for a match in 1.1836 + ** our list. 1.1837 + * Note: Our list may contain SSL v3 ciphers. 1.1838 + * We MUST NOT match on any of those. 1.1839 + * Fortunately, this is easy to detect because SSLv3 ciphers have zero 1.1840 + * in the first byte, and none of the SSLv2 ciphers do. 1.1841 + */ 1.1842 + bestKeySize = bestRealKeySize = 0; 1.1843 + bestCypher = -1; 1.1844 + while (--hc >= 0) { 1.1845 + for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms += 3) { 1.1846 + if ((hs[0] == preferred[0]) && 1.1847 + (hs[1] == preferred[1]) && 1.1848 + (hs[2] == preferred[2]) && 1.1849 + hs[0] != 0) { 1.1850 + /* Pick this cipher immediately! */ 1.1851 + *pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3; 1.1852 + return hs[0]; 1.1853 + } 1.1854 + if ((hs[0] == ms[0]) && (hs[1] == ms[1]) && (hs[2] == ms[2]) && 1.1855 + hs[0] != 0) { 1.1856 + /* Found a match */ 1.1857 + 1.1858 + /* Use secret keySize to determine which cipher is best */ 1.1859 + realKeySize = (hs[1] << 8) | hs[2]; 1.1860 + switch (hs[0]) { 1.1861 + case SSL_CK_RC4_128_EXPORT40_WITH_MD5: 1.1862 + case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: 1.1863 + keySize = 40; 1.1864 + break; 1.1865 + default: 1.1866 + keySize = realKeySize; 1.1867 + break; 1.1868 + } 1.1869 + if (keySize > bestKeySize) { 1.1870 + bestCypher = hs[0]; 1.1871 + bestKeySize = keySize; 1.1872 + bestRealKeySize = realKeySize; 1.1873 + } 1.1874 + } 1.1875 + } 1.1876 + hs += 3; 1.1877 + } 1.1878 + if (bestCypher < 0) { 1.1879 + /* 1.1880 + ** No overlap between server and client. Re-examine server list 1.1881 + ** to see what kind of ciphers it does support so that we can set 1.1882 + ** the error code appropriately. 1.1883 + */ 1.1884 + if ((ohs[0] == SSL_CK_RC4_128_WITH_MD5) || 1.1885 + (ohs[0] == SSL_CK_RC2_128_CBC_WITH_MD5)) { 1.1886 + PORT_SetError(SSL_ERROR_US_ONLY_SERVER); 1.1887 + } else if ((ohs[0] == SSL_CK_RC4_128_EXPORT40_WITH_MD5) || 1.1888 + (ohs[0] == SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)) { 1.1889 + PORT_SetError(SSL_ERROR_EXPORT_ONLY_SERVER); 1.1890 + } else { 1.1891 + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); 1.1892 + } 1.1893 + SSL_DBG(("%d: SSL[%d]: no cipher overlap", SSL_GETPID(), ss->fd)); 1.1894 + goto loser; 1.1895 + } 1.1896 + *pKeyLen = (bestRealKeySize + 7) >> 3; 1.1897 + return bestCypher; 1.1898 + 1.1899 + loser: 1.1900 + return -1; 1.1901 +} 1.1902 + 1.1903 +static SECStatus 1.1904 +ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen) 1.1905 +{ 1.1906 + CERTCertificate *cert = NULL; 1.1907 + SECItem certItem; 1.1908 + 1.1909 + certItem.data = certData; 1.1910 + certItem.len = certLen; 1.1911 + 1.1912 + /* decode the certificate */ 1.1913 + cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, 1.1914 + PR_FALSE, PR_TRUE); 1.1915 + 1.1916 + if (cert == NULL) { 1.1917 + SSL_DBG(("%d: SSL[%d]: decode of server certificate fails", 1.1918 + SSL_GETPID(), ss->fd)); 1.1919 + PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); 1.1920 + return SECFailure; 1.1921 + } 1.1922 + 1.1923 +#ifdef TRACE 1.1924 + { 1.1925 + if (ssl_trace >= 1) { 1.1926 + char *issuer; 1.1927 + char *subject; 1.1928 + issuer = CERT_NameToAscii(&cert->issuer); 1.1929 + subject = CERT_NameToAscii(&cert->subject); 1.1930 + SSL_TRC(1,("%d: server certificate issuer: '%s'", 1.1931 + SSL_GETPID(), issuer ? issuer : "OOPS")); 1.1932 + SSL_TRC(1,("%d: server name: '%s'", 1.1933 + SSL_GETPID(), subject ? subject : "OOPS")); 1.1934 + PORT_Free(issuer); 1.1935 + PORT_Free(subject); 1.1936 + } 1.1937 + } 1.1938 +#endif 1.1939 + 1.1940 + ss->sec.peerCert = cert; 1.1941 + return SECSuccess; 1.1942 +} 1.1943 + 1.1944 + 1.1945 +/* 1.1946 + * Format one block of data for public/private key encryption using 1.1947 + * the rules defined in PKCS #1. SSL2 does this itself to handle the 1.1948 + * rollback detection. 1.1949 + */ 1.1950 +#define RSA_BLOCK_MIN_PAD_LEN 8 1.1951 +#define RSA_BLOCK_FIRST_OCTET 0x00 1.1952 +#define RSA_BLOCK_AFTER_PAD_OCTET 0x00 1.1953 +#define RSA_BLOCK_PUBLIC_OCTET 0x02 1.1954 +unsigned char * 1.1955 +ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data) 1.1956 +{ 1.1957 + unsigned char *block; 1.1958 + unsigned char *bp; 1.1959 + int padLen; 1.1960 + SECStatus rv; 1.1961 + int i; 1.1962 + 1.1963 + if (modulusLen < data->len + (3 + RSA_BLOCK_MIN_PAD_LEN)) { 1.1964 + PORT_SetError(SEC_ERROR_BAD_KEY); 1.1965 + return NULL; 1.1966 + } 1.1967 + block = (unsigned char *) PORT_Alloc(modulusLen); 1.1968 + if (block == NULL) 1.1969 + return NULL; 1.1970 + 1.1971 + bp = block; 1.1972 + 1.1973 + /* 1.1974 + * All RSA blocks start with two octets: 1.1975 + * 0x00 || BlockType 1.1976 + */ 1.1977 + *bp++ = RSA_BLOCK_FIRST_OCTET; 1.1978 + *bp++ = RSA_BLOCK_PUBLIC_OCTET; 1.1979 + 1.1980 + /* 1.1981 + * 0x00 || BT || Pad || 0x00 || ActualData 1.1982 + * 1 1 padLen 1 data->len 1.1983 + * Pad is all non-zero random bytes. 1.1984 + */ 1.1985 + padLen = modulusLen - data->len - 3; 1.1986 + PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN); 1.1987 + rv = PK11_GenerateRandom(bp, padLen); 1.1988 + if (rv == SECFailure) goto loser; 1.1989 + /* replace all the 'zero' bytes */ 1.1990 + for (i = 0; i < padLen; i++) { 1.1991 + while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET) { 1.1992 + rv = PK11_GenerateRandom(bp+i, 1); 1.1993 + if (rv == SECFailure) goto loser; 1.1994 + } 1.1995 + } 1.1996 + bp += padLen; 1.1997 + *bp++ = RSA_BLOCK_AFTER_PAD_OCTET; 1.1998 + PORT_Memcpy (bp, data->data, data->len); 1.1999 + 1.2000 + return block; 1.2001 +loser: 1.2002 + if (block) PORT_Free(block); 1.2003 + return NULL; 1.2004 +} 1.2005 + 1.2006 +/* 1.2007 +** Given the server's public key and cipher specs, generate a session key 1.2008 +** that is ready to use for encrypting/decrypting the byte stream. At 1.2009 +** the same time, generate the SSL_MT_CLIENT_MASTER_KEY message and 1.2010 +** send it to the server. 1.2011 +** 1.2012 +** Called from ssl2_HandleServerHelloMessage() 1.2013 +*/ 1.2014 +static SECStatus 1.2015 +ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen) 1.2016 +{ 1.2017 + sslSessionID * sid; 1.2018 + PRUint8 * ca; /* points to iv data, or NULL if none. */ 1.2019 + PRUint8 * ekbuf = 0; 1.2020 + CERTCertificate * cert = 0; 1.2021 + SECKEYPublicKey * serverKey = 0; 1.2022 + unsigned modulusLen = 0; 1.2023 + SECStatus rv; 1.2024 + int cipher; 1.2025 + int keyLen; /* cipher symkey size in bytes. */ 1.2026 + int ckLen; /* publicly reveal this many bytes of key. */ 1.2027 + int caLen; /* length of IV data at *ca. */ 1.2028 + int nc; 1.2029 + 1.2030 + unsigned char *eblock; /* holds unencrypted PKCS#1 formatted key. */ 1.2031 + SECItem rek; /* holds portion of symkey to be encrypted. */ 1.2032 + 1.2033 + PRUint8 keyData[SSL_MAX_MASTER_KEY_BYTES]; 1.2034 + PRUint8 iv [8]; 1.2035 + 1.2036 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.2037 + 1.2038 + eblock = NULL; 1.2039 + 1.2040 + sid = ss->sec.ci.sid; 1.2041 + PORT_Assert(sid != 0); 1.2042 + 1.2043 + cert = ss->sec.peerCert; 1.2044 + 1.2045 + serverKey = CERT_ExtractPublicKey(cert); 1.2046 + if (!serverKey) { 1.2047 + SSL_DBG(("%d: SSL[%d]: extract public key failed: error=%d", 1.2048 + SSL_GETPID(), ss->fd, PORT_GetError())); 1.2049 + PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); 1.2050 + rv = SECFailure; 1.2051 + goto loser2; 1.2052 + } 1.2053 + 1.2054 + ss->sec.authAlgorithm = ssl_sign_rsa; 1.2055 + ss->sec.keaType = ssl_kea_rsa; 1.2056 + ss->sec.keaKeyBits = \ 1.2057 + ss->sec.authKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey); 1.2058 + 1.2059 + /* Choose a compatible cipher with the server */ 1.2060 + nc = csLen / 3; 1.2061 + cipher = ssl2_ChooseSessionCypher(ss, nc, cs, &keyLen); 1.2062 + if (cipher < 0) { 1.2063 + /* ssl2_ChooseSessionCypher has set error code. */ 1.2064 + ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS); 1.2065 + goto loser; 1.2066 + } 1.2067 + 1.2068 + /* Generate the random keys */ 1.2069 + PK11_GenerateRandom(keyData, sizeof(keyData)); 1.2070 + 1.2071 + /* 1.2072 + ** Next, carve up the keys into clear and encrypted portions. The 1.2073 + ** clear data is taken from the start of keyData and the encrypted 1.2074 + ** portion from the remainder. Note that each of these portions is 1.2075 + ** carved in half, one half for the read-key and one for the 1.2076 + ** write-key. 1.2077 + */ 1.2078 + ca = 0; 1.2079 + 1.2080 + /* We know that cipher is a legit value here, because 1.2081 + * ssl2_ChooseSessionCypher doesn't return bogus values. 1.2082 + */ 1.2083 + ckLen = ssl_Specs[cipher].pubLen; /* cleartext key length. */ 1.2084 + caLen = ssl_Specs[cipher].ivLen; /* IV length. */ 1.2085 + if (caLen) { 1.2086 + PORT_Assert(sizeof iv >= caLen); 1.2087 + PK11_GenerateRandom(iv, caLen); 1.2088 + ca = iv; 1.2089 + } 1.2090 + 1.2091 + /* Fill in session-id */ 1.2092 + rv = ssl2_FillInSID(sid, cipher, keyData, keyLen, 1.2093 + ca, caLen, keyLen << 3, (keyLen - ckLen) << 3, 1.2094 + ss->sec.authAlgorithm, ss->sec.authKeyBits, 1.2095 + ss->sec.keaType, ss->sec.keaKeyBits); 1.2096 + if (rv != SECSuccess) { 1.2097 + goto loser; 1.2098 + } 1.2099 + 1.2100 + SSL_TRC(1, ("%d: SSL[%d]: client, using %s cipher, clear=%d total=%d", 1.2101 + SSL_GETPID(), ss->fd, ssl_cipherName[cipher], 1.2102 + ckLen<<3, keyLen<<3)); 1.2103 + 1.2104 + /* Now setup read and write ciphers */ 1.2105 + rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE); 1.2106 + if (rv != SECSuccess) { 1.2107 + goto loser; 1.2108 + } 1.2109 + 1.2110 + /* 1.2111 + ** Fill in the encryption buffer with some random bytes. Then 1.2112 + ** copy in the portion of the session key we are encrypting. 1.2113 + */ 1.2114 + modulusLen = SECKEY_PublicKeyStrength(serverKey); 1.2115 + rek.data = keyData + ckLen; 1.2116 + rek.len = keyLen - ckLen; 1.2117 + eblock = ssl_FormatSSL2Block(modulusLen, &rek); 1.2118 + if (eblock == NULL) 1.2119 + goto loser; 1.2120 + 1.2121 + /* Set up the padding for version 2 rollback detection. */ 1.2122 + /* XXX We should really use defines here */ 1.2123 + if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { 1.2124 + PORT_Assert((modulusLen - rek.len) > 12); 1.2125 + PORT_Memset(eblock + modulusLen - rek.len - 8 - 1, 0x03, 8); 1.2126 + } 1.2127 + ekbuf = (PRUint8*) PORT_Alloc(modulusLen); 1.2128 + if (!ekbuf) 1.2129 + goto loser; 1.2130 + PRINT_BUF(10, (ss, "master key encryption block:", 1.2131 + eblock, modulusLen)); 1.2132 + 1.2133 + /* Encrypt ekitem */ 1.2134 + rv = PK11_PubEncryptRaw(serverKey, ekbuf, eblock, modulusLen, 1.2135 + ss->pkcs11PinArg); 1.2136 + if (rv) 1.2137 + goto loser; 1.2138 + 1.2139 + /* Now we have everything ready to send */ 1.2140 + rv = ssl2_SendSessionKeyMessage(ss, cipher, keyLen << 3, ca, caLen, 1.2141 + keyData, ckLen, ekbuf, modulusLen); 1.2142 + if (rv != SECSuccess) { 1.2143 + goto loser; 1.2144 + } 1.2145 + rv = SECSuccess; 1.2146 + goto done; 1.2147 + 1.2148 + loser: 1.2149 + rv = SECFailure; 1.2150 + 1.2151 + loser2: 1.2152 + done: 1.2153 + PORT_Memset(keyData, 0, sizeof(keyData)); 1.2154 + PORT_ZFree(ekbuf, modulusLen); 1.2155 + PORT_ZFree(eblock, modulusLen); 1.2156 + SECKEY_DestroyPublicKey(serverKey); 1.2157 + return rv; 1.2158 +} 1.2159 + 1.2160 +/************************************************************************/ 1.2161 + 1.2162 +/* 1.2163 + * Called from ssl2_HandleMessage in response to SSL_MT_SERVER_FINISHED message. 1.2164 + * Caller holds recvBufLock and handshakeLock 1.2165 + */ 1.2166 +static void 1.2167 +ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s) 1.2168 +{ 1.2169 + sslSessionID *sid = ss->sec.ci.sid; 1.2170 + 1.2171 + /* Record entry in nonce cache */ 1.2172 + if (sid->peerCert == NULL) { 1.2173 + PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID)); 1.2174 + sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); 1.2175 + 1.2176 + } 1.2177 + if (!ss->opt.noCache && sid->cached == never_cached) 1.2178 + (*ss->sec.cache)(sid); 1.2179 +} 1.2180 + 1.2181 +/* Called from ssl2_HandleMessage() */ 1.2182 +static SECStatus 1.2183 +ssl2_TriggerNextMessage(sslSocket *ss) 1.2184 +{ 1.2185 + SECStatus rv; 1.2186 + 1.2187 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.2188 + 1.2189 + if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) && 1.2190 + !(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) { 1.2191 + ss->sec.ci.sentElements |= CIS_HAVE_CERTIFICATE; 1.2192 + rv = ssl2_SendCertificateRequestMessage(ss); 1.2193 + return rv; 1.2194 + } 1.2195 + return SECSuccess; 1.2196 +} 1.2197 + 1.2198 +/* See if it's time to send our finished message, or if the handshakes are 1.2199 +** complete. Send finished message if appropriate. 1.2200 +** Returns SECSuccess unless anything goes wrong. 1.2201 +** 1.2202 +** Called from ssl2_HandleMessage, 1.2203 +** ssl2_HandleVerifyMessage 1.2204 +** ssl2_HandleServerHelloMessage 1.2205 +** ssl2_HandleClientSessionKeyMessage 1.2206 +*/ 1.2207 +static SECStatus 1.2208 +ssl2_TryToFinish(sslSocket *ss) 1.2209 +{ 1.2210 + SECStatus rv; 1.2211 + char e, ef; 1.2212 + 1.2213 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.2214 + 1.2215 + e = ss->sec.ci.elements; 1.2216 + ef = e | CIS_HAVE_FINISHED; 1.2217 + if ((ef & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) { 1.2218 + if (ss->sec.isServer) { 1.2219 + /* Send server finished message if we already didn't */ 1.2220 + rv = ssl2_SendServerFinishedMessage(ss); 1.2221 + } else { 1.2222 + /* Send client finished message if we already didn't */ 1.2223 + rv = ssl2_SendClientFinishedMessage(ss); 1.2224 + } 1.2225 + if (rv != SECSuccess) { 1.2226 + return rv; 1.2227 + } 1.2228 + if ((e & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) { 1.2229 + /* Totally finished */ 1.2230 + ss->handshake = 0; 1.2231 + return SECSuccess; 1.2232 + } 1.2233 + } 1.2234 + return SECSuccess; 1.2235 +} 1.2236 + 1.2237 +/* 1.2238 +** Called from ssl2_HandleRequestCertificate 1.2239 +*/ 1.2240 +static SECStatus 1.2241 +ssl2_SignResponse(sslSocket *ss, 1.2242 + SECKEYPrivateKey *key, 1.2243 + SECItem *response) 1.2244 +{ 1.2245 + SGNContext * sgn = NULL; 1.2246 + PRUint8 * challenge; 1.2247 + unsigned int len; 1.2248 + SECStatus rv = SECFailure; 1.2249 + 1.2250 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.2251 + 1.2252 + challenge = ss->sec.ci.serverChallenge; 1.2253 + len = ss->sec.ci.serverChallengeLen; 1.2254 + 1.2255 + /* Sign the expected data... */ 1.2256 + sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,key); 1.2257 + if (!sgn) 1.2258 + goto done; 1.2259 + rv = SGN_Begin(sgn); 1.2260 + if (rv != SECSuccess) 1.2261 + goto done; 1.2262 + rv = SGN_Update(sgn, ss->sec.ci.readKey, ss->sec.ci.keySize); 1.2263 + if (rv != SECSuccess) 1.2264 + goto done; 1.2265 + rv = SGN_Update(sgn, ss->sec.ci.writeKey, ss->sec.ci.keySize); 1.2266 + if (rv != SECSuccess) 1.2267 + goto done; 1.2268 + rv = SGN_Update(sgn, challenge, len); 1.2269 + if (rv != SECSuccess) 1.2270 + goto done; 1.2271 + rv = SGN_Update(sgn, ss->sec.peerCert->derCert.data, 1.2272 + ss->sec.peerCert->derCert.len); 1.2273 + if (rv != SECSuccess) 1.2274 + goto done; 1.2275 + rv = SGN_End(sgn, response); 1.2276 + if (rv != SECSuccess) 1.2277 + goto done; 1.2278 + 1.2279 +done: 1.2280 + SGN_DestroyContext(sgn, PR_TRUE); 1.2281 + return rv == SECSuccess ? SECSuccess : SECFailure; 1.2282 +} 1.2283 + 1.2284 +/* 1.2285 +** Try to handle a request-certificate message. Get client's certificate 1.2286 +** and private key and sign a message for the server to see. 1.2287 +** Caller must hold handshakeLock 1.2288 +** 1.2289 +** Called from ssl2_HandleMessage(). 1.2290 +*/ 1.2291 +static int 1.2292 +ssl2_HandleRequestCertificate(sslSocket *ss) 1.2293 +{ 1.2294 + CERTCertificate * cert = NULL; /* app-selected client cert. */ 1.2295 + SECKEYPrivateKey *key = NULL; /* priv key for cert. */ 1.2296 + SECStatus rv; 1.2297 + SECItem response; 1.2298 + int ret = 0; 1.2299 + PRUint8 authType; 1.2300 + 1.2301 + 1.2302 + /* 1.2303 + * These things all need to be initialized before we can "goto loser". 1.2304 + */ 1.2305 + response.data = NULL; 1.2306 + 1.2307 + /* get challenge info from connectionInfo */ 1.2308 + authType = ss->sec.ci.authType; 1.2309 + 1.2310 + if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) { 1.2311 + SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(), 1.2312 + ss->fd, authType)); 1.2313 + goto no_cert_error; 1.2314 + } 1.2315 + 1.2316 + /* Get certificate and private-key from client */ 1.2317 + if (!ss->getClientAuthData) { 1.2318 + SSL_TRC(7, ("%d: SSL[%d]: client doesn't support client-auth", 1.2319 + SSL_GETPID(), ss->fd)); 1.2320 + goto no_cert_error; 1.2321 + } 1.2322 + ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd, 1.2323 + NULL, &cert, &key); 1.2324 + if ( ret == SECWouldBlock ) { 1.2325 + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); 1.2326 + ret = -1; 1.2327 + goto loser; 1.2328 + } 1.2329 + 1.2330 + if (ret) { 1.2331 + goto no_cert_error; 1.2332 + } 1.2333 + 1.2334 + /* check what the callback function returned */ 1.2335 + if ((!cert) || (!key)) { 1.2336 + /* we are missing either the key or cert */ 1.2337 + if (cert) { 1.2338 + /* got a cert, but no key - free it */ 1.2339 + CERT_DestroyCertificate(cert); 1.2340 + cert = NULL; 1.2341 + } 1.2342 + if (key) { 1.2343 + /* got a key, but no cert - free it */ 1.2344 + SECKEY_DestroyPrivateKey(key); 1.2345 + key = NULL; 1.2346 + } 1.2347 + goto no_cert_error; 1.2348 + } 1.2349 + 1.2350 + rv = ssl2_SignResponse(ss, key, &response); 1.2351 + if ( rv != SECSuccess ) { 1.2352 + ret = -1; 1.2353 + goto loser; 1.2354 + } 1.2355 + 1.2356 + /* Send response message */ 1.2357 + ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response); 1.2358 + 1.2359 + /* Now, remember the cert we sent. But first, forget any previous one. */ 1.2360 + if (ss->sec.localCert) { 1.2361 + CERT_DestroyCertificate(ss->sec.localCert); 1.2362 + } 1.2363 + ss->sec.localCert = CERT_DupCertificate(cert); 1.2364 + PORT_Assert(!ss->sec.ci.sid->localCert); 1.2365 + if (ss->sec.ci.sid->localCert) { 1.2366 + CERT_DestroyCertificate(ss->sec.ci.sid->localCert); 1.2367 + } 1.2368 + ss->sec.ci.sid->localCert = cert; 1.2369 + cert = NULL; 1.2370 + 1.2371 + goto done; 1.2372 + 1.2373 + no_cert_error: 1.2374 + SSL_TRC(7, ("%d: SSL[%d]: no certificate (ret=%d)", SSL_GETPID(), 1.2375 + ss->fd, ret)); 1.2376 + ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE); 1.2377 + 1.2378 + loser: 1.2379 + done: 1.2380 + if ( cert ) { 1.2381 + CERT_DestroyCertificate(cert); 1.2382 + } 1.2383 + if ( key ) { 1.2384 + SECKEY_DestroyPrivateKey(key); 1.2385 + } 1.2386 + if ( response.data ) { 1.2387 + PORT_Free(response.data); 1.2388 + } 1.2389 + 1.2390 + return ret; 1.2391 +} 1.2392 + 1.2393 +/* 1.2394 +** Called from ssl2_HandleMessage for SSL_MT_CLIENT_CERTIFICATE message. 1.2395 +** Caller must hold HandshakeLock and RecvBufLock, since cd and response 1.2396 +** are contained in the gathered input data. 1.2397 +*/ 1.2398 +static SECStatus 1.2399 +ssl2_HandleClientCertificate(sslSocket * ss, 1.2400 + PRUint8 certType, /* XXX unused */ 1.2401 + PRUint8 * cd, 1.2402 + unsigned int cdLen, 1.2403 + PRUint8 * response, 1.2404 + unsigned int responseLen) 1.2405 +{ 1.2406 + CERTCertificate *cert = NULL; 1.2407 + SECKEYPublicKey *pubKey = NULL; 1.2408 + VFYContext * vfy = NULL; 1.2409 + SECItem * derCert; 1.2410 + SECStatus rv = SECFailure; 1.2411 + SECItem certItem; 1.2412 + SECItem rep; 1.2413 + 1.2414 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.2415 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 1.2416 + 1.2417 + /* Extract the certificate */ 1.2418 + certItem.data = cd; 1.2419 + certItem.len = cdLen; 1.2420 + 1.2421 + cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, 1.2422 + PR_FALSE, PR_TRUE); 1.2423 + if (cert == NULL) { 1.2424 + goto loser; 1.2425 + } 1.2426 + 1.2427 + /* save the certificate, since the auth routine will need it */ 1.2428 + ss->sec.peerCert = cert; 1.2429 + 1.2430 + /* Extract the public key */ 1.2431 + pubKey = CERT_ExtractPublicKey(cert); 1.2432 + if (!pubKey) 1.2433 + goto loser; 1.2434 + 1.2435 + /* Verify the response data... */ 1.2436 + rep.data = response; 1.2437 + rep.len = responseLen; 1.2438 + /* SSL 2.0 only supports RSA certs, so we don't have to worry about 1.2439 + * DSA here. */ 1.2440 + vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION, 1.2441 + ss->pkcs11PinArg); 1.2442 + if (!vfy) 1.2443 + goto loser; 1.2444 + rv = VFY_Begin(vfy); 1.2445 + if (rv) 1.2446 + goto loser; 1.2447 + 1.2448 + rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize); 1.2449 + if (rv) 1.2450 + goto loser; 1.2451 + rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize); 1.2452 + if (rv) 1.2453 + goto loser; 1.2454 + rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); 1.2455 + if (rv) 1.2456 + goto loser; 1.2457 + 1.2458 + derCert = &ss->serverCerts[kt_rsa].serverCert->derCert; 1.2459 + rv = VFY_Update(vfy, derCert->data, derCert->len); 1.2460 + if (rv) 1.2461 + goto loser; 1.2462 + rv = VFY_End(vfy); 1.2463 + if (rv) 1.2464 + goto loser; 1.2465 + 1.2466 + /* Now ask the server application if it likes the certificate... */ 1.2467 + rv = (SECStatus) (*ss->authCertificate)(ss->authCertificateArg, 1.2468 + ss->fd, PR_TRUE, PR_TRUE); 1.2469 + /* Hey, it liked it. */ 1.2470 + if (SECSuccess == rv) 1.2471 + goto done; 1.2472 + 1.2473 +loser: 1.2474 + ss->sec.peerCert = NULL; 1.2475 + CERT_DestroyCertificate(cert); 1.2476 + 1.2477 +done: 1.2478 + VFY_DestroyContext(vfy, PR_TRUE); 1.2479 + SECKEY_DestroyPublicKey(pubKey); 1.2480 + return rv; 1.2481 +} 1.2482 + 1.2483 +/* 1.2484 +** Handle remaining messages between client/server. Process finished 1.2485 +** messages from either side and any authentication requests. 1.2486 +** This should only be called for SSLv2 handshake messages, 1.2487 +** not for application data records. 1.2488 +** Caller must hold handshake lock. 1.2489 +** 1.2490 +** Called from ssl_Do1stHandshake(). 1.2491 +** 1.2492 +*/ 1.2493 +static SECStatus 1.2494 +ssl2_HandleMessage(sslSocket *ss) 1.2495 +{ 1.2496 + PRUint8 * data; 1.2497 + PRUint8 * cid; 1.2498 + unsigned len, certType, certLen, responseLen; 1.2499 + int rv; 1.2500 + int rv2; 1.2501 + 1.2502 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.2503 + 1.2504 + ssl_GetRecvBufLock(ss); 1.2505 + 1.2506 + data = ss->gs.buf.buf + ss->gs.recordOffset; 1.2507 + 1.2508 + if (ss->gs.recordLen < 1) { 1.2509 + goto bad_peer; 1.2510 + } 1.2511 + SSL_TRC(3, ("%d: SSL[%d]: received %d message", 1.2512 + SSL_GETPID(), ss->fd, data[0])); 1.2513 + DUMP_MSG(29, (ss, data, ss->gs.recordLen)); 1.2514 + 1.2515 + switch (data[0]) { 1.2516 + case SSL_MT_CLIENT_FINISHED: 1.2517 + if (ss->sec.ci.elements & CIS_HAVE_FINISHED) { 1.2518 + SSL_DBG(("%d: SSL[%d]: dup client-finished message", 1.2519 + SSL_GETPID(), ss->fd)); 1.2520 + goto bad_peer; 1.2521 + } 1.2522 + 1.2523 + /* See if nonce matches */ 1.2524 + len = ss->gs.recordLen - 1; 1.2525 + cid = data + 1; 1.2526 + if ((len != sizeof(ss->sec.ci.connectionID)) || 1.2527 + (PORT_Memcmp(ss->sec.ci.connectionID, cid, len) != 0)) { 1.2528 + SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd)); 1.2529 + PRINT_BUF(5, (ss, "sent connection-id", 1.2530 + ss->sec.ci.connectionID, 1.2531 + sizeof(ss->sec.ci.connectionID))); 1.2532 + PRINT_BUF(5, (ss, "rcvd connection-id", cid, len)); 1.2533 + goto bad_peer; 1.2534 + } 1.2535 + 1.2536 + SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d", 1.2537 + SSL_GETPID(), ss->fd, 1.2538 + ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); 1.2539 + ss->sec.ci.elements |= CIS_HAVE_FINISHED; 1.2540 + break; 1.2541 + 1.2542 + case SSL_MT_SERVER_FINISHED: 1.2543 + if (ss->sec.ci.elements & CIS_HAVE_FINISHED) { 1.2544 + SSL_DBG(("%d: SSL[%d]: dup server-finished message", 1.2545 + SSL_GETPID(), ss->fd)); 1.2546 + goto bad_peer; 1.2547 + } 1.2548 + 1.2549 + if (ss->gs.recordLen - 1 != SSL2_SESSIONID_BYTES) { 1.2550 + SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d", 1.2551 + SSL_GETPID(), ss->fd, ss->gs.recordLen)); 1.2552 + goto bad_peer; 1.2553 + } 1.2554 + ssl2_ClientRegSessionID(ss, data+1); 1.2555 + SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d", 1.2556 + SSL_GETPID(), ss->fd, 1.2557 + ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); 1.2558 + ss->sec.ci.elements |= CIS_HAVE_FINISHED; 1.2559 + break; 1.2560 + 1.2561 + case SSL_MT_REQUEST_CERTIFICATE: 1.2562 + len = ss->gs.recordLen - 2; 1.2563 + if ((len < SSL_MIN_CHALLENGE_BYTES) || 1.2564 + (len > SSL_MAX_CHALLENGE_BYTES)) { 1.2565 + /* Bad challenge */ 1.2566 + SSL_DBG(("%d: SSL[%d]: bad cert request message: code len=%d", 1.2567 + SSL_GETPID(), ss->fd, len)); 1.2568 + goto bad_peer; 1.2569 + } 1.2570 + 1.2571 + /* save auth request info */ 1.2572 + ss->sec.ci.authType = data[1]; 1.2573 + ss->sec.ci.serverChallengeLen = len; 1.2574 + PORT_Memcpy(ss->sec.ci.serverChallenge, data + 2, len); 1.2575 + 1.2576 + rv = ssl2_HandleRequestCertificate(ss); 1.2577 + if (rv == SECWouldBlock) { 1.2578 + SSL_TRC(3, ("%d: SSL[%d]: async cert request", 1.2579 + SSL_GETPID(), ss->fd)); 1.2580 + /* someone is handling this asynchronously */ 1.2581 + ssl_ReleaseRecvBufLock(ss); 1.2582 + return SECWouldBlock; 1.2583 + } 1.2584 + if (rv) { 1.2585 + SET_ERROR_CODE 1.2586 + goto loser; 1.2587 + } 1.2588 + break; 1.2589 + 1.2590 + case SSL_MT_CLIENT_CERTIFICATE: 1.2591 + if (!ss->authCertificate) { 1.2592 + /* Server asked for authentication and can't handle it */ 1.2593 + PORT_SetError(SSL_ERROR_BAD_SERVER); 1.2594 + goto loser; 1.2595 + } 1.2596 + if (ss->gs.recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) { 1.2597 + SET_ERROR_CODE 1.2598 + goto loser; 1.2599 + } 1.2600 + certType = data[1]; 1.2601 + certLen = (data[2] << 8) | data[3]; 1.2602 + responseLen = (data[4] << 8) | data[5]; 1.2603 + if (certType != SSL_CT_X509_CERTIFICATE) { 1.2604 + PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); 1.2605 + goto loser; 1.2606 + } 1.2607 + if (certLen + responseLen + SSL_HL_CLIENT_CERTIFICATE_HBYTES 1.2608 + > ss->gs.recordLen) { 1.2609 + /* prevent overflow crash. */ 1.2610 + rv = SECFailure; 1.2611 + } else 1.2612 + rv = ssl2_HandleClientCertificate(ss, data[1], 1.2613 + data + SSL_HL_CLIENT_CERTIFICATE_HBYTES, 1.2614 + certLen, 1.2615 + data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen, 1.2616 + responseLen); 1.2617 + if (rv) { 1.2618 + rv2 = ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); 1.2619 + SET_ERROR_CODE 1.2620 + goto loser; 1.2621 + } 1.2622 + ss->sec.ci.elements |= CIS_HAVE_CERTIFICATE; 1.2623 + break; 1.2624 + 1.2625 + case SSL_MT_ERROR: 1.2626 + rv = (data[1] << 8) | data[2]; 1.2627 + SSL_TRC(2, ("%d: SSL[%d]: got error message, error=0x%x", 1.2628 + SSL_GETPID(), ss->fd, rv)); 1.2629 + 1.2630 + /* Convert protocol error number into API error number */ 1.2631 + switch (rv) { 1.2632 + case SSL_PE_NO_CYPHERS: 1.2633 + rv = SSL_ERROR_NO_CYPHER_OVERLAP; 1.2634 + break; 1.2635 + case SSL_PE_NO_CERTIFICATE: 1.2636 + rv = SSL_ERROR_NO_CERTIFICATE; 1.2637 + break; 1.2638 + case SSL_PE_BAD_CERTIFICATE: 1.2639 + rv = SSL_ERROR_BAD_CERTIFICATE; 1.2640 + break; 1.2641 + case SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE: 1.2642 + rv = SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE; 1.2643 + break; 1.2644 + default: 1.2645 + goto bad_peer; 1.2646 + } 1.2647 + /* XXX make certificate-request optionally fail... */ 1.2648 + PORT_SetError(rv); 1.2649 + goto loser; 1.2650 + 1.2651 + default: 1.2652 + SSL_DBG(("%d: SSL[%d]: unknown message %d", 1.2653 + SSL_GETPID(), ss->fd, data[0])); 1.2654 + goto loser; 1.2655 + } 1.2656 + 1.2657 + SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x", 1.2658 + SSL_GETPID(), ss->fd, data[0], 1.2659 + ss->sec.ci.requiredElements, ss->sec.ci.elements)); 1.2660 + 1.2661 + rv = ssl2_TryToFinish(ss); 1.2662 + if (rv != SECSuccess) 1.2663 + goto loser; 1.2664 + 1.2665 + ss->gs.recordLen = 0; 1.2666 + ssl_ReleaseRecvBufLock(ss); 1.2667 + 1.2668 + if (ss->handshake == 0) { 1.2669 + return SECSuccess; 1.2670 + } 1.2671 + 1.2672 + ss->handshake = ssl_GatherRecord1stHandshake; 1.2673 + ss->nextHandshake = ssl2_HandleMessage; 1.2674 + return ssl2_TriggerNextMessage(ss); 1.2675 + 1.2676 + bad_peer: 1.2677 + PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER); 1.2678 + /* FALL THROUGH */ 1.2679 + 1.2680 + loser: 1.2681 + ssl_ReleaseRecvBufLock(ss); 1.2682 + return SECFailure; 1.2683 +} 1.2684 + 1.2685 +/************************************************************************/ 1.2686 + 1.2687 +/* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage. 1.2688 +*/ 1.2689 +static SECStatus 1.2690 +ssl2_HandleVerifyMessage(sslSocket *ss) 1.2691 +{ 1.2692 + PRUint8 * data; 1.2693 + SECStatus rv; 1.2694 + 1.2695 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.2696 + ssl_GetRecvBufLock(ss); 1.2697 + 1.2698 + data = ss->gs.buf.buf + ss->gs.recordOffset; 1.2699 + DUMP_MSG(29, (ss, data, ss->gs.recordLen)); 1.2700 + if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) || 1.2701 + (data[0] != SSL_MT_SERVER_VERIFY) || 1.2702 + NSS_SecureMemcmp(data+1, ss->sec.ci.clientChallenge, 1.2703 + SSL_CHALLENGE_BYTES)) { 1.2704 + /* Bad server */ 1.2705 + PORT_SetError(SSL_ERROR_BAD_SERVER); 1.2706 + goto loser; 1.2707 + } 1.2708 + ss->sec.ci.elements |= CIS_HAVE_VERIFY; 1.2709 + 1.2710 + SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x", 1.2711 + SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, 1.2712 + ss->sec.ci.elements)); 1.2713 + 1.2714 + rv = ssl2_TryToFinish(ss); 1.2715 + if (rv) 1.2716 + goto loser; 1.2717 + 1.2718 + ss->gs.recordLen = 0; 1.2719 + ssl_ReleaseRecvBufLock(ss); 1.2720 + 1.2721 + if (ss->handshake == 0) { 1.2722 + return SECSuccess; 1.2723 + } 1.2724 + ss->handshake = ssl_GatherRecord1stHandshake; 1.2725 + ss->nextHandshake = ssl2_HandleMessage; 1.2726 + return SECSuccess; 1.2727 + 1.2728 + 1.2729 + loser: 1.2730 + ssl_ReleaseRecvBufLock(ss); 1.2731 + return SECFailure; 1.2732 +} 1.2733 + 1.2734 +/* Not static because ssl2_GatherData() tests ss->nextHandshake for this value. 1.2735 + * ICK! 1.2736 + * Called from ssl_Do1stHandshake after ssl2_BeginClientHandshake() 1.2737 + */ 1.2738 +SECStatus 1.2739 +ssl2_HandleServerHelloMessage(sslSocket *ss) 1.2740 +{ 1.2741 + sslSessionID * sid; 1.2742 + PRUint8 * cert; 1.2743 + PRUint8 * cs; 1.2744 + PRUint8 * data; 1.2745 + SECStatus rv; 1.2746 + int needed, sidHit, certLen, csLen, cidLen, certType, err; 1.2747 + 1.2748 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.2749 + 1.2750 + if (!ss->opt.enableSSL2) { 1.2751 + PORT_SetError(SSL_ERROR_SSL2_DISABLED); 1.2752 + return SECFailure; 1.2753 + } 1.2754 + 1.2755 + ssl_GetRecvBufLock(ss); 1.2756 + 1.2757 + PORT_Assert(ss->sec.ci.sid != 0); 1.2758 + sid = ss->sec.ci.sid; 1.2759 + 1.2760 + data = ss->gs.buf.buf + ss->gs.recordOffset; 1.2761 + DUMP_MSG(29, (ss, data, ss->gs.recordLen)); 1.2762 + 1.2763 + /* Make sure first message has some data and is the server hello message */ 1.2764 + if ((ss->gs.recordLen < SSL_HL_SERVER_HELLO_HBYTES) 1.2765 + || (data[0] != SSL_MT_SERVER_HELLO)) { 1.2766 + if ((data[0] == SSL_MT_ERROR) && (ss->gs.recordLen == 3)) { 1.2767 + err = (data[1] << 8) | data[2]; 1.2768 + if (err == SSL_PE_NO_CYPHERS) { 1.2769 + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); 1.2770 + goto loser; 1.2771 + } 1.2772 + } 1.2773 + goto bad_server; 1.2774 + } 1.2775 + 1.2776 + sidHit = data[1]; 1.2777 + certType = data[2]; 1.2778 + ss->version = (data[3] << 8) | data[4]; 1.2779 + certLen = (data[5] << 8) | data[6]; 1.2780 + csLen = (data[7] << 8) | data[8]; 1.2781 + cidLen = (data[9] << 8) | data[10]; 1.2782 + cert = data + SSL_HL_SERVER_HELLO_HBYTES; 1.2783 + cs = cert + certLen; 1.2784 + 1.2785 + SSL_TRC(5, 1.2786 + ("%d: SSL[%d]: server-hello, hit=%d vers=%x certLen=%d csLen=%d cidLen=%d", 1.2787 + SSL_GETPID(), ss->fd, sidHit, ss->version, certLen, 1.2788 + csLen, cidLen)); 1.2789 + if (ss->version != SSL_LIBRARY_VERSION_2) { 1.2790 + if (ss->version < SSL_LIBRARY_VERSION_2) { 1.2791 + SSL_TRC(3, ("%d: SSL[%d]: demoting self (%x) to server version (%x)", 1.2792 + SSL_GETPID(), ss->fd, SSL_LIBRARY_VERSION_2, 1.2793 + ss->version)); 1.2794 + } else { 1.2795 + SSL_TRC(1, ("%d: SSL[%d]: server version is %x (we are %x)", 1.2796 + SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2)); 1.2797 + /* server claims to be newer but does not follow protocol */ 1.2798 + PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); 1.2799 + goto loser; 1.2800 + } 1.2801 + } 1.2802 + 1.2803 + if ((SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen + cidLen 1.2804 + > ss->gs.recordLen) 1.2805 + || (csLen % 3) != 0 1.2806 + /* || cidLen < SSL_CONNECTIONID_BYTES || cidLen > 32 */ 1.2807 + ) { 1.2808 + goto bad_server; 1.2809 + } 1.2810 + 1.2811 + /* Save connection-id. 1.2812 + ** This code only saves the first 16 byte of the connectionID. 1.2813 + ** If the connectionID is shorter than 16 bytes, it is zero-padded. 1.2814 + */ 1.2815 + if (cidLen < sizeof ss->sec.ci.connectionID) 1.2816 + memset(ss->sec.ci.connectionID, 0, sizeof ss->sec.ci.connectionID); 1.2817 + cidLen = PR_MIN(cidLen, sizeof ss->sec.ci.connectionID); 1.2818 + PORT_Memcpy(ss->sec.ci.connectionID, cs + csLen, cidLen); 1.2819 + 1.2820 + /* See if session-id hit */ 1.2821 + needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY; 1.2822 + if (sidHit) { 1.2823 + if (certLen || csLen) { 1.2824 + /* Uh oh - bogus server */ 1.2825 + SSL_DBG(("%d: SSL[%d]: client, huh? hit=%d certLen=%d csLen=%d", 1.2826 + SSL_GETPID(), ss->fd, sidHit, certLen, csLen)); 1.2827 + goto bad_server; 1.2828 + } 1.2829 + 1.2830 + /* Total winner. */ 1.2831 + SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x " 1.2832 + "port=0x%04x", 1.2833 + SSL_GETPID(), ss->fd, ss->sec.ci.peer, ss->sec.ci.port)); 1.2834 + ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); 1.2835 + ss->sec.authAlgorithm = sid->authAlgorithm; 1.2836 + ss->sec.authKeyBits = sid->authKeyBits; 1.2837 + ss->sec.keaType = sid->keaType; 1.2838 + ss->sec.keaKeyBits = sid->keaKeyBits; 1.2839 + rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE); 1.2840 + if (rv != SECSuccess) { 1.2841 + goto loser; 1.2842 + } 1.2843 + } else { 1.2844 + if (certType != SSL_CT_X509_CERTIFICATE) { 1.2845 + PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); 1.2846 + goto loser; 1.2847 + } 1.2848 + if (csLen == 0) { 1.2849 + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); 1.2850 + SSL_DBG(("%d: SSL[%d]: no cipher overlap", 1.2851 + SSL_GETPID(), ss->fd)); 1.2852 + goto loser; 1.2853 + } 1.2854 + if (certLen == 0) { 1.2855 + SSL_DBG(("%d: SSL[%d]: client, huh? certLen=%d csLen=%d", 1.2856 + SSL_GETPID(), ss->fd, certLen, csLen)); 1.2857 + goto bad_server; 1.2858 + } 1.2859 + 1.2860 + if (sid->cached != never_cached) { 1.2861 + /* Forget our session-id - server didn't like it */ 1.2862 + SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id", 1.2863 + SSL_GETPID(), ss->fd)); 1.2864 + if (ss->sec.uncache) 1.2865 + (*ss->sec.uncache)(sid); 1.2866 + ssl_FreeSID(sid); 1.2867 + ss->sec.ci.sid = sid = PORT_ZNew(sslSessionID); 1.2868 + if (!sid) { 1.2869 + goto loser; 1.2870 + } 1.2871 + sid->references = 1; 1.2872 + sid->addr = ss->sec.ci.peer; 1.2873 + sid->port = ss->sec.ci.port; 1.2874 + } 1.2875 + 1.2876 + /* decode the server's certificate */ 1.2877 + rv = ssl2_ClientHandleServerCert(ss, cert, certLen); 1.2878 + if (rv != SECSuccess) { 1.2879 + if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) { 1.2880 + (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); 1.2881 + } 1.2882 + goto loser; 1.2883 + } 1.2884 + 1.2885 + /* Setup new session cipher */ 1.2886 + rv = ssl2_ClientSetupSessionCypher(ss, cs, csLen); 1.2887 + if (rv != SECSuccess) { 1.2888 + if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) { 1.2889 + (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); 1.2890 + } 1.2891 + goto loser; 1.2892 + } 1.2893 + } 1.2894 + 1.2895 + /* Build up final list of required elements */ 1.2896 + ss->sec.ci.elements = CIS_HAVE_MASTER_KEY; 1.2897 + ss->sec.ci.requiredElements = needed; 1.2898 + 1.2899 + if (!sidHit) { 1.2900 + /* verify the server's certificate. if sidHit, don't check signatures */ 1.2901 + rv = (* ss->authCertificate)(ss->authCertificateArg, ss->fd, 1.2902 + (PRBool)(!sidHit), PR_FALSE); 1.2903 + if (rv) { 1.2904 + if (ss->handleBadCert) { 1.2905 + rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd); 1.2906 + if ( rv ) { 1.2907 + if ( rv == SECWouldBlock ) { 1.2908 + SSL_DBG(("%d: SSL[%d]: SSL2 bad cert handler returned " 1.2909 + "SECWouldBlock", SSL_GETPID(), ss->fd)); 1.2910 + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); 1.2911 + rv = SECFailure; 1.2912 + } else { 1.2913 + /* cert is bad */ 1.2914 + SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d", 1.2915 + SSL_GETPID(), ss->fd, PORT_GetError())); 1.2916 + } 1.2917 + goto loser; 1.2918 + } 1.2919 + /* cert is good */ 1.2920 + } else { 1.2921 + SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d", 1.2922 + SSL_GETPID(), ss->fd, PORT_GetError())); 1.2923 + goto loser; 1.2924 + } 1.2925 + } 1.2926 + } 1.2927 + /* 1.2928 + ** At this point we have a completed session key and our session 1.2929 + ** cipher is setup and ready to go. Switch to encrypted write routine 1.2930 + ** as all future message data is to be encrypted. 1.2931 + */ 1.2932 + ssl2_UseEncryptedSendFunc(ss); 1.2933 + 1.2934 + rv = ssl2_TryToFinish(ss); 1.2935 + if (rv != SECSuccess) 1.2936 + goto loser; 1.2937 + 1.2938 + ss->gs.recordLen = 0; 1.2939 + 1.2940 + ssl_ReleaseRecvBufLock(ss); 1.2941 + 1.2942 + if (ss->handshake == 0) { 1.2943 + return SECSuccess; 1.2944 + } 1.2945 + 1.2946 + SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x", 1.2947 + SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, 1.2948 + ss->sec.ci.elements)); 1.2949 + ss->handshake = ssl_GatherRecord1stHandshake; 1.2950 + ss->nextHandshake = ssl2_HandleVerifyMessage; 1.2951 + return SECSuccess; 1.2952 + 1.2953 + bad_server: 1.2954 + PORT_SetError(SSL_ERROR_BAD_SERVER); 1.2955 + /* FALL THROUGH */ 1.2956 + 1.2957 + loser: 1.2958 + ssl_ReleaseRecvBufLock(ss); 1.2959 + return SECFailure; 1.2960 +} 1.2961 + 1.2962 +/* Sends out the initial client Hello message on the connection. 1.2963 + * Acquires and releases the socket's xmitBufLock. 1.2964 + */ 1.2965 +SECStatus 1.2966 +ssl2_BeginClientHandshake(sslSocket *ss) 1.2967 +{ 1.2968 + sslSessionID *sid; 1.2969 + PRUint8 *msg; 1.2970 + PRUint8 *cp; 1.2971 + PRUint8 *localCipherSpecs = NULL; 1.2972 + unsigned int localCipherSize; 1.2973 + unsigned int i; 1.2974 + int sendLen, sidLen = 0; 1.2975 + SECStatus rv; 1.2976 + TLSExtensionData *xtnData; 1.2977 + 1.2978 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.2979 + 1.2980 + ss->sec.isServer = 0; 1.2981 + ss->sec.sendSequence = 0; 1.2982 + ss->sec.rcvSequence = 0; 1.2983 + ssl_ChooseSessionIDProcs(&ss->sec); 1.2984 + 1.2985 + if (!ss->cipherSpecs) { 1.2986 + rv = ssl2_ConstructCipherSpecs(ss); 1.2987 + if (rv != SECSuccess) 1.2988 + goto loser; 1.2989 + } 1.2990 + 1.2991 + /* count the SSL2 and SSL3 enabled ciphers. 1.2992 + * if either is zero, clear the socket's enable for that protocol. 1.2993 + */ 1.2994 + rv = ssl2_CheckConfigSanity(ss); 1.2995 + if (rv != SECSuccess) 1.2996 + goto loser; 1.2997 + 1.2998 + /* Get peer name of server */ 1.2999 + rv = ssl_GetPeerInfo(ss); 1.3000 + if (rv < 0) { 1.3001 +#ifdef HPUX11 1.3002 + /* 1.3003 + * On some HP-UX B.11.00 systems, getpeername() occasionally 1.3004 + * fails with ENOTCONN after a successful completion of 1.3005 + * non-blocking connect. I found that if we do a write() 1.3006 + * and then retry getpeername(), it will work. 1.3007 + */ 1.3008 + if (PR_GetError() == PR_NOT_CONNECTED_ERROR) { 1.3009 + char dummy; 1.3010 + (void) PR_Write(ss->fd->lower, &dummy, 0); 1.3011 + rv = ssl_GetPeerInfo(ss); 1.3012 + if (rv < 0) { 1.3013 + goto loser; 1.3014 + } 1.3015 + } 1.3016 +#else 1.3017 + goto loser; 1.3018 +#endif 1.3019 + } 1.3020 + 1.3021 + SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd)); 1.3022 + 1.3023 + /* Try to find server in our session-id cache */ 1.3024 + if (ss->opt.noCache) { 1.3025 + sid = NULL; 1.3026 + } else { 1.3027 + sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, 1.3028 + ss->url); 1.3029 + } 1.3030 + while (sid) { /* this isn't really a loop */ 1.3031 + PRBool sidVersionEnabled = 1.3032 + (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) && 1.3033 + sid->version >= ss->vrange.min && 1.3034 + sid->version <= ss->vrange.max) || 1.3035 + (sid->version < SSL_LIBRARY_VERSION_3_0 && ss->opt.enableSSL2); 1.3036 + 1.3037 + /* if we're not doing this SID's protocol any more, drop it. */ 1.3038 + if (!sidVersionEnabled) { 1.3039 + if (ss->sec.uncache) 1.3040 + ss->sec.uncache(sid); 1.3041 + ssl_FreeSID(sid); 1.3042 + sid = NULL; 1.3043 + break; 1.3044 + } 1.3045 + if (sid->version < SSL_LIBRARY_VERSION_3_0) { 1.3046 + /* If the cipher in this sid is not enabled, drop it. */ 1.3047 + for (i = 0; i < ss->sizeCipherSpecs; i += 3) { 1.3048 + if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType) 1.3049 + break; 1.3050 + } 1.3051 + if (i >= ss->sizeCipherSpecs) { 1.3052 + if (ss->sec.uncache) 1.3053 + ss->sec.uncache(sid); 1.3054 + ssl_FreeSID(sid); 1.3055 + sid = NULL; 1.3056 + break; 1.3057 + } 1.3058 + } 1.3059 + sidLen = sizeof(sid->u.ssl2.sessionID); 1.3060 + PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID, 1.3061 + sidLen)); 1.3062 + ss->version = sid->version; 1.3063 + PORT_Assert(!ss->sec.localCert); 1.3064 + if (ss->sec.localCert) { 1.3065 + CERT_DestroyCertificate(ss->sec.localCert); 1.3066 + } 1.3067 + ss->sec.localCert = CERT_DupCertificate(sid->localCert); 1.3068 + break; /* this isn't really a loop */ 1.3069 + } 1.3070 + if (!sid) { 1.3071 + sidLen = 0; 1.3072 + sid = PORT_ZNew(sslSessionID); 1.3073 + if (!sid) { 1.3074 + goto loser; 1.3075 + } 1.3076 + sid->references = 1; 1.3077 + sid->cached = never_cached; 1.3078 + sid->addr = ss->sec.ci.peer; 1.3079 + sid->port = ss->sec.ci.port; 1.3080 + if (ss->peerID != NULL) { 1.3081 + sid->peerID = PORT_Strdup(ss->peerID); 1.3082 + } 1.3083 + if (ss->url != NULL) { 1.3084 + sid->urlSvrName = PORT_Strdup(ss->url); 1.3085 + } 1.3086 + } 1.3087 + ss->sec.ci.sid = sid; 1.3088 + 1.3089 + PORT_Assert(sid != NULL); 1.3090 + 1.3091 + if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->opt.v2CompatibleHello) && 1.3092 + !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { 1.3093 + ss->gs.state = GS_INIT; 1.3094 + ss->handshake = ssl_GatherRecord1stHandshake; 1.3095 + 1.3096 + /* ssl3_SendClientHello will override this if it succeeds. */ 1.3097 + ss->version = SSL_LIBRARY_VERSION_3_0; 1.3098 + 1.3099 + ssl_GetSSL3HandshakeLock(ss); 1.3100 + ssl_GetXmitBufLock(ss); 1.3101 + rv = ssl3_SendClientHello(ss, PR_FALSE); 1.3102 + ssl_ReleaseXmitBufLock(ss); 1.3103 + ssl_ReleaseSSL3HandshakeLock(ss); 1.3104 + 1.3105 + return rv; 1.3106 + } 1.3107 +#ifndef NSS_DISABLE_ECC 1.3108 + /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */ 1.3109 + ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */ 1.3110 + if (ss->cipherSpecs != NULL) { 1.3111 + PORT_Free(ss->cipherSpecs); 1.3112 + ss->cipherSpecs = NULL; 1.3113 + ss->sizeCipherSpecs = 0; 1.3114 + } 1.3115 +#endif /* NSS_DISABLE_ECC */ 1.3116 + 1.3117 + if (!ss->cipherSpecs) { 1.3118 + rv = ssl2_ConstructCipherSpecs(ss); 1.3119 + if (rv < 0) { 1.3120 + return rv; 1.3121 + } 1.3122 + } 1.3123 + localCipherSpecs = ss->cipherSpecs; 1.3124 + localCipherSize = ss->sizeCipherSpecs; 1.3125 + 1.3126 + /* Add 3 for SCSV */ 1.3127 + sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + 3 + sidLen + 1.3128 + SSL_CHALLENGE_BYTES; 1.3129 + 1.3130 + /* Generate challenge bytes for server */ 1.3131 + PK11_GenerateRandom(ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); 1.3132 + 1.3133 + ssl_GetXmitBufLock(ss); /***************************************/ 1.3134 + 1.3135 + rv = ssl2_GetSendBuffer(ss, sendLen); 1.3136 + if (rv) 1.3137 + goto unlock_loser; 1.3138 + 1.3139 + /* Construct client-hello message */ 1.3140 + cp = msg = ss->sec.ci.sendBuf.buf; 1.3141 + msg[0] = SSL_MT_CLIENT_HELLO; 1.3142 + ss->clientHelloVersion = SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) ? 1.3143 + SSL_LIBRARY_VERSION_2 : ss->vrange.max; 1.3144 + 1.3145 + msg[1] = MSB(ss->clientHelloVersion); 1.3146 + msg[2] = LSB(ss->clientHelloVersion); 1.3147 + /* Add 3 for SCSV */ 1.3148 + msg[3] = MSB(localCipherSize + 3); 1.3149 + msg[4] = LSB(localCipherSize + 3); 1.3150 + msg[5] = MSB(sidLen); 1.3151 + msg[6] = LSB(sidLen); 1.3152 + msg[7] = MSB(SSL_CHALLENGE_BYTES); 1.3153 + msg[8] = LSB(SSL_CHALLENGE_BYTES); 1.3154 + cp += SSL_HL_CLIENT_HELLO_HBYTES; 1.3155 + PORT_Memcpy(cp, localCipherSpecs, localCipherSize); 1.3156 + cp += localCipherSize; 1.3157 + /* 1.3158 + * Add SCSV. SSL 2.0 cipher suites are listed before SSL 3.0 cipher 1.3159 + * suites in localCipherSpecs for compatibility with SSL 2.0 servers. 1.3160 + * Since SCSV looks like an SSL 3.0 cipher suite, we can't add it at 1.3161 + * the beginning. 1.3162 + */ 1.3163 + cp[0] = 0x00; 1.3164 + cp[1] = 0x00; 1.3165 + cp[2] = 0xff; 1.3166 + cp += 3; 1.3167 + if (sidLen) { 1.3168 + PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen); 1.3169 + cp += sidLen; 1.3170 + } 1.3171 + PORT_Memcpy(cp, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); 1.3172 + 1.3173 + /* Send it to the server */ 1.3174 + DUMP_MSG(29, (ss, msg, sendLen)); 1.3175 + ss->handshakeBegun = 1; 1.3176 + rv = (*ss->sec.send)(ss, msg, sendLen, 0); 1.3177 + 1.3178 + ssl_ReleaseXmitBufLock(ss); /***************************************/ 1.3179 + 1.3180 + if (rv < 0) { 1.3181 + goto loser; 1.3182 + } 1.3183 + 1.3184 + rv = ssl3_StartHandshakeHash(ss, msg, sendLen); 1.3185 + if (rv < 0) { 1.3186 + goto loser; 1.3187 + } 1.3188 + 1.3189 + /* 1.3190 + * Since we sent the SCSV, pretend we sent empty RI extension. We need 1.3191 + * to record the extension has been advertised after ssl3_InitState has 1.3192 + * been called, which ssl3_StartHandshakeHash took care for us above. 1.3193 + */ 1.3194 + xtnData = &ss->xtnData; 1.3195 + xtnData->advertised[xtnData->numAdvertised++] = ssl_renegotiation_info_xtn; 1.3196 + 1.3197 + /* Setup to receive servers hello message */ 1.3198 + ssl_GetRecvBufLock(ss); 1.3199 + ss->gs.recordLen = 0; 1.3200 + ssl_ReleaseRecvBufLock(ss); 1.3201 + 1.3202 + ss->handshake = ssl_GatherRecord1stHandshake; 1.3203 + ss->nextHandshake = ssl2_HandleServerHelloMessage; 1.3204 + return SECSuccess; 1.3205 + 1.3206 +unlock_loser: 1.3207 + ssl_ReleaseXmitBufLock(ss); 1.3208 +loser: 1.3209 + return SECFailure; 1.3210 +} 1.3211 + 1.3212 +/************************************************************************/ 1.3213 + 1.3214 +/* Handle the CLIENT-MASTER-KEY message. 1.3215 +** Acquires and releases RecvBufLock. 1.3216 +** Called from ssl2_HandleClientHelloMessage(). 1.3217 +*/ 1.3218 +static SECStatus 1.3219 +ssl2_HandleClientSessionKeyMessage(sslSocket *ss) 1.3220 +{ 1.3221 + PRUint8 * data; 1.3222 + unsigned int caLen; 1.3223 + unsigned int ckLen; 1.3224 + unsigned int ekLen; 1.3225 + unsigned int keyBits; 1.3226 + int cipher; 1.3227 + SECStatus rv; 1.3228 + 1.3229 + 1.3230 + ssl_GetRecvBufLock(ss); 1.3231 + 1.3232 + data = ss->gs.buf.buf + ss->gs.recordOffset; 1.3233 + DUMP_MSG(29, (ss, data, ss->gs.recordLen)); 1.3234 + 1.3235 + if ((ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES) 1.3236 + || (data[0] != SSL_MT_CLIENT_MASTER_KEY)) { 1.3237 + goto bad_client; 1.3238 + } 1.3239 + cipher = data[1]; 1.3240 + keyBits = (data[2] << 8) | data[3]; 1.3241 + ckLen = (data[4] << 8) | data[5]; 1.3242 + ekLen = (data[6] << 8) | data[7]; 1.3243 + caLen = (data[8] << 8) | data[9]; 1.3244 + 1.3245 + SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keyBits=%d ckLen=%d ekLen=%d caLen=%d", 1.3246 + SSL_GETPID(), ss->fd, cipher, keyBits, ckLen, ekLen, caLen)); 1.3247 + 1.3248 + if (ss->gs.recordLen < 1.3249 + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) { 1.3250 + SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d", 1.3251 + SSL_GETPID(), ss->fd, ss->gs.recordLen)); 1.3252 + goto bad_client; 1.3253 + } 1.3254 + 1.3255 + /* Use info from client to setup session key */ 1.3256 + rv = ssl2_ServerSetupSessionCypher(ss, cipher, keyBits, 1.3257 + data + SSL_HL_CLIENT_MASTER_KEY_HBYTES, ckLen, 1.3258 + data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen, ekLen, 1.3259 + data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen); 1.3260 + ss->gs.recordLen = 0; /* we're done with this record. */ 1.3261 + 1.3262 + ssl_ReleaseRecvBufLock(ss); 1.3263 + 1.3264 + if (rv != SECSuccess) { 1.3265 + goto loser; 1.3266 + } 1.3267 + ss->sec.ci.elements |= CIS_HAVE_MASTER_KEY; 1.3268 + ssl2_UseEncryptedSendFunc(ss); 1.3269 + 1.3270 + /* Send server verify message now that keys are established */ 1.3271 + rv = ssl2_SendServerVerifyMessage(ss); 1.3272 + if (rv != SECSuccess) 1.3273 + goto loser; 1.3274 + 1.3275 + rv = ssl2_TryToFinish(ss); 1.3276 + if (rv != SECSuccess) 1.3277 + goto loser; 1.3278 + if (ss->handshake == 0) { 1.3279 + return SECSuccess; 1.3280 + } 1.3281 + 1.3282 + SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d", 1.3283 + SSL_GETPID(), ss->fd, 1.3284 + ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); 1.3285 + ss->handshake = ssl_GatherRecord1stHandshake; 1.3286 + ss->nextHandshake = ssl2_HandleMessage; 1.3287 + 1.3288 + return ssl2_TriggerNextMessage(ss); 1.3289 + 1.3290 +bad_client: 1.3291 + ssl_ReleaseRecvBufLock(ss); 1.3292 + PORT_SetError(SSL_ERROR_BAD_CLIENT); 1.3293 + /* FALLTHROUGH */ 1.3294 + 1.3295 +loser: 1.3296 + return SECFailure; 1.3297 +} 1.3298 + 1.3299 +/* 1.3300 +** Handle the initial hello message from the client 1.3301 +** 1.3302 +** not static because ssl2_GatherData() tests ss->nextHandshake for this value. 1.3303 +*/ 1.3304 +SECStatus 1.3305 +ssl2_HandleClientHelloMessage(sslSocket *ss) 1.3306 +{ 1.3307 + sslSessionID *sid; 1.3308 + sslServerCerts * sc; 1.3309 + CERTCertificate *serverCert; 1.3310 + PRUint8 *msg; 1.3311 + PRUint8 *data; 1.3312 + PRUint8 *cs; 1.3313 + PRUint8 *sd; 1.3314 + PRUint8 *cert = NULL; 1.3315 + PRUint8 *challenge; 1.3316 + unsigned int challengeLen; 1.3317 + SECStatus rv; 1.3318 + int csLen; 1.3319 + int sendLen; 1.3320 + int sdLen; 1.3321 + int certLen; 1.3322 + int pid; 1.3323 + int sent; 1.3324 + int gotXmitBufLock = 0; 1.3325 +#if defined(SOLARIS) && defined(i386) 1.3326 + volatile PRUint8 hit; 1.3327 +#else 1.3328 + int hit; 1.3329 +#endif 1.3330 + PRUint8 csImpl[sizeof implementedCipherSuites]; 1.3331 + 1.3332 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.3333 + 1.3334 + sc = ss->serverCerts + kt_rsa; 1.3335 + serverCert = sc->serverCert; 1.3336 + 1.3337 + ssl_GetRecvBufLock(ss); 1.3338 + 1.3339 + 1.3340 + data = ss->gs.buf.buf + ss->gs.recordOffset; 1.3341 + DUMP_MSG(29, (ss, data, ss->gs.recordLen)); 1.3342 + 1.3343 + /* Make sure first message has some data and is the client hello message */ 1.3344 + if ((ss->gs.recordLen < SSL_HL_CLIENT_HELLO_HBYTES) 1.3345 + || (data[0] != SSL_MT_CLIENT_HELLO)) { 1.3346 + goto bad_client; 1.3347 + } 1.3348 + 1.3349 + /* Get peer name of client */ 1.3350 + rv = ssl_GetPeerInfo(ss); 1.3351 + if (rv != SECSuccess) { 1.3352 + goto loser; 1.3353 + } 1.3354 + 1.3355 + /* Examine version information */ 1.3356 + /* 1.3357 + * See if this might be a V2 client hello asking to use the V3 protocol 1.3358 + */ 1.3359 + if ((data[0] == SSL_MT_CLIENT_HELLO) && 1.3360 + (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) && 1.3361 + !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { 1.3362 + rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen); 1.3363 + if (rv != SECFailure) { /* Success */ 1.3364 + ss->handshake = NULL; 1.3365 + ss->nextHandshake = ssl_GatherRecord1stHandshake; 1.3366 + ss->securityHandshake = NULL; 1.3367 + ss->gs.state = GS_INIT; 1.3368 + 1.3369 + /* ssl3_HandleV3ClientHello has set ss->version, 1.3370 + ** and has gotten us a brand new sid. 1.3371 + */ 1.3372 + ss->sec.ci.sid->version = ss->version; 1.3373 + } 1.3374 + ssl_ReleaseRecvBufLock(ss); 1.3375 + return rv; 1.3376 + } 1.3377 + /* Previously, there was a test here to see if SSL2 was enabled. 1.3378 + ** If not, an error code was set, and SECFailure was returned, 1.3379 + ** without sending any error code to the other end of the connection. 1.3380 + ** That test has been removed. If SSL2 has been disabled, there 1.3381 + ** should be no SSL2 ciphers enabled, and consequently, the code 1.3382 + ** below should send the ssl2 error message SSL_PE_NO_CYPHERS. 1.3383 + ** We now believe this is the correct thing to do, even when SSL2 1.3384 + ** has been explicitly disabled by the application. 1.3385 + */ 1.3386 + 1.3387 + /* Extract info from message */ 1.3388 + ss->version = (data[1] << 8) | data[2]; 1.3389 + 1.3390 + /* If some client thinks ssl v2 is 2.0 instead of 0.2, we'll allow it. */ 1.3391 + if (ss->version >= SSL_LIBRARY_VERSION_3_0) { 1.3392 + ss->version = SSL_LIBRARY_VERSION_2; 1.3393 + } 1.3394 + 1.3395 + csLen = (data[3] << 8) | data[4]; 1.3396 + sdLen = (data[5] << 8) | data[6]; 1.3397 + challengeLen = (data[7] << 8) | data[8]; 1.3398 + cs = data + SSL_HL_CLIENT_HELLO_HBYTES; 1.3399 + sd = cs + csLen; 1.3400 + challenge = sd + sdLen; 1.3401 + PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen)); 1.3402 + 1.3403 + if (!csLen || (csLen % 3) != 0 || 1.3404 + (sdLen != 0 && sdLen != SSL2_SESSIONID_BYTES) || 1.3405 + challengeLen < SSL_MIN_CHALLENGE_BYTES || 1.3406 + challengeLen > SSL_MAX_CHALLENGE_BYTES || 1.3407 + (unsigned)ss->gs.recordLen != 1.3408 + SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) { 1.3409 + SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d", 1.3410 + SSL_GETPID(), ss->fd, ss->gs.recordLen, 1.3411 + SSL_HL_CLIENT_HELLO_HBYTES+csLen+sdLen+challengeLen)); 1.3412 + goto bad_client; 1.3413 + } 1.3414 + 1.3415 + SSL_TRC(3, ("%d: SSL[%d]: client version is %x", 1.3416 + SSL_GETPID(), ss->fd, ss->version)); 1.3417 + if (ss->version != SSL_LIBRARY_VERSION_2) { 1.3418 + if (ss->version > SSL_LIBRARY_VERSION_2) { 1.3419 + /* 1.3420 + ** Newer client than us. Things are ok because new clients 1.3421 + ** are required to be backwards compatible with old servers. 1.3422 + ** Change version number to our version number so that client 1.3423 + ** knows whats up. 1.3424 + */ 1.3425 + ss->version = SSL_LIBRARY_VERSION_2; 1.3426 + } else { 1.3427 + SSL_TRC(1, ("%d: SSL[%d]: client version is %x (we are %x)", 1.3428 + SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2)); 1.3429 + PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); 1.3430 + goto loser; 1.3431 + } 1.3432 + } 1.3433 + 1.3434 + /* Qualify cipher specs before returning them to client */ 1.3435 + csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen); 1.3436 + if (csLen == 0) { 1.3437 + /* no overlap, send client our list of supported SSL v2 ciphers. */ 1.3438 + cs = csImpl; 1.3439 + csLen = sizeof implementedCipherSuites; 1.3440 + PORT_Memcpy(cs, implementedCipherSuites, csLen); 1.3441 + csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen); 1.3442 + if (csLen == 0) { 1.3443 + /* We don't support any SSL v2 ciphers! */ 1.3444 + ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS); 1.3445 + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); 1.3446 + goto loser; 1.3447 + } 1.3448 + /* Since this handhsake is going to fail, don't cache it. */ 1.3449 + ss->opt.noCache = 1; 1.3450 + } 1.3451 + 1.3452 + /* Squirrel away the challenge for later */ 1.3453 + PORT_Memcpy(ss->sec.ci.clientChallenge, challenge, challengeLen); 1.3454 + 1.3455 + /* Examine message and see if session-id is good */ 1.3456 + ss->sec.ci.elements = 0; 1.3457 + if (sdLen > 0 && !ss->opt.noCache) { 1.3458 + SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x", 1.3459 + SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0], 1.3460 + ss->sec.ci.peer.pr_s6_addr32[1], 1.3461 + ss->sec.ci.peer.pr_s6_addr32[2], 1.3462 + ss->sec.ci.peer.pr_s6_addr32[3])); 1.3463 + sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sd, sdLen, ss->dbHandle); 1.3464 + } else { 1.3465 + sid = NULL; 1.3466 + } 1.3467 + if (sid) { 1.3468 + /* Got a good session-id. Short cut! */ 1.3469 + SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)", 1.3470 + SSL_GETPID(), ss->fd, ss->sec.ci.peer, 1.3471 + ssl_Time() - sid->creationTime)); 1.3472 + PRINT_BUF(1, (ss, "session-id value:", sd, sdLen)); 1.3473 + ss->sec.ci.sid = sid; 1.3474 + ss->sec.ci.elements = CIS_HAVE_MASTER_KEY; 1.3475 + hit = 1; 1.3476 + certLen = 0; 1.3477 + csLen = 0; 1.3478 + 1.3479 + ss->sec.authAlgorithm = sid->authAlgorithm; 1.3480 + ss->sec.authKeyBits = sid->authKeyBits; 1.3481 + ss->sec.keaType = sid->keaType; 1.3482 + ss->sec.keaKeyBits = sid->keaKeyBits; 1.3483 + 1.3484 + rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE); 1.3485 + if (rv != SECSuccess) { 1.3486 + goto loser; 1.3487 + } 1.3488 + } else { 1.3489 + SECItem * derCert = &serverCert->derCert; 1.3490 + 1.3491 + SSL_TRC(7, ("%d: SSL[%d]: server, lookup nonce missed", 1.3492 + SSL_GETPID(), ss->fd)); 1.3493 + if (!serverCert) { 1.3494 + SET_ERROR_CODE 1.3495 + goto loser; 1.3496 + } 1.3497 + hit = 0; 1.3498 + sid = PORT_ZNew(sslSessionID); 1.3499 + if (!sid) { 1.3500 + goto loser; 1.3501 + } 1.3502 + sid->references = 1; 1.3503 + sid->addr = ss->sec.ci.peer; 1.3504 + sid->port = ss->sec.ci.port; 1.3505 + 1.3506 + /* Invent a session-id */ 1.3507 + ss->sec.ci.sid = sid; 1.3508 + PK11_GenerateRandom(sid->u.ssl2.sessionID+2, SSL2_SESSIONID_BYTES-2); 1.3509 + 1.3510 + pid = SSL_GETPID(); 1.3511 + sid->u.ssl2.sessionID[0] = MSB(pid); 1.3512 + sid->u.ssl2.sessionID[1] = LSB(pid); 1.3513 + cert = derCert->data; 1.3514 + certLen = derCert->len; 1.3515 + 1.3516 + /* pretend that server sids remember the local cert. */ 1.3517 + PORT_Assert(!sid->localCert); 1.3518 + if (sid->localCert) { 1.3519 + CERT_DestroyCertificate(sid->localCert); 1.3520 + } 1.3521 + sid->localCert = CERT_DupCertificate(serverCert); 1.3522 + 1.3523 + ss->sec.authAlgorithm = ssl_sign_rsa; 1.3524 + ss->sec.keaType = ssl_kea_rsa; 1.3525 + ss->sec.keaKeyBits = \ 1.3526 + ss->sec.authKeyBits = ss->serverCerts[kt_rsa].serverKeyBits; 1.3527 + } 1.3528 + 1.3529 + /* server sids don't remember the local cert, so whether we found 1.3530 + ** a sid or not, just "remember" we used the rsa server cert. 1.3531 + */ 1.3532 + if (ss->sec.localCert) { 1.3533 + CERT_DestroyCertificate(ss->sec.localCert); 1.3534 + } 1.3535 + ss->sec.localCert = CERT_DupCertificate(serverCert); 1.3536 + 1.3537 + /* Build up final list of required elements */ 1.3538 + ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED; 1.3539 + if (ss->opt.requestCertificate) { 1.3540 + ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE; 1.3541 + } 1.3542 + ss->sec.ci.sentElements = 0; 1.3543 + 1.3544 + /* Send hello message back to client */ 1.3545 + sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen 1.3546 + + SSL_CONNECTIONID_BYTES; 1.3547 + 1.3548 + ssl_GetXmitBufLock(ss); gotXmitBufLock = 1; 1.3549 + rv = ssl2_GetSendBuffer(ss, sendLen); 1.3550 + if (rv != SECSuccess) { 1.3551 + goto loser; 1.3552 + } 1.3553 + 1.3554 + SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)", 1.3555 + SSL_GETPID(), ss->fd, sendLen)); 1.3556 + 1.3557 + msg = ss->sec.ci.sendBuf.buf; 1.3558 + msg[0] = SSL_MT_SERVER_HELLO; 1.3559 + msg[1] = hit; 1.3560 + msg[2] = SSL_CT_X509_CERTIFICATE; 1.3561 + msg[3] = MSB(ss->version); 1.3562 + msg[4] = LSB(ss->version); 1.3563 + msg[5] = MSB(certLen); 1.3564 + msg[6] = LSB(certLen); 1.3565 + msg[7] = MSB(csLen); 1.3566 + msg[8] = LSB(csLen); 1.3567 + msg[9] = MSB(SSL_CONNECTIONID_BYTES); 1.3568 + msg[10] = LSB(SSL_CONNECTIONID_BYTES); 1.3569 + if (certLen) { 1.3570 + PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES, cert, certLen); 1.3571 + } 1.3572 + if (csLen) { 1.3573 + PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen, cs, csLen); 1.3574 + } 1.3575 + PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen+csLen, 1.3576 + ss->sec.ci.connectionID, SSL_CONNECTIONID_BYTES); 1.3577 + 1.3578 + DUMP_MSG(29, (ss, msg, sendLen)); 1.3579 + 1.3580 + ss->handshakeBegun = 1; 1.3581 + sent = (*ss->sec.send)(ss, msg, sendLen, 0); 1.3582 + if (sent < 0) { 1.3583 + goto loser; 1.3584 + } 1.3585 + ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0; 1.3586 + 1.3587 + ss->gs.recordLen = 0; 1.3588 + ss->handshake = ssl_GatherRecord1stHandshake; 1.3589 + if (hit) { 1.3590 + /* Old SID Session key is good. Go encrypted */ 1.3591 + ssl2_UseEncryptedSendFunc(ss); 1.3592 + 1.3593 + /* Send server verify message now that keys are established */ 1.3594 + rv = ssl2_SendServerVerifyMessage(ss); 1.3595 + if (rv != SECSuccess) 1.3596 + goto loser; 1.3597 + 1.3598 + ss->nextHandshake = ssl2_HandleMessage; 1.3599 + ssl_ReleaseRecvBufLock(ss); 1.3600 + rv = ssl2_TriggerNextMessage(ss); 1.3601 + return rv; 1.3602 + } 1.3603 + ss->nextHandshake = ssl2_HandleClientSessionKeyMessage; 1.3604 + ssl_ReleaseRecvBufLock(ss); 1.3605 + return SECSuccess; 1.3606 + 1.3607 + bad_client: 1.3608 + PORT_SetError(SSL_ERROR_BAD_CLIENT); 1.3609 + /* FALLTHROUGH */ 1.3610 + 1.3611 + loser: 1.3612 + if (gotXmitBufLock) { 1.3613 + ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0; 1.3614 + } 1.3615 + SSL_TRC(10, ("%d: SSL[%d]: server, wait for client-hello lossage", 1.3616 + SSL_GETPID(), ss->fd)); 1.3617 + ssl_ReleaseRecvBufLock(ss); 1.3618 + return SECFailure; 1.3619 +} 1.3620 + 1.3621 +SECStatus 1.3622 +ssl2_BeginServerHandshake(sslSocket *ss) 1.3623 +{ 1.3624 + SECStatus rv; 1.3625 + sslServerCerts * rsaAuth = ss->serverCerts + kt_rsa; 1.3626 + 1.3627 + ss->sec.isServer = 1; 1.3628 + ssl_ChooseSessionIDProcs(&ss->sec); 1.3629 + ss->sec.sendSequence = 0; 1.3630 + ss->sec.rcvSequence = 0; 1.3631 + 1.3632 + /* don't turn on SSL2 if we don't have an RSA key and cert */ 1.3633 + if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY || 1.3634 + !rsaAuth->serverCert) { 1.3635 + ss->opt.enableSSL2 = PR_FALSE; 1.3636 + } 1.3637 + 1.3638 + if (!ss->cipherSpecs) { 1.3639 + rv = ssl2_ConstructCipherSpecs(ss); 1.3640 + if (rv != SECSuccess) 1.3641 + goto loser; 1.3642 + } 1.3643 + 1.3644 + /* count the SSL2 and SSL3 enabled ciphers. 1.3645 + * if either is zero, clear the socket's enable for that protocol. 1.3646 + */ 1.3647 + rv = ssl2_CheckConfigSanity(ss); 1.3648 + if (rv != SECSuccess) 1.3649 + goto loser; 1.3650 + 1.3651 + /* 1.3652 + ** Generate connection-id. Always do this, even if things fail 1.3653 + ** immediately. This way the random number generator is always 1.3654 + ** rolling around, every time we get a connection. 1.3655 + */ 1.3656 + PK11_GenerateRandom(ss->sec.ci.connectionID, 1.3657 + sizeof(ss->sec.ci.connectionID)); 1.3658 + 1.3659 + ss->gs.recordLen = 0; 1.3660 + ss->handshake = ssl_GatherRecord1stHandshake; 1.3661 + ss->nextHandshake = ssl2_HandleClientHelloMessage; 1.3662 + return SECSuccess; 1.3663 + 1.3664 +loser: 1.3665 + return SECFailure; 1.3666 +} 1.3667 + 1.3668 +/* This function doesn't really belong in this file. 1.3669 +** It's here to keep AIX compilers from optimizing it away, 1.3670 +** and not including it in the DSO. 1.3671 +*/ 1.3672 + 1.3673 +#include "nss.h" 1.3674 +extern const char __nss_ssl_rcsid[]; 1.3675 +extern const char __nss_ssl_sccsid[]; 1.3676 + 1.3677 +PRBool 1.3678 +NSSSSL_VersionCheck(const char *importedVersion) 1.3679 +{ 1.3680 + /* 1.3681 + * This is the secret handshake algorithm. 1.3682 + * 1.3683 + * This release has a simple version compatibility 1.3684 + * check algorithm. This release is not backward 1.3685 + * compatible with previous major releases. It is 1.3686 + * not compatible with future major, minor, or 1.3687 + * patch releases. 1.3688 + */ 1.3689 + volatile char c; /* force a reference that won't get optimized away */ 1.3690 + 1.3691 + c = __nss_ssl_rcsid[0] + __nss_ssl_sccsid[0]; 1.3692 + return NSS_VersionCheck(importedVersion); 1.3693 +} 1.3694 + 1.3695 +const char * 1.3696 +NSSSSL_GetVersion(void) 1.3697 +{ 1.3698 + return NSS_VERSION; 1.3699 +}