OLD | NEW |
(Empty) | |
| 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 * |
| 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 |
| 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_SH
A, 0, 0, 0, }, |
| 199 {0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_S
HA, 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_S
HA, 1, 0, 0, }, |
| 202 {0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_S
HA, 1, 0, 0, }, |
| 203 |
| 204 {0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDHE, C_NULL, B_0, M_S
HA, 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_S
HA, 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_SH
A, 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_SH
A, 1, 0, 0, }, |
| 220 {0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_256, M_SH
A, 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 |
| 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 |
| 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 |
| 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 |
| 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 } |
OLD | NEW |