security/nss/lib/ssl/sslinfo.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 #include "ssl.h"
     5 #include "sslimpl.h"
     6 #include "sslproto.h"
     8 static const char *
     9 ssl_GetCompressionMethodName(SSLCompressionMethod compression)
    10 {
    11     switch (compression) {
    12     case ssl_compression_null:
    13 	return "NULL";
    14 #ifdef NSS_ENABLE_ZLIB
    15     case ssl_compression_deflate:
    16 	return "DEFLATE";
    17 #endif
    18     default:
    19 	return "???";
    20     }
    21 }
    23 SECStatus 
    24 SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
    25 {
    26     sslSocket *      ss;
    27     SSLChannelInfo   inf;
    28     sslSessionID *   sid;
    30     if (!info || len < sizeof inf.length) { 
    31 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
    32 	return SECFailure;
    33     }
    35     ss = ssl_FindSocket(fd);
    36     if (!ss) {
    37 	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
    38 		 SSL_GETPID(), fd));
    39 	return SECFailure;
    40     }
    42     memset(&inf, 0, sizeof inf);
    43     inf.length = PR_MIN(sizeof inf, len);
    45     if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
    46         sid = ss->sec.ci.sid;
    47 	inf.protocolVersion  = ss->version;
    48 	inf.authKeyBits      = ss->sec.authKeyBits;
    49 	inf.keaKeyBits       = ss->sec.keaKeyBits;
    50 	if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
    51 	    inf.cipherSuite           = ss->sec.cipherType | 0xff00;
    52 	    inf.compressionMethod     = ssl_compression_null;
    53 	    inf.compressionMethodName = "N/A";
    54 	} else if (ss->ssl3.initialized) { 	/* SSL3 and TLS */
    55 	    ssl_GetSpecReadLock(ss);
    56 	    /* XXX  The cipher suite should be in the specs and this
    57 	     * function should get it from cwSpec rather than from the "hs".
    58 	     * See bug 275744 comment 69 and bug 766137.
    59 	     */
    60 	    inf.cipherSuite           = ss->ssl3.hs.cipher_suite;
    61 	    inf.compressionMethod     = ss->ssl3.cwSpec->compression_method;
    62 	    ssl_ReleaseSpecReadLock(ss);
    63 	    inf.compressionMethodName =
    64 		ssl_GetCompressionMethodName(inf.compressionMethod);
    65 	}
    66 	if (sid) {
    67 	    inf.creationTime   = sid->creationTime;
    68 	    inf.lastAccessTime = sid->lastAccessTime;
    69 	    inf.expirationTime = sid->expirationTime;
    70 	    if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
    71 	        inf.sessionIDLength = SSL2_SESSIONID_BYTES;
    72 		memcpy(inf.sessionID, sid->u.ssl2.sessionID, 
    73 		       SSL2_SESSIONID_BYTES);
    74 	    } else {
    75 		unsigned int sidLen = sid->u.ssl3.sessionIDLength;
    76 	        sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
    77 	        inf.sessionIDLength = sidLen;
    78 		memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen);
    79 	    }
    80 	}
    81     }
    83     memcpy(info, &inf, inf.length);
    85     return SECSuccess;
    86 }
    89 #define CS(x) x, #x
    90 #define CK(x) x | 0xff00, #x
    92 #define S_DSA   "DSA", ssl_auth_dsa
    93 #define S_RSA	"RSA", ssl_auth_rsa
    94 #define S_KEA   "KEA", ssl_auth_kea
    95 #define S_ECDSA "ECDSA", ssl_auth_ecdsa
    97 #define K_DHE	"DHE", kt_dh
    98 #define K_RSA	"RSA", kt_rsa
    99 #define K_KEA	"KEA", kt_kea
   100 #define K_ECDH	"ECDH", kt_ecdh
   101 #define K_ECDHE	"ECDHE", kt_ecdh
   103 #define C_SEED 	"SEED", calg_seed
   104 #define C_CAMELLIA "CAMELLIA", calg_camellia
   105 #define C_AES	"AES", calg_aes
   106 #define C_RC4	"RC4", calg_rc4
   107 #define C_RC2	"RC2", calg_rc2
   108 #define C_DES	"DES", calg_des
   109 #define C_3DES	"3DES", calg_3des
   110 #define C_NULL  "NULL", calg_null
   111 #define C_SJ 	"SKIPJACK", calg_sj
   112 #define C_AESGCM "AES-GCM", calg_aes_gcm
   114 #define B_256	256, 256, 256
   115 #define B_128	128, 128, 128
   116 #define B_3DES  192, 156, 112
   117 #define B_SJ     96,  80,  80
   118 #define B_DES    64,  56,  56
   119 #define B_56    128,  56,  56
   120 #define B_40    128,  40,  40
   121 #define B_0  	  0,   0,   0
   123 #define M_AEAD_128 "AEAD", ssl_mac_aead, 128
   124 #define M_SHA256 "SHA256", ssl_hmac_sha256, 256
   125 #define M_SHA	"SHA1", ssl_mac_sha, 160
   126 #define M_MD5	"MD5",  ssl_mac_md5, 128
   127 #define M_NULL	"NULL", ssl_mac_null,  0
   129 static const SSLCipherSuiteInfo suiteInfo[] = {
   130 /* <------ Cipher suite --------------------> <auth> <KEA>  <bulk cipher> <MAC> <FIPS> */
   131 {0,CS(TLS_RSA_WITH_AES_128_GCM_SHA256),       S_RSA, K_RSA, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
   133 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
   134 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
   135 {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256),   S_RSA, K_DHE, C_AES, B_256, M_SHA256, 1, 0, 0, },
   136 {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA),      S_RSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
   137 {0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA),      S_DSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
   138 {0,CS(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA),     S_RSA, K_RSA, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
   139 {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA256),       S_RSA, K_RSA, C_AES, B_256, M_SHA256, 1, 0, 0, },
   140 {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA),          S_RSA, K_RSA, C_AES, B_256, M_SHA, 1, 0, 0, },
   142 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
   143 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
   144 {0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA),          S_DSA, K_DHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
   145 {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256),   S_RSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0, },
   146 {0,CS(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256),   S_RSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
   147 {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA),      S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
   148 {0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA),      S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
   149 {0,CS(TLS_RSA_WITH_SEED_CBC_SHA),             S_RSA, K_RSA, C_SEED,B_128, M_SHA, 1, 0, 0, },
   150 {0,CS(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA),     S_RSA, K_RSA, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
   151 {0,CS(TLS_RSA_WITH_RC4_128_SHA),              S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0, },
   152 {0,CS(TLS_RSA_WITH_RC4_128_MD5),              S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
   153 {0,CS(TLS_RSA_WITH_AES_128_CBC_SHA256),       S_RSA, K_RSA, C_AES, B_128, M_SHA256, 1, 0, 0, },
   154 {0,CS(TLS_RSA_WITH_AES_128_CBC_SHA),          S_RSA, K_RSA, C_AES, B_128, M_SHA, 1, 0, 0, },
   156 {0,CS(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA),     S_RSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
   157 {0,CS(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA),     S_DSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
   158 {0,CS(SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA),    S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 1, },
   159 {0,CS(TLS_RSA_WITH_3DES_EDE_CBC_SHA),         S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
   161 {0,CS(TLS_DHE_RSA_WITH_DES_CBC_SHA),          S_RSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
   162 {0,CS(TLS_DHE_DSS_WITH_DES_CBC_SHA),          S_DSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
   163 {0,CS(SSL_RSA_FIPS_WITH_DES_CBC_SHA),         S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 1, },
   164 {0,CS(TLS_RSA_WITH_DES_CBC_SHA),              S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 0, },
   166 {0,CS(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA),    S_RSA, K_RSA, C_RC4, B_56,  M_SHA, 0, 1, 0, },
   167 {0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA),   S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 1, 0, },
   168 {0,CS(TLS_RSA_EXPORT_WITH_RC4_40_MD5),        S_RSA, K_RSA, C_RC4, B_40,  M_MD5, 0, 1, 0, },
   169 {0,CS(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5),    S_RSA, K_RSA, C_RC2, B_40,  M_MD5, 0, 1, 0, },
   170 {0,CS(TLS_RSA_WITH_NULL_SHA256),              S_RSA, K_RSA, C_NULL,B_0,   M_SHA256, 0, 1, 0, },
   171 {0,CS(TLS_RSA_WITH_NULL_SHA),                 S_RSA, K_RSA, C_NULL,B_0,   M_SHA, 0, 1, 0, },
   172 {0,CS(TLS_RSA_WITH_NULL_MD5),                 S_RSA, K_RSA, C_NULL,B_0,   M_MD5, 0, 1, 0, },
   174 #ifndef NSS_DISABLE_ECC
   175 /* ECC cipher suites */
   176 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
   177 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), S_ECDSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
   179 {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA),          S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
   180 {0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA),       S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
   181 {0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA),  S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
   182 {0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA),   S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, },
   183 {0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA),   S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, },
   185 {0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA),         S_ECDSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, },
   186 {0,CS(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA),      S_ECDSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
   187 {0,CS(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
   188 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA),  S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
   189 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA256, 1, 0, 0, },
   190 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA),  S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, },
   192 {0,CS(TLS_ECDH_RSA_WITH_NULL_SHA),            S_RSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
   193 {0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA),         S_RSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
   194 {0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA),    S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
   195 {0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA),     S_RSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, },
   196 {0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA),     S_RSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, },
   198 {0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA),           S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, },
   199 {0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA),        S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
   200 {0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA),   S_RSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
   201 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA),    S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
   202 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_ECDHE, C_AES, B_128, M_SHA256, 1, 0, 0, },
   203 {0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),    S_RSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, },
   204 #endif /* NSS_DISABLE_ECC */
   206 /* SSL 2 table */
   207 {0,CK(SSL_CK_RC4_128_WITH_MD5),               S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
   208 {0,CK(SSL_CK_RC2_128_CBC_WITH_MD5),           S_RSA, K_RSA, C_RC2, B_128, M_MD5, 0, 0, 0, },
   209 {0,CK(SSL_CK_DES_192_EDE3_CBC_WITH_MD5),      S_RSA, K_RSA, C_3DES,B_3DES,M_MD5, 0, 0, 0, },
   210 {0,CK(SSL_CK_DES_64_CBC_WITH_MD5),            S_RSA, K_RSA, C_DES, B_DES, M_MD5, 0, 0, 0, },
   211 {0,CK(SSL_CK_RC4_128_EXPORT40_WITH_MD5),      S_RSA, K_RSA, C_RC4, B_40,  M_MD5, 0, 1, 0, },
   212 {0,CK(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5),  S_RSA, K_RSA, C_RC2, B_40,  M_MD5, 0, 1, 0, }
   213 };
   215 #define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0]))
   218 SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite, 
   219                                  SSLCipherSuiteInfo *info, PRUintn len)
   220 {
   221     unsigned int i;
   223     len = PR_MIN(len, sizeof suiteInfo[0]);
   224     if (!info || len < sizeof suiteInfo[0].length) {
   225 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
   226     	return SECFailure;
   227     }
   228     for (i = 0; i < NUM_SUITEINFOS; i++) {
   229     	if (suiteInfo[i].cipherSuite == cipherSuite) {
   230 	    memcpy(info, &suiteInfo[i], len);
   231 	    info->length = len;
   232 	    return SECSuccess;
   233 	}
   234     }
   235     PORT_SetError(SEC_ERROR_INVALID_ARGS);
   236     return SECFailure;
   237 }
   239 /* This function might be a candidate to be public. 
   240  * Disables all export ciphers in the default set of enabled ciphers.
   241  */
   242 SECStatus 
   243 SSL_DisableDefaultExportCipherSuites(void)
   244 {
   245     const SSLCipherSuiteInfo * pInfo = suiteInfo;
   246     unsigned int i;
   247     SECStatus rv;
   249     for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
   250     	if (pInfo->isExportable) {
   251 	    rv = SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FALSE);
   252 	    PORT_Assert(rv == SECSuccess);
   253 	}
   254     }
   255     return SECSuccess;
   256 }
   258 /* This function might be a candidate to be public, 
   259  * except that it takes an sslSocket pointer as an argument.
   260  * A Public version would take a PRFileDesc pointer.
   261  * Disables all export ciphers in the default set of enabled ciphers.
   262  */
   263 SECStatus 
   264 SSL_DisableExportCipherSuites(PRFileDesc * fd)
   265 {
   266     const SSLCipherSuiteInfo * pInfo = suiteInfo;
   267     unsigned int i;
   268     SECStatus rv;
   270     for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
   271     	if (pInfo->isExportable) {
   272 	    rv = SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE);
   273 	    PORT_Assert(rv == SECSuccess);
   274 	}
   275     }
   276     return SECSuccess;
   277 }
   279 /* Tells us if the named suite is exportable 
   280  * returns false for unknown suites.
   281  */
   282 PRBool
   283 SSL_IsExportCipherSuite(PRUint16 cipherSuite)
   284 {
   285     unsigned int i;
   286     for (i = 0; i < NUM_SUITEINFOS; i++) {
   287     	if (suiteInfo[i].cipherSuite == cipherSuite) {
   288 	    return (PRBool)(suiteInfo[i].isExportable);
   289 	}
   290     }
   291     return PR_FALSE;
   292 }
   294 SECItem*
   295 SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
   296 {
   297     SECItem *sniName = NULL;
   298     sslSocket *ss;
   299     char *name = NULL;
   301     ss = ssl_FindSocket(fd);
   302     if (!ss) {
   303 	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo",
   304 		 SSL_GETPID(), fd));
   305 	return NULL;
   306     }
   308     if (ss->sec.isServer) {
   309         if (ss->version > SSL_LIBRARY_VERSION_3_0 &&
   310             ss->ssl3.initialized) { /* TLS */
   311             SECItem *crsName;
   312             ssl_GetSpecReadLock(ss); /*********************************/
   313             crsName = &ss->ssl3.cwSpec->srvVirtName;
   314             if (crsName->data) {
   315                 sniName = SECITEM_DupItem(crsName);
   316             }
   317             ssl_ReleaseSpecReadLock(ss); /*----------------------------*/
   318         }
   319         return sniName;
   320     } 
   321     name = SSL_RevealURL(fd);
   322     if (name) {
   323         sniName = PORT_ZNew(SECItem);
   324         if (!sniName) {
   325             PORT_Free(name);
   326             return NULL;
   327         }
   328         sniName->data = (void*)name;
   329         sniName->len  = PORT_Strlen(name);
   330     }
   331     return sniName;
   332 }
   334 SECStatus
   335 SSL_ExportKeyingMaterial(PRFileDesc *fd,
   336                          const char *label, unsigned int labelLen,
   337                          PRBool hasContext,
   338                          const unsigned char *context, unsigned int contextLen,
   339                          unsigned char *out, unsigned int outLen)
   340 {
   341     sslSocket *ss;
   342     unsigned char *val = NULL;
   343     unsigned int valLen, i;
   344     SECStatus rv = SECFailure;
   346     ss = ssl_FindSocket(fd);
   347     if (!ss) {
   348 	SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
   349 		 SSL_GETPID(), fd));
   350 	return SECFailure;
   351     }
   353     if (ss->version < SSL_LIBRARY_VERSION_3_1_TLS) {
   354 	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
   355 	return SECFailure;
   356     }
   358     /* construct PRF arguments */
   359     valLen = SSL3_RANDOM_LENGTH * 2;
   360     if (hasContext) {
   361 	valLen += 2 /* PRUint16 length */ + contextLen;
   362     }
   363     val = PORT_Alloc(valLen);
   364     if (!val) {
   365 	return SECFailure;
   366     }
   367     i = 0;
   368     PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
   369     i += SSL3_RANDOM_LENGTH;
   370     PORT_Memcpy(val + i, &ss->ssl3.hs.server_random.rand, SSL3_RANDOM_LENGTH);
   371     i += SSL3_RANDOM_LENGTH;
   372     if (hasContext) {
   373 	val[i++] = contextLen >> 8;
   374 	val[i++] = contextLen;
   375 	PORT_Memcpy(val + i, context, contextLen);
   376 	i += contextLen;
   377     }
   378     PORT_Assert(i == valLen);
   380     /* Allow TLS keying material to be exported sooner, when the master
   381      * secret is available and we have sent ChangeCipherSpec.
   382      */
   383     ssl_GetSpecReadLock(ss);
   384     if (!ss->ssl3.cwSpec->master_secret && !ss->ssl3.cwSpec->msItem.len) {
   385 	PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
   386 	rv = SECFailure;
   387     } else {
   388 	rv = ssl3_TLSPRFWithMasterSecret(ss->ssl3.cwSpec, label, labelLen, val,
   389 					 valLen, out, outLen);
   390     }
   391     ssl_ReleaseSpecReadLock(ss);
   393     PORT_ZFree(val, valLen);
   394     return rv;
   395 }

mercurial