1/* 2 * NSS utility functions 3 * 4 * This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 8#include <stdio.h> 9#include <string.h> 10#include "prerror.h" 11#include "secitem.h" 12#include "prnetdb.h" 13#include "cert.h" 14#include "nspr.h" 15#include "secder.h" 16#include "key.h" 17#include "nss.h" 18#include "ssl.h" 19#include "pk11func.h" /* for PK11_ function calls */ 20 21/* 22 * This callback used by SSL to pull client sertificate upon 23 * server request 24 */ 25SECStatus 26NSS_GetClientAuthData(void * arg, 27 PRFileDesc * socket, 28 struct CERTDistNamesStr * caNames, 29 struct CERTCertificateStr ** pRetCert, 30 struct SECKEYPrivateKeyStr **pRetKey) 31{ 32 CERTCertificate * cert = NULL; 33 SECKEYPrivateKey * privkey = NULL; 34 char * chosenNickName = (char *)arg; /* CONST */ 35 void * proto_win = NULL; 36 SECStatus rv = SECFailure; 37 38 proto_win = SSL_RevealPinArg(socket); 39 40 if (chosenNickName) { 41 cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(), 42 chosenNickName, certUsageSSLClient, 43 PR_FALSE, proto_win); 44 if ( cert ) { 45 privkey = PK11_FindKeyByAnyCert(cert, proto_win); 46 if ( privkey ) { 47 rv = SECSuccess; 48 } else { 49 CERT_DestroyCertificate(cert); 50 } 51 } 52 } else { /* no name given, automatically find the right cert. */ 53 CERTCertNicknames * names; 54 int i; 55 56 names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(), 57 SEC_CERT_NICKNAMES_USER, proto_win); 58 if (names != NULL) { 59 for (i = 0; i < names->numnicknames; i++) { 60 cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(), 61 names->nicknames[i], certUsageSSLClient, 62 PR_FALSE, proto_win); 63 if ( !cert ) 64 continue; 65 /* Only check unexpired certs */ 66 if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) != 67 secCertTimeValid ) { 68 CERT_DestroyCertificate(cert); 69 continue; 70 } 71 rv = NSS_CmpCertChainWCANames(cert, caNames); 72 if ( rv == SECSuccess ) { 73 privkey = PK11_FindKeyByAnyCert(cert, proto_win); 74 if ( privkey ) 75 break; 76 } 77 rv = SECFailure; 78 CERT_DestroyCertificate(cert); 79 } 80 CERT_FreeNicknames(names); 81 } 82 } 83 if (rv == SECSuccess) { 84 *pRetCert = cert; 85 *pRetKey = privkey; 86 } 87 return rv; 88} 89 90