Revert "Merged all Chromoting Host code into remoting_core.dll (Windows)."
[chromium-blink-merge.git] / net / third_party / nss / ssl / sslinfo.c
blob3dcb6dbc510fc2a869bcb269a7bd8a62b6e1fcbf
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 $ */
5 #include "ssl.h"
6 #include "sslimpl.h"
7 #include "sslproto.h"
9 static const char *
10 ssl_GetCompressionMethodName(SSLCompressionMethod compression)
12 switch (compression) {
13 case ssl_compression_null:
14 return "NULL";
15 #ifdef NSS_ENABLE_ZLIB
16 case ssl_compression_deflate:
17 return "DEFLATE";
18 #endif
19 default:
20 return "???";
24 SECStatus
25 SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
27 sslSocket * ss;
28 SSLChannelInfo inf;
29 sslSessionID * sid;
30 PRBool enoughFirstHsDone = PR_FALSE;
32 if (!info || len < sizeof inf.length) {
33 PORT_SetError(SEC_ERROR_INVALID_ARGS);
34 return SECFailure;
37 ss = ssl_FindSocket(fd);
38 if (!ss) {
39 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
40 SSL_GETPID(), fd));
41 return SECFailure;
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) {
55 sid = ss->sec.ci.sid;
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);
75 if (sid) {
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);
83 } else {
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);
94 return SECSuccess;
98 #define CS(x) x, #x
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
129 #define B_0 0, 0, 0
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 */
198 /* SSL 2 table */
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)
213 unsigned int i;
215 len = PR_MIN(len, sizeof suiteInfo[0]);
216 if (!info || len < sizeof suiteInfo[0].length) {
217 PORT_SetError(SEC_ERROR_INVALID_ARGS);
218 return SECFailure;
220 for (i = 0; i < NUM_SUITEINFOS; i++) {
221 if (suiteInfo[i].cipherSuite == cipherSuite) {
222 memcpy(info, &suiteInfo[i], len);
223 info->length = len;
224 return SECSuccess;
227 PORT_SetError(SEC_ERROR_INVALID_ARGS);
228 return SECFailure;
231 /* This function might be a candidate to be public.
232 * Disables all export ciphers in the default set of enabled ciphers.
234 SECStatus
235 SSL_DisableDefaultExportCipherSuites(void)
237 const SSLCipherSuiteInfo * pInfo = suiteInfo;
238 unsigned int i;
239 SECStatus rv;
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);
247 return 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.
255 SECStatus
256 SSL_DisableExportCipherSuites(PRFileDesc * fd)
258 const SSLCipherSuiteInfo * pInfo = suiteInfo;
259 unsigned int i;
260 SECStatus rv;
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);
268 return SECSuccess;
271 /* Tells us if the named suite is exportable
272 * returns false for unknown suites.
274 PRBool
275 SSL_IsExportCipherSuite(PRUint16 cipherSuite)
277 unsigned int i;
278 for (i = 0; i < NUM_SUITEINFOS; i++) {
279 if (suiteInfo[i].cipherSuite == cipherSuite) {
280 return (PRBool)(suiteInfo[i].isExportable);
283 return PR_FALSE;
286 SECItem*
287 SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
289 SECItem *sniName = NULL;
290 sslSocket *ss;
291 char *name = NULL;
293 ss = ssl_FindSocket(fd);
294 if (!ss) {
295 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo",
296 SSL_GETPID(), fd));
297 return NULL;
300 if (ss->sec.isServer) {
301 if (ss->version > SSL_LIBRARY_VERSION_3_0 &&
302 ss->ssl3.initialized) { /* TLS */
303 SECItem *crsName;
304 ssl_GetSpecReadLock(ss); /*********************************/
305 crsName = &ss->ssl3.cwSpec->srvVirtName;
306 if (crsName->data) {
307 sniName = SECITEM_DupItem(crsName);
309 ssl_ReleaseSpecReadLock(ss); /*----------------------------*/
311 return sniName;
313 name = SSL_RevealURL(fd);
314 if (name) {
315 sniName = PORT_ZNew(SECItem);
316 if (!sniName) {
317 PORT_Free(name);
318 return NULL;
320 sniName->data = (void*)name;
321 sniName->len = PORT_Strlen(name);
323 return sniName;
326 SECStatus
327 SSL_ExportKeyingMaterial(PRFileDesc *fd,
328 const char *label, unsigned int labelLen,
329 PRBool hasContext,
330 const unsigned char *context, unsigned int contextLen,
331 unsigned char *out, unsigned int outLen)
333 sslSocket *ss;
334 unsigned char *val = NULL;
335 unsigned int valLen, i;
336 SECStatus rv = SECFailure;
338 ss = ssl_FindSocket(fd);
339 if (!ss) {
340 SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
341 SSL_GETPID(), fd));
342 return SECFailure;
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);
352 return SECFailure;
355 /* construct PRF arguments */
356 valLen = SSL3_RANDOM_LENGTH * 2;
357 if (hasContext) {
358 valLen += 2 /* uint16 length */ + contextLen;
360 val = PORT_Alloc(valLen);
361 if (!val) {
362 ssl_ReleaseSSL3HandshakeLock(ss);
363 ssl_ReleaseRecvBufLock(ss);
364 return SECFailure;
366 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;
373 if (hasContext) {
374 val[i++] = contextLen >> 8;
375 val[i++] = contextLen;
376 PORT_Memcpy(val + i, context, contextLen);
377 i += 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);
387 rv = SECFailure;
388 } else {
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);
397 return rv;