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 /* $Id: sslinfo.c,v 1.31 2012/08/03 23:54:31 wtc%google.com Exp $ */
10 ssl_GetCompressionMethodName(SSLCompressionMethod compression
)
12 switch (compression
) {
13 case ssl_compression_null
:
15 #ifdef NSS_ENABLE_ZLIB
16 case ssl_compression_deflate
:
25 SSL_GetChannelInfo(PRFileDesc
*fd
, SSLChannelInfo
*info
, PRUintn len
)
30 PRBool enoughFirstHsDone
= PR_FALSE
;
32 if (!info
|| len
< sizeof inf
.length
) {
33 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
37 ss
= ssl_FindSocket(fd
);
39 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
44 memset(&inf
, 0, sizeof inf
);
45 inf
.length
= PR_MIN(sizeof inf
, len
);
47 if (ss
->firstHsDone
) {
48 enoughFirstHsDone
= PR_TRUE
;
49 } else if (ss
->version
>= SSL_LIBRARY_VERSION_3_0
&&
50 ssl3_CanFalseStart(ss
)) {
51 enoughFirstHsDone
= PR_TRUE
;
54 if (ss
->opt
.useSecurity
&& enoughFirstHsDone
) {
56 inf
.protocolVersion
= ss
->version
;
57 inf
.authKeyBits
= ss
->sec
.authKeyBits
;
58 inf
.keaKeyBits
= ss
->sec
.keaKeyBits
;
59 if (ss
->version
< SSL_LIBRARY_VERSION_3_0
) { /* SSL2 */
60 inf
.cipherSuite
= ss
->sec
.cipherType
| 0xff00;
61 inf
.compressionMethod
= ssl_compression_null
;
62 inf
.compressionMethodName
= "N/A";
63 } else if (ss
->ssl3
.initialized
) { /* SSL3 and TLS */
64 ssl_GetSpecReadLock(ss
);
65 /* XXX The cipher suite should be in the specs and this
66 * function should get it from cwSpec rather than from the "hs".
67 * See bug 275744 comment 69 and bug 766137.
69 inf
.cipherSuite
= ss
->ssl3
.hs
.cipher_suite
;
70 inf
.compressionMethod
= ss
->ssl3
.cwSpec
->compression_method
;
71 ssl_ReleaseSpecReadLock(ss
);
72 inf
.compressionMethodName
=
73 ssl_GetCompressionMethodName(inf
.compressionMethod
);
76 inf
.creationTime
= sid
->creationTime
;
77 inf
.lastAccessTime
= sid
->lastAccessTime
;
78 inf
.expirationTime
= sid
->expirationTime
;
79 if (ss
->version
< SSL_LIBRARY_VERSION_3_0
) { /* SSL2 */
80 inf
.sessionIDLength
= SSL2_SESSIONID_BYTES
;
81 memcpy(inf
.sessionID
, sid
->u
.ssl2
.sessionID
,
82 SSL2_SESSIONID_BYTES
);
84 unsigned int sidLen
= sid
->u
.ssl3
.sessionIDLength
;
85 sidLen
= PR_MIN(sidLen
, sizeof inf
.sessionID
);
86 inf
.sessionIDLength
= sidLen
;
87 memcpy(inf
.sessionID
, sid
->u
.ssl3
.sessionID
, sidLen
);
92 memcpy(info
, &inf
, inf
.length
);
99 #define CK(x) x | 0xff00, #x
101 #define S_DSA "DSA", ssl_auth_dsa
102 #define S_RSA "RSA", ssl_auth_rsa
103 #define S_KEA "KEA", ssl_auth_kea
104 #define S_ECDSA "ECDSA", ssl_auth_ecdsa
106 #define K_DHE "DHE", kt_dh
107 #define K_RSA "RSA", kt_rsa
108 #define K_KEA "KEA", kt_kea
109 #define K_ECDH "ECDH", kt_ecdh
110 #define K_ECDHE "ECDHE", kt_ecdh
112 #define C_SEED "SEED", calg_seed
113 #define C_CAMELLIA "CAMELLIA", calg_camellia
114 #define C_AES "AES", calg_aes
115 #define C_RC4 "RC4", calg_rc4
116 #define C_RC2 "RC2", calg_rc2
117 #define C_DES "DES", calg_des
118 #define C_3DES "3DES", calg_3des
119 #define C_NULL "NULL", calg_null
120 #define C_SJ "SKIPJACK", calg_sj
122 #define B_256 256, 256, 256
123 #define B_128 128, 128, 128
124 #define B_3DES 192, 156, 112
125 #define B_SJ 96, 80, 80
126 #define B_DES 64, 56, 56
127 #define B_56 128, 56, 56
128 #define B_40 128, 40, 40
131 #define M_SHA "SHA1", ssl_mac_sha, 160
132 #define M_MD5 "MD5", ssl_mac_md5, 128
134 static const SSLCipherSuiteInfo suiteInfo
[] = {
135 /* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */
136 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
), S_RSA
, K_DHE
, C_CAMELLIA
, B_256
, M_SHA
, 0, 0, 0, },
137 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA
), S_DSA
, K_DHE
, C_CAMELLIA
, B_256
, M_SHA
, 0, 0, 0, },
138 {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA
), S_RSA
, K_DHE
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
139 {0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA
), S_DSA
, K_DHE
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
140 {0,CS(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
), S_RSA
, K_RSA
, C_CAMELLIA
, B_256
, M_SHA
, 0, 0, 0, },
141 {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA
), S_RSA
, K_RSA
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
143 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
), S_RSA
, K_DHE
, C_CAMELLIA
, B_128
, M_SHA
, 0, 0, 0, },
144 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA
), S_DSA
, K_DHE
, C_CAMELLIA
, B_128
, M_SHA
, 0, 0, 0, },
145 {0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA
), S_DSA
, K_DHE
, C_RC4
, B_128
, M_SHA
, 0, 0, 0, },
146 {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA
), S_RSA
, K_DHE
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
147 {0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA
), S_DSA
, K_DHE
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
148 {0,CS(TLS_RSA_WITH_SEED_CBC_SHA
), S_RSA
, K_RSA
, C_SEED
,B_128
, M_SHA
, 1, 0, 0, },
149 {0,CS(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
), S_RSA
, K_RSA
, C_CAMELLIA
, B_128
, M_SHA
, 0, 0, 0, },
150 {0,CS(SSL_RSA_WITH_RC4_128_SHA
), S_RSA
, K_RSA
, C_RC4
, B_128
, M_SHA
, 0, 0, 0, },
151 {0,CS(SSL_RSA_WITH_RC4_128_MD5
), S_RSA
, K_RSA
, C_RC4
, B_128
, M_MD5
, 0, 0, 0, },
152 {0,CS(TLS_RSA_WITH_AES_128_CBC_SHA
), S_RSA
, K_RSA
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
154 {0,CS(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
), S_RSA
, K_DHE
, C_3DES
,B_3DES
,M_SHA
, 1, 0, 0, },
155 {0,CS(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
), S_DSA
, K_DHE
, C_3DES
,B_3DES
,M_SHA
, 1, 0, 0, },
156 {0,CS(SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA
), S_RSA
, K_RSA
, C_3DES
,B_3DES
,M_SHA
, 1, 0, 1, },
157 {0,CS(SSL_RSA_WITH_3DES_EDE_CBC_SHA
), S_RSA
, K_RSA
, C_3DES
,B_3DES
,M_SHA
, 1, 0, 0, },
159 {0,CS(SSL_DHE_RSA_WITH_DES_CBC_SHA
), S_RSA
, K_DHE
, C_DES
, B_DES
, M_SHA
, 0, 0, 0, },
160 {0,CS(SSL_DHE_DSS_WITH_DES_CBC_SHA
), S_DSA
, K_DHE
, C_DES
, B_DES
, M_SHA
, 0, 0, 0, },
161 {0,CS(SSL_RSA_FIPS_WITH_DES_CBC_SHA
), S_RSA
, K_RSA
, C_DES
, B_DES
, M_SHA
, 0, 0, 1, },
162 {0,CS(SSL_RSA_WITH_DES_CBC_SHA
), S_RSA
, K_RSA
, C_DES
, B_DES
, M_SHA
, 0, 0, 0, },
164 {0,CS(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA
), S_RSA
, K_RSA
, C_RC4
, B_56
, M_SHA
, 0, 1, 0, },
165 {0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA
), S_RSA
, K_RSA
, C_DES
, B_DES
, M_SHA
, 0, 1, 0, },
166 {0,CS(SSL_RSA_EXPORT_WITH_RC4_40_MD5
), S_RSA
, K_RSA
, C_RC4
, B_40
, M_MD5
, 0, 1, 0, },
167 {0,CS(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
), S_RSA
, K_RSA
, C_RC2
, B_40
, M_MD5
, 0, 1, 0, },
168 {0,CS(SSL_RSA_WITH_NULL_SHA
), S_RSA
, K_RSA
, C_NULL
,B_0
, M_SHA
, 0, 1, 0, },
169 {0,CS(SSL_RSA_WITH_NULL_MD5
), S_RSA
, K_RSA
, C_NULL
,B_0
, M_MD5
, 0, 1, 0, },
171 #ifdef NSS_ENABLE_ECC
172 /* ECC cipher suites */
173 {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA
), S_ECDSA
, K_ECDH
, C_NULL
, B_0
, M_SHA
, 0, 0, 0, },
174 {0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA
), S_ECDSA
, K_ECDH
, C_RC4
, B_128
, M_SHA
, 0, 0, 0, },
175 {0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
), S_ECDSA
, K_ECDH
, C_3DES
, B_3DES
, M_SHA
, 1, 0, 0, },
176 {0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
), S_ECDSA
, K_ECDH
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
177 {0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
), S_ECDSA
, K_ECDH
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
179 {0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA
), S_ECDSA
, K_ECDHE
, C_NULL
, B_0
, M_SHA
, 0, 0, 0, },
180 {0,CS(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
), S_ECDSA
, K_ECDHE
, C_RC4
, B_128
, M_SHA
, 0, 0, 0, },
181 {0,CS(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
), S_ECDSA
, K_ECDHE
, C_3DES
, B_3DES
, M_SHA
, 1, 0, 0, },
182 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
), S_ECDSA
, K_ECDHE
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
183 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
), S_ECDSA
, K_ECDHE
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
185 {0,CS(TLS_ECDH_RSA_WITH_NULL_SHA
), S_RSA
, K_ECDH
, C_NULL
, B_0
, M_SHA
, 0, 0, 0, },
186 {0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA
), S_RSA
, K_ECDH
, C_RC4
, B_128
, M_SHA
, 0, 0, 0, },
187 {0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
), S_RSA
, K_ECDH
, C_3DES
, B_3DES
, M_SHA
, 1, 0, 0, },
188 {0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
), S_RSA
, K_ECDH
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
189 {0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
), S_RSA
, K_ECDH
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
191 {0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA
), S_RSA
, K_ECDHE
, C_NULL
, B_0
, M_SHA
, 0, 0, 0, },
192 {0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA
), S_RSA
, K_ECDHE
, C_RC4
, B_128
, M_SHA
, 0, 0, 0, },
193 {0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
), S_RSA
, K_ECDHE
, C_3DES
, B_3DES
, M_SHA
, 1, 0, 0, },
194 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
), S_RSA
, K_ECDHE
, C_AES
, B_128
, M_SHA
, 1, 0, 0, },
195 {0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
), S_RSA
, K_ECDHE
, C_AES
, B_256
, M_SHA
, 1, 0, 0, },
196 #endif /* NSS_ENABLE_ECC */
199 {0,CK(SSL_CK_RC4_128_WITH_MD5
), S_RSA
, K_RSA
, C_RC4
, B_128
, M_MD5
, 0, 0, 0, },
200 {0,CK(SSL_CK_RC2_128_CBC_WITH_MD5
), S_RSA
, K_RSA
, C_RC2
, B_128
, M_MD5
, 0, 0, 0, },
201 {0,CK(SSL_CK_DES_192_EDE3_CBC_WITH_MD5
), S_RSA
, K_RSA
, C_3DES
,B_3DES
,M_MD5
, 0, 0, 0, },
202 {0,CK(SSL_CK_DES_64_CBC_WITH_MD5
), S_RSA
, K_RSA
, C_DES
, B_DES
, M_MD5
, 0, 0, 0, },
203 {0,CK(SSL_CK_RC4_128_EXPORT40_WITH_MD5
), S_RSA
, K_RSA
, C_RC4
, B_40
, M_MD5
, 0, 1, 0, },
204 {0,CK(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5
), S_RSA
, K_RSA
, C_RC2
, B_40
, M_MD5
, 0, 1, 0, }
207 #define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0]))
210 SECStatus
SSL_GetCipherSuiteInfo(PRUint16 cipherSuite
,
211 SSLCipherSuiteInfo
*info
, PRUintn len
)
215 len
= PR_MIN(len
, sizeof suiteInfo
[0]);
216 if (!info
|| len
< sizeof suiteInfo
[0].length
) {
217 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
220 for (i
= 0; i
< NUM_SUITEINFOS
; i
++) {
221 if (suiteInfo
[i
].cipherSuite
== cipherSuite
) {
222 memcpy(info
, &suiteInfo
[i
], len
);
227 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
231 /* This function might be a candidate to be public.
232 * Disables all export ciphers in the default set of enabled ciphers.
235 SSL_DisableDefaultExportCipherSuites(void)
237 const SSLCipherSuiteInfo
* pInfo
= suiteInfo
;
241 for (i
= 0; i
< NUM_SUITEINFOS
; ++i
, ++pInfo
) {
242 if (pInfo
->isExportable
) {
243 rv
= SSL_CipherPrefSetDefault(pInfo
->cipherSuite
, PR_FALSE
);
244 PORT_Assert(rv
== SECSuccess
);
250 /* This function might be a candidate to be public,
251 * except that it takes an sslSocket pointer as an argument.
252 * A Public version would take a PRFileDesc pointer.
253 * Disables all export ciphers in the default set of enabled ciphers.
256 SSL_DisableExportCipherSuites(PRFileDesc
* fd
)
258 const SSLCipherSuiteInfo
* pInfo
= suiteInfo
;
262 for (i
= 0; i
< NUM_SUITEINFOS
; ++i
, ++pInfo
) {
263 if (pInfo
->isExportable
) {
264 rv
= SSL_CipherPrefSet(fd
, pInfo
->cipherSuite
, PR_FALSE
);
265 PORT_Assert(rv
== SECSuccess
);
271 /* Tells us if the named suite is exportable
272 * returns false for unknown suites.
275 SSL_IsExportCipherSuite(PRUint16 cipherSuite
)
278 for (i
= 0; i
< NUM_SUITEINFOS
; i
++) {
279 if (suiteInfo
[i
].cipherSuite
== cipherSuite
) {
280 return (PRBool
)(suiteInfo
[i
].isExportable
);
287 SSL_GetNegotiatedHostInfo(PRFileDesc
*fd
)
289 SECItem
*sniName
= NULL
;
293 ss
= ssl_FindSocket(fd
);
295 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo",
300 if (ss
->sec
.isServer
) {
301 if (ss
->version
> SSL_LIBRARY_VERSION_3_0
&&
302 ss
->ssl3
.initialized
) { /* TLS */
304 ssl_GetSpecReadLock(ss
); /*********************************/
305 crsName
= &ss
->ssl3
.cwSpec
->srvVirtName
;
307 sniName
= SECITEM_DupItem(crsName
);
309 ssl_ReleaseSpecReadLock(ss
); /*----------------------------*/
313 name
= SSL_RevealURL(fd
);
315 sniName
= PORT_ZNew(SECItem
);
320 sniName
->data
= (void*)name
;
321 sniName
->len
= PORT_Strlen(name
);
327 SSL_ExportKeyingMaterial(PRFileDesc
*fd
,
328 const char *label
, unsigned int labelLen
,
330 const unsigned char *context
, unsigned int contextLen
,
331 unsigned char *out
, unsigned int outLen
)
334 unsigned char *val
= NULL
;
335 unsigned int valLen
, i
;
336 SECStatus rv
= SECFailure
;
338 ss
= ssl_FindSocket(fd
);
340 SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
345 ssl_GetRecvBufLock(ss
);
346 ssl_GetSSL3HandshakeLock(ss
);
348 if (ss
->version
< SSL_LIBRARY_VERSION_3_1_TLS
) {
349 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION
);
350 ssl_ReleaseSSL3HandshakeLock(ss
);
351 ssl_ReleaseRecvBufLock(ss
);
355 /* construct PRF arguments */
356 valLen
= SSL3_RANDOM_LENGTH
* 2;
358 valLen
+= 2 /* uint16 length */ + contextLen
;
360 val
= PORT_Alloc(valLen
);
362 ssl_ReleaseSSL3HandshakeLock(ss
);
363 ssl_ReleaseRecvBufLock(ss
);
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
;
374 val
[i
++] = contextLen
>> 8;
375 val
[i
++] = contextLen
;
376 PORT_Memcpy(val
+ i
, context
, contextLen
);
379 PORT_Assert(i
== valLen
);
381 /* Allow TLS keying material to be exported sooner, when the master
382 * secret is available and we have sent ChangeCipherSpec.
384 ssl_GetSpecReadLock(ss
);
385 if (!ss
->ssl3
.cwSpec
->master_secret
&& !ss
->ssl3
.cwSpec
->msItem
.len
) {
386 PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED
);
389 rv
= ssl3_TLSPRFWithMasterSecret(ss
->ssl3
.cwSpec
, label
, labelLen
, val
,
390 valLen
, out
, outLen
);
392 ssl_ReleaseSpecReadLock(ss
);
393 ssl_ReleaseSSL3HandshakeLock(ss
);
394 ssl_ReleaseRecvBufLock(ss
);
396 PORT_ZFree(val
, valLen
);