1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Original Code is the Netscape security libraries.
15 *
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2001
19 * the Initial Developer. All Rights Reserved.
20 *
21 * Contributor(s):
22 * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37 /* $Id: sslinfo.c,v 1.21 2009/11/09 22:00:18 wtc%google.com Exp $ */
38 #include "ssl.h"
39 #include "sslimpl.h"
40 #include "sslproto.h"
41
42 static const char *
ssl_GetCompressionMethodName(SSLCompressionMethod compression)43 ssl_GetCompressionMethodName(SSLCompressionMethod compression)
44 {
45 switch (compression) {
46 case ssl_compression_null:
47 return "NULL";
48 #ifdef NSS_ENABLE_ZLIB
49 case ssl_compression_deflate:
50 return "DEFLATE";
51 #endif
52 default:
53 return "???";
54 }
55 }
56
57 SECStatus
SSL_GetChannelInfo(PRFileDesc * fd,SSLChannelInfo * info,PRUintn len)58 SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
59 {
60 sslSocket * ss;
61 SSLChannelInfo inf;
62 sslSessionID * sid;
63
64 if (!info || len < sizeof inf.length) {
65 PORT_SetError(SEC_ERROR_INVALID_ARGS);
66 return SECFailure;
67 }
68
69 ss = ssl_FindSocket(fd);
70 if (!ss) {
71 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
72 SSL_GETPID(), fd));
73 return SECFailure;
74 }
75
76 memset(&inf, 0, sizeof inf);
77 inf.length = PR_MIN(sizeof inf, len);
78
79 if (ss->opt.useSecurity && ss->firstHsDone) {
80 sid = ss->sec.ci.sid;
81 inf.protocolVersion = ss->version;
82 inf.authKeyBits = ss->sec.authKeyBits;
83 inf.keaKeyBits = ss->sec.keaKeyBits;
84 if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
85 inf.cipherSuite = ss->sec.cipherType | 0xff00;
86 inf.compressionMethod = ssl_compression_null;
87 inf.compressionMethodName = "N/A";
88 } else if (ss->ssl3.initialized) { /* SSL3 and TLS */
89 ssl_GetSpecReadLock(ss);
90 /* XXX The cipher suite should be in the specs and this
91 * function should get it from crSpec rather than from the "hs".
92 * See bug 275744 comment 69.
93 */
94 inf.cipherSuite = ss->ssl3.hs.cipher_suite;
95 inf.compressionMethod = ss->ssl3.crSpec->compression_method;
96 ssl_ReleaseSpecReadLock(ss);
97 inf.compressionMethodName =
98 ssl_GetCompressionMethodName(inf.compressionMethod);
99 }
100 if (sid) {
101 inf.creationTime = sid->creationTime;
102 inf.lastAccessTime = sid->lastAccessTime;
103 inf.expirationTime = sid->expirationTime;
104 if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
105 inf.sessionIDLength = SSL2_SESSIONID_BYTES;
106 memcpy(inf.sessionID, sid->u.ssl2.sessionID,
107 SSL2_SESSIONID_BYTES);
108 } else {
109 unsigned int sidLen = sid->u.ssl3.sessionIDLength;
110 sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
111 inf.sessionIDLength = sidLen;
112 memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen);
113 }
114 }
115 }
116
117 memcpy(info, &inf, inf.length);
118
119 return SECSuccess;
120 }
121
122
123 #define CS(x) x, #x
124 #define CK(x) x | 0xff00, #x
125
126 #define S_DSA "DSA", ssl_auth_dsa
127 #define S_RSA "RSA", ssl_auth_rsa
128 #define S_KEA "KEA", ssl_auth_kea
129 #define S_ECDSA "ECDSA", ssl_auth_ecdsa
130
131 #define K_DHE "DHE", kt_dh
132 #define K_RSA "RSA", kt_rsa
133 #define K_KEA "KEA", kt_kea
134 #define K_ECDH "ECDH", kt_ecdh
135 #define K_ECDHE "ECDHE", kt_ecdh
136
137 #define C_SEED "SEED", calg_seed
138 #define C_CAMELLIA "CAMELLIA", calg_camellia
139 #define C_AES "AES", calg_aes
140 #define C_RC4 "RC4", calg_rc4
141 #define C_RC2 "RC2", calg_rc2
142 #define C_DES "DES", calg_des
143 #define C_3DES "3DES", calg_3des
144 #define C_NULL "NULL", calg_null
145 #define C_SJ "SKIPJACK", calg_sj
146
147 #define B_256 256, 256, 256
148 #define B_128 128, 128, 128
149 #define B_3DES 192, 156, 112
150 #define B_SJ 96, 80, 80
151 #define B_DES 64, 56, 56
152 #define B_56 128, 56, 56
153 #define B_40 128, 40, 40
154 #define B_0 0, 0, 0
155
156 #define M_SHA "SHA1", ssl_mac_sha, 160
157 #define M_MD5 "MD5", ssl_mac_md5, 128
158
159 static const SSLCipherSuiteInfo suiteInfo[] = {
160 /* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */
161 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
162 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
163 {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
164 {0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
165 {0,CS(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
166 {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_SHA, 1, 0, 0, },
167
168 {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
169 {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
170 {0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA), S_DSA, K_DHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
171 {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
172 {0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
173 {0,CS(TLS_RSA_WITH_SEED_CBC_SHA), S_RSA, K_RSA, C_SEED,B_128, M_SHA, 1, 0, 0, },
174 {0,CS(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
175 {0,CS(SSL_RSA_WITH_RC4_128_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
176 {0,CS(SSL_RSA_WITH_RC4_128_SHA), S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0, },
177 {0,CS(TLS_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_RSA, C_AES, B_128, M_SHA, 1, 0, 0, },
178
179 {0,CS(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
180 {0,CS(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA), S_DSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
181 {0,CS(SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 1, },
182 {0,CS(SSL_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
183
184 {0,CS(SSL_DHE_RSA_WITH_DES_CBC_SHA), S_RSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
185 {0,CS(SSL_DHE_DSS_WITH_DES_CBC_SHA), S_DSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
186 {0,CS(SSL_RSA_FIPS_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 1, },
187 {0,CS(SSL_RSA_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 0, },
188
189 {0,CS(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA), S_RSA, K_RSA, C_RC4, B_56, M_SHA, 0, 1, 0, },
190 {0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 1, 0, },
191 {0,CS(SSL_RSA_EXPORT_WITH_RC4_40_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0, },
192 {0,CS(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0, },
193 {0,CS(SSL_RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL,B_0, M_SHA, 0, 1, 0, },
194 {0,CS(SSL_RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL,B_0, M_MD5, 0, 1, 0, },
195
196 #ifdef NSS_ENABLE_ECC
197 /* ECC cipher suites */
198 {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
199 {0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
200 {0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
201 {0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, },
202 {0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, },
203
204 {0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, },
205 {0,CS(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
206 {0,CS(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
207 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
208 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, },
209
210 {0,CS(TLS_ECDH_RSA_WITH_NULL_SHA), S_RSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
211 {0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
212 {0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
213 {0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, },
214 {0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, },
215
216 {0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA), S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, },
217 {0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
218 {0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
219 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
220 {0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, },
221 #endif /* NSS_ENABLE_ECC */
222
223 /* SSL 2 table */
224 {0,CK(SSL_CK_RC4_128_WITH_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
225 {0,CK(SSL_CK_RC2_128_CBC_WITH_MD5), S_RSA, K_RSA, C_RC2, B_128, M_MD5, 0, 0, 0, },
226 {0,CK(SSL_CK_DES_192_EDE3_CBC_WITH_MD5), S_RSA, K_RSA, C_3DES,B_3DES,M_MD5, 0, 0, 0, },
227 {0,CK(SSL_CK_DES_64_CBC_WITH_MD5), S_RSA, K_RSA, C_DES, B_DES, M_MD5, 0, 0, 0, },
228 {0,CK(SSL_CK_RC4_128_EXPORT40_WITH_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0, },
229 {0,CK(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0, }
230 };
231
232 #define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0]))
233
234
SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,SSLCipherSuiteInfo * info,PRUintn len)235 SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
236 SSLCipherSuiteInfo *info, PRUintn len)
237 {
238 unsigned int i;
239
240 len = PR_MIN(len, sizeof suiteInfo[0]);
241 if (!info || len < sizeof suiteInfo[0].length) {
242 PORT_SetError(SEC_ERROR_INVALID_ARGS);
243 return SECFailure;
244 }
245 for (i = 0; i < NUM_SUITEINFOS; i++) {
246 if (suiteInfo[i].cipherSuite == cipherSuite) {
247 memcpy(info, &suiteInfo[i], len);
248 info->length = len;
249 return SECSuccess;
250 }
251 }
252 PORT_SetError(SEC_ERROR_INVALID_ARGS);
253 return SECFailure;
254 }
255
256 /* This function might be a candidate to be public.
257 * Disables all export ciphers in the default set of enabled ciphers.
258 */
259 SECStatus
SSL_DisableDefaultExportCipherSuites(void)260 SSL_DisableDefaultExportCipherSuites(void)
261 {
262 const SSLCipherSuiteInfo * pInfo = suiteInfo;
263 unsigned int i;
264 SECStatus rv;
265
266 for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
267 if (pInfo->isExportable) {
268 rv = SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FALSE);
269 PORT_Assert(rv == SECSuccess);
270 }
271 }
272 return SECSuccess;
273 }
274
275 /* This function might be a candidate to be public,
276 * except that it takes an sslSocket pointer as an argument.
277 * A Public version would take a PRFileDesc pointer.
278 * Disables all export ciphers in the default set of enabled ciphers.
279 */
280 SECStatus
SSL_DisableExportCipherSuites(PRFileDesc * fd)281 SSL_DisableExportCipherSuites(PRFileDesc * fd)
282 {
283 const SSLCipherSuiteInfo * pInfo = suiteInfo;
284 unsigned int i;
285 SECStatus rv;
286
287 for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
288 if (pInfo->isExportable) {
289 rv = SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE);
290 PORT_Assert(rv == SECSuccess);
291 }
292 }
293 return SECSuccess;
294 }
295
296 /* Tells us if the named suite is exportable
297 * returns false for unknown suites.
298 */
299 PRBool
SSL_IsExportCipherSuite(PRUint16 cipherSuite)300 SSL_IsExportCipherSuite(PRUint16 cipherSuite)
301 {
302 unsigned int i;
303 for (i = 0; i < NUM_SUITEINFOS; i++) {
304 if (suiteInfo[i].cipherSuite == cipherSuite) {
305 return (PRBool)(suiteInfo[i].isExportable);
306 }
307 }
308 return PR_FALSE;
309 }
310