security/nss/lib/ssl/authcert.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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/. */
     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 */
    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;
    38   proto_win = SSL_RevealPinArg(socket);
    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;
    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 }

mercurial