1 /* call-agent.c - Divert GPGSM operations to the agent
2 * Copyright (C) 2001, 2002, 2003, 2005, 2007,
3 * 2008, 2009 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
38 #include "keydb.h" /* fixme: Move this to import.c */
42 static assuan_context_t agent_ctx
= NULL
;
49 const unsigned char *ciphertext
;
57 const unsigned char *sexp
;
71 /* Try to connect to the agent via socket or fork it off and work by
72 pipes. Handle the server's initial greeting */
74 start_agent (ctrl_t ctrl
)
79 rc
= 0; /* fixme: We need a context for each thread or
80 serialize the access to the agent (which is
81 suitable given that the agent is not MT. */
84 rc
= start_new_gpg_agent (&agent_ctx
,
85 GPG_ERR_SOURCE_DEFAULT
,
88 opt
.lc_ctype
, opt
.lc_messages
,
90 opt
.verbose
, DBG_ASSUAN
,
95 /* Tell the agent that we support Pinentry notifications. No
96 error checking so that it will work also with older
98 assuan_transact (agent_ctx
, "OPTION allow-pinentry-notify",
99 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
103 if (!ctrl
->agent_seen
)
105 ctrl
->agent_seen
= 1;
106 audit_log_ok (ctrl
->audit
, AUDIT_AGENT_READY
, rc
);
115 membuf_data_cb (void *opaque
, const void *buffer
, size_t length
)
117 membuf_t
*data
= opaque
;
120 put_membuf (data
, buffer
, length
);
125 /* This is the default inquiry callback. It mainly handles the
126 Pinentry notifications. */
128 default_inq_cb (void *opaque
, const char *line
)
131 ctrl_t ctrl
= opaque
;
133 if (!strncmp (line
, "PINENTRY_LAUNCHED", 17) && (line
[17]==' '||!line
[17]))
135 err
= gpgsm_proxy_pinentry_notify (ctrl
, line
);
137 log_error (_("failed to proxy %s inquiry to client\n"),
138 "PINENTRY_LAUNCHED");
139 /* We do not pass errors to avoid breaking other code. */
142 log_error ("ignoring gpg-agent inquiry `%s'\n", line
);
150 /* Call the agent to do a sign operation using the key identified by
151 the hex string KEYGRIP. */
153 gpgsm_agent_pksign (ctrl_t ctrl
, const char *keygrip
, const char *desc
,
154 unsigned char *digest
, size_t digestlen
, int digestalgo
,
155 unsigned char **r_buf
, size_t *r_buflen
)
158 char *p
, line
[ASSUAN_LINELENGTH
];
163 rc
= start_agent (ctrl
);
167 if (digestlen
*2 + 50 > DIM(line
))
168 return gpg_error (GPG_ERR_GENERAL
);
170 rc
= assuan_transact (agent_ctx
, "RESET", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
174 snprintf (line
, DIM(line
)-1, "SIGKEY %s", keygrip
);
175 line
[DIM(line
)-1] = 0;
176 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
182 snprintf (line
, DIM(line
)-1, "SETKEYDESC %s", desc
);
183 line
[DIM(line
)-1] = 0;
184 rc
= assuan_transact (agent_ctx
, line
,
185 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
190 sprintf (line
, "SETHASH %d ", digestalgo
);
191 p
= line
+ strlen (line
);
192 for (i
=0; i
< digestlen
; i
++, p
+= 2 )
193 sprintf (p
, "%02X", digest
[i
]);
194 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
198 init_membuf (&data
, 1024);
199 rc
= assuan_transact (agent_ctx
, "PKSIGN",
200 membuf_data_cb
, &data
, default_inq_cb
, ctrl
,
204 xfree (get_membuf (&data
, &len
));
207 *r_buf
= get_membuf (&data
, r_buflen
);
209 if (!gcry_sexp_canon_len (*r_buf
, *r_buflen
, NULL
, NULL
))
211 xfree (*r_buf
); *r_buf
= NULL
;
212 return gpg_error (GPG_ERR_INV_VALUE
);
215 return *r_buf
? 0 : out_of_core ();
219 /* Call the scdaemon to do a sign operation using the key identified by
220 the hex string KEYID. */
222 gpgsm_scd_pksign (ctrl_t ctrl
, const char *keyid
, const char *desc
,
223 unsigned char *digest
, size_t digestlen
, int digestalgo
,
224 unsigned char **r_buf
, size_t *r_buflen
)
227 char *p
, line
[ASSUAN_LINELENGTH
];
231 unsigned char *sigbuf
;
240 case GCRY_MD_SHA1
: hashopt
= "--hash=sha1"; break;
241 case GCRY_MD_RMD160
:hashopt
= "--hash=rmd160"; break;
242 case GCRY_MD_MD5
: hashopt
= "--hash=md5"; break;
243 case GCRY_MD_SHA256
:hashopt
= "--hash=sha256"; break;
245 return gpg_error (GPG_ERR_DIGEST_ALGO
);
248 rc
= start_agent (ctrl
);
252 if (digestlen
*2 + 50 > DIM(line
))
253 return gpg_error (GPG_ERR_GENERAL
);
255 p
= stpcpy (line
, "SCD SETDATA " );
256 for (i
=0; i
< digestlen
; i
++, p
+= 2 )
257 sprintf (p
, "%02X", digest
[i
]);
258 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
262 init_membuf (&data
, 1024);
264 snprintf (line
, DIM(line
)-1, "SCD PKSIGN %s %s", hashopt
, keyid
);
265 line
[DIM(line
)-1] = 0;
266 rc
= assuan_transact (agent_ctx
, line
,
267 membuf_data_cb
, &data
, default_inq_cb
, ctrl
,
271 xfree (get_membuf (&data
, &len
));
274 sigbuf
= get_membuf (&data
, &sigbuflen
);
276 /* Create an S-expression from it which is formatted like this:
277 "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" Fixme: If a card ever
278 creates non-RSA keys we need to change things. */
279 *r_buflen
= 21 + 11 + sigbuflen
+ 4;
280 p
= xtrymalloc (*r_buflen
);
281 *r_buf
= (unsigned char*)p
;
287 p
= stpcpy (p
, "(7:sig-val(3:rsa(1:s" );
288 sprintf (p
, "%u:", (unsigned int)sigbuflen
);
290 memcpy (p
, sigbuf
, sigbuflen
);
295 assert (gcry_sexp_canon_len (*r_buf
, *r_buflen
, NULL
, NULL
));
302 /* Handle a CIPHERTEXT inquiry. Note, we only send the data,
303 assuan_transact talkes care of flushing and writing the end */
305 inq_ciphertext_cb (void *opaque
, const char *line
)
307 struct cipher_parm_s
*parm
= opaque
;
310 if (!strncmp (line
, "CIPHERTEXT", 10) && (line
[10]==' '||!line
[10]))
312 assuan_begin_confidential (parm
->ctx
);
313 rc
= assuan_send_data (parm
->ctx
, parm
->ciphertext
, parm
->ciphertextlen
);
314 assuan_end_confidential (parm
->ctx
);
317 rc
= default_inq_cb (parm
->ctrl
, line
);
323 /* Call the agent to do a decrypt operation using the key identified by
324 the hex string KEYGRIP. */
326 gpgsm_agent_pkdecrypt (ctrl_t ctrl
, const char *keygrip
, const char *desc
,
327 ksba_const_sexp_t ciphertext
,
328 char **r_buf
, size_t *r_buflen
)
331 char line
[ASSUAN_LINELENGTH
];
333 struct cipher_parm_s cipher_parm
;
335 char *p
, *buf
, *endp
;
336 size_t ciphertextlen
;
338 if (!keygrip
|| strlen(keygrip
) != 40 || !ciphertext
|| !r_buf
|| !r_buflen
)
339 return gpg_error (GPG_ERR_INV_VALUE
);
342 ciphertextlen
= gcry_sexp_canon_len (ciphertext
, 0, NULL
, NULL
);
344 return gpg_error (GPG_ERR_INV_VALUE
);
346 rc
= start_agent (ctrl
);
350 rc
= assuan_transact (agent_ctx
, "RESET", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
354 assert ( DIM(line
) >= 50 );
355 snprintf (line
, DIM(line
)-1, "SETKEY %s", keygrip
);
356 line
[DIM(line
)-1] = 0;
357 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
363 snprintf (line
, DIM(line
)-1, "SETKEYDESC %s", desc
);
364 line
[DIM(line
)-1] = 0;
365 rc
= assuan_transact (agent_ctx
, line
,
366 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
371 init_membuf (&data
, 1024);
372 cipher_parm
.ctrl
= ctrl
;
373 cipher_parm
.ctx
= agent_ctx
;
374 cipher_parm
.ciphertext
= ciphertext
;
375 cipher_parm
.ciphertextlen
= ciphertextlen
;
376 rc
= assuan_transact (agent_ctx
, "PKDECRYPT",
377 membuf_data_cb
, &data
,
378 inq_ciphertext_cb
, &cipher_parm
, NULL
, NULL
);
381 xfree (get_membuf (&data
, &len
));
385 put_membuf (&data
, "", 1); /* Make sure it is 0 terminated. */
386 buf
= get_membuf (&data
, &len
);
388 return gpg_error (GPG_ERR_ENOMEM
);
389 assert (len
); /* (we forced Nul termination.) */
393 if (len
< 13 || memcmp (buf
, "(5:value", 8) ) /* "(5:valueN:D)\0" */
394 return gpg_error (GPG_ERR_INV_SEXP
);
395 len
-= 11; /* Count only the data of the second part. */
396 p
= buf
+ 8; /* Skip leading parenthesis and the value tag. */
400 /* For compatibility with older gpg-agents handle the old style
401 incomplete S-exps. */
402 len
--; /* Do not count the Nul. */
406 n
= strtoul (p
, &endp
, 10);
407 if (!n
|| *endp
!= ':')
408 return gpg_error (GPG_ERR_INV_SEXP
);
411 return gpg_error (GPG_ERR_INV_SEXP
); /* Oops: Inconsistent S-Exp. */
413 memmove (buf
, endp
, n
);
424 /* Handle a KEYPARMS inquiry. Note, we only send the data,
425 assuan_transact takes care of flushing and writing the end */
427 inq_genkey_parms (void *opaque
, const char *line
)
429 struct genkey_parm_s
*parm
= opaque
;
432 if (!strncmp (line
, "KEYPARAM", 8) && (line
[8]==' '||!line
[8]))
434 rc
= assuan_send_data (parm
->ctx
, parm
->sexp
, parm
->sexplen
);
437 rc
= default_inq_cb (parm
->ctrl
, line
);
444 /* Call the agent to generate a newkey */
446 gpgsm_agent_genkey (ctrl_t ctrl
,
447 ksba_const_sexp_t keyparms
, ksba_sexp_t
*r_pubkey
)
450 struct genkey_parm_s gk_parm
;
456 rc
= start_agent (ctrl
);
460 rc
= assuan_transact (agent_ctx
, "RESET", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
464 init_membuf (&data
, 1024);
466 gk_parm
.ctx
= agent_ctx
;
467 gk_parm
.sexp
= keyparms
;
468 gk_parm
.sexplen
= gcry_sexp_canon_len (keyparms
, 0, NULL
, NULL
);
469 if (!gk_parm
.sexplen
)
470 return gpg_error (GPG_ERR_INV_VALUE
);
471 rc
= assuan_transact (agent_ctx
, "GENKEY",
472 membuf_data_cb
, &data
,
473 inq_genkey_parms
, &gk_parm
, NULL
, NULL
);
476 xfree (get_membuf (&data
, &len
));
479 buf
= get_membuf (&data
, &len
);
481 return gpg_error (GPG_ERR_ENOMEM
);
482 if (!gcry_sexp_canon_len (buf
, len
, NULL
, NULL
))
485 return gpg_error (GPG_ERR_INV_SEXP
);
492 /* Call the agent to read the public key part for a given keygrip. If
493 FROMCARD is true, the key is directly read from the current
494 smartcard. In this case HEXKEYGRIP should be the keyID
497 gpgsm_agent_readkey (ctrl_t ctrl
, int fromcard
, const char *hexkeygrip
,
498 ksba_sexp_t
*r_pubkey
)
504 char line
[ASSUAN_LINELENGTH
];
507 rc
= start_agent (ctrl
);
511 rc
= assuan_transact (agent_ctx
, "RESET",NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
515 snprintf (line
, DIM(line
)-1, "%sREADKEY %s",
516 fromcard
? "SCD ":"", hexkeygrip
);
517 line
[DIM(line
)-1] = 0;
519 init_membuf (&data
, 1024);
520 rc
= assuan_transact (agent_ctx
, line
,
521 membuf_data_cb
, &data
,
522 default_inq_cb
, ctrl
, NULL
, NULL
);
525 xfree (get_membuf (&data
, &len
));
528 buf
= get_membuf (&data
, &len
);
530 return gpg_error (GPG_ERR_ENOMEM
);
531 if (!gcry_sexp_canon_len (buf
, len
, NULL
, NULL
))
534 return gpg_error (GPG_ERR_INV_SEXP
);
542 /* Take the serial number from LINE and return it verbatim in a newly
543 allocated string. We make sure that only hex characters are
546 store_serialno (const char *line
)
551 for (s
=line
; hexdigitp (s
); s
++)
553 p
= xtrymalloc (s
+ 1 - line
);
556 memcpy (p
, line
, s
-line
);
563 /* Callback for the gpgsm_agent_serialno fucntion. */
565 scd_serialno_status_cb (void *opaque
, const char *line
)
567 char **r_serialno
= opaque
;
568 const char *keyword
= line
;
571 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
573 while (spacep (line
))
576 if (keywordlen
== 8 && !memcmp (keyword
, "SERIALNO", keywordlen
))
579 *r_serialno
= store_serialno (line
);
586 /* Call the agent to read the serial number of the current card. */
588 gpgsm_agent_scd_serialno (ctrl_t ctrl
, char **r_serialno
)
591 char *serialno
= NULL
;
594 rc
= start_agent (ctrl
);
598 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO",
600 default_inq_cb
, ctrl
,
601 scd_serialno_status_cb
, &serialno
);
602 if (!rc
&& !serialno
)
603 rc
= gpg_error (GPG_ERR_INTERNAL
);
609 *r_serialno
= serialno
;
615 /* Callback for the gpgsm_agent_serialno fucntion. */
617 scd_keypairinfo_status_cb (void *opaque
, const char *line
)
619 strlist_t
*listaddr
= opaque
;
620 const char *keyword
= line
;
625 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
627 while (spacep (line
))
630 if (keywordlen
== 11 && !memcmp (keyword
, "KEYPAIRINFO", keywordlen
))
632 sl
= append_to_strlist (listaddr
, line
);
634 /* Make sure that we only have two tokes so that future
635 extensions of the format won't change the format expected by
637 while (*p
&& !spacep (p
))
643 while (*p
&& !spacep (p
))
653 /* Call the agent to read the keypairinfo lines of the current card.
654 The list is returned as a string made up of the keygrip, a space
657 gpgsm_agent_scd_keypairinfo (ctrl_t ctrl
, strlist_t
*r_list
)
660 strlist_t list
= NULL
;
663 rc
= start_agent (ctrl
);
667 rc
= assuan_transact (agent_ctx
, "SCD LEARN --force",
669 default_inq_cb
, ctrl
,
670 scd_keypairinfo_status_cb
, &list
);
672 rc
= gpg_error (GPG_ERR_NO_DATA
);
685 istrusted_status_cb (void *opaque
, const char *line
)
687 struct rootca_flags_s
*flags
= opaque
;
689 if (!strncmp (line
, "TRUSTLISTFLAG", 13) && (line
[13]==' ' || !line
[13]))
691 for (line
+= 13; *line
== ' '; line
++)
693 if (!strncmp (line
, "relax", 5) && (line
[5] == ' ' || !line
[5]))
695 else if (!strncmp (line
, "cm", 2) && (line
[2] == ' ' || !line
[2]))
696 flags
->chain_model
= 1;
703 /* Ask the agent whether the certificate is in the list of trusted
704 keys. The certificate is either specified by the CERT object or by
705 the fingerprint HEXFPR. ROOTCA_FLAGS is guaranteed to be cleared
708 gpgsm_agent_istrusted (ctrl_t ctrl
, ksba_cert_t cert
, const char *hexfpr
,
709 struct rootca_flags_s
*rootca_flags
)
712 char line
[ASSUAN_LINELENGTH
];
714 memset (rootca_flags
, 0, sizeof *rootca_flags
);
717 return gpg_error (GPG_ERR_INV_ARG
);
719 rc
= start_agent (ctrl
);
725 snprintf (line
, DIM(line
)-1, "ISTRUSTED %s", hexfpr
);
726 line
[DIM(line
)-1] = 0;
732 fpr
= gpgsm_get_fingerprint_hexstring (cert
, GCRY_MD_SHA1
);
735 log_error ("error getting the fingerprint\n");
736 return gpg_error (GPG_ERR_GENERAL
);
739 snprintf (line
, DIM(line
)-1, "ISTRUSTED %s", fpr
);
740 line
[DIM(line
)-1] = 0;
744 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
,
745 istrusted_status_cb
, rootca_flags
);
747 rootca_flags
->valid
= 1;
751 /* Ask the agent to mark CERT as a trusted Root-CA one */
753 gpgsm_agent_marktrusted (ctrl_t ctrl
, ksba_cert_t cert
)
756 char *fpr
, *dn
, *dnfmt
;
757 char line
[ASSUAN_LINELENGTH
];
759 rc
= start_agent (ctrl
);
763 fpr
= gpgsm_get_fingerprint_hexstring (cert
, GCRY_MD_SHA1
);
766 log_error ("error getting the fingerprint\n");
767 return gpg_error (GPG_ERR_GENERAL
);
770 dn
= ksba_cert_get_issuer (cert
, 0);
774 return gpg_error (GPG_ERR_GENERAL
);
776 dnfmt
= gpgsm_format_name2 (dn
, 0);
779 return gpg_error_from_syserror ();
780 snprintf (line
, DIM(line
)-1, "MARKTRUSTED %s S %s", fpr
, dnfmt
);
781 line
[DIM(line
)-1] = 0;
785 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
786 default_inq_cb
, ctrl
, NULL
, NULL
);
792 /* Ask the agent whether the a corresponding secret key is available
793 for the given keygrip */
795 gpgsm_agent_havekey (ctrl_t ctrl
, const char *hexkeygrip
)
798 char line
[ASSUAN_LINELENGTH
];
800 rc
= start_agent (ctrl
);
804 if (!hexkeygrip
|| strlen (hexkeygrip
) != 40)
805 return gpg_error (GPG_ERR_INV_VALUE
);
807 snprintf (line
, DIM(line
)-1, "HAVEKEY %s", hexkeygrip
);
808 line
[DIM(line
)-1] = 0;
810 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
816 learn_status_cb (void *opaque
, const char *line
)
818 struct learn_parm_s
*parm
= opaque
;
820 /* Pass progress data to the caller. */
821 if (!strncmp (line
, "PROGRESS", 8) && (line
[8]==' ' || !line
[8]))
825 for (line
+= 8; *line
== ' '; line
++)
827 if (gpgsm_status (parm
->ctrl
, STATUS_PROGRESS
, line
))
828 return gpg_error (GPG_ERR_ASS_CANCELED
);
835 learn_cb (void *opaque
, const void *buffer
, size_t length
)
837 struct learn_parm_s
*parm
= opaque
;
848 put_membuf (parm
->data
, buffer
, length
);
851 /* END encountered - process what we have */
852 buf
= get_membuf (parm
->data
, &len
);
855 parm
->error
= gpg_error (GPG_ERR_ENOMEM
);
859 if (gpgsm_status (parm
->ctrl
, STATUS_PROGRESS
, "learncard C 0 0"))
860 return gpg_error (GPG_ERR_ASS_CANCELED
);
862 /* FIXME: this should go into import.c */
863 rc
= ksba_cert_new (&cert
);
869 rc
= ksba_cert_init_from_mem (cert
, buf
, len
);
872 log_error ("failed to parse a certificate: %s\n", gpg_strerror (rc
));
873 ksba_cert_release (cert
);
878 rc
= gpgsm_basic_cert_check (parm
->ctrl
, cert
);
879 if (gpg_err_code (rc
) == GPG_ERR_MISSING_CERT
)
880 { /* For later use we store it in the ephemeral database. */
881 log_info ("issuer certificate missing - storing as ephemeral\n");
882 keydb_store_cert (cert
, 1, NULL
);
885 log_error ("invalid certificate: %s\n", gpg_strerror (rc
));
890 if (!keydb_store_cert (cert
, 0, &existed
))
892 if (opt
.verbose
> 1 && existed
)
893 log_info ("certificate already in DB\n");
894 else if (opt
.verbose
&& !existed
)
895 log_info ("certificate imported\n");
899 ksba_cert_release (cert
);
900 init_membuf (parm
->data
, 4096);
904 /* Call the agent to learn about a smartcard */
906 gpgsm_agent_learn (ctrl_t ctrl
)
909 struct learn_parm_s learn_parm
;
913 rc
= start_agent (ctrl
);
917 init_membuf (&data
, 4096);
918 learn_parm
.error
= 0;
919 learn_parm
.ctrl
= ctrl
;
920 learn_parm
.ctx
= agent_ctx
;
921 learn_parm
.data
= &data
;
922 rc
= assuan_transact (agent_ctx
, "LEARN --send",
923 learn_cb
, &learn_parm
,
925 learn_status_cb
, &learn_parm
);
926 xfree (get_membuf (&data
, &len
));
929 return learn_parm
.error
;
933 /* Ask the agent to change the passphrase of the key identified by
934 HEXKEYGRIP. If DESC is not NULL, display instead of the default
935 description message. */
937 gpgsm_agent_passwd (ctrl_t ctrl
, const char *hexkeygrip
, const char *desc
)
940 char line
[ASSUAN_LINELENGTH
];
942 rc
= start_agent (ctrl
);
946 if (!hexkeygrip
|| strlen (hexkeygrip
) != 40)
947 return gpg_error (GPG_ERR_INV_VALUE
);
951 snprintf (line
, DIM(line
)-1, "SETKEYDESC %s", desc
);
952 line
[DIM(line
)-1] = 0;
953 rc
= assuan_transact (agent_ctx
, line
,
954 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
959 snprintf (line
, DIM(line
)-1, "PASSWD %s", hexkeygrip
);
960 line
[DIM(line
)-1] = 0;
962 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
963 default_inq_cb
, ctrl
, NULL
, NULL
);
969 /* Ask the agent to pop up a confirmation dialog with the text DESC
970 and an okay and cancel button. */
972 gpgsm_agent_get_confirmation (ctrl_t ctrl
, const char *desc
)
975 char line
[ASSUAN_LINELENGTH
];
977 rc
= start_agent (ctrl
);
981 snprintf (line
, DIM(line
)-1, "GET_CONFIRMATION %s", desc
);
982 line
[DIM(line
)-1] = 0;
984 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
985 default_inq_cb
, ctrl
, NULL
, NULL
);
991 /* Return 0 if the agent is alive. This is useful to make sure that
992 an agent has been started. */
994 gpgsm_agent_send_nop (ctrl_t ctrl
)
998 rc
= start_agent (ctrl
);
1000 rc
= assuan_transact (agent_ctx
, "NOP",
1001 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
1008 keyinfo_status_cb (void *opaque
, const char *line
)
1010 char **serialno
= opaque
;
1013 if (!strncmp (line
, "KEYINFO ", 8) && !*serialno
)
1015 s
= strchr (line
+8, ' ');
1016 if (s
&& s
[1] == 'T' && s
[2] == ' ' && s
[3])
1019 s2
= strchr (s
, ' ');
1022 *serialno
= xtrymalloc ((s2
- s
)+1);
1025 memcpy (*serialno
, s
, s2
- s
);
1026 (*serialno
)[s2
- s
] = 0;
1034 /* Return the serial number for a secret key. If the returned serial
1035 number is NULL, the key is not stored on a smartcard. Caller needs
1036 to free R_SERIALNO. */
1038 gpgsm_agent_keyinfo (ctrl_t ctrl
, const char *hexkeygrip
, char **r_serialno
)
1041 char line
[ASSUAN_LINELENGTH
];
1042 char *serialno
= NULL
;
1046 err
= start_agent (ctrl
);
1050 if (!hexkeygrip
|| strlen (hexkeygrip
) != 40)
1051 return gpg_error (GPG_ERR_INV_VALUE
);
1053 snprintf (line
, DIM(line
)-1, "KEYINFO %s", hexkeygrip
);
1054 line
[DIM(line
)-1] = 0;
1056 err
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
,
1057 keyinfo_status_cb
, &serialno
);
1058 if (!err
&& serialno
)
1060 /* Sanity check for bad characters. */
1061 if (strpbrk (serialno
, ":\n\r"))
1062 err
= GPG_ERR_INV_VALUE
;
1067 *r_serialno
= serialno
;