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