* pksign.c (agent_pksign): Detect whether a Smartcard is to be
[gnupg.git] / agent / divert-scd.c
1 /* divert-scd.c - divert operations to the scdaemon 
2  *      Copyright (C) 2002 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <assert.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30
31 #include "agent.h"
32 #include "sexp-parse.h"
33
34
35
36 static int
37 ask_for_card (const unsigned char *shadow_info, char **r_kid)
38 {
39   int rc, i;
40   const unsigned char *s;
41   size_t n;
42   char *serialno;
43   int no_card = 0;
44   char *desc;
45   char *want_sn, *want_kid;
46
47   *r_kid = NULL;
48   s = shadow_info;
49   if (*s != '(')
50     return GNUPG_Invalid_Sexp;
51   s++;
52   n = snext (&s);
53   if (!n)
54     return GNUPG_Invalid_Sexp;
55   want_sn = xtrymalloc (n+1);
56   if (!want_sn)
57     return GNUPG_Out_Of_Core;
58   memcpy (want_sn, s, n);
59   want_sn[n] = 0;
60   s += n;
61
62   n = snext (&s);
63   if (!n)
64     return GNUPG_Invalid_Sexp;
65   want_kid = xtrymalloc (n+1);
66   if (!want_kid)
67     {
68       xfree (want_sn);
69       return GNUPG_Out_Of_Core;
70     }
71   memcpy (want_kid, s, n);
72   want_kid[n] = 0;
73
74   for (;;)
75     {
76       rc = agent_card_serialno (&serialno);
77       if (!rc)
78         {
79           log_debug ("detected card with S/N %s\n", serialno);
80           i = strcmp (serialno, want_sn);
81           xfree (serialno);
82           serialno = NULL;
83           if (!i)
84             {
85               xfree (want_sn);
86               *r_kid = want_kid;
87               return 0; /* yes, we have the correct card */
88             }
89         }
90       else if (rc == GNUPG_Card_Not_Present)
91         {
92           log_debug ("no card present\n");
93           rc = 0;
94           no_card = 1;
95         }
96       else
97         {
98           log_error ("error accesing card: %s\n", gnupg_strerror (rc));
99         }
100
101       if (!rc)
102         {
103           if (asprintf (&desc,
104                     "%s:%%0A%%0A"
105                     "  \"%s\"",
106                     no_card? "Please insert the card with serial number" 
107                     : "Please remove the current card and "
108                     "insert the one with serial number",
109                     want_sn) < 0)
110             {
111               rc = GNUPG_Out_Of_Core;
112             }
113           else
114             {
115               rc = agent_get_confirmation (desc, NULL);
116               free (desc);
117             }
118         }
119       if (rc)
120         {
121           xfree (want_sn);
122           xfree (want_kid);
123           return rc;
124         }
125     }
126 }
127
128
129
130 int
131 divert_pksign (GCRY_SEXP *s_sig, GCRY_SEXP s_hash, const char *shadow_info)
132 {
133   int rc;
134   char *kid;
135
136   rc = ask_for_card (shadow_info, &kid);
137   if (rc)
138     return rc;
139
140  
141   xfree (kid);
142   return GNUPG_Not_Implemented;
143 }
144
145
146 int 
147 divert_pkdecrypt (GCRY_SEXP *s_plain, GCRY_SEXP s_cipher,
148                   const char *shadow_info)
149 {
150   int rc;
151   char *kid;
152
153   rc = ask_for_card (shadow_info, &kid);
154   if (rc)
155     return rc;
156
157  
158   xfree (kid);
159   return GNUPG_Not_Implemented;
160 }
161
162
163