2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
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/>.
25 #include <sys/types.h>
30 #include "pwmd-error.h"
31 #include "util-misc.h"
37 #include "util-string.h"
44 #define STATUS_TIMEOUT_INIT(crypto) \
46 crypto->status_timeout = time (NULL); \
47 crypto->progress_rc = 0; \
50 #define STATUS_TIMEOUT_TEST(crypto, rc, s, line) \
52 time_t now = time (NULL); \
53 if (now - crypto->status_timeout >= keepalive && crypto->client_ctx) { \
54 rc = send_status (crypto->client_ctx, s, line); \
55 crypto->status_timeout = now; \
61 show_key_output (gpgme_key_t key
)
63 gpgme_subkey_t keyp
; // first is primary
65 for (keyp
= key
->subkeys
; keyp
; keyp
= keyp
->next
)
67 fprintf(stderr
, "keyid: %s, revoked: %i, expired: %i, disabled: %i, invalid: %i,"
68 "encrypt: %i, sign: %i, cert: %i, auth: %i, secret: %i\n",
69 keyp
->keyid
, keyp
->revoked
, keyp
->expired
, keyp
->disabled
,
70 keyp
->invalid
, keyp
->can_encrypt
, keyp
->can_sign
,
71 keyp
->can_certify
, keyp
->can_authenticate
, keyp
->secret
);
79 passphrase_cb (void *data
, const char *hint
, const char *info
, int bad
, int fd
)
81 struct crypto_s
*crypto
= data
;
82 unsigned char *result
= NULL
;
84 gpg_error_t rc
= GPG_ERR_CANCELED
;
87 rc
= assuan_write_status (crypto
->client_ctx
, "PASSPHRASE_HINT", hint
);
90 rc
= assuan_write_status (crypto
->client_ctx
, "PASSPHRASE_INFO", info
);
93 rc
= assuan_inquire (crypto
->client_ctx
, "PASSPHRASE", &result
, &len
, 0);
97 if (!result
|| !*result
)
98 gpgme_io_writen (fd
, "\n", 1);
101 int nl
= result
[len
-1] == '\n';
104 ret
= gpgme_io_writen (fd
, result
, len
);
106 gpgme_io_writen (fd
, "\n", 1);
108 rc
= GPG_ERR_CANCELED
;
117 progress_cb (void *data
, const char *what
, int type
, int current
, int total
)
119 struct crypto_s
*crypto
= data
;
121 crypto
->progress_rc
= send_status (crypto
->client_ctx
, STATUS_GPGME
,
122 "%s %i %i %i", what
, type
, current
, total
);
126 crypto_data_to_buf (const gpgme_data_t data
, unsigned char **result
,
129 gpgme_error_t rc
= gpgme_data_seek (data
, 0, SEEK_SET
);
131 size_t total
= 0, size
= BUFSIZE
;
137 buf
= xmalloc (size
);
139 return GPG_ERR_ENOMEM
;
143 ret
= gpgme_data_read (data
, &buf
[total
], BUFSIZE
);
150 p
= xrealloc (buf
, size
* sizeof(char));
154 return GPG_ERR_ENOMEM
;
163 rc
= gpgme_err_code_from_syserror ();
174 crypto_list_keys (struct crypto_s
*crypto
, char *keys
[], int secret
,
175 gpgme_key_t
**result
)
178 gpgme_key_t key
= NULL
, *res
= NULL
;
181 STATUS_TIMEOUT_INIT (crypto
);
182 rc
= gpgme_op_keylist_ext_start (crypto
->ctx
, (const char **)keys
, secret
, 0);
190 rc
= gpgme_op_keylist_next (crypto
->ctx
, &key
);
191 if (rc
&& gpgme_err_code(rc
) != GPG_ERR_EOF
)
200 p
= xrealloc (res
, (total
+2) * sizeof (gpgme_key_t
*));
210 STATUS_TIMEOUT_TEST (crypto
, rc
, STATUS_GPGME
, NULL
);
215 rc
= gpgme_op_keylist_end (crypto
->ctx
);
219 rc
= total
? 0 : secret
? GPG_ERR_NO_SECKEY
: GPG_ERR_NO_PUBKEY
;
223 crypto_free_key_list (res
);
229 crypto_cleanup_save (struct save_s
*save
)
234 strv_free (save
->pubkey
);
235 strv_free (save
->sigkey
);
236 memset (save
, 0, sizeof (struct save_s
));
240 crypto_cleanup_non_keys (struct crypto_s
*crypto
)
246 gpgme_release (crypto
->ctx
);
249 xfree (crypto
->plaintext
);
250 crypto
->plaintext
= NULL
;
251 crypto
->plaintext_size
= 0;
254 gpgme_data_release (crypto
->cipher
);
256 crypto
->cipher
= NULL
;
257 crypto_cleanup_save (&crypto
->save
);
261 crypto_cleanup (struct crypto_s
*crypto
)
266 crypto_cleanup_non_keys (crypto
);
267 strv_free (crypto
->pubkey
);
268 strv_free (crypto
->sigkey
);
269 xfree (crypto
->filename
);
274 crypto_init_ctx (struct crypto_s
*crypto
, int no_pinentry
)
277 gpgme_keylist_mode_t keylist_mode
;
280 rc
= gpgme_new (&ctx
);
284 rc
= gpgme_set_protocol (ctx
, GPGME_PROTOCOL_OPENPGP
);
287 keylist_mode
= gpgme_get_keylist_mode (ctx
);
288 keylist_mode
|= GPGME_KEYLIST_MODE_LOCAL
|GPGME_KEYLIST_MODE_WITH_SECRET
;
289 rc
= gpgme_set_keylist_mode (ctx
, keylist_mode
);
293 rc
= gpgme_set_pinentry_mode (ctx
, GPGME_PINENTRY_MODE_LOOPBACK
);
295 rc
= gpgme_set_pinentry_mode (ctx
, GPGME_PINENTRY_MODE_DEFAULT
);
297 gpgme_set_passphrase_cb (ctx
, passphrase_cb
, crypto
);
298 gpgme_set_progress_cb (ctx
, progress_cb
, crypto
);
310 crypto_init (struct crypto_s
**crypto
, void *ctx
, const char *filename
,
313 struct crypto_s
*new = xcalloc (1, sizeof (struct crypto_s
));
316 keepalive
= config_get_integer ("global", "keepalive_interval");
319 return GPG_ERR_ENOMEM
;
321 rc
= crypto_init_ctx (new, no_pinentry
);
327 new->filename
= str_dup (filename
);
332 new->client_ctx
= ctx
;
337 crypto_cleanup (new);
342 crypto_decrypt (struct client_s
*client
, struct crypto_s
*crypto
)
349 rc
= gpgme_data_new (&plain
);
353 fd
= open (crypto
->filename
, O_RDONLY
);
355 return gpgme_err_code_from_syserror ();
357 rc
= gpgme_data_new_from_fd (&cipher
, fd
);
364 STATUS_TIMEOUT_INIT(crypto
);
365 rc
= send_status (client
? client
->ctx
: NULL
, STATUS_DECRYPT
, NULL
);
367 rc
= gpgme_op_decrypt_verify_start (crypto
->ctx
, cipher
, plain
);
372 gpgme_data_release (cipher
);
378 if (!rc
&& crypto
->progress_rc
)
379 rc
= crypto
->progress_rc
;
382 STATUS_TIMEOUT_TEST (crypto
, rc
, STATUS_DECRYPT
, NULL
);
386 } while (!gpgme_wait (crypto
->ctx
, &rc
, 0) && !rc
);
388 gpgme_data_release (cipher
);
394 gpgme_decrypt_result_t result
;
396 result
= gpgme_op_decrypt_result (crypto
->ctx
);
397 if (!result
->unsupported_algorithm
&& !result
->wrong_key_usage
)
401 strv_free (crypto
->pubkey
);
402 crypto
->pubkey
= NULL
;
404 for (r
= result
->recipients
; r
; r
= r
->next
)
406 log_write (_ ("%s: recipient: %s, status=%u"),
407 crypto
->filename
, r
->keyid
, r
->status
);
409 pp
= strv_cat(crypto
->pubkey
, str_dup (r
->keyid
));
419 else if (result
->wrong_key_usage
)
420 rc
= GPG_ERR_WRONG_KEY_USAGE
;
421 else if (result
->unsupported_algorithm
)
422 rc
= GPG_ERR_UNSUPPORTED_ALGORITHM
;
426 gpgme_verify_result_t result
;
429 strv_free (crypto
->sigkey
);
430 crypto
->sigkey
= NULL
;
431 result
= gpgme_op_verify_result (crypto
->ctx
);
433 for (s
= result
->signatures
; s
; s
= s
->next
)
435 log_write (_ ("%s: signer: %s, status=%u"),
436 crypto
->filename
, s
->fpr
, s
->status
);
437 if (s
->status
|| s
->wrong_key_usage
438 || !(s
->summary
& GPGME_SIGSUM_VALID
))
441 pp
= strv_cat (crypto
->sigkey
, str_dup (s
->fpr
));
451 xfree (crypto
->plaintext
);
452 crypto
->plaintext
= NULL
;
453 crypto
->plaintext_size
= 0;
456 rc
= crypto_data_to_buf (plain
, &crypto
->plaintext
,
457 &crypto
->plaintext_size
);
461 gpgme_data_release (plain
);
466 crypto_free_key_list (gpgme_key_t
*keys
)
470 for (i
= 0; keys
&& keys
[i
]; i
++)
471 gpgme_key_unref (keys
[i
]);
477 crypto_encrypt (struct client_s
*client
, struct crypto_s
*crypto
)
481 gpgme_key_t
*keys
= NULL
;
482 gpgme_key_t
*sigkeys
= NULL
;
484 STATUS_TIMEOUT_INIT (crypto
);
485 rc
= crypto_list_keys (crypto
, crypto
->save
.pubkey
, 0, &keys
);
489 rc
= gpgme_data_new (&cipher
);
491 rc
= gpgme_data_set_file_name (cipher
, crypto
->filename
);
495 rc
= crypto_list_keys (crypto
, crypto
->save
.sigkey
, 1, &sigkeys
);
496 if (gpg_err_code (rc
) == GPG_ERR_NO_DATA
)
504 rc
= gpgme_data_new_from_mem (&plain
, (char *)crypto
->plaintext
,
505 crypto
->plaintext_size
, 0);
510 gpgme_signers_clear (crypto
->ctx
);
512 for (i
= 0; sigkeys
&& sigkeys
[i
]; i
++)
513 gpgme_signers_add (crypto
->ctx
, sigkeys
[i
]);
516 rc
= GPG_ERR_NO_SIGNATURE_SCHEME
;
521 gpgme_data_set_encoding (cipher
, GPGME_DATA_ENCODING_ARMOR
);
523 rc
= send_status (client
? client
->ctx
: NULL
, STATUS_ENCRYPT
, NULL
);
527 int f
= config_get_boolean ("global", "encrypt_to");
530 flags
|= GPGME_ENCRYPT_NO_ENCRYPT_TO
;
532 f
= config_get_boolean ("global", "always_trust");
534 flags
|= GPGME_ENCRYPT_ALWAYS_TRUST
;
536 rc
= gpgme_op_encrypt_sign_start (crypto
->ctx
, keys
, flags
,
545 if (!rc
&& crypto
->progress_rc
)
546 rc
= crypto
->progress_rc
;
549 STATUS_TIMEOUT_TEST (crypto
, rc
, STATUS_ENCRYPT
, NULL
);
553 } while (!gpgme_wait (crypto
->ctx
, &rc
, 0) && !rc
);
557 gpgme_encrypt_result_t result
;
558 gpgme_sign_result_t sresult
;
559 gpgme_invalid_key_t inv
;
561 result
= gpgme_op_encrypt_result (crypto
->ctx
);
562 inv
= result
->invalid_recipients
;
565 log_write (_ ("%s: invalid recipient: %s, rc=%u"),
566 crypto
->filename
, inv
->fpr
, inv
->reason
);
570 sresult
= gpgme_op_sign_result (crypto
->ctx
);
571 inv
= sresult
->invalid_signers
;
574 log_write (_ ("%s: invalid signer: %s, rc=%u"),
575 crypto
->filename
, inv
->fpr
, inv
->reason
);
579 crypto
->cipher
= cipher
;
583 gpgme_data_release (plain
);
586 crypto_free_key_list (keys
);
587 crypto_free_key_list (sigkeys
);
590 gpgme_data_release (cipher
);
596 crypto_passwd (struct client_s
*client
, struct crypto_s
*crypto
)
599 gpgme_key_t
*keys
= NULL
;
601 rc
= crypto_list_keys (crypto
, crypto
->pubkey
, 1, &keys
);
605 STATUS_TIMEOUT_INIT (crypto
);
606 rc
= send_status (client
->ctx
, STATUS_PASSWD
, NULL
);
607 rc
= gpgme_op_passwd_start (crypto
->ctx
, keys
[0], 0);
612 if (!rc
&& crypto
->progress_rc
)
613 rc
= crypto
->progress_rc
;
616 STATUS_TIMEOUT_TEST (crypto
, rc
, STATUS_PASSWD
, NULL
);
620 } while (!gpgme_wait (crypto
->ctx
, &rc
, 0) && !rc
);
623 crypto_free_key_list (keys
);
627 /* Generate a new key pair. The resulting keyid's are stored in crypto->save.
630 crypto_genkey (struct client_s
*client
, struct crypto_s
*crypto
,
631 const unsigned char *params
)
633 gpgme_genkey_result_t result
;
636 STATUS_TIMEOUT_INIT (crypto
);
637 rc
= send_status (client
? client
->ctx
: NULL
, STATUS_GENKEY
, NULL
);
639 rc
= gpgme_op_genkey_start (crypto
->ctx
, (const char *)params
, NULL
, NULL
);
646 if (!rc
&& crypto
->progress_rc
)
647 rc
= crypto
->progress_rc
;
650 STATUS_TIMEOUT_TEST (crypto
, rc
, STATUS_GENKEY
, NULL
);
654 } while (!gpgme_wait (crypto
->ctx
, &rc
, 0) && !rc
);
658 result
= gpgme_op_genkey_result (crypto
->ctx
);
659 crypto
->save
.pubkey
= strv_cat (crypto
->save
.pubkey
,
660 str_dup (result
->fpr
));
661 crypto
->save
.sigkey
= strv_cat (crypto
->save
.sigkey
,
662 str_dup (result
->fpr
));
663 rc
= send_status (client
? client
->ctx
: NULL
, STATUS_GENKEY
, "%s",
671 crypto_default_key_params ()
673 char *user
= get_username (getuid());
674 char *params
= str_asprintf(
675 "<GnupgKeyParms format=\"internal\">\n"
676 " Key-Type: default\n"
677 " Subkey-Type: default\n"
682 getenv ("REALNAME") ? getenv ("REALNAME") : user
,
683 getenv ("EMAIL") ? getenv ("EMAIL") : user
);
690 crypto_write_file (struct crypto_s
*crypto
)
700 if (crypto
->filename
)
702 if (lstat (crypto
->filename
, &st
) == 0)
704 mode
= st
.st_mode
& (S_IRWXU
| S_IRWXG
| S_IRWXO
);
706 if (!(mode
& S_IWUSR
))
707 return GPG_ERR_EACCES
;
709 else if (errno
!= ENOENT
)
710 return gpg_error_from_errno (errno
);
712 snprintf (tmp
, sizeof (tmp
), "%s.XXXXXX", crypto
->filename
);
716 rc
= gpg_error_from_errno (errno
);
717 log_write ("%s: %s", tmp
, pwmd_strerror (rc
));
724 rc
= crypto_data_to_buf (crypto
->cipher
, &buf
, &size
);
725 len
= write (fd
, buf
, size
);
728 rc
= gpg_error_from_errno (errno
);
732 if (fsync (fd
) != -1)
734 if (crypto
->filename
&& close (fd
) != -1)
737 if (mode
&& config_get_boolean (crypto
->filename
, "backup"))
741 snprintf (tmp2
, sizeof (tmp2
), "%s.backup", crypto
->filename
);
742 if (rename (crypto
->filename
, tmp2
) == -1)
744 rc
= gpg_error_from_errno (errno
);
747 else if (crypto
->filename
)
748 rc
= gpg_error_from_errno (errno
);
751 rc
= gpg_error_from_errno (errno
);
756 if (crypto
->filename
&& rename (tmp
, crypto
->filename
) == -1)
757 rc
= gpg_error_from_errno (errno
);
758 else if (crypto
->filename
&& mode
)
759 chmod (crypto
->filename
, mode
);
769 crypto_key_info (const gpgme_key_t key
)
771 struct string_s
*string
= string_new (NULL
), *s
;
774 gpgme_subkey_t subkey
;
780 for (u
= 0, uid
= key
->uids
; uid
; uid
= uid
->next
)
783 for (n
= 0, subkey
= key
->subkeys
; subkey
; subkey
= subkey
->next
)
786 s
= string_append_printf (string
, "%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%i:%i:%u:%u",
787 key
->revoked
, key
->expired
, key
->disabled
,
788 key
->invalid
, key
->can_encrypt
, key
->can_sign
,
789 key
->can_certify
, key
->secret
,
790 key
->can_authenticate
, key
->is_qualified
,
791 key
->protocol
, key
->owner_trust
, u
, n
);
794 string_free (string
, 1);
799 for (subkey
= key
->subkeys
; subkey
; subkey
= subkey
->next
)
803 s
= string_append_printf (string
, ":%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%i:%u",
804 subkey
->revoked
, subkey
->expired
,
805 subkey
->disabled
, subkey
->invalid
,
806 subkey
->can_encrypt
, subkey
->can_sign
,
807 subkey
->can_certify
, subkey
->secret
,
808 subkey
->can_authenticate
, subkey
->is_qualified
,
809 subkey
->is_cardkey
, subkey
->pubkey_algo
,
813 string_free (string
, 1);
818 s
= string_append_printf (string
, ":%s:%s:%li:%li:%s",
819 subkey
->keyid
, subkey
->fpr
, subkey
->timestamp
,
821 subkey
->card_number
? subkey
->card_number
: "0");
824 string_free (string
, 1);
829 tmp
= openpgp_escape (subkey
->curve
);
830 s
= string_append_printf (string
, ":%s", tmp
? tmp
: "");
834 string_free (string
, 1);
841 for (uid
= key
->uids
; uid
; uid
= uid
->next
)
843 char *userid
, *name
, *email
, *comment
;
845 userid
= openpgp_escape (uid
->uid
);
846 name
= openpgp_escape (uid
->name
);
847 email
= openpgp_escape (uid
->email
);
848 comment
= openpgp_escape (uid
->comment
);
849 s
= string_append_printf (string
, ":%u:%u:%u:%s:%s:%s:%s",
850 uid
->revoked
, uid
->invalid
, uid
->validity
,
851 userid
? userid
: "",
854 comment
? comment
: "");
861 string_free (string
, 1);
869 string_free (string
, 0);
874 crypto_try_decrypt (struct client_s
*client
, int no_pinentry
)
876 struct crypto_s
*crypto
;
879 rc
= crypto_init (&crypto
, client
->ctx
, client
->filename
, no_pinentry
);
882 rc
= crypto_decrypt (client
, crypto
);
883 crypto_cleanup (crypto
);