libpurple/plugins/ssl/ssl-nss.c

changeset 36222
fd55a0f119db
parent 36212
fa725d4d41ab
parent 36220
f26d96f03176
child 36229
c6b248d98ba9
equal deleted inserted replaced
36213:f47eb0bc58c9 36222:fd55a0f119db
137 } 137 }
138 138
139 return ret; 139 return ret;
140 } 140 }
141 141
142 static void ssl_nss_log_ciphers(void) { 142 static const PRUint16 default_ciphers[] = {
143 #if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR > 15 ) \
144 || ( NSS_VMAJOR == 3 && NSS_VMINOR == 15 && NSS_VPATCH >= 1 )
145 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
146 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
147 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
148 # if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR > 15 ) \
149 || ( NSS_VMAJOR == 3 && NSS_VMINOR == 15 && NSS_VPATCH >= 2 )
150 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
151 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
152 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
153 # endif
154 #endif
155 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
156 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
157
158 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
159 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
160
161 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
162
163 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
164
165 TLS_DHE_DSS_WITH_AES_128_CBC_SHA, /* deprecated (DSS) */
166 /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA, false }, // deprecated (DSS) */
167
168 TLS_ECDHE_RSA_WITH_RC4_128_SHA, /* deprecated (RC4) */
169 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, /* deprecated (RC4) */
170
171 /* RFC 6120 Mandatory */
172 TLS_RSA_WITH_AES_128_CBC_SHA, /* deprecated (RSA key exchange) */
173 TLS_RSA_WITH_AES_256_CBC_SHA, /* deprecated (RSA key exchange) */
174 /* TLS_RSA_WITH_3DES_EDE_CBC_SHA, deprecated (RSA key exchange, 3DES) */
175
176 0 /* end marker */
177 };
178
179 /* It's unfortunate we need to manage these manually,
180 * ideally NSS would choose good defaults.
181 * This is mostly based on FireFox's list:
182 * https://hg.mozilla.org/mozilla-central/log/default/security/manager/ssl/src/nsNSSComponent.cpp */
183 static void ssl_nss_init_ciphers(void) {
184 /* Disable any ciphers that NSS might have enabled by default */
143 const PRUint16 *cipher; 185 const PRUint16 *cipher;
186 for (cipher = SSL_GetImplementedCiphers(); *cipher != 0; ++cipher) {
187 SSL_CipherPrefSetDefault(*cipher, PR_FALSE);
188 }
189
190 /* Now only set SSL/TLS ciphers we knew about at compile time */
191 for (cipher = default_ciphers; *cipher != 0; ++cipher) {
192 SSL_CipherPrefSetDefault(*cipher, PR_TRUE);
193 }
194
195 /* Now log the available and enabled Ciphers */
144 for (cipher = SSL_GetImplementedCiphers(); *cipher != 0; ++cipher) { 196 for (cipher = SSL_GetImplementedCiphers(); *cipher != 0; ++cipher) {
145 const PRUint16 suite = *cipher; 197 const PRUint16 suite = *cipher;
146 SECStatus rv; 198 SECStatus rv;
147 PRBool enabled; 199 PRBool enabled;
148 PRErrorCode err; 200 PRErrorCode err;
149 SSLCipherSuiteInfo info; 201 SSLCipherSuiteInfo info;
150 202
151 rv = SSL_CipherPrefGetDefault(suite, &enabled); 203 rv = SSL_CipherPrefGetDefault(suite, &enabled);
152 if (rv != SECSuccess) { 204 if (rv != SECSuccess) {
153 err = PR_GetError(); 205 gchar *error_txt = get_error_text();
154 purple_debug_warning("nss", 206 purple_debug_warning("nss",
155 "SSL_CipherPrefGetDefault didn't like value 0x%04x: %s\n", 207 "SSL_CipherPrefGetDefault didn't like value 0x%04x: %s\n",
156 suite, PORT_ErrorToString(err)); 208 suite, error_txt);
209 g_free(error_txt);
157 continue; 210 continue;
158 } 211 }
159 rv = SSL_GetCipherSuiteInfo(suite, &info, (int)(sizeof info)); 212 rv = SSL_GetCipherSuiteInfo(suite, &info, (int)(sizeof info));
160 if (rv != SECSuccess) { 213 if (rv != SECSuccess) {
161 err = PR_GetError(); 214 gchar *error_txt = get_error_text();
162 purple_debug_warning("nss", 215 purple_debug_warning("nss",
163 "SSL_GetCipherSuiteInfo didn't like value 0x%04x: %s\n", 216 "SSL_GetCipherSuiteInfo didn't like value 0x%04x: %s\n",
164 suite, PORT_ErrorToString(err)); 217 suite, error_txt);
218 g_free(error_txt);
165 continue; 219 continue;
166 } 220 }
167 purple_debug_info("nss", "Cipher - %s: %s\n", 221 purple_debug_info("nss", "Cipher - %s: %s\n",
168 info.cipherSuiteName, 222 info.cipherSuiteName,
169 enabled ? "Enabled" : "Disabled"); 223 enabled ? "Enabled" : "Disabled");
177 SSLVersionRange supported, enabled; 231 SSLVersionRange supported, enabled;
178 #endif /* NSS >= 3.14 */ 232 #endif /* NSS >= 3.14 */
179 233
180 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); 234 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
181 NSS_NoDB_Init("."); 235 NSS_NoDB_Init(".");
182 #if (NSS_VMAJOR == 3 && (NSS_VMINOR < 15 || (NSS_VMINOR == 15 && NSS_VMICRO < 2))) 236 #if (NSS_VMAJOR == 3 && (NSS_VMINOR < 15 || (NSS_VMINOR == 15 && NSS_VPATCH < 2)))
183 NSS_SetDomesticPolicy(); 237 NSS_SetDomesticPolicy();
184 #endif /* NSS < 3.15.2 */ 238 #endif /* NSS < 3.15.2 */
185 239
186 SSL_CipherPrefSetDefault(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 1); 240 ssl_nss_init_ciphers();
187 SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 1);
188 SSL_CipherPrefSetDefault(TLS_RSA_WITH_AES_256_CBC_SHA, 1);
189 SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_RC4_128_SHA, 1);
190 SSL_CipherPrefSetDefault(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 1);
191 SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 1);
192 SSL_CipherPrefSetDefault(SSL_RSA_WITH_RC4_128_SHA, 1);
193 SSL_CipherPrefSetDefault(TLS_RSA_WITH_AES_128_CBC_SHA, 1);
194 SSL_CipherPrefSetDefault(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 1);
195 SSL_CipherPrefSetDefault(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 1);
196 SSL_CipherPrefSetDefault(SSL_DHE_RSA_WITH_DES_CBC_SHA, 1);
197 SSL_CipherPrefSetDefault(SSL_DHE_DSS_WITH_DES_CBC_SHA, 1);
198 241
199 #if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR >= 14 ) 242 #if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR >= 14 )
200 /* Get the ranges of supported and enabled SSL versions */ 243 /* Get the ranges of supported and enabled SSL versions */
201 if ((SSL_VersionRangeGetSupported(ssl_variant_stream, &supported) == SECSuccess) && 244 if ((SSL_VersionRangeGetSupported(ssl_variant_stream, &supported) == SECSuccess) &&
202 (SSL_VersionRangeGetDefault(ssl_variant_stream, &enabled) == SECSuccess)) { 245 (SSL_VersionRangeGetDefault(ssl_variant_stream, &enabled) == SECSuccess)) {
227 CERT_EnableOCSPChecking(PR_FALSE); 270 CERT_EnableOCSPChecking(PR_FALSE);
228 271
229 _identity = PR_GetUniqueIdentity("Purple"); 272 _identity = PR_GetUniqueIdentity("Purple");
230 _nss_methods = PR_GetDefaultIOMethods(); 273 _nss_methods = PR_GetDefaultIOMethods();
231 274
232 ssl_nss_log_ciphers();
233 } 275 }
234 276
235 static SECStatus 277 static SECStatus
236 ssl_auth_cert(void *arg, PRFileDesc *socket, PRBool checksig, PRBool is_server) 278 ssl_auth_cert(void *arg, PRFileDesc *socket, PRBool checksig, PRBool is_server)
237 { 279 {
1116 } 1158 }
1117 break; 1159 break;
1118 case SEC_ERROR_CA_CERT_INVALID: 1160 case SEC_ERROR_CA_CERT_INVALID:
1119 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: 1161 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
1120 case SEC_ERROR_UNTRUSTED_CERT: 1162 case SEC_ERROR_UNTRUSTED_CERT:
1163 #ifdef SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
1121 case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: 1164 case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
1165 #endif
1122 if (!self_signed) { 1166 if (!self_signed) {
1123 *flags |= PURPLE_CERTIFICATE_INVALID_CHAIN; 1167 *flags |= PURPLE_CERTIFICATE_INVALID_CHAIN;
1124 } 1168 }
1125 break; 1169 break;
1126 case SEC_ERROR_BAD_SIGNATURE: 1170 case SEC_ERROR_BAD_SIGNATURE:

mercurial