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
.display
, opt
.ttyname
, opt
.ttytype
,
89 opt
.lc_ctype
, opt
.lc_messages
,
90 opt
.xauthority
, opt
.pinentry_user_data
,
91 opt
.verbose
, DBG_ASSUAN
,
96 /* Tell the agent that we support Pinentry notifications. No
97 error checking so that it will work also with older
99 assuan_transact (agent_ctx
, "OPTION allow-pinentry-notify",
100 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
104 if (!ctrl
->agent_seen
)
106 ctrl
->agent_seen
= 1;
107 audit_log_ok (ctrl
->audit
, AUDIT_AGENT_READY
, rc
);
116 membuf_data_cb (void *opaque
, const void *buffer
, size_t length
)
118 membuf_t
*data
= opaque
;
121 put_membuf (data
, buffer
, length
);
126 /* This is the default inquiry callback. It mainly handles the
127 Pinentry notifications. */
129 default_inq_cb (void *opaque
, const char *line
)
132 ctrl_t ctrl
= opaque
;
134 if (!strncmp (line
, "PINENTRY_LAUNCHED", 17) && (line
[17]==' '||!line
[17]))
136 err
= gpgsm_proxy_pinentry_notify (ctrl
, line
);
138 log_error (_("failed to proxy %s inquiry to client\n"),
139 "PINENTRY_LAUNCHED");
140 /* We do not pass errors to avoid breaking other code. */
143 log_error ("ignoring gpg-agent inquiry `%s'\n", line
);
151 /* Call the agent to do a sign operation using the key identified by
152 the hex string KEYGRIP. */
154 gpgsm_agent_pksign (ctrl_t ctrl
, const char *keygrip
, const char *desc
,
155 unsigned char *digest
, size_t digestlen
, int digestalgo
,
156 unsigned char **r_buf
, size_t *r_buflen
)
159 char *p
, line
[ASSUAN_LINELENGTH
];
164 rc
= start_agent (ctrl
);
168 if (digestlen
*2 + 50 > DIM(line
))
169 return gpg_error (GPG_ERR_GENERAL
);
171 rc
= assuan_transact (agent_ctx
, "RESET", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
175 snprintf (line
, DIM(line
)-1, "SIGKEY %s", keygrip
);
176 line
[DIM(line
)-1] = 0;
177 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
183 snprintf (line
, DIM(line
)-1, "SETKEYDESC %s", desc
);
184 line
[DIM(line
)-1] = 0;
185 rc
= assuan_transact (agent_ctx
, line
,
186 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
191 sprintf (line
, "SETHASH %d ", digestalgo
);
192 p
= line
+ strlen (line
);
193 for (i
=0; i
< digestlen
; i
++, p
+= 2 )
194 sprintf (p
, "%02X", digest
[i
]);
195 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
199 init_membuf (&data
, 1024);
200 rc
= assuan_transact (agent_ctx
, "PKSIGN",
201 membuf_data_cb
, &data
, default_inq_cb
, ctrl
,
205 xfree (get_membuf (&data
, &len
));
208 *r_buf
= get_membuf (&data
, r_buflen
);
210 if (!gcry_sexp_canon_len (*r_buf
, *r_buflen
, NULL
, NULL
))
212 xfree (*r_buf
); *r_buf
= NULL
;
213 return gpg_error (GPG_ERR_INV_VALUE
);
216 return *r_buf
? 0 : out_of_core ();
220 /* Call the scdaemon to do a sign operation using the key identified by
221 the hex string KEYID. */
223 gpgsm_scd_pksign (ctrl_t ctrl
, const char *keyid
, const char *desc
,
224 unsigned char *digest
, size_t digestlen
, int digestalgo
,
225 unsigned char **r_buf
, size_t *r_buflen
)
228 char *p
, line
[ASSUAN_LINELENGTH
];
232 unsigned char *sigbuf
;
241 case GCRY_MD_SHA1
: hashopt
= "--hash=sha1"; break;
242 case GCRY_MD_RMD160
:hashopt
= "--hash=rmd160"; break;
243 case GCRY_MD_MD5
: hashopt
= "--hash=md5"; break;
244 case GCRY_MD_SHA256
:hashopt
= "--hash=sha256"; break;
246 return gpg_error (GPG_ERR_DIGEST_ALGO
);
249 rc
= start_agent (ctrl
);
253 if (digestlen
*2 + 50 > DIM(line
))
254 return gpg_error (GPG_ERR_GENERAL
);
256 p
= stpcpy (line
, "SCD SETDATA " );
257 for (i
=0; i
< digestlen
; i
++, p
+= 2 )
258 sprintf (p
, "%02X", digest
[i
]);
259 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
263 init_membuf (&data
, 1024);
265 snprintf (line
, DIM(line
)-1, "SCD PKSIGN %s %s", hashopt
, keyid
);
266 line
[DIM(line
)-1] = 0;
267 rc
= assuan_transact (agent_ctx
, line
,
268 membuf_data_cb
, &data
, default_inq_cb
, ctrl
,
272 xfree (get_membuf (&data
, &len
));
275 sigbuf
= get_membuf (&data
, &sigbuflen
);
277 /* Create an S-expression from it which is formatted like this:
278 "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" Fixme: If a card ever
279 creates non-RSA keys we need to change things. */
280 *r_buflen
= 21 + 11 + sigbuflen
+ 4;
281 p
= xtrymalloc (*r_buflen
);
282 *r_buf
= (unsigned char*)p
;
288 p
= stpcpy (p
, "(7:sig-val(3:rsa(1:s" );
289 sprintf (p
, "%u:", (unsigned int)sigbuflen
);
291 memcpy (p
, sigbuf
, sigbuflen
);
296 assert (gcry_sexp_canon_len (*r_buf
, *r_buflen
, NULL
, NULL
));
303 /* Handle a CIPHERTEXT inquiry. Note, we only send the data,
304 assuan_transact talkes care of flushing and writing the end */
306 inq_ciphertext_cb (void *opaque
, const char *line
)
308 struct cipher_parm_s
*parm
= opaque
;
311 if (!strncmp (line
, "CIPHERTEXT", 10) && (line
[10]==' '||!line
[10]))
313 assuan_begin_confidential (parm
->ctx
);
314 rc
= assuan_send_data (parm
->ctx
, parm
->ciphertext
, parm
->ciphertextlen
);
315 assuan_end_confidential (parm
->ctx
);
318 rc
= default_inq_cb (parm
->ctrl
, line
);
324 /* Call the agent to do a decrypt operation using the key identified by
325 the hex string KEYGRIP. */
327 gpgsm_agent_pkdecrypt (ctrl_t ctrl
, const char *keygrip
, const char *desc
,
328 ksba_const_sexp_t ciphertext
,
329 char **r_buf
, size_t *r_buflen
)
332 char line
[ASSUAN_LINELENGTH
];
334 struct cipher_parm_s cipher_parm
;
336 char *p
, *buf
, *endp
;
337 size_t ciphertextlen
;
339 if (!keygrip
|| strlen(keygrip
) != 40 || !ciphertext
|| !r_buf
|| !r_buflen
)
340 return gpg_error (GPG_ERR_INV_VALUE
);
343 ciphertextlen
= gcry_sexp_canon_len (ciphertext
, 0, NULL
, NULL
);
345 return gpg_error (GPG_ERR_INV_VALUE
);
347 rc
= start_agent (ctrl
);
351 rc
= assuan_transact (agent_ctx
, "RESET", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
355 assert ( DIM(line
) >= 50 );
356 snprintf (line
, DIM(line
)-1, "SETKEY %s", keygrip
);
357 line
[DIM(line
)-1] = 0;
358 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
364 snprintf (line
, DIM(line
)-1, "SETKEYDESC %s", desc
);
365 line
[DIM(line
)-1] = 0;
366 rc
= assuan_transact (agent_ctx
, line
,
367 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
372 init_membuf (&data
, 1024);
373 cipher_parm
.ctrl
= ctrl
;
374 cipher_parm
.ctx
= agent_ctx
;
375 cipher_parm
.ciphertext
= ciphertext
;
376 cipher_parm
.ciphertextlen
= ciphertextlen
;
377 rc
= assuan_transact (agent_ctx
, "PKDECRYPT",
378 membuf_data_cb
, &data
,
379 inq_ciphertext_cb
, &cipher_parm
, NULL
, NULL
);
382 xfree (get_membuf (&data
, &len
));
386 put_membuf (&data
, "", 1); /* Make sure it is 0 terminated. */
387 buf
= get_membuf (&data
, &len
);
389 return gpg_error (GPG_ERR_ENOMEM
);
390 assert (len
); /* (we forced Nul termination.) */
394 if (len
< 13 || memcmp (buf
, "(5:value", 8) ) /* "(5:valueN:D)\0" */
395 return gpg_error (GPG_ERR_INV_SEXP
);
396 len
-= 11; /* Count only the data of the second part. */
397 p
= buf
+ 8; /* Skip leading parenthesis and the value tag. */
401 /* For compatibility with older gpg-agents handle the old style
402 incomplete S-exps. */
403 len
--; /* Do not count the Nul. */
407 n
= strtoul (p
, &endp
, 10);
408 if (!n
|| *endp
!= ':')
409 return gpg_error (GPG_ERR_INV_SEXP
);
412 return gpg_error (GPG_ERR_INV_SEXP
); /* Oops: Inconsistent S-Exp. */
414 memmove (buf
, endp
, n
);
425 /* Handle a KEYPARMS inquiry. Note, we only send the data,
426 assuan_transact takes care of flushing and writing the end */
428 inq_genkey_parms (void *opaque
, const char *line
)
430 struct genkey_parm_s
*parm
= opaque
;
433 if (!strncmp (line
, "KEYPARAM", 8) && (line
[8]==' '||!line
[8]))
435 rc
= assuan_send_data (parm
->ctx
, parm
->sexp
, parm
->sexplen
);
438 rc
= default_inq_cb (parm
->ctrl
, line
);
445 /* Call the agent to generate a newkey */
447 gpgsm_agent_genkey (ctrl_t ctrl
,
448 ksba_const_sexp_t keyparms
, ksba_sexp_t
*r_pubkey
)
451 struct genkey_parm_s gk_parm
;
457 rc
= start_agent (ctrl
);
461 rc
= assuan_transact (agent_ctx
, "RESET", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
465 init_membuf (&data
, 1024);
467 gk_parm
.ctx
= agent_ctx
;
468 gk_parm
.sexp
= keyparms
;
469 gk_parm
.sexplen
= gcry_sexp_canon_len (keyparms
, 0, NULL
, NULL
);
470 if (!gk_parm
.sexplen
)
471 return gpg_error (GPG_ERR_INV_VALUE
);
472 rc
= assuan_transact (agent_ctx
, "GENKEY",
473 membuf_data_cb
, &data
,
474 inq_genkey_parms
, &gk_parm
, NULL
, NULL
);
477 xfree (get_membuf (&data
, &len
));
480 buf
= get_membuf (&data
, &len
);
482 return gpg_error (GPG_ERR_ENOMEM
);
483 if (!gcry_sexp_canon_len (buf
, len
, NULL
, NULL
))
486 return gpg_error (GPG_ERR_INV_SEXP
);
493 /* Call the agent to read the public key part for a given keygrip. If
494 FROMCARD is true, the key is directly read from the current
495 smartcard. In this case HEXKEYGRIP should be the keyID
498 gpgsm_agent_readkey (ctrl_t ctrl
, int fromcard
, const char *hexkeygrip
,
499 ksba_sexp_t
*r_pubkey
)
505 char line
[ASSUAN_LINELENGTH
];
508 rc
= start_agent (ctrl
);
512 rc
= assuan_transact (agent_ctx
, "RESET",NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
516 snprintf (line
, DIM(line
)-1, "%sREADKEY %s",
517 fromcard
? "SCD ":"", hexkeygrip
);
518 line
[DIM(line
)-1] = 0;
520 init_membuf (&data
, 1024);
521 rc
= assuan_transact (agent_ctx
, line
,
522 membuf_data_cb
, &data
,
523 default_inq_cb
, ctrl
, NULL
, NULL
);
526 xfree (get_membuf (&data
, &len
));
529 buf
= get_membuf (&data
, &len
);
531 return gpg_error (GPG_ERR_ENOMEM
);
532 if (!gcry_sexp_canon_len (buf
, len
, NULL
, NULL
))
535 return gpg_error (GPG_ERR_INV_SEXP
);
544 istrusted_status_cb (void *opaque
, const char *line
)
546 struct rootca_flags_s
*flags
= opaque
;
548 if (!strncmp (line
, "TRUSTLISTFLAG", 13) && (line
[13]==' ' || !line
[13]))
550 for (line
+= 13; *line
== ' '; line
++)
552 if (!strncmp (line
, "relax", 5) && (line
[5] == ' ' || !line
[5]))
554 else if (!strncmp (line
, "cm", 2) && (line
[2] == ' ' || !line
[2]))
555 flags
->chain_model
= 1;
562 /* Ask the agent whether the certificate is in the list of trusted
563 keys. The certificate is either specified by the CERT object or by
564 the fingerprint HEXFPR. ROOTCA_FLAGS is guaranteed to be cleared
567 gpgsm_agent_istrusted (ctrl_t ctrl
, ksba_cert_t cert
, const char *hexfpr
,
568 struct rootca_flags_s
*rootca_flags
)
571 char line
[ASSUAN_LINELENGTH
];
573 memset (rootca_flags
, 0, sizeof *rootca_flags
);
576 return gpg_error (GPG_ERR_INV_ARG
);
578 rc
= start_agent (ctrl
);
584 snprintf (line
, DIM(line
)-1, "ISTRUSTED %s", hexfpr
);
585 line
[DIM(line
)-1] = 0;
591 fpr
= gpgsm_get_fingerprint_hexstring (cert
, GCRY_MD_SHA1
);
594 log_error ("error getting the fingerprint\n");
595 return gpg_error (GPG_ERR_GENERAL
);
598 snprintf (line
, DIM(line
)-1, "ISTRUSTED %s", fpr
);
599 line
[DIM(line
)-1] = 0;
603 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
,
604 istrusted_status_cb
, rootca_flags
);
606 rootca_flags
->valid
= 1;
610 /* Ask the agent to mark CERT as a trusted Root-CA one */
612 gpgsm_agent_marktrusted (ctrl_t ctrl
, ksba_cert_t cert
)
616 char line
[ASSUAN_LINELENGTH
];
618 rc
= start_agent (ctrl
);
622 fpr
= gpgsm_get_fingerprint_hexstring (cert
, GCRY_MD_SHA1
);
625 log_error ("error getting the fingerprint\n");
626 return gpg_error (GPG_ERR_GENERAL
);
629 dn
= ksba_cert_get_issuer (cert
, 0);
633 return gpg_error (GPG_ERR_GENERAL
);
635 snprintf (line
, DIM(line
)-1, "MARKTRUSTED %s S %s", fpr
, dn
);
636 line
[DIM(line
)-1] = 0;
640 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
641 default_inq_cb
, ctrl
, NULL
, NULL
);
647 /* Ask the agent whether the a corresponding secret key is available
648 for the given keygrip */
650 gpgsm_agent_havekey (ctrl_t ctrl
, const char *hexkeygrip
)
653 char line
[ASSUAN_LINELENGTH
];
655 rc
= start_agent (ctrl
);
659 if (!hexkeygrip
|| strlen (hexkeygrip
) != 40)
660 return gpg_error (GPG_ERR_INV_VALUE
);
662 snprintf (line
, DIM(line
)-1, "HAVEKEY %s", hexkeygrip
);
663 line
[DIM(line
)-1] = 0;
665 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
671 learn_cb (void *opaque
, const void *buffer
, size_t length
)
673 struct learn_parm_s
*parm
= opaque
;
684 put_membuf (parm
->data
, buffer
, length
);
687 /* END encountered - process what we have */
688 buf
= get_membuf (parm
->data
, &len
);
691 parm
->error
= gpg_error (GPG_ERR_ENOMEM
);
696 /* FIXME: this should go into import.c */
697 rc
= ksba_cert_new (&cert
);
703 rc
= ksba_cert_init_from_mem (cert
, buf
, len
);
706 log_error ("failed to parse a certificate: %s\n", gpg_strerror (rc
));
707 ksba_cert_release (cert
);
712 rc
= gpgsm_basic_cert_check (parm
->ctrl
, cert
);
713 if (gpg_err_code (rc
) == GPG_ERR_MISSING_CERT
)
714 { /* For later use we store it in the ephemeral database. */
715 log_info ("issuer certificate missing - storing as ephemeral\n");
716 keydb_store_cert (cert
, 1, NULL
);
719 log_error ("invalid certificate: %s\n", gpg_strerror (rc
));
724 if (!keydb_store_cert (cert
, 0, &existed
))
726 if (opt
.verbose
> 1 && existed
)
727 log_info ("certificate already in DB\n");
728 else if (opt
.verbose
&& !existed
)
729 log_info ("certificate imported\n");
733 ksba_cert_release (cert
);
734 init_membuf (parm
->data
, 4096);
738 /* Call the agent to learn about a smartcard */
740 gpgsm_agent_learn (ctrl_t ctrl
)
743 struct learn_parm_s learn_parm
;
747 rc
= start_agent (ctrl
);
751 init_membuf (&data
, 4096);
752 learn_parm
.error
= 0;
753 learn_parm
.ctrl
= ctrl
;
754 learn_parm
.ctx
= agent_ctx
;
755 learn_parm
.data
= &data
;
756 rc
= assuan_transact (agent_ctx
, "LEARN --send",
757 learn_cb
, &learn_parm
,
758 NULL
, NULL
, NULL
, NULL
);
759 xfree (get_membuf (&data
, &len
));
762 return learn_parm
.error
;
766 /* Ask the agent to change the passphrase of the key identified by
767 HEXKEYGRIP. If DESC is not NULL, display instead of the default
768 description message. */
770 gpgsm_agent_passwd (ctrl_t ctrl
, const char *hexkeygrip
, const char *desc
)
773 char line
[ASSUAN_LINELENGTH
];
775 rc
= start_agent (ctrl
);
779 if (!hexkeygrip
|| strlen (hexkeygrip
) != 40)
780 return gpg_error (GPG_ERR_INV_VALUE
);
784 snprintf (line
, DIM(line
)-1, "SETKEYDESC %s", desc
);
785 line
[DIM(line
)-1] = 0;
786 rc
= assuan_transact (agent_ctx
, line
,
787 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
792 snprintf (line
, DIM(line
)-1, "PASSWD %s", hexkeygrip
);
793 line
[DIM(line
)-1] = 0;
795 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
796 default_inq_cb
, ctrl
, NULL
, NULL
);
802 /* Ask the agent to pop up a confirmation dialog with the text DESC
803 and an okay and cancel button. */
805 gpgsm_agent_get_confirmation (ctrl_t ctrl
, const char *desc
)
808 char line
[ASSUAN_LINELENGTH
];
810 rc
= start_agent (ctrl
);
814 snprintf (line
, DIM(line
)-1, "GET_CONFIRMATION %s", desc
);
815 line
[DIM(line
)-1] = 0;
817 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
818 default_inq_cb
, ctrl
, NULL
, NULL
);
824 /* Return 0 if the agent is alive. This is useful to make sure that
825 an agent has been started. */
827 gpgsm_agent_send_nop (ctrl_t ctrl
)
831 rc
= start_agent (ctrl
);
833 rc
= assuan_transact (agent_ctx
, "NOP",
834 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
841 keyinfo_status_cb (void *opaque
, const char *line
)
843 char **serialno
= opaque
;
846 if (!strncmp (line
, "KEYINFO ", 8) && !*serialno
)
848 s
= strchr (line
+8, ' ');
849 if (s
&& s
[1] == 'T' && s
[2] == ' ' && s
[3])
852 s2
= strchr (s
, ' ');
855 *serialno
= xtrymalloc ((s2
- s
)+1);
858 memcpy (*serialno
, s
, s2
- s
);
859 (*serialno
)[s2
- s
] = 0;
867 /* Return the serial number for a secret key. If the returned serial
868 number is NULL, the key is not stored on a smartcard. Caller needs
869 to free R_SERIALNO. */
871 gpgsm_agent_keyinfo (ctrl_t ctrl
, const char *hexkeygrip
, char **r_serialno
)
874 char line
[ASSUAN_LINELENGTH
];
875 char *serialno
= NULL
;
879 err
= start_agent (ctrl
);
883 if (!hexkeygrip
|| strlen (hexkeygrip
) != 40)
884 return gpg_error (GPG_ERR_INV_VALUE
);
886 snprintf (line
, DIM(line
)-1, "KEYINFO %s", hexkeygrip
);
887 line
[DIM(line
)-1] = 0;
889 err
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
,
890 keyinfo_status_cb
, &serialno
);
891 if (!err
&& serialno
)
893 /* Sanity check for bad characters. */
894 if (strpbrk (serialno
, ":\n\r"))
895 err
= GPG_ERR_INV_VALUE
;
900 *r_serialno
= serialno
;