12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* This Source Code Form is subject to the terms of the Mozilla Public 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * License, v. 2.0. If a copy of the MPL was not distributed with this 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "cert.h" 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "secitem.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ssl.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslimpl.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslproto.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pk11func.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ocsp.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* NEED LOCKS IN HERE. */ 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CERTCertificate * 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_PeerCertificate(PRFileDesc *fd) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket *ss; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss = ssl_FindSocket(fd); 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate", 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), fd)); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.useSecurity && ss->sec.peerCert) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CERT_DupCertificate(ss->sec.peerCert); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* NEED LOCKS IN HERE. */ 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CERTCertList * 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SSL_PeerCertificateChain(PRFileDesc *fd) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket *ss; 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CERTCertList *chain = NULL; 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CERTCertificate *cert; 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ssl3CertNode *cur; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss = ssl_FindSocket(fd); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificateChain", 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), fd)); 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!ss->opt.useSecurity || !ss->sec.peerCert) { 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PORT_SetError(SSL_ERROR_NO_CERTIFICATE); 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chain = CERT_NewCertList(); 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!chain) { 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cert = CERT_DupCertificate(ss->sec.peerCert); 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (CERT_AddCertToListTail(chain, cert) != SECSuccess) { 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) goto loser; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (cur = ss->ssl3.peerCertChain; cur; cur = cur->next) { 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cert = CERT_DupCertificate(cur->cert); 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (CERT_AddCertToListTail(chain, cert) != SECSuccess) { 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) goto loser; 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return chain; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)loser: 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CERT_DestroyCertList(chain); 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* NEED LOCKS IN HERE. */ 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CERTCertificate * 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_LocalCertificate(PRFileDesc *fd) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket *ss; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss = ssl_FindSocket(fd); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate", 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), fd)); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.useSecurity) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->sec.localCert) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CERT_DupCertificate(ss->sec.localCert); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->sec.ci.sid && ss->sec.ci.sid->localCert) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CERT_DupCertificate(ss->sec.ci.sid->localCert); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* NEED LOCKS IN HERE. */ 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **ip, char **sp) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket *ss; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *cipherName; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool isDes = PR_FALSE; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss = ssl_FindSocket(fd); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: bad socket in SecurityStatus", 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), fd)); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cp) *cp = 0; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kp0) *kp0 = 0; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kp1) *kp1 = 0; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ip) *ip = 0; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sp) *sp = 0; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (op) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *op = SSL_SECURITY_STATUS_OFF; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (ss->opt.useSecurity && ss->enoughFirstHsDone) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->version < SSL_LIBRARY_VERSION_3_0) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cipherName = ssl_cipherName[ss->sec.cipherType]; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cipherName = ssl3_cipherName[ss->sec.cipherType]; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(cipherName); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cipherName) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cp) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cp = PORT_Strdup(cipherName); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kp0) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *kp0 = ss->sec.keyBits; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isDes) *kp0 = (*kp0 * 7) / 8; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kp1) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *kp1 = ss->sec.secretKeyBits; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isDes) *kp1 = (*kp1 * 7) / 8; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (op) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->sec.keyBits == 0) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *op = SSL_SECURITY_STATUS_OFF; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ss->sec.secretKeyBits < 90) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *op = SSL_SECURITY_STATUS_ON_LOW; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *op = SSL_SECURITY_STATUS_ON_HIGH; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ip || sp) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERTCertificate *cert; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert = ss->sec.peerCert; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cert) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ip) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ip = CERT_NameToAscii(&cert->issuer); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sp) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = CERT_NameToAscii(&cert->subject); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ip) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ip = PORT_Strdup("no certificate"); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sp) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = PORT_Strdup("no certificate"); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************/ 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* NEED LOCKS IN HERE. */ 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_AuthCertificateHook(PRFileDesc *s, SSLAuthCertificate func, void *arg) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket *ss; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss = ssl_FindSocket(s); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: bad socket in AuthCertificateHook", 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), s)); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->authCertificate = func; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->authCertificateArg = arg; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* NEED LOCKS IN HERE. */ 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func, 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *arg) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket *ss; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss = ssl_FindSocket(s); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook", 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), s)); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->getClientAuthData = func; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->getClientAuthDataArg = arg; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_SetClientChannelIDCallback(PRFileDesc *fd, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLClientChannelIDCallback callback, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *arg) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket *ss = ssl_FindSocket(fd); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetClientChannelIDCallback", 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), fd)); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->getChannelID = callback; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->getChannelIDArg = arg; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_PLATFORM_CLIENT_AUTH 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* NEED LOCKS IN HERE. */ 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_GetPlatformClientAuthDataHook(PRFileDesc *s, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLGetPlatformClientAuthData func, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *arg) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket *ss; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss = ssl_FindSocket(s); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: bad socket in GetPlatformClientAuthDataHook", 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), s)); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->getPlatformClientAuthData = func; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->getPlatformClientAuthDataArg = arg; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* NSS_PLATFORM_CLIENT_AUTH */ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* NEED LOCKS IN HERE. */ 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket *ss; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss = ssl_FindSocket(s); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook", 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), s)); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->pkcs11PinArg = arg; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This is the "default" authCert callback function. It is called when a 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * certificate message is received from the peer and the local application 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * has not registered an authCert callback function. 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_AuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERTCertDBHandle * handle; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket * ss; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECCertUsage certUsage; 288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const char * hostname = NULL; 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRTime now = PR_Now(); 290a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SECItemArray * certStatusArray; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss = ssl_FindSocket(fd); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(ss != NULL); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle = (CERTCertDBHandle *)arg; 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) certStatusArray = &ss->sec.ci.sid->peerCertStatus; 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (certStatusArray->len) { 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PORT_SetError(0); 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (CERT_CacheOCSPResponseFromSideChannel(handle, ss->sec.peerCert, now, 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &certStatusArray->items[0], 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ss->pkcs11PinArg) 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) != SECSuccess) { 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PRErrorCode error = PR_GetError(); 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PORT_Assert(error != 0); 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* this may seem backwards, but isn't. */ 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) certUsage = isServer ? certUsageSSLClient : certUsageSSLServer; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = CERT_VerifyCert(handle, ss->sec.peerCert, checkSig, certUsage, 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) now, ss->pkcs11PinArg, NULL); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( rv != SECSuccess || isServer ) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* cert is OK. This is the client side of an SSL connection. 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Now check the name field in the cert against the desired hostname. 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NB: This is our only defense against Man-In-The-Middle (MITM) attacks! 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostname = ss->url; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hostname && hostname[0]) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = CERT_VerifyCertName(ss->sec.peerCert, hostname); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECFailure; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335