2 Copyright (C) 2006-2021 Ben Kibbey <bjk@luxsci.net>
4 This file is part of pwmd.
6 Pwmd is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
10 Pwmd is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/types.h>
33 #include "pwmd-error.h"
34 #include "util-misc.h"
40 #include "util-string.h"
44 static unsigned keepalive
;
45 static pthread_mutex_t crypto_mutex
= PTHREAD_MUTEX_INITIALIZER
;
49 #define STATUS_TIMEOUT_INIT(crypto) \
51 crypto->status_timeout = time (NULL); \
52 crypto->progress_rc = 0; \
55 #define STATUS_TIMEOUT_TEST(crypto, rc, s, line) \
57 time_t now = time (NULL); \
58 if (now - crypto->status_timeout >= keepalive && crypto->client_ctx) { \
59 rc = send_status (crypto->client_ctx, s, line); \
60 crypto->status_timeout = now; \
65 get_password_file (const char *keyfile
, unsigned char **result
, size_t *len
)
69 unsigned char *buf
= NULL
;
72 log_write (_ ("obtaining passphrase from passphrase file"));
73 rc
= open_check_file (keyfile
, &fd
, &st
, 0);
77 buf
= xmalloc (st
.st_size
+1);
80 size_t rlen
= read (fd
, buf
, st
.st_size
);
82 if (rlen
!= st
.st_size
)
83 rc
= GPG_ERR_ASS_READ_ERROR
;
87 /* The passphrase may have been truncated do to a nul byte before the
88 * EOF. Better to return an error here rather than passing the
89 * truncated passphrase on. */
90 if (rlen
&& strlen ((char *)buf
) != rlen
)
91 rc
= GPG_ERR_INV_PASSPHRASE
;
111 status_cb (void *data
, const char *keyword
, const char *args
)
113 struct crypto_s
*crypto
= data
;
116 if (!crypto
->client_ctx
)
119 if (!strcmp (keyword
, "INQUIRE_MAXLEN") &&
120 (crypto
->flags
& CRYPTO_FLAG_KEYFILE
))
123 return assuan_write_status (crypto
->client_ctx
, keyword
, args
);
127 passphrase_cb (void *data
, const char *hint
, const char *info
, int bad
, int fd
)
129 struct crypto_s
*crypto
= data
;
130 unsigned char *result
= NULL
;
134 if (crypto
->flags
& CRYPTO_FLAG_KEYFILE
)
135 rc
= get_password_file (crypto
->keyfile
, &result
, &len
);
139 rc
= assuan_write_status (crypto
->client_ctx
, "PASSPHRASE_HINT", hint
);
142 rc
= assuan_write_status (crypto
->client_ctx
, "PASSPHRASE_INFO", info
);
146 const char *keyword
= "PASSPHRASE";
148 if (!bad
&& crypto
->flags
& CRYPTO_FLAG_PASSWD_SIGN
)
149 keyword
= "SIGN_PASSPHRASE";
150 else if (!bad
&& crypto
->flags
& CRYPTO_FLAG_PASSWD_NEW
)
152 crypto
->flags
|= CRYPTO_FLAG_PASSWD_SIGN
;
153 keyword
= "NEW_PASSPHRASE";
155 else if (!bad
&& crypto
->flags
& CRYPTO_FLAG_PASSWD
)
156 crypto
->flags
|= CRYPTO_FLAG_PASSWD_NEW
;
157 else if (!bad
&& crypto
->flags
& CRYPTO_FLAG_NEWFILE
)
159 keyword
= "NEW_PASSPHRASE";
160 if (crypto
->save
.sigkey
)
161 crypto
->flags
|= CRYPTO_FLAG_PASSWD_SIGN
;
164 rc
= assuan_inquire (crypto
->client_ctx
, keyword
, &result
, &len
, 0);
170 pthread_cleanup_push ((void *)xfree
, result
);
173 gpgme_io_writen (fd
, "\n", 1);
176 int nl
= result
[len
-1] == '\n';
179 ret
= gpgme_io_writen (fd
, result
, len
);
181 gpgme_io_writen (fd
, "\n", 1);
183 rc
= GPG_ERR_CANCELED
;
186 pthread_cleanup_pop (1);
193 progress_cb (void *data
, const char *what
, int type
, int current
, int total
)
195 struct crypto_s
*crypto
= data
;
197 crypto
->progress_rc
= send_status (crypto
->client_ctx
, STATUS_GPGME
,
198 "%s %i %i %i", what
, type
, current
, total
);
202 crypto_data_to_buf (const gpgme_data_t data
, unsigned char **result
,
205 off_t ret
= gpgme_data_seek (data
, 0, SEEK_SET
);
207 size_t total
= 0, size
= BUFSIZE
;
208 unsigned char *buf
= NULL
;
214 return gpg_error_from_syserror ();
216 buf
= xmalloc (size
);
218 return GPG_ERR_ENOMEM
;
222 ret
= gpgme_data_read (data
, &buf
[total
], BUFSIZE
);
229 p
= xrealloc (buf
, size
* sizeof (unsigned char));
233 return GPG_ERR_ENOMEM
;
242 rc
= gpgme_err_code_from_syserror ();
257 crypto_list_keys (struct crypto_s
*crypto
, char *keys
[], int secret
,
258 gpgme_key_t
**result
)
261 gpgme_key_t key
= NULL
, *res
= NULL
;
264 rc
= gpgme_op_keylist_ext_start (crypto
->ctx
, (const char **)keys
, secret
, 0);
268 STATUS_TIMEOUT_INIT (crypto
);
273 pthread_cleanup_push ((void *)crypto_free_key_list
, res
);
274 rc
= gpgme_op_keylist_next (crypto
->ctx
, &key
);
275 pthread_cleanup_pop (0);
276 if (rc
&& gpgme_err_code(rc
) != GPG_ERR_EOF
)
285 p
= xrealloc (res
, (total
+2) * sizeof (gpgme_key_t
));
295 pthread_cleanup_push ((void *)crypto_free_key_list
, res
);
296 STATUS_TIMEOUT_TEST (crypto
, rc
, STATUS_KEEPALIVE
, NULL
);
297 pthread_cleanup_pop (0);
302 rc
= gpgme_op_keylist_end (crypto
->ctx
);
306 rc
= total
? 0 : secret
? GPG_ERR_NO_SECKEY
: GPG_ERR_NO_PUBKEY
;
310 crypto_free_key_list (res
);
316 crypto_free_save (struct save_s
*save
)
321 strv_free (save
->pubkey
);
322 xfree (save
->sigkey
);
323 xfree (save
->userid
);
325 crypto_free_key_list (save
->mainkey
);
327 memset (save
, 0, sizeof (struct save_s
));
331 free_gpgme_data_cb (void *data
)
333 gpgme_data_t d
= data
;
340 t
= gpgme_data_release_and_get_mem (d
, &len
);
342 wipememory (t
, 0, len
);
348 crypto_free_non_keys (struct crypto_s
*crypto
)
354 gpgme_release (crypto
->ctx
);
357 xfree (crypto
->plaintext
);
358 crypto
->plaintext
= NULL
;
359 crypto
->plaintext_size
= 0;
362 free_gpgme_data_cb (crypto
->cipher
);
364 crypto
->cipher
= NULL
;
365 crypto_free_save (&crypto
->save
);
366 xfree (crypto
->keyfile
);
367 crypto
->keyfile
= NULL
;
368 crypto
->flags
&= ~CRYPTO_FLAG_KEYFILE
;
372 crypto_free (struct crypto_s
*crypto
)
377 crypto_free_non_keys (crypto
);
378 strv_free (crypto
->pubkey
);
379 xfree (crypto
->sigkey
);
380 xfree (crypto
->filename
);
385 crypto_init_ctx (struct crypto_s
*crypto
, int no_pinentry
,
386 char *passphrase_file
)
389 gpgme_keylist_mode_t keylist_mode
;
392 rc
= gpgme_new (&ctx
);
396 rc
= gpgme_set_protocol (ctx
, GPGME_PROTOCOL_OPENPGP
);
399 keylist_mode
= gpgme_get_keylist_mode (ctx
);
400 keylist_mode
|= GPGME_KEYLIST_MODE_LOCAL
|GPGME_KEYLIST_MODE_WITH_SECRET
;
401 rc
= gpgme_set_keylist_mode (ctx
, keylist_mode
);
404 if (no_pinentry
|| passphrase_file
)
405 rc
= gpgme_set_pinentry_mode (ctx
, GPGME_PINENTRY_MODE_LOOPBACK
);
407 rc
= gpgme_set_pinentry_mode (ctx
, GPGME_PINENTRY_MODE_DEFAULT
);
411 gpgme_set_ctx_flag (ctx
, "no-symkey-cache", "1");
412 gpgme_set_passphrase_cb (ctx
, passphrase_cb
, crypto
);
413 gpgme_set_progress_cb (ctx
, progress_cb
, crypto
);
414 gpgme_set_status_cb (ctx
, status_cb
, crypto
);
420 crypto
->keyfile
= passphrase_file
;
421 crypto
->flags
|= CRYPTO_FLAG_KEYFILE
;
434 crypto_set_keepalive ()
436 keepalive
= config_get_integer ("global", "keepalive_interval");
440 crypto_init (struct crypto_s
**crypto
, void *ctx
, const char *filename
,
441 int no_pinentry
, char *passphrase_file
)
443 struct crypto_s
*new = xcalloc (1, sizeof (struct crypto_s
));
446 crypto_set_keepalive ();
449 return GPG_ERR_ENOMEM
;
451 rc
= crypto_init_ctx (new, no_pinentry
, passphrase_file
);
457 new->filename
= str_dup (filename
);
465 new->client_ctx
= ctx
;
474 /* Converts a 40 byte key id to the 16 byte form. Needed for comparison of
475 * gpgme_recipient_t.keyid. */
477 crypto_keyid_to_16b_once (char *key
)
479 size_t len
= strlen (key
);
482 return GPG_ERR_INV_ARG
;
484 memmove (&key
[0], &key
[len
-16], 16);
490 crypto_keyid_to_16b (char **keys
)
494 for (p
= keys
; p
&& *p
; p
++)
496 gpg_error_t rc
= crypto_keyid_to_16b_once (*p
);
505 crypto_decrypt (struct client_s
*client
, struct crypto_s
*crypto
)
512 char **new_recipients
= NULL
;
513 char **new_signers
= NULL
;
515 gpgme_decrypt_result_t result
;
517 rc
= gpgme_data_new (&plain
);
521 if (gpgme_check_version ("1.16.0"))
523 gpgme_data_set_flag (plain
, "io-buffer-size", "4096");
524 gpgme_data_set_flag (plain
, "sensitive", "1");
527 pthread_cleanup_push ((void *)free_gpgme_data_cb
, plain
);
528 rc
= open_check_file (crypto
->filename
, &fd
, &st
, 1);
531 pthread_cleanup_push ((void *)close_fd_cb
, &fd
);
532 rc
= gpgme_data_new_from_fd (&cipher
, fd
);
535 pthread_cleanup_push ((void *)free_gpgme_data_cb
, cipher
);
536 rc
= send_status (client
? client
->ctx
: NULL
, STATUS_DECRYPT
, NULL
);
539 MUTEX_TRYLOCK ((client
? client
->ctx
: NULL
), &crypto_mutex
, rc
,
540 (client
? client
->lock_timeout
: -1));
543 pthread_cleanup_push (release_mutex_cb
, &crypto_mutex
);
544 rc
= gpgme_op_decrypt_verify_start (crypto
->ctx
, cipher
, plain
);
547 STATUS_TIMEOUT_INIT(crypto
);
550 if (!rc
&& crypto
->progress_rc
)
551 rc
= crypto
->progress_rc
;
553 STATUS_TIMEOUT_TEST (crypto
, rc
, STATUS_DECRYPT
, NULL
);
555 } while (!rc
&& !gpgme_wait (crypto
->ctx
, &rc
, 0) && !rc
);
557 pthread_cleanup_pop (1); // release_mutex_cb
560 pthread_cleanup_pop (1); // free_gpgme_data_cb (cipher)
563 pthread_cleanup_pop (1); // close (fd)
566 pthread_cleanup_pop (0); // free_gpgme_data_cb (plain)
570 free_gpgme_data_cb (plain
);
574 pthread_cleanup_push ((void *)free_gpgme_data_cb
, plain
);
575 result
= gpgme_op_decrypt_result (crypto
->ctx
);
576 if (!result
->unsupported_algorithm
&& !result
->wrong_key_usage
)
580 for (r
= result
->recipients
; r
; r
= r
->next
)
582 pthread_cleanup_push ((void *)strv_free
, new_recipients
);
583 log_write1 (_ ("%s: recipient: %s, status=%u"),
584 crypto
->filename
, r
->keyid
, r
->status
);
585 pthread_cleanup_pop (0);
586 pp
= strv_cat(new_recipients
, str_dup (r
->keyid
));
596 else if (result
->wrong_key_usage
)
597 rc
= GPG_ERR_WRONG_KEY_USAGE
;
598 else if (result
->unsupported_algorithm
)
599 rc
= GPG_ERR_UNSUPPORTED_ALGORITHM
;
603 gpgme_verify_result_t verify
;
606 verify
= gpgme_op_verify_result (crypto
->ctx
);
607 for (s
= verify
->signatures
; s
; s
= s
->next
)
609 unsigned flags
= s
->summary
;
611 pthread_cleanup_push ((void *)strv_free
, new_signers
);
612 log_write1 (_ ("%s: signer: %s, status=%u"),
613 crypto
->filename
, s
->fpr
, s
->status
);
614 pthread_cleanup_pop (0);
616 flags
&= ~(GPGME_SIGSUM_KEY_EXPIRED
|GPGME_SIGSUM_SIG_EXPIRED
);
618 flags
|= GPGME_SIGSUM_VALID
;
620 if (gpg_err_code (s
->status
) == GPG_ERR_KEY_EXPIRED
)
623 if (s
->status
|| s
->wrong_key_usage
|| !(flags
& GPGME_SIGSUM_VALID
))
626 pp
= strv_cat (new_signers
, str_dup (s
->fpr
));
636 if (verify
->signatures
&& !new_signers
)
637 rc
= GPG_ERR_BAD_SIGNATURE
;
641 xfree (crypto
->plaintext
);
642 crypto
->plaintext
= NULL
;
643 crypto
->plaintext_size
= 0;
644 pthread_cleanup_push ((void *)strv_free
, new_recipients
);
645 pthread_cleanup_push ((void *)strv_free
, new_signers
);
646 rc
= crypto_data_to_buf (plain
, &crypto
->plaintext
,
647 &crypto
->plaintext_size
);
648 pthread_cleanup_pop (0);
649 pthread_cleanup_pop (0);
652 strv_free (crypto
->pubkey
);
653 crypto
->pubkey
= new_recipients
;
654 crypto_keyid_to_16b (crypto
->pubkey
);
656 xfree (crypto
->sigkey
);
657 crypto
->sigkey
= NULL
;
660 crypto
->sigkey
= str_dup (*new_signers
);
661 strv_free (new_signers
);
662 crypto_keyid_to_16b_once (crypto
->sigkey
);
670 strv_free (new_recipients
);
671 strv_free (new_signers
);
674 pthread_cleanup_pop (1); // free_gpgme_data_cb (plain)
679 crypto_free_key_list (gpgme_key_t
*keys
)
683 for (i
= 0; keys
&& keys
[i
]; i
++)
684 gpgme_key_unref (keys
[i
]);
689 /* Removes strings in 'prune' from 'a'. */
691 prune_keys (char **a
, char **prune
)
695 for (p
= prune
; p
&& *p
; p
++)
699 for (ap
= a
; ap
&& *ap
; ap
++)
701 if (!strcmp (*ap
, *p
))
716 remove_duplicates (char **a
)
720 for (p
= a
; p
&& *p
; p
++)
724 for (t
= p
+1; t
&& *t
; t
++)
726 if (!strcmp (*p
, *t
))
738 remove_duplicates (a
);
746 crypto_encrypt (struct client_s
*client
, struct crypto_s
*crypto
)
749 gpgme_data_t cipher
= NULL
;
750 gpgme_key_t
*keys
= NULL
;
751 gpgme_key_t
*sigkeys
= NULL
;
755 if (!((crypto
->flags
& CRYPTO_FLAG_SYMMETRIC
)))
757 crypto_keyid_to_16b (crypto
->save
.pubkey
);
758 remove_duplicates (crypto
->save
.pubkey
);
759 rc
= crypto_list_keys (crypto
, crypto
->save
.pubkey
, 0, &keys
);
764 pthread_cleanup_push ((void *)crypto_free_key_list
, keys
);
765 rc
= gpgme_data_new (&cipher
);
766 pthread_cleanup_push ((void *)free_gpgme_data_cb
, cipher
);
768 rc
= gpgme_data_set_file_name (cipher
, crypto
->filename
);
770 if (!rc
&& crypto
->save
.sigkey
)
774 crypto_keyid_to_16b_once (crypto
->save
.sigkey
);
775 strv_printf (&tmp
, "%s", crypto
->save
.sigkey
);
776 pthread_cleanup_push ((void *)strv_free
, tmp
);
777 rc
= crypto_list_keys (crypto
, tmp
, 1, &sigkeys
);
778 pthread_cleanup_pop (1);
779 if (gpg_err_code (rc
) == GPG_ERR_NO_DATA
)
785 gpgme_data_t plain
= NULL
;
787 pthread_cleanup_push ((void *)crypto_free_key_list
, sigkeys
);
788 rc
= gpgme_data_new_from_mem (&plain
, (char *)crypto
->plaintext
,
789 crypto
->plaintext_size
, 0);
790 pthread_cleanup_push ((void *)free_gpgme_data_cb
, plain
);
795 gpgme_signers_clear (crypto
->ctx
);
797 for (i
= 0; sigkeys
&& sigkeys
[i
]; i
++)
798 gpgme_signers_add (crypto
->ctx
, sigkeys
[i
]);
803 gpgme_data_set_encoding (cipher
, GPGME_DATA_ENCODING_ARMOR
);
804 rc
= send_status (client
? client
->ctx
: NULL
, STATUS_ENCRYPT
, NULL
);
809 int f
= config_get_boolean ("global", "encrypt_to");
812 flags
|= GPGME_ENCRYPT_NO_ENCRYPT_TO
;
814 f
= config_get_boolean ("global", "always_trust");
816 flags
|= GPGME_ENCRYPT_ALWAYS_TRUST
;
818 if (!(crypto
->flags
& CRYPTO_FLAG_SYMMETRIC
)
819 || (crypto
->flags
& CRYPTO_FLAG_SYMMETRIC
&& sigkeys
))
824 MUTEX_TRYLOCK ((client
? client
->ctx
: NULL
), &crypto_mutex
, rc
,
825 (client
? client
->lock_timeout
: -1));
829 pthread_cleanup_push (release_mutex_cb
, &crypto_mutex
);
831 rc
= gpgme_op_encrypt_sign_start (crypto
->ctx
, keys
, flags
, plain
,
834 rc
= gpgme_op_encrypt_start (crypto
->ctx
, NULL
, flags
, plain
,
838 STATUS_TIMEOUT_INIT (crypto
);
841 if (!rc
&& crypto
->progress_rc
)
842 rc
= crypto
->progress_rc
;
844 STATUS_TIMEOUT_TEST (crypto
, rc
, STATUS_ENCRYPT
, NULL
);
846 } while (!rc
&& !gpgme_wait (crypto
->ctx
, &rc
, 0) && !rc
);
848 pthread_cleanup_pop (1);
852 gpgme_encrypt_result_t result
;
853 gpgme_sign_result_t sresult
;
854 gpgme_invalid_key_t inv
;
855 gpgme_new_signature_t sigs
;
859 result
= gpgme_op_encrypt_result (crypto
->ctx
);
860 inv
= result
->invalid_recipients
;
863 pthread_cleanup_push ((void *)strv_free
, prune
);
864 log_write1 (_ ("%s: invalid recipient: %s, rc=%u"),
865 crypto
->filename
, inv
->fpr
, inv
->reason
);
866 pthread_cleanup_pop (0);
867 p
= strv_cat (prune
, str_dup(inv
->fpr
));
881 p
= prune_keys (crypto
->save
.pubkey
, prune
);
882 crypto
->save
.pubkey
= p
;
886 crypto_keyid_to_16b (crypto
->save
.pubkey
);
887 sresult
= gpgme_op_sign_result (crypto
->ctx
);
888 inv
= sresult
? sresult
->invalid_signers
: NULL
;
891 log_write1 (_ ("%s: invalid signer: %s, rc=%u"),
892 crypto
->filename
, inv
->fpr
, inv
->reason
);
896 sigs
= sresult
? sresult
->signatures
: NULL
;
905 pthread_cleanup_push ((void *)strv_free
, p
);
906 log_write1 (_ ("%s: signer: %s"), crypto
->filename
,
908 pthread_cleanup_pop (0);
910 pp
= strv_cat (p
, str_dup (sigs
->fpr
));
924 xfree (crypto
->save
.sigkey
);
925 crypto
->save
.sigkey
= str_dup (*p
);
927 crypto_keyid_to_16b_once (crypto
->save
.sigkey
);
928 crypto
->cipher
= cipher
;
931 else if (!rc
&& crypto
->flags
& CRYPTO_FLAG_SYMMETRIC
)
933 crypto
->cipher
= cipher
;
937 if (!(crypto
->flags
& CRYPTO_FLAG_SYMMETRIC
)
938 || (crypto
->flags
& CRYPTO_FLAG_SYMMETRIC
&& sigkeys
))
939 rc
= GPG_ERR_NO_SIGNATURE_SCHEME
;
944 pthread_cleanup_pop (1); // free_gpgme_data_cb (plain)
945 pthread_cleanup_pop (1); // crypto_free_key_list (sigkeys)
948 pthread_cleanup_pop (0); // free_gpgme_data_cb (cipher)
949 pthread_cleanup_pop (1); // crypto_free_key_list (keys)
952 free_gpgme_data_cb (cipher
);
958 crypto_passwd (struct client_s
*client
, struct crypto_s
*crypto
)
961 gpgme_key_t
*keys
= NULL
;
963 /* Use SAVE instead for symmetric files. */
964 rc
= crypto_is_symmetric (client
->filename
);
965 if (!rc
|| rc
!= GPG_ERR_BAD_DATA
)
966 return !rc
? GPG_ERR_NOT_SUPPORTED
: rc
;
968 /* Cannot change the passphrase of a key stored on a smartcard. Use
969 * gpg --card-edit instead. */
970 rc
= cache_is_shadowed (client
->filename
);
972 return GPG_ERR_NOT_SUPPORTED
;
973 else if (rc
!= GPG_ERR_NO_DATA
)
976 rc
= crypto_list_keys (crypto
, crypto
->pubkey
, 1, &keys
);
980 crypto
->flags
|= CRYPTO_FLAG_PASSWD
;
981 pthread_cleanup_push ((void *)crypto_free_key_list
, keys
);
982 rc
= send_status (client
->ctx
, STATUS_KEEPALIVE
, NULL
);
984 MUTEX_TRYLOCK (client
->ctx
, &crypto_mutex
, rc
, client
->lock_timeout
);
988 pthread_cleanup_push (release_mutex_cb
, &crypto_mutex
);
989 rc
= gpgme_op_passwd_start (crypto
->ctx
, keys
[0], 0);
992 STATUS_TIMEOUT_INIT (crypto
);
995 if (!rc
&& crypto
->progress_rc
)
996 rc
= crypto
->progress_rc
;
998 STATUS_TIMEOUT_TEST (crypto
, rc
, STATUS_KEEPALIVE
, NULL
);
1000 } while (!rc
&& !gpgme_wait (crypto
->ctx
, &rc
, 0) && !rc
);
1002 pthread_cleanup_pop (1);
1005 pthread_cleanup_pop (1);
1009 /* Generate a new key pair. The resulting keyid's are stored in crypto->save.
1012 crypto_genkey (struct client_s
*client
, struct crypto_s
*crypto
)
1016 rc
= send_status (client
? client
->ctx
: NULL
, STATUS_GENKEY
, NULL
);
1018 MUTEX_TRYLOCK ((client
? client
->ctx
: NULL
), &crypto_mutex
, rc
,
1019 (client
? client
->lock_timeout
: 0));
1023 pthread_cleanup_push (release_mutex_cb
, &crypto_mutex
);
1024 if (crypto
->save
.mainkey
)
1026 rc
= gpgme_op_createsubkey_start (crypto
->ctx
,
1027 crypto
->save
.mainkey
[0],
1030 crypto
->save
.expire
,
1031 crypto
->save
.flags
);
1035 rc
= gpgme_op_createkey_start (crypto
->ctx
,
1036 crypto
->save
.userid
,
1039 crypto
->save
.expire
,
1041 crypto
->save
.flags
);
1046 STATUS_TIMEOUT_INIT (crypto
);
1049 if (!rc
&& crypto
->progress_rc
)
1050 rc
= crypto
->progress_rc
;
1052 STATUS_TIMEOUT_TEST (crypto
, rc
, STATUS_GENKEY
, NULL
);
1054 } while (!rc
&& !gpgme_wait (crypto
->ctx
, &rc
, 0) && !rc
);
1056 pthread_cleanup_pop (1);
1061 gpgme_key_t
*keys
= NULL
;
1062 gpgme_genkey_result_t result
;
1064 result
= gpgme_op_genkey_result (crypto
->ctx
);
1065 xfree (crypto
->save
.sigkey
);
1066 crypto
->save
.sigkey
= str_dup (result
->fpr
);
1067 crypto_keyid_to_16b_once (crypto
->save
.sigkey
);
1073 strv_printf (&tmp
, "%s", crypto
->save
.sigkey
);
1074 pthread_cleanup_push ((void *)strv_free
, tmp
);
1075 rc
= crypto_list_keys (crypto
, tmp
, 1, &keys
);
1076 pthread_cleanup_pop (1);
1081 gpgme_subkey_t key
= keys
[0]->subkeys
;
1083 for (; key
; key
= key
->next
)
1085 if (key
->can_encrypt
)
1089 pthread_cleanup_push ((void *)crypto_free_key_list
, keys
);
1090 rc
= send_status (client
? client
->ctx
: NULL
, STATUS_GENKEY
, "%s %s",
1091 crypto
->save
.sigkey
, key
? key
->fpr
: "");
1094 crypto
->save
.pubkey
= strv_cat (crypto
->save
.pubkey
,
1095 str_dup (key
->fpr
));
1096 crypto_keyid_to_16b (crypto
->save
.pubkey
);
1099 pthread_cleanup_pop (1);
1108 acl_free_cb (void *arg
)
1110 acl_t acl
= arg
? (acl_t
) arg
: NULL
;
1117 /* The advisory lock should be obtained before calling this function. */
1119 crypto_write_file (struct crypto_s
*crypto
, unsigned char **r_crc
,
1133 if (crypto
->filename
)
1135 if (lstat (crypto
->filename
, &st
) == 0)
1137 mode
= st
.st_mode
& (S_IRWXU
| S_IRWXG
| S_IRWXO
);
1139 if (!(mode
& S_IWUSR
))
1140 return GPG_ERR_EACCES
;
1142 else if (errno
!= ENOENT
)
1143 return gpg_error_from_errno (errno
);
1145 snprintf (tmp
, sizeof (tmp
), "%s.XXXXXX", crypto
->filename
);
1146 mode_t tmode
= umask (0600);
1150 rc
= gpg_error_from_errno (errno
);
1152 log_write ("%s: %s", tmp
, pwmd_strerror (rc
));
1161 rc
= crypto_data_to_buf (crypto
->cipher
, &buf
, &size
);
1164 if (crypto
->filename
)
1169 pthread_cleanup_push ((void *)close_fd_cb
, &fd
);
1171 rc
= get_checksum_memory (buf
, size
, r_crc
, r_crclen
);
1175 pthread_cleanup_push ((void *)xfree
, buf
);
1176 len
= write (fd
, buf
, size
);
1177 pthread_cleanup_pop (1);
1179 rc
= gpg_error_from_errno (errno
);
1184 if (fsync (fd
) != -1)
1186 if (crypto
->filename
&& close (fd
) != -1)
1189 acl
= acl_get_file (crypto
->filename
, ACL_TYPE_ACCESS
);
1190 if (!acl
&& errno
== ENOENT
)
1191 acl
= acl_get_file (".", ACL_TYPE_DEFAULT
);
1193 log_write ("ACL: %s: %s", crypto
->filename
,
1194 pwmd_strerror (gpg_error_from_errno (errno
)));
1195 pthread_cleanup_push ((void *)acl_free_cb
, acl
);
1199 if (config_get_boolean (crypto
->filename
, "backup"))
1201 char tmp2
[PATH_MAX
];
1203 snprintf (tmp2
, sizeof (tmp2
), "%s.backup", crypto
->filename
);
1204 if (rename (crypto
->filename
, tmp2
) == -1)
1205 if (errno
!= ENOENT
)
1206 rc
= gpg_error_from_errno (errno
);
1209 if (!rc
&& rename (tmp
, crypto
->filename
) == -1)
1210 rc
= gpg_error_from_errno (errno
);
1214 if (chmod (crypto
->filename
, mode
) == -1)
1215 log_write ("%s(%u): %s", __FILE__
, __LINE__
,
1216 pwmd_strerror (gpg_error_from_syserror ()));
1219 if (!rc
&& acl
&& acl_set_file (crypto
->filename
,
1220 ACL_TYPE_ACCESS
, acl
))
1221 log_write ("ACL: %s: %s", crypto
->filename
,
1222 pwmd_strerror (gpg_error_from_errno (errno
)));
1223 pthread_cleanup_pop (1);
1226 else if (crypto
->filename
)
1227 rc
= gpg_error_from_errno (errno
);
1229 if (!rc
&& fd
!= -1)
1231 char *datadir
= str_asprintf ("%s/data", homedir
);
1235 int dfd
= open (datadir
, O_RDONLY
);
1239 if (fsync (dfd
) == -1)
1240 log_write ("%s %d: %s", __FILE__
, __LINE__
,
1241 pwmd_strerror (errno
));
1246 log_write ("%s %d: %s", __FILE__
, __LINE__
,
1247 pwmd_strerror (errno
));
1254 rc
= gpg_error_from_errno (errno
);
1257 pthread_cleanup_pop (0); // close (fd)
1265 crypto_key_info (const gpgme_key_t key
)
1267 struct string_s
*string
= string_new (NULL
), *s
;
1270 gpgme_subkey_t subkey
;
1271 gpgme_user_id_t uid
;
1276 for (u
= 0, uid
= key
->uids
; uid
; uid
= uid
->next
)
1279 for (n
= 0, subkey
= key
->subkeys
; subkey
; subkey
= subkey
->next
)
1282 s
= string_append_printf (string
, "%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%i:%s:%s:%s:%i:%u:%u",
1283 key
->revoked
, key
->expired
, key
->disabled
,
1284 key
->invalid
, key
->can_encrypt
, key
->can_sign
,
1285 key
->can_certify
, key
->secret
,
1286 key
->can_authenticate
, key
->is_qualified
,
1288 key
->issuer_serial
? key
->issuer_serial
: "",
1289 key
->issuer_name
? key
->issuer_name
: "",
1290 key
->chain_id
? key
->chain_id
: "",
1291 key
->owner_trust
, u
, n
);
1294 string_free (string
, 1);
1299 for (subkey
= key
->subkeys
; subkey
; subkey
= subkey
->next
)
1303 s
= string_append_printf (string
, ":%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%i:%u",
1304 subkey
->revoked
, subkey
->expired
,
1305 subkey
->disabled
, subkey
->invalid
,
1306 subkey
->can_encrypt
, subkey
->can_sign
,
1307 subkey
->can_certify
, subkey
->secret
,
1308 subkey
->can_authenticate
, subkey
->is_qualified
,
1309 subkey
->is_cardkey
, subkey
->pubkey_algo
,
1313 string_free (string
, 1);
1318 s
= string_append_printf (string
, ":%s:%s:%s:%li:%li:%s",
1319 subkey
->keyid
, subkey
->fpr
,
1320 subkey
->keygrip
? subkey
->keygrip
: "",
1321 subkey
->timestamp
, subkey
->expires
,
1322 subkey
->card_number
? subkey
->card_number
: "0");
1325 string_free (string
, 1);
1330 tmp
= gnupg_escape (subkey
->curve
);
1331 s
= string_append_printf (string
, ":%s", tmp
? tmp
: "");
1335 string_free (string
, 1);
1342 for (uid
= key
->uids
; uid
; uid
= uid
->next
)
1344 char *userid
, *name
, *email
, *comment
;
1346 userid
= gnupg_escape (uid
->uid
);
1347 name
= gnupg_escape (uid
->name
);
1348 email
= gnupg_escape (uid
->email
);
1349 comment
= gnupg_escape (uid
->comment
);
1350 s
= string_append_printf (string
, ":%u:%u:%u:%s:%s:%s:%s",
1351 uid
->revoked
, uid
->invalid
, uid
->validity
,
1352 userid
? userid
: "",
1355 comment
? comment
: "");
1362 string_free (string
, 1);
1370 string_free (string
, 0);
1375 crypto_try_decrypt (struct client_s
*client
, int no_pinentry
)
1377 struct crypto_s
*crypto
;
1379 char *keyfile
= config_get_string (client
->filename
, "passphrase_file");
1381 rc
= crypto_init (&crypto
, client
->ctx
, client
->filename
, no_pinentry
,
1385 pthread_cleanup_push ((void *)crypto_free
, crypto
);
1386 rc
= crypto_decrypt (client
, crypto
);
1387 pthread_cleanup_pop (1);
1395 /* The advisory lock should be obtained before calling this function. */
1397 crypto_is_symmetric (const char *filename
)
1404 rc
= open_check_file (filename
, &fd
, NULL
, 1);
1408 len
= read (fd
, &magic
, sizeof(magic
));
1410 if (len
!= sizeof (magic
))
1411 return GPG_ERR_INV_VALUE
;
1413 // Always read as big endian.
1414 if (magic
[0] != 0x8c || magic
[1] != 0x0d)
1415 return GPG_ERR_BAD_DATA
;
1421 crypto_delete_key (struct client_s
*client
, struct crypto_s
*crypto
,
1422 const gpgme_key_t key
, int secret
)
1426 STATUS_TIMEOUT_INIT (crypto
);
1427 rc
= send_status (client
->ctx
, STATUS_DECRYPT
, NULL
);
1429 rc
= gpgme_op_delete_ext_start (crypto
->ctx
, key
, GPGME_DELETE_FORCE
1430 | GPGME_DELETE_ALLOW_SECRET
);
1437 if (!rc
&& crypto
->progress_rc
)
1438 rc
= crypto
->progress_rc
;
1441 STATUS_TIMEOUT_TEST (crypto
, rc
, STATUS_DECRYPT
, NULL
);
1445 } while (!gpgme_wait (crypto
->ctx
, &rc
, 0) && !rc
);