Back to index

lightning-sunbird  0.9+nobinonly
sslinfo.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 2001
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 /* $Id: sslinfo.c,v 1.14.2.1 2006/01/28 00:13:37 wtchang%redhat.com Exp $ */
00038 #include "ssl.h"
00039 #include "sslimpl.h"
00040 #include "sslproto.h"
00041 
00042 SECStatus 
00043 SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
00044 {
00045     sslSocket *      ss;
00046     SSLChannelInfo   inf;
00047     sslSessionID *   sid;
00048 
00049     if (!info || len < sizeof inf.length) { 
00050        return SECSuccess;
00051     }
00052 
00053     ss = ssl_FindSocket(fd);
00054     if (!ss) {
00055        SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
00056                SSL_GETPID(), fd));
00057        return SECFailure;
00058     }
00059 
00060     memset(&inf, 0, sizeof inf);
00061     inf.length = PR_MIN(sizeof inf, len);
00062 
00063     if (ss->opt.useSecurity && ss->firstHsDone) {
00064         sid = ss->sec.ci.sid;
00065        inf.protocolVersion  = ss->version;
00066        inf.authKeyBits      = ss->sec.authKeyBits;
00067        inf.keaKeyBits       = ss->sec.keaKeyBits;
00068        if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
00069            inf.cipherSuite      = ss->sec.cipherType | 0xff00;
00070        } else if (ss->ssl3.initialized) {        /* SSL3 and TLS */
00071 
00072            /* XXX  These should come from crSpec */
00073            inf.cipherSuite      = ss->ssl3.hs.cipher_suite;
00074        }
00075        if (sid) {
00076            inf.creationTime   = sid->creationTime;
00077            inf.lastAccessTime = sid->lastAccessTime;
00078            inf.expirationTime = sid->expirationTime;
00079            if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
00080                inf.sessionIDLength = SSL2_SESSIONID_BYTES;
00081               memcpy(inf.sessionID, sid->u.ssl2.sessionID, 
00082                      SSL2_SESSIONID_BYTES);
00083            } else {
00084               unsigned int sidLen = sid->u.ssl3.sessionIDLength;
00085                sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
00086                inf.sessionIDLength = sidLen;
00087               memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen);
00088            }
00089        }
00090     }
00091 
00092     memcpy(info, &inf, inf.length);
00093 
00094     return SECSuccess;
00095 }
00096 
00097 
00098 #define CS(x) x, #x
00099 #define CK(x) x | 0xff00, #x
00100 
00101 #define S_DSA   "DSA", ssl_auth_dsa
00102 #define S_RSA "RSA", ssl_auth_rsa
00103 #define S_KEA   "KEA", ssl_auth_kea
00104 #define S_ECDSA "ECDSA", ssl_auth_ecdsa
00105 
00106 #define K_DHE "DHE", kt_dh
00107 #define K_RSA "RSA", kt_rsa
00108 #define K_KEA "KEA", kt_kea
00109 #define K_ECDH       "ECDH", kt_ecdh
00110 #define K_ECDHE      "ECDHE", kt_ecdh
00111 
00112 #define C_AES "AES", calg_aes
00113 #define C_RC4 "RC4", calg_rc4
00114 #define C_RC2 "RC2", calg_rc2
00115 #define C_DES "DES", calg_des
00116 #define C_3DES       "3DES", calg_3des
00117 #define C_NULL  "NULL", calg_null
00118 #define C_SJ  "SKIPJACK", calg_sj
00119 
00120 #define B_256 256, 256, 256
00121 #define B_128 128, 128, 128
00122 #define B_3DES  192, 156, 112
00123 #define B_SJ     96,  80,  80
00124 #define B_DES    64,  56,  56
00125 #define B_56    128,  56,  56
00126 #define B_40    128,  40,  40
00127 #define B_0     0,   0,   0
00128 
00129 #define M_SHA "SHA1", ssl_mac_sha, 160
00130 #define M_MD5 "MD5",  ssl_mac_md5, 128
00131 
00132 static const SSLCipherSuiteInfo suiteInfo[] = {
00133 /* <------ Cipher suite --------------------> <auth> <KEA>  <bulk cipher> <MAC> <FIPS> */
00134 {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA),      S_RSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
00135 {0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA),      S_DSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
00136 {0,CS(TLS_RSA_WITH_AES_256_CBC_SHA),          S_RSA, K_RSA, C_AES, B_256, M_SHA, 1, 0, 0, },
00137 
00138 {0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA),          S_DSA, K_DHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
00139 {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA),      S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
00140 {0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA),      S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
00141 {0,CS(SSL_RSA_WITH_RC4_128_MD5),              S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
00142 {0,CS(SSL_RSA_WITH_RC4_128_SHA),              S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0, },
00143 {0,CS(TLS_RSA_WITH_AES_128_CBC_SHA),          S_RSA, K_RSA, C_AES, B_128, M_SHA, 1, 0, 0, },
00144 
00145 {0,CS(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA),     S_RSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
00146 {0,CS(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA),     S_DSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
00147 {0,CS(SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA),    S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 1, },
00148 {0,CS(SSL_RSA_WITH_3DES_EDE_CBC_SHA),         S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
00149 
00150 {0,CS(SSL_DHE_RSA_WITH_DES_CBC_SHA),          S_RSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
00151 {0,CS(SSL_DHE_DSS_WITH_DES_CBC_SHA),          S_DSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
00152 {0,CS(SSL_RSA_FIPS_WITH_DES_CBC_SHA),         S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 1, },
00153 {0,CS(SSL_RSA_WITH_DES_CBC_SHA),              S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 0, },
00154 
00155 {0,CS(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA),    S_RSA, K_RSA, C_RC4, B_56,  M_SHA, 0, 1, 0, },
00156 {0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA),   S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 1, 0, },
00157 {0,CS(SSL_RSA_EXPORT_WITH_RC4_40_MD5),        S_RSA, K_RSA, C_RC4, B_40,  M_MD5, 0, 1, 0, },
00158 {0,CS(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5),    S_RSA, K_RSA, C_RC2, B_40,  M_MD5, 0, 1, 0, },
00159 {0,CS(SSL_RSA_WITH_NULL_SHA),                 S_RSA, K_RSA, C_NULL,B_0,   M_SHA, 0, 1, 0, },
00160 {0,CS(SSL_RSA_WITH_NULL_MD5),                 S_RSA, K_RSA, C_NULL,B_0,   M_MD5, 0, 1, 0, },
00161 
00162 #ifdef NSS_ENABLE_ECC
00163 /* ECC cipher suites */
00164 {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA),          S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
00165 {0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA),       S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
00166 {0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA),  S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
00167 {0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA),   S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, },
00168 {0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA),   S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, },
00169 
00170 {0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA),         S_ECDSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, },
00171 {0,CS(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA),      S_ECDSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
00172 {0,CS(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
00173 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA),  S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
00174 {0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA),  S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, },
00175 
00176 {0,CS(TLS_ECDH_RSA_WITH_NULL_SHA),            S_RSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
00177 {0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA),         S_RSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
00178 {0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA),    S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
00179 {0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA),     S_RSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, },
00180 {0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA),     S_RSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, },
00181 
00182 {0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA),           S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, },
00183 {0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA),        S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
00184 {0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA),   S_RSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
00185 {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA),    S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
00186 {0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),    S_RSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, },
00187 #endif /* NSS_ENABLE_ECC */
00188 
00189 /* SSL 2 table */
00190 {0,CK(SSL_CK_RC4_128_WITH_MD5),               S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
00191 {0,CK(SSL_CK_RC2_128_CBC_WITH_MD5),           S_RSA, K_RSA, C_RC2, B_128, M_MD5, 0, 0, 0, },
00192 {0,CK(SSL_CK_DES_192_EDE3_CBC_WITH_MD5),      S_RSA, K_RSA, C_3DES,B_3DES,M_MD5, 0, 0, 0, },
00193 {0,CK(SSL_CK_DES_64_CBC_WITH_MD5),            S_RSA, K_RSA, C_DES, B_DES, M_MD5, 0, 0, 0, },
00194 {0,CK(SSL_CK_RC4_128_EXPORT40_WITH_MD5),      S_RSA, K_RSA, C_RC4, B_40,  M_MD5, 0, 1, 0, },
00195 {0,CK(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5),  S_RSA, K_RSA, C_RC2, B_40,  M_MD5, 0, 1, 0, }
00196 };
00197 
00198 #define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0]))
00199 
00200 
00201 SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite, 
00202                                  SSLCipherSuiteInfo *info, PRUintn len)
00203 {
00204     unsigned int i;
00205 
00206     len = PR_MIN(len, sizeof suiteInfo[0]);
00207     if (!info || len < sizeof suiteInfo[0].length) {
00208        PORT_SetError(SEC_ERROR_INVALID_ARGS);
00209        return SECFailure;
00210     }
00211     for (i = 0; i < NUM_SUITEINFOS; i++) {
00212        if (suiteInfo[i].cipherSuite == cipherSuite) {
00213            memcpy(info, &suiteInfo[i], len);
00214            info->length = len;
00215            return SECSuccess;
00216        }
00217     }
00218     PORT_SetError(SEC_ERROR_INVALID_ARGS);
00219     return SECFailure;
00220 }
00221 
00222 /* This function might be a candidate to be public. 
00223  * Disables all export ciphers in the default set of enabled ciphers.
00224  */
00225 SECStatus 
00226 SSL_DisableDefaultExportCipherSuites(void)
00227 {
00228     const SSLCipherSuiteInfo * pInfo = suiteInfo;
00229     unsigned int i;
00230     SECStatus rv;
00231 
00232     for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
00233        if (pInfo->isExportable) {
00234            rv = SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FALSE);
00235            PORT_Assert(rv == SECSuccess);
00236        }
00237     }
00238     return SECSuccess;
00239 }
00240 
00241 /* This function might be a candidate to be public, 
00242  * except that it takes an sslSocket pointer as an argument.
00243  * A Public version would take a PRFileDesc pointer.
00244  * Disables all export ciphers in the default set of enabled ciphers.
00245  */
00246 SECStatus 
00247 SSL_DisableExportCipherSuites(PRFileDesc * fd)
00248 {
00249     const SSLCipherSuiteInfo * pInfo = suiteInfo;
00250     unsigned int i;
00251     SECStatus rv;
00252 
00253     for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
00254        if (pInfo->isExportable) {
00255            rv = SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE);
00256            PORT_Assert(rv == SECSuccess);
00257        }
00258     }
00259     return SECSuccess;
00260 }
00261 
00262 /* Tells us if the named suite is exportable 
00263  * returns false for unknown suites.
00264  */
00265 PRBool
00266 SSL_IsExportCipherSuite(PRUint16 cipherSuite)
00267 {
00268     unsigned int i;
00269     for (i = 0; i < NUM_SUITEINFOS; i++) {
00270        if (suiteInfo[i].cipherSuite == cipherSuite) {
00271            return (PRBool)(suiteInfo[i].isExportable);
00272        }
00273     }
00274     return PR_FALSE;
00275 }