Home | History | Annotate | Download | only in ssl
      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 (at) 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_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 
    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 }
    310