libpurple/plugins/ssl/ssl-nss.c

changeset 36212
fa725d4d41ab
parent 36201
bf10d2bb6919
parent 36209
9bafa7dfb2a3
child 36222
fd55a0f119db
equal deleted inserted replaced
36211:de73d2ecffe8 36212:fa725d4d41ab
137 } 137 }
138 138
139 return ret; 139 return ret;
140 } 140 }
141 141
142 static void ssl_nss_log_ciphers(void) {
143 const PRUint16 *cipher;
144 for (cipher = SSL_GetImplementedCiphers(); *cipher != 0; ++cipher) {
145 const PRUint16 suite = *cipher;
146 SECStatus rv;
147 PRBool enabled;
148 PRErrorCode err;
149 SSLCipherSuiteInfo info;
150
151 rv = SSL_CipherPrefGetDefault(suite, &enabled);
152 if (rv != SECSuccess) {
153 err = PR_GetError();
154 purple_debug_warning("nss",
155 "SSL_CipherPrefGetDefault didn't like value 0x%04x: %s\n",
156 suite, PORT_ErrorToString(err));
157 continue;
158 }
159 rv = SSL_GetCipherSuiteInfo(suite, &info, (int)(sizeof info));
160 if (rv != SECSuccess) {
161 err = PR_GetError();
162 purple_debug_warning("nss",
163 "SSL_GetCipherSuiteInfo didn't like value 0x%04x: %s\n",
164 suite, PORT_ErrorToString(err));
165 continue;
166 }
167 purple_debug_info("nss", "Cipher - %s: %s\n",
168 info.cipherSuiteName,
169 enabled ? "Enabled" : "Disabled");
170 }
171 }
172
142 static void 173 static void
143 ssl_nss_init_nss(void) 174 ssl_nss_init_nss(void)
144 { 175 {
145 #if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR >= 14 ) 176 #if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR >= 14 )
146 SSLVersionRange supported, enabled; 177 SSLVersionRange supported, enabled;
147 #endif /* NSS >= 3.14 */ 178 #endif /* NSS >= 3.14 */
148 179
149 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); 180 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
150 NSS_NoDB_Init("."); 181 NSS_NoDB_Init(".");
182 #if (NSS_VMAJOR == 3 && (NSS_VMINOR < 15 || (NSS_VMINOR == 15 && NSS_VMICRO < 2)))
151 NSS_SetDomesticPolicy(); 183 NSS_SetDomesticPolicy();
184 #endif /* NSS < 3.15.2 */
152 185
153 SSL_CipherPrefSetDefault(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 1); 186 SSL_CipherPrefSetDefault(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 1);
154 SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 1); 187 SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 1);
155 SSL_CipherPrefSetDefault(TLS_RSA_WITH_AES_256_CBC_SHA, 1); 188 SSL_CipherPrefSetDefault(TLS_RSA_WITH_AES_256_CBC_SHA, 1);
156 SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_RC4_128_SHA, 1); 189 SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_RC4_128_SHA, 1);
193 /** Disable OCSP Checking until we can make that use our HTTP & Proxy stuff */ 226 /** Disable OCSP Checking until we can make that use our HTTP & Proxy stuff */
194 CERT_EnableOCSPChecking(PR_FALSE); 227 CERT_EnableOCSPChecking(PR_FALSE);
195 228
196 _identity = PR_GetUniqueIdentity("Purple"); 229 _identity = PR_GetUniqueIdentity("Purple");
197 _nss_methods = PR_GetDefaultIOMethods(); 230 _nss_methods = PR_GetDefaultIOMethods();
231
232 ssl_nss_log_ciphers();
198 } 233 }
199 234
200 static SECStatus 235 static SECStatus
201 ssl_auth_cert(void *arg, PRFileDesc *socket, PRBool checksig, PRBool is_server) 236 ssl_auth_cert(void *arg, PRFileDesc *socket, PRBool checksig, PRBool is_server)
202 { 237 {
1032 static void x509_verify_cert(PurpleCertificateVerificationRequest *vrq, PurpleCertificateVerificationStatus *flags) 1067 static void x509_verify_cert(PurpleCertificateVerificationRequest *vrq, PurpleCertificateVerificationStatus *flags)
1033 { 1068 {
1034 CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); 1069 CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
1035 CERTCertificate *crt_dat; 1070 CERTCertificate *crt_dat;
1036 PRTime now = PR_Now(); 1071 PRTime now = PR_Now();
1037 SECStatus rv; 1072 SECStatus rv;
1038 PurpleCertificate *first_cert = vrq->cert_chain->data; 1073 PurpleCertificate *first_cert = vrq->cert_chain->data;
1039 CERTVerifyLog log; 1074 CERTVerifyLog log;
1075 gboolean self_signed = FALSE;
1040 1076
1041 crt_dat = X509_NSS_DATA(first_cert); 1077 crt_dat = X509_NSS_DATA(first_cert);
1042 1078
1043 log.arena = PORT_NewArena(512); 1079 log.arena = PORT_NewArena(512);
1044 log.head = log.tail = NULL; 1080 log.head = log.tail = NULL;
1047 1083
1048 if (rv != SECSuccess || log.count > 0) { 1084 if (rv != SECSuccess || log.count > 0) {
1049 CERTVerifyLogNode *node = NULL; 1085 CERTVerifyLogNode *node = NULL;
1050 unsigned int depth = (unsigned int)-1; 1086 unsigned int depth = (unsigned int)-1;
1051 1087
1088 if (crt_dat->isRoot) {
1089 self_signed = TRUE;
1090 *flags |= PURPLE_CERTIFICATE_SELF_SIGNED;
1091 }
1092
1093 /* Handling of untrusted, etc. modeled after
1094 * source/security/manager/ssl/src/TransportSecurityInfo.cpp in Firefox
1095 */
1052 for (node = log.head; node; node = node->next) { 1096 for (node = log.head; node; node = node->next) {
1053 if (depth != node->depth) { 1097 if (depth != node->depth) {
1054 depth = node->depth; 1098 depth = node->depth;
1055 purple_debug_error("nss", "CERT %d. %s %s:\n", depth, 1099 purple_debug_error("nss", "CERT %d. %s %s:\n", depth,
1056 node->cert->subjectName, 1100 node->cert->subjectName,
1063 *flags |= PURPLE_CERTIFICATE_EXPIRED; 1107 *flags |= PURPLE_CERTIFICATE_EXPIRED;
1064 break; 1108 break;
1065 case SEC_ERROR_REVOKED_CERTIFICATE: 1109 case SEC_ERROR_REVOKED_CERTIFICATE:
1066 *flags |= PURPLE_CERTIFICATE_REVOKED; 1110 *flags |= PURPLE_CERTIFICATE_REVOKED;
1067 break; 1111 break;
1112 case SEC_ERROR_UNKNOWN_ISSUER:
1068 case SEC_ERROR_UNTRUSTED_ISSUER: 1113 case SEC_ERROR_UNTRUSTED_ISSUER:
1069 if (crt_dat->isRoot) { 1114 if (!self_signed) {
1070 *flags |= PURPLE_CERTIFICATE_SELF_SIGNED;
1071 } else {
1072 *flags |= PURPLE_CERTIFICATE_CA_UNKNOWN; 1115 *flags |= PURPLE_CERTIFICATE_CA_UNKNOWN;
1073 } 1116 }
1074 break; 1117 break;
1118 case SEC_ERROR_CA_CERT_INVALID:
1119 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
1120 case SEC_ERROR_UNTRUSTED_CERT:
1075 case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: 1121 case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
1122 if (!self_signed) {
1123 *flags |= PURPLE_CERTIFICATE_INVALID_CHAIN;
1124 }
1125 break;
1076 case SEC_ERROR_BAD_SIGNATURE: 1126 case SEC_ERROR_BAD_SIGNATURE:
1077 default: 1127 default:
1078 *flags |= PURPLE_CERTIFICATE_INVALID_CHAIN; 1128 *flags |= PURPLE_CERTIFICATE_INVALID_CHAIN;
1079 } 1129 }
1080 if (node->cert) 1130 if (node->cert)
1081 CERT_DestroyCertificate(node->cert); 1131 CERT_DestroyCertificate(node->cert);
1082 } 1132 }
1083 } else { 1133 }
1084 rv = CERT_VerifyCertName(crt_dat, vrq->subject_name); 1134
1085 if (rv != SECSuccess) { 1135 rv = CERT_VerifyCertName(crt_dat, vrq->subject_name);
1086 purple_debug_error("nss", "Cert chain valid, but name not verified\n"); 1136 if (rv != SECSuccess) {
1087 *flags |= PURPLE_CERTIFICATE_NAME_MISMATCH; 1137 purple_debug_error("nss", "subject name not verified\n");
1088 } 1138 *flags |= PURPLE_CERTIFICATE_NAME_MISMATCH;
1089 } 1139 }
1090 1140
1091 PORT_FreeArena(log.arena, PR_FALSE); 1141 PORT_FreeArena(log.arena, PR_FALSE);
1092 } 1142 }
1093 1143

mercurial