2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
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>
33 #include "pwmd-error.h"
38 #include "util-misc.h"
39 #include "util-string.h"
46 #include <acl/libacl.h>
53 static uint8_t pwmd_magic
[5] = { '\177', 'P', 'W', 'M', 'D' };
55 static gpg_error_t
mem_realloc_cb(void *data
, const void *buffer
, size_t len
)
57 membuf_t
*mem
= (membuf_t
*)data
;
63 if ((p
= xrealloc(mem
->buf
, mem
->len
+ len
)) == NULL
)
67 memcpy((char *)mem
->buf
+ mem
->len
, buffer
, len
);
72 static gpg_error_t
status_cb(void * data
, const char *line
)
74 struct agent_s
*agent
= data
;
76 agent
->inquire_maxlen
= 0;
78 if (!strncmp(line
, "INQUIRE_MAXLEN ", 15)) {
79 agent
->inquire_maxlen
= atoi(line
+15);
80 if (!agent
->client_ctx
)
84 return send_status(agent
->client_ctx
, STATUS_AGENT
, "%s", line
);
87 static gpg_error_t
assuan_command(struct agent_s
*a
, char **result
,
88 size_t *len
, const char *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
= (char *)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 char *t
= NULL
;
134 static struct assuan_malloc_hooks mhooks
= { xmalloc
, xrealloc
, xfree
};
135 char *s
, buf
[LINE_MAX
];
138 s
= config_get_string("global", "agent_env_file");
140 char *ss
= expand_homedir(s
);
147 while ((s
= fgets(buf
, sizeof(buf
), fp
))) {
149 if (!strncmp(s
, "GPG_AGENT_INFO=", strlen("GPG_AGENT_INFO="))) {
150 setenv("GPG_AGENT_INFO", s
+strlen("GPG_AGENT_INFO="), 1);
158 log_write("%s: %s", s
, pwmd_strerror(gpg_error_from_syserror()));
161 t
= 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 char **fields
= str_split(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
, char **result
, size_t *len
,
204 const char *fmt
, ...)
211 rc
= launch_agent(agent
);
217 if (str_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 unsetenv("GPG_AGENT_INFO");
224 rc
= launch_agent(agent
);
226 rc
= assuan_command(agent
, result
, len
, cmd
);
239 static void agent_disconnect(struct agent_s
*agent
)
245 assuan_release(agent
->ctx
);
250 void cleanup_agent(struct agent_s
*agent
)
256 xfree(agent
->display
);
257 xfree(agent
->ttyname
);
258 xfree(agent
->ttytype
);
259 xfree(agent
->lc_messages
);
260 xfree(agent
->lc_ctype
);
263 agent_disconnect(agent
);
268 gpg_error_t
agent_init(struct agent_s
**agent
)
270 struct agent_s
*new = xcalloc(1, sizeof(struct agent_s
));
273 return GPG_ERR_ENOMEM
;
279 void set_header_defaults(file_header_t
*hdr
)
281 char *s
= config_get_string(NULL
, "cipher");
282 int 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 char *filename
, file_header_t
*rhdr
,
294 struct stat
*rst
, int *rfd
)
302 if (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
< 0x030000)
319 rc
= GPG_ERR_UNKNOWN_VERSION
;
337 gpg_error_t
read_data_file(const char *filename
, struct crypto_s
*crypto
)
345 cleanup_crypto_stage1(crypto
);
346 rc
= read_data_header(filename
, &crypto
->hdr
, &st
, &fd
);
350 crypto
->ciphertext_len
= crypto
->hdr
.datalen
;
351 crypto
->ciphertext
= xmalloc(crypto
->hdr
.datalen
);
352 if (!crypto
->ciphertext
) {
357 rlen
= read(fd
, crypto
->grip
, 20);
359 rc
= rc
== -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA
;
363 rlen
= read(fd
, crypto
->sign_grip
, 20);
365 rc
= rc
== -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA
;
369 len
= read(fd
, crypto
->ciphertext
, crypto
->hdr
.datalen
);
370 if (len
!= crypto
->hdr
.datalen
) {
371 rc
= rc
== -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA
;
375 len
= st
.st_size
-sizeof(file_header_t
)-crypto
->hdr
.datalen
-40;
382 rlen
= read(fd
, buf
, len
);
384 rc
= rc
== -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA
;
388 rc
= gcry_sexp_new(&crypto
->ciphertext_sexp
, buf
, rlen
, 1);
392 if (crypto
->pkey_sexp
)
393 gcry_sexp_release(crypto
->pkey_sexp
);
395 if (crypto
->sigpkey_sexp
)
396 gcry_sexp_release(crypto
->sigpkey_sexp
);
398 crypto
->pkey_sexp
= crypto
->sigpkey_sexp
= NULL
;
399 rc
= get_pubkey_bin(crypto
, crypto
->grip
, &crypto
->pkey_sexp
);
401 rc
= get_pubkey_bin(crypto
, crypto
->sign_grip
, &crypto
->sigpkey_sexp
);
409 static gpg_error_t
inquire_cb(void * user
, const char *keyword
)
411 struct inquire_data_s
*idata
= user
;
413 if (!idata
->preset
&& (!strcmp(keyword
, "PASSPHRASE")
414 || !strcmp(keyword
, "NEW_PASSPHRASE"))) {
415 return agent_loopback_cb(idata
->crypto
, keyword
);
417 // SAVE --inquire-keyparam
418 else if (idata
->preset
&& !strcmp(keyword
, "KEYPARAM")) {
420 return agent_loopback_cb(idata
->crypto
, keyword
);
423 if (idata
->crypto
->agent
->inquire_maxlen
424 && idata
->len
> idata
->crypto
->agent
->inquire_maxlen
) {
425 log_write(_("Inquired data too large: have=%u, max=%u"), idata
->len
,
426 idata
->crypto
->agent
->inquire_maxlen
);
427 return GPG_ERR_TOO_LARGE
;
430 idata
->crypto
->agent
->inquire_maxlen
= 0;
431 return assuan_send_data(idata
->crypto
->agent
->ctx
, idata
->line
, idata
->len
);
434 static gpg_error_t
extract_key(struct crypto_s
*crypto
, unsigned char **result
,
438 gcry_sexp_t enc_sexp
= NULL
, tmp_sexp
;
439 struct inquire_data_s idata
= {0};
440 char *hexgrip
= NULL
;
442 size_t keylen
, keysize
;
444 int algo
= cipher_to_gcrypt(crypto
->hdr
.flags
);
447 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_KEYLEN
, NULL
, &keysize
);
451 tmp_sexp
= gcry_sexp_find_token(crypto
->ciphertext_sexp
, "enc-val", 0);
453 return GPG_ERR_BAD_DATA
;
455 hexgrip
= bin2hex(crypto
->grip
, sizeof(crypto
->grip
));
461 rc
= cache_is_shadowed(hexgrip
);
462 if (rc
&& rc
!= GPG_ERR_NO_DATA
)
465 shadowed
= !rc
? 1 : 0;
467 gcry_sexp_t tmp2_sexp
= gcry_sexp_cdr(tmp_sexp
);
468 gcry_sexp_release(tmp_sexp
);
469 tmp_sexp
= gcry_sexp_nth(tmp2_sexp
, 0);
470 gcry_sexp_release(tmp2_sexp
);
471 rc
= gcry_sexp_build(&enc_sexp
, NULL
, "(enc-val (flags pkcs1) %S)",
475 rc
= gcry_sexp_build(&enc_sexp
, NULL
, "%S", tmp_sexp
);
477 gcry_sexp_release(tmp_sexp
);
481 crypto
->agent
->inquire_cb
= inquire_cb
;
482 idata
.crypto
= crypto
;
483 idata
.len
= gcry_sexp_sprint(enc_sexp
, GCRYSEXP_FMT_CANON
, NULL
, 0);
484 idata
.line
= xmalloc(idata
.len
);
490 idata
.len
= gcry_sexp_sprint(enc_sexp
, GCRYSEXP_FMT_CANON
, idata
.line
,
492 crypto
->agent
->inquire_data
= &idata
;
493 gcry_sexp_release(enc_sexp
);
495 log_write1(_("Keygrip is %s, bits=%i"), hexgrip
,
496 gcry_pk_get_nbits(crypto
->pkey_sexp
));
497 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
, "SETKEY %s", hexgrip
);
501 if (!crypto
->agent
->desc
) {
503 "A %s is required to unlock the secret key for the "
504 "encrypted data file \"%s\". Please enter the %s "
506 shadowed
? "PIN" : _("passphrase"), crypto
->filename
,
507 shadowed
? "PIN" : _("passphrase"));
510 tmp
= plus_escape(crypto
->agent
->desc
);
512 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
, "SETKEYDESC %s", tmp
);
517 assuan_begin_confidential(crypto
->agent
->ctx
);
518 rc
= send_to_agent(crypto
->agent
, &key
, &keylen
, "PKDECRYPT");
519 assuan_end_confidential(crypto
->agent
->ctx
);
523 rc
= gcry_sexp_new(&tmp_sexp
, key
, keylen
, 1);
528 key
= (char *)gcry_sexp_nth_data(tmp_sexp
, 1, result_len
);
530 *result
= gcry_malloc(*result_len
);
534 memcpy(*result
, key
, *result_len
);
537 rc
= GPG_ERR_BAD_DATA
;
539 gcry_sexp_release(tmp_sexp
);
546 gcry_sexp_release(enc_sexp
);
551 static gpg_error_t
verify(gcry_sexp_t pkey
, gcry_sexp_t sig_sexp
,
552 const void * data
, size_t len
)
555 unsigned hashlen
= gcry_md_get_algo_dlen(GCRY_MD_SHA256
);
557 gcry_sexp_t data_sexp
;
559 hash
= gcry_malloc(hashlen
);
561 return GPG_ERR_ENOMEM
;
563 gcry_md_hash_buffer(GCRY_MD_SHA256
, hash
, data
, len
);
564 rc
= gcry_sexp_build(&data_sexp
, NULL
,
565 "(data (flags pkcs1) (hash sha256 %b))", hashlen
, hash
);
568 rc
= gcry_pk_verify(sig_sexp
, data_sexp
, pkey
);
569 gcry_sexp_release(data_sexp
);
575 #define CRYPTO_BLOCKSIZE(c) (blocksize * 1024)
578 * Useful for a large amount of data. Rather than doing all of the data in one
579 * iteration do it in chunks. This lets the command be cancelable rather than
580 * waiting for it to complete.
582 static gpg_error_t
iterate_crypto_once(gcry_cipher_hd_t h
, unsigned char *inbuf
,
583 size_t insize
, size_t blocksize
, status_msg_t which
)
586 off_t len
= CRYPTO_BLOCKSIZE(blocksize
);
587 void * p
= gcry_malloc(len
);
589 unsigned char *inbuf2
;
592 return GPG_ERR_ENOMEM
;
594 if (insize
< CRYPTO_BLOCKSIZE(blocksize
))
597 pthread_cleanup_push(gcry_free
, p
);
600 inbuf2
= inbuf
+total
;
603 if (len
+ total
> insize
)
606 if (which
== STATUS_ENCRYPT
)
607 rc
= gcry_cipher_encrypt(h
, p
, len
, inbuf2
, len
);
609 rc
= gcry_cipher_decrypt(h
, p
, len
, inbuf2
, len
);
615 memmove(tmp
, p
, len
);
620 pthread_testcancel();
623 pthread_cleanup_pop(1);
627 static void cleanup_cipher(void *arg
)
629 gcry_cipher_close((gcry_cipher_hd_t
)arg
);
632 gpg_error_t
decrypt_data(assuan_context_t ctx
, struct crypto_s
*crypto
)
635 unsigned char *key
= NULL
;
637 gcry_cipher_hd_t h
= NULL
;
638 size_t blocksize
, keysize
;
639 int algo
= cipher_to_gcrypt(crypto
->hdr
.flags
);
640 void * outbuf
= NULL
;
641 gcry_sexp_t sig_sexp
;
642 uint64_t n
= crypto
->hdr
.iterations
;
645 rc
= extract_key(crypto
, &key
, &keylen
);
649 sig_sexp
= gcry_sexp_find_token(crypto
->ciphertext_sexp
, "sig-val", 0);
652 return GPG_ERR_BAD_DATA
;
655 pthread_cleanup_push(gcry_free
, key
);
656 rc
= verify(crypto
->sigpkey_sexp
, sig_sexp
, crypto
->ciphertext
, crypto
->ciphertext_len
);
657 gcry_sexp_release(sig_sexp
);
660 rc
= gcry_cipher_open(&h
, algo
, GCRY_CIPHER_MODE_CBC
, 0);
662 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_KEYLEN
, NULL
,
665 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_BLKLEN
, NULL
,
668 rc
= gcry_cipher_setiv(h
, crypto
->hdr
.iv
,
669 sizeof(crypto
->hdr
.iv
));
671 rc
= gcry_cipher_setkey(h
, key
, keylen
);
678 pthread_cleanup_push(cleanup_cipher
, rc
? NULL
: h
);
681 outbuf
= gcry_malloc(crypto
->hdr
.datalen
);
686 pthread_cleanup_push(gcry_free
, outbuf
);
689 memcpy(outbuf
, crypto
->ciphertext
, crypto
->hdr
.datalen
);
690 rc
= iterate_crypto_once(h
, outbuf
, crypto
->hdr
.datalen
, blocksize
,
694 rc
= gcry_cipher_setkey(h
, key
, keylen
);
699 progress
= config_get_long(NULL
, "cipher_progress");
701 progress
= strtol(DEFAULT_ITERATION_PROGRESS
, NULL
, 10);
704 if (!rc
&& ctx
&& crypto
->hdr
.iterations
)
705 rc
= send_status(ctx
, STATUS_DECRYPT
, "%llu %llu", 0,
706 crypto
->hdr
.iterations
);
708 for (n
= 0; !rc
&& n
< crypto
->hdr
.iterations
; n
++) {
709 if (ctx
&& !(n
%progress
)) {
710 rc
= send_status(ctx
, STATUS_DECRYPT
, "%llu %llu", n
,
711 crypto
->hdr
.iterations
);
716 rc
= gcry_cipher_setiv(h
, crypto
->hdr
.iv
, sizeof(crypto
->hdr
.iv
));
720 rc
= iterate_crypto_once(h
, outbuf
, crypto
->hdr
.datalen
, blocksize
,
724 if (!rc
&& ctx
&& crypto
->hdr
.iterations
)
725 rc
= send_status(ctx
, STATUS_DECRYPT
, "%llu %llu", n
,
726 crypto
->hdr
.iterations
);
728 pthread_cleanup_pop(rc
? 1 : 0); // outbuf
729 pthread_cleanup_pop(1); // cipher
730 pthread_cleanup_pop(1); // key
732 crypto
->plaintext
= outbuf
;
733 crypto
->plaintext_len
= crypto
->hdr
.datalen
;
739 gpg_error_t
decrypt_xml(struct crypto_s
*crypto
, const void * data
,
742 gcry_cipher_hd_t h
= NULL
;
745 rc
= gcry_cipher_open(&h
, GCRY_CIPHER_AES
, GCRY_CIPHER_MODE_CBC
, 0);
749 gcry_free(crypto
->plaintext
);
750 crypto
->plaintext
= gcry_malloc(len
);
751 if (!crypto
->plaintext
) {
756 rc
= gcry_cipher_setiv(h
, cache_iv
, cache_blocksize
);
760 rc
= gcry_cipher_setkey(h
, cache_key
, cache_keysize
);
764 rc
= gcry_cipher_decrypt(h
, crypto
->plaintext
, len
, data
, len
);
766 gcry_free(crypto
->plaintext
);
767 crypto
->plaintext
= NULL
;
770 crypto
->plaintext_len
= len
;
774 gcry_cipher_close(h
);
779 gpg_error_t
encrypt_xml(assuan_context_t ctx
, void * key
, size_t keylen
,
780 int algo
, const void * xml
, size_t len
, void * *result
, size_t
781 *result_len
, unsigned char **iv
, size_t *iv_len
, uint64_t iter
)
785 size_t blocksize
, keysize
;
790 unsigned char *tmpkey
= NULL
;
791 int free_iv
= *(iv_len
) == 0;
793 rc
= gcry_cipher_open(&h
, algo
, GCRY_CIPHER_MODE_CBC
, 0);
797 pthread_cleanup_push(cleanup_cipher
, h
);
798 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_KEYLEN
, NULL
, &keysize
);
800 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_BLKLEN
, NULL
, &blocksize
);
802 if (!rc
&& *(iv_len
) == 0) {
803 *(iv
) = xmalloc(blocksize
);
807 gcry_create_nonce(*(iv
), blocksize
);
810 pthread_cleanup_push(xfree
, *(iv_len
) == 0 ? *(iv
) : NULL
);
813 tmpkey
= gcry_malloc(keylen
);
818 pthread_cleanup_push(gcry_free
, tmpkey
);
821 memcpy(tmpkey
, key
, keylen
);
823 rc
= gcry_cipher_setkey(h
, tmpkey
, keylen
);
826 len
+= blocksize
-(len
%blocksize
);
831 inbuf
= gcry_malloc(len
);
836 pthread_cleanup_push(gcry_free
, inbuf
);
839 memset(inbuf
, 0, len
);
840 memcpy(inbuf
, xml
, olen
);
841 progress
= config_get_long(NULL
, "cipher_progress");
843 progress
= strtol(DEFAULT_ITERATION_PROGRESS
, NULL
, 10);
845 if (!rc
&& ctx
&& iter
)
846 rc
= send_status(ctx
, STATUS_ENCRYPT
, "%llu %llu", 0, iter
);
848 for (n
= 0; !rc
&& n
< iter
; n
++) {
849 if (ctx
&& !(n
%progress
)) {
850 rc
= send_status(ctx
, STATUS_ENCRYPT
, "%llu %llu", n
, iter
);
855 rc
= gcry_cipher_setiv(h
, *(iv
), blocksize
);
859 rc
= iterate_crypto_once(h
, inbuf
, len
, blocksize
, STATUS_ENCRYPT
);
863 if (!rc
&& ctx
&& iter
)
864 rc
= send_status(ctx
, STATUS_ENCRYPT
, "%llu %llu", n
, iter
);
867 /* Do at least one iteration. */
868 rc
= gcry_cipher_setiv(h
, *(iv
), blocksize
);
870 rc
= gcry_cipher_setkey(h
, key
, keylen
);
872 rc
= iterate_crypto_once(h
, inbuf
, len
, blocksize
,
877 pthread_cleanup_pop(rc
? 1 : 0); // inbuf
878 pthread_cleanup_pop(1); // tmpkey
879 pthread_cleanup_pop(rc
&& free_iv
? 1 : 0); // iv
880 pthread_cleanup_pop(1); // cipher
881 *result
= rc
? NULL
: inbuf
;
886 gpg_error_t
agent_loopback_cb(void * user
, const char *keyword
)
888 struct crypto_s
*crypto
= user
;
890 unsigned char *result
;
894 if (!strcmp(keyword
, "KEYPARAM")) {
896 rc
= assuan_inquire(crypto
->client_ctx
, keyword
, &result
, &len
, 0);
898 else { // PASSPHRASE or NEW_PASSPHRASE
899 assuan_begin_confidential(crypto
->client_ctx
);
900 rc
= assuan_inquire(crypto
->client_ctx
, keyword
, &result
, &len
, 0);
901 assuan_end_confidential(crypto
->client_ctx
);
905 if (keyparam
&& !len
) {
906 char *tmp
= default_key_params(crypto
);
909 return gpg_error(GPG_ERR_ENOMEM
);
912 result
= xmalloc(len
);
913 memcpy(result
, tmp
, len
);
917 pthread_cleanup_push(xfree
, result
);
920 rc
= assuan_send_data(crypto
->agent
->ctx
, result
, len
);
922 assuan_begin_confidential(crypto
->agent
->ctx
);
923 rc
= assuan_send_data(crypto
->agent
->ctx
, result
, len
);
924 assuan_end_confidential(crypto
->agent
->ctx
);
927 pthread_cleanup_pop(1);
929 else if (gpg_err_code(rc
) == GPG_ERR_ASS_CANCELED
) {
930 gpg_error_t arc
= assuan_write_line(crypto
->agent
->ctx
, "CAN");
936 arc
= assuan_read_line(crypto
->agent
->ctx
, &line
, &len
);
947 static gpg_error_t
sign(gcry_sexp_t
*rsexp
, const char *sign_hexgrip
,
948 struct crypto_s
*crypto
, const void * data
, size_t len
)
952 char *tmp
= sign_hexgrip
? str_dup(sign_hexgrip
)
953 : bin2hex(crypto
->grip
, sizeof(crypto
->grip
));
955 pthread_cleanup_push(xfree
, tmp
);
956 log_write1(_("Sign keygrip is %s"), tmp
);
957 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
, "SIGKEY %s", tmp
);
958 pthread_cleanup_pop(1);
961 unsigned hashlen
= gcry_md_get_algo_dlen(GCRY_MD_SHA256
);
963 hash
= gcry_malloc(hashlen
);
965 return GPG_ERR_ENOMEM
;
967 gcry_md_hash_buffer(GCRY_MD_SHA256
, hash
, data
, len
);
968 tmp
= bin2hex(hash
, hashlen
);
970 pthread_cleanup_push(xfree
, tmp
);
971 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
,
972 "SETHASH --hash=sha256 %s", tmp
);
973 pthread_cleanup_pop(1);
977 struct inquire_data_s idata
= {0};
979 idata
.crypto
= crypto
;
980 crypto
->agent
->inquire_data
= &idata
;
981 crypto
->agent
->inquire_cb
= inquire_cb
;
982 rc
= send_to_agent(crypto
->agent
, &result
, &len
, "PKSIGN");
984 rc
= gcry_sexp_sscan(rsexp
, NULL
, result
, len
);
992 static gpg_error_t
write_file(struct crypto_s
*crypto
, const char *filename
,
993 void * data
, size_t data_len
, void * sexp
, size_t sexp_len
,
994 gcry_sexp_t pubkey
, gcry_sexp_t sigpkey
)
996 char tmp
[FILENAME_MAX
] = { 0 };
1007 if (lstat(filename
, &st
) == 0) {
1008 mode
= st
.st_mode
& (S_IRWXU
|S_IRWXG
|S_IRWXO
);
1010 if (!(mode
& S_IWUSR
))
1011 return GPG_ERR_EACCES
;
1013 else if (errno
!= ENOENT
)
1014 return gpg_error_from_syserror();
1016 snprintf(tmp
, sizeof(tmp
), "%s.XXXXXX", filename
);
1019 rc
= gpg_error_from_syserror();
1020 log_write("%s: %s", tmp
, pwmd_strerror(rc
));
1025 // xml_import() or convert_file() from command line.
1029 pthread_cleanup_push(cleanup_unlink_cb
, tmp
);
1030 crypto
->save
.hdr
.version
= VERSION_HEX
;
1031 len
= write(fd
, &crypto
->save
.hdr
, sizeof(file_header_t
));
1032 if (len
== sizeof(file_header_t
)) {
1033 unsigned char grip
[20];
1035 gcry_pk_get_keygrip(pubkey
, grip
);
1036 len
= write(fd
, grip
, sizeof(grip
));
1037 if (len
== sizeof(grip
)) {
1038 gcry_pk_get_keygrip(sigpkey
, grip
);
1039 len
= write(fd
, grip
, sizeof(grip
));
1040 if (len
== sizeof(grip
)) {
1041 len
= write(fd
, data
, data_len
);
1042 if (len
== data_len
) {
1043 len
= write(fd
, sexp
, sexp_len
);
1044 if (len
!= sexp_len
)
1045 rc
= gpg_error_from_syserror();
1048 rc
= gpg_error_from_syserror();
1052 rc
= gpg_error_from_syserror();
1055 rc
= gpg_error_from_syserror();
1058 pthread_cleanup_push(acl_free
, acl
);
1061 if (fsync(fd
) != -1) {
1062 if (filename
&& close(fd
) != -1) {
1063 if (mode
&& config_get_boolean(filename
, "backup")) {
1064 char tmp2
[FILENAME_MAX
];
1066 snprintf(tmp2
, sizeof(tmp2
), "%s.backup", filename
);
1068 acl
= acl_get_file(filename
, ACL_TYPE_ACCESS
);
1070 log_write("ACL: %s: %s", filename
,
1071 pwmd_strerror(gpg_error_from_syserror()));
1074 if (rename(filename
, tmp2
) == -1)
1075 rc
= gpg_error_from_syserror();
1077 else if (filename
) {
1079 acl
= acl_get_file(".", ACL_TYPE_DEFAULT
);
1081 log_write("ACL: %s: %s", filename
,
1082 pwmd_strerror(gpg_error_from_syserror()));
1087 rc
= gpg_error_from_syserror();
1090 rc
= gpg_error_from_syserror();
1094 if (filename
&& rename(tmp
, filename
) != -1) {
1096 if (filename
&& mode
)
1097 chmod(filename
, mode
);
1100 if (filename
&& acl
&& acl_set_file(filename
, ACL_TYPE_ACCESS
, acl
))
1101 log_write("ACL: %s: %s", filename
,
1102 pwmd_strerror(gpg_error_from_syserror()));
1106 rc
= gpg_error_from_syserror();
1110 pthread_cleanup_pop(1);
1112 pthread_cleanup_pop(rc
? 1 : 0); // unlink
1116 gpg_error_t
encrypt_data_file(assuan_context_t ctx
, struct crypto_s
*crypto
,
1117 gcry_sexp_t pubkey
, gcry_sexp_t sigpkey
, const char *filename
, const
1118 void * xml
, size_t len
)
1122 size_t data_len
= 0;
1123 void * enc_xml
= NULL
;
1124 size_t enc_xml_len
= 0;
1125 unsigned char *iv
= NULL
;
1127 int algo
= cipher_to_gcrypt(crypto
->save
.hdr
.flags
);
1130 unsigned char sig_grip
[20];
1131 unsigned char grip
[20];
1133 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_KEYLEN
, NULL
, &keysize
);
1137 pthread_cleanup_push(gcry_free
, key
);
1138 key
= gcry_random_bytes_secure(keysize
, GCRY_STRONG_RANDOM
);
1139 pthread_testcancel(); // may have been a long operation
1140 pthread_cleanup_pop(0);
1142 return GPG_ERR_ENOMEM
;
1144 gcry_pk_get_keygrip(pubkey
, grip
);
1145 gcry_pk_get_keygrip(sigpkey
, sig_grip
);
1146 pthread_cleanup_push(xfree
, iv
);
1147 pthread_cleanup_push(gcry_free
, key
);
1148 rc
= encrypt_xml(ctx
, key
, keysize
, algo
, xml
, len
, &enc_xml
, &enc_xml_len
,
1149 &iv
, &iv_len
, crypto
->save
.hdr
.iterations
);
1151 gcry_sexp_t sig_sexp
= NULL
;
1152 char *hexgrip
= bin2hex(sig_grip
, 20);
1154 pthread_cleanup_push(gcry_free
, enc_xml
);
1155 rc
= sign(&sig_sexp
, hexgrip
, crypto
, enc_xml
, enc_xml_len
);
1159 rc
= verify(sigpkey
, sig_sexp
, enc_xml
, enc_xml_len
);
1162 gcry_sexp_t tmp_sexp
;
1164 rc
= gcry_sexp_build(&tmp_sexp
, NULL
,
1165 "(data (flags pkcs1) (value %b))", keysize
, key
);
1167 gcry_sexp_t key_sexp
;
1169 pthread_cleanup_push((void (*)(void*))gcry_sexp_release
,
1171 rc
= gcry_pk_encrypt(&key_sexp
, tmp_sexp
, pubkey
);
1172 pthread_cleanup_pop(0);
1173 gcry_sexp_release(tmp_sexp
);
1176 memcpy(crypto
->save
.hdr
.iv
, iv
, iv_len
);
1177 crypto
->save
.hdr
.datalen
= enc_xml_len
;
1178 rc
= gcry_sexp_build(&tmp_sexp
, NULL
, "%S%S", key_sexp
,
1180 gcry_sexp_release(key_sexp
);
1183 data_len
= gcry_sexp_sprint(tmp_sexp
,
1184 GCRYSEXP_FMT_CANON
, NULL
, 0);
1185 data
= xmalloc(data_len
);
1187 gcry_sexp_sprint(tmp_sexp
, GCRYSEXP_FMT_CANON
,
1190 rc
= GPG_ERR_ENOMEM
;
1192 gcry_sexp_release(tmp_sexp
);
1199 pthread_cleanup_pop(0); // enc_xml
1202 gcry_sexp_release(sig_sexp
);
1205 pthread_cleanup_pop(1); // key
1206 pthread_cleanup_pop(1); // iv
1209 pthread_cleanup_push(gcry_free
, enc_xml
);
1210 rc
= write_file(crypto
, filename
, enc_xml
, enc_xml_len
, data
, data_len
,
1212 pthread_cleanup_pop(1); // enc_xml
1214 memcpy(&crypto
->hdr
, &crypto
->save
.hdr
, sizeof(file_header_t
));
1221 void cleanup_save(struct save_s
*save
)
1227 gcry_sexp_release(save
->pkey
);
1230 gcry_sexp_release(save
->sigpkey
);
1232 memset(save
, 0, sizeof(struct save_s
));
1235 /* Keep the agent ctx to retain pinentry options which will be freed in
1236 * cleanup_cb(). Also keep .pubkey since it may be needed for a SAVE. */
1237 void cleanup_crypto_stage1(struct crypto_s
*cr
)
1242 cleanup_save(&cr
->save
);
1244 if (cr
->ciphertext_sexp
)
1245 gcry_sexp_release(cr
->ciphertext_sexp
);
1248 gcry_free(cr
->plaintext
);
1250 xfree(cr
->ciphertext
);
1251 xfree(cr
->filename
);
1252 cr
->filename
= NULL
;
1253 cr
->ciphertext_sexp
= NULL
;
1254 cr
->ciphertext
= NULL
;
1255 cr
->ciphertext_len
= 0;
1256 cr
->plaintext
= NULL
;
1257 cr
->plaintext_len
= 0;
1260 void cleanup_crypto_stage2(struct crypto_s
*cr
)
1265 cleanup_crypto_stage1(cr
);
1266 set_header_defaults(&cr
->hdr
);
1269 void cleanup_crypto(struct crypto_s
**c
)
1271 struct crypto_s
*cr
= *c
;
1276 cleanup_crypto_stage2(cr
);
1279 gcry_sexp_release(cr
->pkey_sexp
);
1281 if (cr
->sigpkey_sexp
)
1282 gcry_sexp_release(cr
->sigpkey_sexp
);
1285 cleanup_agent(cr
->agent
);
1291 gpg_error_t
init_client_crypto(struct crypto_s
**crypto
)
1293 struct crypto_s
*new = xcalloc(1, sizeof(struct crypto_s
));
1297 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
1298 return GPG_ERR_ENOMEM
;
1301 rc
= agent_init(&new->agent
);
1303 rc
= send_agent_common_options(new->agent
);
1305 rc
= set_pinentry_options(new->agent
);
1313 set_header_defaults(&new->hdr
);
1318 gpg_error_t
generate_key(struct crypto_s
*crypto
, char *sexpstr
,
1319 int empty
, int preset
)
1325 if (crypto
->save
.s2k_count
) {
1326 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
,
1327 "OPTION s2k-count=%lu", crypto
->save
.s2k_count
);
1332 if (!crypto
->agent
->inquire_cb
)
1333 crypto
->agent
->inquire_cb
= inquire_cb
;
1335 rc
= send_to_agent(crypto
->agent
, &pkey
, &plen
, "GENKEY %s%s",
1336 preset
? "--preset " : "",
1337 empty
? "--no-protection" : "");
1341 if (crypto
->save
.pkey
)
1342 gcry_sexp_release(crypto
->save
.pkey
);
1344 crypto
->save
.pkey
= NULL
;
1345 rc
= gcry_sexp_new(&crypto
->save
.pkey
, pkey
, plen
, 1);
1347 unsigned char grip
[20];
1349 gcry_pk_get_keygrip(crypto
->save
.pkey
, grip
);
1350 char *hexgrip
= bin2hex(grip
, sizeof(grip
));
1351 log_write1(_("Keygrip is %s"), hexgrip
);
1354 if (!crypto
->save
.sigpkey
) {
1355 gcry_sexp_build((gcry_sexp_t
*)&crypto
->save
.sigpkey
, NULL
, "%S",
1364 gpg_error_t
set_agent_option(struct agent_s
*agent
, const char *name
,
1367 return send_to_agent(agent
, NULL
, NULL
, "OPTION %s=%s", name
, value
);
1370 gpg_error_t
set_agent_passphrase(struct crypto_s
*crypto
, const char *key
,
1374 struct inquire_data_s idata
;
1378 /* This is for use with key files or passphrases obtained from an inquire.
1379 * gpg-agent uses strings as passphrases and will truncate the passphrase
1380 * at the first encountered null byte. It's only a warning because the
1381 * passphrase may belong to a key shared outside of pwmd. */
1382 for (i
= 0; i
< len
; i
++) {
1384 log_write(_("WARNING: keylen=%i, truncated to %i."), len
, i
);
1389 hexgrip
= bin2hex(crypto
->grip
, 20);
1390 crypto
->agent
->inquire_cb
= inquire_cb
;
1391 crypto
->agent
->inquire_data
= &idata
;
1392 idata
.crypto
= crypto
;
1393 idata
.line
= (char *)key
,
1396 assuan_begin_confidential(crypto
->agent
->ctx
);
1397 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
,
1398 "PRESET_PASSPHRASE --inquire %s -1", hexgrip
);
1399 assuan_end_confidential(crypto
->agent
->ctx
);
1405 gpg_error_t
set_pinentry_mode(struct agent_s
*agent
, const char *mode
)
1407 return set_agent_option(agent
, "pinentry-mode", mode
);
1410 gpg_error_t
get_pubkey_bin(struct crypto_s
*crypto
, const unsigned char *grip
,
1411 gcry_sexp_t
*result
)
1413 char *hexgrip
= bin2hex(grip
, 20);
1417 return GPG_ERR_ENOMEM
;
1419 rc
= get_pubkey(crypto
, hexgrip
, result
);
1424 gpg_error_t
get_pubkey(struct crypto_s
*crypto
, const char *grip
,
1425 gcry_sexp_t
*result
)
1431 rc
= send_to_agent(crypto
->agent
, &pkey
, &plen
, "READKEY %s", grip
);
1433 rc
= gcry_sexp_new(result
, pkey
, plen
, 1);
1439 gpg_error_t
set_pinentry_options(struct agent_s
*agent
)
1443 if (getenv("DISPLAY")) {
1444 rc
= set_agent_option(agent
, "display", getenv("DISPLAY"));
1446 xfree(agent
->display
);
1447 agent
->display
= str_dup(getenv("DISPLAY"));
1450 else if (ttyname(STDOUT_FILENO
)) {
1451 rc
= set_agent_option(agent
, "ttyname", ttyname(STDOUT_FILENO
));
1453 rc
= set_agent_option(agent
, "ttytype", getenv("TERM"));
1455 xfree(agent
->ttyname
);
1456 xfree(agent
->ttytype
);
1457 agent
->ttyname
= str_dup(ttyname(STDOUT_FILENO
));
1458 agent
->ttytype
= str_dup(getenv("TERM"));
1466 static gpg_error_t
inquire_keyfile(void * user
, const char *keyword
)
1468 struct crypto_s
*crypto
= user
;
1469 char *filename
= crypto
->agent
->inquire_data2
;
1470 char *params
= crypto
->agent
->inquire_data3
;
1477 if (!strcmp(keyword
, "KEYPARAM"))
1478 return assuan_send_data(crypto
->agent
->ctx
, params
, strlen(params
));
1480 // This function is only used when generating a new keypair.
1481 if (strcmp(keyword
, "NEW_PASSPHRASE"))
1482 return gpg_error(GPG_ERR_ASS_UNKNOWN_INQUIRE
);
1484 if (stat(filename
, &st
) == -1)
1485 return gpg_error_from_syserror();
1487 if (crypto
->agent
->inquire_maxlen
1488 && st
.st_size
> crypto
->agent
->inquire_maxlen
) {
1489 log_write(_("The passphrase is too large: have=%u, max=%u."),
1490 (unsigned)st
.st_size
, crypto
->agent
->inquire_maxlen
);
1491 return GPG_ERR_TOO_LARGE
;
1494 buf
= gcry_malloc_secure(st
.st_size
);
1496 return GPG_ERR_ENOMEM
;
1498 fd
= open(filename
, O_RDONLY
);
1500 rc
= gpg_error_from_syserror();
1502 len
= read(fd
, buf
, st
.st_size
);
1503 if (len
== st
.st_size
) {
1504 assuan_begin_confidential(crypto
->agent
->ctx
);
1505 rc
= assuan_send_data(crypto
->agent
->ctx
, buf
, len
);
1506 assuan_end_confidential(crypto
->agent
->ctx
);
1509 rc
= gpg_error_from_syserror();
1511 rc
= GPG_ERR_BUFFER_TOO_SHORT
;
1519 gpg_error_t
export_common(struct crypto_s
*crypto
, const char *hexgrip
,
1520 const char *sign_hexgrip
, int no_passphrase
,
1521 const void * data
, size_t datalen
, const char *outfile
,
1522 const char *keyparams
, const char *keyfile
)
1526 if (!sign_hexgrip
&& hexgrip
)
1527 sign_hexgrip
= hexgrip
;
1530 if (crypto
->sigpkey_sexp
)
1531 gcry_sexp_release(crypto
->sigpkey_sexp
);
1533 crypto
->sigpkey_sexp
= NULL
;
1534 rc
= get_pubkey(crypto
, sign_hexgrip
, &crypto
->save
.sigpkey
);
1538 gcry_pk_get_keygrip(crypto
->save
.sigpkey
, crypto
->sign_grip
);
1542 rc
= get_pubkey(crypto
, hexgrip
, &crypto
->save
.pkey
);
1544 gcry_pk_get_keygrip(crypto
->save
.pkey
, crypto
->grip
);
1547 struct inquire_data_s idata
= {0};
1548 char *params
= keyparams
? str_dup(keyparams
)
1549 : default_key_params(crypto
);
1551 pthread_cleanup_push(xfree
, params
);
1552 log_write(_("Generating a new keypair ..."));
1554 log_write(_("Using passphrase obtained from file '%s'"), keyfile
);
1555 rc
= set_pinentry_mode(crypto
->agent
, "loopback");
1556 crypto
->agent
->inquire_cb
= inquire_keyfile
;
1557 crypto
->agent
->inquire_data
= crypto
;
1558 crypto
->agent
->inquire_data2
= (char *)keyfile
;
1559 crypto
->agent
->inquire_data3
= params
;
1562 idata
.line
= params
;
1563 idata
.len
= strlen(params
);
1564 idata
.crypto
= crypto
;
1565 crypto
->agent
->inquire_cb
= inquire_cb
;
1566 crypto
->agent
->inquire_data
= &idata
;
1570 rc
= generate_key(crypto
, params
, no_passphrase
, 1);
1571 gcry_pk_get_keygrip(crypto
->save
.pkey
, crypto
->grip
);
1574 (void)set_pinentry_mode(crypto
->agent
, "ask");
1575 pthread_cleanup_pop(1);
1579 rc
= encrypt_data_file(NULL
, crypto
, crypto
->save
.pkey
,
1580 crypto
->save
.sigpkey
, outfile
, data
, datalen
);
1582 char *tmp
= bin2hex(crypto
->grip
, sizeof(crypto
->grip
));
1584 log_write(_("Success! Keygrip is %s."), tmp
);
1585 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
,
1586 "CLEAR_PASSPHRASE --mode=normal %s", tmp
);
1590 tmp
= bin2hex(crypto
->sign_grip
, sizeof(crypto
->sign_grip
));
1591 log_write(_("Signed with keygrip %s."), tmp
);
1600 char *default_key_params(struct crypto_s
*crypto
)
1602 int len
= config_get_integer(NULL
, "nbits");
1604 char *algo
= config_get_string(NULL
, "algo");
1607 snprintf(buf
, sizeof(buf
), "%i", len
);
1608 result
= str_asprintf("(genkey (%s (nbits %lu:%i)))", algo
, strlen(buf
),
1614 gpg_error_t
agent_passwd(struct crypto_s
*crypto
)
1616 struct inquire_data_s idata
= {0};
1618 char *tmp
= bin2hex(crypto
->grip
, 20);
1620 idata
.crypto
= crypto
;
1621 crypto
->agent
->inquire_cb
= inquire_cb
;
1622 crypto
->agent
->inquire_data
= &idata
;
1623 rc
= send_to_agent(crypto
->agent
, NULL
, NULL
, "PASSWD --preset %s", tmp
);
1628 gpg_error_t
kill_scd(struct agent_s
*agent
)
1632 if (config_get_boolean(NULL
, "kill_scd")) {
1633 rc
= send_to_agent(agent
, NULL
, NULL
, "SCD KILLSCD");
1634 if (rc
&& gpg_err_code(rc
) != GPG_ERR_NO_SCDAEMON
)
1635 log_write("%s: %s", __FUNCTION__
, pwmd_strerror(rc
));