- add sources.
[platform/framework/web/crosswalk.git] / src / net / third_party / nss / ssl / authcert.c
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