1 /* divert-scd.c - divert operations to the scdaemon
2 * Copyright (C) 2002, 2003, 2009 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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/>.
32 #include "sexp-parse.h"
36 ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
42 char *want_sn, *want_kid;
47 rc = parse_shadow_info (shadow_info, &want_sn, &want_kid, NULL);
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
55 want_sn_displen = strlen (want_sn);
56 if (want_sn_displen == 20 && want_sn[19] == '0')
61 rc = agent_card_serialno (ctrl, &serialno, want_sn);
64 log_debug ("detected card with S/N %s\n", serialno);
65 i = strcmp (serialno, want_sn);
72 return 0; /* yes, we have the correct card */
75 else if (gpg_err_code (rc) == GPG_ERR_ENODEV)
77 log_debug ("no device present\n");
81 else if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT)
83 log_debug ("no card present\n");
89 log_error ("error accessing card: %s\n", gpg_strerror (rc));
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)
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);
125 /* Put the DIGEST into an DER encoded container and return it in R_VAL. */
127 encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo,
128 unsigned char **r_val, size_t *r_len)
130 unsigned char *frame;
131 unsigned char asn[100];
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))
142 log_error ("no object identifier for algo %d\n", algo);
143 return gpg_error (GPG_ERR_INTERNAL);
146 frame = xtrymalloc (asnlen + digestlen);
148 return out_of_core ();
149 memcpy (frame, asn, asnlen);
150 memcpy (frame+asnlen, digest, digestlen);
152 log_printhex ("encoded hash:", frame, asnlen+digestlen);
155 *r_len = asnlen+digestlen;
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.
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.
173 'N' = New PIN, this requests a second prompt to repeat the
174 PIN. If the PIN is not correctly repeated it starts from
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.
182 "|AN|Please enter the new security officer's PIN"
184 The text "Please ..." will get displayed and the flags 'A' and 'N'
188 getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
190 struct pin_entry_info_s *pi;
192 ctrl_t ctrl = opaque;
193 const char *ends, *s;
198 const char *again_text = NULL;
199 const char *prompt = "PIN";
201 if (buf && maxbuf < 2)
202 return gpg_error (GPG_ERR_INV_VALUE);
204 /* Parse the flags. */
205 if (info && *info =='|' && (ends=strchr (info+1, '|')))
207 for (s=info+1; s < ends; s++)
210 prompt = L_("Admin PIN");
213 /* TRANSLATORS: A PUK is the Personal Unblocking Code
214 used to unblock a PIN. */
222 prompt = L_("Reset Code");
229 else if (info && *info == '|')
230 log_debug ("pin_cb called without proper PIN info hack\n");
232 /* If BUF has been passed as NULL, we are in pinpad mode: The
233 callback opens the popup and immediately returns. */
236 if (maxbuf == 0) /* Close the pinentry. */
238 agent_popup_message_stop (ctrl);
241 else if (maxbuf == 1) /* Open the pinentry. */
247 if ( asprintf (&desc,
248 L_("%s%%0A%%0AUse the reader's pinpad for input."),
250 rc = gpg_error_from_syserror ();
253 rc = agent_popup_message_start (ctrl, desc, NULL);
258 rc = agent_popup_message_start (ctrl, NULL, NULL);
261 rc = gpg_error (GPG_ERR_INV_VALUE);
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. */
269 pi = gcry_calloc_secure (1, sizeof (*pi) + maxbuf + 10);
271 return gpg_error_from_syserror ();
272 pi->max_length = maxbuf-1;
273 pi->min_digits = 0; /* we want a real passphrase */
279 rc = agent_askpin (ctrl, info, prompt, again_text, pi, NULL, 0);
283 struct pin_entry_info_s *pi2;
284 pi2 = gcry_calloc_secure (1, sizeof (*pi) + maxbuf + 10);
287 rc = gpg_error_from_syserror ();
291 pi2->max_length = maxbuf-1;
293 pi2->max_digits = 16;
295 rc = agent_askpin (ctrl,
297 L_("Repeat this Reset Code"):
299 L_("Repeat this PUK"):
300 L_("Repeat this PIN")),
301 prompt, NULL, pi2, NULL, 0);
302 if (!rc && strcmp (pi->pin, pi2->pin))
304 again_text = (resetcode?
305 L_("Reset Code not correctly repeated; try again"):
307 L_("PUK not correctly repeated; try again"):
308 L_("PIN not correctly repeated; try again"));
319 if ( asprintf (&desc,
320 L_("Please enter the PIN%s%s%s to unlock the card"),
325 rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi, NULL, 0);
331 strncpy (buf, pi->pin, maxbuf-1);
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,
350 unsigned char *sigval = NULL;
352 rc = ask_for_card (ctrl, shadow_info, &kid);
356 if (algo == MD_USER_TLS_MD5SHA1)
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;
369 rc = encode_md_for_card (digest, digestlen, algo, &data, &ndata);
372 rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl,
373 algo, data, ndata, &sigval, &siglen);
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. */
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)
402 const unsigned char *s;
404 const unsigned char *ciphertext;
405 size_t ciphertextlen;
413 return gpg_error (GPG_ERR_INV_SEXP);
417 return gpg_error (GPG_ERR_INV_SEXP);
418 if (!smatch (&s, n, "enc-val"))
419 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
421 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
425 return gpg_error (GPG_ERR_INV_SEXP);
426 if (smatch (&s, n, "rsa"))
429 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
433 return gpg_error (GPG_ERR_INV_SEXP);
434 if (!smatch (&s, n, "a"))
435 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
438 else if (smatch (&s, n, "ecdh"))
441 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
445 return gpg_error (GPG_ERR_INV_SEXP);
446 if (smatch (&s, n, "s"))
451 return gpg_error (GPG_ERR_INV_SEXP);
453 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
456 return gpg_error (GPG_ERR_INV_SEXP);
458 if (!smatch (&s, n, "e"))
459 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
463 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
466 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
470 rc = ask_for_card (ctrl, shadow_info, &kid);
474 rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl,
475 ciphertext, ciphertextlen,
476 &plaintext, &plaintextlen, r_padding);
480 *r_len = plaintextlen;
487 divert_writekey (ctrl_t ctrl, int force, const char *serialno,
488 const char *id, const char *keydata, size_t keydatalen)
490 return agent_card_writekey (ctrl, force, serialno, id, keydata, keydatalen,
495 divert_generic_cmd (ctrl_t ctrl, const char *cmdline, void *assuan_context)
497 return agent_card_scd (ctrl, cmdline, getpin_cb, ctrl, assuan_context);