| OLD | NEW |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 #include "cert.h" | 4 #include "cert.h" |
| 5 #include "secitem.h" | 5 #include "secitem.h" |
| 6 #include "ssl.h" | 6 #include "ssl.h" |
| 7 #include "sslimpl.h" | 7 #include "sslimpl.h" |
| 8 #include "sslproto.h" | 8 #include "sslproto.h" |
| 9 #include "pk11func.h" | 9 #include "pk11func.h" |
| 10 #include "ocsp.h" | 10 #include "ocsp.h" |
| 11 | 11 |
| 12 /* NEED LOCKS IN HERE. */ | 12 /* NEED LOCKS IN HERE. */ |
| 13 CERTCertificate * | 13 CERTCertificate * |
| 14 SSL_PeerCertificate(PRFileDesc *fd) | 14 SSL_PeerCertificate(PRFileDesc *fd) |
| 15 { | 15 { |
| 16 sslSocket *ss; | 16 sslSocket *ss; |
| 17 | 17 |
| 18 ss = ssl_FindSocket(fd); | 18 ss = ssl_FindSocket(fd); |
| 19 if (!ss) { | 19 if (!ss) { |
| 20 » SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate", | 20 SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate", |
| 21 » » SSL_GETPID(), fd)); | 21 SSL_GETPID(), fd)); |
| 22 » return 0; | 22 return 0; |
| 23 } | 23 } |
| 24 if (ss->opt.useSecurity && ss->sec.peerCert) { | 24 if (ss->opt.useSecurity && ss->sec.peerCert) { |
| 25 » return CERT_DupCertificate(ss->sec.peerCert); | 25 return CERT_DupCertificate(ss->sec.peerCert); |
| 26 } | 26 } |
| 27 return 0; | 27 return 0; |
| 28 } | 28 } |
| 29 | 29 |
| 30 /* NEED LOCKS IN HERE. */ | 30 /* NEED LOCKS IN HERE. */ |
| 31 CERTCertList * | 31 CERTCertList * |
| 32 SSL_PeerCertificateChain(PRFileDesc *fd) | 32 SSL_PeerCertificateChain(PRFileDesc *fd) |
| 33 { | 33 { |
| 34 sslSocket *ss; | 34 sslSocket *ss; |
| 35 CERTCertList *chain = NULL; | 35 CERTCertList *chain = NULL; |
| 36 CERTCertificate *cert; | 36 CERTCertificate *cert; |
| 37 ssl3CertNode *cur; | 37 ssl3CertNode *cur; |
| 38 | 38 |
| 39 ss = ssl_FindSocket(fd); | 39 ss = ssl_FindSocket(fd); |
| 40 if (!ss) { | 40 if (!ss) { |
| 41 » SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificateChain", | 41 SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificateChain", |
| 42 » » SSL_GETPID(), fd)); | 42 SSL_GETPID(), fd)); |
| 43 » return NULL; | 43 return NULL; |
| 44 } | 44 } |
| 45 if (!ss->opt.useSecurity || !ss->sec.peerCert) { | 45 if (!ss->opt.useSecurity || !ss->sec.peerCert) { |
| 46 » PORT_SetError(SSL_ERROR_NO_CERTIFICATE); | 46 PORT_SetError(SSL_ERROR_NO_CERTIFICATE); |
| 47 » return NULL; | 47 return NULL; |
| 48 } | 48 } |
| 49 chain = CERT_NewCertList(); | 49 chain = CERT_NewCertList(); |
| 50 if (!chain) { | 50 if (!chain) { |
| 51 » return NULL; | 51 return NULL; |
| 52 } | 52 } |
| 53 cert = CERT_DupCertificate(ss->sec.peerCert); | 53 cert = CERT_DupCertificate(ss->sec.peerCert); |
| 54 if (CERT_AddCertToListTail(chain, cert) != SECSuccess) { | 54 if (CERT_AddCertToListTail(chain, cert) != SECSuccess) { |
| 55 » goto loser; | 55 goto loser; |
| 56 } | 56 } |
| 57 for (cur = ss->ssl3.peerCertChain; cur; cur = cur->next) { | 57 for (cur = ss->ssl3.peerCertChain; cur; cur = cur->next) { |
| 58 » cert = CERT_DupCertificate(cur->cert); | 58 cert = CERT_DupCertificate(cur->cert); |
| 59 » if (CERT_AddCertToListTail(chain, cert) != SECSuccess) { | 59 if (CERT_AddCertToListTail(chain, cert) != SECSuccess) { |
| 60 » goto loser; | 60 goto loser; |
| 61 » } | 61 } |
| 62 } | 62 } |
| 63 return chain; | 63 return chain; |
| 64 | 64 |
| 65 loser: | 65 loser: |
| 66 CERT_DestroyCertList(chain); | 66 CERT_DestroyCertList(chain); |
| 67 return NULL; | 67 return NULL; |
| 68 } | 68 } |
| 69 | 69 |
| 70 /* NEED LOCKS IN HERE. */ | 70 /* NEED LOCKS IN HERE. */ |
| 71 CERTCertificate * | 71 CERTCertificate * |
| 72 SSL_LocalCertificate(PRFileDesc *fd) | 72 SSL_LocalCertificate(PRFileDesc *fd) |
| 73 { | 73 { |
| 74 sslSocket *ss; | 74 sslSocket *ss; |
| 75 | 75 |
| 76 ss = ssl_FindSocket(fd); | 76 ss = ssl_FindSocket(fd); |
| 77 if (!ss) { | 77 if (!ss) { |
| 78 » SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate", | 78 SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate", |
| 79 » » SSL_GETPID(), fd)); | 79 SSL_GETPID(), fd)); |
| 80 » return NULL; | 80 return NULL; |
| 81 } | 81 } |
| 82 if (ss->opt.useSecurity) { | 82 if (ss->opt.useSecurity) { |
| 83 » if (ss->sec.localCert) { | 83 if (ss->sec.localCert) { |
| 84 » return CERT_DupCertificate(ss->sec.localCert); | 84 return CERT_DupCertificate(ss->sec.localCert); |
| 85 » } | 85 } |
| 86 » if (ss->sec.ci.sid && ss->sec.ci.sid->localCert) { | 86 if (ss->sec.ci.sid && ss->sec.ci.sid->localCert) { |
| 87 » return CERT_DupCertificate(ss->sec.ci.sid->localCert); | 87 return CERT_DupCertificate(ss->sec.ci.sid->localCert); |
| 88 » } | 88 } |
| 89 } | 89 } |
| 90 return NULL; | 90 return NULL; |
| 91 } | 91 } |
| 92 | 92 |
| 93 | |
| 94 | |
| 95 /* NEED LOCKS IN HERE. */ | 93 /* NEED LOCKS IN HERE. */ |
| 96 SECStatus | 94 SECStatus |
| 97 SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1, | 95 SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1, |
| 98 » » char **ip, char **sp) | 96 char **ip, char **sp) |
| 99 { | 97 { |
| 100 sslSocket *ss; | 98 sslSocket *ss; |
| 101 const char *cipherName; | 99 const char *cipherName; |
| 102 PRBool isDes = PR_FALSE; | 100 PRBool isDes = PR_FALSE; |
| 103 | 101 |
| 104 ss = ssl_FindSocket(fd); | 102 ss = ssl_FindSocket(fd); |
| 105 if (!ss) { | 103 if (!ss) { |
| 106 » SSL_DBG(("%d: SSL[%d]: bad socket in SecurityStatus", | 104 SSL_DBG(("%d: SSL[%d]: bad socket in SecurityStatus", |
| 107 » » SSL_GETPID(), fd)); | 105 SSL_GETPID(), fd)); |
| 108 » return SECFailure; | 106 return SECFailure; |
| 109 } | 107 } |
| 110 | 108 |
| 111 if (cp) *cp = 0; | 109 if (cp) |
| 112 if (kp0) *kp0 = 0; | 110 *cp = 0; |
| 113 if (kp1) *kp1 = 0; | 111 if (kp0) |
| 114 if (ip) *ip = 0; | 112 *kp0 = 0; |
| 115 if (sp) *sp = 0; | 113 if (kp1) |
| 114 *kp1 = 0; |
| 115 if (ip) |
| 116 *ip = 0; |
| 117 if (sp) |
| 118 *sp = 0; |
| 116 if (op) { | 119 if (op) { |
| 117 » *op = SSL_SECURITY_STATUS_OFF; | 120 *op = SSL_SECURITY_STATUS_OFF; |
| 118 } | 121 } |
| 119 | 122 |
| 120 if (ss->opt.useSecurity && ss->enoughFirstHsDone) { | 123 if (ss->opt.useSecurity && ss->enoughFirstHsDone) { |
| 121 » if (ss->version < SSL_LIBRARY_VERSION_3_0) { | 124 if (ss->version < SSL_LIBRARY_VERSION_3_0) { |
| 122 » cipherName = ssl_cipherName[ss->sec.cipherType]; | 125 cipherName = ssl_cipherName[ss->sec.cipherType]; |
| 123 » } else { | 126 } else { |
| 124 » cipherName = ssl3_cipherName[ss->sec.cipherType]; | 127 cipherName = ssl3_cipherName[ss->sec.cipherType]; |
| 125 » } | 128 } |
| 126 » PORT_Assert(cipherName); | 129 PORT_Assert(cipherName); |
| 127 » if (cipherName) { | 130 if (cipherName) { |
| 128 if (PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE; | 131 if (PORT_Strstr(cipherName, "DES")) |
| 132 isDes = PR_TRUE; |
| 129 | 133 |
| 130 if (cp) { | 134 if (cp) { |
| 131 *cp = PORT_Strdup(cipherName); | 135 *cp = PORT_Strdup(cipherName); |
| 132 } | 136 } |
| 133 } | 137 } |
| 134 | 138 |
| 135 » if (kp0) { | 139 if (kp0) { |
| 136 » *kp0 = ss->sec.keyBits; | 140 *kp0 = ss->sec.keyBits; |
| 137 » if (isDes) *kp0 = (*kp0 * 7) / 8; | 141 if (isDes) |
| 138 » } | 142 *kp0 = (*kp0 * 7) / 8; |
| 139 » if (kp1) { | 143 } |
| 140 » *kp1 = ss->sec.secretKeyBits; | 144 if (kp1) { |
| 141 » if (isDes) *kp1 = (*kp1 * 7) / 8; | 145 *kp1 = ss->sec.secretKeyBits; |
| 142 » } | 146 if (isDes) |
| 143 » if (op) { | 147 *kp1 = (*kp1 * 7) / 8; |
| 144 » if (ss->sec.keyBits == 0) { | 148 } |
| 145 » » *op = SSL_SECURITY_STATUS_OFF; | 149 if (op) { |
| 146 » } else if (ss->sec.secretKeyBits < 90) { | 150 if (ss->sec.keyBits == 0) { |
| 147 » » *op = SSL_SECURITY_STATUS_ON_LOW; | 151 *op = SSL_SECURITY_STATUS_OFF; |
| 152 } else if (ss->sec.secretKeyBits < 90) { |
| 153 *op = SSL_SECURITY_STATUS_ON_LOW; |
| 154 } else { |
| 155 *op = SSL_SECURITY_STATUS_ON_HIGH; |
| 156 } |
| 157 } |
| 148 | 158 |
| 149 » } else { | 159 if (ip || sp) { |
| 150 » » *op = SSL_SECURITY_STATUS_ON_HIGH; | 160 CERTCertificate *cert; |
| 151 » } | |
| 152 » } | |
| 153 | 161 |
| 154 » if (ip || sp) { | 162 cert = ss->sec.peerCert; |
| 155 » CERTCertificate *cert; | 163 if (cert) { |
| 156 | 164 if (ip) { |
| 157 » cert = ss->sec.peerCert; | 165 *ip = CERT_NameToAscii(&cert->issuer); |
| 158 » if (cert) { | 166 } |
| 159 » » if (ip) { | 167 if (sp) { |
| 160 » » *ip = CERT_NameToAscii(&cert->issuer); | 168 *sp = CERT_NameToAscii(&cert->subject); |
| 161 » » } | 169 } |
| 162 » » if (sp) { | 170 } else { |
| 163 » » *sp = CERT_NameToAscii(&cert->subject); | 171 if (ip) { |
| 164 » » } | 172 *ip = PORT_Strdup("no certificate"); |
| 165 » } else { | 173 } |
| 166 » » if (ip) { | 174 if (sp) { |
| 167 » » *ip = PORT_Strdup("no certificate"); | 175 *sp = PORT_Strdup("no certificate"); |
| 168 » » } | 176 } |
| 169 » » if (sp) { | 177 } |
| 170 » » *sp = PORT_Strdup("no certificate"); | 178 } |
| 171 » » } | |
| 172 » } | |
| 173 » } | |
| 174 } | 179 } |
| 175 | 180 |
| 176 return SECSuccess; | 181 return SECSuccess; |
| 177 } | 182 } |
| 178 | 183 |
| 179 /************************************************************************/ | 184 /************************************************************************/ |
| 180 | 185 |
| 181 /* NEED LOCKS IN HERE. */ | 186 /* NEED LOCKS IN HERE. */ |
| 182 SECStatus | 187 SECStatus |
| 183 SSL_AuthCertificateHook(PRFileDesc *s, SSLAuthCertificate func, void *arg) | 188 SSL_AuthCertificateHook(PRFileDesc *s, SSLAuthCertificate func, void *arg) |
| 184 { | 189 { |
| 185 sslSocket *ss; | 190 sslSocket *ss; |
| 186 | 191 |
| 187 ss = ssl_FindSocket(s); | 192 ss = ssl_FindSocket(s); |
| 188 if (!ss) { | 193 if (!ss) { |
| 189 » SSL_DBG(("%d: SSL[%d]: bad socket in AuthCertificateHook", | 194 SSL_DBG(("%d: SSL[%d]: bad socket in AuthCertificateHook", |
| 190 » » SSL_GETPID(), s)); | 195 SSL_GETPID(), s)); |
| 191 » return SECFailure; | 196 return SECFailure; |
| 192 } | 197 } |
| 193 | 198 |
| 194 ss->authCertificate = func; | 199 ss->authCertificate = func; |
| 195 ss->authCertificateArg = arg; | 200 ss->authCertificateArg = arg; |
| 196 | 201 |
| 197 return SECSuccess; | 202 return SECSuccess; |
| 198 } | 203 } |
| 199 | 204 |
| 200 /* NEED LOCKS IN HERE. */ | 205 /* NEED LOCKS IN HERE. */ |
| 201 SECStatus | 206 SECStatus |
| 202 SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func, | 207 SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func, |
| 203 » » » void *arg) | 208 void *arg) |
| 204 { | 209 { |
| 205 sslSocket *ss; | 210 sslSocket *ss; |
| 206 | 211 |
| 207 ss = ssl_FindSocket(s); | 212 ss = ssl_FindSocket(s); |
| 208 if (!ss) { | 213 if (!ss) { |
| 209 » SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook", | 214 SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook", |
| 210 » » SSL_GETPID(), s)); | 215 SSL_GETPID(), s)); |
| 211 » return SECFailure; | 216 return SECFailure; |
| 212 } | 217 } |
| 213 | 218 |
| 214 ss->getClientAuthData = func; | 219 ss->getClientAuthData = func; |
| 215 ss->getClientAuthDataArg = arg; | 220 ss->getClientAuthDataArg = arg; |
| 216 return SECSuccess; | 221 return SECSuccess; |
| 217 } | 222 } |
| 218 | 223 |
| 219 SECStatus | 224 SECStatus |
| 220 SSL_SetClientChannelIDCallback(PRFileDesc *fd, | 225 SSL_SetClientChannelIDCallback(PRFileDesc *fd, |
| 221 » » » SSLClientChannelIDCallback callback, | 226 SSLClientChannelIDCallback callback, |
| 222 » » » void *arg) { | 227 void *arg) |
| 228 { |
| 223 sslSocket *ss = ssl_FindSocket(fd); | 229 sslSocket *ss = ssl_FindSocket(fd); |
| 224 | 230 |
| 225 if (!ss) { | 231 if (!ss) { |
| 226 » SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetClientChannelIDCallback", | 232 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetClientChannelIDCallback", |
| 227 » » SSL_GETPID(), fd)); | 233 SSL_GETPID(), fd)); |
| 228 » return SECFailure; | 234 return SECFailure; |
| 229 } | 235 } |
| 230 | 236 |
| 231 ss->getChannelID = callback; | 237 ss->getChannelID = callback; |
| 232 ss->getChannelIDArg = arg; | 238 ss->getChannelIDArg = arg; |
| 233 | 239 |
| 234 return SECSuccess; | 240 return SECSuccess; |
| 235 } | 241 } |
| 236 | 242 |
| 237 #ifdef NSS_PLATFORM_CLIENT_AUTH | |
| 238 /* NEED LOCKS IN HERE. */ | 243 /* NEED LOCKS IN HERE. */ |
| 239 SECStatus | 244 SECStatus |
| 240 SSL_GetPlatformClientAuthDataHook(PRFileDesc *s, | |
| 241 SSLGetPlatformClientAuthData func, | |
| 242 void *arg) | |
| 243 { | |
| 244 sslSocket *ss; | |
| 245 | |
| 246 ss = ssl_FindSocket(s); | |
| 247 if (!ss) { | |
| 248 » SSL_DBG(("%d: SSL[%d]: bad socket in GetPlatformClientAuthDataHook", | |
| 249 » » SSL_GETPID(), s)); | |
| 250 » return SECFailure; | |
| 251 } | |
| 252 | |
| 253 ss->getPlatformClientAuthData = func; | |
| 254 ss->getPlatformClientAuthDataArg = arg; | |
| 255 return SECSuccess; | |
| 256 } | |
| 257 #endif /* NSS_PLATFORM_CLIENT_AUTH */ | |
| 258 | |
| 259 /* NEED LOCKS IN HERE. */ | |
| 260 SECStatus | |
| 261 SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg) | 245 SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg) |
| 262 { | 246 { |
| 263 sslSocket *ss; | 247 sslSocket *ss; |
| 264 | 248 |
| 265 ss = ssl_FindSocket(s); | 249 ss = ssl_FindSocket(s); |
| 266 if (!ss) { | 250 if (!ss) { |
| 267 » SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook", | 251 SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook", |
| 268 » » SSL_GETPID(), s)); | 252 SSL_GETPID(), s)); |
| 269 » return SECFailure; | 253 return SECFailure; |
| 270 } | 254 } |
| 271 | 255 |
| 272 ss->pkcs11PinArg = arg; | 256 ss->pkcs11PinArg = arg; |
| 273 return SECSuccess; | 257 return SECSuccess; |
| 274 } | 258 } |
| 275 | 259 |
| 276 | 260 /* This is the "default" authCert callback function. It is called when a |
| 277 /* This is the "default" authCert callback function. It is called when a | |
| 278 * certificate message is received from the peer and the local application | 261 * certificate message is received from the peer and the local application |
| 279 * has not registered an authCert callback function. | 262 * has not registered an authCert callback function. |
| 280 */ | 263 */ |
| 281 SECStatus | 264 SECStatus |
| 282 SSL_AuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) | 265 SSL_AuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) |
| 283 { | 266 { |
| 284 SECStatus rv; | 267 SECStatus rv; |
| 285 CERTCertDBHandle * handle; | 268 CERTCertDBHandle *handle; |
| 286 sslSocket * ss; | 269 sslSocket *ss; |
| 287 SECCertUsage certUsage; | 270 SECCertUsage certUsage; |
| 288 const char * hostname = NULL; | 271 const char *hostname = NULL; |
| 289 PRTime now = PR_Now(); | 272 PRTime now = PR_Now(); |
| 290 SECItemArray * certStatusArray; | 273 SECItemArray *certStatusArray; |
| 291 | 274 |
| 292 ss = ssl_FindSocket(fd); | 275 ss = ssl_FindSocket(fd); |
| 293 PORT_Assert(ss != NULL); | 276 PORT_Assert(ss != NULL); |
| 294 if (!ss) { | 277 if (!ss) { |
| 295 » return SECFailure; | 278 return SECFailure; |
| 296 } | 279 } |
| 297 | 280 |
| 298 handle = (CERTCertDBHandle *)arg; | 281 handle = (CERTCertDBHandle *)arg; |
| 299 certStatusArray = &ss->sec.ci.sid->peerCertStatus; | 282 certStatusArray = &ss->sec.ci.sid->peerCertStatus; |
| 300 | 283 |
| 301 if (certStatusArray->len) { | 284 if (certStatusArray->len) { |
| 302 » PORT_SetError(0); | 285 PORT_SetError(0); |
| 303 » if (CERT_CacheOCSPResponseFromSideChannel(handle, ss->sec.peerCert, now, | 286 if (CERT_CacheOCSPResponseFromSideChannel(handle, ss->sec.peerCert, now, |
| 304 » » » » » » &certStatusArray->items[0], | 287 &certStatusArray->items[0], |
| 305 » » » » » » ss->pkcs11PinArg) | 288 ss->pkcs11PinArg) != |
| 306 » » != SECSuccess) { | 289 SECSuccess) { |
| 307 » PORT_Assert(PR_GetError() != 0); | 290 PORT_Assert(PR_GetError() != 0); |
| 308 » } | 291 } |
| 309 } | 292 } |
| 310 | 293 |
| 311 /* this may seem backwards, but isn't. */ | 294 /* this may seem backwards, but isn't. */ |
| 312 certUsage = isServer ? certUsageSSLClient : certUsageSSLServer; | 295 certUsage = isServer ? certUsageSSLClient : certUsageSSLServer; |
| 313 | 296 |
| 314 rv = CERT_VerifyCert(handle, ss->sec.peerCert, checkSig, certUsage, | 297 rv = CERT_VerifyCert(handle, ss->sec.peerCert, checkSig, certUsage, |
| 315 » » » now, ss->pkcs11PinArg, NULL); | 298 now, ss->pkcs11PinArg, NULL); |
| 316 | 299 |
| 317 if ( rv != SECSuccess || isServer ) | 300 if (rv != SECSuccess || isServer) |
| 318 » return rv; | 301 return rv; |
| 319 | 302 |
| 320 /* cert is OK. This is the client side of an SSL connection. | 303 /* cert is OK. This is the client side of an SSL connection. |
| 321 * Now check the name field in the cert against the desired hostname. | 304 * Now check the name field in the cert against the desired hostname. |
| 322 * NB: This is our only defense against Man-In-The-Middle (MITM) attacks! | 305 * NB: This is our only defense against Man-In-The-Middle (MITM) attacks! |
| 323 */ | 306 */ |
| 324 hostname = ss->url; | 307 hostname = ss->url; |
| 325 if (hostname && hostname[0]) | 308 if (hostname && hostname[0]) |
| 326 » rv = CERT_VerifyCertName(ss->sec.peerCert, hostname); | 309 rv = CERT_VerifyCertName(ss->sec.peerCert, hostname); |
| 327 else | 310 else |
| 328 » rv = SECFailure; | 311 rv = SECFailure; |
| 329 if (rv != SECSuccess) | 312 if (rv != SECSuccess) |
| 330 » PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); | 313 PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); |
| 331 | 314 |
| 332 return rv; | 315 return rv; |
| 333 } | 316 } |
| OLD | NEW |