Home | History | Annotate | Download | only in ssl
      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
     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