1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
4 Ben Kibbey <bjk@luxsci.net>
6 This file is part of pwmd.
8 Pwmd is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
13 Pwmd is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
27 #include <glib/gprintf.h>
28 #include <glib/gstdio.h>
32 #include <sys/types.h>
36 #include "pwmd-error.h"
48 #include <acl/libacl.h>
52 #include <sys/types.h>
56 static guint8 pwmd_magic
[5] = { '\177', 'P', 'W', 'M', 'D' };
58 static gpg_error_t
mem_realloc_cb(void *data
, const void *buffer
, size_t len
)
60 membuf_t
*mem
= (membuf_t
*)data
;
66 if ((p
= xrealloc(mem
->buf
, mem
->len
+ len
)) == NULL
)
70 memcpy((char *)mem
->buf
+ mem
->len
, buffer
, len
);
75 static gpg_error_t
status_cb(gpointer data
, const gchar
*line
)
77 struct agent_s
*agent
= data
;
79 agent
->inquire_maxlen
= 0;
81 if (!strncmp(line
, "INQUIRE_MAXLEN ", 15))
82 agent
->inquire_maxlen
= atoi(line
+15);
84 return send_status(agent
->client_ctx
, STATUS_AGENT
, "%s", line
);
87 static gpg_error_t
assuan_command(struct agent_s
*a
, gchar
**result
,
88 gsize
*len
, const gchar
*cmd
)
98 rc
= assuan_transact(a
->ctx
, cmd
, mem_realloc_cb
, &a
->data
,
99 a
->inquire_cb
, a
->inquire_data
, status_cb
, a
);
105 mem_realloc_cb(&a
->data
, "", 1);
107 *result
= (gchar
*)a
->data
.buf
;
119 /* This commands are sent from launch_agent() after reconnecting to the agent
120 * and also from the initial client connection. */
121 static gpg_error_t
send_agent_common_options(struct agent_s
*agent
)
125 rc
= send_to_agent(agent
, NULL
, NULL
, "OPTION cache-ttl-opt-preset=-1");
129 static gpg_error_t
launch_agent(struct agent_s
*agent
)
132 assuan_context_t ctx
;
133 const gchar
*t
= NULL
;
134 static struct assuan_malloc_hooks mhooks
= { xmalloc
, xrealloc
, xfree
};
135 gchar
*s
, buf
[LINE_MAX
];
138 s
= get_key_file_string("global", "agent_env_file");
140 gchar
*ss
= expand_homedir(s
);
147 while ((s
= fgets(buf
, sizeof(buf
), fp
))) {
149 if (g_str_has_prefix(s
, "GPG_AGENT_INFO=")) {
150 g_setenv("GPG_AGENT_INFO", s
+strlen("GPG_AGENT_INFO="), TRUE
);
158 log_write("%s: %s", s
, pwmd_strerror(gpg_error_from_syserror()));
161 t
= g_getenv("GPG_AGENT_INFO");
163 return gpg_err_code(GPG_ERR_NO_AGENT
);
165 rc
= assuan_new_ext(&ctx
, GPG_ERR_SOURCE_DEFAULT
, &mhooks
,
166 debug_level
? assuan_log_cb
: NULL
, "AGENT ");
170 gchar
**fields
= g_strsplit(t
, ":", 0);
171 rc
= assuan_socket_connect(ctx
, fields
[0], ASSUAN_INVALID_PID
, 0);
179 /* Restore the previous agent settings for this new context. */
180 assuan_release(agent
->ctx
);
182 rc
= send_agent_common_options(agent
);
183 if (!rc
&& agent
->display
)
184 rc
= set_agent_option(agent
, "display", agent
->display
);
186 if (!rc
&& agent
->ttyname
)
187 rc
= set_agent_option(agent
, "ttyname", agent
->ttyname
);
189 if (!rc
&& agent
->ttytype
)
190 rc
= set_agent_option(agent
, "ttytype", agent
->ttytype
);
192 if (!rc
&& agent
->lc_messages
)
193 rc
= set_agent_option(agent
, "lc-messages", agent
->lc_messages
);
195 if (!rc
&& agent
->lc_ctype
)
196 rc
= set_agent_option(agent
, "lc-ctype", agent
->lc_ctype
);
203 gpg_error_t
send_to_agent(struct agent_s
*agent
, gchar
**result
, gsize
*len
,
204 const gchar
*fmt
, ...)
211 rc
= launch_agent(agent
);
217 if (g_vasprintf(&cmd
, fmt
, ap
) > 0) {
218 rc
= assuan_command(agent
, result
, len
, cmd
);
219 if (!agent
->restart
&& gpg_err_source(rc
) == GPG_ERR_SOURCE_DEFAULT
220 && (gpg_err_code(rc
) == GPG_ERR_ASS_CONNECT_FAILED
221 || gpg_err_code(rc
) == GPG_ERR_EPIPE
)) {
222 g_unsetenv("GPG_AGENT_INFO");
223 agent
->restart
= TRUE
;
224 rc
= launch_agent(agent
);
226 rc
= assuan_command(agent
, result
, len
, cmd
);
229 agent
->restart
= FALSE
;
239 static void agent_disconnect(struct agent_s
*agent
)
245 assuan_release(agent
->ctx
);
250 void cleanup_agent(struct agent_s
*agent
)
256 g_free(agent
->display
);
257 g_free(agent
->ttyname
);
258 g_free(agent
->ttytype
);
259 g_free(agent
->lc_messages
);
260 g_free(agent
->lc_ctype
);
263 agent_disconnect(agent
);
268 gpg_error_t
agent_init(struct agent_s
**agent
)
270 struct agent_s
*new = g_malloc0(sizeof(struct agent_s
));
273 return GPG_ERR_ENOMEM
;
279 void set_header_defaults(file_header_t
*hdr
)
281 gchar
*s
= get_key_file_string(NULL
, "cipher");
282 gint flags
= cipher_string_to_cipher(s
);
285 memset(hdr
, 0, sizeof(file_header_t
));
286 memcpy(hdr
->magic
, pwmd_magic
, sizeof(hdr
->magic
));
288 log_write(_("Invalid 'cipher' in configuration file. Using a default of aes256."));
289 hdr
->flags
= flags
== -1 ? PWMD_CIPHER_AES256
: flags
;
290 hdr
->version
= VERSION_HEX
;
293 gpg_error_t
read_data_header(const gchar
*filename
, file_header_t
*rhdr
,
294 struct stat
*rst
, gint
*rfd
)
302 if (g_lstat(filename
, &st
) == -1)
303 return gpg_error_from_syserror();
305 if (!S_ISREG(st
.st_mode
))
306 return GPG_ERR_ENOANO
;
308 fd
= open(filename
, O_RDONLY
);
310 return gpg_error_from_syserror();
312 len
= read(fd
, &hdr
, sizeof(file_header_t
));
313 if (len
!= sizeof(file_header_t
))
314 rc
= rc
== -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA
;
316 if (!rc
&& memcmp(hdr
.magic
, pwmd_magic
, sizeof(hdr
.magic
)))
317 rc
= GPG_ERR_BAD_DATA
;
318 else if (hdr
.version
< 0x0300)
319 rc
= GPG_ERR_UNKNOWN_VERSION
;
337 gpg_error_t
read_data_file(const gchar
*filename
, struct crypto_s
*crypto
)
344 cleanup_crypto_stage1(crypto
);
345 rc
= read_data_header(filename
, &crypto
->hdr
, &crypto
->st
, &fd
);
349 crypto
->ciphertext_len
= crypto
->hdr
.datalen
;
350 crypto
->ciphertext
= g_malloc(crypto
->hdr
.datalen
);
351 if (!crypto
->ciphertext
) {
356 len
= read(fd
, crypto
->ciphertext
, crypto
->hdr
.datalen
);
357 if (len
!= crypto
->hdr
.datalen
) {
358 rc
= rc
== -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA
;
362 rlen
= read(fd
, crypto
->grip
, 20);
364 rc
= rc
== -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA
;
368 rlen
= read(fd
, crypto
->sign_grip
, 20);
370 rc
= rc
== -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA
;
374 len
= crypto
->st
.st_size
-sizeof(file_header_t
)-crypto
->hdr
.datalen
-40;
381 rlen
= read(fd
, buf
, len
);
383 rc
= rc
== -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA
;
387 rc
= gcry_sexp_new(&crypto
->ciphertext_sexp
, buf
, rlen
, 1);
391 if (crypto
->pkey_sexp
)
392 gcry_sexp_release(crypto
->pkey_sexp
);
394 if (crypto
->sigpkey_sexp
)
395 gcry_sexp_release(crypto
->sigpkey_sexp
);
397 crypto
->pkey_sexp
= crypto
->sigpkey_sexp
= NULL
;
398 rc
= get_pubkey_bin(crypto
, crypto
->grip
, &crypto
->pkey_sexp
);
400 rc
= get_pubkey_bin(crypto
, crypto
->sign_grip
, &crypto
->sigpkey_sexp
);
408 static gpg_error_t
inquire_cb(gpointer user
, const char *keyword
)
410 struct inquire_data_s
*idata
= user
;
412 if (!idata
->preset
&& (!g_strcmp0(keyword
, "PASSPHRASE")
413 || !g_strcmp0(keyword
, "NEW_PASSPHRASE"))) {
414 return agent_loopback_cb(idata
->crypto
, keyword
);
416 // SAVE --inquire-keyparam
417 else if (idata
->preset
&& !g_strcmp0(keyword
, "KEYPARAM")) {
418 idata
->preset
= FALSE
;
419 return agent_loopback_cb(idata
->crypto
, keyword
);
422 if (idata
->crypto
->agent
->inquire_maxlen
423 && idata
->len
> idata
->crypto
->agent
->inquire_maxlen
) {
424 log_write(_("Inquired data too large: have=%u, max=%u"), idata
->len
,
425 idata
->crypto
->agent
->inquire_maxlen
);
426 return GPG_ERR_TOO_LARGE
;
429 idata
->crypto
->agent
->inquire_maxlen
= 0;
430 return assuan_send_data(idata
->crypto
->agent
->ctx
, idata
->line
, idata
->len
);
433 static gpg_error_t
extract_key(struct crypto_s
*crypto
, guchar
**result
,
437 gcry_sexp_t enc_sexp
= NULL
, tmp_sexp
;
438 struct inquire_data_s idata
= {0};
439 gchar
*hexgrip
= NULL
;
441 gsize keylen
, keysize
;
443 gint algo
= cipher_to_gcrypt(crypto
->hdr
.flags
);
446 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_KEYLEN
, NULL
, &keysize
);
450 tmp_sexp
= gcry_sexp_find_token(crypto
->ciphertext_sexp
, "enc-val", 0);
452 return GPG_ERR_BAD_DATA
;
454 hexgrip
= bin2hex(crypto
->grip
, sizeof(crypto
->grip
));
460 rc
= cache_is_shadowed(hexgrip
);
461 if (rc
&& rc
!= GPG_ERR_NO_DATA
)
464 shadowed
= !rc
? TRUE
: FALSE
;
466 gcry_sexp_t tmp2_sexp
= gcry_sexp_cdr(tmp_sexp
);
467 gcry_sexp_release(tmp_sexp
);
468 tmp_sexp
= gcry_sexp_nth(tmp2_sexp
, 0);
469 gcry_sexp_release(tmp2_sexp
);
470 rc
= gcry_sexp_build(&enc_sexp
, NULL
, "(enc-val (flags pkcs1) %S)",
474 rc
= gcry_sexp_build(&enc_sexp
, NULL
, "%S", tmp_sexp
);
476 gcry_sexp_release(tmp_sexp
);
480 crypto
->agent
->inquire_cb
= inquire_cb
;
481 idata
.crypto
= crypto
;
482 idata
.len
= gcry_sexp_sprint(enc_sexp
, GCRYSEXP_FMT_CANON
, NULL
, 0);
483 idata
.line
= g_malloc(idata
.len
);
489 idata
.len
= gcry_sexp_sprint(enc_sexp
, GCRYSEXP_FMT_CANON
, idata
.line
,
491 crypto
->agent
->inquire_data
= &idata
;
492 gcry_sexp_release(enc_sexp
);
494 log_write1(_("Keygrip is %s, bits=%i"), hexgrip
,
495 gcry_pk_get_nbits(crypto
->pkey_sexp
));
496 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
, "SETKEY %s", hexgrip
);
500 if (!crypto
->agent
->desc
) {
502 "A %s is required to unlock the secret key for the "
503 "encrypted data file \"%s\". Please enter the %s "
505 shadowed
? "PIN" : _("passphrase"), crypto
->filename
,
506 shadowed
? "PIN" : _("passphrase"));
509 tmp
= plus_escape(crypto
->agent
->desc
);
511 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
, "SETKEYDESC %s", tmp
);
516 assuan_begin_confidential(crypto
->agent
->ctx
);
517 rc
= send_to_agent(crypto
->agent
, &key
, &keylen
, "PKDECRYPT");
518 assuan_end_confidential(crypto
->agent
->ctx
);
522 rc
= gcry_sexp_new(&tmp_sexp
, key
, keylen
, 1);
527 key
= (gchar
*)gcry_sexp_nth_data(tmp_sexp
, 1, result_len
);
529 *result
= gcry_malloc(*result_len
);
533 memcpy(*result
, key
, *result_len
);
536 rc
= GPG_ERR_BAD_DATA
;
538 gcry_sexp_release(tmp_sexp
);
545 gcry_sexp_release(enc_sexp
);
550 static gpg_error_t
verify(gcry_sexp_t pkey
, gcry_sexp_t sig_sexp
,
551 const gpointer data
, gsize len
)
554 guint hashlen
= gcry_md_get_algo_dlen(GCRY_MD_SHA256
);
556 gcry_sexp_t data_sexp
;
558 hash
= gcry_malloc(hashlen
);
560 return GPG_ERR_ENOMEM
;
562 gcry_md_hash_buffer(GCRY_MD_SHA256
, hash
, data
, len
);
563 rc
= gcry_sexp_build(&data_sexp
, NULL
,
564 "(data (flags pkcs1) (hash sha256 %b))", hashlen
, hash
);
567 rc
= gcry_pk_verify(sig_sexp
, data_sexp
, pkey
);
568 gcry_sexp_release(data_sexp
);
574 gpg_error_t
decrypt_data(struct crypto_s
*crypto
)
579 gcry_cipher_hd_t h
= NULL
;
580 gsize blocksize
, keysize
;
581 gint algo
= cipher_to_gcrypt(crypto
->hdr
.flags
);
582 gpointer outbuf
= NULL
;
583 gcry_sexp_t sig_sexp
;
585 rc
= extract_key(crypto
, &key
, &keylen
);
589 sig_sexp
= gcry_sexp_find_token(crypto
->ciphertext_sexp
, "sig-val", 0);
591 rc
= GPG_ERR_BAD_DATA
;
595 rc
= verify(crypto
->sigpkey_sexp
, sig_sexp
, crypto
->ciphertext
, crypto
->ciphertext_len
);
596 gcry_sexp_release(sig_sexp
);
600 rc
= gcry_cipher_open(&h
, algo
, GCRY_CIPHER_MODE_CBC
, 0);
604 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_KEYLEN
, NULL
, &keysize
);
607 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_BLKLEN
, NULL
, &blocksize
);
611 rc
= gcry_cipher_setiv(h
, crypto
->hdr
.iv
, sizeof(crypto
->hdr
.iv
));
615 rc
= gcry_cipher_setkey(h
, key
, keylen
);
619 outbuf
= gcry_malloc(crypto
->hdr
.datalen
);
625 rc
= gcry_cipher_decrypt(h
, outbuf
, crypto
->hdr
.datalen
,
626 crypto
->ciphertext
, crypto
->hdr
.datalen
);
630 crypto
->plaintext
= outbuf
;
631 crypto
->plaintext_len
= crypto
->hdr
.datalen
;
636 gcry_cipher_close(h
);
640 static gpg_error_t
encrypt_xml(gpointer key
, gsize keylen
, gint algo
,
641 const gpointer xml
, gsize len
, gpointer
*result
, gsize
*result_len
,
642 guchar
**iv
, gsize
*iv_len
)
646 gsize blocksize
, keysize
;
647 gpointer inbuf
= NULL
;
650 rc
= gcry_cipher_open(&h
, algo
, GCRY_CIPHER_MODE_CBC
, 0);
654 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_KEYLEN
, NULL
, &keysize
);
658 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_BLKLEN
, NULL
, &blocksize
);
662 *(iv
) = g_malloc(blocksize
);
667 gcry_create_nonce(*(iv
), blocksize
);
668 rc
= gcry_cipher_setiv(h
, *(iv
), blocksize
);
672 rc
= gcry_cipher_setkey(h
, key
, keylen
);
677 len
+= blocksize
-(len
%blocksize
);
679 inbuf
= gcry_malloc(len
);
685 memset(inbuf
, 0, len
);
686 memcpy(inbuf
, xml
, olen
);
687 rc
= gcry_cipher_encrypt(h
, inbuf
, len
, NULL
, 0);
693 gcry_cipher_close(h
);
703 gcry_cipher_close(h
);
707 gpg_error_t
agent_loopback_cb(gpointer user
, const gchar
*keyword
)
709 struct crypto_s
*crypto
= user
;
713 gboolean keyparam
= FALSE
;
715 if (!g_strcmp0(keyword
, "KEYPARAM")) {
717 rc
= assuan_inquire(crypto
->client_ctx
, keyword
, &result
, &len
, 0);
719 else { // PASSPHRASE or NEW_PASSPHRASE
720 assuan_begin_confidential(crypto
->client_ctx
);
721 rc
= assuan_inquire(crypto
->client_ctx
, keyword
, &result
, &len
, 0);
722 assuan_end_confidential(crypto
->client_ctx
);
726 if (keyparam
&& !len
) {
727 gchar
*tmp
= default_key_params(crypto
);
730 return gpg_error(GPG_ERR_ENOMEM
);
733 result
= xmalloc(len
);
734 memcpy(result
, tmp
, len
);
738 pthread_cleanup_push(xfree
, result
);
741 rc
= assuan_send_data(crypto
->agent
->ctx
, result
, len
);
743 assuan_begin_confidential(crypto
->agent
->ctx
);
744 rc
= assuan_send_data(crypto
->agent
->ctx
, result
, len
);
745 assuan_end_confidential(crypto
->agent
->ctx
);
748 pthread_cleanup_pop(1);
750 else if (gpg_err_code(rc
) == GPG_ERR_ASS_CANCELED
) {
751 gpg_error_t arc
= assuan_write_line(crypto
->agent
->ctx
, "CAN");
757 arc
= assuan_read_line(crypto
->agent
->ctx
, &line
, &len
);
768 static gpg_error_t
sign(gcry_sexp_t
*rsexp
, const gchar
*sign_hexgrip
,
769 struct crypto_s
*crypto
, const gpointer data
, gsize len
)
773 gchar
*tmp
= sign_hexgrip
? g_strdup(sign_hexgrip
)
774 : bin2hex(crypto
->grip
, sizeof(crypto
->grip
));
776 pthread_cleanup_push(g_free
, tmp
);
777 log_write1(_("Sign keygrip is %s"), tmp
);
778 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
, "SIGKEY %s", tmp
);
779 pthread_cleanup_pop(1);
782 guint hashlen
= gcry_md_get_algo_dlen(GCRY_MD_SHA256
);
784 hash
= gcry_malloc(hashlen
);
786 return GPG_ERR_ENOMEM
;
788 gcry_md_hash_buffer(GCRY_MD_SHA256
, hash
, data
, len
);
789 tmp
= bin2hex(hash
, hashlen
);
791 pthread_cleanup_push(g_free
, tmp
);
792 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
,
793 "SETHASH --hash=sha256 %s", tmp
);
794 pthread_cleanup_pop(1);
798 struct inquire_data_s idata
= {0};
800 idata
.crypto
= crypto
;
801 crypto
->agent
->inquire_data
= &idata
;
802 crypto
->agent
->inquire_cb
= inquire_cb
;
803 rc
= send_to_agent(crypto
->agent
, &result
, &len
, "PKSIGN");
805 rc
= gcry_sexp_sscan(rsexp
, NULL
, result
, len
);
813 static gpg_error_t
write_file(struct crypto_s
*crypto
, const gchar
*filename
,
814 gpointer data
, gsize data_len
, gpointer sexp
, gsize sexp_len
)
816 gchar tmp
[FILENAME_MAX
] = { 0 };
827 if (g_lstat(filename
, &st
) == 0) {
828 mode
= st
.st_mode
& (S_IRWXU
|S_IRWXG
|S_IRWXO
);
830 if (!(mode
& S_IWUSR
))
831 return GPG_ERR_EACCES
;
833 else if (errno
!= ENOENT
)
834 return gpg_error_from_syserror();
836 g_snprintf(tmp
, sizeof(tmp
), "%s.XXXXXX", filename
);
837 #if GLIB_CHECK_VERSION(2, 22, 0)
838 fd
= g_mkstemp_full(tmp
, O_WRONLY
, 0600);
843 rc
= gpg_error_from_syserror();
844 log_write("%s: %s", tmp
, pwmd_strerror(rc
));
849 // xml_import() or convert_file() from command line.
853 pthread_cleanup_push(cleanup_unlink_cb
, tmp
);
854 crypto
->save
.hdr
.version
= VERSION_HEX
;
855 len
= write(fd
, &crypto
->save
.hdr
, sizeof(file_header_t
));
856 if (len
== sizeof(file_header_t
)) {
857 len
= write(fd
, data
, data_len
);
858 if (len
== data_len
) {
859 len
= write(fd
, sexp
, sexp_len
);
861 rc
= gpg_error_from_syserror();
864 rc
= gpg_error_from_syserror();
867 rc
= gpg_error_from_syserror();
870 pthread_cleanup_push(acl_free
, acl
);
873 if (fsync(fd
) != -1) {
874 if (filename
&& close(fd
) != -1) {
875 if (mode
&& get_key_file_boolean(filename
, "backup")) {
876 gchar tmp2
[FILENAME_MAX
];
878 g_snprintf(tmp2
, sizeof(tmp2
), "%s.backup", filename
);
880 acl
= acl_get_file(filename
, ACL_TYPE_ACCESS
);
882 log_write("ACL: %s: %s", filename
,
883 pwmd_strerror(gpg_error_from_syserror()));
886 if (g_rename(filename
, tmp2
) == -1)
887 rc
= gpg_error_from_syserror();
891 acl
= acl_get_file(".", ACL_TYPE_DEFAULT
);
893 log_write("ACL: %s: %s", filename
,
894 pwmd_strerror(gpg_error_from_syserror()));
899 rc
= gpg_error_from_syserror();
902 rc
= gpg_error_from_syserror();
906 if (filename
&& g_rename(tmp
, filename
) != -1) {
908 if (filename
&& mode
)
909 g_chmod(filename
, mode
);
912 if (filename
&& acl
&& acl_set_file(filename
, ACL_TYPE_ACCESS
, acl
))
913 log_write("ACL: %s: %s", filename
,
914 pwmd_strerror(gpg_error_from_syserror()));
917 /* Be sure the file entry has been written to disk. On FreeBSD I
918 * noticed delays causing a following command to return
919 * GPG_ERR_CHECKSUM. Recommended from fsync(2) (Linux).
923 gchar
*s
= get_key_file_string("global", "data_directory");
925 path
= expand_homedir(s
);
934 rc
= gpg_error_from_syserror();
939 rc
= gpg_error_from_syserror();
942 rc
= gpg_error_from_syserror();
946 pthread_cleanup_pop(1);
948 pthread_cleanup_pop(rc
? 1 : 0); // unlink
952 gpg_error_t
encrypt_data_file(struct crypto_s
*crypto
, gcry_sexp_t pubkey
,
953 gcry_sexp_t sigpkey
, const gchar
*filename
, const gpointer xml
,
957 gpointer data
= NULL
;
959 gpointer enc_xml
= NULL
;
960 gsize enc_xml_len
= 0;
963 gint algo
= cipher_to_gcrypt(crypto
->save
.hdr
.flags
);
969 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_KEYLEN
, NULL
, &keysize
);
973 pthread_cleanup_push(gcry_free
, key
);
974 key
= gcry_random_bytes_secure(keysize
, GCRY_STRONG_RANDOM
);
975 pthread_testcancel(); // may have been a long operation
976 pthread_cleanup_pop(0);
978 return GPG_ERR_ENOMEM
;
980 gcry_pk_get_keygrip(pubkey
, grip
);
981 gcry_pk_get_keygrip(sigpkey
, sig_grip
);
982 pthread_cleanup_push(g_free
, iv
);
983 pthread_cleanup_push(gcry_free
, key
);
984 rc
= encrypt_xml(key
, keysize
, algo
, xml
, len
, &enc_xml
, &enc_xml_len
,
987 gcry_sexp_t sig_sexp
= NULL
;
988 gchar
*hexgrip
= bin2hex(sig_grip
, 20);
990 pthread_cleanup_push(gcry_free
, enc_xml
);
991 rc
= sign(&sig_sexp
, hexgrip
, crypto
, enc_xml
, enc_xml_len
);
995 rc
= verify(sigpkey
, sig_sexp
, enc_xml
, enc_xml_len
);
998 gcry_sexp_t tmp_sexp
;
1000 rc
= gcry_sexp_build(&tmp_sexp
, NULL
,
1001 "(data (flags pkcs1) (value %b))", keysize
, key
);
1003 gcry_sexp_t key_sexp
;
1005 pthread_cleanup_push((void (*)(void*))gcry_sexp_release
,
1007 rc
= gcry_pk_encrypt(&key_sexp
, tmp_sexp
, pubkey
);
1008 pthread_cleanup_pop(0);
1009 gcry_sexp_release(tmp_sexp
);
1012 memcpy(crypto
->save
.hdr
.iv
, iv
, iv_len
);
1013 crypto
->save
.hdr
.datalen
= enc_xml_len
;
1014 rc
= gcry_sexp_build(&tmp_sexp
, NULL
, "%S%S", key_sexp
,
1016 gcry_sexp_release(key_sexp
);
1019 data_len
= gcry_sexp_sprint(tmp_sexp
,
1020 GCRYSEXP_FMT_CANON
, NULL
, 0);
1021 data
= g_malloc(data_len
+40); // +40 for keygrips
1023 gcry_sexp_sprint(tmp_sexp
, GCRYSEXP_FMT_CANON
,
1028 rc
= GPG_ERR_ENOMEM
;
1030 gcry_sexp_release(tmp_sexp
);
1037 pthread_cleanup_pop(0); // enc_xml
1040 gcry_sexp_release(sig_sexp
);
1043 pthread_cleanup_pop(1); // key
1044 pthread_cleanup_pop(1); // iv
1047 pthread_cleanup_push(gcry_free
, enc_xml
);
1048 memcpy(data
, grip
, 20);
1049 memcpy(data
+20, sig_grip
, 20);
1050 rc
= write_file(crypto
, filename
, enc_xml
, enc_xml_len
, data
, data_len
);
1051 pthread_cleanup_pop(1); // enc_xml
1054 g_lstat(filename
, &crypto
->st
);
1056 memcpy(&crypto
->hdr
, &crypto
->save
.hdr
, sizeof(file_header_t
));
1064 void cleanup_save(struct save_s
*save
)
1070 gcry_sexp_release(save
->pkey
);
1073 gcry_sexp_release(save
->sigpkey
);
1075 memset(save
, 0, sizeof(struct save_s
));
1078 /* Keep the agent ctx to retain pinentry options which will be freed in
1079 * cleanup_cb(). Also keep .pubkey since it may be needed for a SAVE. */
1080 void cleanup_crypto_stage1(struct crypto_s
*cr
)
1085 cleanup_save(&cr
->save
);
1087 if (cr
->ciphertext_sexp
)
1088 gcry_sexp_release(cr
->ciphertext_sexp
);
1091 gcry_free(cr
->plaintext
);
1093 g_free(cr
->ciphertext
);
1094 g_free(cr
->filename
);
1095 cr
->filename
= NULL
;
1096 cr
->ciphertext_sexp
= NULL
;
1097 cr
->ciphertext
= NULL
;
1098 cr
->ciphertext_len
= 0;
1099 cr
->plaintext
= NULL
;
1100 cr
->plaintext_len
= 0;
1103 void cleanup_crypto_stage2(struct crypto_s
*cr
)
1108 cleanup_crypto_stage1(cr
);
1109 set_header_defaults(&cr
->hdr
);
1112 void cleanup_crypto(struct crypto_s
**c
)
1114 struct crypto_s
*cr
= *c
;
1119 cleanup_crypto_stage2(cr
);
1122 gcry_sexp_release(cr
->pkey_sexp
);
1124 if (cr
->sigpkey_sexp
)
1125 gcry_sexp_release(cr
->sigpkey_sexp
);
1128 cleanup_agent(cr
->agent
);
1134 gpg_error_t
init_client_crypto(struct crypto_s
**crypto
)
1136 struct crypto_s
*new = g_malloc0(sizeof(struct crypto_s
));
1140 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
1141 return GPG_ERR_ENOMEM
;
1144 rc
= agent_init(&new->agent
);
1146 rc
= send_agent_common_options(new->agent
);
1148 rc
= set_pinentry_options(new->agent
);
1156 set_header_defaults(&new->hdr
);
1161 gpg_error_t
generate_key(struct crypto_s
*crypto
, gchar
*sexpstr
,
1162 gboolean empty
, gboolean preset
)
1168 if (crypto
->save
.s2k_count
) {
1169 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
,
1170 "OPTION s2k-count=%lu", crypto
->save
.s2k_count
);
1175 if (!crypto
->agent
->inquire_cb
)
1176 crypto
->agent
->inquire_cb
= inquire_cb
;
1178 rc
= send_to_agent(crypto
->agent
, &pkey
, &plen
, "GENKEY %s%s",
1179 preset
? "--preset " : "",
1180 empty
? "--no-protection" : "");
1184 if (crypto
->save
.pkey
)
1185 gcry_sexp_release(crypto
->save
.pkey
);
1187 crypto
->save
.pkey
= NULL
;
1188 rc
= gcry_sexp_new(&crypto
->save
.pkey
, pkey
, plen
, 1);
1192 gcry_pk_get_keygrip(crypto
->save
.pkey
, grip
);
1193 gchar
*hexgrip
= bin2hex(grip
, sizeof(grip
));
1194 log_write1(_("Keygrip is %s"), hexgrip
);
1197 if (!crypto
->save
.sigpkey
) {
1198 gcry_sexp_build((gcry_sexp_t
*)&crypto
->save
.sigpkey
, NULL
, "%S",
1207 gpg_error_t
set_agent_option(struct agent_s
*agent
, const gchar
*name
,
1210 return send_to_agent(agent
, NULL
, NULL
, "OPTION %s=%s", name
, value
);
1213 gpg_error_t
set_agent_passphrase(struct crypto_s
*crypto
, const gchar
*key
,
1217 struct inquire_data_s idata
;
1221 /* This is for use with key files or passphrases obtained from an inquire.
1222 * gpg-agent uses strings as passphrases and will truncate the passphrase
1223 * at the first encountered null byte. It's only a warning because the
1224 * passphrase may belong to a key shared outside of pwmd. */
1225 for (i
= 0; i
< len
; i
++) {
1227 log_write(_("WARNING: keylen=%i, truncated to %i."), len
, i
);
1232 hexgrip
= bin2hex(crypto
->grip
, 20);
1233 crypto
->agent
->inquire_cb
= inquire_cb
;
1234 crypto
->agent
->inquire_data
= &idata
;
1235 idata
.crypto
= crypto
;
1236 idata
.line
= (gchar
*)key
,
1238 idata
.preset
= TRUE
;
1239 assuan_begin_confidential(crypto
->agent
->ctx
);
1240 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
,
1241 "PRESET_PASSPHRASE --inquire %s -1", hexgrip
);
1242 assuan_end_confidential(crypto
->agent
->ctx
);
1243 idata
.preset
= FALSE
;
1248 gpg_error_t
set_pinentry_mode(struct agent_s
*agent
, const gchar
*mode
)
1250 return set_agent_option(agent
, "pinentry-mode", mode
);
1253 gpg_error_t
get_pubkey_bin(struct crypto_s
*crypto
, const guchar
*grip
,
1254 gcry_sexp_t
*result
)
1256 gchar
*hexgrip
= bin2hex(grip
, 20);
1260 return GPG_ERR_ENOMEM
;
1262 rc
= get_pubkey(crypto
, hexgrip
, result
);
1267 gpg_error_t
get_pubkey(struct crypto_s
*crypto
, const gchar
*grip
,
1268 gcry_sexp_t
*result
)
1274 rc
= send_to_agent(crypto
->agent
, &pkey
, &plen
, "READKEY %s", grip
);
1276 rc
= gcry_sexp_new(result
, pkey
, plen
, 1);
1282 gpg_error_t
set_pinentry_options(struct agent_s
*agent
)
1286 if (getenv("DISPLAY")) {
1287 rc
= set_agent_option(agent
, "display", getenv("DISPLAY"));
1289 g_free(agent
->display
);
1290 agent
->display
= g_strdup(getenv("DISPLAY"));
1293 else if (ttyname(STDOUT_FILENO
)) {
1294 rc
= set_agent_option(agent
, "ttyname", ttyname(STDOUT_FILENO
));
1296 rc
= set_agent_option(agent
, "ttytype", getenv("TERM"));
1298 g_free(agent
->ttyname
);
1299 g_free(agent
->ttytype
);
1300 agent
->ttyname
= g_strdup(ttyname(STDOUT_FILENO
));
1301 agent
->ttytype
= g_strdup(getenv("TERM"));
1309 static gpg_error_t
inquire_keyfile(gpointer user
, const gchar
*keyword
)
1311 struct crypto_s
*crypto
= user
;
1312 gchar
*filename
= crypto
->agent
->inquire_data2
;
1313 gchar
*params
= crypto
->agent
->inquire_data3
;
1320 if (!g_strcmp0(keyword
, "KEYPARAM"))
1321 return assuan_send_data(crypto
->agent
->ctx
, params
, strlen(params
));
1323 // This function is only used when generating a new keypair.
1324 if (g_strcmp0(keyword
, "NEW_PASSPHRASE"))
1325 return gpg_error(GPG_ERR_ASS_UNKNOWN_INQUIRE
);
1327 if (stat(filename
, &st
) == -1)
1328 return gpg_error_from_syserror();
1330 if (crypto
->agent
->inquire_maxlen
1331 && st
.st_size
> crypto
->agent
->inquire_maxlen
) {
1332 log_write(_("The passphrase is too large: have=%u, max=%u."),
1333 (unsigned)st
.st_size
, crypto
->agent
->inquire_maxlen
);
1334 return GPG_ERR_TOO_LARGE
;
1337 buf
= gcry_malloc_secure(st
.st_size
);
1339 return GPG_ERR_ENOMEM
;
1341 fd
= open(filename
, O_RDONLY
);
1343 rc
= gpg_error_from_syserror();
1345 len
= read(fd
, buf
, st
.st_size
);
1346 if (len
== st
.st_size
) {
1347 assuan_begin_confidential(crypto
->agent
->ctx
);
1348 rc
= assuan_send_data(crypto
->agent
->ctx
, buf
, len
);
1349 assuan_end_confidential(crypto
->agent
->ctx
);
1352 rc
= gpg_error_from_syserror();
1354 rc
= GPG_ERR_BUFFER_TOO_SHORT
;
1362 gpg_error_t
export_common(struct crypto_s
*crypto
, const gchar
*hexgrip
,
1363 const gchar
*sign_hexgrip
, gboolean no_passphrase
,
1364 const gpointer data
, gsize datalen
, const gchar
*outfile
,
1365 const gchar
*keyparams
, const gchar
*keyfile
)
1370 if (crypto
->sigpkey_sexp
)
1371 gcry_sexp_release(crypto
->sigpkey_sexp
);
1373 crypto
->sigpkey_sexp
= NULL
;
1374 rc
= get_pubkey(crypto
, sign_hexgrip
, &crypto
->save
.sigpkey
);
1378 gcry_pk_get_keygrip(crypto
->save
.sigpkey
, crypto
->sign_grip
);
1382 rc
= get_pubkey(crypto
, hexgrip
, &crypto
->save
.pkey
);
1384 gcry_pk_get_keygrip(crypto
->save
.pkey
, crypto
->grip
);
1387 struct inquire_data_s idata
= {0};
1388 gchar
*params
= keyparams
? g_strdup(keyparams
)
1389 : default_key_params(crypto
);
1391 pthread_cleanup_push(g_free
, params
);
1392 log_write(_("Generating a new keypair ..."));
1394 log_write(N_("Using passphrase obtained from file '%s'"), keyfile
);
1395 rc
= set_pinentry_mode(crypto
->agent
, "loopback");
1396 crypto
->agent
->inquire_cb
= inquire_keyfile
;
1397 crypto
->agent
->inquire_data
= crypto
;
1398 crypto
->agent
->inquire_data2
= (gchar
*)keyfile
;
1399 crypto
->agent
->inquire_data3
= params
;
1402 idata
.line
= params
;
1403 idata
.len
= strlen(params
);
1404 idata
.crypto
= crypto
;
1405 crypto
->agent
->inquire_cb
= inquire_cb
;
1406 crypto
->agent
->inquire_data
= &idata
;
1410 rc
= generate_key(crypto
, params
, no_passphrase
, TRUE
);
1411 gcry_pk_get_keygrip(crypto
->save
.pkey
, crypto
->grip
);
1414 (void)set_pinentry_mode(crypto
->agent
, "ask");
1415 pthread_cleanup_pop(1);
1419 rc
= encrypt_data_file(crypto
, crypto
->save
.pkey
, crypto
->save
.sigpkey
,
1420 outfile
, data
, datalen
);
1422 gchar
*tmp
= bin2hex(crypto
->grip
, sizeof(crypto
->grip
));
1424 log_write(_("Success! Keygrip is %s."), tmp
);
1425 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
,
1426 "CLEAR_PASSPHRASE --mode=normal %s", tmp
);
1430 tmp
= bin2hex(crypto
->sign_grip
, sizeof(crypto
->sign_grip
));
1431 log_write(_("Signed with keygrip %s."), tmp
);
1440 gchar
*default_key_params(struct crypto_s
*crypto
)
1442 gint len
= get_key_file_integer(NULL
, "nbits");
1444 gchar
*algo
= get_key_file_string(NULL
, "algo");
1447 g_snprintf(buf
, sizeof(buf
), "%i", len
);
1448 result
= g_strdup_printf("(genkey (%s (nbits %i:%i)))", algo
, strlen(buf
),
1454 gpg_error_t
agent_passwd(struct crypto_s
*crypto
)
1456 struct inquire_data_s idata
= {0};
1458 gchar
*tmp
= bin2hex(crypto
->grip
, 20);
1460 idata
.crypto
= crypto
;
1461 crypto
->agent
->inquire_cb
= inquire_cb
;
1462 crypto
->agent
->inquire_data
= &idata
;
1463 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
, "PASSWD --preset %s", tmp
);