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