chiark / gitweb /
gpg: Fix searching for mail addresses in keyrings.
[gnupg2.git] / agent / divert-scd.c
1 /* divert-scd.c - divert operations to the scdaemon
2  *      Copyright (C) 2002, 2003, 2009 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 3 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, see <https://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <assert.h>
27 #include <unistd.h>
28 #include <sys/stat.h>
29
30 #include "agent.h"
31 #include "i18n.h"
32 #include "sexp-parse.h"
33
34
35 static int
36 ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
37 {
38   int rc, i;
39   char *serialno;
40   int no_card = 0;
41   char *desc;
42   char *want_sn, *want_kid;
43   int want_sn_displen;
44
45   *r_kid = NULL;
46
47   rc = parse_shadow_info (shadow_info, &want_sn, &want_kid, NULL);
48   if (rc)
49     return rc;
50
51   /* We assume that a 20 byte serial number is a standard one which
52      has the property to have a zero in the last nibble (Due to BCD
53      representation).  We don't display this '0' because it may
54      confuse the user.  */
55   want_sn_displen = strlen (want_sn);
56   if (want_sn_displen == 20 && want_sn[19] == '0')
57     want_sn_displen--;
58
59   for (;;)
60     {
61       rc = agent_card_serialno (ctrl, &serialno, want_sn);
62       if (!rc)
63         {
64           log_debug ("detected card with S/N %s\n", serialno);
65           i = strcmp (serialno, want_sn);
66           xfree (serialno);
67           serialno = NULL;
68           if (!i)
69             {
70               xfree (want_sn);
71               *r_kid = want_kid;
72               return 0; /* yes, we have the correct card */
73             }
74         }
75       else if (gpg_err_code (rc) == GPG_ERR_ENODEV)
76         {
77           log_debug ("no device present\n");
78           rc = 0;
79           no_card = 1;
80         }
81       else if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT)
82         {
83           log_debug ("no card present\n");
84           rc = 0;
85           no_card = 2;
86         }
87       else
88         {
89           log_error ("error accessing card: %s\n", gpg_strerror (rc));
90         }
91
92       if (!rc)
93         {
94           if (asprintf (&desc,
95                     "%s:%%0A%%0A"
96                     "  \"%.*s\"",
97                         no_card
98                         ? L_("Please insert the card with serial number")
99                         : L_("Please remove the current card and "
100                              "insert the one with serial number"),
101                     want_sn_displen, want_sn) < 0)
102             {
103               rc = out_of_core ();
104             }
105           else
106             {
107               rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
108               if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK &&
109                   gpg_err_code (rc) == GPG_ERR_NO_PIN_ENTRY)
110                 rc = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
111
112               xfree (desc);
113             }
114         }
115       if (rc)
116         {
117           xfree (want_sn);
118           xfree (want_kid);
119           return rc;
120         }
121     }
122 }
123
124
125 /* Put the DIGEST into an DER encoded container and return it in R_VAL. */
126 static int
127 encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo,
128                     unsigned char **r_val, size_t *r_len)
129 {
130   unsigned char *frame;
131   unsigned char asn[100];
132   size_t asnlen;
133
134   *r_val = NULL;
135   *r_len = 0;
136
137   asnlen = DIM(asn);
138   if (!algo || gcry_md_test_algo (algo))
139     return gpg_error (GPG_ERR_DIGEST_ALGO);
140   if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
141     {
142       log_error ("no object identifier for algo %d\n", algo);
143       return gpg_error (GPG_ERR_INTERNAL);
144     }
145
146   frame = xtrymalloc (asnlen + digestlen);
147   if (!frame)
148     return out_of_core ();
149   memcpy (frame, asn, asnlen);
150   memcpy (frame+asnlen, digest, digestlen);
151   if (DBG_CRYPTO)
152     log_printhex ("encoded hash:", frame, asnlen+digestlen);
153
154   *r_val = frame;
155   *r_len = asnlen+digestlen;
156   return 0;
157 }
158
159
160 /* Callback used to ask for the PIN which should be set into BUF.  The
161    buf has been allocated by the caller and is of size MAXBUF which
162    includes the terminating null.  The function should return an UTF-8
163    string with the passphrase, the buffer may optionally be padded
164    with arbitrary characters.
165
166    INFO gets displayed as part of a generic string.  However if the
167    first character of INFO is a vertical bar all up to the next
168    verical bar are considered flags and only everything after the
169    second vertical bar gets displayed as the full prompt.
170
171    Flags:
172
173       'N' = New PIN, this requests a second prompt to repeat the
174             PIN.  If the PIN is not correctly repeated it starts from
175             all over.
176       'A' = The PIN is an Admin PIN, SO-PIN or alike.
177       'P' = The PIN is a PUK (Personal Unblocking Key).
178       'R' = The PIN is a Reset Code.
179
180    Example:
181
182      "|AN|Please enter the new security officer's PIN"
183
184    The text "Please ..." will get displayed and the flags 'A' and 'N'
185    are considered.
186  */
187 static int
188 getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
189 {
190   struct pin_entry_info_s *pi;
191   int rc;
192   ctrl_t ctrl = opaque;
193   const char *ends, *s;
194   int any_flags = 0;
195   int newpin = 0;
196   int resetcode = 0;
197   int is_puk = 0;
198   const char *again_text = NULL;
199   const char *prompt = "PIN";
200
201   if (buf && maxbuf < 2)
202     return gpg_error (GPG_ERR_INV_VALUE);
203
204   /* Parse the flags. */
205   if (info && *info =='|' && (ends=strchr (info+1, '|')))
206     {
207       for (s=info+1; s < ends; s++)
208         {
209           if (*s == 'A')
210             prompt = L_("Admin PIN");
211           else if (*s == 'P')
212             {
213               /* TRANSLATORS: A PUK is the Personal Unblocking Code
214                  used to unblock a PIN. */
215               prompt = L_("PUK");
216               is_puk = 1;
217             }
218           else if (*s == 'N')
219             newpin = 1;
220           else if (*s == 'R')
221             {
222               prompt = L_("Reset Code");
223               resetcode = 1;
224             }
225         }
226       info = ends+1;
227       any_flags = 1;
228     }
229   else if (info && *info == '|')
230     log_debug ("pin_cb called without proper PIN info hack\n");
231
232   /* If BUF has been passed as NULL, we are in pinpad mode: The
233      callback opens the popup and immediately returns. */
234   if (!buf)
235     {
236       if (maxbuf == 0) /* Close the pinentry. */
237         {
238           agent_popup_message_stop (ctrl);
239           rc = 0;
240         }
241       else if (maxbuf == 1)  /* Open the pinentry. */
242         {
243           if (info)
244             {
245               char *desc;
246
247               if ( asprintf (&desc,
248                              L_("%s%%0A%%0AUse the reader's pinpad for input."),
249                              info) < 0 )
250                 rc = gpg_error_from_syserror ();
251               else
252                 {
253                   rc = agent_popup_message_start (ctrl, desc, NULL);
254                   xfree (desc);
255                 }
256             }
257           else
258             rc = agent_popup_message_start (ctrl, NULL, NULL);
259         }
260       else
261         rc = gpg_error (GPG_ERR_INV_VALUE);
262       return rc;
263     }
264
265   /* FIXME: keep PI and TRIES in OPAQUE.  Frankly this is a whole
266      mess because we should call the card's verify function from the
267      pinentry check pin CB. */
268  again:
269   pi = gcry_calloc_secure (1, sizeof (*pi) + maxbuf + 10);
270   if (!pi)
271     return gpg_error_from_syserror ();
272   pi->max_length = maxbuf-1;
273   pi->min_digits = 0;  /* we want a real passphrase */
274   pi->max_digits = 16;
275   pi->max_tries = 3;
276
277   if (any_flags)
278     {
279       rc = agent_askpin (ctrl, info, prompt, again_text, pi, NULL, 0);
280       again_text = NULL;
281       if (!rc && newpin)
282         {
283           struct pin_entry_info_s *pi2;
284           pi2 = gcry_calloc_secure (1, sizeof (*pi) + maxbuf + 10);
285           if (!pi2)
286             {
287               rc = gpg_error_from_syserror ();
288               xfree (pi);
289               return rc;
290             }
291           pi2->max_length = maxbuf-1;
292           pi2->min_digits = 0;
293           pi2->max_digits = 16;
294           pi2->max_tries = 1;
295           rc = agent_askpin (ctrl,
296                              (resetcode?
297                               L_("Repeat this Reset Code"):
298                               is_puk?
299                               L_("Repeat this PUK"):
300                               L_("Repeat this PIN")),
301                              prompt, NULL, pi2, NULL, 0);
302           if (!rc && strcmp (pi->pin, pi2->pin))
303             {
304               again_text = (resetcode?
305                             L_("Reset Code not correctly repeated; try again"):
306                             is_puk?
307                             L_("PUK not correctly repeated; try again"):
308                             L_("PIN not correctly repeated; try again"));
309               xfree (pi2);
310               xfree (pi);
311               goto again;
312             }
313           xfree (pi2);
314         }
315     }
316   else
317     {
318       char *desc;
319       if ( asprintf (&desc,
320                      L_("Please enter the PIN%s%s%s to unlock the card"),
321                      info? " (":"",
322                      info? info:"",
323                      info? ")":"") < 0)
324         desc = NULL;
325       rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi, NULL, 0);
326       xfree (desc);
327     }
328
329   if (!rc)
330     {
331       strncpy (buf, pi->pin, maxbuf-1);
332       buf[maxbuf-1] = 0;
333     }
334   xfree (pi);
335   return rc;
336 }
337
338
339
340
341 int
342 divert_pksign (ctrl_t ctrl,
343                const unsigned char *digest, size_t digestlen, int algo,
344                const unsigned char *shadow_info, unsigned char **r_sig,
345                size_t *r_siglen)
346 {
347   int rc;
348   char *kid;
349   size_t siglen;
350   unsigned char *sigval = NULL;
351
352   rc = ask_for_card (ctrl, shadow_info, &kid);
353   if (rc)
354     return rc;
355
356   if (algo == MD_USER_TLS_MD5SHA1)
357     {
358       int save = ctrl->use_auth_call;
359       ctrl->use_auth_call = 1;
360       rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl,
361                               algo, digest, digestlen, &sigval, &siglen);
362       ctrl->use_auth_call = save;
363     }
364   else
365     {
366       unsigned char *data;
367       size_t ndata;
368
369       rc = encode_md_for_card (digest, digestlen, algo, &data, &ndata);
370       if (!rc)
371         {
372           rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl,
373                                   algo, data, ndata, &sigval, &siglen);
374           xfree (data);
375         }
376     }
377
378   if (!rc)
379     {
380       *r_sig = sigval;
381       *r_siglen = siglen;
382     }
383
384   xfree (kid);
385
386   return rc;
387 }
388
389
390 /* Decrypt the the value given asn an S-expression in CIPHER using the
391    key identified by SHADOW_INFO and return the plaintext in an
392    allocated buffer in R_BUF.  The padding information is stored at
393    R_PADDING with -1 for not known.  */
394 int
395 divert_pkdecrypt (ctrl_t ctrl,
396                   const unsigned char *cipher,
397                   const unsigned char *shadow_info,
398                   char **r_buf, size_t *r_len, int *r_padding)
399 {
400   int rc;
401   char *kid;
402   const unsigned char *s;
403   size_t n;
404   const unsigned char *ciphertext;
405   size_t ciphertextlen;
406   char *plaintext;
407   size_t plaintextlen;
408
409   *r_padding = -1;
410
411   s = cipher;
412   if (*s != '(')
413     return gpg_error (GPG_ERR_INV_SEXP);
414   s++;
415   n = snext (&s);
416   if (!n)
417     return gpg_error (GPG_ERR_INV_SEXP);
418   if (!smatch (&s, n, "enc-val"))
419     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
420   if (*s != '(')
421     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
422   s++;
423   n = snext (&s);
424   if (!n)
425     return gpg_error (GPG_ERR_INV_SEXP);
426   if (smatch (&s, n, "rsa"))
427     {
428       if (*s != '(')
429         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
430       s++;
431       n = snext (&s);
432       if (!n)
433         return gpg_error (GPG_ERR_INV_SEXP);
434       if (!smatch (&s, n, "a"))
435         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
436       n = snext (&s);
437     }
438   else if (smatch (&s, n, "ecdh"))
439     {
440       if (*s != '(')
441         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
442       s++;
443       n = snext (&s);
444       if (!n)
445         return gpg_error (GPG_ERR_INV_SEXP);
446       if (smatch (&s, n, "s"))
447         {
448           n = snext (&s);
449           s += n;
450           if (*s++ != ')')
451             return gpg_error (GPG_ERR_INV_SEXP);
452           if (*s++ != '(')
453             return gpg_error (GPG_ERR_UNKNOWN_SEXP);
454           n = snext (&s);
455           if (!n)
456             return gpg_error (GPG_ERR_INV_SEXP);
457         }
458       if (!smatch (&s, n, "e"))
459         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
460       n = snext (&s);
461     }
462   else
463     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
464
465   if (!n)
466     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
467   ciphertext = s;
468   ciphertextlen = n;
469
470   rc = ask_for_card (ctrl, shadow_info, &kid);
471   if (rc)
472     return rc;
473
474   rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl,
475                              ciphertext, ciphertextlen,
476                              &plaintext, &plaintextlen, r_padding);
477   if (!rc)
478     {
479       *r_buf = plaintext;
480       *r_len = plaintextlen;
481     }
482   xfree (kid);
483   return rc;
484 }
485
486 int
487 divert_writekey (ctrl_t ctrl, int force, const char *serialno,
488                  const char *id, const char *keydata, size_t keydatalen)
489 {
490   return agent_card_writekey (ctrl, force, serialno, id, keydata, keydatalen,
491                               getpin_cb, ctrl);
492 }
493
494 int
495 divert_generic_cmd (ctrl_t ctrl, const char *cmdline, void *assuan_context)
496 {
497   return agent_card_scd (ctrl, cmdline, getpin_cb, ctrl, assuan_context);
498 }