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