Tizen 2.0 Release
[external/libgnutls26.git] / src / p11common.c
1 /*
2  * Copyright (C) 2011 Free Software Foundation, Inc.
3  * Author: Nikos Mavrogiannopoulos
4  *
5  * This file is part of GnuTLS.
6  *
7  * GnuTLS is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuTLS is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #include <getpass.h>
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <gnutls/pkcs11.h>
29 #include <p11common.h>
30
31 #define MIN(x,y) ((x)<(y))?(x):(y)
32
33 #define MAX_CACHE_TRIES 5
34 static int
35 pin_callback (void *user, int attempt, const char *token_url,
36               const char *token_label, unsigned int flags, char *pin,
37               size_t pin_max)
38 {
39   const char *password;
40   const char * desc;
41   int len, cache = MAX_CACHE_TRIES;
42 /* allow caching of PIN */
43   static char *cached_url = NULL;
44   static char cached_pin[32] = "";
45
46   if (flags & GNUTLS_PKCS11_PIN_SO)
47     desc = "security officer";
48   else
49     desc = "user";
50
51   if (flags & GNUTLS_PKCS11_PIN_FINAL_TRY)
52     {
53       cache = 0;
54       printf ("*** This is the final try before locking!\n");
55     }
56   if (flags & GNUTLS_PKCS11_PIN_COUNT_LOW)
57     {
58       cache = 0;
59       printf ("*** Only few tries left before locking!\n");
60     }
61
62   if (flags & GNUTLS_PKCS11_PIN_WRONG)
63     {
64       cache = 0;
65       printf ("*** Wrong PIN has been provided!\n");
66     }
67     
68   if (cache > 0 && cached_url != NULL)
69     {
70       if (strcmp (cached_url, token_url) == 0)
71         {
72           if (strlen(pin) >= sizeof(cached_pin))
73             {
74               fprintf (stderr, "Too long PIN given\n");
75               exit (1);
76             }
77
78           fprintf(stderr, "Re-using cached PIN for token '%s'\n", token_label);
79           strcpy (pin, cached_pin);
80           cache--;
81           return 0;
82         }
83     }
84
85   printf ("Token '%s' with URL '%s' ", token_label, token_url);
86   printf ("requires %s PIN\n", desc);
87
88   password = getpass ("Enter PIN: ");
89   if (password == NULL || password[0] == 0)
90     {
91       fprintf (stderr, "No password given\n");
92       exit (1);
93     }
94
95   len = MIN (pin_max, strlen (password));
96   memcpy (pin, password, len);
97   pin[len] = 0;
98
99   /* cache */
100   strcpy (cached_pin, pin);
101   free (cached_url);
102   cached_url = strdup (token_url);
103   cache = MAX_CACHE_TRIES;
104
105   return 0;
106 }
107
108 static int
109 token_callback (void *user, const char *label, const unsigned retry)
110 {
111   char buf[32];
112   char *p;
113
114   if (retry > 0)
115     {
116       fprintf (stderr, "Could not find token %s\n", label);
117       return -1;
118     }
119   printf ("Please insert token '%s' in slot and press enter\n", label);
120   p = fgets (buf, sizeof (buf), stdin);
121   if (p==NULL) return -1;
122
123   return 0;
124 }
125
126 void
127 pkcs11_common (void)
128 {
129
130   gnutls_pkcs11_set_pin_function (pin_callback, NULL);
131   gnutls_pkcs11_set_token_function (token_callback, NULL);
132
133 }