| OLD | NEW |
| 1 /* | 1 /* |
| 2 * SSL3 Protocol | 2 * SSL3 Protocol |
| 3 * | 3 * |
| 4 * ***** BEGIN LICENSE BLOCK ***** | 4 * ***** BEGIN LICENSE BLOCK ***** |
| 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| 6 * | 6 * |
| 7 * The contents of this file are subject to the Mozilla Public License Version | 7 * The contents of this file are subject to the Mozilla Public License Version |
| 8 * 1.1 (the "License"); you may not use this file except in compliance with | 8 * 1.1 (the "License"); you may not use this file except in compliance with |
| 9 * the License. You may obtain a copy of the License at | 9 * the License. You may obtain a copy of the License at |
| 10 * http://www.mozilla.org/MPL/ | 10 * http://www.mozilla.org/MPL/ |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 * in which case the provisions of the GPL or the LGPL are applicable instead | 32 * in which case the provisions of the GPL or the LGPL are applicable instead |
| 33 * of those above. If you wish to allow use of your version of this file only | 33 * of those above. If you wish to allow use of your version of this file only |
| 34 * under the terms of either the GPL or the LGPL, and not to allow others to | 34 * under the terms of either the GPL or the LGPL, and not to allow others to |
| 35 * use your version of this file under the terms of the MPL, indicate your | 35 * use your version of this file under the terms of the MPL, indicate your |
| 36 * decision by deleting the provisions above and replace them with the notice | 36 * decision by deleting the provisions above and replace them with the notice |
| 37 * and other provisions required by the GPL or the LGPL. If you do not delete | 37 * and other provisions required by the GPL or the LGPL. If you do not delete |
| 38 * the provisions above, a recipient may use your version of this file under | 38 * the provisions above, a recipient may use your version of this file under |
| 39 * the terms of any one of the MPL, the GPL or the LGPL. | 39 * the terms of any one of the MPL, the GPL or the LGPL. |
| 40 * | 40 * |
| 41 * ***** END LICENSE BLOCK ***** */ | 41 * ***** END LICENSE BLOCK ***** */ |
| 42 /* $Id: ssl3con.c,v 1.142.2.4 2010/09/01 19:47:11 wtc%google.com Exp $ */ | 42 /* $Id: ssl3con.c,v 1.164 2012/02/17 09:50:04 kaie%kuix.de Exp $ */ |
| 43 | 43 |
| 44 #include "cert.h" | 44 #include "cert.h" |
| 45 #include "ssl.h" | 45 #include "ssl.h" |
| 46 #include "cryptohi.h" /* for DSAU_ stuff */ | 46 #include "cryptohi.h" /* for DSAU_ stuff */ |
| 47 #include "keyhi.h" | 47 #include "keyhi.h" |
| 48 #include "secder.h" | 48 #include "secder.h" |
| 49 #include "secitem.h" | 49 #include "secitem.h" |
| 50 | 50 |
| 51 #include "sslimpl.h" | 51 #include "sslimpl.h" |
| 52 #include "sslproto.h" | 52 #include "sslproto.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 81 static SECStatus ssl3_InitState( sslSocket *ss); | 81 static SECStatus ssl3_InitState( sslSocket *ss); |
| 82 static SECStatus ssl3_SendCertificate( sslSocket *ss); | 82 static SECStatus ssl3_SendCertificate( sslSocket *ss); |
| 83 static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); | 83 static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); |
| 84 static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); | 84 static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); |
| 85 static SECStatus ssl3_SendNextProto( sslSocket *ss); | 85 static SECStatus ssl3_SendNextProto( sslSocket *ss); |
| 86 static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags); | 86 static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags); |
| 87 static SECStatus ssl3_SendServerHello( sslSocket *ss); | 87 static SECStatus ssl3_SendServerHello( sslSocket *ss); |
| 88 static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); | 88 static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); |
| 89 static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss); | 89 static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss); |
| 90 static SECStatus ssl3_NewHandshakeHashes( sslSocket *ss); | 90 static SECStatus ssl3_NewHandshakeHashes( sslSocket *ss); |
| 91 static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss, unsigned char *b, | 91 static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss, |
| 92 const unsigned char *b, |
| 92 unsigned int l); | 93 unsigned int l); |
| 93 | 94 |
| 94 static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, | 95 static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, |
| 95 int maxOutputLen, const unsigned char *input, | 96 int maxOutputLen, const unsigned char *input, |
| 96 int inputLen); | 97 int inputLen); |
| 97 | 98 |
| 98 #define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */ | 99 #define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */ |
| 99 #define MIN_SEND_BUF_LENGTH 4000 | 100 #define MIN_SEND_BUF_LENGTH 4000 |
| 100 | 101 |
| 101 #define MAX_CIPHER_SUITES 20 | 102 #define MAX_CIPHER_SUITES 20 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 | 232 |
| 232 /* | 233 /* |
| 233 * make sure there is room in the write buffer for padding and | 234 * make sure there is room in the write buffer for padding and |
| 234 * other compression and cryptographic expansions. | 235 * other compression and cryptographic expansions. |
| 235 */ | 236 */ |
| 236 #define SSL3_BUFFER_FUDGE 100 + SSL3_COMPRESSION_MAX_EXPANSION | 237 #define SSL3_BUFFER_FUDGE 100 + SSL3_COMPRESSION_MAX_EXPANSION |
| 237 | 238 |
| 238 #define EXPORT_RSA_KEY_LENGTH 64 /* bytes */ | 239 #define EXPORT_RSA_KEY_LENGTH 64 /* bytes */ |
| 239 | 240 |
| 240 | 241 |
| 241 /* This is a hack to make sure we don't do double handshakes for US policy */ | |
| 242 PRBool ssl3_global_policy_some_restricted = PR_FALSE; | |
| 243 | |
| 244 /* This global item is used only in servers. It is is initialized by | 242 /* This global item is used only in servers. It is is initialized by |
| 245 ** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest(). | 243 ** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest(). |
| 246 */ | 244 */ |
| 247 CERTDistNames *ssl3_server_ca_list = NULL; | 245 CERTDistNames *ssl3_server_ca_list = NULL; |
| 248 static SSL3Statistics ssl3stats; | 246 static SSL3Statistics ssl3stats; |
| 249 | 247 |
| 250 /* indexed by SSL3BulkCipher */ | 248 /* indexed by SSL3BulkCipher */ |
| 251 static const ssl3BulkCipherDef bulk_cipher_defs[] = { | 249 static const ssl3BulkCipherDef bulk_cipher_defs[] = { |
| 252 /* cipher calg keySz secretSz type ivSz BlkSz keygen */ | 250 /* cipher calg keySz secretSz type ivSz BlkSz keygen */ |
| 253 {cipher_null, calg_null, 0, 0, type_stream, 0, 0, kg_null}, | 251 {cipher_null, calg_null, 0, 0, type_stream, 0, 0, kg_null}, |
| (...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 923 #ifdef NSS_ENABLE_ECC | 921 #ifdef NSS_ENABLE_ECC |
| 924 unsigned int len; | 922 unsigned int len; |
| 925 #endif /* NSS_ENABLE_ECC */ | 923 #endif /* NSS_ENABLE_ECC */ |
| 926 | 924 |
| 927 | 925 |
| 928 PRINT_BUF(60, (NULL, "check signed hashes", | 926 PRINT_BUF(60, (NULL, "check signed hashes", |
| 929 buf->data, buf->len)); | 927 buf->data, buf->len)); |
| 930 | 928 |
| 931 key = CERT_ExtractPublicKey(cert); | 929 key = CERT_ExtractPublicKey(cert); |
| 932 if (key == NULL) { | 930 if (key == NULL) { |
| 933 » /* CERT_ExtractPublicKey doesn't set error code */ | 931 » ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); |
| 934 » PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); | |
| 935 return SECFailure; | 932 return SECFailure; |
| 936 } | 933 } |
| 937 | 934 |
| 938 switch (key->keyType) { | 935 switch (key->keyType) { |
| 939 case rsaKey: | 936 case rsaKey: |
| 940 hashItem.data = hash->md5; | 937 hashItem.data = hash->md5; |
| 941 hashItem.len = sizeof(SSL3Hashes); | 938 hashItem.len = sizeof(SSL3Hashes); |
| 942 break; | 939 break; |
| 943 case dsaKey: | 940 case dsaKey: |
| 944 hashItem.data = hash->sha; | 941 hashItem.data = hash->sha; |
| (...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2035 sid->u.ssl3.clAuthModuleID != PK11_GetModuleID(slot) || | 2032 sid->u.ssl3.clAuthModuleID != PK11_GetModuleID(slot) || |
| 2036 (PK11_NeedLogin(slot) && !PK11_IsLoggedIn(slot, NULL))) { | 2033 (PK11_NeedLogin(slot) && !PK11_IsLoggedIn(slot, NULL))) { |
| 2037 isPresent = PR_FALSE; | 2034 isPresent = PR_FALSE; |
| 2038 } | 2035 } |
| 2039 if (slot) { | 2036 if (slot) { |
| 2040 PK11_FreeSlot(slot); | 2037 PK11_FreeSlot(slot); |
| 2041 } | 2038 } |
| 2042 return isPresent; | 2039 return isPresent; |
| 2043 } | 2040 } |
| 2044 | 2041 |
| 2045 /* Caller must hold the spec read lock. wrBuf is sometimes, but not always, | 2042 /* Caller must hold the spec read lock. */ |
| 2046 * ss->sec.writeBuf. | |
| 2047 */ | |
| 2048 static SECStatus | 2043 static SECStatus |
| 2049 ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec, | 2044 ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec, |
| 2050 PRBool isServer, | 2045 PRBool isServer, |
| 2051 SSL3ContentType type, | 2046 SSL3ContentType type, |
| 2052 const SSL3Opaque * pIn, | 2047 const SSL3Opaque * pIn, |
| 2053 PRUint32 contentLen, | 2048 PRUint32 contentLen, |
| 2054 sslBuffer * wrBuf) | 2049 sslBuffer * wrBuf) |
| 2055 { | 2050 { |
| 2056 const ssl3BulkCipherDef * cipher_def; | 2051 const ssl3BulkCipherDef * cipher_def; |
| 2057 SECStatus rv; | 2052 SECStatus rv; |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2222 return SECFailure; | 2217 return SECFailure; |
| 2223 } | 2218 } |
| 2224 | 2219 |
| 2225 while (nIn > 0) { | 2220 while (nIn > 0) { |
| 2226 PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); | 2221 PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); |
| 2227 unsigned int spaceNeeded; | 2222 unsigned int spaceNeeded; |
| 2228 unsigned int numRecords; | 2223 unsigned int numRecords; |
| 2229 | 2224 |
| 2230 ssl_GetSpecReadLock(ss); /********************************/ | 2225 ssl_GetSpecReadLock(ss); /********************************/ |
| 2231 | 2226 |
| 2232 » if (nIn > 1 && | 2227 » if (nIn > 1 && ss->opt.cbcRandomIV && |
| 2233 » ss->opt.enableFalseStart && | |
| 2234 ss->ssl3.cwSpec->version <= SSL_LIBRARY_VERSION_3_1_TLS && | 2228 ss->ssl3.cwSpec->version <= SSL_LIBRARY_VERSION_3_1_TLS && |
| 2235 type == content_application_data && | 2229 type == content_application_data && |
| 2236 ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) { | 2230 ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) { |
| 2237 /* We will split the first byte of the record into its own record, | 2231 /* We will split the first byte of the record into its own record, |
| 2238 * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h | 2232 * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h |
| 2239 */ | 2233 */ |
| 2240 numRecords = 2; | 2234 numRecords = 2; |
| 2241 } else { | 2235 } else { |
| 2242 numRecords = 1; | 2236 numRecords = 1; |
| 2243 } | 2237 } |
| 2244 | 2238 |
| 2245 spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE); | 2239 spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE); |
| 2246 if (spaceNeeded > wrBuf->space) { | 2240 if (spaceNeeded > wrBuf->space) { |
| 2247 rv = sslBuffer_Grow(wrBuf, spaceNeeded); | 2241 rv = sslBuffer_Grow(wrBuf, spaceNeeded); |
| 2248 if (rv != SECSuccess) { | 2242 if (rv != SECSuccess) { |
| 2249 SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", | 2243 SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", |
| 2250 SSL_GETPID(), ss->fd, spaceNeeded)); | 2244 SSL_GETPID(), ss->fd, spaceNeeded)); |
| 2251 » » goto spec_locked_loser; /* sslBuffer_Grow set a memory error cod
e. */ | 2245 » » goto spec_locked_loser; /* sslBuffer_Grow set error code. */ |
| 2252 } | 2246 } |
| 2253 } | 2247 } |
| 2254 | 2248 |
| 2255 if (numRecords == 2) { | 2249 if (numRecords == 2) { |
| 2256 sslBuffer secondRecord; | 2250 sslBuffer secondRecord; |
| 2257 | 2251 |
| 2258 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, | 2252 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, |
| 2259 ss->sec.isServer, type, pIn, 1, | 2253 ss->sec.isServer, type, pIn, 1, |
| 2260 wrBuf); | 2254 wrBuf); |
| 2261 if (rv != SECSuccess) | 2255 if (rv != SECSuccess) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2274 if (rv == SECSuccess) { | 2268 if (rv == SECSuccess) { |
| 2275 PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:", | 2269 PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:", |
| 2276 secondRecord.buf, secondRecord.len)); | 2270 secondRecord.buf, secondRecord.len)); |
| 2277 wrBuf->len += secondRecord.len; | 2271 wrBuf->len += secondRecord.len; |
| 2278 } | 2272 } |
| 2279 } else { | 2273 } else { |
| 2280 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, | 2274 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, |
| 2281 ss->sec.isServer, type, pIn, | 2275 ss->sec.isServer, type, pIn, |
| 2282 contentLen, wrBuf); | 2276 contentLen, wrBuf); |
| 2283 if (rv == SECSuccess) { | 2277 if (rv == SECSuccess) { |
| 2284 » PRINT_BUF(50, (ss, "send (encrypted) record data [1/1]:", | 2278 » PRINT_BUF(50, (ss, "send (encrypted) record data:", |
| 2285 wrBuf->buf, wrBuf->len)); | 2279 wrBuf->buf, wrBuf->len)); |
| 2286 } | 2280 } |
| 2287 } | 2281 } |
| 2288 | 2282 |
| 2289 spec_locked_loser: | 2283 spec_locked_loser: |
| 2290 ssl_ReleaseSpecReadLock(ss); /************************************/ | 2284 ssl_ReleaseSpecReadLock(ss); /************************************/ |
| 2291 | 2285 |
| 2292 if (rv != SECSuccess) | 2286 if (rv != SECSuccess) |
| 2293 return SECFailure; | 2287 return SECFailure; |
| 2294 | 2288 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2610 */ | 2604 */ |
| 2611 static SECStatus | 2605 static SECStatus |
| 2612 ssl3_HandshakeFailure(sslSocket *ss) | 2606 ssl3_HandshakeFailure(sslSocket *ss) |
| 2613 { | 2607 { |
| 2614 (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); | 2608 (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); |
| 2615 PORT_SetError( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT | 2609 PORT_SetError( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT |
| 2616 : SSL_ERROR_BAD_SERVER ); | 2610 : SSL_ERROR_BAD_SERVER ); |
| 2617 return SECFailure; | 2611 return SECFailure; |
| 2618 } | 2612 } |
| 2619 | 2613 |
| 2614 static void |
| 2615 ssl3_SendAlertForCertError(sslSocket * ss, PRErrorCode errCode) |
| 2616 { |
| 2617 SSL3AlertDescription desc = bad_certificate; |
| 2618 PRBool isTLS = ss->version >= SSL_LIBRARY_VERSION_3_1_TLS; |
| 2619 |
| 2620 switch (errCode) { |
| 2621 case SEC_ERROR_LIBRARY_FAILURE: desc = unsupported_certificate; break; |
| 2622 case SEC_ERROR_EXPIRED_CERTIFICATE: desc = certificate_expired; break; |
| 2623 case SEC_ERROR_REVOKED_CERTIFICATE: desc = certificate_revoked; break; |
| 2624 case SEC_ERROR_INADEQUATE_KEY_USAGE: |
| 2625 case SEC_ERROR_INADEQUATE_CERT_TYPE: |
| 2626 desc = certificate_unknown; break; |
| 2627 case SEC_ERROR_UNTRUSTED_CERT: |
| 2628 desc = isTLS ? access_denied : certificate_unknown; break; |
| 2629 case SEC_ERROR_UNKNOWN_ISSUER: |
| 2630 case SEC_ERROR_UNTRUSTED_ISSUER: |
| 2631 desc = isTLS ? unknown_ca : certificate_unknown; break; |
| 2632 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: |
| 2633 desc = isTLS ? unknown_ca : certificate_expired; break; |
| 2634 |
| 2635 case SEC_ERROR_CERT_NOT_IN_NAME_SPACE: |
| 2636 case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID: |
| 2637 case SEC_ERROR_CA_CERT_INVALID: |
| 2638 case SEC_ERROR_BAD_SIGNATURE: |
| 2639 default: desc = bad_certificate; break; |
| 2640 } |
| 2641 SSL_DBG(("%d: SSL3[%d]: peer certificate is no good: error=%d", |
| 2642 SSL_GETPID(), ss->fd, errCode)); |
| 2643 |
| 2644 (void) SSL3_SendAlert(ss, alert_fatal, desc); |
| 2645 } |
| 2646 |
| 2647 |
| 2620 /* | 2648 /* |
| 2621 * Send handshake_Failure alert. Set generic error number. | 2649 * Send handshake_Failure alert. Set generic error number. |
| 2622 */ | 2650 */ |
| 2623 static SECStatus | 2651 static SECStatus |
| 2624 ssl3_DecodeError(sslSocket *ss) | 2652 ssl3_DecodeError(sslSocket *ss) |
| 2625 { | 2653 { |
| 2626 (void)SSL3_SendAlert(ss, alert_fatal, | 2654 (void)SSL3_SendAlert(ss, alert_fatal, |
| 2627 ss->version > SSL_LIBRARY_VERSION_3_0 ? decode_error | 2655 ss->version > SSL_LIBRARY_VERSION_3_0 ? decode_error |
| 2628 : illegal_parameter); | 2656 : illegal_parameter); |
| 2629 PORT_SetError( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT | 2657 PORT_SetError( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3226 /* | 3254 /* |
| 3227 * Handshake messages | 3255 * Handshake messages |
| 3228 */ | 3256 */ |
| 3229 /* Called from ssl3_AppendHandshake() | 3257 /* Called from ssl3_AppendHandshake() |
| 3230 ** ssl3_StartHandshakeHash() | 3258 ** ssl3_StartHandshakeHash() |
| 3231 ** ssl3_HandleV2ClientHello() | 3259 ** ssl3_HandleV2ClientHello() |
| 3232 ** ssl3_HandleHandshakeMessage() | 3260 ** ssl3_HandleHandshakeMessage() |
| 3233 ** Caller must hold the ssl3Handshake lock. | 3261 ** Caller must hold the ssl3Handshake lock. |
| 3234 */ | 3262 */ |
| 3235 static SECStatus | 3263 static SECStatus |
| 3236 ssl3_UpdateHandshakeHashes(sslSocket *ss, unsigned char *b, unsigned int l) | 3264 ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b, |
| 3265 » » » unsigned int l) |
| 3237 { | 3266 { |
| 3238 SECStatus rv = SECSuccess; | 3267 SECStatus rv = SECSuccess; |
| 3239 | 3268 |
| 3240 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | 3269 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 3241 | 3270 |
| 3242 PRINT_BUF(90, (NULL, "MD5 & SHA handshake hash input:", b, l)); | 3271 PRINT_BUF(90, (NULL, "MD5 & SHA handshake hash input:", b, l)); |
| 3243 | 3272 |
| 3244 if (ss->opt.bypassPKCS11) { | 3273 if (ss->opt.bypassPKCS11) { |
| 3245 MD5_Update((MD5Context *)ss->ssl3.hs.md5_cx, b, l); | 3274 MD5_Update((MD5Context *)ss->ssl3.hs.md5_cx, b, l); |
| 3246 SHA1_Update((SHA1Context *)ss->ssl3.hs.sha_cx, b, l); | 3275 SHA1_Update((SHA1Context *)ss->ssl3.hs.sha_cx, b, l); |
| (...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3766 ssl_ReleaseSSL3HandshakeLock(ss); /**************************************/ | 3795 ssl_ReleaseSSL3HandshakeLock(ss); /**************************************/ |
| 3767 return rv; | 3796 return rv; |
| 3768 } | 3797 } |
| 3769 | 3798 |
| 3770 /************************************************************************** | 3799 /************************************************************************** |
| 3771 * end of Handshake Hash functions. | 3800 * end of Handshake Hash functions. |
| 3772 * Begin Send and Handle functions for handshakes. | 3801 * Begin Send and Handle functions for handshakes. |
| 3773 **************************************************************************/ | 3802 **************************************************************************/ |
| 3774 | 3803 |
| 3775 /* Called from ssl3_HandleHelloRequest(), | 3804 /* Called from ssl3_HandleHelloRequest(), |
| 3776 * ssl3_HandleFinished() (for step-up) | |
| 3777 * ssl3_RedoHandshake() | 3805 * ssl3_RedoHandshake() |
| 3778 * ssl2_BeginClientHandshake (when resuming ssl3 session) | 3806 * ssl2_BeginClientHandshake (when resuming ssl3 session) |
| 3779 */ | 3807 */ |
| 3780 SECStatus | 3808 SECStatus |
| 3781 ssl3_SendClientHello(sslSocket *ss) | 3809 ssl3_SendClientHello(sslSocket *ss) |
| 3782 { | 3810 { |
| 3783 sslSessionID * sid; | 3811 sslSessionID * sid; |
| 3784 ssl3CipherSpec * cwSpec; | 3812 ssl3CipherSpec * cwSpec; |
| 3785 SECStatus rv; | 3813 SECStatus rv; |
| 3786 int i; | 3814 int i; |
| (...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4339 SECKEYPrivateKey * svrPrivKey; | 4367 SECKEYPrivateKey * svrPrivKey; |
| 4340 SECKEYPublicKey * svrPubKey = NULL; | 4368 SECKEYPublicKey * svrPubKey = NULL; |
| 4341 PK11SymKey * unwrappedWrappingKey = NULL; | 4369 PK11SymKey * unwrappedWrappingKey = NULL; |
| 4342 PK11SymKey ** pSymWrapKey; | 4370 PK11SymKey ** pSymWrapKey; |
| 4343 CK_MECHANISM_TYPE asymWrapMechanism = CKM_INVALID_MECHANISM; | 4371 CK_MECHANISM_TYPE asymWrapMechanism = CKM_INVALID_MECHANISM; |
| 4344 int length; | 4372 int length; |
| 4345 int symWrapMechIndex; | 4373 int symWrapMechIndex; |
| 4346 SECStatus rv; | 4374 SECStatus rv; |
| 4347 SECItem wrappedKey; | 4375 SECItem wrappedKey; |
| 4348 SSLWrappedSymWrappingKey wswk; | 4376 SSLWrappedSymWrappingKey wswk; |
| 4377 #ifdef NSS_ENABLE_ECC |
| 4378 PK11SymKey * Ks = NULL; |
| 4379 SECKEYPublicKey *pubWrapKey = NULL; |
| 4380 SECKEYPrivateKey *privWrapKey = NULL; |
| 4381 ECCWrappedKeyInfo *ecWrapped; |
| 4382 #endif /* NSS_ENABLE_ECC */ |
| 4349 | 4383 |
| 4350 svrPrivKey = ss->serverCerts[exchKeyType].SERVERKEY; | 4384 svrPrivKey = ss->serverCerts[exchKeyType].SERVERKEY; |
| 4351 PORT_Assert(svrPrivKey != NULL); | 4385 PORT_Assert(svrPrivKey != NULL); |
| 4352 if (!svrPrivKey) { | 4386 if (!svrPrivKey) { |
| 4353 return NULL; /* why are we here?!? */ | 4387 return NULL; /* why are we here?!? */ |
| 4354 } | 4388 } |
| 4355 | 4389 |
| 4356 symWrapMechIndex = ssl_FindIndexByWrapMechanism(masterWrapMech); | 4390 symWrapMechIndex = ssl_FindIndexByWrapMechanism(masterWrapMech); |
| 4357 PORT_Assert(symWrapMechIndex >= 0); | 4391 PORT_Assert(symWrapMechIndex >= 0); |
| 4358 if (symWrapMechIndex < 0) | 4392 if (symWrapMechIndex < 0) |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4415 wrappedKey.type = siBuffer; | 4449 wrappedKey.type = siBuffer; |
| 4416 wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey); | 4450 wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey); |
| 4417 wrappedKey.data = wswk.wrappedSymmetricWrappingkey; | 4451 wrappedKey.data = wswk.wrappedSymmetricWrappingkey; |
| 4418 | 4452 |
| 4419 PORT_Assert(wrappedKey.len <= sizeof wswk.wrappedSymmetricWrappingkey); | 4453 PORT_Assert(wrappedKey.len <= sizeof wswk.wrappedSymmetricWrappingkey); |
| 4420 if (wrappedKey.len > sizeof wswk.wrappedSymmetricWrappingkey) | 4454 if (wrappedKey.len > sizeof wswk.wrappedSymmetricWrappingkey) |
| 4421 goto loser; | 4455 goto loser; |
| 4422 | 4456 |
| 4423 /* wrap symmetric wrapping key in server's public key. */ | 4457 /* wrap symmetric wrapping key in server's public key. */ |
| 4424 switch (exchKeyType) { | 4458 switch (exchKeyType) { |
| 4425 #ifdef NSS_ENABLE_ECC | |
| 4426 PK11SymKey * Ks = NULL; | |
| 4427 SECKEYPublicKey *pubWrapKey = NULL; | |
| 4428 SECKEYPrivateKey *privWrapKey = NULL; | |
| 4429 ECCWrappedKeyInfo *ecWrapped; | |
| 4430 #endif /* NSS_ENABLE_ECC */ | |
| 4431 | |
| 4432 case kt_rsa: | 4459 case kt_rsa: |
| 4433 asymWrapMechanism = CKM_RSA_PKCS; | 4460 asymWrapMechanism = CKM_RSA_PKCS; |
| 4434 rv = PK11_PubWrapSymKey(asymWrapMechanism, svrPubKey, | 4461 rv = PK11_PubWrapSymKey(asymWrapMechanism, svrPubKey, |
| 4435 unwrappedWrappingKey, &wrappedKey); | 4462 unwrappedWrappingKey, &wrappedKey); |
| 4436 break; | 4463 break; |
| 4437 | 4464 |
| 4438 #ifdef NSS_ENABLE_ECC | 4465 #ifdef NSS_ENABLE_ECC |
| 4439 case kt_ecdh: | 4466 case kt_ecdh: |
| 4440 /* | 4467 /* |
| 4441 * We generate an ephemeral EC key pair. Perform an ECDH | 4468 * We generate an ephemeral EC key pair. Perform an ECDH |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4789 | 4816 |
| 4790 SSL_TRC(3, ("%d: SSL3[%d]: send client_key_exchange handshake", | 4817 SSL_TRC(3, ("%d: SSL3[%d]: send client_key_exchange handshake", |
| 4791 SSL_GETPID(), ss->fd)); | 4818 SSL_GETPID(), ss->fd)); |
| 4792 | 4819 |
| 4793 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | 4820 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
| 4794 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | 4821 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
| 4795 | 4822 |
| 4796 if (ss->sec.peerKey == NULL) { | 4823 if (ss->sec.peerKey == NULL) { |
| 4797 serverKey = CERT_ExtractPublicKey(ss->sec.peerCert); | 4824 serverKey = CERT_ExtractPublicKey(ss->sec.peerCert); |
| 4798 if (serverKey == NULL) { | 4825 if (serverKey == NULL) { |
| 4799 » PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); | 4826 » ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); |
| 4800 return SECFailure; | 4827 return SECFailure; |
| 4801 } | 4828 } |
| 4802 } else { | 4829 } else { |
| 4803 serverKey = ss->sec.peerKey; | 4830 serverKey = ss->sec.peerKey; |
| 4804 ss->sec.peerKey = NULL; /* we're done with it now */ | 4831 ss->sec.peerKey = NULL; /* we're done with it now */ |
| 4805 } | 4832 } |
| 4806 | 4833 |
| 4807 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); | 4834 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); |
| 4808 /* enforce limits on kea key sizes. */ | 4835 /* enforce limits on kea key sizes. */ |
| 4809 if (ss->ssl3.hs.kea_def->is_limited) { | 4836 if (ss->ssl3.hs.kea_def->is_limited) { |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5219 ss->ssl3.hs.ws = wait_change_cipher; | 5246 ss->ssl3.hs.ws = wait_change_cipher; |
| 5220 | 5247 |
| 5221 ss->ssl3.hs.isResuming = PR_TRUE; | 5248 ss->ssl3.hs.isResuming = PR_TRUE; |
| 5222 | 5249 |
| 5223 /* copy the peer cert from the SID */ | 5250 /* copy the peer cert from the SID */ |
| 5224 if (sid->peerCert != NULL) { | 5251 if (sid->peerCert != NULL) { |
| 5225 ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); | 5252 ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); |
| 5226 ssl3_CopyPeerCertsFromSID(ss, sid); | 5253 ssl3_CopyPeerCertsFromSID(ss, sid); |
| 5227 } | 5254 } |
| 5228 | 5255 |
| 5256 |
| 5229 /* NULL value for PMS signifies re-use of the old MS */ | 5257 /* NULL value for PMS signifies re-use of the old MS */ |
| 5230 rv = ssl3_InitPendingCipherSpec(ss, NULL); | 5258 rv = ssl3_InitPendingCipherSpec(ss, NULL); |
| 5231 if (rv != SECSuccess) { | 5259 if (rv != SECSuccess) { |
| 5232 goto alert_loser; /* err code was set */ | 5260 goto alert_loser; /* err code was set */ |
| 5233 } | 5261 } |
| 5234 return SECSuccess; | 5262 return SECSuccess; |
| 5235 } while (0); | 5263 } while (0); |
| 5236 | 5264 |
| 5237 if (sid_match) | 5265 if (sid_match) |
| 5238 SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_not_ok ); | 5266 SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_not_ok ); |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5633 } else { | 5661 } else { |
| 5634 /* XXX Should pass cert_types in this call!! */ | 5662 /* XXX Should pass cert_types in this call!! */ |
| 5635 rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg, | 5663 rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg, |
| 5636 ss->fd, &ca_list, | 5664 ss->fd, &ca_list, |
| 5637 &ss->ssl3.clientCertificate, | 5665 &ss->ssl3.clientCertificate, |
| 5638 &ss->ssl3.clientPrivateKey); | 5666 &ss->ssl3.clientPrivateKey); |
| 5639 } | 5667 } |
| 5640 #endif /* NSS_PLATFORM_CLIENT_AUTH */ | 5668 #endif /* NSS_PLATFORM_CLIENT_AUTH */ |
| 5641 switch (rv) { | 5669 switch (rv) { |
| 5642 case SECWouldBlock: /* getClientAuthData has put up a dialog box. */ | 5670 case SECWouldBlock: /* getClientAuthData has put up a dialog box. */ |
| 5643 » ssl_SetAlwaysBlock(ss); | 5671 » ssl3_SetAlwaysBlock(ss); |
| 5644 break; /* not an error */ | 5672 break; /* not an error */ |
| 5645 | 5673 |
| 5646 case SECSuccess: | 5674 case SECSuccess: |
| 5647 #ifdef NSS_PLATFORM_CLIENT_AUTH | 5675 #ifdef NSS_PLATFORM_CLIENT_AUTH |
| 5648 if (!platform_cert_list || CERT_LIST_EMPTY(platform_cert_list) || | 5676 if (!platform_cert_list || CERT_LIST_EMPTY(platform_cert_list) || |
| 5649 !ss->ssl3.platformClientKey) { | 5677 !ss->ssl3.platformClientKey) { |
| 5650 if (platform_cert_list) { | 5678 if (platform_cert_list) { |
| 5651 CERT_DestroyCertList(platform_cert_list); | 5679 CERT_DestroyCertList(platform_cert_list); |
| 5652 platform_cert_list = NULL; | 5680 platform_cert_list = NULL; |
| 5653 } | 5681 } |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5779 * It does not work on a subsequent handshake (redo). | 5807 * It does not work on a subsequent handshake (redo). |
| 5780 * | 5808 * |
| 5781 * Caller holds 1stHandshakeLock. | 5809 * Caller holds 1stHandshakeLock. |
| 5782 */ | 5810 */ |
| 5783 SECStatus | 5811 SECStatus |
| 5784 ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, | 5812 ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, |
| 5785 CERTCertificate * cert, | 5813 CERTCertificate * cert, |
| 5786 SECKEYPrivateKey * key, | 5814 SECKEYPrivateKey * key, |
| 5787 CERTCertificateList *certChain) | 5815 CERTCertificateList *certChain) |
| 5788 { | 5816 { |
| 5789 SECStatus rv = SECFailure; | 5817 SECStatus rv = SECSuccess; |
| 5790 | 5818 |
| 5791 /* XXX This code only works on the initial handshake on a connection, | 5819 /* XXX This code only works on the initial handshake on a connection, |
| 5792 ** XXX It does not work on a subsequent handshake (redo). | 5820 ** XXX It does not work on a subsequent handshake (redo). |
| 5793 */ | 5821 */ |
| 5794 if (ss->handshake != 0) { | 5822 if (ss->handshake != 0) { |
| 5795 ss->handshake = ssl_GatherRecord1stHandshake; | 5823 ss->handshake = ssl_GatherRecord1stHandshake; |
| 5796 ss->ssl3.clientCertificate = cert; | 5824 ss->ssl3.clientCertificate = cert; |
| 5797 ss->ssl3.clientPrivateKey = key; | 5825 ss->ssl3.clientPrivateKey = key; |
| 5798 ss->ssl3.clientCertChain = certChain; | 5826 ss->ssl3.clientCertChain = certChain; |
| 5799 if (!cert || !key || !certChain) { | 5827 if (!cert || !key || !certChain) { |
| 5800 /* we are missing the key, cert, or cert chain */ | 5828 /* we are missing the key, cert, or cert chain */ |
| 5801 if (ss->ssl3.clientCertificate) { | 5829 if (ss->ssl3.clientCertificate) { |
| 5802 CERT_DestroyCertificate(ss->ssl3.clientCertificate); | 5830 CERT_DestroyCertificate(ss->ssl3.clientCertificate); |
| 5803 ss->ssl3.clientCertificate = NULL; | 5831 ss->ssl3.clientCertificate = NULL; |
| 5804 } | 5832 } |
| 5805 if (ss->ssl3.clientPrivateKey) { | 5833 if (ss->ssl3.clientPrivateKey) { |
| 5806 SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); | 5834 SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); |
| 5807 ss->ssl3.clientPrivateKey = NULL; | 5835 ss->ssl3.clientPrivateKey = NULL; |
| 5808 } | 5836 } |
| 5809 if (ss->ssl3.clientCertChain != NULL) { | 5837 if (ss->ssl3.clientCertChain != NULL) { |
| 5810 CERT_DestroyCertificateList(ss->ssl3.clientCertChain); | 5838 CERT_DestroyCertificateList(ss->ssl3.clientCertChain); |
| 5811 ss->ssl3.clientCertChain = NULL; | 5839 ss->ssl3.clientCertChain = NULL; |
| 5812 } | 5840 } |
| 5813 if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { | 5841 if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { |
| 5814 ss->ssl3.sendEmptyCert = PR_TRUE; | 5842 ss->ssl3.sendEmptyCert = PR_TRUE; |
| 5815 } else { | 5843 } else { |
| 5816 (void)SSL3_SendAlert(ss, alert_warning, no_certificate); | 5844 (void)SSL3_SendAlert(ss, alert_warning, no_certificate); |
| 5817 } | 5845 } |
| 5818 } | 5846 } |
| 5819 ssl_GetRecvBufLock(ss); | |
| 5820 if (ss->ssl3.hs.msgState.buf != NULL) { | |
| 5821 rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); | |
| 5822 } | |
| 5823 ssl_ReleaseRecvBufLock(ss); | |
| 5824 } else { | 5847 } else { |
| 5825 if (cert) { | 5848 if (cert) { |
| 5826 CERT_DestroyCertificate(cert); | 5849 CERT_DestroyCertificate(cert); |
| 5827 } | 5850 } |
| 5828 if (key) { | 5851 if (key) { |
| 5829 SECKEY_DestroyPrivateKey(key); | 5852 SECKEY_DestroyPrivateKey(key); |
| 5830 } | 5853 } |
| 5831 if (certChain) { | 5854 if (certChain) { |
| 5832 CERT_DestroyCertificateList(certChain); | 5855 CERT_DestroyCertificateList(certChain); |
| 5833 } | 5856 } |
| 5857 rv = SECFailure; |
| 5834 } | 5858 } |
| 5835 return rv; | 5859 return rv; |
| 5836 } | 5860 } |
| 5837 | 5861 |
| 5838 PRBool | 5862 PRBool |
| 5839 ssl3_CanFalseStart(sslSocket *ss) { | 5863 ssl3_CanFalseStart(sslSocket *ss) { |
| 5840 return ss->opt.enableFalseStart && | 5864 PRBool rv; |
| 5841 » !ss->sec.isServer && | 5865 |
| 5842 » !ss->ssl3.hs.isResuming && | 5866 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 5843 » ss->ssl3.cwSpec && | 5867 |
| 5844 » ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 && | 5868 /* XXX: does not take into account whether we are waiting for |
| 5845 » (ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_rsa || | 5869 * SSL_AuthCertificateComplete or SSL_RestartHandshakeAfterCertReq. If/when |
| 5846 » ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_dh || | 5870 * that is done, this function could return different results each time it |
| 5847 » ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_ecdh); | 5871 * would be called. |
| 5872 */ |
| 5873 |
| 5874 ssl_GetSpecReadLock(ss); |
| 5875 rv = ss->opt.enableFalseStart && |
| 5876 » !ss->sec.isServer && |
| 5877 » !ss->ssl3.hs.isResuming && |
| 5878 » ss->ssl3.cwSpec && |
| 5879 » ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 && |
| 5880 » (ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_rsa || |
| 5881 » ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_dh || |
| 5882 » ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_ecdh); |
| 5883 ssl_ReleaseSpecReadLock(ss); |
| 5884 return rv; |
| 5848 } | 5885 } |
| 5849 | 5886 |
| 5887 static SECStatus ssl3_SendClientSecondRound(sslSocket *ss); |
| 5888 |
| 5850 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete | 5889 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
| 5851 * ssl3 Server Hello Done message. | 5890 * ssl3 Server Hello Done message. |
| 5852 * Caller must hold Handshake and RecvBuf locks. | 5891 * Caller must hold Handshake and RecvBuf locks. |
| 5853 */ | 5892 */ |
| 5854 static SECStatus | 5893 static SECStatus |
| 5855 ssl3_HandleServerHelloDone(sslSocket *ss) | 5894 ssl3_HandleServerHelloDone(sslSocket *ss) |
| 5856 { | 5895 { |
| 5857 SECStatus rv; | 5896 SECStatus rv; |
| 5858 SSL3WaitState ws = ss->ssl3.hs.ws; | 5897 SSL3WaitState ws = ss->ssl3.hs.ws; |
| 5859 PRBool sendEmptyCert, sendCert; | |
| 5860 int n = 0, i; | |
| 5861 typedef SECStatus (*SendFunction)(sslSocket*); | |
| 5862 SendFunction send_funcs[5]; | |
| 5863 | 5898 |
| 5864 SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello_done handshake", | 5899 SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello_done handshake", |
| 5865 SSL_GETPID(), ss->fd)); | 5900 SSL_GETPID(), ss->fd)); |
| 5866 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 5901 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 5867 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | 5902 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 5868 | 5903 |
| 5869 if (ws != wait_hello_done && | 5904 if (ws != wait_hello_done && |
| 5870 ws != wait_server_cert && | 5905 ws != wait_server_cert && |
| 5871 ws != wait_server_key && | 5906 ws != wait_server_key && |
| 5872 ws != wait_cert_request) { | 5907 ws != wait_cert_request) { |
| 5873 SSL3_SendAlert(ss, alert_fatal, unexpected_message); | 5908 SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
| 5874 PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); | 5909 PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); |
| 5875 return SECFailure; | 5910 return SECFailure; |
| 5876 } | 5911 } |
| 5877 | 5912 |
| 5913 rv = ssl3_SendClientSecondRound(ss); |
| 5914 |
| 5915 return rv; |
| 5916 } |
| 5917 |
| 5918 /* Called from ssl3_HandleServerHelloDone and ssl3_AuthCertificateComplete. |
| 5919 * |
| 5920 * Caller must hold Handshake and RecvBuf locks. |
| 5921 */ |
| 5922 static SECStatus |
| 5923 ssl3_SendClientSecondRound(sslSocket *ss) |
| 5924 { |
| 5925 SECStatus rv; |
| 5926 PRBool sendClientCert; |
| 5927 PRBool sendEmptyCert; |
| 5928 int n = 0, i; |
| 5929 typedef SECStatus (*SendFunction)(sslSocket*); |
| 5930 SendFunction send_funcs[5]; |
| 5931 |
| 5932 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 5933 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 5934 |
| 5935 sendClientCert = !ss->ssl3.sendEmptyCert && |
| 5936 ss->ssl3.clientCertChain != NULL && |
| 5937 (ss->ssl3.platformClientKey || |
| 5938 ss->ssl3.clientPrivateKey != NULL); |
| 5939 |
| 5940 /* We must wait for the server's certificate to be authenticated before |
| 5941 * sending the client certificate in order to disclosing the client |
| 5942 * certificate to an attacker that does not have a valid cert for the |
| 5943 * domain we are connecting to. |
| 5944 * |
| 5945 * XXX: We should do the same for the NPN extension, but for that we |
| 5946 * need an option to give the application the ability to leak the NPN |
| 5947 * information to get better performance. |
| 5948 * |
| 5949 * During the initial handshake on a connection, we never send/receive |
| 5950 * application data until we have authenticated the server's certificate; |
| 5951 * i.e. we have fully authenticated the handshake before using the cipher |
| 5952 * specs agreed upon for that handshake. During a renegotiation, we may |
| 5953 * continue sending and receiving application data during the handshake |
| 5954 * interleaved with the handshake records. If we were to send the client's |
| 5955 * second round for a renegotiation before the server's certificate was |
| 5956 * authenticated, then the application data sent/received after this point |
| 5957 * would be using cipher spec that hadn't been authenticated. By waiting |
| 5958 * until the server's certificate has been authenticated during |
| 5959 * renegotiations, we ensure that renegotiations have the same property |
| 5960 * as initial handshakes; i.e. we have fully authenticated the handshake |
| 5961 * before using the cipher specs agreed upon for that handshake for |
| 5962 * application data. |
| 5963 */ |
| 5964 if (ss->ssl3.hs.restartTarget) { |
| 5965 PR_NOT_REACHED("unexpected ss->ssl3.hs.restartTarget"); |
| 5966 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
| 5967 return SECFailure; |
| 5968 } |
| 5969 if (ss->ssl3.hs.authCertificatePending && |
| 5970 (sendClientCert || ss->ssl3.sendEmptyCert || ss->firstHsDone)) { |
| 5971 ss->ssl3.hs.restartTarget = ssl3_SendClientSecondRound; |
| 5972 return SECWouldBlock; |
| 5973 } |
| 5974 |
| 5878 ssl_GetXmitBufLock(ss); /*******************************/ | 5975 ssl_GetXmitBufLock(ss); /*******************************/ |
| 5879 | 5976 |
| 5880 sendEmptyCert = ss->ssl3.sendEmptyCert; | 5977 sendEmptyCert = ss->ssl3.sendEmptyCert; |
| 5881 ss->ssl3.sendEmptyCert = PR_FALSE; | 5978 ss->ssl3.sendEmptyCert = PR_FALSE; |
| 5882 sendCert = !sendEmptyCert && | |
| 5883 ss->ssl3.clientCertChain != NULL && | |
| 5884 (ss->ssl3.platformClientKey || | |
| 5885 ss->ssl3.clientPrivateKey != NULL); | |
| 5886 | 5979 |
| 5887 if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { | 5980 if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { |
| 5888 send_funcs[n++] = ssl3_SendClientKeyExchange; | 5981 send_funcs[n++] = ssl3_SendClientKeyExchange; |
| 5889 send_funcs[n++] = ssl3_SendChangeCipherSpecs; | 5982 send_funcs[n++] = ssl3_SendChangeCipherSpecs; |
| 5890 if (sendEmptyCert) { | 5983 if (sendEmptyCert) { |
| 5891 send_funcs[n++] = ssl3_SendEmptyCertificate; | 5984 send_funcs[n++] = ssl3_SendEmptyCertificate; |
| 5892 } | 5985 } |
| 5893 » if (sendCert) { | 5986 » if (sendClientCert) { |
| 5894 send_funcs[n++] = ssl3_SendCertificate; | 5987 send_funcs[n++] = ssl3_SendCertificate; |
| 5895 send_funcs[n++] = ssl3_SendCertificateVerify; | 5988 send_funcs[n++] = ssl3_SendCertificateVerify; |
| 5896 } | 5989 } |
| 5897 } else { | 5990 } else { |
| 5898 if (sendEmptyCert) { | 5991 if (sendEmptyCert) { |
| 5899 send_funcs[n++] = ssl3_SendEmptyCertificate; | 5992 send_funcs[n++] = ssl3_SendEmptyCertificate; |
| 5900 } | 5993 } |
| 5901 » if (sendCert) { | 5994 » if (sendClientCert) { |
| 5902 send_funcs[n++] = ssl3_SendCertificate; | 5995 send_funcs[n++] = ssl3_SendCertificate; |
| 5903 } | 5996 } |
| 5904 send_funcs[n++] = ssl3_SendClientKeyExchange; | 5997 send_funcs[n++] = ssl3_SendClientKeyExchange; |
| 5905 » if (sendCert) { | 5998 » if (sendClientCert) { |
| 5906 send_funcs[n++] = ssl3_SendCertificateVerify; | 5999 send_funcs[n++] = ssl3_SendCertificateVerify; |
| 5907 } | 6000 } |
| 5908 send_funcs[n++] = ssl3_SendChangeCipherSpecs; | 6001 send_funcs[n++] = ssl3_SendChangeCipherSpecs; |
| 5909 } | 6002 } |
| 5910 | 6003 |
| 5911 PORT_Assert(n <= sizeof(send_funcs)/sizeof(send_funcs[0])); | 6004 PORT_Assert(n <= sizeof(send_funcs)/sizeof(send_funcs[0])); |
| 5912 | 6005 |
| 5913 for (i = 0; i < n; i++) { | 6006 for (i = 0; i < n; i++) { |
| 5914 rv = send_funcs[i](ss); | 6007 rv = send_funcs[i](ss); |
| 5915 if (rv != SECSuccess) { | 6008 if (rv != SECSuccess) { |
| 5916 goto loser; /* err code was set. */ | 6009 goto loser; /* err code was set. */ |
| 5917 } | 6010 } |
| 5918 } | 6011 } |
| 5919 | 6012 |
| 5920 /* We don't send NPN in a renegotiation as it's explicitly disallowed by | 6013 /* XXX: If the server's certificate hasn't been authenticated by this |
| 5921 * the spec. */ | 6014 * point, then we may be leaking this NPN message to an attacker. |
| 6015 */ |
| 5922 if (!ss->firstHsDone) { | 6016 if (!ss->firstHsDone) { |
| 5923 rv = ssl3_SendNextProto(ss); | 6017 rv = ssl3_SendNextProto(ss); |
| 5924 if (rv != SECSuccess) { | 6018 if (rv != SECSuccess) { |
| 5925 goto loser; /* err code was set. */ | 6019 goto loser; /* err code was set. */ |
| 5926 } | 6020 } |
| 5927 } | 6021 } |
| 5928 | 6022 |
| 5929 rv = ssl3_SendFinished(ss, 0); | 6023 rv = ssl3_SendFinished(ss, 0); |
| 5930 if (rv != SECSuccess) { | 6024 if (rv != SECSuccess) { |
| 5931 goto loser; /* err code was set. */ | 6025 goto loser; /* err code was set. */ |
| (...skipping 1960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7892 len += fakeCert.len + 3; | 7986 len += fakeCert.len + 3; |
| 7893 } else { | 7987 } else { |
| 7894 len += certChain->certs[i].len + 3; | 7988 len += certChain->certs[i].len + 3; |
| 7895 } | 7989 } |
| 7896 #else | 7990 #else |
| 7897 len += certChain->certs[i].len + 3; | 7991 len += certChain->certs[i].len + 3; |
| 7898 #endif | 7992 #endif |
| 7899 } | 7993 } |
| 7900 } | 7994 } |
| 7901 | 7995 |
| 7902 if (ss->ssl3.cachedInfoCertChainDigestReceived) { | |
| 7903 /* Compute hash. */ | |
| 7904 PRUint64 certChainHash; | |
| 7905 int i; | |
| 7906 FNV1A64_Init(&certChainHash); | |
| 7907 for (i = 0; i < certChain->len; i++) { | |
| 7908 unsigned int certLen = certChain->certs[i].len; | |
| 7909 unsigned char certLenArray[3] = { | |
| 7910 certLen >> 16, | |
| 7911 certLen >> 8, | |
| 7912 certLen | |
| 7913 }; | |
| 7914 FNV1A64_Update(&certChainHash, certLenArray, sizeof(certLenArray)); | |
| 7915 FNV1A64_Update(&certChainHash, certChain->certs[i].data, certLen); | |
| 7916 } | |
| 7917 FNV1A64_Final(&certChainHash); | |
| 7918 | |
| 7919 /* Both |&certChainHash| and |ss->ssl3.certChainDigest| should be in | |
| 7920 * network byte order since both are computed with the FNV1A64 hash, | |
| 7921 * which calls the function htonll. | |
| 7922 */ | |
| 7923 if (memcmp(&certChainHash, ss->ssl3.certChainDigest, | |
| 7924 sizeof(certChainHash)) == 0) { | |
| 7925 /* The client correctly predicted the certificate chain. */ | |
| 7926 | |
| 7927 /* Handshake type: certificate. */ | |
| 7928 rv = ssl3_AppendHandshakeNumber(ss, certificate, 1); | |
| 7929 if (rv != SECSuccess) { | |
| 7930 return rv; /* err set by AppendHandshake. */ | |
| 7931 } | |
| 7932 /* Handshake message length. */ | |
| 7933 rv = ssl3_AppendHandshakeNumber(ss, 15, 3); | |
| 7934 if (rv != SECSuccess) { | |
| 7935 return rv; /* err set by AppendHandshake. */ | |
| 7936 } | |
| 7937 /* CertChainLen(3) + ASN.1CertLen(3) + DigestLen(1) + Digest(8) */ | |
| 7938 rv = ssl3_AppendHandshakeNumber(ss, 12, 3); | |
| 7939 if (rv != SECSuccess) { | |
| 7940 return rv; /* err set by AppendHandshake. */ | |
| 7941 } | |
| 7942 /* ASN.1CertLen(3) + DigestLen(1) + Digest(8) */ | |
| 7943 rv = ssl3_AppendHandshakeNumber(ss, 9, 3); | |
| 7944 if (rv != SECSuccess) { | |
| 7945 return rv; /* err set by AppendHandshake. */ | |
| 7946 } | |
| 7947 /* Digest Length Byte */ | |
| 7948 rv = ssl3_AppendHandshakeNumber(ss, sizeof(certChainHash), 1); | |
| 7949 if (rv != SECSuccess) { | |
| 7950 return rv; /* err set by AppendHandshake. */ | |
| 7951 } | |
| 7952 /* Digest */ | |
| 7953 rv = ssl3_AppendHandshake(ss, &certChainHash, | |
| 7954 sizeof(certChainHash)); | |
| 7955 if (rv != SECSuccess) { | |
| 7956 return rv; /* err set by AppendHandshake. */ | |
| 7957 } | |
| 7958 | |
| 7959 return SECSuccess; | |
| 7960 } | |
| 7961 } | |
| 7962 | |
| 7963 /* Send the entire certificate as usual. */ | |
| 7964 | |
| 7965 rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3); | 7996 rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3); |
| 7966 if (rv != SECSuccess) { | 7997 if (rv != SECSuccess) { |
| 7967 return rv; /* err set by AppendHandshake. */ | 7998 return rv; /* err set by AppendHandshake. */ |
| 7968 } | 7999 } |
| 7969 rv = ssl3_AppendHandshakeNumber(ss, len, 3); | 8000 rv = ssl3_AppendHandshakeNumber(ss, len, 3); |
| 7970 if (rv != SECSuccess) { | 8001 if (rv != SECSuccess) { |
| 7971 return rv; /* err set by AppendHandshake. */ | 8002 return rv; /* err set by AppendHandshake. */ |
| 7972 } | 8003 } |
| 7973 if (certChain) { | 8004 if (certChain) { |
| 7974 for (i = 0; i < certChain->len; i++) { | 8005 for (i = 0; i < certChain->len; i++) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8102 | 8133 |
| 8103 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete | 8134 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete |
| 8104 * ssl3 Certificate message. | 8135 * ssl3 Certificate message. |
| 8105 * Caller must hold Handshake and RecvBuf locks. | 8136 * Caller must hold Handshake and RecvBuf locks. |
| 8106 */ | 8137 */ |
| 8107 static SECStatus | 8138 static SECStatus |
| 8108 ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) | 8139 ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) |
| 8109 { | 8140 { |
| 8110 ssl3CertNode * c; | 8141 ssl3CertNode * c; |
| 8111 ssl3CertNode * lastCert = NULL; | 8142 ssl3CertNode * lastCert = NULL; |
| 8112 ssl3CertNode * certs = NULL; | |
| 8113 PRArenaPool * arena = NULL; | |
| 8114 CERTCertificate *cert; | |
| 8115 PRInt32 remaining = 0; | 8143 PRInt32 remaining = 0; |
| 8116 PRInt32 size; | 8144 PRInt32 size; |
| 8117 SECStatus rv; | 8145 SECStatus rv; |
| 8118 PRBool isServer = (PRBool)(!!ss->sec.isServer); | 8146 PRBool isServer = (PRBool)(!!ss->sec.isServer); |
| 8147 PRBool trusted = PR_FALSE; |
| 8119 PRBool isTLS; | 8148 PRBool isTLS; |
| 8120 SSL3AlertDescription desc» = bad_certificate; | 8149 SSL3AlertDescription desc; |
| 8121 int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE; | 8150 int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE; |
| 8122 SECItem certItem; | 8151 SECItem certItem; |
| 8123 | 8152 |
| 8124 SSL_TRC(3, ("%d: SSL3[%d]: handle certificate handshake", | 8153 SSL_TRC(3, ("%d: SSL3[%d]: handle certificate handshake", |
| 8125 SSL_GETPID(), ss->fd)); | 8154 SSL_GETPID(), ss->fd)); |
| 8126 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 8155 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 8127 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | 8156 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 8128 | 8157 |
| 8129 if ((ss->ssl3.hs.ws != wait_server_cert) && | 8158 if ((ss->ssl3.hs.ws != wait_server_cert) && |
| 8130 (ss->ssl3.hs.ws != wait_client_cert)) { | 8159 (ss->ssl3.hs.ws != wait_client_cert)) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 8160 if (!remaining) { | 8189 if (!remaining) { |
| 8161 if (!(isTLS && isServer)) | 8190 if (!(isTLS && isServer)) |
| 8162 goto alert_loser; | 8191 goto alert_loser; |
| 8163 /* This is TLS's version of a no_certificate alert. */ | 8192 /* This is TLS's version of a no_certificate alert. */ |
| 8164 /* I'm a server. I've requested a client cert. He hasn't got one. */ | 8193 /* I'm a server. I've requested a client cert. He hasn't got one. */ |
| 8165 rv = ssl3_HandleNoCertificate(ss); | 8194 rv = ssl3_HandleNoCertificate(ss); |
| 8166 if (rv != SECSuccess) { | 8195 if (rv != SECSuccess) { |
| 8167 errCode = PORT_GetError(); | 8196 errCode = PORT_GetError(); |
| 8168 goto loser; | 8197 goto loser; |
| 8169 } | 8198 } |
| 8170 » goto cert_block; | 8199 » goto server_no_cert; |
| 8171 } | 8200 } |
| 8172 | 8201 |
| 8173 ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 8202 ss->ssl3.peerCertArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 8174 if ( arena == NULL ) { | 8203 if (ss->ssl3.peerCertArena == NULL) { |
| 8175 goto loser; /* don't send alerts on memory errors */ | 8204 goto loser; /* don't send alerts on memory errors */ |
| 8176 } | 8205 } |
| 8177 | 8206 |
| 8178 if (length == 12 && ssl3_ExtensionNegotiated(ss, ssl_cached_info_xtn)) { | 8207 /* First get the peer cert. */ |
| 8179 » /* We are dealing with a certificate_chain digest */ | 8208 remaining -= 3; |
| 8180 » int i; | 8209 if (remaining < 0) |
| 8210 » goto decode_loser; |
| 8181 | 8211 |
| 8182 » ss->ssl3.cachedInfoCertChainDigestReceived = PR_TRUE; | 8212 size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
| 8213 if (size <= 0) |
| 8214 » goto loser;» /* fatal alert already sent by ConsumeHandshake. */ |
| 8183 | 8215 |
| 8184 » /* Make sure the digests match. */ | 8216 if (remaining < size) |
| 8185 » if (memcmp(b + 4, ss->ssl3.certChainDigest, 8)) { | 8217 » goto decode_loser; |
| 8186 » desc = handshake_failure; | |
| 8187 » goto alert_loser; | |
| 8188 » } | |
| 8189 | 8218 |
| 8190 » /* First get the peer cert. */ | 8219 certItem.data = b; |
| 8191 » if (ss->ssl3.predictedCertChain[0] == NULL) { | 8220 certItem.len = size; |
| 8192 » desc = handshake_failure; | 8221 b += size; |
| 8193 » goto alert_loser; | 8222 length -= size; |
| 8194 » } | 8223 remaining -= size; |
| 8195 » ss->sec.peerCert = CERT_DupCertificate(ss->ssl3.predictedCertChain[0]); | |
| 8196 | 8224 |
| 8197 » /* Now get all of the CA certs. */ | 8225 ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, |
| 8198 » ss->ssl3.peerCertChain = NULL; | 8226 PR_FALSE, PR_TRUE); |
| 8199 » for (i = 1; ss->ssl3.predictedCertChain[i] != NULL; i++) { | 8227 if (ss->sec.peerCert == NULL) { |
| 8200 » c = PORT_ArenaNew(arena, ssl3CertNode); | 8228 » /* We should report an alert if the cert was bad, but not if the |
| 8201 » if (c == NULL) { | 8229 » * problem was just some local problem, like memory error. |
| 8202 » » goto loser;» /* don't send alerts on memory errors */ | 8230 » */ |
| 8203 » } | 8231 » goto ambiguous_err; |
| 8204 » c->cert = CERT_DupCertificate(ss->ssl3.predictedCertChain[i]); | 8232 } |
| 8205 » c->next = NULL; | |
| 8206 » if (lastCert) { | |
| 8207 » » lastCert->next = c; | |
| 8208 » } else { | |
| 8209 » » ss->ssl3.peerCertChain = c; | |
| 8210 » } | |
| 8211 » lastCert = c; | |
| 8212 » } | |
| 8213 } else { | |
| 8214 » /* We are dealing with a regular certificate message */ | |
| 8215 » ss->ssl3.cachedInfoCertChainDigestReceived = PR_FALSE; | |
| 8216 | 8233 |
| 8217 » /* First get the peer cert. */ | 8234 /* Now get all of the CA certs. */ |
| 8235 while (remaining > 0) { |
| 8218 remaining -= 3; | 8236 remaining -= 3; |
| 8219 if (remaining < 0) | 8237 if (remaining < 0) |
| 8220 goto decode_loser; | 8238 goto decode_loser; |
| 8221 | 8239 |
| 8222 size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); | 8240 size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
| 8223 if (size <= 0) | 8241 if (size <= 0) |
| 8224 goto loser; /* fatal alert already sent by ConsumeHandshake. */ | 8242 goto loser; /* fatal alert already sent by ConsumeHandshake. */ |
| 8225 | 8243 |
| 8226 if (remaining < size) | 8244 if (remaining < size) |
| 8227 goto decode_loser; | 8245 goto decode_loser; |
| 8228 | 8246 |
| 8229 certItem.data = b; | 8247 certItem.data = b; |
| 8230 certItem.len = size; | 8248 certItem.len = size; |
| 8231 » b += size; | 8249 » b += size; |
| 8232 length -= size; | 8250 length -= size; |
| 8233 remaining -= size; | 8251 remaining -= size; |
| 8234 | 8252 |
| 8235 » ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, | 8253 » c = PORT_ArenaNew(ss->ssl3.peerCertArena, ssl3CertNode); |
| 8236 » » » » » » NULL, PR_FALSE, PR_TRUE); | 8254 » if (c == NULL) { |
| 8237 » if (ss->sec.peerCert == NULL) { | 8255 » goto loser;»/* don't send alerts on memory errors */ |
| 8238 » /* We should report an alert if the cert was bad, but not if the | 8256 » } |
| 8239 » * problem was just some local problem, like memory error. | 8257 |
| 8240 » */ | 8258 » c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, |
| 8259 » PR_FALSE, PR_TRUE); |
| 8260 » if (c->cert == NULL) { |
| 8241 goto ambiguous_err; | 8261 goto ambiguous_err; |
| 8242 } | 8262 } |
| 8243 | 8263 |
| 8244 » /* Now get all of the CA certs. */ | 8264 » if (c->cert->trust) |
| 8245 » while (remaining > 0) { | 8265 » trusted = PR_TRUE; |
| 8246 » remaining -= 3; | |
| 8247 » if (remaining < 0) | |
| 8248 » » goto decode_loser; | |
| 8249 | 8266 |
| 8250 » size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); | 8267 » c->next = NULL; |
| 8251 » if (size <= 0) | 8268 » if (lastCert) { |
| 8252 » » goto loser; /* fatal alert already sent by ConsumeHandshake. */ | 8269 » lastCert->next = c; |
| 8253 | 8270 » } else { |
| 8254 » if (remaining < size) | 8271 » ss->ssl3.peerCertChain = c; |
| 8255 » » goto decode_loser; | |
| 8256 | |
| 8257 » certItem.data = b; | |
| 8258 » certItem.len = size; | |
| 8259 » b += size; | |
| 8260 » length -= size; | |
| 8261 » remaining -= size; | |
| 8262 | |
| 8263 » c = PORT_ArenaNew(arena, ssl3CertNode); | |
| 8264 » if (c == NULL) { | |
| 8265 » » goto loser;» /* don't send alerts on memory errors */ | |
| 8266 » } | |
| 8267 | |
| 8268 » c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, | |
| 8269 » » » » » PR_FALSE, PR_TRUE); | |
| 8270 » if (c->cert == NULL) { | |
| 8271 » » goto ambiguous_err; | |
| 8272 » } | |
| 8273 | |
| 8274 » c->next = NULL; | |
| 8275 » if (lastCert) { | |
| 8276 » » lastCert->next = c; | |
| 8277 » } else { | |
| 8278 » » certs = c; | |
| 8279 » } | |
| 8280 » lastCert = c; | |
| 8281 } | 8272 } |
| 8282 | 8273 » lastCert = c; |
| 8283 » if (remaining != 0) | |
| 8284 » goto decode_loser; | |
| 8285 | |
| 8286 » ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL; | |
| 8287 } | 8274 } |
| 8288 | 8275 |
| 8276 if (remaining != 0) |
| 8277 goto decode_loser; |
| 8278 |
| 8289 SECKEY_UpdateCertPQG(ss->sec.peerCert); | 8279 SECKEY_UpdateCertPQG(ss->sec.peerCert); |
| 8290 | 8280 |
| 8281 ss->ssl3.hs.authCertificatePending = PR_FALSE; |
| 8282 |
| 8291 /* | 8283 /* |
| 8292 * Ask caller-supplied callback function to validate cert chain. | 8284 * Ask caller-supplied callback function to validate cert chain. |
| 8293 */ | 8285 */ |
| 8294 rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd, | 8286 rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd, |
| 8295 PR_TRUE, isServer); | 8287 PR_TRUE, isServer); |
| 8296 if (rv) { | 8288 if (rv) { |
| 8297 errCode = PORT_GetError(); | 8289 errCode = PORT_GetError(); |
| 8298 » if (!ss->handleBadCert) { | 8290 » if (rv != SECWouldBlock) { |
| 8299 » goto bad_cert; | 8291 » if (ss->handleBadCert) { |
| 8292 » » rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd); |
| 8293 » } |
| 8300 } | 8294 } |
| 8301 » rv = (SECStatus)(*ss->handleBadCert)(ss->badCertArg, ss->fd); | 8295 |
| 8302 » if ( rv ) { | 8296 » if (rv == SECWouldBlock) { |
| 8303 » if ( rv == SECWouldBlock ) { | 8297 » if (ss->sec.isServer) { |
| 8304 » » /* someone will handle this connection asynchronously*/ | 8298 » » errCode = SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS; |
| 8305 » » SSL_DBG(("%d: SSL3[%d]: go to async cert handler", | 8299 » » rv = SECFailure; |
| 8306 » » » SSL_GETPID(), ss->fd)); | 8300 » » goto loser; |
| 8307 » » ssl_SetAlwaysBlock(ss); | |
| 8308 » » goto cert_block; | |
| 8309 } | 8301 } |
| 8310 » /* cert is bad */ | 8302 |
| 8311 » goto bad_cert; | 8303 » ss->ssl3.hs.authCertificatePending = PR_TRUE; |
| 8304 » rv = SECSuccess; |
| 8305 |
| 8306 » /* XXX: Async cert validation and False Start don't work together |
| 8307 » * safely yet; if we leave False Start enabled, we may end up false |
| 8308 » * starting (sending application data) before we |
| 8309 » * SSL_AuthCertificateComplete has been called. |
| 8310 » */ |
| 8311 » ss->opt.enableFalseStart = PR_FALSE; |
| 8312 } | 8312 } |
| 8313 /* cert is good */ | |
| 8314 } | |
| 8315 | 8313 |
| 8316 /* start SSL Step Up, if appropriate */ | 8314 » if (rv != SECSuccess) { |
| 8317 cert = ss->sec.peerCert; | 8315 » ssl3_SendAlertForCertError(ss, errCode); |
| 8318 if (!isServer && | 8316 » goto loser; |
| 8319 » ssl3_global_policy_some_restricted && | 8317 » } |
| 8320 ss->ssl3.policy == SSL_ALLOWED && | |
| 8321 » anyRestrictedEnabled(ss) && | |
| 8322 » SECSuccess == CERT_VerifyCertNow(cert->dbhandle, cert, | |
| 8323 » PR_FALSE, /* checkSig */ | |
| 8324 » » » » certUsageSSLServerWithStepUp, | |
| 8325 /*XXX*/»» » » ss->authCertificateArg) ) { | |
| 8326 » ss->ssl3.policy = SSL_RESTRICTED; | |
| 8327 » ss->ssl3.hs.rehandshake = PR_TRUE; | |
| 8328 } | 8318 } |
| 8329 | 8319 |
| 8330 ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); | 8320 ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); |
| 8331 ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid); | 8321 ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid); |
| 8332 | 8322 |
| 8333 if (!ss->sec.isServer) { | 8323 if (!ss->sec.isServer) { |
| 8324 CERTCertificate *cert = ss->sec.peerCert; |
| 8325 |
| 8334 /* set the server authentication and key exchange types and sizes | 8326 /* set the server authentication and key exchange types and sizes |
| 8335 ** from the value in the cert. If the key exchange key is different, | 8327 ** from the value in the cert. If the key exchange key is different, |
| 8336 ** it will get fixed when we handle the server key exchange message. | 8328 ** it will get fixed when we handle the server key exchange message. |
| 8337 */ | 8329 */ |
| 8338 SECKEYPublicKey * pubKey = CERT_ExtractPublicKey(cert); | 8330 SECKEYPublicKey * pubKey = CERT_ExtractPublicKey(cert); |
| 8339 ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType; | 8331 ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType; |
| 8340 ss->sec.keaType = ss->ssl3.hs.kea_def->exchKeyType; | 8332 ss->sec.keaType = ss->ssl3.hs.kea_def->exchKeyType; |
| 8341 if (pubKey) { | 8333 if (pubKey) { |
| 8342 ss->sec.keaKeyBits = ss->sec.authKeyBits = | 8334 ss->sec.keaKeyBits = ss->sec.authKeyBits = |
| 8343 SECKEY_PublicKeyStrengthInBits(pubKey); | 8335 SECKEY_PublicKeyStrengthInBits(pubKey); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 8364 /* | 8356 /* |
| 8365 * XXX: if cert is not signed by rsa we should | 8357 * XXX: if cert is not signed by rsa we should |
| 8366 * destroy pubKey and goto bad_cert | 8358 * destroy pubKey and goto bad_cert |
| 8367 */ | 8359 */ |
| 8368 } | 8360 } |
| 8369 } | 8361 } |
| 8370 #endif /* NSS_ENABLE_ECC */ | 8362 #endif /* NSS_ENABLE_ECC */ |
| 8371 SECKEY_DestroyPublicKey(pubKey); | 8363 SECKEY_DestroyPublicKey(pubKey); |
| 8372 pubKey = NULL; | 8364 pubKey = NULL; |
| 8373 } | 8365 } |
| 8374 } | |
| 8375 | 8366 |
| 8376 cert_block: | |
| 8377 if (ss->sec.isServer) { | |
| 8378 if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { | |
| 8379 ss->ssl3.hs.ws = wait_cert_verify; | |
| 8380 } else { | |
| 8381 ss->ssl3.hs.ws = wait_client_key; | |
| 8382 } | |
| 8383 } else { | |
| 8384 ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */ | 8367 ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */ |
| 8385 if (ss->ssl3.hs.kea_def->is_limited || | 8368 if (ss->ssl3.hs.kea_def->is_limited || |
| 8386 /* XXX OR server cert is signing only. */ | 8369 /* XXX OR server cert is signing only. */ |
| 8387 #ifdef NSS_ENABLE_ECC | 8370 #ifdef NSS_ENABLE_ECC |
| 8388 ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa || | 8371 ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa || |
| 8389 ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa || | 8372 ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa || |
| 8390 #endif /* NSS_ENABLE_ECC */ | 8373 #endif /* NSS_ENABLE_ECC */ |
| 8391 ss->ssl3.hs.kea_def->exchKeyType == kt_dh) { | 8374 ss->ssl3.hs.kea_def->exchKeyType == kt_dh) { |
| 8392 ss->ssl3.hs.ws = wait_server_key; /* allow server_key_exchange */ | 8375 ss->ssl3.hs.ws = wait_server_key; /* allow server_key_exchange */ |
| 8393 } | 8376 } |
| 8377 } else { |
| 8378 server_no_cert: |
| 8379 if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { |
| 8380 ss->ssl3.hs.ws = wait_cert_verify; |
| 8381 } else { |
| 8382 ss->ssl3.hs.ws = wait_client_key; |
| 8383 } |
| 8394 } | 8384 } |
| 8395 | 8385 |
| 8396 /* rv must normally be equal to SECSuccess here. If we called | 8386 PORT_Assert(rv == SECSuccess); |
| 8397 * handleBadCert, it can also be SECWouldBlock. | 8387 if (rv != SECSuccess) { |
| 8398 */ | 8388 » errCode = SEC_ERROR_LIBRARY_FAILURE; |
| 8389 » rv = SECFailure; |
| 8390 » goto loser; |
| 8391 } |
| 8392 |
| 8399 return rv; | 8393 return rv; |
| 8400 | 8394 |
| 8401 ambiguous_err: | 8395 ambiguous_err: |
| 8402 errCode = PORT_GetError(); | 8396 errCode = PORT_GetError(); |
| 8403 switch (errCode) { | 8397 switch (errCode) { |
| 8404 case PR_OUT_OF_MEMORY_ERROR: | 8398 case PR_OUT_OF_MEMORY_ERROR: |
| 8405 case SEC_ERROR_BAD_DATABASE: | 8399 case SEC_ERROR_BAD_DATABASE: |
| 8406 case SEC_ERROR_NO_MEMORY: | 8400 case SEC_ERROR_NO_MEMORY: |
| 8407 if (isTLS) { | 8401 if (isTLS) { |
| 8408 desc = internal_error; | 8402 desc = internal_error; |
| 8409 goto alert_loser; | 8403 goto alert_loser; |
| 8410 } | 8404 } |
| 8411 goto loser; | 8405 goto loser; |
| 8412 } | 8406 } |
| 8413 /* fall through to bad_cert. */ | 8407 ssl3_SendAlertForCertError(ss, errCode); |
| 8414 | 8408 goto loser; |
| 8415 bad_cert:» /* caller has set errCode. */ | |
| 8416 switch (errCode) { | |
| 8417 case SEC_ERROR_LIBRARY_FAILURE: desc = unsupported_certificate; break; | |
| 8418 case SEC_ERROR_EXPIRED_CERTIFICATE: desc = certificate_expired; break; | |
| 8419 case SEC_ERROR_REVOKED_CERTIFICATE: desc = certificate_revoked; break; | |
| 8420 case SEC_ERROR_INADEQUATE_KEY_USAGE: | |
| 8421 case SEC_ERROR_INADEQUATE_CERT_TYPE: | |
| 8422 » » desc = certificate_unknown; break; | |
| 8423 case SEC_ERROR_UNTRUSTED_CERT: | |
| 8424 » » desc = isTLS ? access_denied : certificate_unknown; break; | |
| 8425 case SEC_ERROR_UNKNOWN_ISSUER: | |
| 8426 case SEC_ERROR_UNTRUSTED_ISSUER: | |
| 8427 » » desc = isTLS ? unknown_ca : certificate_unknown; break; | |
| 8428 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: | |
| 8429 » » desc = isTLS ? unknown_ca : certificate_expired; break; | |
| 8430 | |
| 8431 case SEC_ERROR_CERT_NOT_IN_NAME_SPACE: | |
| 8432 case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID: | |
| 8433 case SEC_ERROR_CA_CERT_INVALID: | |
| 8434 case SEC_ERROR_BAD_SIGNATURE: | |
| 8435 default: desc = bad_certificate; break; | |
| 8436 } | |
| 8437 SSL_DBG(("%d: SSL3[%d]: peer certificate is no good: error=%d", | |
| 8438 » SSL_GETPID(), ss->fd, errCode)); | |
| 8439 | |
| 8440 goto alert_loser; | |
| 8441 | 8409 |
| 8442 decode_loser: | 8410 decode_loser: |
| 8443 desc = isTLS ? decode_error : bad_certificate; | 8411 desc = isTLS ? decode_error : bad_certificate; |
| 8444 | 8412 |
| 8445 alert_loser: | 8413 alert_loser: |
| 8446 (void)SSL3_SendAlert(ss, alert_fatal, desc); | 8414 (void)SSL3_SendAlert(ss, alert_fatal, desc); |
| 8447 | 8415 |
| 8448 loser: | 8416 loser: |
| 8449 if (ss->ssl3.peerCertChain == NULL) { | |
| 8450 ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL; | |
| 8451 } | |
| 8452 PORT_Assert(certs == NULL); | |
| 8453 ssl3_CleanupPeerCerts(ss); | 8417 ssl3_CleanupPeerCerts(ss); |
| 8454 | 8418 |
| 8455 if (ss->sec.peerCert != NULL) { | 8419 if (ss->sec.peerCert != NULL) { |
| 8456 CERT_DestroyCertificate(ss->sec.peerCert); | 8420 CERT_DestroyCertificate(ss->sec.peerCert); |
| 8457 ss->sec.peerCert = NULL; | 8421 ss->sec.peerCert = NULL; |
| 8458 } | 8422 } |
| 8459 (void)ssl_MapLowLevelError(errCode); | 8423 (void)ssl_MapLowLevelError(errCode); |
| 8460 return SECFailure; | 8424 return SECFailure; |
| 8461 } | 8425 } |
| 8462 | 8426 |
| 8427 static SECStatus ssl3_FinishHandshake(sslSocket *ss); |
| 8463 | 8428 |
| 8464 /* restart an SSL connection that we stopped to run certificate dialogs | 8429 static SECStatus |
| 8465 ** XXX» Need to document here how an application marks a cert to show that | 8430 ssl3_AlwaysFail(sslSocket * ss) |
| 8466 **» the application has accepted it (overridden CERT_VerifyCert). | 8431 { |
| 8467 * | 8432 PORT_SetError(PR_INVALID_STATE_ERROR); |
| 8468 * XXX This code only works on the initial handshake on a connection, XXX | 8433 return SECFailure; |
| 8469 * It does not work on a subsequent handshake (redo). | 8434 } |
| 8470 * | 8435 |
| 8471 * Return value: XXX | 8436 /* Caller must hold 1stHandshakeLock. |
| 8472 * | |
| 8473 * Caller holds 1stHandshakeLock. | |
| 8474 */ | 8437 */ |
| 8475 int | 8438 SECStatus |
| 8476 ssl3_RestartHandshakeAfterServerCert(sslSocket *ss) | 8439 ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error) |
| 8477 { | 8440 { |
| 8478 CERTCertificate * cert; | 8441 SECStatus rv; |
| 8479 int rv» = SECSuccess; | |
| 8480 | 8442 |
| 8481 if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) { | 8443 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); |
| 8482 » SET_ERROR_CODE | 8444 |
| 8483 » return SECFailure; | 8445 if (ss->sec.isServer) { |
| 8484 } | 8446 » PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS); |
| 8485 if (!ss->ssl3.initialized) { | 8447 » return SECFailure; |
| 8486 » SET_ERROR_CODE | |
| 8487 » return SECFailure; | |
| 8488 } | 8448 } |
| 8489 | 8449 |
| 8490 cert = ss->sec.peerCert; | 8450 ssl_GetRecvBufLock(ss); |
| 8451 ssl_GetSSL3HandshakeLock(ss); |
| 8491 | 8452 |
| 8492 /* Permit step up if user decided to accept the cert */ | 8453 if (!ss->ssl3.hs.authCertificatePending) { |
| 8493 if (!ss->sec.isServer && | 8454 » PORT_SetError(PR_INVALID_STATE_ERROR); |
| 8494 » ssl3_global_policy_some_restricted && | 8455 » rv = SECFailure; |
| 8495 ss->ssl3.policy == SSL_ALLOWED && | 8456 » goto done; |
| 8496 » anyRestrictedEnabled(ss) && | |
| 8497 » (SECSuccess == CERT_VerifyCertNow(cert->dbhandle, cert, | |
| 8498 » PR_FALSE, /* checksig */ | |
| 8499 » » » » certUsageSSLServerWithStepUp, | |
| 8500 /*XXX*/»» » » ss->authCertificateArg) )) { | |
| 8501 » ss->ssl3.policy = SSL_RESTRICTED; | |
| 8502 » ss->ssl3.hs.rehandshake = PR_TRUE; | |
| 8503 } | 8457 } |
| 8504 | 8458 |
| 8505 if (ss->handshake != NULL) { | 8459 ss->ssl3.hs.authCertificatePending = PR_FALSE; |
| 8506 » ss->handshake = ssl_GatherRecord1stHandshake; | |
| 8507 » ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); | |
| 8508 » ssl3_CopyPeerCertsToSID((ssl3CertNode *)ss->ssl3.peerCertChain, | |
| 8509 » » » » ss->sec.ci.sid); | |
| 8510 | 8460 |
| 8511 » ssl_GetRecvBufLock(ss); | 8461 if (error != 0) { |
| 8512 » if (ss->ssl3.hs.msgState.buf != NULL) { | 8462 » ss->ssl3.hs.restartTarget = ssl3_AlwaysFail; |
| 8513 » rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); | 8463 » ssl3_SendAlertForCertError(ss, error); |
| 8464 » rv = SECSuccess; |
| 8465 } else if (ss->ssl3.hs.restartTarget != NULL) { |
| 8466 » sslRestartTarget target = ss->ssl3.hs.restartTarget; |
| 8467 » ss->ssl3.hs.restartTarget = NULL; |
| 8468 » rv = target(ss); |
| 8469 » /* Even if we blocked here, we have accomplished enough to claim |
| 8470 » * success. Any remaining work will be taken care of by subsequent |
| 8471 » * calls to SSL_ForceHandshake/PR_Send/PR_Read/etc. |
| 8472 » */ |
| 8473 » if (rv == SECWouldBlock) { |
| 8474 » rv = SECSuccess; |
| 8514 } | 8475 } |
| 8515 » ssl_ReleaseRecvBufLock(ss); | 8476 } else { |
| 8477 » rv = SECSuccess; |
| 8516 } | 8478 } |
| 8517 | 8479 |
| 8480 done: |
| 8481 ssl_ReleaseSSL3HandshakeLock(ss); |
| 8482 ssl_ReleaseRecvBufLock(ss); |
| 8483 |
| 8518 return rv; | 8484 return rv; |
| 8519 } | 8485 } |
| 8520 | 8486 |
| 8521 /* The calling function must acquire and release the appropriate lock (i.e., | 8487 /* The calling function must acquire and release the appropriate lock (i.e., |
| 8522 * ssl_GetSpecReadLock / ssl_ReleaseSpecReadLock for ss->ssl3.crSpec). Any | 8488 * ssl_GetSpecReadLock / ssl_ReleaseSpecReadLock for ss->ssl3.crSpec). Any |
| 8523 * label must already be concatenated onto the beginning of val. | 8489 * label must already be concatenated onto the beginning of val. |
| 8524 */ | 8490 */ |
| 8525 SECStatus | 8491 SECStatus |
| 8526 ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label, | 8492 ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label, |
| 8527 unsigned int labelLen, const unsigned char *val, unsigned int valLen, | 8493 unsigned int labelLen, const unsigned char *val, unsigned int valLen, |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8772 * Caller must hold Handshake and RecvBuf locks. | 8738 * Caller must hold Handshake and RecvBuf locks. |
| 8773 */ | 8739 */ |
| 8774 static SECStatus | 8740 static SECStatus |
| 8775 ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, | 8741 ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, |
| 8776 const SSL3Hashes *hashes) | 8742 const SSL3Hashes *hashes) |
| 8777 { | 8743 { |
| 8778 sslSessionID * sid = ss->sec.ci.sid; | 8744 sslSessionID * sid = ss->sec.ci.sid; |
| 8779 SECStatus rv = SECSuccess; | 8745 SECStatus rv = SECSuccess; |
| 8780 PRBool isServer = ss->sec.isServer; | 8746 PRBool isServer = ss->sec.isServer; |
| 8781 PRBool isTLS; | 8747 PRBool isTLS; |
| 8782 PRBool doStepUp; | |
| 8783 SSL3KEAType effectiveExchKeyType; | 8748 SSL3KEAType effectiveExchKeyType; |
| 8784 | 8749 |
| 8785 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 8750 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 8786 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | 8751 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 8787 | 8752 |
| 8788 SSL_TRC(3, ("%d: SSL3[%d]: handle finished handshake", | 8753 SSL_TRC(3, ("%d: SSL3[%d]: handle finished handshake", |
| 8789 SSL_GETPID(), ss->fd)); | 8754 SSL_GETPID(), ss->fd)); |
| 8790 | 8755 |
| 8791 if (ss->ssl3.hs.ws != wait_finished) { | 8756 if (ss->ssl3.hs.ws != wait_finished) { |
| 8792 SSL3_SendAlert(ss, alert_fatal, unexpected_message); | 8757 SSL3_SendAlert(ss, alert_fatal, unexpected_message); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8828 else | 8793 else |
| 8829 ss->ssl3.hs.finishedMsgs.sFinished[0] = *hashes; | 8794 ss->ssl3.hs.finishedMsgs.sFinished[0] = *hashes; |
| 8830 ss->ssl3.hs.finishedBytes = sizeof *hashes; | 8795 ss->ssl3.hs.finishedBytes = sizeof *hashes; |
| 8831 if (0 != NSS_SecureMemcmp(hashes, b, length)) { | 8796 if (0 != NSS_SecureMemcmp(hashes, b, length)) { |
| 8832 (void)ssl3_HandshakeFailure(ss); | 8797 (void)ssl3_HandshakeFailure(ss); |
| 8833 PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); | 8798 PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); |
| 8834 return SECFailure; | 8799 return SECFailure; |
| 8835 } | 8800 } |
| 8836 } | 8801 } |
| 8837 | 8802 |
| 8838 doStepUp = (PRBool)(!isServer && ss->ssl3.hs.rehandshake); | |
| 8839 | |
| 8840 ssl_GetXmitBufLock(ss); /*************************************/ | 8803 ssl_GetXmitBufLock(ss); /*************************************/ |
| 8841 | 8804 |
| 8842 if ((isServer && !ss->ssl3.hs.isResuming) || | 8805 if ((isServer && !ss->ssl3.hs.isResuming) || |
| 8843 (!isServer && ss->ssl3.hs.isResuming)) { | 8806 (!isServer && ss->ssl3.hs.isResuming)) { |
| 8844 PRInt32 flags = 0; | 8807 PRInt32 flags = 0; |
| 8845 | 8808 |
| 8846 /* Send a NewSessionTicket message if the client sent us | 8809 /* Send a NewSessionTicket message if the client sent us |
| 8847 * either an empty session ticket, or one that did not verify. | 8810 * either an empty session ticket, or one that did not verify. |
| 8848 * (Note that if either of these conditions was met, then the | 8811 * (Note that if either of these conditions was met, then the |
| 8849 * server has sent a SessionTicket extension in the | 8812 * server has sent a SessionTicket extension in the |
| 8850 * ServerHello message.) | 8813 * ServerHello message.) |
| 8851 */ | 8814 */ |
| 8852 if (isServer && !ss->ssl3.hs.isResuming && | 8815 if (isServer && !ss->ssl3.hs.isResuming && |
| 8853 ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) { | 8816 ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) { |
| 8854 rv = ssl3_SendNewSessionTicket(ss); | 8817 rv = ssl3_SendNewSessionTicket(ss); |
| 8855 if (rv != SECSuccess) { | 8818 if (rv != SECSuccess) { |
| 8856 goto xmit_loser; | 8819 goto xmit_loser; |
| 8857 } | 8820 } |
| 8858 } | 8821 } |
| 8859 | 8822 |
| 8860 rv = ssl3_SendChangeCipherSpecs(ss); | 8823 rv = ssl3_SendChangeCipherSpecs(ss); |
| 8861 if (rv != SECSuccess) { | 8824 if (rv != SECSuccess) { |
| 8862 goto xmit_loser; /* err is set. */ | 8825 goto xmit_loser; /* err is set. */ |
| 8863 } | 8826 } |
| 8864 /* If this thread is in SSL_SecureSend (trying to write some data) | 8827 /* If this thread is in SSL_SecureSend (trying to write some data) |
| 8865 ** or if it is going to step up, | |
| 8866 ** then set the ssl_SEND_FLAG_FORCE_INTO_BUFFER flag, so that the | 8828 ** then set the ssl_SEND_FLAG_FORCE_INTO_BUFFER flag, so that the |
| 8867 ** last two handshake messages (change cipher spec and finished) | 8829 ** last two handshake messages (change cipher spec and finished) |
| 8868 ** will be sent in the same send/write call as the application data. | 8830 ** will be sent in the same send/write call as the application data. |
| 8869 */ | 8831 */ |
| 8870 » if (doStepUp || ss->writerThread == PR_GetCurrentThread()) { | 8832 » if (ss->writerThread == PR_GetCurrentThread()) { |
| 8871 flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER; | 8833 flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER; |
| 8872 } | 8834 } |
| 8873 | 8835 |
| 8874 if (!isServer && !ss->firstHsDone) { | 8836 if (!isServer && !ss->firstHsDone) { |
| 8875 rv = ssl3_SendNextProto(ss); | 8837 rv = ssl3_SendNextProto(ss); |
| 8876 if (rv != SECSuccess) { | 8838 if (rv != SECSuccess) { |
| 8877 » » goto xmit_loser;» /* err code was set. */ | 8839 » » goto xmit_loser; /* err code was set. */ |
| 8878 } | 8840 } |
| 8879 } | 8841 } |
| 8880 | 8842 |
| 8881 rv = ssl3_SendFinished(ss, flags); | 8843 rv = ssl3_SendFinished(ss, flags); |
| 8882 if (rv != SECSuccess) { | 8844 if (rv != SECSuccess) { |
| 8883 goto xmit_loser; /* err is set. */ | 8845 goto xmit_loser; /* err is set. */ |
| 8884 } | 8846 } |
| 8885 } | 8847 } |
| 8886 | 8848 |
| 8887 /* Optimization: don't cache this connection if we're going to step up. */ | |
| 8888 if (doStepUp) { | |
| 8889 ssl_FreeSID(sid); | |
| 8890 ss->sec.ci.sid = sid = NULL; | |
| 8891 ss->ssl3.hs.rehandshake = PR_FALSE; | |
| 8892 rv = ssl3_SendClientHello(ss); | |
| 8893 xmit_loser: | 8849 xmit_loser: |
| 8894 » ssl_ReleaseXmitBufLock(ss); | 8850 ssl_ReleaseXmitBufLock(ss);»/*************************************/ |
| 8895 » return rv;» /* err code is set if appropriate. */ | 8851 if (rv != SECSuccess) { |
| 8852 return rv; |
| 8896 } | 8853 } |
| 8897 | 8854 |
| 8898 ssl_ReleaseXmitBufLock(ss); /*************************************/ | |
| 8899 | |
| 8900 /* The first handshake is now completed. */ | |
| 8901 ss->handshake = NULL; | |
| 8902 ss->firstHsDone = PR_TRUE; | |
| 8903 ss->gs.writeOffset = 0; | 8855 ss->gs.writeOffset = 0; |
| 8904 ss->gs.readOffset = 0; | 8856 ss->gs.readOffset = 0; |
| 8905 | 8857 |
| 8906 if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) { | 8858 if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) { |
| 8907 effectiveExchKeyType = kt_rsa; | 8859 effectiveExchKeyType = kt_rsa; |
| 8908 } else { | 8860 } else { |
| 8909 effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType; | 8861 effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType; |
| 8910 } | 8862 } |
| 8911 | 8863 |
| 8912 if (sid->cached == never_cached && !ss->opt.noCache && ss->sec.cache) { | 8864 if (sid->cached == never_cached && !ss->opt.noCache && ss->sec.cache) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 8942 rv = ssl3_CacheWrappedMasterSecret(ss, ss->sec.ci.sid, | 8894 rv = ssl3_CacheWrappedMasterSecret(ss, ss->sec.ci.sid, |
| 8943 ss->ssl3.crSpec, | 8895 ss->ssl3.crSpec, |
| 8944 effectiveExchKeyType); | 8896 effectiveExchKeyType); |
| 8945 sid->u.ssl3.keys.msIsWrapped = PR_TRUE; | 8897 sid->u.ssl3.keys.msIsWrapped = PR_TRUE; |
| 8946 } | 8898 } |
| 8947 ssl_ReleaseSpecReadLock(ss); /*************************************/ | 8899 ssl_ReleaseSpecReadLock(ss); /*************************************/ |
| 8948 | 8900 |
| 8949 /* If the wrap failed, we don't cache the sid. | 8901 /* If the wrap failed, we don't cache the sid. |
| 8950 * The connection continues normally however. | 8902 * The connection continues normally however. |
| 8951 */ | 8903 */ |
| 8952 » if (rv == SECSuccess) { | 8904 » ss->ssl3.hs.cacheSID = rv == SECSuccess; |
| 8953 » (*ss->sec.cache)(sid); | 8905 } |
| 8906 |
| 8907 if (ss->ssl3.hs.authCertificatePending) { |
| 8908 » if (ss->ssl3.hs.restartTarget) { |
| 8909 » PR_NOT_REACHED("ssl3_HandleFinished: unexpected restartTarget"); |
| 8910 » PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
| 8911 » return SECFailure; |
| 8954 } | 8912 } |
| 8913 |
| 8914 ss->ssl3.hs.restartTarget = ssl3_FinishHandshake; |
| 8915 return SECWouldBlock; |
| 8955 } | 8916 } |
| 8917 |
| 8918 rv = ssl3_FinishHandshake(ss); |
| 8919 return rv; |
| 8920 } |
| 8921 |
| 8922 SECStatus |
| 8923 ssl3_FinishHandshake(sslSocket * ss) |
| 8924 { |
| 8925 SECStatus rv; |
| 8926 |
| 8927 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 8928 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 8929 PORT_Assert( ss->ssl3.hs.restartTarget == NULL ); |
| 8930 |
| 8931 /* The first handshake is now completed. */ |
| 8932 ss->handshake = NULL; |
| 8933 ss->firstHsDone = PR_TRUE; |
| 8934 |
| 8935 if (ss->sec.ci.sid->cached == never_cached && |
| 8936 !ss->opt.noCache && ss->sec.cache && ss->ssl3.hs.cacheSID) { |
| 8937 (*ss->sec.cache)(ss->sec.ci.sid); |
| 8938 } |
| 8939 |
| 8956 ss->ssl3.hs.ws = idle_handshake; | 8940 ss->ssl3.hs.ws = idle_handshake; |
| 8957 | 8941 |
| 8958 /* Do the handshake callback for sslv3 here, if we cannot false start. */ | 8942 /* Do the handshake callback for sslv3 here, if we cannot false start. */ |
| 8959 if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) { | 8943 if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) { |
| 8960 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); | 8944 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); |
| 8961 } | 8945 } |
| 8962 | 8946 |
| 8963 return SECSuccess; | 8947 return SECSuccess; |
| 8964 } | 8948 } |
| 8965 | 8949 |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9310 * | 9294 * |
| 9311 * If cText is NULL, then the ciphertext has previously been deciphered and | 9295 * If cText is NULL, then the ciphertext has previously been deciphered and |
| 9312 * checked, and is already sitting in databuf. It is processed as an SSL | 9296 * checked, and is already sitting in databuf. It is processed as an SSL |
| 9313 * Handshake message. | 9297 * Handshake message. |
| 9314 * | 9298 * |
| 9315 * DOES NOT process the decrypted/decompressed application data. | 9299 * DOES NOT process the decrypted/decompressed application data. |
| 9316 * On return, databuf contains the decrypted/decompressed record. | 9300 * On return, databuf contains the decrypted/decompressed record. |
| 9317 * | 9301 * |
| 9318 * Called from ssl3_GatherCompleteHandshake | 9302 * Called from ssl3_GatherCompleteHandshake |
| 9319 * ssl3_RestartHandshakeAfterCertReq | 9303 * ssl3_RestartHandshakeAfterCertReq |
| 9320 * ssl3_RestartHandshakeAfterServerCert | |
| 9321 * | 9304 * |
| 9322 * Caller must hold the RecvBufLock. | 9305 * Caller must hold the RecvBufLock. |
| 9323 * | 9306 * |
| 9324 * This function aquires and releases the SSL3Handshake Lock, holding the | 9307 * This function aquires and releases the SSL3Handshake Lock, holding the |
| 9325 * lock around any calls to functions that handle records other than | 9308 * lock around any calls to functions that handle records other than |
| 9326 * Application Data records. | 9309 * Application Data records. |
| 9327 */ | 9310 */ |
| 9328 SECStatus | 9311 SECStatus |
| 9329 ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) | 9312 ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) |
| 9330 { | 9313 { |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9660 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | 9643 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
| 9661 | 9644 |
| 9662 if (ss->ssl3.initialized) | 9645 if (ss->ssl3.initialized) |
| 9663 return SECSuccess; /* Function should be idempotent */ | 9646 return SECSuccess; /* Function should be idempotent */ |
| 9664 | 9647 |
| 9665 ss->ssl3.policy = SSL_ALLOWED; | 9648 ss->ssl3.policy = SSL_ALLOWED; |
| 9666 | 9649 |
| 9667 ssl_GetSpecWriteLock(ss); | 9650 ssl_GetSpecWriteLock(ss); |
| 9668 ss->ssl3.crSpec = ss->ssl3.cwSpec = &ss->ssl3.specs[0]; | 9651 ss->ssl3.crSpec = ss->ssl3.cwSpec = &ss->ssl3.specs[0]; |
| 9669 ss->ssl3.prSpec = ss->ssl3.pwSpec = &ss->ssl3.specs[1]; | 9652 ss->ssl3.prSpec = ss->ssl3.pwSpec = &ss->ssl3.specs[1]; |
| 9670 ss->ssl3.hs.rehandshake = PR_FALSE; | |
| 9671 ss->ssl3.hs.sendingSCSV = PR_FALSE; | 9653 ss->ssl3.hs.sendingSCSV = PR_FALSE; |
| 9672 ssl3_InitCipherSpec(ss, ss->ssl3.crSpec); | 9654 ssl3_InitCipherSpec(ss, ss->ssl3.crSpec); |
| 9673 ssl3_InitCipherSpec(ss, ss->ssl3.prSpec); | 9655 ssl3_InitCipherSpec(ss, ss->ssl3.prSpec); |
| 9674 | 9656 |
| 9675 ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello; | 9657 ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello; |
| 9676 #ifdef NSS_ENABLE_ECC | 9658 #ifdef NSS_ENABLE_ECC |
| 9677 ss->ssl3.hs.negotiatedECCurves = SSL3_SUPPORTED_CURVES_MASK; | 9659 ss->ssl3.hs.negotiatedECCurves = SSL3_SUPPORTED_CURVES_MASK; |
| 9678 #endif | 9660 #endif |
| 9679 ssl_ReleaseSpecWriteLock(ss); | 9661 ssl_ReleaseSpecWriteLock(ss); |
| 9680 | 9662 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9769 ssl3_SetPolicy(ssl3CipherSuite which, int policy) | 9751 ssl3_SetPolicy(ssl3CipherSuite which, int policy) |
| 9770 { | 9752 { |
| 9771 ssl3CipherSuiteCfg *suite; | 9753 ssl3CipherSuiteCfg *suite; |
| 9772 | 9754 |
| 9773 suite = ssl_LookupCipherSuiteCfg(which, cipherSuites); | 9755 suite = ssl_LookupCipherSuiteCfg(which, cipherSuites); |
| 9774 if (suite == NULL) { | 9756 if (suite == NULL) { |
| 9775 return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */ | 9757 return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */ |
| 9776 } | 9758 } |
| 9777 suite->policy = policy; | 9759 suite->policy = policy; |
| 9778 | 9760 |
| 9779 if (policy == SSL_RESTRICTED) { | |
| 9780 ssl3_global_policy_some_restricted = PR_TRUE; | |
| 9781 } | |
| 9782 | |
| 9783 return SECSuccess; | 9761 return SECSuccess; |
| 9784 } | 9762 } |
| 9785 | 9763 |
| 9786 SECStatus | 9764 SECStatus |
| 9787 ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *oPolicy) | 9765 ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *oPolicy) |
| 9788 { | 9766 { |
| 9789 ssl3CipherSuiteCfg *suite; | 9767 ssl3CipherSuiteCfg *suite; |
| 9790 PRInt32 policy; | 9768 PRInt32 policy; |
| 9791 SECStatus rv; | 9769 SECStatus rv; |
| 9792 | 9770 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9949 ssl_GetXmitBufLock(ss); /**************************************/ | 9927 ssl_GetXmitBufLock(ss); /**************************************/ |
| 9950 | 9928 |
| 9951 /* start off a new handshake. */ | 9929 /* start off a new handshake. */ |
| 9952 rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss) | 9930 rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss) |
| 9953 : ssl3_SendClientHello(ss); | 9931 : ssl3_SendClientHello(ss); |
| 9954 | 9932 |
| 9955 ssl_ReleaseXmitBufLock(ss); /**************************************/ | 9933 ssl_ReleaseXmitBufLock(ss); /**************************************/ |
| 9956 return rv; | 9934 return rv; |
| 9957 } | 9935 } |
| 9958 | 9936 |
| 9959 static void | |
| 9960 ssl3_CleanupPredictedPeerCertificates(sslSocket *ss) { | |
| 9961 unsigned int i; | |
| 9962 | |
| 9963 if (!ss->ssl3.predictedCertChain) | |
| 9964 return; | |
| 9965 | |
| 9966 for (i = 0; ss->ssl3.predictedCertChain[i]; i++) { | |
| 9967 CERT_DestroyCertificate(ss->ssl3.predictedCertChain[i]); | |
| 9968 } | |
| 9969 | |
| 9970 PORT_Free(ss->ssl3.predictedCertChain); | |
| 9971 ss->ssl3.predictedCertChain = NULL; | |
| 9972 } | |
| 9973 | |
| 9974 /* Called from ssl_DestroySocketContents() in sslsock.c */ | 9937 /* Called from ssl_DestroySocketContents() in sslsock.c */ |
| 9975 void | 9938 void |
| 9976 ssl3_DestroySSL3Info(sslSocket *ss) | 9939 ssl3_DestroySSL3Info(sslSocket *ss) |
| 9977 { | 9940 { |
| 9978 | 9941 |
| 9979 if (ss->ssl3.clientCertificate != NULL) | 9942 if (ss->ssl3.clientCertificate != NULL) |
| 9980 CERT_DestroyCertificate(ss->ssl3.clientCertificate); | 9943 CERT_DestroyCertificate(ss->ssl3.clientCertificate); |
| 9981 | 9944 |
| 9982 if (ss->ssl3.clientPrivateKey != NULL) | 9945 if (ss->ssl3.clientPrivateKey != NULL) |
| 9983 SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); | 9946 SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); |
| 9984 #ifdef NSS_PLATFORM_CLIENT_AUTH | 9947 #ifdef NSS_PLATFORM_CLIENT_AUTH |
| 9985 if (ss->ssl3.platformClientKey) | 9948 if (ss->ssl3.platformClientKey) |
| 9986 ssl_FreePlatformKey(ss->ssl3.platformClientKey); | 9949 ssl_FreePlatformKey(ss->ssl3.platformClientKey); |
| 9987 #endif /* NSS_PLATFORM_CLIENT_AUTH */ | 9950 #endif /* NSS_PLATFORM_CLIENT_AUTH */ |
| 9988 | 9951 |
| 9989 if (ss->ssl3.peerCertArena != NULL) | 9952 if (ss->ssl3.peerCertArena != NULL) |
| 9990 ssl3_CleanupPeerCerts(ss); | 9953 ssl3_CleanupPeerCerts(ss); |
| 9991 | 9954 |
| 9992 if (ss->ssl3.clientCertChain != NULL) { | 9955 if (ss->ssl3.clientCertChain != NULL) { |
| 9993 CERT_DestroyCertificateList(ss->ssl3.clientCertChain); | 9956 CERT_DestroyCertificateList(ss->ssl3.clientCertChain); |
| 9994 ss->ssl3.clientCertChain = NULL; | 9957 ss->ssl3.clientCertChain = NULL; |
| 9995 } | 9958 } |
| 9996 | 9959 |
| 9997 if (ss->ssl3.predictedCertChain != NULL) | |
| 9998 ssl3_CleanupPredictedPeerCertificates(ss); | |
| 9999 | |
| 10000 /* clean up handshake */ | 9960 /* clean up handshake */ |
| 10001 if (ss->opt.bypassPKCS11) { | 9961 if (ss->opt.bypassPKCS11) { |
| 10002 SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE); | 9962 SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE); |
| 10003 MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE); | 9963 MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE); |
| 10004 } | 9964 } |
| 10005 if (ss->ssl3.hs.md5) { | 9965 if (ss->ssl3.hs.md5) { |
| 10006 PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE); | 9966 PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE); |
| 10007 } | 9967 } |
| 10008 if (ss->ssl3.hs.sha) { | 9968 if (ss->ssl3.hs.sha) { |
| 10009 PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE); | 9969 PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 10023 | 9983 |
| 10024 /* free the SSL3Buffer (msg_body) */ | 9984 /* free the SSL3Buffer (msg_body) */ |
| 10025 PORT_Free(ss->ssl3.hs.msg_body.buf); | 9985 PORT_Free(ss->ssl3.hs.msg_body.buf); |
| 10026 | 9986 |
| 10027 /* free up the CipherSpecs */ | 9987 /* free up the CipherSpecs */ |
| 10028 ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE/*freeSrvName*/); | 9988 ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE/*freeSrvName*/); |
| 10029 ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/); | 9989 ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/); |
| 10030 | 9990 |
| 10031 ss->ssl3.initialized = PR_FALSE; | 9991 ss->ssl3.initialized = PR_FALSE; |
| 10032 | 9992 |
| 10033 if (ss->ssl3.nextProto.data) { | 9993 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); |
| 10034 » PORT_Free(ss->ssl3.nextProto.data); | |
| 10035 » ss->ssl3.nextProto.data = NULL; | |
| 10036 } | |
| 10037 } | 9994 } |
| 10038 | 9995 |
| 10039 /* End of ssl3con.c */ | 9996 /* End of ssl3con.c */ |
| OLD | NEW |