2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of pwmd.
7 Pwmd 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 2 of the License, or
10 (at your option) any later version.
12 Pwmd 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 Pwmd. If not, see <http://www.gnu.org/licenses/>.
27 #include <sys/types.h>
37 #include "pwmd-error.h"
38 #include "util-misc.h"
43 #include "util-string.h"
51 mem_realloc_cb (void *data
, const void *buffer
, size_t len
)
53 membuf_t
*mem
= (membuf_t
*) data
;
59 if ((p
= xrealloc (mem
->buf
, mem
->len
+ len
)) == NULL
)
63 memcpy ((char *) mem
->buf
+ mem
->len
, buffer
, len
);
68 /* Forward status messages from gpg-agent to the client. */
70 status_cb (void *data
, const char *line
)
72 struct agent_s
*agent
= data
;
74 agent
->inquire_maxlen
= 0;
76 if (!strncmp (line
, "INQUIRE_MAXLEN ", 15))
78 agent
->inquire_maxlen
= atoi (line
+ 15);
79 if (!agent
->client_ctx
)
83 return send_status (agent
->client_ctx
, STATUS_AGENT
, "%s", line
);
87 assuan_command (struct agent_s
*a
, char **result
,
88 size_t * len
, const char *cmd
)
99 rc
= assuan_transact (a
->ctx
, cmd
, mem_realloc_cb
, &a
->data
,
100 a
->inquire_cb
, a
->inquire_data
, status_cb
, a
);
107 mem_realloc_cb (&a
->data
, "", 1);
109 *result
= (char *) a
->data
.buf
;
121 /* This commands are sent from launch_agent() after reconnecting to the agent
122 * and also from the initial client connection. */
124 send_agent_common_options (struct agent_s
*agent
)
128 rc
= send_to_agent (agent
, NULL
, NULL
, "OPTION cache-ttl-opt-preset=-1");
133 launch_agent (struct agent_s
*agent
)
136 assuan_context_t ctx
= NULL
;
137 static struct assuan_malloc_hooks mhooks
= { xmalloc
, xrealloc
, xfree
};
140 agent
->did_restart
= 0;
141 rc
= assuan_new_ext (&ctx
, GPG_ERR_SOURCE_DEFAULT
, &mhooks
,
142 debug_level
? assuan_log_cb
: NULL
, "AGENT ");
146 s
= config_get_string ("global", "gpg_agent_socket");
147 rc
= assuan_socket_connect (ctx
, s
, ASSUAN_INVALID_PID
, 0);
152 assuan_release (ctx
);
157 assuan_release (agent
->ctx
);
160 rc
= send_agent_common_options (agent
);
161 if (!rc
&& agent
->pinentry_opts
.display
)
162 rc
= set_agent_option (agent
, "display", agent
->pinentry_opts
.display
);
164 if (!rc
&& agent
->pinentry_opts
.ttyname
)
165 rc
= set_agent_option (agent
, "ttyname", agent
->pinentry_opts
.ttyname
);
167 if (!rc
&& agent
->pinentry_opts
.ttytype
)
168 rc
= set_agent_option (agent
, "ttytype", agent
->pinentry_opts
.ttytype
);
170 if (!rc
&& agent
->pinentry_opts
.lc_messages
)
171 rc
= set_agent_option (agent
, "lc-messages",
172 agent
->pinentry_opts
.lc_messages
);
174 if (!rc
&& agent
->pinentry_opts
.lc_ctype
)
175 rc
= set_agent_option (agent
, "lc-ctype", agent
->pinentry_opts
.lc_ctype
);
181 send_to_agent (struct agent_s
* agent
, char **result
, size_t * len
,
182 const char *fmt
, ...)
190 rc
= launch_agent (agent
);
196 if (str_vasprintf (&cmd
, fmt
, ap
) > 0)
198 rc
= assuan_command (agent
, result
, len
, cmd
);
199 if (!agent
->restart
&& gpg_err_source (rc
) == GPG_ERR_SOURCE_DEFAULT
200 && (gpg_err_code (rc
) == GPG_ERR_ASS_CONNECT_FAILED
201 || gpg_err_code (rc
) == GPG_ERR_EPIPE
))
203 log_write (_ ("gpg-agent connection died (rc=%i), reconnecting"), rc
);
205 rc
= launch_agent (agent
);
208 agent
->did_restart
= 1;
209 rc
= assuan_command (agent
, result
, len
, cmd
);
224 agent_disconnect (struct agent_s
*agent
)
230 assuan_release (agent
->ctx
);
236 cleanup_agent (struct agent_s
*agent
)
241 pinentry_free_opts (&agent
->pinentry_opts
);
242 agent_disconnect (agent
);
247 agent_init (struct agent_s
**agent
)
249 struct agent_s
*new = xcalloc (1, sizeof (struct agent_s
));
252 return GPG_ERR_ENOMEM
;
259 inquire_cb (void *user
, const char *keyword
)
261 struct inquire_data_s
*idata
= user
;
263 if (!idata
->preset
&& (!strcmp (keyword
, "PASSPHRASE")
264 || !strcmp (keyword
, "NEW_PASSPHRASE")))
266 return agent_loopback_cb (idata
->crypto
, keyword
);
268 // SAVE --inquire-keyparam
269 else if (idata
->preset
&& !strcmp (keyword
, "KEYPARAM"))
272 return agent_loopback_cb (idata
->crypto
, keyword
);
275 if (idata
->crypto
->agent
->inquire_maxlen
276 && idata
->len
> idata
->crypto
->agent
->inquire_maxlen
)
278 log_write (_("Inquired data too large: have=%u, max=%u"), idata
->len
,
279 idata
->crypto
->agent
->inquire_maxlen
);
280 return GPG_ERR_TOO_LARGE
;
283 idata
->crypto
->agent
->inquire_maxlen
= 0;
284 return assuan_send_data (idata
->crypto
->agent
->ctx
, idata
->line
,
288 /* Retrieve the passphrase needed to decrypt the XML from the secret
289 * key using gpg-agent. */
291 agent_extract_key (struct crypto_s
*crypto
, unsigned char **result
,
295 gcry_sexp_t enc_sexp
= NULL
, tmp_sexp
;
296 struct inquire_data_s idata
= { 0 };
297 char *hexgrip
= NULL
;
299 size_t keylen
, keysize
;
301 int algo
= cipher_to_gcrypt (crypto
->hdr
.flags
);
304 rc
= gcry_cipher_algo_info (algo
, GCRYCTL_GET_KEYLEN
, NULL
, &keysize
);
308 tmp_sexp
= gcry_sexp_find_token (crypto
->ciphertext_sexp
, "enc-val", 0);
310 return gpg_error (GPG_ERR_BAD_DATA
);
312 hexgrip
= bin2hex (crypto
->grip
, sizeof (crypto
->grip
));
319 rc
= cache_is_shadowed (hexgrip
);
320 if (rc
&& rc
!= GPG_ERR_NO_DATA
)
323 shadowed
= !rc
? 1 : 0;
326 /* The key is not on a smartcard. */
327 gcry_sexp_t tmp2_sexp
= gcry_sexp_cdr (tmp_sexp
);
328 gcry_sexp_release (tmp_sexp
);
329 tmp_sexp
= gcry_sexp_nth (tmp2_sexp
, 0);
330 gcry_sexp_release (tmp2_sexp
);
331 rc
= gcry_sexp_build (&enc_sexp
, NULL
, "(enc-val (flags pkcs1) %S)",
335 rc
= gcry_sexp_build (&enc_sexp
, NULL
, "%S", tmp_sexp
);
337 gcry_sexp_release (tmp_sexp
);
341 crypto
->agent
->inquire_cb
= inquire_cb
;
342 idata
.crypto
= crypto
;
343 idata
.len
= gcry_sexp_sprint (enc_sexp
, GCRYSEXP_FMT_CANON
, NULL
, 0);
344 idata
.line
= xmalloc (idata
.len
);
351 idata
.len
= gcry_sexp_sprint (enc_sexp
, GCRYSEXP_FMT_CANON
, idata
.line
,
353 crypto
->agent
->inquire_data
= &idata
;
354 gcry_sexp_release (enc_sexp
);
356 log_write1 (_("Keygrip is %s, bits=%i"), hexgrip
,
357 gcry_pk_get_nbits (crypto
->pkey_sexp
));
358 rc
= send_to_agent (crypto
->agent
, NULL
, NULL
, "SETKEY %s", hexgrip
);
362 if (!crypto
->agent
->pinentry_opts
.desc
)
366 ("A %s is required to unlock the secret key for the "
367 "encrypted data file \"%s\". Please enter the %s "
368 "below."), shadowed
? "PIN" : _("passphrase"),
369 crypto
->filename
, shadowed
? "PIN" : _("passphrase"));
372 tmp
= plus_escape (crypto
->agent
->pinentry_opts
.desc
);
374 rc
= send_to_agent (crypto
->agent
, NULL
, NULL
, "SETKEYDESC %s", tmp
);
379 assuan_begin_confidential (crypto
->agent
->ctx
);
380 rc
= send_to_agent (crypto
->agent
, &key
, &keylen
, "PKDECRYPT");
381 assuan_end_confidential (crypto
->agent
->ctx
);
385 rc
= gcry_sexp_new (&tmp_sexp
, key
, keylen
, 1);
390 key
= (char *) gcry_sexp_nth_data (tmp_sexp
, 1, result_len
);
393 *result
= gcry_malloc (*result_len
);
397 memcpy (*result
, key
, *result_len
);
400 rc
= GPG_ERR_BAD_DATA
;
402 gcry_sexp_release (tmp_sexp
);
409 gcry_sexp_release (enc_sexp
);
411 if (rc
&& gpg_err_source (rc
) == GPG_ERR_SOURCE_UNKNOWN
)
418 /* Return an error for public key algorithms other than RSA or DSA or ELG.
419 * Others are supported by libgcrypt but I dont know what to do for ECDA. Key
420 * generation works as does signing but decryption fails for unsupported
421 * algorithms so disable them. */
423 get_key_info (gcry_sexp_t pubkey
, char **hash_str
, int *hash_type
,
424 size_t *len
, int *pk_algo
)
426 unsigned nbits
= gcry_pk_get_nbits (pubkey
);
427 gcry_sexp_t sexp
, tmp
;
431 tmp
= gcry_sexp_find_token (pubkey
, "public-key", 0);
433 return GPG_ERR_NO_PUBKEY
;
435 sexp
= gcry_sexp_nth (tmp
, 1);
436 gcry_sexp_release (tmp
);
437 algo
= gcry_sexp_nth_string (sexp
, 0);
438 gcry_sexp_release (sexp
);
442 return GPG_ERR_BAD_PUBKEY
;
445 if (!strcmp (algo
, "rsa"))
447 *pk_algo
= GCRY_PK_RSA
;
448 *hash_str
= "sha256";
449 *hash_type
= GCRY_MD_SHA256
;
450 *len
= gcry_md_get_algo_dlen (GCRY_MD_SHA256
);
452 else if (!strcmp (algo
, "elg"))
454 *pk_algo
= GCRY_PK_ELG
;
455 *hash_str
= "sha256";
456 *hash_type
= GCRY_MD_SHA256
;
457 *len
= gcry_md_get_algo_dlen (GCRY_MD_SHA256
);
459 else if (!strcmp (algo
, "dsa"))
461 *pk_algo
= GCRY_PK_DSA
;
467 *hash_type
= GCRY_MD_SHA1
;
468 *len
= gcry_md_get_algo_dlen (GCRY_MD_SHA1
);
471 *hash_str
= "sha224";
472 *hash_type
= GCRY_MD_SHA224
;
473 *len
= gcry_md_get_algo_dlen (GCRY_MD_SHA224
);
476 *hash_str
= "sha256";
477 *hash_type
= GCRY_MD_SHA256
;
478 *len
= gcry_md_get_algo_dlen (GCRY_MD_SHA256
);
481 *hash_str
= "sha384";
482 *hash_type
= GCRY_MD_SHA384
;
483 *len
= gcry_md_get_algo_dlen (GCRY_MD_SHA384
);
486 *hash_str
= "sha512";
487 *hash_type
= GCRY_MD_SHA512
;
488 *len
= gcry_md_get_algo_dlen (GCRY_MD_SHA512
);
493 rc
= GPG_ERR_UNSUPPORTED_ALGORITHM
;
500 agent_verify (gcry_sexp_t pkey
, gcry_sexp_t sig_sexp
, const void *data
,
506 gcry_sexp_t data_sexp
;
507 char *hash_str
= NULL
;
509 gpg_error_t rc
= get_key_info (pkey
, &hash_str
, &hash_type
, &hashlen
,
515 hash
= gcry_malloc (hashlen
);
517 return GPG_ERR_ENOMEM
;
519 gcry_md_hash_buffer (hash_type
, hash
, data
, len
);
520 if (pk_algo
== GCRY_PK_RSA
|| pk_algo
== GCRY_PK_ELG
)
521 rc
= gcry_sexp_build (&data_sexp
, NULL
,
522 "(data (flags pkcs1) (hash %s %b))", hash_str
,
525 rc
= gcry_sexp_build (&data_sexp
, NULL
,
526 "(data (flags raw) (value %b))", hashlen
, hash
);
531 rc
= gcry_pk_verify (sig_sexp
, data_sexp
, pkey
);
532 gcry_sexp_release (data_sexp
);
538 /* Inquire data from the client. The inquire initiated from gpg-agent. */
540 agent_loopback_cb (void *user
, const char *keyword
)
542 struct crypto_s
*crypto
= user
;
544 unsigned char *result
;
548 if (!strcmp (keyword
, "KEYPARAM"))
551 rc
= assuan_inquire (crypto
->client_ctx
, keyword
, &result
, &len
, 0);
554 { // PASSPHRASE or NEW_PASSPHRASE
555 assuan_begin_confidential (crypto
->client_ctx
);
556 rc
= assuan_inquire (crypto
->client_ctx
, keyword
, &result
, &len
, 0);
557 assuan_end_confidential (crypto
->client_ctx
);
559 if (!rc
&& len
== 1 && *result
== 0)
565 if (keyparam
&& !len
)
567 char *tmp
= default_key_params (crypto
);
570 return gpg_error (GPG_ERR_ENOMEM
);
574 result
= xmalloc (len
);
575 memcpy (result
, tmp
, len
);
579 pthread_cleanup_push (xfree
, result
);
582 rc
= assuan_send_data (crypto
->agent
->ctx
, result
, len
);
585 assuan_begin_confidential (crypto
->agent
->ctx
);
586 rc
= assuan_send_data (crypto
->agent
->ctx
, result
, len
);
587 assuan_end_confidential (crypto
->agent
->ctx
);
590 pthread_cleanup_pop (1);
592 else if (gpg_err_code (rc
) == GPG_ERR_ASS_CANCELED
)
594 gpg_error_t arc
= assuan_write_line (crypto
->agent
->ctx
, "CAN");
601 arc
= assuan_read_line (crypto
->agent
->ctx
, &line
, &len
);
613 sign (gcry_sexp_t
* rsexp
, gcry_sexp_t sigpkey
, struct crypto_s
*crypto
,
614 const void *data
, size_t len
)
618 unsigned char grip
[20];
621 gcry_pk_get_keygrip (sigpkey
, grip
);
622 tmp
= bin2hex (grip
, sizeof(grip
));
623 pthread_cleanup_push (xfree
, tmp
);
624 log_write1 (_("Signed with keygrip %s"), tmp
);
625 rc
= send_to_agent (crypto
->agent
, NULL
, NULL
, "SIGKEY %s", tmp
);
626 pthread_cleanup_pop (1);
630 char *hash_str
= NULL
;
634 rc
= get_key_info (sigpkey
, &hash_str
, &hash_type
, &hashlen
, &pk_algo
);
637 unsigned char *hash
= gcry_malloc (hashlen
);
640 rc
= gpg_error (GPG_ERR_ENOMEM
);
644 gcry_md_hash_buffer (hash_type
, hash
, data
, len
);
645 tmp
= bin2hex (hash
, hashlen
);
647 pthread_cleanup_push (xfree
, tmp
);
648 rc
= send_to_agent (crypto
->agent
, NULL
, NULL
,
649 "SETHASH --hash=%s %s", hash_str
, tmp
);
650 pthread_cleanup_pop (1);
660 struct inquire_data_s idata
= { 0 };
662 idata
.crypto
= crypto
;
663 crypto
->agent
->inquire_data
= &idata
;
664 crypto
->agent
->inquire_cb
= inquire_cb
;
665 rc
= send_to_agent (crypto
->agent
, &result
, &len
, "PKSIGN");
668 rc
= gcry_sexp_sscan (rsexp
, NULL
, result
, len
);
673 if (rc
&& gpg_err_source (rc
) == GPG_ERR_SOURCE_UNKNOWN
)
679 /* Encrypt the data file to 'pubkey' and sign with 'sigpkey'. */
681 encrypt_data_file (assuan_context_t ctx
, struct crypto_s
* crypto
,
682 gcry_sexp_t pubkey
, gcry_sexp_t sigpkey
,
683 const char *filename
, const void *xml
, size_t len
)
688 void *enc_xml
= NULL
;
689 size_t enc_xml_len
= 0;
690 unsigned char *iv
= NULL
;
692 int algo
= cipher_to_gcrypt (crypto
->save
.hdr
.flags
);
695 unsigned char sig_grip
[20];
696 unsigned char grip
[20];
698 rc
= gcry_cipher_algo_info (algo
, GCRYCTL_GET_KEYLEN
, NULL
, &keysize
);
702 pthread_cleanup_push (gcry_free
, key
);
703 key
= gcry_random_bytes_secure (keysize
, GCRY_STRONG_RANDOM
);
704 #ifdef HAVE_PTHREAD_TESTCANCEL
705 pthread_testcancel (); // may have been a long operation
707 pthread_cleanup_pop (0);
709 return gpg_error (GPG_ERR_ENOMEM
);
711 gcry_pk_get_keygrip (pubkey
, grip
);
712 gcry_pk_get_keygrip (sigpkey
, sig_grip
);
713 pthread_cleanup_push (gcry_free
, key
);
714 rc
= encrypt_xml (ctx
, key
, keysize
, algo
, xml
, len
, &enc_xml
, &enc_xml_len
,
715 &iv
, &iv_len
, crypto
->save
.hdr
.iterations
);
718 gcry_sexp_t sig_sexp
= NULL
;
719 char *hexgrip
= bin2hex (grip
, 20);
721 pthread_cleanup_push (xfree
, iv
);
722 log_write1 (_("Encrypted with keygrip %s"), hexgrip
);
724 hexgrip
= bin2hex (sig_grip
, 20);
725 pthread_cleanup_push (gcry_free
, enc_xml
);
726 rc
= sign (&sig_sexp
, sigpkey
, crypto
, enc_xml
, enc_xml_len
);
731 rc
= agent_verify (sigpkey
, sig_sexp
, enc_xml
, enc_xml_len
);
734 gcry_sexp_t tmp_sexp
;
736 rc
= gcry_sexp_build (&tmp_sexp
, NULL
,
737 "(data (flags pkcs1) (value %b))",
741 gcry_sexp_t key_sexp
;
743 pthread_cleanup_push ((void (*)(void *)) gcry_sexp_release
,
745 rc
= gcry_pk_encrypt (&key_sexp
, tmp_sexp
, pubkey
);
746 pthread_cleanup_pop (0);
747 gcry_sexp_release (tmp_sexp
);
751 memcpy (crypto
->save
.hdr
.iv
, iv
, iv_len
);
752 crypto
->save
.hdr
.datalen
= enc_xml_len
;
753 rc
= gcry_sexp_build (&tmp_sexp
, NULL
, "%S%S", key_sexp
,
755 gcry_sexp_release (key_sexp
);
759 data_len
= gcry_sexp_sprint (tmp_sexp
,
762 data
= xmalloc (data_len
);
764 gcry_sexp_sprint (tmp_sexp
, GCRYSEXP_FMT_CANON
,
769 gcry_sexp_release (tmp_sexp
);
776 pthread_cleanup_pop (0); // enc_xml
777 pthread_cleanup_pop (1); // iv
780 gcry_sexp_release (sig_sexp
);
783 pthread_cleanup_pop (1); // key
787 pthread_cleanup_push (gcry_free
, enc_xml
);
788 rc
= write_file (crypto
, filename
, enc_xml
, enc_xml_len
, data
, data_len
,
790 pthread_cleanup_pop (1); // enc_xml
792 memcpy (&crypto
->hdr
, &crypto
->save
.hdr
, sizeof (file_header_t
));
796 if (rc
&& gpg_err_source (rc
) == GPG_ERR_SOURCE_UNKNOWN
)
802 /* Generated a new keypair from the key parameters in 'sexpstr'. */
804 generate_key (struct crypto_s
* crypto
, char *sexpstr
, int empty
, int preset
)
810 if (crypto
->save
.s2k_count
)
812 rc
= send_to_agent (crypto
->agent
, NULL
, NULL
,
813 "OPTION s2k-count=%lu", crypto
->save
.s2k_count
);
818 if (!crypto
->agent
->inquire_cb
)
819 crypto
->agent
->inquire_cb
= inquire_cb
;
821 rc
= send_to_agent (crypto
->agent
, &pkey
, &plen
, "GENKEY %s%s",
822 preset
? "--preset " : "",
823 empty
? "--no-protection" : "");
827 if (crypto
->save
.pkey
)
828 gcry_sexp_release (crypto
->save
.pkey
);
830 crypto
->save
.pkey
= NULL
;
831 rc
= gcry_sexp_new (&crypto
->save
.pkey
, pkey
, plen
, 1);
834 unsigned char grip
[20];
836 gcry_pk_get_keygrip (crypto
->save
.pkey
, grip
);
837 char *hexgrip
= bin2hex (grip
, sizeof (grip
));
838 log_write (_("Keygrip is %s"), hexgrip
);
841 if (!crypto
->save
.sigpkey
)
843 gcry_sexp_build ((gcry_sexp_t
*) & crypto
->save
.sigpkey
, NULL
, "%S",
853 set_agent_option (struct agent_s
* agent
, const char *name
, const char *value
)
855 return send_to_agent (agent
, NULL
, NULL
, "OPTION %s=%s", name
, value
);
859 set_agent_passphrase (struct crypto_s
* crypto
, const char *key
, size_t len
)
862 struct inquire_data_s idata
;
866 /* This is for use with key files or passphrases obtained from an inquire.
867 * gpg-agent uses strings as passphrases and will truncate the passphrase
868 * at the first encountered null byte. It's only a warning because the
869 * passphrase may belong to a key shared outside of pwmd. */
870 for (i
= 0; i
< len
; i
++)
874 log_write (_("WARNING: keylen=%i, truncated to %i."), len
, i
);
879 hexgrip
= bin2hex (crypto
->grip
, 20);
880 crypto
->agent
->inquire_cb
= inquire_cb
;
881 crypto
->agent
->inquire_data
= &idata
;
882 idata
.crypto
= crypto
;
883 idata
.line
= (char *) key
, idata
.len
= len
;
885 assuan_begin_confidential (crypto
->agent
->ctx
);
886 rc
= send_to_agent (crypto
->agent
, NULL
, NULL
,
887 "PRESET_PASSPHRASE --inquire %s -1", hexgrip
);
888 assuan_end_confidential (crypto
->agent
->ctx
);
895 set_pinentry_mode (struct agent_s
* agent
, const char *mode
)
897 return set_agent_option (agent
, "pinentry-mode", mode
);
901 get_pubkey_bin (struct crypto_s
* crypto
, const unsigned char *grip
,
902 gcry_sexp_t
* result
)
904 char *hexgrip
= bin2hex (grip
, 20);
908 return GPG_ERR_ENOMEM
;
910 rc
= get_pubkey (crypto
, hexgrip
, result
);
916 get_pubkey (struct crypto_s
* crypto
, const char *grip
, gcry_sexp_t
* result
)
922 rc
= send_to_agent (crypto
->agent
, &pkey
, &plen
, "READKEY %s", grip
);
924 rc
= gcry_sexp_new (result
, pkey
, plen
, 1);
931 agent_set_pinentry_options (struct agent_s
* agent
)
934 struct pinentry_option_s
*opts
= &agent
->pinentry_opts
;
936 if (!opts
->display
&& getenv ("DISPLAY"))
938 rc
= set_agent_option (agent
, "display", getenv ("DISPLAY"));
941 opts
->display
= str_dup (getenv ("DISPLAY"));
944 else if (!opts
->ttyname
&& ttyname (STDOUT_FILENO
))
946 rc
= set_agent_option (agent
, "ttyname", ttyname (STDOUT_FILENO
));
949 rc
= set_agent_option (agent
, "ttytype",
950 opts
->ttytype
? opts
->ttytype
: getenv ("TERM"));
953 xfree (opts
->ttyname
);
954 xfree (opts
->ttytype
);
955 opts
->ttyname
= str_dup (ttyname (STDOUT_FILENO
));
956 opts
->ttytype
= str_dup (getenv ("TERM"));
965 inquire_keyfile (void *user
, const char *keyword
)
967 struct crypto_s
*crypto
= user
;
968 char *filename
= crypto
->agent
->inquire_data2
;
969 char *params
= crypto
->agent
->inquire_data3
;
975 if (!strcmp (keyword
, "KEYPARAM"))
976 return assuan_send_data (crypto
->agent
->ctx
, params
, strlen (params
));
978 // This function is only used when generating a new keypair.
979 if (strcmp (keyword
, "NEW_PASSPHRASE"))
980 return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE
);
982 if (stat (filename
, &st
) == -1)
983 return gpg_error_from_errno (errno
);
985 if (crypto
->agent
->inquire_maxlen
986 && st
.st_size
> crypto
->agent
->inquire_maxlen
)
988 log_write (_("The passphrase is too large: have=%u, max=%u."),
989 (unsigned) st
.st_size
, crypto
->agent
->inquire_maxlen
);
990 return GPG_ERR_TOO_LARGE
;
993 buf
= gcry_malloc_secure (st
.st_size
);
995 return GPG_ERR_ENOMEM
;
997 fd
= open (filename
, O_RDONLY
);
999 rc
= gpg_error_from_errno (errno
);
1002 size_t len
= read (fd
, buf
, st
.st_size
);
1004 if (len
== st
.st_size
)
1006 assuan_begin_confidential (crypto
->agent
->ctx
);
1007 rc
= assuan_send_data (crypto
->agent
->ctx
, buf
, len
);
1008 assuan_end_confidential (crypto
->agent
->ctx
);
1011 rc
= gpg_error_from_errno (errno
);
1013 rc
= GPG_ERR_BUFFER_TOO_SHORT
;
1024 agent_export_common (struct crypto_s
* crypto
, const char *hexgrip
,
1025 const char *sign_hexgrip
, int no_passphrase
,
1026 const void *data
, size_t datalen
, const char *outfile
,
1027 const char *keyparams
, const char *keyfile
)
1031 if (!sign_hexgrip
&& hexgrip
)
1032 sign_hexgrip
= hexgrip
;
1036 if (crypto
->sigpkey_sexp
)
1037 gcry_sexp_release (crypto
->sigpkey_sexp
);
1039 crypto
->sigpkey_sexp
= NULL
;
1040 rc
= get_pubkey (crypto
, sign_hexgrip
, &crypto
->save
.sigpkey
);
1044 gcry_pk_get_keygrip (crypto
->save
.sigpkey
, crypto
->sign_grip
);
1049 rc
= get_pubkey (crypto
, hexgrip
, &crypto
->save
.pkey
);
1051 gcry_pk_get_keygrip (crypto
->save
.pkey
, crypto
->grip
);
1055 struct inquire_data_s idata
= { 0 };
1056 char *params
= keyparams
? str_dup (keyparams
)
1057 : default_key_params (crypto
);
1059 pthread_cleanup_push (xfree
, params
);
1060 log_write (_("Generating a new keypair ..."));
1063 log_write (_("Using passphrase obtained from file '%s'"), keyfile
);
1064 rc
= set_pinentry_mode (crypto
->agent
, "loopback");
1065 crypto
->agent
->inquire_cb
= inquire_keyfile
;
1066 crypto
->agent
->inquire_data
= crypto
;
1067 crypto
->agent
->inquire_data2
= (char *) keyfile
;
1068 crypto
->agent
->inquire_data3
= params
;
1072 idata
.line
= params
;
1073 idata
.len
= strlen (params
);
1074 idata
.crypto
= crypto
;
1075 crypto
->agent
->inquire_cb
= inquire_cb
;
1076 crypto
->agent
->inquire_data
= &idata
;
1081 rc
= generate_key (crypto
, params
, no_passphrase
, 1);
1083 gcry_pk_get_keygrip (crypto
->save
.pkey
, crypto
->grip
);
1086 (void) set_pinentry_mode (crypto
->agent
, "ask");
1087 pthread_cleanup_pop (1);
1092 rc
= encrypt_data_file (NULL
, crypto
, crypto
->save
.pkey
,
1093 crypto
->save
.sigpkey
, outfile
, data
, datalen
);
1096 char *tmp
= bin2hex (crypto
->grip
, sizeof (crypto
->grip
));
1098 log_write (_("Success! Keygrip is %s."), tmp
);
1099 rc
= send_to_agent (crypto
->agent
, NULL
, NULL
,
1100 "CLEAR_PASSPHRASE --mode=normal %s", tmp
);
1105 tmp
= bin2hex (crypto
->sign_grip
, sizeof (crypto
->sign_grip
));
1106 log_write (_("Signed with keygrip %s."), tmp
);
1112 if (rc
&& gpg_err_source (rc
) == GPG_ERR_SOURCE_UNKNOWN
)
1113 rc
= gpg_error (rc
);
1119 default_key_params (struct crypto_s
*crypto
)
1121 return config_get_string (NULL
, "keyparam");
1125 agent_passwd (struct crypto_s
* crypto
)
1127 struct inquire_data_s idata
= { 0 };
1129 char *tmp
= bin2hex (crypto
->grip
, 20);
1131 idata
.crypto
= crypto
;
1132 crypto
->agent
->inquire_cb
= inquire_cb
;
1133 crypto
->agent
->inquire_data
= &idata
;
1134 rc
= send_to_agent (crypto
->agent
, NULL
, NULL
, "PASSWD --preset %s", tmp
);
1140 kill_scd (struct agent_s
* agent
)
1147 if (config_get_boolean (NULL
, "kill_scd"))
1149 rc
= send_to_agent (agent
, NULL
, NULL
, "SCD KILLSCD");
1150 if (rc
&& gpg_err_code (rc
) != GPG_ERR_NO_SCDAEMON
)
1151 log_write ("%s: %s", __FUNCTION__
, pwmd_strerror (rc
));