mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-12 22:11:29 +02:00
Sample ECC keys and message do now work.
Import and export of secret keys does now work. Encryption has been fixed to be compatible with the sample messages. This version tests for new Libgcrypt function and thus needs to be build with a new Libgcrypt installed.
This commit is contained in:
parent
e0d4139e19
commit
4659c923a0
@ -1,3 +1,7 @@
|
|||||||
|
2011-02-01 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* configure.ac (HAVE_GCRY_PK_GET_CURVE): Define if availabale.
|
||||||
|
|
||||||
2011-01-20 Werner Koch <wk@g10code.com>
|
2011-01-20 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* configure.ac (AC_CONFIG_FILES): Remove keyserver/.
|
* configure.ac (AC_CONFIG_FILES): Remove keyserver/.
|
||||||
|
101
agent/ChangeLog
101
agent/ChangeLog
@ -1,5 +1,12 @@
|
|||||||
|
2011-02-02 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* cvt-openpgp.c (convert_secret_key): Remove algo mapping.
|
||||||
|
|
||||||
2011-01-31 Werner Koch <wk@g10code.com>
|
2011-01-31 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* cvt-openpgp.c (convert_to_openpgp): Adjust to reverted Libgcrypt
|
||||||
|
ABI.
|
||||||
|
|
||||||
* protect.c (protect_info): Adjust ECDSA and ECDH parameter names.
|
* protect.c (protect_info): Adjust ECDSA and ECDH parameter names.
|
||||||
Add "ecc".
|
Add "ecc".
|
||||||
* findkey.c (key_parms_from_sexp): Ditto.
|
* findkey.c (key_parms_from_sexp): Ditto.
|
||||||
@ -522,7 +529,7 @@
|
|||||||
* genkey.c (agent_protect_and_store): Return RC and not 0.
|
* genkey.c (agent_protect_and_store): Return RC and not 0.
|
||||||
* protect.c (do_encryption): Fix ignored error code from malloc.
|
* protect.c (do_encryption): Fix ignored error code from malloc.
|
||||||
Reported by Fabian Keil.
|
Reported by Fabian Keil.
|
||||||
|
|
||||||
2009-06-17 Werner Koch <wk@g10code.com>
|
2009-06-17 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* call-pinentry.c (agent_get_confirmation): Add arg WITH_CANCEL.
|
* call-pinentry.c (agent_get_confirmation): Add arg WITH_CANCEL.
|
||||||
@ -546,7 +553,7 @@
|
|||||||
* trustlist.c: Include estream.h.
|
* trustlist.c: Include estream.h.
|
||||||
(agent_marktrusted): Replace stdio stream by estream functions.
|
(agent_marktrusted): Replace stdio stream by estream functions.
|
||||||
|
|
||||||
* protect-tool.c (store_private_key): Use bin2hex.
|
* protect-tool.c (store_private_key): Use bin2hex.
|
||||||
|
|
||||||
2009-06-02 Werner Koch <wk@g10code.com>
|
2009-06-02 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
@ -560,7 +567,7 @@
|
|||||||
2009-05-15 Werner Koch <wk@g10code.com>
|
2009-05-15 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
Fix bug #1053.
|
Fix bug #1053.
|
||||||
|
|
||||||
* agent.h (lookup_ttl_t): New.
|
* agent.h (lookup_ttl_t): New.
|
||||||
* findkey.c (unprotect): Add arg LOOKUP_TTL.
|
* findkey.c (unprotect): Add arg LOOKUP_TTL.
|
||||||
(agent_key_from_file): Ditto.
|
(agent_key_from_file): Ditto.
|
||||||
@ -638,7 +645,7 @@
|
|||||||
(agent_istrusted): Add arg R_DISABLED. Change all callers.
|
(agent_istrusted): Add arg R_DISABLED. Change all callers.
|
||||||
(agent_marktrusted): Do not ask if flagged as disabled. Reverse
|
(agent_marktrusted): Do not ask if flagged as disabled. Reverse
|
||||||
the order of the questions. Store the disabled flag.
|
the order of the questions. Store the disabled flag.
|
||||||
|
|
||||||
* gpg-agent.c (main): Save signal mask and open fds. Restore mask
|
* gpg-agent.c (main): Save signal mask and open fds. Restore mask
|
||||||
and close all fds prior to the exec. Fixes bug#1013.
|
and close all fds prior to the exec. Fixes bug#1013.
|
||||||
|
|
||||||
@ -749,11 +756,11 @@
|
|||||||
* command.c (cmd_geteventcounter): Mark unused arg.
|
* command.c (cmd_geteventcounter): Mark unused arg.
|
||||||
(cmd_listtrusted, cmd_pksign, cmd_pkdecrypt, cmd_genkey): Ditto.
|
(cmd_listtrusted, cmd_pksign, cmd_pkdecrypt, cmd_genkey): Ditto.
|
||||||
(cmd_updatestartuptty, post_cmd_notify): Ditto.
|
(cmd_updatestartuptty, post_cmd_notify): Ditto.
|
||||||
* command-ssh.c (add_control_entry)
|
* command-ssh.c (add_control_entry)
|
||||||
(ssh_handler_request_identities, ssh_handler_remove_identity)
|
(ssh_handler_request_identities, ssh_handler_remove_identity)
|
||||||
(ssh_handler_remove_all_identities, ssh_handler_lock)
|
(ssh_handler_remove_all_identities, ssh_handler_lock)
|
||||||
(ssh_handler_unlock): Ditto.
|
(ssh_handler_unlock): Ditto.
|
||||||
* call-pinentry.c (pinentry_active_p, popup_message_thread)
|
* call-pinentry.c (pinentry_active_p, popup_message_thread)
|
||||||
(agent_popup_message_stop): Ditto.
|
(agent_popup_message_stop): Ditto.
|
||||||
* findkey.c (agent_public_key_from_file): Ditto.
|
* findkey.c (agent_public_key_from_file): Ditto.
|
||||||
* genkey.c (check_passphrase_pattern): Ditto.
|
* genkey.c (check_passphrase_pattern): Ditto.
|
||||||
@ -872,7 +879,7 @@
|
|||||||
* agent.h (struct server_control_s): Add XAUTHORITY and
|
* agent.h (struct server_control_s): Add XAUTHORITY and
|
||||||
PINENTRY_USER_DATA.
|
PINENTRY_USER_DATA.
|
||||||
* gpg-agent.c: New option --xauthority.
|
* gpg-agent.c: New option --xauthority.
|
||||||
(main, agent_init_default_ctrl)
|
(main, agent_init_default_ctrl)
|
||||||
(agent_deinit_default_ctrl): Implemented
|
(agent_deinit_default_ctrl): Implemented
|
||||||
* command.c (cmd_updatestartuptty): Ditto.
|
* command.c (cmd_updatestartuptty): Ditto.
|
||||||
* command-ssh.c (start_command_handler_ssh): Ditto.
|
* command-ssh.c (start_command_handler_ssh): Ditto.
|
||||||
@ -1032,7 +1039,7 @@
|
|||||||
|
|
||||||
2007-06-21 Werner Koch <wk@g10code.com>
|
2007-06-21 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* agent.h (ctrl_t): Remove. It is now declared in ../common/util.h.
|
* agent.h (ctrl_t): Remove. It is now declared in ../common/util.h.
|
||||||
|
|
||||||
* gpg-agent.c (check_for_running_agent): New arg SILENT. Changed
|
* gpg-agent.c (check_for_running_agent): New arg SILENT. Changed
|
||||||
all callers.
|
all callers.
|
||||||
@ -1065,7 +1072,7 @@
|
|||||||
* preset-passphrase.c (main): Setup default socket name for
|
* preset-passphrase.c (main): Setup default socket name for
|
||||||
simple-pwquery.
|
simple-pwquery.
|
||||||
(map_spwq_error): Remove.
|
(map_spwq_error): Remove.
|
||||||
(MAP_SPWQ_ERROR_IMPL): New.
|
(MAP_SPWQ_ERROR_IMPL): New.
|
||||||
|
|
||||||
* call-pinentry.c (start_pinentry): Use gnupg_module_name.
|
* call-pinentry.c (start_pinentry): Use gnupg_module_name.
|
||||||
* call-scd.c (start_scd): Ditto.
|
* call-scd.c (start_scd): Ditto.
|
||||||
@ -1127,7 +1134,7 @@
|
|||||||
(main): Call the setup_libgcrypt_logging helper.
|
(main): Call the setup_libgcrypt_logging helper.
|
||||||
* protect-tool.c (my_gcry_logger): Removed.
|
* protect-tool.c (my_gcry_logger): Removed.
|
||||||
(main): Call the setup_libgcrypt_logging helper.
|
(main): Call the setup_libgcrypt_logging helper.
|
||||||
|
|
||||||
2007-04-03 Werner Koch <wk@g10code.com>
|
2007-04-03 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* trustlist.c (read_trustfiles): Take a missing trustlist as an
|
* trustlist.c (read_trustfiles): Take a missing trustlist as an
|
||||||
@ -1135,7 +1142,7 @@
|
|||||||
|
|
||||||
2007-03-20 Werner Koch <wk@g10code.com>
|
2007-03-20 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* protect-tool.c: New option --p12-charset.
|
* protect-tool.c: New option --p12-charset.
|
||||||
* minip12.c (p12_build): Implement it.
|
* minip12.c (p12_build): Implement it.
|
||||||
|
|
||||||
2007-03-19 Werner Koch <wk@g10code.com>
|
2007-03-19 Werner Koch <wk@g10code.com>
|
||||||
@ -1170,7 +1177,7 @@
|
|||||||
|
|
||||||
2007-01-31 Werner Koch <wk@g10code.com>
|
2007-01-31 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* command-ssh.c (start_command_handler_ssh):
|
* command-ssh.c (start_command_handler_ssh):
|
||||||
|
|
||||||
* Makefile.am (t_common_ldadd): Add LIBICONV.
|
* Makefile.am (t_common_ldadd): Add LIBICONV.
|
||||||
|
|
||||||
@ -1298,7 +1305,7 @@
|
|||||||
(agent_pksign_do): Use it here for the TLS algo.
|
(agent_pksign_do): Use it here for the TLS algo.
|
||||||
* agent.h (GCRY_MD_USER_TLS_MD5SHA1): New.
|
* agent.h (GCRY_MD_USER_TLS_MD5SHA1): New.
|
||||||
* divert-scd.c (pksign): Add case for tls-md5sha1.
|
* divert-scd.c (pksign): Add case for tls-md5sha1.
|
||||||
|
|
||||||
* divert-scd.c (encode_md_for_card): Check that the algo is valid.
|
* divert-scd.c (encode_md_for_card): Check that the algo is valid.
|
||||||
|
|
||||||
2006-10-04 Werner Koch <wk@g10code.com>
|
2006-10-04 Werner Koch <wk@g10code.com>
|
||||||
@ -1368,7 +1375,7 @@
|
|||||||
|
|
||||||
Replaced all Assuan error codes by libgpg-error codes. Removed
|
Replaced all Assuan error codes by libgpg-error codes. Removed
|
||||||
all map_to_assuan_status and map_assuan_err.
|
all map_to_assuan_status and map_assuan_err.
|
||||||
|
|
||||||
* gpg-agent.c (main): Call assuan_set_assuan_err_source to have Assuan
|
* gpg-agent.c (main): Call assuan_set_assuan_err_source to have Assuan
|
||||||
switch to gpg-error codes.
|
switch to gpg-error codes.
|
||||||
* command.c (set_error): Adjusted.
|
* command.c (set_error): Adjusted.
|
||||||
@ -1412,7 +1419,7 @@
|
|||||||
|
|
||||||
* minip12.c (oid_pkcs_12_keyBag): New.
|
* minip12.c (oid_pkcs_12_keyBag): New.
|
||||||
(parse_bag_encrypted_data): New arg R_RESULT. Support keybags and
|
(parse_bag_encrypted_data): New arg R_RESULT. Support keybags and
|
||||||
return the key object.
|
return the key object.
|
||||||
(p12_parse): Take new arg into account. Free RESULT on error.
|
(p12_parse): Take new arg into account. Free RESULT on error.
|
||||||
|
|
||||||
2006-06-26 Werner Koch <wk@g10code.com>
|
2006-06-26 Werner Koch <wk@g10code.com>
|
||||||
@ -1480,7 +1487,7 @@
|
|||||||
* call-scd.c (inq_needpin): Reworked to support the new KEYPADINFO.
|
* call-scd.c (inq_needpin): Reworked to support the new KEYPADINFO.
|
||||||
|
|
||||||
* query.c (start_pinentry): Keep track of the owner.
|
* query.c (start_pinentry): Keep track of the owner.
|
||||||
(popup_message_thread, agent_popup_message_start)
|
(popup_message_thread, agent_popup_message_start)
|
||||||
(agent_popup_message_stop, agent_reset_query): New.
|
(agent_popup_message_stop, agent_reset_query): New.
|
||||||
* command.c (start_command_handler): Make sure a popup window gets
|
* command.c (start_command_handler): Make sure a popup window gets
|
||||||
closed.
|
closed.
|
||||||
@ -1531,7 +1538,7 @@
|
|||||||
|
|
||||||
2005-06-21 Werner Koch <wk@g10code.com>
|
2005-06-21 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* minip12.c (create_final): Cast size_t to ulong for printf.
|
* minip12.c (create_final): Cast size_t to ulong for printf.
|
||||||
(build_key_bag, build_cert_bag, build_cert_sequence): Ditto.
|
(build_key_bag, build_cert_bag, build_cert_sequence): Ditto.
|
||||||
|
|
||||||
2005-06-16 Werner Koch <wk@g10code.com>
|
2005-06-16 Werner Koch <wk@g10code.com>
|
||||||
@ -1546,7 +1553,7 @@
|
|||||||
* protect.c (do_encryption): Ditto.
|
* protect.c (do_encryption): Ditto.
|
||||||
(do_encryption): Made arg PROTBEGIN unsigned. Initialize RESULT
|
(do_encryption): Made arg PROTBEGIN unsigned. Initialize RESULT
|
||||||
and RESULTLEN even on error.
|
and RESULTLEN even on error.
|
||||||
(merge_lists): Need to cast unsigned char * for strcpy. Initialize
|
(merge_lists): Need to cast unsigned char * for strcpy. Initialize
|
||||||
RESULTand RESULTLEN even on error.
|
RESULTand RESULTLEN even on error.
|
||||||
(agent_unprotect): Likewise for strtoul.
|
(agent_unprotect): Likewise for strtoul.
|
||||||
(make_shadow_info): Made P and INFO plain char.
|
(make_shadow_info): Made P and INFO plain char.
|
||||||
@ -1606,7 +1613,7 @@
|
|||||||
* command.c (cmd_updatestartuptty): New.
|
* command.c (cmd_updatestartuptty): New.
|
||||||
|
|
||||||
* gpg-agent.c: New option --write-env-file.
|
* gpg-agent.c: New option --write-env-file.
|
||||||
|
|
||||||
* gpg-agent.c (handle_connections): Make sure that the signals we
|
* gpg-agent.c (handle_connections): Make sure that the signals we
|
||||||
are handling are not blocked.Block signals while creating new
|
are handling are not blocked.Block signals while creating new
|
||||||
threads.
|
threads.
|
||||||
@ -1876,8 +1883,8 @@
|
|||||||
(make_cstring): Ditto.
|
(make_cstring): Ditto.
|
||||||
(data_sign): Don't use a variable for the passphrase prompt, make
|
(data_sign): Don't use a variable for the passphrase prompt, make
|
||||||
it translatable.
|
it translatable.
|
||||||
(ssh_request_process):
|
(ssh_request_process):
|
||||||
|
|
||||||
|
|
||||||
* findkey.c (modify_description): Renamed arguments for clarity,
|
* findkey.c (modify_description): Renamed arguments for clarity,
|
||||||
polished documentation. Make comment a C-string. Fixed case of
|
polished documentation. Make comment a C-string. Fixed case of
|
||||||
@ -2003,7 +2010,7 @@
|
|||||||
2004-12-21 Werner Koch <wk@g10code.com>
|
2004-12-21 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* gpg-agent.c (main): Use default_homedir().
|
* gpg-agent.c (main): Use default_homedir().
|
||||||
* protect-tool.c (main): Ditto.
|
* protect-tool.c (main): Ditto.
|
||||||
|
|
||||||
2004-12-20 Werner Koch <wk@g10code.com>
|
2004-12-20 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
@ -2029,7 +2036,7 @@
|
|||||||
* query.c (initialize_module_query): New.
|
* query.c (initialize_module_query): New.
|
||||||
* call-scd.c (initialize_module_call_scd): New.
|
* call-scd.c (initialize_module_call_scd): New.
|
||||||
* gpg-agent.c (main): Call them.
|
* gpg-agent.c (main): Call them.
|
||||||
|
|
||||||
2004-12-18 Werner Koch <wk@g10code.com>
|
2004-12-18 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* gpg-agent.c (main): Remove special Pth initialize.
|
* gpg-agent.c (main): Remove special Pth initialize.
|
||||||
@ -2081,10 +2088,10 @@
|
|||||||
to Moritz for pointing this out.
|
to Moritz for pointing this out.
|
||||||
|
|
||||||
2004-09-25 Moritz Schulte <moritz@g10code.com>
|
2004-09-25 Moritz Schulte <moritz@g10code.com>
|
||||||
|
|
||||||
* agent.h: Declare: agent_pksign_do.
|
* agent.h: Declare: agent_pksign_do.
|
||||||
(struct server_control_s): New member: raw_value.
|
(struct server_control_s): New member: raw_value.
|
||||||
|
|
||||||
* pksign.c (do_encode_md): New argument: raw_value; support
|
* pksign.c (do_encode_md): New argument: raw_value; support
|
||||||
generation of raw (non-pkcs1) data objects; adjust callers.
|
generation of raw (non-pkcs1) data objects; adjust callers.
|
||||||
(agent_pksign_do): New function, based on code ripped
|
(agent_pksign_do): New function, based on code ripped
|
||||||
@ -2092,7 +2099,7 @@
|
|||||||
(agent_pksign): Use agent_pksign_do.
|
(agent_pksign): Use agent_pksign_do.
|
||||||
|
|
||||||
* command.c (start_command_handler): Set ctrl.digest.raw_value.
|
* command.c (start_command_handler): Set ctrl.digest.raw_value.
|
||||||
|
|
||||||
2004-09-09 Werner Koch <wk@g10code.de>
|
2004-09-09 Werner Koch <wk@g10code.de>
|
||||||
|
|
||||||
* gpg-agent.c (check_for_running_agent): New.
|
* gpg-agent.c (check_for_running_agent): New.
|
||||||
@ -2133,14 +2140,14 @@
|
|||||||
|
|
||||||
* gpg-agent.c (handle_signal): Reload the trustlist on SIGHUP.
|
* gpg-agent.c (handle_signal): Reload the trustlist on SIGHUP.
|
||||||
(start_connection_thread): Hack to simulate a ticker.
|
(start_connection_thread): Hack to simulate a ticker.
|
||||||
* trustlist.c (agent_trustlist_housekeeping)
|
* trustlist.c (agent_trustlist_housekeeping)
|
||||||
(agent_reload_trustlist): New. Protected all global functions
|
(agent_reload_trustlist): New. Protected all global functions
|
||||||
here with a simple counter which is sufficient for Pth.
|
here with a simple counter which is sufficient for Pth.
|
||||||
|
|
||||||
2004-05-03 Werner Koch <wk@gnupg.org>
|
2004-05-03 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* gpg-agent.c: Remove help texts for options lile --lc-ctype.
|
* gpg-agent.c: Remove help texts for options lile --lc-ctype.
|
||||||
(main): New option --allow-mark-trusted.
|
(main): New option --allow-mark-trusted.
|
||||||
* trustlist.c (agent_marktrusted): Use it here.
|
* trustlist.c (agent_marktrusted): Use it here.
|
||||||
|
|
||||||
2004-04-30 Werner Koch <wk@gnupg.org>
|
2004-04-30 Werner Koch <wk@gnupg.org>
|
||||||
@ -2213,7 +2220,7 @@
|
|||||||
string. Changed all callers.
|
string. Changed all callers.
|
||||||
|
|
||||||
* minip12.c: Revamped the build part.
|
* minip12.c: Revamped the build part.
|
||||||
(p12_build): New args CERT and CERTLEN.
|
(p12_build): New args CERT and CERTLEN.
|
||||||
|
|
||||||
2004-02-18 Werner Koch <wk@gnupg.org>
|
2004-02-18 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
@ -2307,7 +2314,7 @@
|
|||||||
|
|
||||||
* findkey.c (agent_key_from_file): Now return an error code so
|
* findkey.c (agent_key_from_file): Now return an error code so
|
||||||
that we have more detailed error messages in the upper layers.
|
that we have more detailed error messages in the upper layers.
|
||||||
This fixes the handling of pinentry's cancel button.
|
This fixes the handling of pinentry's cancel button.
|
||||||
* pksign.c (agent_pksign): Changed accordingly.
|
* pksign.c (agent_pksign): Changed accordingly.
|
||||||
* pkdecrypt.c (agent_pkdecrypt): Ditto.
|
* pkdecrypt.c (agent_pkdecrypt): Ditto.
|
||||||
* command.c (cmd_passwd): Ditto.
|
* command.c (cmd_passwd): Ditto.
|
||||||
@ -2334,12 +2341,12 @@
|
|||||||
|
|
||||||
* pksign.c (do_encode_md): Allocate enough space. Cast md
|
* pksign.c (do_encode_md): Allocate enough space. Cast md
|
||||||
byte to unsigned char to prevent sign extension.
|
byte to unsigned char to prevent sign extension.
|
||||||
|
|
||||||
2003-08-14 Timo Schulz <twoaday@freakmail.de>
|
2003-08-14 Timo Schulz <twoaday@freakmail.de>
|
||||||
|
|
||||||
* pksign.c (do_encode_md): Due to the fact pkcs#1 padding
|
* pksign.c (do_encode_md): Due to the fact pkcs#1 padding
|
||||||
is now in Libgcrypt, use the new interface.
|
is now in Libgcrypt, use the new interface.
|
||||||
|
|
||||||
2003-07-31 Werner Koch <wk@gnupg.org>
|
2003-07-31 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* Makefile.am (gpg_agent_LDADD): Added INTLLIBS.
|
* Makefile.am (gpg_agent_LDADD): Added INTLLIBS.
|
||||||
@ -2389,7 +2396,7 @@
|
|||||||
* gpg-agent.c (handle_connections): Adjusted for Pth 2.0
|
* gpg-agent.c (handle_connections): Adjusted for Pth 2.0
|
||||||
|
|
||||||
Adjusted for changes in the libgcrypt API. Some more fixes for the
|
Adjusted for changes in the libgcrypt API. Some more fixes for the
|
||||||
libgpg-error stuff.
|
libgpg-error stuff.
|
||||||
|
|
||||||
2003-06-04 Werner Koch <wk@gnupg.org>
|
2003-06-04 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
@ -2468,11 +2475,11 @@
|
|||||||
(agent_askpin,agent_get_passphrase,agent_get_confirmation): Add
|
(agent_askpin,agent_get_passphrase,agent_get_confirmation): Add
|
||||||
CTRL arg and pass it ot start_pinentry.
|
CTRL arg and pass it ot start_pinentry.
|
||||||
* command.c (cmd_get_passphrase): Pass CTRL argument.
|
* command.c (cmd_get_passphrase): Pass CTRL argument.
|
||||||
* trustlist.c (agent_marktrusted): Add CTRL argument
|
* trustlist.c (agent_marktrusted): Add CTRL argument
|
||||||
* command.c (cmd_marktrusted): Pass CTRL argument
|
* command.c (cmd_marktrusted): Pass CTRL argument
|
||||||
* divert-scd.c (ask_for_card): Add CTRL arg.
|
* divert-scd.c (ask_for_card): Add CTRL arg.
|
||||||
(divert_pksign,divert_pkdecrypt): Ditto. Changed caller.
|
(divert_pksign,divert_pkdecrypt): Ditto. Changed caller.
|
||||||
(getpin_cb): Use OPAQUE to pass the CTRL variable. Changed both
|
(getpin_cb): Use OPAQUE to pass the CTRL variable. Changed both
|
||||||
users.
|
users.
|
||||||
* findkey.c (unprotect): Add CTRL arg.
|
* findkey.c (unprotect): Add CTRL arg.
|
||||||
(agent_key_from_file): Ditto.
|
(agent_key_from_file): Ditto.
|
||||||
@ -2707,7 +2714,7 @@
|
|||||||
convert it to hex here.
|
convert it to hex here.
|
||||||
* findkey.c (agent_write_private_key): New.
|
* findkey.c (agent_write_private_key): New.
|
||||||
* genkey.c (store_key): And use it here.
|
* genkey.c (store_key): And use it here.
|
||||||
|
|
||||||
* pkdecrypt.c (agent_pkdecrypt): Changed the way the diversion is done.
|
* pkdecrypt.c (agent_pkdecrypt): Changed the way the diversion is done.
|
||||||
* divert-scd.c (divert_pkdecrypt): Changed interface and
|
* divert-scd.c (divert_pkdecrypt): Changed interface and
|
||||||
implemented it.
|
implemented it.
|
||||||
@ -2737,7 +2744,7 @@
|
|||||||
* protect.c (snext,sskip,smatch): Moved to
|
* protect.c (snext,sskip,smatch): Moved to
|
||||||
* sexp-parse.h: New file.
|
* sexp-parse.h: New file.
|
||||||
* divert-scd.c: New.
|
* divert-scd.c: New.
|
||||||
|
|
||||||
2002-02-27 Werner Koch <wk@gnupg.org>
|
2002-02-27 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* protect.c (agent_shadow_key): New.
|
* protect.c (agent_shadow_key): New.
|
||||||
@ -2765,7 +2772,7 @@
|
|||||||
|
|
||||||
* gpg-agent.c: New option --default-cache-ttl.
|
* gpg-agent.c: New option --default-cache-ttl.
|
||||||
* cache.c (agent_put_cache): Use it.
|
* cache.c (agent_put_cache): Use it.
|
||||||
|
|
||||||
* cache.c: Add a few debug outputs.
|
* cache.c: Add a few debug outputs.
|
||||||
|
|
||||||
* protect.c (agent_private_key_type): New.
|
* protect.c (agent_private_key_type): New.
|
||||||
@ -2773,10 +2780,10 @@
|
|||||||
* findkey.c (agent_key_from_file): Use it to decide whether we
|
* findkey.c (agent_key_from_file): Use it to decide whether we
|
||||||
have to unprotect a key.
|
have to unprotect a key.
|
||||||
(unprotect): Cache the passphrase.
|
(unprotect): Cache the passphrase.
|
||||||
|
|
||||||
* findkey.c (agent_key_from_file,agent_key_available): The key
|
* findkey.c (agent_key_from_file,agent_key_available): The key
|
||||||
files do now require a ".key" suffix to make a script's life
|
files do now require a ".key" suffix to make a script's life
|
||||||
easier.
|
easier.
|
||||||
* genkey.c (store_key): Ditto.
|
* genkey.c (store_key): Ditto.
|
||||||
|
|
||||||
2002-01-31 Werner Koch <wk@gnupg.org>
|
2002-01-31 Werner Koch <wk@gnupg.org>
|
||||||
@ -2784,11 +2791,11 @@
|
|||||||
* genkey.c (store_key): Protect the key.
|
* genkey.c (store_key): Protect the key.
|
||||||
(agent_genkey): Ask for the passphrase.
|
(agent_genkey): Ask for the passphrase.
|
||||||
* findkey.c (unprotect): Actually unprotect the key.
|
* findkey.c (unprotect): Actually unprotect the key.
|
||||||
* query.c (agent_askpin): Add an optional start_err_text.
|
* query.c (agent_askpin): Add an optional start_err_text.
|
||||||
|
|
||||||
2002-01-30 Werner Koch <wk@gnupg.org>
|
2002-01-30 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* protect.c: New.
|
* protect.c: New.
|
||||||
(hash_passphrase): Based on the GnuPG 1.0.6 version.
|
(hash_passphrase): Based on the GnuPG 1.0.6 version.
|
||||||
* protect-tool.c: New
|
* protect-tool.c: New
|
||||||
|
|
||||||
@ -2842,10 +2849,10 @@
|
|||||||
|
|
||||||
* command.c (rc_to_assuan_status): Removed and changed all callers
|
* command.c (rc_to_assuan_status): Removed and changed all callers
|
||||||
to use map_to_assuan_status.
|
to use map_to_assuan_status.
|
||||||
|
|
||||||
2001-12-19 Werner Koch <wk@gnupg.org>
|
2001-12-19 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* keyformat.txt: New.
|
* keyformat.txt: New.
|
||||||
|
|
||||||
2001-12-19 Marcus Brinkmann <marcus@g10code.de>
|
2001-12-19 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Helper to pass data via the callback to do_unprotect. */
|
/* Helper to pass data via the callback to do_unprotect. */
|
||||||
struct try_do_unprotect_arg_s
|
struct try_do_unprotect_arg_s
|
||||||
{
|
{
|
||||||
int is_v4;
|
int is_v4;
|
||||||
int is_protected;
|
int is_protected;
|
||||||
@ -87,10 +87,12 @@ get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip)
|
|||||||
"(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
|
"(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GCRY_PK_ECDSA:
|
case GCRY_PK_ECDSA:
|
||||||
case GCRY_PK_ECDH:
|
case GCRY_PK_ECDH:
|
||||||
err = gcry_sexp_build (&s_pkey, NULL,
|
err = gcry_sexp_build (&s_pkey, NULL,
|
||||||
"(public-key(ecc(c%m)(q%m)))", pkey[0], pkey[1]);
|
"(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))",
|
||||||
|
pkey[0], pkey[1], pkey[2], pkey[3], pkey[4],
|
||||||
|
pkey[5]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -108,8 +110,7 @@ get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip)
|
|||||||
|
|
||||||
/* Convert a secret key given as algorithm id and an array of key
|
/* Convert a secret key given as algorithm id and an array of key
|
||||||
parameters into our s-expression based format. Note that
|
parameters into our s-expression based format. Note that
|
||||||
PUBKEY_ALGO is a standard id and not an OpenPGP id.
|
PUBKEY_ALGO has an gcrypt algorithm number. */
|
||||||
*/
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
|
convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
|
||||||
{
|
{
|
||||||
@ -118,9 +119,6 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
|
|||||||
|
|
||||||
*r_key = NULL;
|
*r_key = NULL;
|
||||||
|
|
||||||
/* FIXME: This is not consistent with the above comment. */
|
|
||||||
pubkey_algo = map_pk_openpgp_to_gcry (pubkey_algo);
|
|
||||||
|
|
||||||
switch (pubkey_algo)
|
switch (pubkey_algo)
|
||||||
{
|
{
|
||||||
case GCRY_PK_DSA:
|
case GCRY_PK_DSA:
|
||||||
@ -147,15 +145,15 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GCRY_PK_ECDSA:
|
case GCRY_PK_ECDSA:
|
||||||
err = gcry_sexp_build (&s_skey, NULL,
|
|
||||||
"(private-key(ecdsa(c%m)(q%m)(d%m)))",
|
|
||||||
skey[0], skey[1], skey[2]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GCRY_PK_ECDH:
|
case GCRY_PK_ECDH:
|
||||||
|
/* Although our code would work with "ecc" we explicitly use
|
||||||
|
"ecdh" or "ecdsa" to implicitly set the key capabilities. */
|
||||||
err = gcry_sexp_build (&s_skey, NULL,
|
err = gcry_sexp_build (&s_skey, NULL,
|
||||||
"(private-key(ecdh(c%m)(q%m)(p%m)(d%m)))",
|
"(private-key(%s(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)"
|
||||||
skey[0], skey[1], skey[2], skey[3]);
|
"(d%m)))",
|
||||||
|
pubkey_algo == GCRY_PK_ECDSA?"ecdsa":"ecdh",
|
||||||
|
skey[0], skey[1], skey[2], skey[3], skey[4],
|
||||||
|
skey[5], skey[6]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -184,7 +182,7 @@ hash_passphrase_and_set_key (const char *passphrase,
|
|||||||
keylen = gcry_cipher_get_algo_keylen (protect_algo);
|
keylen = gcry_cipher_get_algo_keylen (protect_algo);
|
||||||
if (!keylen)
|
if (!keylen)
|
||||||
return gpg_error (GPG_ERR_INTERNAL);
|
return gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
|
||||||
key = xtrymalloc_secure (keylen);
|
key = xtrymalloc_secure (keylen);
|
||||||
if (!key)
|
if (!key)
|
||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
@ -204,7 +202,7 @@ static u16
|
|||||||
checksum (const unsigned char *p, unsigned int n)
|
checksum (const unsigned char *p, unsigned int n)
|
||||||
{
|
{
|
||||||
u16 a;
|
u16 a;
|
||||||
|
|
||||||
for (a=0; n; n-- )
|
for (a=0; n; n-- )
|
||||||
a += *p++;
|
a += *p++;
|
||||||
return a;
|
return a;
|
||||||
@ -272,7 +270,7 @@ do_unprotect (const char *passphrase,
|
|||||||
return gpg_error (GPG_ERR_MISSING_VALUE);
|
return gpg_error (GPG_ERR_MISSING_VALUE);
|
||||||
if (nskey+1 >= skeysize)
|
if (nskey+1 >= skeysize)
|
||||||
return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
|
return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
|
||||||
|
|
||||||
/* Check whether SKEY is at all protected. If it is not protected
|
/* Check whether SKEY is at all protected. If it is not protected
|
||||||
merely verify the checksum. */
|
merely verify the checksum. */
|
||||||
if (!is_protected)
|
if (!is_protected)
|
||||||
@ -284,7 +282,7 @@ do_unprotect (const char *passphrase,
|
|||||||
{
|
{
|
||||||
if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE))
|
if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE))
|
||||||
return gpg_error (GPG_ERR_BAD_SECKEY);
|
return gpg_error (GPG_ERR_BAD_SECKEY);
|
||||||
|
|
||||||
err = gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, skey[i]);
|
err = gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, skey[i]);
|
||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
@ -301,7 +299,7 @@ do_unprotect (const char *passphrase,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actual_csum != desired_csum)
|
if (actual_csum != desired_csum)
|
||||||
return gpg_error (GPG_ERR_CHECKSUM);
|
return gpg_error (GPG_ERR_CHECKSUM);
|
||||||
return 0;
|
return 0;
|
||||||
@ -324,7 +322,7 @@ do_unprotect (const char *passphrase,
|
|||||||
s2k_algo, gcry_md_algo_name (s2k_algo));
|
s2k_algo, gcry_md_algo_name (s2k_algo));
|
||||||
return gpg_error (GPG_ERR_DIGEST_ALGO);
|
return gpg_error (GPG_ERR_DIGEST_ALGO);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = gcry_cipher_open (&cipher_hd, protect_algo,
|
err = gcry_cipher_open (&cipher_hd, protect_algo,
|
||||||
GCRY_CIPHER_MODE_CFB,
|
GCRY_CIPHER_MODE_CFB,
|
||||||
(GCRY_CIPHER_SECURE
|
(GCRY_CIPHER_SECURE
|
||||||
@ -343,10 +341,10 @@ do_unprotect (const char *passphrase,
|
|||||||
{
|
{
|
||||||
gcry_cipher_close (cipher_hd);
|
gcry_cipher_close (cipher_hd);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
gcry_cipher_setiv (cipher_hd, protect_iv, protect_ivlen);
|
gcry_cipher_setiv (cipher_hd, protect_iv, protect_ivlen);
|
||||||
|
|
||||||
actual_csum = 0;
|
actual_csum = 0;
|
||||||
if (pkt_version >= 4)
|
if (pkt_version >= 4)
|
||||||
{
|
{
|
||||||
@ -379,15 +377,15 @@ do_unprotect (const char *passphrase,
|
|||||||
{
|
{
|
||||||
/* This is the new SHA1 checksum method to detect tampering
|
/* This is the new SHA1 checksum method to detect tampering
|
||||||
with the key as used by the Klima/Rosa attack. */
|
with the key as used by the Klima/Rosa attack. */
|
||||||
desired_csum = 0;
|
desired_csum = 0;
|
||||||
actual_csum = 1; /* Default to bad checksum. */
|
actual_csum = 1; /* Default to bad checksum. */
|
||||||
|
|
||||||
if (ndata < 20)
|
if (ndata < 20)
|
||||||
log_error ("not enough bytes for SHA-1 checksum\n");
|
log_error ("not enough bytes for SHA-1 checksum\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gcry_md_hd_t h;
|
gcry_md_hd_t h;
|
||||||
|
|
||||||
if (gcry_md_open (&h, GCRY_MD_SHA1, 1))
|
if (gcry_md_open (&h, GCRY_MD_SHA1, 1))
|
||||||
BUG(); /* Algo not available. */
|
BUG(); /* Algo not available. */
|
||||||
gcry_md_write (h, data, ndata - 20);
|
gcry_md_write (h, data, ndata - 20);
|
||||||
@ -397,13 +395,13 @@ do_unprotect (const char *passphrase,
|
|||||||
gcry_md_close (h);
|
gcry_md_close (h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Old 16 bit checksum method. */
|
/* Old 16 bit checksum method. */
|
||||||
if (ndata < 2)
|
if (ndata < 2)
|
||||||
{
|
{
|
||||||
log_error ("not enough bytes for checksum\n");
|
log_error ("not enough bytes for checksum\n");
|
||||||
desired_csum = 0;
|
desired_csum = 0;
|
||||||
actual_csum = 1; /* Mark checksum bad. */
|
actual_csum = 1; /* Mark checksum bad. */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -417,7 +415,7 @@ do_unprotect (const char *passphrase,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Better check it here. Otherwise the gcry_mpi_scan would fail
|
/* Better check it here. Otherwise the gcry_mpi_scan would fail
|
||||||
because the length may have an arbitrary value. */
|
because the length may have an arbitrary value. */
|
||||||
if (desired_csum == actual_csum)
|
if (desired_csum == actual_csum)
|
||||||
@ -468,7 +466,7 @@ do_unprotect (const char *passphrase,
|
|||||||
gcry_cipher_close (cipher_hd);
|
gcry_cipher_close (cipher_hd);
|
||||||
return gpg_error (GPG_ERR_BAD_SECKEY);
|
return gpg_error (GPG_ERR_BAD_SECKEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = xtrymalloc_secure (ndata);
|
buffer = xtrymalloc_secure (ndata);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
{
|
{
|
||||||
@ -476,7 +474,7 @@ do_unprotect (const char *passphrase,
|
|||||||
gcry_cipher_close (cipher_hd);
|
gcry_cipher_close (cipher_hd);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
gcry_cipher_sync (cipher_hd);
|
gcry_cipher_sync (cipher_hd);
|
||||||
buffer[0] = p[0];
|
buffer[0] = p[0];
|
||||||
buffer[1] = p[1];
|
buffer[1] = p[1];
|
||||||
@ -557,7 +555,7 @@ try_do_unprotect_cb (struct pin_entry_info_s *pi)
|
|||||||
pointed to by GRIP. On error NULL is stored at all return
|
pointed to by GRIP. On error NULL is stored at all return
|
||||||
arguments. */
|
arguments. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
||||||
unsigned char *grip, const char *prompt,
|
unsigned char *grip, const char *prompt,
|
||||||
const char *cache_nonce,
|
const char *cache_nonce,
|
||||||
unsigned char **r_key, char **r_passphrase)
|
unsigned char **r_key, char **r_passphrase)
|
||||||
@ -625,7 +623,7 @@ convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
|||||||
if (!protect_algo && !!strcmp (string, "IDEA"))
|
if (!protect_algo && !!strcmp (string, "IDEA"))
|
||||||
protect_algo = GCRY_CIPHER_IDEA;
|
protect_algo = GCRY_CIPHER_IDEA;
|
||||||
xfree (string);
|
xfree (string);
|
||||||
|
|
||||||
value = gcry_sexp_nth_data (list, 3, &valuelen);
|
value = gcry_sexp_nth_data (list, 3, &valuelen);
|
||||||
if (!value || !valuelen || valuelen > sizeof iv)
|
if (!value || !valuelen || valuelen > sizeof iv)
|
||||||
goto bad_seckey;
|
goto bad_seckey;
|
||||||
@ -848,7 +846,7 @@ convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
|
|||||||
bad_seckey:
|
bad_seckey:
|
||||||
err = gpg_error (GPG_ERR_BAD_SECKEY);
|
err = gpg_error (GPG_ERR_BAD_SECKEY);
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
outofmem:
|
outofmem:
|
||||||
err = gpg_error (GPG_ERR_ENOMEM);
|
err = gpg_error (GPG_ERR_ENOMEM);
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -874,13 +872,13 @@ key_from_sexp (gcry_sexp_t sexp, const char *elems, gcry_mpi_t *array)
|
|||||||
}
|
}
|
||||||
array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
|
array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
|
||||||
gcry_sexp_release (l2);
|
gcry_sexp_release (l2);
|
||||||
if (!array[idx])
|
if (!array[idx])
|
||||||
{
|
{
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ); /* Required parameter invalid. */
|
err = gpg_error (GPG_ERR_INV_OBJ); /* Required parameter invalid. */
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
@ -1028,7 +1026,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
|
|||||||
gcry_sexp_release (list);
|
gcry_sexp_release (list);
|
||||||
return gpg_error (GPG_ERR_INV_OBJ); /* Invalid structure of object. */
|
return gpg_error (GPG_ERR_INV_OBJ); /* Invalid structure of object. */
|
||||||
}
|
}
|
||||||
|
|
||||||
algo = gcry_pk_map_name (name);
|
algo = gcry_pk_map_name (name);
|
||||||
xfree (name);
|
xfree (name);
|
||||||
|
|
||||||
@ -1038,8 +1036,8 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
|
|||||||
case GCRY_PK_ELG: algoname = "elg"; npkey = 3; elems = "pgyx"; break;
|
case GCRY_PK_ELG: algoname = "elg"; npkey = 3; elems = "pgyx"; break;
|
||||||
case GCRY_PK_ELG_E: algoname = "elg"; npkey = 3; elems = "pgyx"; break;
|
case GCRY_PK_ELG_E: algoname = "elg"; npkey = 3; elems = "pgyx"; break;
|
||||||
case GCRY_PK_DSA: algoname = "dsa"; npkey = 4; elems = "pqgyx"; break;
|
case GCRY_PK_DSA: algoname = "dsa"; npkey = 4; elems = "pqgyx"; break;
|
||||||
case GCRY_PK_ECDSA: algoname = "ecdsa"; npkey = 2; elems = "cqd"; break;
|
case GCRY_PK_ECDSA: algoname = "ecdsa"; npkey = 6; elems = "pabgnqd"; break;
|
||||||
case GCRY_PK_ECDH: algoname = "ecdh"; npkey = 3; elems = "cqpd"; break;
|
case GCRY_PK_ECDH: algoname = "ecdh"; npkey = 6; elems = "pabgnqd"; break;
|
||||||
default: algoname = ""; npkey = 0; elems = NULL; break;
|
default: algoname = ""; npkey = 0; elems = NULL; break;
|
||||||
}
|
}
|
||||||
assert (!elems || strlen (elems) < DIM (array) );
|
assert (!elems || strlen (elems) < DIM (array) );
|
||||||
@ -1070,9 +1068,9 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
|
|||||||
void *format_args[10+2];
|
void *format_args[10+2];
|
||||||
size_t n;
|
size_t n;
|
||||||
gcry_sexp_t tmpkey, tmpsexp = NULL;
|
gcry_sexp_t tmpkey, tmpsexp = NULL;
|
||||||
|
|
||||||
snprintf (countbuf, sizeof countbuf, "%lu", s2k_count);
|
snprintf (countbuf, sizeof countbuf, "%lu", s2k_count);
|
||||||
|
|
||||||
init_membuf (&mbuf, 50);
|
init_membuf (&mbuf, 50);
|
||||||
put_membuf_str (&mbuf, "(skey");
|
put_membuf_str (&mbuf, "(skey");
|
||||||
for (i=j=0; i < npkey; i++)
|
for (i=j=0; i < npkey; i++)
|
||||||
@ -1105,7 +1103,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
|
|||||||
" %S\n"
|
" %S\n"
|
||||||
" (protection sha1 aes %b 1:3 sha1 %b %s))\n",
|
" (protection sha1 aes %b 1:3 sha1 %b %s))\n",
|
||||||
algoname,
|
algoname,
|
||||||
tmpkey,
|
tmpkey,
|
||||||
(int)sizeof protect_iv, protect_iv,
|
(int)sizeof protect_iv, protect_iv,
|
||||||
(int)sizeof salt, salt,
|
(int)sizeof salt, salt,
|
||||||
countbuf);
|
countbuf);
|
||||||
|
@ -42,6 +42,12 @@
|
|||||||
#ifndef GPG_ERR_FULLY_CANCELED
|
#ifndef GPG_ERR_FULLY_CANCELED
|
||||||
#define GPG_ERR_FULLY_CANCELED 198
|
#define GPG_ERR_FULLY_CANCELED 198
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef GPG_ERR_INV_CURVE
|
||||||
|
#define GPG_ERR_INV_CURVE 187
|
||||||
|
#endif
|
||||||
|
#ifndef GPG_ERR_UNKNOWN_CURVE
|
||||||
|
#define GPG_ERR_UNKNOWN_CURVE 188
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Hash function used with libksba. */
|
/* Hash function used with libksba. */
|
||||||
@ -75,10 +81,10 @@
|
|||||||
|
|
||||||
|
|
||||||
/* GCC attributes. */
|
/* GCC attributes. */
|
||||||
#if __GNUC__ >= 4
|
#if __GNUC__ >= 4
|
||||||
# define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a)))
|
# define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a)))
|
||||||
#else
|
#else
|
||||||
# define GNUPG_GCC_A_SENTINEL(a)
|
# define GNUPG_GCC_A_SENTINEL(a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -132,14 +138,14 @@ int answer_is_yes_no_quit (const char *s);
|
|||||||
int answer_is_okay_cancel (const char *s, int def_answer);
|
int answer_is_okay_cancel (const char *s, int def_answer);
|
||||||
|
|
||||||
/*-- xreadline.c --*/
|
/*-- xreadline.c --*/
|
||||||
ssize_t read_line (FILE *fp,
|
ssize_t read_line (FILE *fp,
|
||||||
char **addr_of_buffer, size_t *length_of_buffer,
|
char **addr_of_buffer, size_t *length_of_buffer,
|
||||||
size_t *max_length);
|
size_t *max_length);
|
||||||
|
|
||||||
|
|
||||||
/*-- b64enc.c and b64dec.c --*/
|
/*-- b64enc.c and b64dec.c --*/
|
||||||
struct b64state
|
struct b64state
|
||||||
{
|
{
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
int idx;
|
int idx;
|
||||||
int quad_count;
|
int quad_count;
|
||||||
@ -184,9 +190,9 @@ unsigned char *make_canon_sexp_from_rsa_pk (const void *m, size_t mlen,
|
|||||||
size_t *r_len);
|
size_t *r_len);
|
||||||
gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata,
|
gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata,
|
||||||
size_t keydatalen,
|
size_t keydatalen,
|
||||||
unsigned char const **r_n,
|
unsigned char const **r_n,
|
||||||
size_t *r_nlen,
|
size_t *r_nlen,
|
||||||
unsigned char const **r_e,
|
unsigned char const **r_e,
|
||||||
size_t *r_elen);
|
size_t *r_elen);
|
||||||
gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata,
|
gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata,
|
||||||
size_t keydatalen,
|
size_t keydatalen,
|
||||||
@ -231,7 +237,7 @@ const char *dirmngr_socket_name (void);
|
|||||||
gpgconf. */
|
gpgconf. */
|
||||||
#define GNUPG_MODULE_NAME_AGENT 1
|
#define GNUPG_MODULE_NAME_AGENT 1
|
||||||
#define GNUPG_MODULE_NAME_PINENTRY 2
|
#define GNUPG_MODULE_NAME_PINENTRY 2
|
||||||
#define GNUPG_MODULE_NAME_SCDAEMON 3
|
#define GNUPG_MODULE_NAME_SCDAEMON 3
|
||||||
#define GNUPG_MODULE_NAME_DIRMNGR 4
|
#define GNUPG_MODULE_NAME_DIRMNGR 4
|
||||||
#define GNUPG_MODULE_NAME_PROTECT_TOOL 5
|
#define GNUPG_MODULE_NAME_PROTECT_TOOL 5
|
||||||
#define GNUPG_MODULE_NAME_CHECK_PATTERN 6
|
#define GNUPG_MODULE_NAME_CHECK_PATTERN 6
|
||||||
@ -286,7 +292,7 @@ int gnupg_compare_version (const char *a, const char *b);
|
|||||||
#ifndef HAVE_TTYNAME
|
#ifndef HAVE_TTYNAME
|
||||||
/* Systems without ttyname (W32) will merely return NULL. */
|
/* Systems without ttyname (W32) will merely return NULL. */
|
||||||
static inline char *
|
static inline char *
|
||||||
ttyname (int fd)
|
ttyname (int fd)
|
||||||
{
|
{
|
||||||
(void)fd;
|
(void)fd;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
16
configure.ac
16
configure.ac
@ -742,6 +742,7 @@ AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION",
|
|||||||
AM_PATH_LIBGCRYPT("$NEED_LIBGCRYPT_API:$NEED_LIBGCRYPT_VERSION",
|
AM_PATH_LIBGCRYPT("$NEED_LIBGCRYPT_API:$NEED_LIBGCRYPT_VERSION",
|
||||||
have_libgcrypt=yes,have_libgcrypt=no)
|
have_libgcrypt=yes,have_libgcrypt=no)
|
||||||
|
|
||||||
|
# fixme: We can remove the next two checks if we require libgcrypt 1.5.
|
||||||
AC_CACHE_CHECK([whether Libgcrypt support ECDH], gnupg_cv_gcry_pk_ecdh,
|
AC_CACHE_CHECK([whether Libgcrypt support ECDH], gnupg_cv_gcry_pk_ecdh,
|
||||||
[ _gnupg_gcry_save_cflags=$CFLAGS
|
[ _gnupg_gcry_save_cflags=$CFLAGS
|
||||||
CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS"
|
CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS"
|
||||||
@ -756,6 +757,21 @@ if test "$gnupg_cv_gcry_pk_ecdh" = yes; then
|
|||||||
[Define if gcrypt.h has the enum value for ECDH.])
|
[Define if gcrypt.h has the enum value for ECDH.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether Libgcrypt has gcry_pk_get_curve],
|
||||||
|
gnupg_cv_gcry_pk_get_curve,
|
||||||
|
[ _gnupg_gcry_save_cflags=$CFLAGS
|
||||||
|
CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS"
|
||||||
|
AC_TRY_COMPILE(
|
||||||
|
[#include <gcrypt.h>],
|
||||||
|
[ return gcry_pk_get_curve (NULL, 0, NULL); ],
|
||||||
|
gnupg_cv_gcry_pk_get_curve=yes,
|
||||||
|
gnupg_cv_gcry_pk_get_curve=no)
|
||||||
|
CFLAGS=$_gnupg_gcry_save_cflags])
|
||||||
|
if test "$gnupg_cv_gcry_pk_get_curve" = yes; then
|
||||||
|
AC_DEFINE([HAVE_GCRY_PK_GET_CURVE], 1,
|
||||||
|
[Define if gcrypt.h has gcry_pk_get_curve.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# libassuan is used for IPC
|
# libassuan is used for IPC
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
2011-02-02 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* import.c (transfer_secret_keys): Make sure keyids are available.
|
||||||
|
|
||||||
|
* keyid.c (hash_public_key): Adjust for the ECC case.
|
||||||
|
|
||||||
|
2011-02-01 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* import.c (transfer_secret_keys): Implement ECC case.
|
||||||
|
|
||||||
|
* gpg.c (main): Call setup_libgcrypt_logging.
|
||||||
|
|
||||||
|
* keygen.c (gpg_curve_to_oid): New.
|
||||||
|
(ecckey_from_sexp): Factor curve name mapping out to new function.
|
||||||
|
|
||||||
2011-01-31 Werner Koch <wk@g10code.com>
|
2011-01-31 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* misc.c (make_flagged_int, openpgp_oid_from_str)
|
* misc.c (make_flagged_int, openpgp_oid_from_str)
|
||||||
|
81
g10/ecdh.c
81
g10/ecdh.c
@ -36,7 +36,7 @@ static const struct
|
|||||||
unsigned int qbits;
|
unsigned int qbits;
|
||||||
int openpgp_hash_id; /* KEK digest algorithm. */
|
int openpgp_hash_id; /* KEK digest algorithm. */
|
||||||
int openpgp_cipher_id; /* KEK cipher algorithm. */
|
int openpgp_cipher_id; /* KEK cipher algorithm. */
|
||||||
} kek_params_table[] =
|
} kek_params_table[] =
|
||||||
/* Note: Must be sorted by ascending values for QBITS. */
|
/* Note: Must be sorted by ascending values for QBITS. */
|
||||||
{
|
{
|
||||||
{ 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES },
|
{ 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES },
|
||||||
@ -60,8 +60,8 @@ pk_ecdh_default_params (unsigned int qbits)
|
|||||||
if (!kek_params)
|
if (!kek_params)
|
||||||
return NULL;
|
return NULL;
|
||||||
kek_params[0] = 3; /* Number of bytes to follow. */
|
kek_params[0] = 3; /* Number of bytes to follow. */
|
||||||
kek_params[1] = 1; /* Version for KDF+AESWRAP. */
|
kek_params[1] = 1; /* Version for KDF+AESWRAP. */
|
||||||
|
|
||||||
/* Search for matching KEK parameter. Defaults to the strongest
|
/* Search for matching KEK parameter. Defaults to the strongest
|
||||||
possible choices. Performance is not an issue here, only
|
possible choices. Performance is not an issue here, only
|
||||||
interoperability. */
|
interoperability. */
|
||||||
@ -78,7 +78,7 @@ pk_ecdh_default_params (unsigned int qbits)
|
|||||||
assert (i < DIM (kek_params_table));
|
assert (i < DIM (kek_params_table));
|
||||||
if (DBG_CIPHER)
|
if (DBG_CIPHER)
|
||||||
log_printhex ("ECDH KEK params are", kek_params, sizeof(kek_params) );
|
log_printhex ("ECDH KEK params are", kek_params, sizeof(kek_params) );
|
||||||
|
|
||||||
return gcry_mpi_set_opaque (NULL, kek_params, 4 * 8);
|
return gcry_mpi_set_opaque (NULL, kek_params, 4 * 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,16 +88,16 @@ pk_ecdh_default_params (unsigned int qbits)
|
|||||||
key_derivation+key_wrapping. If IS_ENCRYPT is true the function
|
key_derivation+key_wrapping. If IS_ENCRYPT is true the function
|
||||||
encrypts; if false, it decrypts. On success the result is stored
|
encrypts; if false, it decrypts. On success the result is stored
|
||||||
at R_RESULT; on failure NULL is stored at R_RESULT and an error
|
at R_RESULT; on failure NULL is stored at R_RESULT and an error
|
||||||
code returned.
|
code returned.
|
||||||
|
|
||||||
FIXME: explain PKEY and PK_FP.
|
FIXME: explain PKEY and PK_FP.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: memory leaks (x_secret).
|
TODO: memory leaks (x_secret).
|
||||||
*/
|
*/
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
||||||
const byte pk_fp[MAX_FINGERPRINT_LEN],
|
const byte pk_fp[MAX_FINGERPRINT_LEN],
|
||||||
gcry_mpi_t data, gcry_mpi_t *pkey,
|
gcry_mpi_t data, gcry_mpi_t *pkey,
|
||||||
gcry_mpi_t *r_result)
|
gcry_mpi_t *r_result)
|
||||||
@ -106,8 +106,8 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
byte *secret_x;
|
byte *secret_x;
|
||||||
int secret_x_size;
|
int secret_x_size;
|
||||||
unsigned int nbits;
|
unsigned int nbits;
|
||||||
const unsigned char *kdf_params;
|
const unsigned char *kek_params;
|
||||||
size_t kdf_params_size;
|
size_t kek_params_size;
|
||||||
int kdf_hash_algo;
|
int kdf_hash_algo;
|
||||||
int kdf_encr_algo;
|
int kdf_encr_algo;
|
||||||
unsigned char message[256];
|
unsigned char message[256];
|
||||||
@ -139,11 +139,11 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
secret_x_size = (nbits+7)/8;
|
secret_x_size = (nbits+7)/8;
|
||||||
assert (nbytes > secret_x_size);
|
assert (nbytes > secret_x_size);
|
||||||
memmove (secret_x, secret_x+1, secret_x_size);
|
memmove (secret_x, secret_x+1, secret_x_size);
|
||||||
memset (secret_x+secret_x_size, 0, nbytes-secret_x_size);
|
memset (secret_x+secret_x_size, 0, nbytes-secret_x_size);
|
||||||
|
|
||||||
if (DBG_CIPHER)
|
if (DBG_CIPHER)
|
||||||
log_printhex ("ECDH shared secret X is:", secret_x, secret_x_size );
|
log_printhex ("ECDH shared secret X is:", secret_x, secret_x_size );
|
||||||
}
|
}
|
||||||
@ -158,24 +158,24 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
*/
|
*/
|
||||||
if (!gcry_mpi_get_flag (pkey[2], GCRYMPI_FLAG_OPAQUE))
|
if (!gcry_mpi_get_flag (pkey[2], GCRYMPI_FLAG_OPAQUE))
|
||||||
return GPG_ERR_BUG;
|
return GPG_ERR_BUG;
|
||||||
kdf_params = gcry_mpi_get_opaque (pkey[2], &nbits);
|
kek_params = gcry_mpi_get_opaque (pkey[2], &nbits);
|
||||||
kdf_params_size = (nbits+7)/8;
|
kek_params_size = (nbits+7)/8;
|
||||||
|
|
||||||
if (DBG_CIPHER)
|
if (DBG_CIPHER)
|
||||||
log_printhex ("ecdh KDF params:", kdf_params, kdf_params_size);
|
log_printhex ("ecdh KDF params:", kek_params, kek_params_size);
|
||||||
|
|
||||||
/* Expect 4 bytes 03 01 hash_alg symm_alg. */
|
/* Expect 4 bytes 03 01 hash_alg symm_alg. */
|
||||||
if (kdf_params_size != 4 || kdf_params[0] != 3 || kdf_params[1] != 1)
|
if (kek_params_size != 4 || kek_params[0] != 3 || kek_params[1] != 1)
|
||||||
return GPG_ERR_BAD_PUBKEY;
|
return GPG_ERR_BAD_PUBKEY;
|
||||||
|
|
||||||
kdf_hash_algo = kdf_params[2];
|
kdf_hash_algo = kek_params[2];
|
||||||
kdf_encr_algo = kdf_params[3];
|
kdf_encr_algo = kek_params[3];
|
||||||
|
|
||||||
if (DBG_CIPHER)
|
if (DBG_CIPHER)
|
||||||
log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n",
|
log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n",
|
||||||
openpgp_md_algo_name (kdf_hash_algo),
|
openpgp_md_algo_name (kdf_hash_algo),
|
||||||
openpgp_cipher_algo_name (kdf_encr_algo));
|
openpgp_cipher_algo_name (kdf_encr_algo));
|
||||||
|
|
||||||
if (kdf_hash_algo != GCRY_MD_SHA256
|
if (kdf_hash_algo != GCRY_MD_SHA256
|
||||||
&& kdf_hash_algo != GCRY_MD_SHA384
|
&& kdf_hash_algo != GCRY_MD_SHA384
|
||||||
&& kdf_hash_algo != GCRY_MD_SHA512)
|
&& kdf_hash_algo != GCRY_MD_SHA512)
|
||||||
@ -199,7 +199,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
/* fixed-length field 4 */
|
/* fixed-length field 4 */
|
||||||
iobuf_write (obuf, "Anonymous Sender ", 20);
|
iobuf_write (obuf, "Anonymous Sender ", 20);
|
||||||
/* fixed-length field 5, recipient fp */
|
/* fixed-length field 5, recipient fp */
|
||||||
iobuf_write (obuf, pk_fp, 20);
|
iobuf_write (obuf, pk_fp, 20);
|
||||||
|
|
||||||
message_size = iobuf_temp_to_buffer (obuf, message, sizeof message);
|
message_size = iobuf_temp_to_buffer (obuf, message, sizeof message);
|
||||||
iobuf_close (obuf);
|
iobuf_close (obuf);
|
||||||
@ -207,11 +207,10 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
return err;
|
return err;
|
||||||
|
|
||||||
if(DBG_CIPHER)
|
if(DBG_CIPHER)
|
||||||
log_printhex ("ecdh KDF message params are:",
|
log_printhex ("ecdh KDF message params are:", message, message_size);
|
||||||
kdf_params, kdf_params_size );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive a KEK (key wrapping key) using kdf_params and secret_x. */
|
/* Derive a KEK (key wrapping key) using MESSAGE and SECRET_X. */
|
||||||
{
|
{
|
||||||
gcry_md_hd_t h;
|
gcry_md_hd_t h;
|
||||||
int old_size;
|
int old_size;
|
||||||
@ -222,7 +221,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
kdf_hash_algo, gpg_strerror (err));
|
kdf_hash_algo, gpg_strerror (err));
|
||||||
gcry_md_write(h, "\x00\x00\x00\x01", 4); /* counter = 1 */
|
gcry_md_write(h, "\x00\x00\x00\x01", 4); /* counter = 1 */
|
||||||
gcry_md_write(h, secret_x, secret_x_size); /* x of the point X */
|
gcry_md_write(h, secret_x, secret_x_size); /* x of the point X */
|
||||||
gcry_md_write(h, kdf_params, kdf_params_size);/* KDF parameters */
|
gcry_md_write(h, message, message_size);/* KDF parameters */
|
||||||
|
|
||||||
gcry_md_final (h);
|
gcry_md_final (h);
|
||||||
|
|
||||||
@ -242,7 +241,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
if (DBG_CIPHER)
|
if (DBG_CIPHER)
|
||||||
log_printhex ("ecdh KEK is:", secret_x, secret_x_size );
|
log_printhex ("ecdh KEK is:", secret_x, secret_x_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And, finally, aeswrap with key secret_x. */
|
/* And, finally, aeswrap with key secret_x. */
|
||||||
{
|
{
|
||||||
gcry_cipher_hd_t hd;
|
gcry_cipher_hd_t hd;
|
||||||
@ -284,7 +283,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
if (is_encrypt)
|
if (is_encrypt)
|
||||||
{
|
{
|
||||||
byte *in = data_buf+1+data_buf_size+8;
|
byte *in = data_buf+1+data_buf_size+8;
|
||||||
|
|
||||||
/* Write data MPI into the end of data_buf. data_buf is size
|
/* Write data MPI into the end of data_buf. data_buf is size
|
||||||
aeswrap data. */
|
aeswrap data. */
|
||||||
err = gcry_mpi_print (GCRYMPI_FMT_USG, in,
|
err = gcry_mpi_print (GCRYMPI_FMT_USG, in,
|
||||||
@ -296,7 +295,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
xfree (data_buf);
|
xfree (data_buf);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DBG_CIPHER)
|
if (DBG_CIPHER)
|
||||||
log_printhex ("ecdh encrypting :", in, data_buf_size );
|
log_printhex ("ecdh encrypting :", in, data_buf_size );
|
||||||
|
|
||||||
@ -325,14 +324,14 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
*r_result = result;
|
*r_result = result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
byte *in;
|
byte *in;
|
||||||
const void *p;
|
const void *p;
|
||||||
|
|
||||||
p = gcry_mpi_get_opaque (data, &nbits);
|
p = gcry_mpi_get_opaque (data, &nbits);
|
||||||
nbytes = (nbits+7)/8;
|
nbytes = (nbits+7)/8;
|
||||||
if (!p || nbytes > data_buf_size || !nbytes)
|
if (!p || nbytes > data_buf_size || !nbytes)
|
||||||
@ -349,10 +348,10 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
}
|
}
|
||||||
in = data_buf+data_buf_size;
|
in = data_buf+data_buf_size;
|
||||||
data_buf_size = data_buf[0];
|
data_buf_size = data_buf[0];
|
||||||
|
|
||||||
if (DBG_CIPHER)
|
if (DBG_CIPHER)
|
||||||
log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size);
|
log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size);
|
||||||
|
|
||||||
err = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1,
|
err = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1,
|
||||||
data_buf_size);
|
data_buf_size);
|
||||||
gcry_cipher_close (hd);
|
gcry_cipher_close (hd);
|
||||||
@ -363,12 +362,12 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
xfree (data_buf);
|
xfree (data_buf);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_buf_size -= 8;
|
data_buf_size -= 8;
|
||||||
|
|
||||||
if (DBG_CIPHER)
|
if (DBG_CIPHER)
|
||||||
log_printhex ("ecdh decrypted to :", in, data_buf_size);
|
log_printhex ("ecdh decrypted to :", in, data_buf_size);
|
||||||
|
|
||||||
/* Padding is removed later. */
|
/* Padding is removed later. */
|
||||||
/* if (in[data_buf_size-1] > 8 ) */
|
/* if (in[data_buf_size-1] > 8 ) */
|
||||||
/* { */
|
/* { */
|
||||||
@ -376,7 +375,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
/* in[data_buf_size-1] ); */
|
/* in[data_buf_size-1] ); */
|
||||||
/* return GPG_ERR_BAD_KEY; */
|
/* return GPG_ERR_BAD_KEY; */
|
||||||
/* } */
|
/* } */
|
||||||
|
|
||||||
err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, in, data_buf_size, NULL);
|
err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, in, data_buf_size, NULL);
|
||||||
xfree (data_buf);
|
xfree (data_buf);
|
||||||
if (err)
|
if (err)
|
||||||
@ -385,11 +384,11 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
*r_result = result;
|
*r_result = result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,5 +452,3 @@ pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN],
|
|||||||
sk_fp, data/*encr data as an MPI*/,
|
sk_fp, data/*encr data as an MPI*/,
|
||||||
skey, result);
|
skey, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
148
g10/export.c
148
g10/export.c
@ -107,7 +107,7 @@ export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users,
|
|||||||
kbnode_t *keyblock_out, unsigned int options )
|
kbnode_t *keyblock_out, unsigned int options )
|
||||||
{
|
{
|
||||||
int any, rc;
|
int any, rc;
|
||||||
|
|
||||||
rc = do_export_stream (ctrl, out, users, 0, keyblock_out, options, &any);
|
rc = do_export_stream (ctrl, out, users, 0, keyblock_out, options, &any);
|
||||||
if (!rc && !any)
|
if (!rc && !any)
|
||||||
rc = -1;
|
rc = -1;
|
||||||
@ -197,9 +197,9 @@ do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options )
|
|||||||
int any, rc;
|
int any, rc;
|
||||||
armor_filter_context_t *afx = NULL;
|
armor_filter_context_t *afx = NULL;
|
||||||
compress_filter_context_t zfx;
|
compress_filter_context_t zfx;
|
||||||
|
|
||||||
memset( &zfx, 0, sizeof zfx);
|
memset( &zfx, 0, sizeof zfx);
|
||||||
|
|
||||||
rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, &out );
|
rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, &out );
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
@ -251,7 +251,7 @@ subkey_in_list_p (subkey_list_t list, KBNODE node)
|
|||||||
u32 kid[2];
|
u32 kid[2];
|
||||||
|
|
||||||
keyid_from_pk (node->pkt->pkt.public_key, kid);
|
keyid_from_pk (node->pkt->pkt.public_key, kid);
|
||||||
|
|
||||||
for (; list; list = list->next)
|
for (; list; list = list->next)
|
||||||
if (list->kid[0] == kid[0] && list->kid[1] == kid[1])
|
if (list->kid[0] == kid[0] && list->kid[1] == kid[1])
|
||||||
return 1;
|
return 1;
|
||||||
@ -293,17 +293,17 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
|
|||||||
case KEYDB_SEARCH_MODE_LONG_KID:
|
case KEYDB_SEARCH_MODE_LONG_KID:
|
||||||
keyid_from_pk (node->pkt->pkt.public_key, kid);
|
keyid_from_pk (node->pkt->pkt.public_key, kid);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEYDB_SEARCH_MODE_FPR16:
|
case KEYDB_SEARCH_MODE_FPR16:
|
||||||
case KEYDB_SEARCH_MODE_FPR20:
|
case KEYDB_SEARCH_MODE_FPR20:
|
||||||
case KEYDB_SEARCH_MODE_FPR:
|
case KEYDB_SEARCH_MODE_FPR:
|
||||||
fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen);
|
fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(desc->mode)
|
switch(desc->mode)
|
||||||
{
|
{
|
||||||
case KEYDB_SEARCH_MODE_SHORT_KID:
|
case KEYDB_SEARCH_MODE_SHORT_KID:
|
||||||
@ -346,7 +346,7 @@ canon_pubkey_algo (int algo)
|
|||||||
case GCRY_PK_RSA:
|
case GCRY_PK_RSA:
|
||||||
case GCRY_PK_RSA_E:
|
case GCRY_PK_RSA_E:
|
||||||
case GCRY_PK_RSA_S: return GCRY_PK_RSA;
|
case GCRY_PK_RSA_S: return GCRY_PK_RSA;
|
||||||
case GCRY_PK_ELG:
|
case GCRY_PK_ELG:
|
||||||
case GCRY_PK_ELG_E: return GCRY_PK_ELG;
|
case GCRY_PK_ELG_E: return GCRY_PK_ELG;
|
||||||
default: return algo;
|
default: return algo;
|
||||||
}
|
}
|
||||||
@ -354,7 +354,7 @@ canon_pubkey_algo (int algo)
|
|||||||
|
|
||||||
|
|
||||||
/* Use the key transfer format given in S_PGP to create the secinfo
|
/* Use the key transfer format given in S_PGP to create the secinfo
|
||||||
structure in PK and chnage the parameter array in PK to include the
|
structure in PK and change the parameter array in PK to include the
|
||||||
secret parameters. */
|
secret parameters. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
|
transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
|
||||||
@ -415,7 +415,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
|
|||||||
goto bad_seckey;
|
goto bad_seckey;
|
||||||
protect_algo = gcry_cipher_map_name (string);
|
protect_algo = gcry_cipher_map_name (string);
|
||||||
xfree (string);
|
xfree (string);
|
||||||
|
|
||||||
value = gcry_sexp_nth_data (list, 3, &valuelen);
|
value = gcry_sexp_nth_data (list, 3, &valuelen);
|
||||||
if (!value || !valuelen || valuelen > sizeof iv)
|
if (!value || !valuelen || valuelen > sizeof iv)
|
||||||
goto bad_seckey;
|
goto bad_seckey;
|
||||||
@ -460,6 +460,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
|
|||||||
|| gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey)
|
|| gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey)
|
||||||
|| !npkey || npkey >= nskey || nskey > PUBKEY_MAX_NSKEY)
|
|| !npkey || npkey >= nskey || nskey > PUBKEY_MAX_NSKEY)
|
||||||
goto bad_seckey;
|
goto bad_seckey;
|
||||||
|
pubkey_algo = map_pk_gcry_to_openpgp (pubkey_algo);
|
||||||
|
|
||||||
gcry_sexp_release (list);
|
gcry_sexp_release (list);
|
||||||
list = gcry_sexp_find_token (top_list, "skey", 0);
|
list = gcry_sexp_find_token (top_list, "skey", 0);
|
||||||
@ -557,6 +558,77 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We need to change the received parameters for ECC algorithms.
|
||||||
|
The transfer format has all parameters but OpenPGP defines that
|
||||||
|
only the OID of the curve is to be used. */
|
||||||
|
if (pubkey_algo == PUBKEY_ALGO_ECDSA || pubkey_algo == PUBKEY_ALGO_ECDH)
|
||||||
|
{
|
||||||
|
gcry_sexp_t s_pubkey;
|
||||||
|
const char *curvename, *curveoidstr;
|
||||||
|
gcry_mpi_t mpi;
|
||||||
|
|
||||||
|
/* We build an S-expression with the public key parameters and
|
||||||
|
ask Libgcrypt to return the matching curve name. */
|
||||||
|
if (npkey != 6 || !skey[0] || !skey[1] || !skey[2]
|
||||||
|
|| !skey[3] || !skey[4] || !skey[5]
|
||||||
|
|| !skey[6] || skey[7])
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
err = gcry_sexp_build (&s_pubkey, NULL,
|
||||||
|
"(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))",
|
||||||
|
skey[0], skey[1], skey[2], skey[3], skey[4]);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
#ifdef HAVE_GCRY_PK_GET_CURVE
|
||||||
|
curvename = gcry_pk_get_curve (s_pubkey, 0, NULL);
|
||||||
|
#else
|
||||||
|
curvename = "?";
|
||||||
|
#endif
|
||||||
|
gcry_sexp_release (s_pubkey);
|
||||||
|
curveoidstr = gpg_curve_to_oid (curvename, NULL);
|
||||||
|
if (!curveoidstr)
|
||||||
|
{
|
||||||
|
log_error ("no OID known for curve `%s'\n", curvename);
|
||||||
|
err = gpg_error (GPG_ERR_UNKNOWN_NAME);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
err = openpgp_oid_from_str (curveoidstr, &mpi);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
/* Now replace the curve parameters by the OID and shift the
|
||||||
|
rest of the parameters. */
|
||||||
|
gcry_mpi_release (skey[0]);
|
||||||
|
skey[0] = mpi;
|
||||||
|
for (idx=1; idx <= 4; idx++)
|
||||||
|
gcry_mpi_release (skey[idx]);
|
||||||
|
skey[1] = skey[5];
|
||||||
|
skey[2] = skey[6];
|
||||||
|
for (idx=3; idx <= 6; idx++)
|
||||||
|
skey[idx] = NULL;
|
||||||
|
|
||||||
|
/* Fixup the NPKEY and NSKEY to match OpenPGP reality. */
|
||||||
|
npkey = 2;
|
||||||
|
nskey = 3;
|
||||||
|
|
||||||
|
/* for (idx=0; skey[idx]; idx++) */
|
||||||
|
/* { */
|
||||||
|
/* log_info ("YYY skey[%d]:", idx); */
|
||||||
|
/* if (gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE)) */
|
||||||
|
/* { */
|
||||||
|
/* void *p; */
|
||||||
|
/* unsigned int nbits; */
|
||||||
|
/* p = gcry_mpi_get_opaque (skey[idx], &nbits); */
|
||||||
|
/* log_printhex (NULL, p, (nbits+7)/8); */
|
||||||
|
/* } */
|
||||||
|
/* else */
|
||||||
|
/* gcry_mpi_dump (skey[idx]); */
|
||||||
|
/* log_printf ("\n"); */
|
||||||
|
/* } */
|
||||||
|
}
|
||||||
|
|
||||||
/* Do some sanity checks. */
|
/* Do some sanity checks. */
|
||||||
if (s2k_count <= 1024)
|
if (s2k_count <= 1024)
|
||||||
{
|
{
|
||||||
@ -576,11 +648,17 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
|
|||||||
err = openpgp_md_test_algo (s2k_algo);
|
err = openpgp_md_test_algo (s2k_algo);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
/* Check that the public key parameters match. */
|
/* Check that the public key parameters match. Since Libgcrypt 1.5
|
||||||
|
and the gcry_pk_get_curve function, gcry_mpi_cmp handles opaque
|
||||||
|
MPI correctly and thus we don't need to to do the extra
|
||||||
|
opaqueness checks. */
|
||||||
for (idx=0; idx < npkey; idx++)
|
for (idx=0; idx < npkey; idx++)
|
||||||
if (gcry_mpi_get_flag (pk->pkey[idx], GCRYMPI_FLAG_OPAQUE)
|
if (0
|
||||||
|
#ifndef HAVE_GCRY_PK_GET_CURVE
|
||||||
|
gcry_mpi_get_flag (pk->pkey[idx], GCRYMPI_FLAG_OPAQUE)
|
||||||
|| gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE)
|
|| gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE)
|
||||||
|
#endif
|
||||||
|| gcry_mpi_cmp (pk->pkey[idx], skey[idx]))
|
|| gcry_mpi_cmp (pk->pkey[idx], skey[idx]))
|
||||||
{
|
{
|
||||||
err = gpg_error (GPG_ERR_BAD_PUBKEY);
|
err = gpg_error (GPG_ERR_BAD_PUBKEY);
|
||||||
@ -607,7 +685,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
|
|||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
ski->is_protected = 1;
|
ski->is_protected = 1;
|
||||||
ski->sha1chk = 1;
|
ski->sha1chk = 1;
|
||||||
ski->algo = protect_algo;
|
ski->algo = protect_algo;
|
||||||
@ -636,7 +714,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
|
|||||||
bad_seckey:
|
bad_seckey:
|
||||||
err = gpg_error (GPG_ERR_BAD_SECKEY);
|
err = gpg_error (GPG_ERR_BAD_SECKEY);
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
outofmem:
|
outofmem:
|
||||||
err = gpg_error (GPG_ERR_ENOMEM);
|
err = gpg_error (GPG_ERR_ENOMEM);
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -671,7 +749,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
init_packet (&pkt);
|
init_packet (&pkt);
|
||||||
kdbhd = keydb_new ();
|
kdbhd = keydb_new ();
|
||||||
|
|
||||||
if (!users)
|
if (!users)
|
||||||
{
|
{
|
||||||
ndesc = 1;
|
ndesc = 1;
|
||||||
desc = xcalloc (ndesc, sizeof *desc);
|
desc = xcalloc (ndesc, sizeof *desc);
|
||||||
@ -679,10 +757,10 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
|
for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
|
||||||
;
|
;
|
||||||
desc = xmalloc ( ndesc * sizeof *desc);
|
desc = xmalloc ( ndesc * sizeof *desc);
|
||||||
|
|
||||||
for (ndesc=0, sl=users; sl; sl = sl->next)
|
for (ndesc=0, sl=users; sl; sl = sl->next)
|
||||||
{
|
{
|
||||||
if (!(err=classify_user_id (sl->d, desc+ndesc)))
|
if (!(err=classify_user_id (sl->d, desc+ndesc)))
|
||||||
@ -708,7 +786,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For secret key export we need to setup a decryption context. */
|
/* For secret key export we need to setup a decryption context. */
|
||||||
if (secret)
|
if (secret)
|
||||||
{
|
{
|
||||||
@ -721,7 +799,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
log_error ("error getting the KEK: %s\n", gpg_strerror (err));
|
log_error ("error getting the KEK: %s\n", gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare a cipher context. */
|
/* Prepare a cipher context. */
|
||||||
err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
|
err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
|
||||||
GCRY_CIPHER_MODE_AESWRAP, 0);
|
GCRY_CIPHER_MODE_AESWRAP, 0);
|
||||||
@ -737,20 +815,20 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
kek = NULL;
|
kek = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!(err = keydb_search2 (kdbhd, desc, ndesc, &descindex)))
|
while (!(err = keydb_search2 (kdbhd, desc, ndesc, &descindex)))
|
||||||
{
|
{
|
||||||
int skip_until_subkey = 0;
|
int skip_until_subkey = 0;
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
PKT_public_key *pk;
|
PKT_public_key *pk;
|
||||||
|
|
||||||
if (!users)
|
if (!users)
|
||||||
desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
|
desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
|
||||||
|
|
||||||
/* Read the keyblock. */
|
/* Read the keyblock. */
|
||||||
release_kbnode (keyblock);
|
release_kbnode (keyblock);
|
||||||
keyblock = NULL;
|
keyblock = NULL;
|
||||||
err = keydb_get_keyblock (kdbhd, &keyblock);
|
err = keydb_get_keyblock (kdbhd, &keyblock);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
|
log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -802,7 +880,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL);
|
clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL);
|
||||||
|
|
||||||
/* And write it. */
|
/* And write it. */
|
||||||
for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
|
for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
|
||||||
{
|
{
|
||||||
if (skip_until_subkey)
|
if (skip_until_subkey)
|
||||||
{
|
{
|
||||||
@ -835,7 +913,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
subkey and include that subkey into the output
|
subkey and include that subkey into the output
|
||||||
too. Need to add this subkey to a list so that
|
too. Need to add this subkey to a list so that
|
||||||
it won't get processed a second time.
|
it won't get processed a second time.
|
||||||
|
|
||||||
So the first step here is to check that list and
|
So the first step here is to check that list and
|
||||||
skip in any case if the key is in that list.
|
skip in any case if the key is in that list.
|
||||||
|
|
||||||
@ -843,7 +921,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
function of GnuPG < 2.1 is not able to merge
|
function of GnuPG < 2.1 is not able to merge
|
||||||
secret keys and thus it is useless to output them
|
secret keys and thus it is useless to output them
|
||||||
as two separate keys and have import merge them. */
|
as two separate keys and have import merge them. */
|
||||||
if (subkey_in_list_p (subkey_list, node))
|
if (subkey_in_list_p (subkey_list, node))
|
||||||
skip_until_subkey = 1; /* Already processed this one. */
|
skip_until_subkey = 1; /* Already processed this one. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -854,7 +932,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
&& exact_subkey_match_p (desc+j, node))
|
&& exact_subkey_match_p (desc+j, node))
|
||||||
break;
|
break;
|
||||||
if (!(j < ndesc))
|
if (!(j < ndesc))
|
||||||
skip_until_subkey = 1; /* No other one matching. */
|
skip_until_subkey = 1; /* No other one matching. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -885,7 +963,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
&& node->pkt->pkt.signature->revkey)
|
&& node->pkt->pkt.signature->revkey)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
|
for (i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
|
||||||
if ( (node->pkt->pkt.signature->revkey[i]->class & 0x40))
|
if ( (node->pkt->pkt.signature->revkey[i]->class & 0x40))
|
||||||
break;
|
break;
|
||||||
@ -904,7 +982,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
or a signature on an attrib */
|
or a signature on an attrib */
|
||||||
while (kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE)
|
while (kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE)
|
||||||
kbctx = kbctx->next;
|
kbctx = kbctx->next;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -913,7 +991,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
{
|
{
|
||||||
u32 subkidbuf[2], *subkid;
|
u32 subkidbuf[2], *subkid;
|
||||||
char *hexgrip, *serialno;
|
char *hexgrip, *serialno;
|
||||||
|
|
||||||
pk = node->pkt->pkt.public_key;
|
pk = node->pkt->pkt.public_key;
|
||||||
if (node->pkt->pkttype == PKT_PUBLIC_KEY)
|
if (node->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||||
subkid = NULL;
|
subkid = NULL;
|
||||||
@ -930,7 +1008,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
skip_until_subkey = 1;
|
skip_until_subkey = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = hexkeygrip_from_pk (pk, &hexgrip);
|
err = hexkeygrip_from_pk (pk, &hexgrip);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
@ -970,7 +1048,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
/* Create a key stub. */
|
/* Create a key stub. */
|
||||||
struct seckey_info *ski;
|
struct seckey_info *ski;
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
|
pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
|
||||||
if (!ski)
|
if (!ski)
|
||||||
{
|
{
|
||||||
@ -989,7 +1067,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
ski->ivlen++, s += 2)
|
ski->ivlen++, s += 2)
|
||||||
ski->iv[ski->ivlen] = xtoi_2 (s);
|
ski->iv[ski->ivlen] = xtoi_2 (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((options&EXPORT_SEXP_FORMAT))
|
if ((options&EXPORT_SEXP_FORMAT))
|
||||||
err = build_sexp (out, node->pkt, &indent);
|
err = build_sexp (out, node->pkt, &indent);
|
||||||
else
|
else
|
||||||
@ -1032,7 +1110,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
|
realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
|
||||||
if (!realkeylen)
|
if (!realkeylen)
|
||||||
goto unwraperror; /* Invalid csexp. */
|
goto unwraperror; /* Invalid csexp. */
|
||||||
|
|
||||||
err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen);
|
err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen);
|
||||||
xfree (key);
|
xfree (key);
|
||||||
key = NULL;
|
key = NULL;
|
||||||
@ -1252,7 +1330,7 @@ build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent)
|
|||||||
|
|
||||||
/* For some packet types we write them in a S-expression format. This
|
/* For some packet types we write them in a S-expression format. This
|
||||||
is still EXPERIMENTAL and subject to change. */
|
is still EXPERIMENTAL and subject to change. */
|
||||||
static int
|
static int
|
||||||
build_sexp (iobuf_t out, PACKET *pkt, int *indent)
|
build_sexp (iobuf_t out, PACKET *pkt, int *indent)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -1959,6 +1959,9 @@ main (int argc, char **argv)
|
|||||||
NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
|
NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Use our own logging handler for Libcgrypt. */
|
||||||
|
setup_libgcrypt_logging ();
|
||||||
|
|
||||||
/* Put random number into secure memory */
|
/* Put random number into secure memory */
|
||||||
gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
|
gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
|
||||||
|
|
||||||
|
252
g10/import.c
252
g10/import.c
@ -1,6 +1,6 @@
|
|||||||
/* import.c - import a key into our key storage.
|
/* import.c - import a key into our key storage.
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||||
* 2007, 2010 Free Software Foundation, Inc.
|
* 2007, 2010, 2011 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -200,7 +200,7 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames,
|
|||||||
rc = import (ctrl, inp2, fname, stats, fpr, fpr_len, options);
|
rc = import (ctrl, inp2, fname, stats, fpr, fpr_len, options);
|
||||||
iobuf_close(inp2);
|
iobuf_close(inp2);
|
||||||
/* Must invalidate that ugly cache to actually close it. */
|
/* Must invalidate that ugly cache to actually close it. */
|
||||||
iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE,
|
iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE,
|
||||||
0, (char*)fname);
|
0, (char*)fname);
|
||||||
if( rc )
|
if( rc )
|
||||||
log_error("import from `%s' failed: %s\n", fname,
|
log_error("import from `%s' failed: %s\n", fname,
|
||||||
@ -294,7 +294,7 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct stats_s *stats,
|
|||||||
if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY )
|
if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY )
|
||||||
rc = import_one (ctrl, fname, keyblock,
|
rc = import_one (ctrl, fname, keyblock,
|
||||||
stats, fpr, fpr_len, options, 0);
|
stats, fpr, fpr_len, options, 0);
|
||||||
else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
|
else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
|
||||||
rc = import_secret_one (ctrl, fname, keyblock, stats, options);
|
rc = import_secret_one (ctrl, fname, keyblock, stats, options);
|
||||||
else if( keyblock->pkt->pkttype == PKT_SIGNATURE
|
else if( keyblock->pkt->pkttype == PKT_SIGNATURE
|
||||||
&& keyblock->pkt->pkt.signature->sig_class == 0x20 )
|
&& keyblock->pkt->pkt.signature->sig_class == 0x20 )
|
||||||
@ -647,7 +647,7 @@ check_prefs (ctrl_t ctrl, kbnode_t keyblock)
|
|||||||
kbnode_t node;
|
kbnode_t node;
|
||||||
PKT_public_key *pk;
|
PKT_public_key *pk;
|
||||||
int problem=0;
|
int problem=0;
|
||||||
|
|
||||||
merge_keys_and_selfsig(keyblock);
|
merge_keys_and_selfsig(keyblock);
|
||||||
pk=keyblock->pkt->pkt.public_key;
|
pk=keyblock->pkt->pkt.public_key;
|
||||||
|
|
||||||
@ -672,9 +672,9 @@ check_prefs (ctrl_t ctrl, kbnode_t keyblock)
|
|||||||
{
|
{
|
||||||
if (openpgp_cipher_test_algo (prefs->value))
|
if (openpgp_cipher_test_algo (prefs->value))
|
||||||
{
|
{
|
||||||
const char *algo =
|
const char *algo =
|
||||||
(openpgp_cipher_test_algo (prefs->value)
|
(openpgp_cipher_test_algo (prefs->value)
|
||||||
? num
|
? num
|
||||||
: openpgp_cipher_algo_name (prefs->value));
|
: openpgp_cipher_algo_name (prefs->value));
|
||||||
if(!problem)
|
if(!problem)
|
||||||
check_prefs_warning(pk);
|
check_prefs_warning(pk);
|
||||||
@ -689,7 +689,7 @@ check_prefs (ctrl_t ctrl, kbnode_t keyblock)
|
|||||||
{
|
{
|
||||||
const char *algo =
|
const char *algo =
|
||||||
(gcry_md_test_algo (prefs->value)
|
(gcry_md_test_algo (prefs->value)
|
||||||
? num
|
? num
|
||||||
: gcry_md_algo_name (prefs->value));
|
: gcry_md_algo_name (prefs->value));
|
||||||
if(!problem)
|
if(!problem)
|
||||||
check_prefs_warning(pk);
|
check_prefs_warning(pk);
|
||||||
@ -801,7 +801,7 @@ import_one (ctrl_t ctrl,
|
|||||||
log_error( _("key %s: no user ID\n"), keystr_from_pk(pk));
|
log_error( _("key %s: no user ID\n"), keystr_from_pk(pk));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.interactive) {
|
if (opt.interactive) {
|
||||||
if(is_status_enabled())
|
if(is_status_enabled())
|
||||||
print_import_check (pk, uidnode->pkt->pkt.user_id);
|
print_import_check (pk, uidnode->pkt->pkt.user_id);
|
||||||
@ -938,7 +938,7 @@ import_one (ctrl_t ctrl,
|
|||||||
size_t an;
|
size_t an;
|
||||||
|
|
||||||
fingerprint_from_pk (pk_orig, afp, &an);
|
fingerprint_from_pk (pk_orig, afp, &an);
|
||||||
while (an < MAX_FINGERPRINT_LEN)
|
while (an < MAX_FINGERPRINT_LEN)
|
||||||
afp[an++] = 0;
|
afp[an++] = 0;
|
||||||
rc = keydb_search_fpr (hd, afp);
|
rc = keydb_search_fpr (hd, afp);
|
||||||
}
|
}
|
||||||
@ -962,7 +962,7 @@ import_one (ctrl_t ctrl,
|
|||||||
n_sigs_cleaned = fix_bad_direct_key_sigs (keyblock_orig, keyid);
|
n_sigs_cleaned = fix_bad_direct_key_sigs (keyblock_orig, keyid);
|
||||||
if (n_sigs_cleaned)
|
if (n_sigs_cleaned)
|
||||||
commit_kbnode (&keyblock_orig);
|
commit_kbnode (&keyblock_orig);
|
||||||
|
|
||||||
/* and try to merge the block */
|
/* and try to merge the block */
|
||||||
clear_kbnode_flags( keyblock_orig );
|
clear_kbnode_flags( keyblock_orig );
|
||||||
clear_kbnode_flags( keyblock );
|
clear_kbnode_flags( keyblock );
|
||||||
@ -1032,13 +1032,13 @@ import_one (ctrl_t ctrl,
|
|||||||
stats->n_sigs_cleaned +=n_sigs_cleaned;
|
stats->n_sigs_cleaned +=n_sigs_cleaned;
|
||||||
stats->n_uids_cleaned +=n_uids_cleaned;
|
stats->n_uids_cleaned +=n_uids_cleaned;
|
||||||
|
|
||||||
if (is_status_enabled ())
|
if (is_status_enabled ())
|
||||||
print_import_ok (pk, ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0)));
|
print_import_ok (pk, ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
same_key = 1;
|
same_key = 1;
|
||||||
if (is_status_enabled ())
|
if (is_status_enabled ())
|
||||||
print_import_ok (pk, 0);
|
print_import_ok (pk, 0);
|
||||||
|
|
||||||
if( !opt.quiet )
|
if( !opt.quiet )
|
||||||
@ -1107,6 +1107,37 @@ import_one (ctrl_t ctrl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Extract one MPI value from the S-expression PKEY which is expected
|
||||||
|
to hold a "public-key". Returns NULL on error. */
|
||||||
|
static gcry_mpi_t
|
||||||
|
one_mpi_from_pkey (gcry_sexp_t pkey, const char *name, size_t namelen)
|
||||||
|
{
|
||||||
|
gcry_sexp_t list, l2;
|
||||||
|
gcry_mpi_t a;
|
||||||
|
|
||||||
|
list = gcry_sexp_find_token (pkey, "public-key", 0);
|
||||||
|
if (!list)
|
||||||
|
return NULL;
|
||||||
|
l2 = gcry_sexp_cadr (list);
|
||||||
|
gcry_sexp_release (list);
|
||||||
|
list = l2;
|
||||||
|
if (!list)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
l2 = gcry_sexp_find_token (list, name, namelen);
|
||||||
|
if (!l2)
|
||||||
|
{
|
||||||
|
gcry_sexp_release (list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
a = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
|
||||||
|
gcry_sexp_release (l2);
|
||||||
|
gcry_sexp_release (list);
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Transfer all the secret keys in SEC_KEYBLOCK to the gpg-agent. The
|
/* Transfer all the secret keys in SEC_KEYBLOCK to the gpg-agent. The
|
||||||
function prints diagnostics and returns an error code. */
|
function prints diagnostics and returns an error code. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
@ -1133,6 +1164,7 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
|
|||||||
unsigned char *wrappedkey = NULL;
|
unsigned char *wrappedkey = NULL;
|
||||||
size_t wrappedkeylen;
|
size_t wrappedkeylen;
|
||||||
char *cache_nonce = NULL;
|
char *cache_nonce = NULL;
|
||||||
|
gcry_mpi_t ecc_params[5] = {NULL, NULL, NULL, NULL, NULL};
|
||||||
|
|
||||||
/* Get the current KEK. */
|
/* Get the current KEK. */
|
||||||
err = agent_keywrap_key (ctrl, 0, &kek, &keklen);
|
err = agent_keywrap_key (ctrl, 0, &kek, &keklen);
|
||||||
@ -1148,7 +1180,8 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
|
|||||||
if (!err)
|
if (!err)
|
||||||
err = gcry_cipher_setkey (cipherhd, kek, keklen);
|
err = gcry_cipher_setkey (cipherhd, kek, keklen);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave; xfree (kek);
|
goto leave;
|
||||||
|
xfree (kek);
|
||||||
kek = NULL;
|
kek = NULL;
|
||||||
|
|
||||||
main_pk = NULL;
|
main_pk = NULL;
|
||||||
@ -1161,6 +1194,20 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
|
|||||||
if (!main_pk)
|
if (!main_pk)
|
||||||
main_pk = pk;
|
main_pk = pk;
|
||||||
|
|
||||||
|
/* Make sure the keyids are available. */
|
||||||
|
keyid_from_pk (pk, NULL);
|
||||||
|
if (node->pkt->pkttype == PKT_SECRET_KEY)
|
||||||
|
{
|
||||||
|
pk->main_keyid[0] = pk->keyid[0];
|
||||||
|
pk->main_keyid[1] = pk->keyid[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pk->main_keyid[0] = main_pk->keyid[0];
|
||||||
|
pk->main_keyid[1] = main_pk->keyid[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ski = pk->seckey_info;
|
ski = pk->seckey_info;
|
||||||
if (!ski)
|
if (!ski)
|
||||||
BUG ();
|
BUG ();
|
||||||
@ -1191,34 +1238,109 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
|
|||||||
|
|
||||||
init_membuf (&mbuf, 50);
|
init_membuf (&mbuf, 50);
|
||||||
put_membuf_str (&mbuf, "(skey");
|
put_membuf_str (&mbuf, "(skey");
|
||||||
for (i=j=0; i < nskey; i++)
|
if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|
||||||
|
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH)
|
||||||
{
|
{
|
||||||
if (!pk->pkey[i])
|
/* We need special treatment for ECC algorithms. OpenPGP
|
||||||
; /* Protected keys only have NPKEY+1 elements. */
|
stores only the curve name but the agent expects a full
|
||||||
else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
|
key. This is so that we can keep all curve name
|
||||||
{
|
validation code out of gpg-agent. */
|
||||||
put_membuf_str (&mbuf, " e %b");
|
#if PUBKEY_MAX_NSKEY < 7
|
||||||
format_args_buf_ptr[i] = gcry_mpi_get_opaque (pk->pkey[i], &n);
|
#error PUBKEY_MAX_NSKEY too low for ECC
|
||||||
format_args_buf_int[i] = (n+7)/8;
|
#endif
|
||||||
format_args[j++] = format_args_buf_int + i;
|
char *curve = openpgp_oid_to_str (pk->pkey[0]);
|
||||||
format_args[j++] = format_args_buf_ptr + i;
|
if (!curve)
|
||||||
}
|
err = gpg_error_from_syserror ();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
put_membuf_str (&mbuf, " _ %m");
|
#ifdef HAVE_GCRY_PK_GET_CURVE /* Also ensures availability of get_param. */
|
||||||
format_args[j++] = pk->pkey + i;
|
gcry_sexp_t cparam = gcry_pk_get_param (GCRY_PK_ECDSA, curve);
|
||||||
|
#else
|
||||||
|
gcry_sexp_t cparam = NULL;
|
||||||
|
#endif
|
||||||
|
xfree (curve);
|
||||||
|
if (!cparam)
|
||||||
|
err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
/* Append the curve parameters P, A, B, G and N. */
|
||||||
|
for (i=j=0; !err && *(s = "pabgn"+i); i++)
|
||||||
|
{
|
||||||
|
ecc_params[i] = one_mpi_from_pkey (cparam, s, 1);
|
||||||
|
if (!ecc_params[i])
|
||||||
|
err = gpg_error (GPG_ERR_INV_CURVE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_membuf_str (&mbuf, " _ %m");
|
||||||
|
format_args[j++] = ecc_params+i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gcry_sexp_release (cparam);
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
/* Append the public key element Q. */
|
||||||
|
put_membuf_str (&mbuf, " _ %m");
|
||||||
|
format_args[j++] = pk->pkey + 1;
|
||||||
|
|
||||||
|
/* Append the secret key element D. Note that
|
||||||
|
for ECDH we need to skip PKEY[2] because this
|
||||||
|
holds the KEK which is not needed. */
|
||||||
|
i = pk->pubkey_algo == PUBKEY_ALGO_ECDH? 3 : 2;
|
||||||
|
if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
|
||||||
|
{
|
||||||
|
put_membuf_str (&mbuf, " e %b");
|
||||||
|
format_args_buf_ptr[i]
|
||||||
|
= gcry_mpi_get_opaque (pk->pkey[i],&n);
|
||||||
|
format_args_buf_int[i] = (n+7)/8;
|
||||||
|
format_args[j++] = format_args_buf_int + i;
|
||||||
|
format_args[j++] = format_args_buf_ptr + i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_membuf_str (&mbuf, " _ %m");
|
||||||
|
format_args[j++] = pk->pkey + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Standard case for the old (non-ECC) algorithms. */
|
||||||
|
for (i=j=0; i < nskey; i++)
|
||||||
|
{
|
||||||
|
if (!pk->pkey[i])
|
||||||
|
; /* Protected keys only have NPKEY+1 elements. */
|
||||||
|
else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
|
||||||
|
{
|
||||||
|
put_membuf_str (&mbuf, " e %b");
|
||||||
|
format_args_buf_ptr[i] = gcry_mpi_get_opaque (pk->pkey[i],&n);
|
||||||
|
format_args_buf_int[i] = (n+7)/8;
|
||||||
|
format_args[j++] = format_args_buf_int + i;
|
||||||
|
format_args[j++] = format_args_buf_ptr + i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_membuf_str (&mbuf, " _ %m");
|
||||||
|
format_args[j++] = pk->pkey + i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
put_membuf_str (&mbuf, ")\n");
|
put_membuf_str (&mbuf, ")\n");
|
||||||
put_membuf (&mbuf, "", 1);
|
put_membuf (&mbuf, "", 1);
|
||||||
{
|
if (err)
|
||||||
char *format = get_membuf (&mbuf, NULL);
|
xfree (get_membuf (&mbuf, NULL));
|
||||||
if (!format)
|
else
|
||||||
err = gpg_error_from_syserror ();
|
{
|
||||||
else
|
char *format = get_membuf (&mbuf, NULL);
|
||||||
err = gcry_sexp_build_array (&skey, NULL, format, format_args);
|
if (!format)
|
||||||
xfree (format);
|
err = gpg_error_from_syserror ();
|
||||||
}
|
else
|
||||||
|
err = gcry_sexp_build_array (&skey, NULL, format, format_args);
|
||||||
|
xfree (format);
|
||||||
|
}
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_error ("error building skey array: %s\n", gpg_strerror (err));
|
log_error ("error building skey array: %s\n", gpg_strerror (err));
|
||||||
@ -1228,7 +1350,7 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
|
|||||||
if (ski->is_protected)
|
if (ski->is_protected)
|
||||||
{
|
{
|
||||||
char countbuf[35];
|
char countbuf[35];
|
||||||
|
|
||||||
/* Note that the IVLEN may be zero if we are working on a
|
/* Note that the IVLEN may be zero if we are working on a
|
||||||
dummy key. We can't express that in an S-expression and
|
dummy key. We can't express that in an S-expression and
|
||||||
thus we send dummy data for the IV. */
|
thus we send dummy data for the IV. */
|
||||||
@ -1289,9 +1411,9 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
|
|||||||
transferkey = NULL;
|
transferkey = NULL;
|
||||||
|
|
||||||
/* Send the wrapped key to the agent. */
|
/* Send the wrapped key to the agent. */
|
||||||
{
|
{
|
||||||
char *desc = gpg_format_keydesc (pk, 1, 1);
|
char *desc = gpg_format_keydesc (pk, 1, 1);
|
||||||
err = agent_import_key (ctrl, desc, &cache_nonce,
|
err = agent_import_key (ctrl, desc, &cache_nonce,
|
||||||
wrappedkey, wrappedkeylen);
|
wrappedkey, wrappedkeylen);
|
||||||
xfree (desc);
|
xfree (desc);
|
||||||
}
|
}
|
||||||
@ -1328,6 +1450,8 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
for (i=0; i < DIM (ecc_params); i++)
|
||||||
|
gcry_mpi_release (ecc_params[i]);
|
||||||
xfree (cache_nonce);
|
xfree (cache_nonce);
|
||||||
xfree (wrappedkey);
|
xfree (wrappedkey);
|
||||||
xfree (transferkey);
|
xfree (transferkey);
|
||||||
@ -1392,7 +1516,7 @@ sec_to_pub_keyblock (kbnode_t sec_keyblock)
|
|||||||
* with the trust calculation.
|
* with the trust calculation.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
||||||
struct stats_s *stats, unsigned int options)
|
struct stats_s *stats, unsigned int options)
|
||||||
{
|
{
|
||||||
PKT_public_key *pk;
|
PKT_public_key *pk;
|
||||||
@ -1400,17 +1524,17 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
|||||||
KBNODE node, uidnode;
|
KBNODE node, uidnode;
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/* Get the key and print some info about it */
|
/* Get the key and print some info about it */
|
||||||
node = find_kbnode (keyblock, PKT_SECRET_KEY);
|
node = find_kbnode (keyblock, PKT_SECRET_KEY);
|
||||||
if (!node)
|
if (!node)
|
||||||
BUG ();
|
BUG ();
|
||||||
|
|
||||||
pk = node->pkt->pkt.public_key;
|
pk = node->pkt->pkt.public_key;
|
||||||
|
|
||||||
keyid_from_pk (pk, keyid);
|
keyid_from_pk (pk, keyid);
|
||||||
uidnode = find_next_kbnode (keyblock, PKT_USER_ID);
|
uidnode = find_next_kbnode (keyblock, PKT_USER_ID);
|
||||||
|
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
{
|
{
|
||||||
log_info ("sec %4u%c/%s %s ",
|
log_info ("sec %4u%c/%s %s ",
|
||||||
@ -1423,7 +1547,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
|||||||
log_printf ("\n");
|
log_printf ("\n");
|
||||||
}
|
}
|
||||||
stats->secret_read++;
|
stats->secret_read++;
|
||||||
|
|
||||||
if (!uidnode)
|
if (!uidnode)
|
||||||
{
|
{
|
||||||
log_error( _("key %s: no user ID\n"), keystr_from_pk (pk));
|
log_error( _("key %s: no user ID\n"), keystr_from_pk (pk));
|
||||||
@ -1456,10 +1580,10 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
|||||||
log_error (_("importing secret keys not allowed\n"));
|
log_error (_("importing secret keys not allowed\n"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
clear_kbnode_flags (keyblock);
|
clear_kbnode_flags (keyblock);
|
||||||
|
|
||||||
if (!(options&IMPORT_MERGE_ONLY) || !have_secret_key_with_kid (keyid) )
|
if (!(options&IMPORT_MERGE_ONLY) || !have_secret_key_with_kid (keyid) )
|
||||||
{
|
{
|
||||||
/* We don't have this key, insert as a new key. */
|
/* We don't have this key, insert as a new key. */
|
||||||
@ -1477,7 +1601,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
|||||||
/* Fixme: We should check for an invalid keyblock and
|
/* Fixme: We should check for an invalid keyblock and
|
||||||
cancel the secret key import in this case. */
|
cancel the secret key import in this case. */
|
||||||
release_kbnode (pub_keyblock);
|
release_kbnode (pub_keyblock);
|
||||||
|
|
||||||
/* Read the keyblock again to get the effects of a merge. */
|
/* Read the keyblock again to get the effects of a merge. */
|
||||||
/* Fixme: we should do this based on the fingerprint or
|
/* Fixme: we should do this based on the fingerprint or
|
||||||
even better let import_one return the merged
|
even better let import_one return the merged
|
||||||
@ -1493,7 +1617,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
|||||||
if (!opt.quiet)
|
if (!opt.quiet)
|
||||||
log_info (_("key %s: secret key imported\n"),
|
log_info (_("key %s: secret key imported\n"),
|
||||||
keystr_from_pk (pk));
|
keystr_from_pk (pk));
|
||||||
if (is_status_enabled ())
|
if (is_status_enabled ())
|
||||||
print_import_ok (pk, 1|16);
|
print_import_ok (pk, 1|16);
|
||||||
check_prefs (ctrl, node);
|
check_prefs (ctrl, node);
|
||||||
}
|
}
|
||||||
@ -1502,11 +1626,11 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We don't want to merge the secret keys. */
|
/* We don't want to merge the secret keys. */
|
||||||
log_error (_("key %s: secret key part already available\n"),
|
log_error (_("key %s: secret key part already available\n"),
|
||||||
keystr_from_pk (pk));
|
keystr_from_pk (pk));
|
||||||
if (is_status_enabled ())
|
if (is_status_enabled ())
|
||||||
print_import_ok (pk, 16);
|
print_import_ok (pk, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1556,9 +1680,9 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
|
|||||||
{
|
{
|
||||||
byte afp[MAX_FINGERPRINT_LEN];
|
byte afp[MAX_FINGERPRINT_LEN];
|
||||||
size_t an;
|
size_t an;
|
||||||
|
|
||||||
fingerprint_from_pk (pk, afp, &an);
|
fingerprint_from_pk (pk, afp, &an);
|
||||||
while (an < MAX_FINGERPRINT_LEN)
|
while (an < MAX_FINGERPRINT_LEN)
|
||||||
afp[an++] = 0;
|
afp[an++] = 0;
|
||||||
rc = keydb_search_fpr (hd, afp);
|
rc = keydb_search_fpr (hd, afp);
|
||||||
}
|
}
|
||||||
@ -1654,11 +1778,11 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
|
|||||||
int rc;
|
int rc;
|
||||||
u32 bsdate=0, rsdate=0;
|
u32 bsdate=0, rsdate=0;
|
||||||
kbnode_t bsnode = NULL, rsnode = NULL;
|
kbnode_t bsnode = NULL, rsnode = NULL;
|
||||||
|
|
||||||
(void)fname;
|
(void)fname;
|
||||||
(void)pk;
|
(void)pk;
|
||||||
|
|
||||||
for (n=keyblock; (n = find_next_kbnode (n, 0)); )
|
for (n=keyblock; (n = find_next_kbnode (n, 0)); )
|
||||||
{
|
{
|
||||||
if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||||
{
|
{
|
||||||
@ -1672,7 +1796,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
|
|||||||
|
|
||||||
if ( n->pkt->pkttype != PKT_SIGNATURE )
|
if ( n->pkt->pkttype != PKT_SIGNATURE )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sig = n->pkt->pkt.signature;
|
sig = n->pkt->pkt.signature;
|
||||||
if ( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
|
if ( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
|
||||||
{
|
{
|
||||||
@ -1684,7 +1808,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
|
|||||||
import a fully-cached key which speeds things up. */
|
import a fully-cached key which speeds things up. */
|
||||||
if (!opt.no_sig_cache)
|
if (!opt.no_sig_cache)
|
||||||
check_key_signature (keyblock, n, NULL);
|
check_key_signature (keyblock, n, NULL);
|
||||||
|
|
||||||
if ( IS_UID_SIG(sig) || IS_UID_REV(sig) )
|
if ( IS_UID_SIG(sig) || IS_UID_REV(sig) )
|
||||||
{
|
{
|
||||||
KBNODE unode = find_prev_kbnode( keyblock, n, PKT_USER_ID );
|
KBNODE unode = find_prev_kbnode( keyblock, n, PKT_USER_ID );
|
||||||
@ -1694,16 +1818,16 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
|
|||||||
keystr(keyid));
|
keystr(keyid));
|
||||||
return -1; /* The complete keyblock is invalid. */
|
return -1; /* The complete keyblock is invalid. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If it hasn't been marked valid yet, keep trying. */
|
/* If it hasn't been marked valid yet, keep trying. */
|
||||||
if (!(unode->flag&1))
|
if (!(unode->flag&1))
|
||||||
{
|
{
|
||||||
rc = check_key_signature (keyblock, n, NULL);
|
rc = check_key_signature (keyblock, n, NULL);
|
||||||
if ( rc )
|
if ( rc )
|
||||||
{
|
{
|
||||||
if ( opt.verbose )
|
if ( opt.verbose )
|
||||||
{
|
{
|
||||||
char *p = utf8_to_native
|
char *p = utf8_to_native
|
||||||
(unode->pkt->pkt.user_id->name,
|
(unode->pkt->pkt.user_id->name,
|
||||||
strlen (unode->pkt->pkt.user_id->name),0);
|
strlen (unode->pkt->pkt.user_id->name),0);
|
||||||
log_info (gpg_err_code(rc) == G10ERR_PUBKEY_ALGO ?
|
log_info (gpg_err_code(rc) == G10ERR_PUBKEY_ALGO ?
|
||||||
@ -1732,7 +1856,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
|
|||||||
n->flag |= 4;
|
n->flag |= 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( IS_SUBKEY_SIG (sig) )
|
else if ( IS_SUBKEY_SIG (sig) )
|
||||||
{
|
{
|
||||||
/* Note that this works based solely on the timestamps like
|
/* Note that this works based solely on the timestamps like
|
||||||
the rest of gpg. If the standard gets revocation
|
the rest of gpg. If the standard gets revocation
|
||||||
@ -1761,19 +1885,19 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* It's valid, so is it newer? */
|
/* It's valid, so is it newer? */
|
||||||
if (sig->timestamp >= bsdate)
|
if (sig->timestamp >= bsdate)
|
||||||
{
|
{
|
||||||
knode->flag |= 1; /* The subkey is valid. */
|
knode->flag |= 1; /* The subkey is valid. */
|
||||||
if (bsnode)
|
if (bsnode)
|
||||||
{
|
{
|
||||||
/* Delete the last binding sig since this
|
/* Delete the last binding sig since this
|
||||||
one is newer */
|
one is newer */
|
||||||
bsnode->flag |= 4;
|
bsnode->flag |= 4;
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info (_("key %s: removed multiple subkey"
|
log_info (_("key %s: removed multiple subkey"
|
||||||
" binding\n"),keystr(keyid));
|
" binding\n"),keystr(keyid));
|
||||||
}
|
}
|
||||||
|
|
||||||
bsnode = n;
|
bsnode = n;
|
||||||
bsdate = sig->timestamp;
|
bsdate = sig->timestamp;
|
||||||
}
|
}
|
||||||
@ -1818,12 +1942,12 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
|
|||||||
{
|
{
|
||||||
/* Delete the last revocation sig since
|
/* Delete the last revocation sig since
|
||||||
this one is newer. */
|
this one is newer. */
|
||||||
rsnode->flag |= 4;
|
rsnode->flag |= 4;
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info (_("key %s: removed multiple subkey"
|
log_info (_("key %s: removed multiple subkey"
|
||||||
" revocation\n"),keystr(keyid));
|
" revocation\n"),keystr(keyid));
|
||||||
}
|
}
|
||||||
|
|
||||||
rsnode = n;
|
rsnode = n;
|
||||||
rsdate = sig->timestamp;
|
rsdate = sig->timestamp;
|
||||||
}
|
}
|
||||||
|
57
g10/keygen.c
57
g10/keygen.c
@ -1080,6 +1080,40 @@ write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Map the Libgcrypt ECC curve NAME to an OID. If R_NBITS is not NULL
|
||||||
|
store the bit size of the curve there. Returns NULL for unknown
|
||||||
|
curve names. */
|
||||||
|
const char *
|
||||||
|
gpg_curve_to_oid (const char *name, unsigned int *r_nbits)
|
||||||
|
{
|
||||||
|
unsigned int nbits = 0;
|
||||||
|
const char *oidstr;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
oidstr = NULL;
|
||||||
|
else if (!strcmp (name, "NIST P-256"))
|
||||||
|
{
|
||||||
|
oidstr = "1.2.840.10045.3.1.7";
|
||||||
|
nbits = 256;
|
||||||
|
}
|
||||||
|
else if (!strcmp (name, "NIST P-384"))
|
||||||
|
{
|
||||||
|
oidstr = "1.3.132.0.34";
|
||||||
|
nbits = 384;
|
||||||
|
}
|
||||||
|
else if (!strcmp (name, "NIST P-521"))
|
||||||
|
{
|
||||||
|
oidstr = "1.3.132.0.35";
|
||||||
|
nbits = 521;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
oidstr = NULL;
|
||||||
|
|
||||||
|
if (r_nbits)
|
||||||
|
*r_nbits = nbits;
|
||||||
|
return oidstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo)
|
ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo)
|
||||||
@ -1117,23 +1151,11 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
gcry_sexp_release (l2);
|
gcry_sexp_release (l2);
|
||||||
if (!strcmp (curve, "NIST P-256"))
|
oidstr = gpg_curve_to_oid (curve, &nbits);
|
||||||
{
|
if (!oidstr)
|
||||||
oidstr = "1.2.840.10045.3.1.7";
|
|
||||||
nbits = 256;
|
|
||||||
}
|
|
||||||
else if (!strcmp (curve, "NIST P-384"))
|
|
||||||
{
|
|
||||||
oidstr = "1.3.132.0.34";
|
|
||||||
nbits = 384;
|
|
||||||
}
|
|
||||||
else if (!strcmp (curve, "NIST P-521"))
|
|
||||||
{
|
|
||||||
oidstr = "1.3.132.0.35";
|
|
||||||
nbits = 521;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
/* That can't happen because we used one of the curves
|
||||||
|
gpg_curve_to_oid knows about. */
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -1445,7 +1467,8 @@ gen_ecc (int algo, unsigned int nbits, kbnode_t pub_root,
|
|||||||
|
|
||||||
assert (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH);
|
assert (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH);
|
||||||
|
|
||||||
/* For now we may only use one of the 3 NISY curves. */
|
/* For now we may only use one of the 3 NIST curves. See also
|
||||||
|
gpg_curve_to_oid. */
|
||||||
if (nbits <= 256)
|
if (nbits <= 256)
|
||||||
curve = "NIST P-256";
|
curve = "NIST P-256";
|
||||||
else if (nbits <= 384)
|
else if (nbits <= 384)
|
||||||
|
97
g10/keyid.c
97
g10/keyid.c
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_UNSIGNED_TIME_T
|
#ifdef HAVE_UNSIGNED_TIME_T
|
||||||
# define IS_INVALID_TIME_T(a) ((a) == (time_t)(-1))
|
# define IS_INVALID_TIME_T(a) ((a) == (time_t)(-1))
|
||||||
#else
|
#else
|
||||||
/* Error or 32 bit time_t and value after 2038-01-19. */
|
/* Error or 32 bit time_t and value after 2038-01-19. */
|
||||||
# define IS_INVALID_TIME_T(a) ((a) < 0)
|
# define IS_INVALID_TIME_T(a) ((a) < 0)
|
||||||
#endif
|
#endif
|
||||||
@ -81,6 +81,11 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
|
|||||||
if(pk->version<4)
|
if(pk->version<4)
|
||||||
n+=2;
|
n+=2;
|
||||||
|
|
||||||
|
/* FIXME: We can avoid the extra malloc by calling only the first
|
||||||
|
mpi_print here which computes the required length and calling the
|
||||||
|
real mpi_print only at the end. The speed advantage would only be
|
||||||
|
for ECC (opaque MPIs) or if we could implement an mpi_print
|
||||||
|
variant with a callback handler to do the hashing. */
|
||||||
if (npkey==0 && pk->pkey[0]
|
if (npkey==0 && pk->pkey[0]
|
||||||
&& gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
|
&& gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
|
||||||
{
|
{
|
||||||
@ -92,25 +97,32 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
|
|||||||
{
|
{
|
||||||
for (i=0; i < npkey; i++ )
|
for (i=0; i < npkey; i++ )
|
||||||
{
|
{
|
||||||
enum gcry_mpi_format fmt;
|
if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
|
||||||
|
{
|
||||||
if ((pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|
size_t nbits;
|
||||||
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH)
|
const void *p;
|
||||||
&& (i == 0 || i == 2))
|
|
||||||
fmt = GCRYMPI_FMT_USG; /* Name of OID or KEK parms. */
|
p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
|
||||||
|
pp[i] = xmalloc ((nbits+7)/8);
|
||||||
|
memcpy (pp[i], p, (nbits+7)/8);
|
||||||
|
nn[i] = (nbits+7)/8;
|
||||||
|
n += nn[i];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
fmt = GCRYMPI_FMT_PGP;
|
{
|
||||||
|
if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0,
|
||||||
if (gcry_mpi_print (fmt, NULL, 0, &nbytes, pk->pkey[i]))
|
&nbytes, pk->pkey[i]))
|
||||||
BUG ();
|
BUG ();
|
||||||
pp[i] = xmalloc (nbytes);
|
pp[i] = xmalloc (nbytes);
|
||||||
if (gcry_mpi_print (fmt, pp[i], nbytes, &nbytes, pk->pkey[i]))
|
if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
|
||||||
BUG ();
|
&nbytes, pk->pkey[i]))
|
||||||
nn[i] = nbytes;
|
BUG ();
|
||||||
n += nn[i];
|
nn[i] = nbytes;
|
||||||
|
n += nn[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gcry_md_putc ( md, 0x99 ); /* ctb */
|
gcry_md_putc ( md, 0x99 ); /* ctb */
|
||||||
/* What does it mean if n is greater than than 0xFFFF ? */
|
/* What does it mean if n is greater than than 0xFFFF ? */
|
||||||
gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */
|
gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */
|
||||||
@ -127,7 +139,7 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
|
|||||||
u16 days=0;
|
u16 days=0;
|
||||||
if(pk->expiredate)
|
if(pk->expiredate)
|
||||||
days=(u16)((pk->expiredate - pk->timestamp) / 86400L);
|
days=(u16)((pk->expiredate - pk->timestamp) / 86400L);
|
||||||
|
|
||||||
gcry_md_putc ( md, days >> 8 );
|
gcry_md_putc ( md, days >> 8 );
|
||||||
gcry_md_putc ( md, days );
|
gcry_md_putc ( md, days );
|
||||||
}
|
}
|
||||||
@ -178,7 +190,7 @@ v3_keyid (gcry_mpi_t a, u32 *ki)
|
|||||||
BUG ();
|
BUG ();
|
||||||
if (nbytes < 8) /* oops */
|
if (nbytes < 8) /* oops */
|
||||||
ki[0] = ki[1] = 0;
|
ki[0] = ki[1] = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p = buffer + nbytes - 8;
|
p = buffer + nbytes - 8;
|
||||||
ki[0] = (p[0] << 24) | (p[1] <<16) | (p[2] << 8) | p[3];
|
ki[0] = (p[0] << 24) | (p[1] <<16) | (p[2] << 8) | p[3];
|
||||||
@ -215,7 +227,7 @@ keystrlen(void)
|
|||||||
|
|
||||||
const char *
|
const char *
|
||||||
keystr (u32 *keyid)
|
keystr (u32 *keyid)
|
||||||
{
|
{
|
||||||
static char keyid_str[KEYID_STR_SIZE];
|
static char keyid_str[KEYID_STR_SIZE];
|
||||||
|
|
||||||
switch (opt.keyid_format)
|
switch (opt.keyid_format)
|
||||||
@ -226,7 +238,7 @@ keystr (u32 *keyid)
|
|||||||
|
|
||||||
case KF_LONG:
|
case KF_LONG:
|
||||||
if (keyid[0])
|
if (keyid[0])
|
||||||
snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX",
|
snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX",
|
||||||
(ulong)keyid[0], (ulong)keyid[1]);
|
(ulong)keyid[0], (ulong)keyid[1]);
|
||||||
else
|
else
|
||||||
snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
|
snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
|
||||||
@ -238,12 +250,12 @@ keystr (u32 *keyid)
|
|||||||
|
|
||||||
case KF_0xLONG:
|
case KF_0xLONG:
|
||||||
if(keyid[0])
|
if(keyid[0])
|
||||||
snprintf (keyid_str, sizeof keyid_str, "0x%08lX%08lX",
|
snprintf (keyid_str, sizeof keyid_str, "0x%08lX%08lX",
|
||||||
(ulong)keyid[0],(ulong)keyid[1]);
|
(ulong)keyid[0],(ulong)keyid[1]);
|
||||||
else
|
else
|
||||||
snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
|
snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
@ -254,7 +266,7 @@ keystr (u32 *keyid)
|
|||||||
|
|
||||||
const char *
|
const char *
|
||||||
keystr_with_sub (u32 *main_kid, u32 *sub_kid)
|
keystr_with_sub (u32 *main_kid, u32 *sub_kid)
|
||||||
{
|
{
|
||||||
static char buffer[KEYID_STR_SIZE+1+KEYID_STR_SIZE];
|
static char buffer[KEYID_STR_SIZE+1+KEYID_STR_SIZE];
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
@ -408,7 +420,7 @@ keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
|
|||||||
else
|
else
|
||||||
keyid_from_pk (&pk, keyid);
|
keyid_from_pk (&pk, keyid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const byte *dp = fprint;
|
const byte *dp = fprint;
|
||||||
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
||||||
@ -422,7 +434,7 @@ keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
|
|||||||
u32
|
u32
|
||||||
keyid_from_sig (PKT_signature *sig, u32 *keyid)
|
keyid_from_sig (PKT_signature *sig, u32 *keyid)
|
||||||
{
|
{
|
||||||
if( keyid )
|
if( keyid )
|
||||||
{
|
{
|
||||||
keyid[0] = sig->keyid[0];
|
keyid[0] = sig->keyid[0];
|
||||||
keyid[1] = sig->keyid[1];
|
keyid[1] = sig->keyid[1];
|
||||||
@ -437,13 +449,13 @@ namehash_from_uid (PKT_user_id *uid)
|
|||||||
if (!uid->namehash)
|
if (!uid->namehash)
|
||||||
{
|
{
|
||||||
uid->namehash = xmalloc (20);
|
uid->namehash = xmalloc (20);
|
||||||
|
|
||||||
if (uid->attrib_data)
|
if (uid->attrib_data)
|
||||||
rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len);
|
rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len);
|
||||||
else
|
else
|
||||||
rmd160_hash_buffer (uid->namehash, uid->name, uid->len);
|
rmd160_hash_buffer (uid->namehash, uid->name, uid->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return uid->namehash;
|
return uid->namehash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +477,7 @@ mk_datestr (char *buffer, time_t atime)
|
|||||||
|
|
||||||
if (IS_INVALID_TIME_T (atime))
|
if (IS_INVALID_TIME_T (atime))
|
||||||
strcpy (buffer, "????" "-??" "-??"); /* Mark this as invalid. */
|
strcpy (buffer, "????" "-??" "-??"); /* Mark this as invalid. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tp = gmtime (&atime);
|
tp = gmtime (&atime);
|
||||||
sprintf (buffer,"%04d-%02d-%02d",
|
sprintf (buffer,"%04d-%02d-%02d",
|
||||||
@ -485,7 +497,7 @@ datestr_from_pk (PKT_public_key *pk)
|
|||||||
{
|
{
|
||||||
static char buffer[11+5];
|
static char buffer[11+5];
|
||||||
time_t atime = pk->timestamp;
|
time_t atime = pk->timestamp;
|
||||||
|
|
||||||
return mk_datestr (buffer, atime);
|
return mk_datestr (buffer, atime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +530,7 @@ expirestr_from_sig (PKT_signature *sig)
|
|||||||
{
|
{
|
||||||
static char buffer[11+5];
|
static char buffer[11+5];
|
||||||
time_t atime;
|
time_t atime;
|
||||||
|
|
||||||
if (!sig->expiredate)
|
if (!sig->expiredate)
|
||||||
return _("never ");
|
return _("never ");
|
||||||
atime=sig->expiredate;
|
atime=sig->expiredate;
|
||||||
@ -591,7 +603,7 @@ const char *
|
|||||||
colon_datestr_from_sig (PKT_signature *sig)
|
colon_datestr_from_sig (PKT_signature *sig)
|
||||||
{
|
{
|
||||||
static char buf[20];
|
static char buf[20];
|
||||||
|
|
||||||
snprintf (buf, sizeof buf, "%lu", (ulong)sig->timestamp);
|
snprintf (buf, sizeof buf, "%lu", (ulong)sig->timestamp);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@ -621,21 +633,21 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
|
|||||||
const byte *dp;
|
const byte *dp;
|
||||||
size_t len, nbytes;
|
size_t len, nbytes;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ( pk->version < 4 )
|
if ( pk->version < 4 )
|
||||||
{
|
{
|
||||||
if ( is_RSA(pk->pubkey_algo) )
|
if ( is_RSA(pk->pubkey_algo) )
|
||||||
{
|
{
|
||||||
/* RSA in version 3 packets is special. */
|
/* RSA in version 3 packets is special. */
|
||||||
gcry_md_hd_t md;
|
gcry_md_hd_t md;
|
||||||
|
|
||||||
if (gcry_md_open (&md, DIGEST_ALGO_MD5, 0))
|
if (gcry_md_open (&md, DIGEST_ALGO_MD5, 0))
|
||||||
BUG ();
|
BUG ();
|
||||||
if ( pubkey_get_npkey (pk->pubkey_algo) > 1 )
|
if ( pubkey_get_npkey (pk->pubkey_algo) > 1 )
|
||||||
{
|
{
|
||||||
for (i=0; i < 2; i++)
|
for (i=0; i < 2; i++)
|
||||||
{
|
{
|
||||||
if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0,
|
if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0,
|
||||||
&nbytes, pk->pkey[i]))
|
&nbytes, pk->pkey[i]))
|
||||||
BUG ();
|
BUG ();
|
||||||
/* fixme: Better allocate BUF on the stack */
|
/* fixme: Better allocate BUF on the stack */
|
||||||
@ -662,10 +674,10 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
|
|||||||
memset (array,0,16);
|
memset (array,0,16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gcry_md_hd_t md;
|
gcry_md_hd_t md;
|
||||||
|
|
||||||
md = do_fingerprint_md(pk);
|
md = do_fingerprint_md(pk);
|
||||||
dp = gcry_md_read( md, 0 );
|
dp = gcry_md_read( md, 0 );
|
||||||
len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
|
len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
|
||||||
@ -677,7 +689,7 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
|
|||||||
pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
||||||
gcry_md_close( md);
|
gcry_md_close( md);
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret_len = len;
|
*ret_len = len;
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
@ -694,7 +706,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
|
|||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
gcry_sexp_t s_pkey;
|
gcry_sexp_t s_pkey;
|
||||||
|
|
||||||
if (DBG_PACKET)
|
if (DBG_PACKET)
|
||||||
log_debug ("get_keygrip for public key\n");
|
log_debug ("get_keygrip for public key\n");
|
||||||
|
|
||||||
@ -742,7 +754,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
|
|||||||
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
|
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -758,7 +770,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
|
|||||||
/* FIXME: Save the keygrip in PK. */
|
/* FIXME: Save the keygrip in PK. */
|
||||||
}
|
}
|
||||||
gcry_sexp_release (s_pkey);
|
gcry_sexp_release (s_pkey);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -786,4 +798,3 @@ hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip)
|
|||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,6 +236,7 @@ void keyedit_passwd (ctrl_t ctrl, const char *username);
|
|||||||
void show_basic_key_info (KBNODE keyblock);
|
void show_basic_key_info (KBNODE keyblock);
|
||||||
|
|
||||||
/*-- keygen.c --*/
|
/*-- keygen.c --*/
|
||||||
|
const char *gpg_curve_to_oid (const char *name, unsigned int *r_nbits);
|
||||||
u32 parse_expire_string(const char *string);
|
u32 parse_expire_string(const char *string);
|
||||||
u32 ask_expire_interval(int object,const char *def_expire);
|
u32 ask_expire_interval(int object,const char *def_expire);
|
||||||
u32 ask_expiredate(void);
|
u32 ask_expiredate(void);
|
||||||
|
104
g10/passphrase.c
104
g10/passphrase.c
@ -74,7 +74,7 @@ encode_s2k_iterations (int iterations)
|
|||||||
if (err && gpg_err_code (err) != GPG_ERR_ASS_PARAMETER)
|
if (err && gpg_err_code (err) != GPG_ERR_ASS_PARAMETER)
|
||||||
log_error (_("problem with the agent: %s\n"), gpg_strerror (err));
|
log_error (_("problem with the agent: %s\n"), gpg_strerror (err));
|
||||||
/* Default to 65536 which we used up to 2.0.13. */
|
/* Default to 65536 which we used up to 2.0.13. */
|
||||||
return 96;
|
return 96;
|
||||||
}
|
}
|
||||||
else if (mycnt >= 65011712)
|
else if (mycnt >= 65011712)
|
||||||
return 255; /* Largest possible value. */
|
return 255; /* Largest possible value. */
|
||||||
@ -87,7 +87,7 @@ encode_s2k_iterations (int iterations)
|
|||||||
|
|
||||||
if (iterations >= 65011712)
|
if (iterations >= 65011712)
|
||||||
return 255;
|
return 255;
|
||||||
|
|
||||||
/* Need count to be in the range 16-31 */
|
/* Need count to be in the range 16-31 */
|
||||||
for (count=iterations>>6; count>=32; count>>=1)
|
for (count=iterations>>6; count>=32; count>>=1)
|
||||||
c++;
|
c++;
|
||||||
@ -96,13 +96,13 @@ encode_s2k_iterations (int iterations)
|
|||||||
|
|
||||||
if (S2K_DECODE_COUNT(result) < iterations)
|
if (S2K_DECODE_COUNT(result) < iterations)
|
||||||
result++;
|
result++;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Hash a passphrase using the supplied s2k.
|
/* Hash a passphrase using the supplied s2k.
|
||||||
Always needs: dek->algo, s2k->mode, s2k->hash_algo. */
|
Always needs: dek->algo, s2k->mode, s2k->hash_algo. */
|
||||||
static void
|
static void
|
||||||
hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k)
|
hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k)
|
||||||
@ -119,20 +119,20 @@ hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k)
|
|||||||
|
|
||||||
if (gcry_md_open (&md, s2k->hash_algo, 1))
|
if (gcry_md_open (&md, s2k->hash_algo, 1))
|
||||||
BUG ();
|
BUG ();
|
||||||
for (pass=0; used < dek->keylen ; pass++ )
|
for (pass=0; used < dek->keylen ; pass++ )
|
||||||
{
|
{
|
||||||
if ( pass )
|
if ( pass )
|
||||||
{
|
{
|
||||||
gcry_md_reset (md);
|
gcry_md_reset (md);
|
||||||
for (i=0; i < pass; i++ ) /* Preset the hash context. */
|
for (i=0; i < pass; i++ ) /* Preset the hash context. */
|
||||||
gcry_md_putc (md, 0 );
|
gcry_md_putc (md, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( s2k->mode == 1 || s2k->mode == 3 )
|
if ( s2k->mode == 1 || s2k->mode == 3 )
|
||||||
{
|
{
|
||||||
int len2 = pwlen + 8;
|
int len2 = pwlen + 8;
|
||||||
ulong count = len2;
|
ulong count = len2;
|
||||||
|
|
||||||
if ( s2k->mode == 3 )
|
if ( s2k->mode == 3 )
|
||||||
{
|
{
|
||||||
count = S2K_DECODE_COUNT(s2k->count);
|
count = S2K_DECODE_COUNT(s2k->count);
|
||||||
@ -146,7 +146,7 @@ hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k)
|
|||||||
|
|
||||||
/* A little bit complicated because we need a ulong for count. */
|
/* A little bit complicated because we need a ulong for count. */
|
||||||
while ( count > len2 ) /* maybe iterated+salted */
|
while ( count > len2 ) /* maybe iterated+salted */
|
||||||
{
|
{
|
||||||
gcry_md_write ( md, s2k->salt, 8 );
|
gcry_md_write ( md, s2k->salt, 8 );
|
||||||
gcry_md_write ( md, pw, pwlen );
|
gcry_md_write ( md, pw, pwlen );
|
||||||
count -= len2;
|
count -= len2;
|
||||||
@ -231,7 +231,7 @@ read_passphrase_from_fd( int fd )
|
|||||||
int i, len;
|
int i, len;
|
||||||
char *pw;
|
char *pw;
|
||||||
|
|
||||||
if ( !opt.batch )
|
if ( !opt.batch )
|
||||||
{ /* Not used but we have to do a dummy read, so that it won't end
|
{ /* Not used but we have to do a dummy read, so that it won't end
|
||||||
up at the begin of the message if the quite usual trick to
|
up at the begin of the message if the quite usual trick to
|
||||||
prepend the passphtrase to the message is used. */
|
prepend the passphtrase to the message is used. */
|
||||||
@ -240,12 +240,12 @@ read_passphrase_from_fd( int fd )
|
|||||||
while (!(read (fd, buf, 1) != 1 || *buf == '\n' ))
|
while (!(read (fd, buf, 1) != 1 || *buf == '\n' ))
|
||||||
;
|
;
|
||||||
*buf = 0;
|
*buf = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (pw = NULL, i = len = 100; ; i++ )
|
for (pw = NULL, i = len = 100; ; i++ )
|
||||||
{
|
{
|
||||||
if (i >= len-1 )
|
if (i >= len-1 )
|
||||||
{
|
{
|
||||||
char *pw2 = pw;
|
char *pw2 = pw;
|
||||||
len += 100;
|
len += 100;
|
||||||
@ -311,35 +311,35 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
|
|||||||
if( keyid && get_pubkey( pk, keyid ) )
|
if( keyid && get_pubkey( pk, keyid ) )
|
||||||
{
|
{
|
||||||
if (pk)
|
if (pk)
|
||||||
free_public_key( pk );
|
free_public_key( pk );
|
||||||
pk = NULL; /* oops: no key for some reason */
|
pk = NULL; /* oops: no key for some reason */
|
||||||
}
|
}
|
||||||
|
|
||||||
orig_codeset = i18n_switchto_utf8 ();
|
orig_codeset = i18n_switchto_utf8 ();
|
||||||
|
|
||||||
if (custom_description)
|
if (custom_description)
|
||||||
atext = native_to_utf8 (custom_description);
|
atext = native_to_utf8 (custom_description);
|
||||||
else if ( !mode && pk && keyid )
|
else if ( !mode && pk && keyid )
|
||||||
{
|
{
|
||||||
char *uid;
|
char *uid;
|
||||||
size_t uidlen;
|
size_t uidlen;
|
||||||
const char *algo_name = openpgp_pk_algo_name ( pk->pubkey_algo );
|
const char *algo_name = openpgp_pk_algo_name ( pk->pubkey_algo );
|
||||||
const char *timestr;
|
const char *timestr;
|
||||||
char *maink;
|
char *maink;
|
||||||
|
|
||||||
if ( !algo_name )
|
if ( !algo_name )
|
||||||
algo_name = "?";
|
algo_name = "?";
|
||||||
|
|
||||||
#define KEYIDSTRING _(" (main key ID %s)")
|
#define KEYIDSTRING _(" (main key ID %s)")
|
||||||
|
|
||||||
maink = xmalloc ( strlen (KEYIDSTRING) + keystrlen() + 20 );
|
maink = xmalloc ( strlen (KEYIDSTRING) + keystrlen() + 20 );
|
||||||
if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
|
if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
|
||||||
&& keyid[1] != keyid[3] )
|
&& keyid[1] != keyid[3] )
|
||||||
sprintf( maink, KEYIDSTRING, keystr(&keyid[2]) );
|
sprintf( maink, KEYIDSTRING, keystr(&keyid[2]) );
|
||||||
else
|
else
|
||||||
*maink = 0;
|
*maink = 0;
|
||||||
|
|
||||||
uid = get_user_id ( keyid, &uidlen );
|
uid = get_user_id ( keyid, &uidlen );
|
||||||
timestr = strtimestamp (pk->timestamp);
|
timestr = strtimestamp (pk->timestamp);
|
||||||
|
|
||||||
#undef KEYIDSTRING
|
#undef KEYIDSTRING
|
||||||
@ -350,7 +350,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
|
|||||||
"%u-bit %s key, ID %s,\n" \
|
"%u-bit %s key, ID %s,\n" \
|
||||||
"created %s%s.\n" )
|
"created %s%s.\n" )
|
||||||
|
|
||||||
atext = xmalloc ( 100 + strlen (PROMPTSTRING)
|
atext = xmalloc ( 100 + strlen (PROMPTSTRING)
|
||||||
+ uidlen + 15 + strlen(algo_name) + keystrlen()
|
+ uidlen + 15 + strlen(algo_name) + keystrlen()
|
||||||
+ strlen (timestr) + strlen (maink) );
|
+ strlen (timestr) + strlen (maink) );
|
||||||
sprintf (atext, PROMPTSTRING,
|
sprintf (atext, PROMPTSTRING,
|
||||||
@ -362,16 +362,16 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
|
|||||||
|
|
||||||
#undef PROMPTSTRING
|
#undef PROMPTSTRING
|
||||||
|
|
||||||
{
|
{
|
||||||
size_t dummy;
|
size_t dummy;
|
||||||
fingerprint_from_pk( pk, fpr, &dummy );
|
fingerprint_from_pk( pk, fpr, &dummy );
|
||||||
have_fpr = 1;
|
have_fpr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
atext = xstrdup ( _("Enter passphrase\n") );
|
atext = xstrdup ( _("Enter passphrase\n") );
|
||||||
|
|
||||||
|
|
||||||
if (!mode && cacheid)
|
if (!mode && cacheid)
|
||||||
my_cacheid = cacheid;
|
my_cacheid = cacheid;
|
||||||
@ -387,7 +387,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
|
|||||||
|
|
||||||
rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext,
|
rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext,
|
||||||
repeat, check, &pw);
|
repeat, check, &pw);
|
||||||
|
|
||||||
xfree (my_prompt);
|
xfree (my_prompt);
|
||||||
xfree (atext); atext = NULL;
|
xfree (atext); atext = NULL;
|
||||||
|
|
||||||
@ -396,14 +396,14 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
|
|||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
;
|
;
|
||||||
else if (gpg_err_code (rc) == GPG_ERR_CANCELED
|
else if (gpg_err_code (rc) == GPG_ERR_CANCELED
|
||||||
|| gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
|
|| gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
|
||||||
{
|
{
|
||||||
log_info (_("cancelled by user\n") );
|
log_info (_("cancelled by user\n") );
|
||||||
if (canceled)
|
if (canceled)
|
||||||
*canceled = 1;
|
*canceled = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_error (_("problem with the agent: %s\n"), gpg_strerror (rc));
|
log_error (_("problem with the agent: %s\n"), gpg_strerror (rc));
|
||||||
/* Due to limitations in the API of the upper layers they
|
/* Due to limitations in the API of the upper layers they
|
||||||
@ -412,7 +412,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
|
|||||||
definitely not happen and let it continue without requiring a
|
definitely not happen and let it continue without requiring a
|
||||||
passphrase. Given that now all the upper layers handle a
|
passphrase. Given that now all the upper layers handle a
|
||||||
cancel correctly, we simply set the cancel flag now for all
|
cancel correctly, we simply set the cancel flag now for all
|
||||||
errors from the agent. */
|
errors from the agent. */
|
||||||
if (canceled)
|
if (canceled)
|
||||||
*canceled = 1;
|
*canceled = 1;
|
||||||
|
|
||||||
@ -440,7 +440,7 @@ passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
(void)algo;
|
(void)algo;
|
||||||
|
|
||||||
if (!cacheid)
|
if (!cacheid)
|
||||||
{
|
{
|
||||||
PKT_public_key *pk;
|
PKT_public_key *pk;
|
||||||
@ -450,7 +450,7 @@ passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
|
|||||||
byte fpr[MAX_FINGERPRINT_LEN];
|
byte fpr[MAX_FINGERPRINT_LEN];
|
||||||
char hexfprbuf[2*20+1];
|
char hexfprbuf[2*20+1];
|
||||||
size_t dummy;
|
size_t dummy;
|
||||||
|
|
||||||
pk = xcalloc (1, sizeof *pk);
|
pk = xcalloc (1, sizeof *pk);
|
||||||
if ( !keyid || get_pubkey( pk, keyid ) )
|
if ( !keyid || get_pubkey( pk, keyid ) )
|
||||||
{
|
{
|
||||||
@ -478,7 +478,7 @@ passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
|
|||||||
NULL, sets it to true.
|
NULL, sets it to true.
|
||||||
|
|
||||||
MODE 0: Allow cached passphrase
|
MODE 0: Allow cached passphrase
|
||||||
1: Ignore cached passphrase
|
1: Ignore cached passphrase
|
||||||
2: Ditto, but create a new key
|
2: Ditto, but create a new key
|
||||||
3: Allow cached passphrase; use the S2K salt as the cache ID
|
3: Allow cached passphrase; use the S2K salt as the cache ID
|
||||||
4: Ditto, but create a new key
|
4: Ditto, but create a new key
|
||||||
@ -486,7 +486,7 @@ passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
|
|||||||
DEK *
|
DEK *
|
||||||
passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
|
passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
|
||||||
int cipher_algo, STRING2KEY *s2k, int mode,
|
int cipher_algo, STRING2KEY *s2k, int mode,
|
||||||
const char *tryagain_text,
|
const char *tryagain_text,
|
||||||
const char *custdesc, const char *custprompt,
|
const char *custdesc, const char *custprompt,
|
||||||
int *canceled)
|
int *canceled)
|
||||||
{
|
{
|
||||||
@ -499,11 +499,11 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
|
|||||||
if (!canceled)
|
if (!canceled)
|
||||||
canceled = &dummy_canceled;
|
canceled = &dummy_canceled;
|
||||||
*canceled = 0;
|
*canceled = 0;
|
||||||
|
|
||||||
if ( !s2k )
|
if ( !s2k )
|
||||||
{
|
{
|
||||||
assert (mode != 3 && mode != 4);
|
assert (mode != 3 && mode != 4);
|
||||||
/* This is used for the old rfc1991 mode
|
/* This is used for the old rfc1991 mode
|
||||||
* Note: This must match the code in encode.c with opt.rfc1991 set */
|
* Note: This must match the code in encode.c with opt.rfc1991 set */
|
||||||
s2k = &help_s2k;
|
s2k = &help_s2k;
|
||||||
s2k->mode = 0;
|
s2k->mode = 0;
|
||||||
@ -529,16 +529,16 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
|
|||||||
|
|
||||||
/* If we do not have a passphrase available in NEXT_PW and status
|
/* If we do not have a passphrase available in NEXT_PW and status
|
||||||
information are request, we print them now. */
|
information are request, we print them now. */
|
||||||
if ( !next_pw && is_status_enabled() )
|
if ( !next_pw && is_status_enabled() )
|
||||||
{
|
{
|
||||||
char buf[50];
|
char buf[50];
|
||||||
|
|
||||||
if ( keyid )
|
if ( keyid )
|
||||||
{
|
{
|
||||||
u32 used_kid[2];
|
u32 used_kid[2];
|
||||||
char *us;
|
char *us;
|
||||||
|
|
||||||
if ( keyid[2] && keyid[3] )
|
if ( keyid[2] && keyid[3] )
|
||||||
{
|
{
|
||||||
used_kid[0] = keyid[2];
|
used_kid[0] = keyid[2];
|
||||||
used_kid[1] = keyid[3];
|
used_kid[1] = keyid[3];
|
||||||
@ -548,16 +548,16 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
|
|||||||
used_kid[0] = keyid[0];
|
used_kid[0] = keyid[0];
|
||||||
used_kid[1] = keyid[1];
|
used_kid[1] = keyid[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
us = get_long_user_id_string ( keyid );
|
us = get_long_user_id_string ( keyid );
|
||||||
write_status_text ( STATUS_USERID_HINT, us );
|
write_status_text ( STATUS_USERID_HINT, us );
|
||||||
xfree(us);
|
xfree(us);
|
||||||
|
|
||||||
snprintf (buf, sizeof buf -1, "%08lX%08lX %08lX%08lX %d 0",
|
snprintf (buf, sizeof buf -1, "%08lX%08lX %08lX%08lX %d 0",
|
||||||
(ulong)keyid[0], (ulong)keyid[1],
|
(ulong)keyid[0], (ulong)keyid[1],
|
||||||
(ulong)used_kid[0], (ulong)used_kid[1],
|
(ulong)used_kid[0], (ulong)used_kid[1],
|
||||||
pubkey_algo );
|
pubkey_algo );
|
||||||
|
|
||||||
write_status_text ( STATUS_NEED_PASSPHRASE, buf );
|
write_status_text ( STATUS_NEED_PASSPHRASE, buf );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -576,7 +576,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
|
|||||||
{
|
{
|
||||||
PKT_public_key *pk = xmalloc_clear( sizeof *pk );
|
PKT_public_key *pk = xmalloc_clear( sizeof *pk );
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
p = get_user_id_native(keyid);
|
p = get_user_id_native(keyid);
|
||||||
tty_printf ("\n");
|
tty_printf ("\n");
|
||||||
tty_printf (_("You need a passphrase to unlock the secret key for\n"
|
tty_printf (_("You need a passphrase to unlock the secret key for\n"
|
||||||
@ -586,7 +586,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
|
|||||||
if ( !get_pubkey( pk, keyid ) )
|
if ( !get_pubkey( pk, keyid ) )
|
||||||
{
|
{
|
||||||
const char *s = openpgp_pk_algo_name ( pk->pubkey_algo );
|
const char *s = openpgp_pk_algo_name ( pk->pubkey_algo );
|
||||||
|
|
||||||
tty_printf (_("%u-bit %s key, ID %s, created %s"),
|
tty_printf (_("%u-bit %s key, ID %s, created %s"),
|
||||||
nbits_from_pk( pk ), s?s:"?", keystr(keyid),
|
nbits_from_pk( pk ), s?s:"?", keystr(keyid),
|
||||||
strtimestamp(pk->timestamp) );
|
strtimestamp(pk->timestamp) );
|
||||||
@ -610,19 +610,19 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
|
|||||||
free_public_key( pk );
|
free_public_key( pk );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( next_pw )
|
if ( next_pw )
|
||||||
{
|
{
|
||||||
/* Simply return the passphrase we already have in NEXT_PW. */
|
/* Simply return the passphrase we already have in NEXT_PW. */
|
||||||
pw = next_pw;
|
pw = next_pw;
|
||||||
next_pw = NULL;
|
next_pw = NULL;
|
||||||
}
|
}
|
||||||
else if ( have_static_passphrase () )
|
else if ( have_static_passphrase () )
|
||||||
{
|
{
|
||||||
/* Return the passphrase we have stored in FD_PASSWD. */
|
/* Return the passphrase we have stored in FD_PASSWD. */
|
||||||
pw = xmalloc_secure ( strlen(fd_passwd)+1 );
|
pw = xmalloc_secure ( strlen(fd_passwd)+1 );
|
||||||
strcpy ( pw, fd_passwd );
|
strcpy ( pw, fd_passwd );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((mode == 3 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3))
|
if ((mode == 3 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3))
|
||||||
{
|
{
|
||||||
@ -643,7 +643,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !pw || !*pw )
|
if ( !pw || !*pw )
|
||||||
write_status( STATUS_MISSING_PASSPHRASE );
|
write_status( STATUS_MISSING_PASSPHRASE );
|
||||||
|
|
||||||
@ -689,15 +689,15 @@ gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped)
|
|||||||
char *maink;
|
char *maink;
|
||||||
char *desc;
|
char *desc;
|
||||||
const char *prompt;
|
const char *prompt;
|
||||||
|
|
||||||
algo_name = openpgp_pk_algo_name (pk->pubkey_algo);
|
algo_name = openpgp_pk_algo_name (pk->pubkey_algo);
|
||||||
timestr = strtimestamp (pk->timestamp);
|
timestr = strtimestamp (pk->timestamp);
|
||||||
uid = get_user_id (pk->keyid, &uidlen);
|
uid = get_user_id (pk->keyid, &uidlen);
|
||||||
|
|
||||||
orig_codeset = i18n_switchto_utf8 ();
|
orig_codeset = i18n_switchto_utf8 ();
|
||||||
|
|
||||||
if (pk->main_keyid[0] && pk->main_keyid[1]
|
if (pk->main_keyid[0] && pk->main_keyid[1]
|
||||||
&& pk->keyid[0] != pk->main_keyid[0]
|
&& pk->keyid[0] != pk->main_keyid[0]
|
||||||
&& pk->keyid[1] != pk->main_keyid[1])
|
&& pk->keyid[1] != pk->main_keyid[1])
|
||||||
maink = xtryasprintf (_(" (main key ID %s)"), keystr (pk->main_keyid));
|
maink = xtryasprintf (_(" (main key ID %s)"), keystr (pk->main_keyid));
|
||||||
else
|
else
|
||||||
@ -724,7 +724,7 @@ gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped)
|
|||||||
"created %s%s.\n"),
|
"created %s%s.\n"),
|
||||||
prompt,
|
prompt,
|
||||||
(int)uidlen, uid,
|
(int)uidlen, uid,
|
||||||
nbits_from_pk (pk), algo_name,
|
nbits_from_pk (pk), algo_name,
|
||||||
keystr (pk->keyid), timestr,
|
keystr (pk->keyid), timestr,
|
||||||
maink?maink:"" );
|
maink?maink:"" );
|
||||||
xfree (maink);
|
xfree (maink);
|
||||||
@ -735,7 +735,7 @@ gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped)
|
|||||||
if (escaped)
|
if (escaped)
|
||||||
{
|
{
|
||||||
char *tmp = percent_plus_escape (desc);
|
char *tmp = percent_plus_escape (desc);
|
||||||
xfree (desc);
|
xfree (desc);
|
||||||
desc = tmp;
|
desc = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2011-02-01 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* cipher.h (PUBKEY_MAX_NPKEY, PUBKEY_MAX_NSKEY): Bump up to
|
||||||
|
accommodate gcrypt ECC keys.
|
||||||
|
|
||||||
2011-01-21 Werner Koch <wk@g10code.com>
|
2011-01-21 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* cipher.h (GCRY_PK_USAGE_CERT): Remove compatibility macros
|
* cipher.h (GCRY_PK_USAGE_CERT): Remove compatibility macros
|
||||||
|
@ -100,8 +100,8 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
/* Constants to allocate static MPI arrays. */
|
/* Constants to allocate static MPI arrays. */
|
||||||
#define PUBKEY_MAX_NPKEY 4
|
#define PUBKEY_MAX_NPKEY 5
|
||||||
#define PUBKEY_MAX_NSKEY 6
|
#define PUBKEY_MAX_NSKEY 7
|
||||||
#define PUBKEY_MAX_NSIG 2
|
#define PUBKEY_MAX_NSIG 2
|
||||||
#define PUBKEY_MAX_NENC 2
|
#define PUBKEY_MAX_NENC 2
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
no-creation-time.gpg A key with a zero creation time.
|
no-creation-time.gpg A key with a zero creation time.
|
||||||
|
ecc-sample-1-pub.asc The first ECC sample key.
|
||||||
|
ecc-sample-1-sec.asc The first ECC sample key (secret).
|
||||||
|
|
||||||
|
22
tests/openpgp/samplekeys/ecc-sample-1-pub.asc
Normal file
22
tests/openpgp/samplekeys/ecc-sample-1-pub.asc
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
The key has been generated by the first GnuPG ECC version at
|
||||||
|
http://code.google.com/p/gnupg-ecc.
|
||||||
|
|
||||||
|
The sample key has ECDSA top key 0xBAA59D9C and a single ECDH
|
||||||
|
encryption subkey 0x4089AB73. ECDH subkey uses SHA-256 and AES-128
|
||||||
|
with KDF.
|
||||||
|
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: GnuPG v2.1.0-ecc (GNU/Linux)
|
||||||
|
|
||||||
|
mFIETJPQrRMIKoZIzj0DAQcCAwQLx6e669XwjHTHe3HuROe7C1oYMXuZbaU5PjOs
|
||||||
|
xSkyxtL2D00e/jWgufuNN4ftS+6XygEtB7j1g1vnCTVF1TLmtCRlY19kc2FfZGhf
|
||||||
|
MjU2IDxvcGVucGdwQGJyYWluaHViLm9yZz6IegQTEwgAIgUCTJPQrQIbAwYLCQgH
|
||||||
|
AwIGFQgCCQoLBBYCAwECHgECF4AACgkQC6Ut8LqlnZzmXQEAiKgiSzPSpUOJcX9d
|
||||||
|
JtLJ5As98Alit2oFwzhxG7mSVmQA/RP67yOeoUtdsK6bwmRA95cwf9lBIusNjehx
|
||||||
|
XDfpHj+/uFYETJPQrRIIKoZIzj0DAQcCAwR/cMCoGEzcrqXbILqP7Rfke977dE1X
|
||||||
|
XsRJEwrzftreZYrn7jXSDoiXkRyfVkvjPZqUvB5cknsaoH/3UNLRHClxAwEIB4hh
|
||||||
|
BBgTCAAJBQJMk9CtAhsMAAoJEAulLfC6pZ2c1yYBAOSUmaQ8rkgihnepbnpK7tNz
|
||||||
|
3QEocsLEtsTCDUBGNYGyAQDclifYqsUChXlWKaw3md+yHJPcWZXzHt37c4q/MhIm
|
||||||
|
oQ==
|
||||||
|
=hMzp
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
25
tests/openpgp/samplekeys/ecc-sample-1-sec.asc
Normal file
25
tests/openpgp/samplekeys/ecc-sample-1-sec.asc
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
The key has been generated by the first GnuPG ECC version at
|
||||||
|
http://code.google.com/p/gnupg-ecc.
|
||||||
|
|
||||||
|
The sample key has ECDSA top key 0xBAA59D9C and a single ECDH
|
||||||
|
encryption subkey 0x4089AB73. ECDH subkey uses SHA-256 and AES-128
|
||||||
|
with KDF. The password for the key is "ecc".
|
||||||
|
|
||||||
|
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
|
Version: GnuPG v2.1.0-ecc (GNU/Linux)
|
||||||
|
|
||||||
|
lJ0ETJPQrRMIKoZIzj0DAQcCAwQLx6e669XwjHTHe3HuROe7C1oYMXuZbaU5PjOs
|
||||||
|
xSkyxtL2D00e/jWgufuNN4ftS+6XygEtB7j1g1vnCTVF1TLm/gMDAmHomSLb9NbE
|
||||||
|
oyWUoqgKTbZzbFR/SWmiCcuiQEhREcTyvyU1hAglj7FsBJoQ6/pbeAEQZ3bVzlNM
|
||||||
|
8F0nF8KPLPuEADF1+4CntCRlY19kc2FfZGhfMjU2IDxvcGVucGdwQGJyYWluaHVi
|
||||||
|
Lm9yZz6IegQTEwgAIgUCTJPQrQIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA
|
||||||
|
CgkQC6Ut8LqlnZzmXQEAiKgiSzPSpUOJcX9dJtLJ5As98Alit2oFwzhxG7mSVmQA
|
||||||
|
/RP67yOeoUtdsK6bwmRA95cwf9lBIusNjehxXDfpHj+/nKEETJPQrRIIKoZIzj0D
|
||||||
|
AQcCAwR/cMCoGEzcrqXbILqP7Rfke977dE1XXsRJEwrzftreZYrn7jXSDoiXkRyf
|
||||||
|
VkvjPZqUvB5cknsaoH/3UNLRHClxAwEIB/4DAwJh6Jki2/TWxKO7gHKWIcOcxYZp
|
||||||
|
CRWjlUghbKb6Q83p8GLPjKRN0USl/U1tObWdksqMXhUO0ePLWUnrbwoWYfYXg9Er
|
||||||
|
ADTgCYhhBBgTCAAJBQJMk9CtAhsMAAoJEAulLfC6pZ2c1yYA/3eJRirPQZmBno+Z
|
||||||
|
P/HOBSFWmFt4cUBGUx3oqiUd5loOAP480pb+vXx9ipljJWCJDSl/boRSuqB4hePP
|
||||||
|
qt9Rd5gNdQ==
|
||||||
|
=O8Dg
|
||||||
|
-----END PGP PRIVATE KEY BLOCK-----
|
Loading…
x
Reference in New Issue
Block a user