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