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