• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
25 SECStatus
NSS_GetClientAuthData(void * arg,PRFileDesc * socket,struct CERTDistNamesStr * caNames,struct CERTCertificateStr ** pRetCert,struct SECKEYPrivateKeyStr ** pRetKey)26 NSS_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