michael@0: /* michael@0: * NSS utility functions michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: #include michael@0: #include "prerror.h" michael@0: #include "secitem.h" michael@0: #include "prnetdb.h" michael@0: #include "cert.h" michael@0: #include "nspr.h" michael@0: #include "secder.h" michael@0: #include "key.h" michael@0: #include "nss.h" michael@0: #include "ssl.h" michael@0: #include "pk11func.h" /* for PK11_ function calls */ michael@0: michael@0: /* michael@0: * This callback used by SSL to pull client sertificate upon michael@0: * server request michael@0: */ michael@0: SECStatus michael@0: NSS_GetClientAuthData(void * arg, michael@0: PRFileDesc * socket, michael@0: struct CERTDistNamesStr * caNames, michael@0: struct CERTCertificateStr ** pRetCert, michael@0: struct SECKEYPrivateKeyStr **pRetKey) michael@0: { michael@0: CERTCertificate * cert = NULL; michael@0: SECKEYPrivateKey * privkey = NULL; michael@0: char * chosenNickName = (char *)arg; /* CONST */ michael@0: void * proto_win = NULL; michael@0: SECStatus rv = SECFailure; michael@0: michael@0: proto_win = SSL_RevealPinArg(socket); michael@0: michael@0: if (chosenNickName) { michael@0: cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(), michael@0: chosenNickName, certUsageSSLClient, michael@0: PR_FALSE, proto_win); michael@0: if ( cert ) { michael@0: privkey = PK11_FindKeyByAnyCert(cert, proto_win); michael@0: if ( privkey ) { michael@0: rv = SECSuccess; michael@0: } else { michael@0: CERT_DestroyCertificate(cert); michael@0: } michael@0: } michael@0: } else { /* no name given, automatically find the right cert. */ michael@0: CERTCertNicknames * names; michael@0: int i; michael@0: michael@0: names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(), michael@0: SEC_CERT_NICKNAMES_USER, proto_win); michael@0: if (names != NULL) { michael@0: for (i = 0; i < names->numnicknames; i++) { michael@0: cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(), michael@0: names->nicknames[i], certUsageSSLClient, michael@0: PR_FALSE, proto_win); michael@0: if ( !cert ) michael@0: continue; michael@0: /* Only check unexpired certs */ michael@0: if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) != michael@0: secCertTimeValid ) { michael@0: CERT_DestroyCertificate(cert); michael@0: continue; michael@0: } michael@0: rv = NSS_CmpCertChainWCANames(cert, caNames); michael@0: if ( rv == SECSuccess ) { michael@0: privkey = PK11_FindKeyByAnyCert(cert, proto_win); michael@0: if ( privkey ) michael@0: break; michael@0: } michael@0: rv = SECFailure; michael@0: CERT_DestroyCertificate(cert); michael@0: } michael@0: CERT_FreeNicknames(names); michael@0: } michael@0: } michael@0: if (rv == SECSuccess) { michael@0: *pRetCert = cert; michael@0: *pRetKey = privkey; michael@0: } michael@0: return rv; michael@0: } michael@0: