mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
MDC feature support and other stuff
This commit is contained in:
parent
64d586ef17
commit
bab40b52cd
6
NEWS
6
NEWS
@ -24,7 +24,11 @@
|
||||
* Merged Stefan's patches for RISC OS in. See comments in
|
||||
scripts/build-riscos.
|
||||
|
||||
* It is now possible to sign an convenional encrypt a message (-cs).
|
||||
* It is now possible to sign and convenional encrypt a message (-cs).
|
||||
|
||||
* The MDC feature flag is supported and can be set by using
|
||||
the "updpref" edit command.
|
||||
|
||||
|
||||
Noteworthy changes in version 1.0.6 (2001-05-29)
|
||||
------------------------------------------------
|
||||
|
16
TODO
16
TODO
@ -1,4 +1,5 @@
|
||||
|
||||
* need a BAD_PASSPHRASE status for -c
|
||||
|
||||
* add listing of notation data
|
||||
|
||||
@ -9,11 +10,6 @@
|
||||
|
||||
* Show more info does not work from edit->trust
|
||||
|
||||
* keyedit_menu: We first look for a secret key and then for a public
|
||||
key. This is bad we must match the keys. Better check all places
|
||||
were we match keys. build_sig_packet: implement update for
|
||||
sig-creation.
|
||||
|
||||
* set default charset from nl_langinfo.
|
||||
|
||||
* check all mpi_read() for error returns.
|
||||
@ -79,10 +75,18 @@
|
||||
preferences is okay and make AES the default.
|
||||
|
||||
* Concatenated encryption messages don't work corectly - only the
|
||||
first one is processes.
|
||||
first one is processed.
|
||||
|
||||
* Add status message for reasons why a key was not selected.
|
||||
|
||||
* Add option to put the list of recipients (from the encryption
|
||||
layer) into the signatures notation data.
|
||||
|
||||
* v3 RSA keys do work but the user IDs are shown as [?] which
|
||||
cheking the signatures. Reported by Dave Dykstra. Print
|
||||
"[uncertain]" + user ID
|
||||
|
||||
|
||||
Scheduled for 1.1
|
||||
-----------------
|
||||
* export by user-IDs does only export the first matching name which leads
|
||||
|
@ -18,3 +18,8 @@ secret key 9D266E0F expired at
|
||||
: expired at
|
||||
gpg: Note: This key has expired!
|
||||
gpg: Fingerprint: 0826 1CB7 C976 5344 E207 4184 3C6B BBE6 9D26 6E0F
|
||||
gpg: 3DES encrypted data
|
||||
gpg: CAST5 encrypted data
|
||||
gpg: BLOWFISH encrypted data
|
||||
gpg: TWOFISH encrypted data
|
||||
gpg: RIJNDAEL encrypted data
|
||||
|
@ -1,3 +1,8 @@
|
||||
2001-08-29 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* faq.raw: Described how to delete a secret key w/o a public key
|
||||
and changed the entry on updating the preferences.
|
||||
|
||||
2001-08-08 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* gpg.sgml: Documented --print-mds and marked the --print-md * as
|
||||
|
@ -227,7 +227,7 @@ more arguments in future versions.
|
||||
Mark the start and end of the actual decryption process. These
|
||||
are also emitted when in --list-only mode.
|
||||
|
||||
BEGIN_ENCRYPTION
|
||||
BEGIN_ENCRYPTION <mdc_method> <sym_algo>
|
||||
END_ENCRYPTION
|
||||
Mark the start and end of the actual encryption process.
|
||||
|
||||
|
88
doc/FAQ
88
doc/FAQ
@ -45,21 +45,22 @@ you could search in the mailing list archive.
|
||||
4.4) What is the difference between options and commands?
|
||||
4.5) I can't delete an user id because it is already deleted on my public
|
||||
keyring?
|
||||
4.6) What are trust, validity and ownertrust?
|
||||
4.7) How do I sign a patch file?
|
||||
4.8) Where is the "encrypt-to-self" option?
|
||||
4.9) How can I get rid of the Version and Comment headers in armored
|
||||
4.6) I can't delete the secret key because my public key disappeared?
|
||||
4.7) What are trust, validity and ownertrust?
|
||||
4.8) How do I sign a patch file?
|
||||
4.9) Where is the "encrypt-to-self" option?
|
||||
4.10) How can I get rid of the Version and Comment headers in armored
|
||||
messages?
|
||||
4.10) What does the "You are using the xxxx character set." mean?
|
||||
4.11) How can a get list of key IDs used to encrypt a message?
|
||||
4.12) I can't decrypt my symmetrical only (-c) encrypted message with
|
||||
4.11) What does the "You are using the xxxx character set." mean?
|
||||
4.12) How can a get list of key IDs used to encrypt a message?
|
||||
4.13) I can't decrypt my symmetrical only (-c) encrypted message with
|
||||
a new version of GnuPG.
|
||||
4.13) How can I used GnuPG in an automated environment?
|
||||
4.14) Which email-client can I use with GnuPG?
|
||||
4.15) Can't we have a gpg library?
|
||||
4.16) I have successfully generated a revocation certificate, but I don't
|
||||
4.14) How can I used GnuPG in an automated environment?
|
||||
4.15) Which email-client can I use with GnuPG?
|
||||
4.16) Can't we have a gpg library?
|
||||
4.17) I have successfully generated a revocation certificate, but I don't
|
||||
understand how to send it to the key servers.
|
||||
4.17) How do I put my keyring in a different directory?
|
||||
4.18) How do I put my keyring in a different directory?
|
||||
|
||||
5. COMPATIBILITY ISSUES
|
||||
5.1) How can I encrypt a message with GnuPG so that PGP is able to decrypt it?
|
||||
@ -330,7 +331,18 @@ keyring?
|
||||
ring. Now select this user id and delete it. Both user ids will be
|
||||
removed from the secret ring.
|
||||
|
||||
4.6) What are trust, validity and ownertrust?
|
||||
4.6) I can't delete the secret key because my public key disappeared?
|
||||
|
||||
To select a key a search is always done on the public keyring,
|
||||
therefore it is not possible to select an secret key without
|
||||
having the public key. Normally it shoud never happen that the
|
||||
public key got lost but the secret key is still available. The
|
||||
reality is different, so we GnuPG implements a special way to do
|
||||
deal with it: Simply use the long keyid which you can figure out
|
||||
by using the --with-colons options (it is the fifth field in the
|
||||
lines beginning with "sec").
|
||||
|
||||
4.7) What are trust, validity and ownertrust?
|
||||
|
||||
"ownertrust" is used instead of "trust" to make clear that this is
|
||||
the value you have assigned to a key to express how much you trust
|
||||
@ -340,7 +352,7 @@ keyring?
|
||||
who claims to be the owner of the key). For more see the chapter
|
||||
"The Web of Trust" in the Manual.
|
||||
|
||||
4.7) How do I sign a patch file?
|
||||
4.8) How do I sign a patch file?
|
||||
|
||||
Use "gpg --clearsign --not-dash-escaped ...". The problem with
|
||||
--clearsign is that all lines starting with a dash are quoted with
|
||||
@ -353,19 +365,19 @@ keyring?
|
||||
mailer may not preserve these. If you want to mail a file you can
|
||||
simply sign it using your MUA.
|
||||
|
||||
4.8) Where is the "encrypt-to-self" option?
|
||||
4.9) Where is the "encrypt-to-self" option?
|
||||
|
||||
Use "--encrypt-to your_keyid". You can use more than one of these
|
||||
options. To temporary override the use of this additional keys, you
|
||||
can use the option "--no-encrypt-to".
|
||||
|
||||
4.9) How can I get rid of the Version and Comment headers in armored
|
||||
4.10) How can I get rid of the Version and Comment headers in armored
|
||||
messages?
|
||||
|
||||
Use "--no-version --comment ''". Note that the left over blank line
|
||||
is required by the protocol.
|
||||
|
||||
4.10) What does the "You are using the xxxx character set." mean?
|
||||
4.11) What does the "You are using the xxxx character set." mean?
|
||||
|
||||
This note is printed when UTF8 mapping has to be done. Make sure
|
||||
that the displayed charset is the one you have activated on your
|
||||
@ -375,12 +387,12 @@ messages?
|
||||
if not, restrict yourself to plain 7 bit ASCII and no mapping has to
|
||||
be done.
|
||||
|
||||
4.11) How can a get list of key IDs used to encrypt a message?
|
||||
4.12) How can a get list of key IDs used to encrypt a message?
|
||||
|
||||
gpg --batch --decrypt --list-only --status-fd 1 2>/dev/null | \
|
||||
awk '/^\[GNUPG:\] ENC_TO / { print $3 }'
|
||||
|
||||
4.12) I can't decrypt my symmetrical only (-c) encrypted message with
|
||||
4.13) I can't decrypt my symmetrical only (-c) encrypted message with
|
||||
a new version of GnuPG.
|
||||
|
||||
There used to be a bug in GnuPG < 1.0.1 which happens only if 3DES
|
||||
@ -391,7 +403,7 @@ messages?
|
||||
without this option. The option will be removed in 1.1, so better
|
||||
re-encrypt your message now.
|
||||
|
||||
4.13) How can I used GnuPG in an automated environment?
|
||||
4.14) How can I used GnuPG in an automated environment?
|
||||
|
||||
You should use the option --batch and don't use pass phrases as
|
||||
there is usually no way to store it more secure than the secret
|
||||
@ -415,7 +427,7 @@ messages?
|
||||
turn can revoke all the subkeys installed on that machine and
|
||||
install new subkeys.
|
||||
|
||||
4.14) Which email-client can I use with GnuPG?
|
||||
4.15) Which email-client can I use with GnuPG?
|
||||
|
||||
Using GnuPG to encrypt email is one of the most popular
|
||||
uses. Several mail clients or mail user-agents (MUA) support GnuPG
|
||||
@ -441,7 +453,7 @@ messages?
|
||||
may be possible to use a wrapper.
|
||||
|
||||
|
||||
4.15) Can't we have a gpg library?
|
||||
4.16) Can't we have a gpg library?
|
||||
|
||||
This has been frequently requested. However, the current viewpoint
|
||||
of the GnuPG maintainers is that this would lead to several security
|
||||
@ -451,7 +463,7 @@ messages?
|
||||
ftp://ftp.guug.de/pub/gcrypt/alpha/gpgme
|
||||
|
||||
|
||||
4.16) I have successfully generated a revocation certificate, but I don't
|
||||
4.17) I have successfully generated a revocation certificate, but I don't
|
||||
understand how to send it to the key servers.
|
||||
|
||||
Most keyservers don't accept a 'bare' revocation certificate. You
|
||||
@ -462,7 +474,7 @@ messages?
|
||||
(or use a keyserver web interface for this).
|
||||
|
||||
|
||||
4.17) How do I put my keyring in a different directory?
|
||||
4.18) How do I put my keyring in a different directory?
|
||||
|
||||
GnuPG keeps several files in a special homedir directory. These
|
||||
include the options file, pubring.gpg, secring.gpg, the trustdb, and
|
||||
@ -915,25 +927,15 @@ material?
|
||||
|
||||
7.8) How do I change the list of preferred algorithms?
|
||||
|
||||
Currently the default is hard-wired into the GnuPG source code.
|
||||
You'll have to change g10/keygen.c and recompile. The
|
||||
function you'll have to change is keygen_add_std_prefs.
|
||||
The code is pretty self-explanatory. The constants used to
|
||||
denote the algorithms are defined in include/cipher.h.
|
||||
|
||||
After having done that, generate a new key pair (or a new encryption
|
||||
subkey) with the modified executable. This new key will have the
|
||||
modified preferences and can then be used with unmodified executables.
|
||||
|
||||
To modify the preferences of an existing key, use a modified
|
||||
executable (see above) to change the expiry date and then save the
|
||||
key. The use your original expiry date and save the key again. Now
|
||||
you've got the prefs changed and can use the key again with your
|
||||
unmodified executable.
|
||||
|
||||
Changing the list of preferences with an unmodified GnuPG
|
||||
executable (possibly in the edit-key menu) is on the TODO list and
|
||||
planned for future releases.
|
||||
Use the edit menu and set the new list of preference using the
|
||||
command "setpref"; the format of this command resembles the output
|
||||
of the command "pref". The preference are not changes immediately
|
||||
but the set preference will be used when a new user ID is
|
||||
created. If you want to update the preferences for existing user
|
||||
IDs, select those user IDs (or select none to update all) and
|
||||
enter the command "updpref". Note that the timestamp of the
|
||||
self-signaures is increaded by one second when running this
|
||||
command.
|
||||
|
||||
|
||||
8. ACKNOWLEDGEMENTS
|
||||
|
39
doc/faq.raw
39
doc/faq.raw
@ -279,6 +279,17 @@ keyring?
|
||||
ring. Now select this user id and delete it. Both user ids will be
|
||||
removed from the secret ring.
|
||||
|
||||
<Q> I can't delete the secret key because my public key disappeared?
|
||||
|
||||
To select a key a search is always done on the public keyring,
|
||||
therefore it is not possible to select an secret key without
|
||||
having the public key. Normally it shoud never happen that the
|
||||
public key got lost but the secret key is still available. The
|
||||
reality is different, so we GnuPG implements a special way to do
|
||||
deal with it: Simply use the long keyid which you can figure out
|
||||
by using the --with-colons options (it is the fifth field in the
|
||||
lines beginning with "sec").
|
||||
|
||||
<Q> What are trust, validity and ownertrust?
|
||||
|
||||
"ownertrust" is used instead of "trust" to make clear that this is
|
||||
@ -887,25 +898,15 @@ material?
|
||||
|
||||
<Q> How do I change the list of preferred algorithms?
|
||||
|
||||
Currently the default is hard-wired into the GnuPG source code.
|
||||
You'll have to change [H pre]g10/keygen.c[H/pre] and recompile. The
|
||||
function you'll have to change is [H pre]keygen_add_std_prefs[H /pre].
|
||||
The code is pretty self-explanatory. The constants used to
|
||||
denote the algorithms are defined in [H pre]include/cipher.h[H /pre].
|
||||
|
||||
After having done that, generate a new key pair (or a new encryption
|
||||
subkey) with the modified executable. This new key will have the
|
||||
modified preferences and can then be used with unmodified executables.
|
||||
|
||||
To modify the preferences of an existing key, use a modified
|
||||
executable (see above) to change the expiry date and then save the
|
||||
key. The use your original expiry date and save the key again. Now
|
||||
you've got the prefs changed and can use the key again with your
|
||||
unmodified executable.
|
||||
|
||||
Changing the list of preferences with an unmodified GnuPG
|
||||
executable (possibly in the edit-key menu) is on the TODO list and
|
||||
planned for future releases.
|
||||
Use the edit menu and set the new list of preference using the
|
||||
command "setpref"; the format of this command resembles the output
|
||||
of the command "pref". The preference are not changes immediately
|
||||
but the set preference will be used when a new user ID is
|
||||
created. If you want to update the preferences for existing user
|
||||
IDs, select those user IDs (or select none to update all) and
|
||||
enter the command "updpref". Note that the timestamp of the
|
||||
self-signaures is increaded by one second when running this
|
||||
command.
|
||||
|
||||
|
||||
<S> ACKNOWLEDGEMENTS
|
||||
|
@ -1,3 +1,45 @@
|
||||
2001-08-30 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* packet.h (sigsubpkttype_t): Add SIGSUBPKT_FEATURES.
|
||||
(PKT_public_key, PKT_user_id): Add a flag for it.
|
||||
* parse-packet.c, build-packet.c: Add support for them.
|
||||
* getkey.c (fixup_uidnode, merge_selfsigs): Set the MDC flags.
|
||||
* keygen.c (add_feature_mdc): New.
|
||||
(keygen_upd_std_prefs): Always set the MDC feature.
|
||||
* keyedit.c (show_prefs): List the MDC flag
|
||||
* pkclist.c (select_mdc_from_pklist): New.
|
||||
* encode.c (encode_crypt, encrypt_filter): Test whether MDC
|
||||
should be used.
|
||||
* cipher.c (write_header): Set MDC use depending on the above test.
|
||||
Print more status info.
|
||||
|
||||
* delkey.c (do_delete_key): Kludge to delete a secret key with no
|
||||
public key available.
|
||||
|
||||
* ringedit.c (find_secret_keyblock_direct): New.
|
||||
* getkey.c (seckey_available): Simplified.
|
||||
|
||||
* ringedit.c (cmp_seckey): Now compares the secret key against the
|
||||
public key while ignoring all secret parts.
|
||||
(keyring_search): Use a public key packet as arg. Allow to search
|
||||
for subnkeys
|
||||
(search): Likewise. Changed all callers.
|
||||
(find_secret_keyblock_bypk): New.
|
||||
(find_secret_keyblock_byname): First locate the pubkey and then
|
||||
find the correponding secret key.
|
||||
* parse-packet.c (parse): Renamed pkttype arg to onlykeypkts and
|
||||
changed code accordingly. Changed all callers.
|
||||
(search_packet): Removed pkttype arg.
|
||||
* keyedit.c (keyedit_menu): First locate the public key and then
|
||||
try to locate a secret key.
|
||||
|
||||
* ringedit.c (locate_keyblock_by_fpr): Removed.
|
||||
(locate_keyblock_by_keyid): Removed.
|
||||
(find_keyblock_bysk): Removed.
|
||||
|
||||
* sig-check.c (check_key_signature2): Print the keyid along with
|
||||
the wrong sig class errors.
|
||||
|
||||
2001-08-24 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* sign.c (sign_file): Stripped the disabled comment packet code.
|
||||
|
@ -747,6 +747,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
|
||||
case SIGSUBPKT_PREF_SYM:
|
||||
case SIGSUBPKT_PREF_HASH:
|
||||
case SIGSUBPKT_PREF_COMPR:
|
||||
case SIGSUBPKT_FEATURES:
|
||||
delete_sig_subpkt (sig->hashed, type);
|
||||
break;
|
||||
default:
|
||||
@ -783,6 +784,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
|
||||
case SIGSUBPKT_REVOC_REASON:
|
||||
case SIGSUBPKT_PRIMARY_UID:
|
||||
case SIGSUBPKT_KEY_FLAGS:
|
||||
case SIGSUBPKT_FEATURES:
|
||||
hashed = 1; break;
|
||||
default: hashed = 0; break;
|
||||
}
|
||||
|
24
g10/cipher.c
24
g10/cipher.c
@ -47,16 +47,27 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
|
||||
byte temp[18];
|
||||
unsigned blocksize;
|
||||
unsigned nprefix;
|
||||
int use_mdc = opt.force_mdc;
|
||||
int use_mdc;
|
||||
|
||||
blocksize = cipher_get_blocksize( cfx->dek->algo );
|
||||
if( blocksize < 8 || blocksize > 16 )
|
||||
log_fatal("unsupported blocksize %u\n", blocksize );
|
||||
|
||||
use_mdc = cfx->dek->use_mdc;
|
||||
|
||||
if( blocksize != 8 )
|
||||
use_mdc = 1; /* enable it for all modern ciphers */
|
||||
use_mdc = 1; /* Hack: enable it for all modern ciphers */
|
||||
/* Note: We should remove this hack as soon as a reasonable number of keys
|
||||
are carrying the MDC flag. But always keep the hack for conventional
|
||||
encryption */
|
||||
|
||||
if (opt.force_mdc)
|
||||
use_mdc = 1;
|
||||
|
||||
if( opt.rfc2440 || opt.rfc1991 )
|
||||
use_mdc = 0; /* override - rfc2440 does not know about MDC */
|
||||
|
||||
|
||||
memset( &ed, 0, sizeof ed );
|
||||
ed.len = cfx->datalen;
|
||||
ed.extralen = blocksize+2;
|
||||
@ -67,6 +78,14 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
|
||||
if ( DBG_HASHING )
|
||||
md_start_debug( cfx->mdc_hash, "creatmdc" );
|
||||
}
|
||||
|
||||
{
|
||||
char buf[20];
|
||||
|
||||
sprintf (buf, "%d %d", ed.mdc_method, cfx->dek->algo);
|
||||
write_status_text (STATUS_BEGIN_ENCRYPTION, buf);
|
||||
}
|
||||
|
||||
init_packet( &pkt );
|
||||
pkt.pkttype = use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED;
|
||||
pkt.pkt.encrypted = &ed;
|
||||
@ -111,7 +130,6 @@ cipher_filter( void *opaque, int control,
|
||||
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
|
||||
assert(a);
|
||||
if( !cfx->header ) {
|
||||
write_status( STATUS_BEGIN_ENCRYPTION );
|
||||
write_header( cfx, a );
|
||||
}
|
||||
if( cfx->mdc_hash )
|
||||
|
14
g10/delkey.c
14
g10/delkey.c
@ -61,8 +61,18 @@ do_delete_key( const char *username, int secret, int *r_sec_avail )
|
||||
|
||||
*r_sec_avail = 0;
|
||||
/* search the userid */
|
||||
rc = secret? find_secret_keyblock_byname( &kbpos, username )
|
||||
: find_keyblock_byname( &kbpos, username );
|
||||
if (secret
|
||||
&& classify_user_id (username, keyid, NULL, NULL, NULL) == 11) {
|
||||
/* if the user supplied a long keyID we use the direct search
|
||||
methods which allows us to delete a key if the
|
||||
corresponding secret key is missing */
|
||||
rc = find_secret_keyblock_direct (&kbpos, keyid);
|
||||
}
|
||||
else if (secret)
|
||||
rc = find_secret_keyblock_byname (&kbpos, username);
|
||||
else
|
||||
rc = find_keyblock_byname (&kbpos, username);
|
||||
|
||||
if( rc ) {
|
||||
log_error(_("%s: user not found\n"), username );
|
||||
write_status_text( STATUS_DELETE_PROBLEM, "1" );
|
||||
|
@ -299,6 +299,8 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
}
|
||||
else
|
||||
cfx.dek->algo = opt.def_cipher_algo;
|
||||
cfx.dek->use_mdc = select_mdc_from_pklist (pk_list);
|
||||
|
||||
make_session_key( cfx.dek );
|
||||
if( DBG_CIPHER )
|
||||
log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
|
||||
@ -428,6 +430,9 @@ encrypt_filter( void *opaque, int control,
|
||||
}
|
||||
else
|
||||
efx->cfx.dek->algo = opt.def_cipher_algo;
|
||||
|
||||
efx->cfx.dek->use_mdc = select_mdc_from_pklist (efx->pk_list);
|
||||
|
||||
make_session_key( efx->cfx.dek );
|
||||
if( DBG_CIPHER )
|
||||
log_hexdump("DEK is: ",
|
||||
|
70
g10/getkey.c
70
g10/getkey.c
@ -542,55 +542,8 @@ get_seckey( PKT_secret_key *sk, u32 *keyid )
|
||||
int
|
||||
seckey_available( u32 *keyid )
|
||||
{
|
||||
#if 0
|
||||
int rc;
|
||||
struct getkey_ctx_s ctx;
|
||||
KBNODE kb = NULL;
|
||||
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.exact = 1; /* use the key ID exactly as given */
|
||||
ctx.not_allocated = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = 11;
|
||||
ctx.items[0].keyid[0] = keyid[0];
|
||||
ctx.items[0].keyid[1] = keyid[1];
|
||||
rc = lookup( &ctx, &kb, 1 );
|
||||
get_seckey_end( &ctx );
|
||||
release_kbnode ( kb );
|
||||
return rc;
|
||||
#endif
|
||||
int rc;
|
||||
int found = 0;
|
||||
int oldmode = set_packet_list_mode (0);
|
||||
KBNODE keyblock = NULL;
|
||||
KBPOS kbpos;
|
||||
|
||||
rc = enum_keyblocks ( 5, &kbpos, NULL );
|
||||
if ( !rc ) {
|
||||
while ( !(rc = enum_keyblocks (1, &kbpos, &keyblock)) ) {
|
||||
KBNODE k;
|
||||
|
||||
for (k=keyblock; k; k = k->next ) {
|
||||
if ( k->pkt->pkttype == PKT_SECRET_KEY
|
||||
|| k->pkt->pkttype == PKT_SECRET_SUBKEY ) {
|
||||
u32 aki[2];
|
||||
keyid_from_sk (k->pkt->pkt.secret_key, aki );
|
||||
if( aki[1] == keyid[1] && aki[0] == keyid[0] ) {
|
||||
found = 1;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
release_kbnode (keyblock); keyblock = NULL;
|
||||
}
|
||||
}
|
||||
if( rc && rc != -1 )
|
||||
log_error ("enum_keyblocks failed: %s\n", g10_errstr(rc));
|
||||
leave:
|
||||
release_kbnode (keyblock);
|
||||
enum_keyblocks ( 2, &kbpos, NULL );
|
||||
set_packet_list_mode (oldmode);
|
||||
return found? 0 : G10ERR_NO_SECKEY;
|
||||
KBPOS dummy_kbpos;
|
||||
return find_secret_keyblock_direct (&dummy_kbpos, keyid)? G10ERR_NO_SECKEY:0;
|
||||
}
|
||||
|
||||
|
||||
@ -1458,7 +1411,7 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
|
||||
* from the hashed list but if there are no such preferences, we
|
||||
* try to get them from the unhashed list. There is no risk with
|
||||
* that, because our implementation comes only with strong
|
||||
* algorithms and it woulkd be fruitless for an attacker to insert
|
||||
* algorithms and it would be fruitless for an attacker to insert
|
||||
* an weak algorithm. */
|
||||
p = parse_sig_subpkt2 ( sig, SIGSUBPKT_PREF_SYM, &n );
|
||||
sym = p; nsym = p?n:0;
|
||||
@ -1490,6 +1443,18 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
|
||||
uid->prefs[n].value = 0;
|
||||
}
|
||||
|
||||
/* see whether we have the MDC feature */
|
||||
uid->mdc_feature = 0;
|
||||
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n);
|
||||
if (!p)
|
||||
n=0;
|
||||
for (; n; n--, p++) {
|
||||
if (*p == 1) {
|
||||
uid->mdc_feature = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1846,6 +1811,7 @@ merge_selfsigs( KBNODE keyblock )
|
||||
int revoked;
|
||||
PKT_public_key *main_pk;
|
||||
prefitem_t *prefs;
|
||||
int mdc_feature;
|
||||
|
||||
if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY ) {
|
||||
if (keyblock->pkt->pkttype == PKT_SECRET_KEY ) {
|
||||
@ -1890,12 +1856,15 @@ merge_selfsigs( KBNODE keyblock )
|
||||
* use reference counting to optimize the preference lists storage.
|
||||
* FIXME: it might be better to use the intersection of
|
||||
* all preferences.
|
||||
* Do a similar thing for the MDC feature flag.
|
||||
*/
|
||||
prefs = NULL;
|
||||
mdc_feature = 0;
|
||||
for (k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next) {
|
||||
if (k->pkt->pkttype == PKT_USER_ID
|
||||
&& k->pkt->pkt.user_id->is_primary) {
|
||||
prefs = k->pkt->pkt.user_id->prefs;
|
||||
mdc_feature = k->pkt->pkt.user_id->mdc_feature;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1906,6 +1875,7 @@ merge_selfsigs( KBNODE keyblock )
|
||||
if (pk->prefs)
|
||||
m_free (pk->prefs);
|
||||
pk->prefs = copy_prefs (prefs);
|
||||
pk->mdc_feature = mdc_feature;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,12 +385,13 @@ dump_kbnode( KBNODE node )
|
||||
else if( node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
PKT_public_key *pk = node->pkt->pkt.public_key;
|
||||
fprintf(stderr, " keyid=%08lX a=%d u=%d %c%c%c\n",
|
||||
fprintf(stderr, " keyid=%08lX a=%d u=%d %c%c%c%c\n",
|
||||
(ulong)keyid_from_pk( pk, NULL ),
|
||||
pk->pubkey_algo, pk->pubkey_usage,
|
||||
pk->has_expired? 'e':'.',
|
||||
pk->is_revoked? 'r':'.',
|
||||
pk->is_valid? 'v':'.' );
|
||||
pk->is_valid? 'v':'.',
|
||||
pk->mdc_feature? 'm':'.');
|
||||
}
|
||||
else
|
||||
fputs("\n", stderr);
|
||||
|
@ -124,6 +124,7 @@ int check_signatures_trust( PKT_signature *sig );
|
||||
void release_pk_list( PK_LIST pk_list );
|
||||
int build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use );
|
||||
int select_algo_from_prefs( PK_LIST pk_list, int preftype );
|
||||
int select_mdc_from_pklist (PK_LIST pk_list);
|
||||
|
||||
/*-- skclist.c --*/
|
||||
void release_sk_list( SK_LIST sk_list );
|
||||
@ -218,15 +219,12 @@ int add_keyblock_resource( const char *resname, int force, int secret );
|
||||
const char *keyblock_resource_name( KBPOS *kbpos );
|
||||
int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos );
|
||||
char *get_writable_keyblock_file( int secret );
|
||||
int locate_keyblock_by_fpr( KBPOS *kbpos, const byte *fpr,
|
||||
int fprlen, int secret );
|
||||
int locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid,
|
||||
int shortkid, int secret );
|
||||
int find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos );
|
||||
int find_keyblock_byname( KBPOS *kbpos, const char *username );
|
||||
int find_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk );
|
||||
int find_keyblock_bysk( KBPOS *kbpos, PKT_secret_key *sk );
|
||||
int find_secret_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk );
|
||||
int find_secret_keyblock_byname( KBPOS *kbpos, const char *username );
|
||||
int find_secret_keyblock_direct (KBPOS *kbpos, u32 *keyid);
|
||||
int lock_keyblock( KBPOS *kbpos );
|
||||
void unlock_keyblock( KBPOS *kbpos );
|
||||
int read_keyblock( KBPOS *kbpos, KBNODE *ret_root );
|
||||
|
@ -650,10 +650,19 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
||||
have_commands = 1;
|
||||
}
|
||||
|
||||
/* get the public key */
|
||||
rc = get_keyblock_byname( &keyblock, &keyblockpos, username );
|
||||
if( rc )
|
||||
goto leave;
|
||||
if( fix_keyblock( keyblock ) )
|
||||
modified++;
|
||||
if( collapse_uids( &keyblock ) )
|
||||
modified++;
|
||||
|
||||
if( !sign_mode ) {
|
||||
/* first try to locate it as secret key */
|
||||
rc = find_secret_keyblock_byname( &sec_keyblockpos, username );
|
||||
if( !sign_mode ) {/* see whether we have a matching secret key */
|
||||
PKT_public_key *pk = keyblock->pkt->pkt.public_key;
|
||||
|
||||
rc = find_secret_keyblock_bypk( &sec_keyblockpos, pk );
|
||||
if( !rc ) {
|
||||
rc = read_keyblock( &sec_keyblockpos, &sec_keyblock );
|
||||
if( rc ) {
|
||||
@ -667,17 +676,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
||||
}
|
||||
}
|
||||
|
||||
/* and now get the public key */
|
||||
rc = get_keyblock_byname( &keyblock, &keyblockpos, username );
|
||||
if( rc )
|
||||
goto leave;
|
||||
if( fix_keyblock( keyblock ) )
|
||||
modified++;
|
||||
if( collapse_uids( &keyblock ) )
|
||||
modified++;
|
||||
|
||||
if( sec_keyblock ) { /* check that they match */
|
||||
/* fixme: check that they both match */
|
||||
if( sec_keyblock ) {
|
||||
tty_printf(_("Secret key is available.\n"));
|
||||
}
|
||||
|
||||
@ -1118,6 +1117,8 @@ show_prefs (PKT_user_id *uid, int verbose)
|
||||
prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
|
||||
prefs[i].value);
|
||||
}
|
||||
if (uid->mdc_feature)
|
||||
tty_printf (" [mdc]");
|
||||
tty_printf("\n");
|
||||
}
|
||||
}
|
||||
|
28
g10/keygen.c
28
g10/keygen.c
@ -280,6 +280,30 @@ keygen_get_std_prefs ()
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_feature_mdc (PKT_signature *sig)
|
||||
{
|
||||
const byte *s;
|
||||
size_t i, n;
|
||||
char *buf;
|
||||
|
||||
s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n );
|
||||
if (!s)
|
||||
n = 0;
|
||||
|
||||
for (i=0; i < n; i++ ) {
|
||||
if (s[i] == 1)
|
||||
return; /* already set */
|
||||
}
|
||||
|
||||
buf = m_alloc (n+1);
|
||||
buf[0] = 1; /* MDC feature */
|
||||
memcpy (buf+1, s, n);
|
||||
build_sig_subpkt (sig, SIGSUBPKT_FEATURES, buf, n+1);
|
||||
m_free (buf);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
keygen_upd_std_prefs( PKT_signature *sig, void *opaque )
|
||||
{
|
||||
@ -298,6 +322,10 @@ keygen_upd_std_prefs( PKT_signature *sig, void *opaque )
|
||||
build_sig_subpkt (sig, SIGSUBPKT_PREF_COMPR, zip_prefs, nzip_prefs);
|
||||
else
|
||||
delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_COMPR);
|
||||
|
||||
/* Make sure that the MDC feature flag is set */
|
||||
add_feature_mdc (sig);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
11
g10/packet.h
11
g10/packet.h
@ -145,6 +145,7 @@ typedef struct {
|
||||
int is_primary;
|
||||
int is_revoked;
|
||||
prefitem_t *prefs; /* list of preferences (may be NULL)*/
|
||||
int mdc_feature;
|
||||
u32 created; /* according to the self-signature */
|
||||
char name[1];
|
||||
} PKT_user_id;
|
||||
@ -172,6 +173,7 @@ typedef struct {
|
||||
u32 main_keyid[2]; /* keyid of the primary key */
|
||||
u32 keyid[2]; /* calculated by keyid_from_pk() */
|
||||
prefitem_t *prefs; /* list of preferences (may be NULL) */
|
||||
int mdc_feature; /* mdc feature set */
|
||||
byte *namehash; /* if != NULL: found by this name */
|
||||
PKT_user_id *user_id; /* if != NULL: found by that uid */
|
||||
MPI pkey[PUBKEY_MAX_NPKEY];
|
||||
@ -303,6 +305,7 @@ typedef enum {
|
||||
SIGSUBPKT_KEY_FLAGS =27, /* key flags */
|
||||
SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */
|
||||
SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */
|
||||
SIGSUBPKT_FEATURES =30, /* feature flags */
|
||||
SIGSUBPKT_PRIV_VERIFY_CACHE =101, /* cache verification result */
|
||||
|
||||
SIGSUBPKT_FLAG_CRITICAL=128
|
||||
@ -320,7 +323,7 @@ int list_packets( IOBUF a );
|
||||
int set_packet_list_mode( int mode );
|
||||
|
||||
#if DEBUG_PARSE_PACKET
|
||||
int dbg_search_packet( IOBUF inp, PACKET *pkt, int pkttype, off_t *retpos,
|
||||
int dbg_search_packet( IOBUF inp, PACKET *pkt, off_t *retpos,
|
||||
const char* file, int lineno );
|
||||
int dbg_parse_packet( IOBUF inp, PACKET *ret_pkt,
|
||||
const char* file, int lineno );
|
||||
@ -330,8 +333,8 @@ int dbg_copy_some_packets( IOBUF inp, IOBUF out, off_t stopoff,
|
||||
const char* file, int lineno );
|
||||
int dbg_skip_some_packets( IOBUF inp, unsigned n,
|
||||
const char* file, int lineno );
|
||||
#define search_packet( a,b,c,d ) \
|
||||
dbg_search_packet( (a), (b), (c), (d), __FILE__, __LINE__ )
|
||||
#define search_packet( a,b,c ) \
|
||||
dbg_search_packet( (a), (b), (c), __FILE__, __LINE__ )
|
||||
#define parse_packet( a, b ) \
|
||||
dbg_parse_packet( (a), (b), __FILE__, __LINE__ )
|
||||
#define copy_all_packets( a,b ) \
|
||||
@ -341,7 +344,7 @@ int dbg_skip_some_packets( IOBUF inp, unsigned n,
|
||||
#define skip_some_packets( a,b ) \
|
||||
dbg_skip_some_packets((a),(b), __FILE__, __LINE__ )
|
||||
#else
|
||||
int search_packet( IOBUF inp, PACKET *pkt, int pkttype, off_t *retpos );
|
||||
int search_packet( IOBUF inp, PACKET *pkt, off_t *retpos );
|
||||
int parse_packet( IOBUF inp, PACKET *ret_pkt);
|
||||
int copy_all_packets( IOBUF inp, IOBUF out );
|
||||
int copy_some_packets( IOBUF inp, IOBUF out, off_t stopoff );
|
||||
|
@ -38,7 +38,7 @@
|
||||
static int mpi_print_mode = 0;
|
||||
static int list_mode = 0;
|
||||
|
||||
static int parse( IOBUF inp, PACKET *pkt, int reqtype,
|
||||
static int parse( IOBUF inp, PACKET *pkt, int onlykeypkts,
|
||||
off_t *retpos, int *skip, IOBUF out, int do_skip
|
||||
#ifdef DEBUG_PARSE_PACKET
|
||||
,const char *dbg_w, const char *dbg_f, int dbg_l
|
||||
@ -154,28 +154,28 @@ parse_packet( IOBUF inp, PACKET *pkt )
|
||||
#endif
|
||||
|
||||
/****************
|
||||
* Like parse packet, but only return packets of the given type.
|
||||
* Like parse packet, but only return secret or public (sub)key packets.
|
||||
*/
|
||||
#ifdef DEBUG_PARSE_PACKET
|
||||
int
|
||||
dbg_search_packet( IOBUF inp, PACKET *pkt, int pkttype, off_t *retpos,
|
||||
dbg_search_packet( IOBUF inp, PACKET *pkt, off_t *retpos,
|
||||
const char *dbg_f, int dbg_l )
|
||||
{
|
||||
int skip, rc;
|
||||
|
||||
do {
|
||||
rc = parse( inp, pkt, pkttype, retpos, &skip, NULL, 0, "search", dbg_f, dbg_l );
|
||||
rc = parse( inp, pkt, 1, retpos, &skip, NULL, 0, "search", dbg_f, dbg_l );
|
||||
} while( skip );
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
int
|
||||
search_packet( IOBUF inp, PACKET *pkt, int pkttype, off_t *retpos )
|
||||
search_packet( IOBUF inp, PACKET *pkt, off_t *retpos )
|
||||
{
|
||||
int skip, rc;
|
||||
|
||||
do {
|
||||
rc = parse( inp, pkt, pkttype, retpos, &skip, NULL, 0 );
|
||||
rc = parse( inp, pkt, 1, retpos, &skip, NULL, 0 );
|
||||
} while( skip );
|
||||
return rc;
|
||||
}
|
||||
@ -277,14 +277,14 @@ skip_some_packets( IOBUF inp, unsigned n )
|
||||
|
||||
|
||||
/****************
|
||||
* Parse packet. Set the variable skip points to to 1 if the packet
|
||||
* should be skipped; this is the case if either there is a
|
||||
* requested packet type and the parsed packet doesn't match or the
|
||||
* Parse packet. Set the variable skip points to 1 if the packet
|
||||
* should be skipped; this is the case if either ONLYKEYPKTS is set
|
||||
* and the parsed packet isn't one or the
|
||||
* packet-type is 0, indicating deleted stuff.
|
||||
* if OUT is not NULL, a special copymode is used.
|
||||
*/
|
||||
static int
|
||||
parse( IOBUF inp, PACKET *pkt, int reqtype, off_t *retpos,
|
||||
parse( IOBUF inp, PACKET *pkt, int onlykeypkts, off_t *retpos,
|
||||
int *skip, IOBUF out, int do_skip
|
||||
#ifdef DEBUG_PARSE_PACKET
|
||||
,const char *dbg_w, const char *dbg_f, int dbg_l
|
||||
@ -375,7 +375,12 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, off_t *retpos,
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if( do_skip || !pkttype || (reqtype && pkttype != reqtype) ) {
|
||||
if( do_skip
|
||||
|| !pkttype
|
||||
|| (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY
|
||||
&& pkttype != PKT_PUBLIC_KEY
|
||||
&& pkttype != PKT_SECRET_SUBKEY
|
||||
&& pkttype != PKT_SECRET_KEY ) ) {
|
||||
skip_rest(inp, pktlen);
|
||||
*skip = 1;
|
||||
rc = 0;
|
||||
@ -856,6 +861,11 @@ dump_sig_subpkt( int hashed, int type, int critical,
|
||||
printf("%02X", buffer[i] );
|
||||
}
|
||||
break;
|
||||
case SIGSUBPKT_FEATURES:
|
||||
fputs ( "features:", stdout );
|
||||
for( i=0; i < length; i++ )
|
||||
printf(" %d", buffer[i] );
|
||||
break;
|
||||
case SIGSUBPKT_PRIV_VERIFY_CACHE:
|
||||
p = "verification cache";
|
||||
break;
|
||||
@ -903,6 +913,7 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
|
||||
case SIGSUBPKT_PREF_HASH:
|
||||
case SIGSUBPKT_PREF_COMPR:
|
||||
case SIGSUBPKT_POLICY:
|
||||
case SIGSUBPKT_FEATURES:
|
||||
return 0;
|
||||
case SIGSUBPKT_PRIMARY_UID:
|
||||
if ( n != 1 )
|
||||
@ -944,6 +955,7 @@ can_handle_critical( const byte *buffer, size_t n, int type )
|
||||
case SIGSUBPKT_PREF_COMPR:
|
||||
case SIGSUBPKT_KEY_FLAGS:
|
||||
case SIGSUBPKT_PRIMARY_UID:
|
||||
case SIGSUBPKT_FEATURES:
|
||||
return 1;
|
||||
|
||||
case SIGSUBPKT_POLICY: /* Is it enough to show the policy? */
|
||||
|
@ -1146,4 +1146,29 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Select the MDC flag from the pk_list. We can only use MDC if all recipients
|
||||
* support this feature
|
||||
*/
|
||||
int
|
||||
select_mdc_from_pklist (PK_LIST pk_list)
|
||||
{
|
||||
PK_LIST pkr;
|
||||
|
||||
if( !pk_list )
|
||||
return 0;
|
||||
|
||||
for (pkr = pk_list; pkr; pkr = pkr->next) {
|
||||
int mdc;
|
||||
|
||||
if (pkr->pk->user_id) /* selected by user ID */
|
||||
mdc = pkr->pk->user_id->mdc_feature;
|
||||
else
|
||||
mdc = pkr->pk->mdc_feature;
|
||||
if (!mdc)
|
||||
return 0; /* at least on recipeint does not support it */
|
||||
}
|
||||
return 1; /* can be used */
|
||||
}
|
||||
|
||||
|
||||
|
259
g10/ringedit.c
259
g10/ringedit.c
@ -84,11 +84,12 @@ static RESTBL resource_table[MAX_RESOURCES];
|
||||
static int default_public_resource;
|
||||
static int default_secret_resource;
|
||||
|
||||
static int search( PACKET *pkt, KBPOS *kbpos, int secret );
|
||||
static int search (PKT_public_key *req_pk, u32 *req_keyid,
|
||||
KBPOS *kbpos, int secret);
|
||||
|
||||
|
||||
static int keyring_search( PACKET *pkt, KBPOS *kbpos, IOBUF iobuf,
|
||||
const char *fname );
|
||||
static int keyring_search (PKT_public_key *req_pk, u32 *req_keyid,
|
||||
KBPOS *kbpos, IOBUF iobuf, const char *fname );
|
||||
static int keyring_read( KBPOS *kbpos, KBNODE *ret_root );
|
||||
static int keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs );
|
||||
static int keyring_copy( KBPOS *kbpos, int mode, KBNODE root );
|
||||
@ -97,7 +98,7 @@ static int keyring_copy( KBPOS *kbpos, int mode, KBNODE root );
|
||||
static int do_gdbm_store( KBPOS *kbpos, KBNODE root, int update );
|
||||
static int do_gdbm_locate( GDBM_FILE dbf, KBPOS *kbpos,
|
||||
const byte *fpr, int fprlen );
|
||||
static int do_gdbm_locate_by_keyid( GDBM_FILE dbf, KBPOS *kbpos, u32 *keyid );
|
||||
/*static int do_gdbm_locate_by_keyid( GDBM_FILE dbf, KBPOS *kbpos, u32 *keyid );*/
|
||||
static int do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root );
|
||||
static int do_gdbm_enum( KBPOS *kbpos, KBNODE *ret_root );
|
||||
#endif
|
||||
@ -464,26 +465,31 @@ get_writable_keyblock_file( int secret )
|
||||
* Returns: 0 if found, -1 if not found or an errorcode.
|
||||
*/
|
||||
static int
|
||||
search( PACKET *pkt, KBPOS *kbpos, int secret )
|
||||
search (PKT_public_key *req_pk, u32 *req_keyid, KBPOS *kbpos, int secret)
|
||||
{
|
||||
int i, rc, last_rc=-1;
|
||||
|
||||
for(i=0; i < MAX_RESOURCES; i++ ) {
|
||||
if( resource_table[i].used && !resource_table[i].secret == !secret ) {
|
||||
switch( resource_table[i].rt ) {
|
||||
case rt_RING:
|
||||
rc = keyring_search( pkt, kbpos, resource_table[i].iobuf,
|
||||
resource_table[i].fname );
|
||||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_RING:
|
||||
rc = keyring_search (req_pk, req_keyid,
|
||||
kbpos, resource_table[i].iobuf,
|
||||
resource_table[i].fname );
|
||||
|
||||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM: {
|
||||
PKT_public_key *req_pk = pkt->pkt.public_key;
|
||||
byte fpr[20];
|
||||
size_t fprlen;
|
||||
|
||||
fingerprint_from_pk( req_pk, fpr, &fprlen );
|
||||
rc = do_gdbm_locate( resource_table[i].dbf,
|
||||
kbpos, fpr, fprlen );
|
||||
|
||||
if (!req_pk)
|
||||
rc = G10ERR_UNSUPPORTED;
|
||||
else {
|
||||
fingerprint_from_pk( req_pk, fpr, &fprlen );
|
||||
rc = do_gdbm_locate( resource_table[i].dbf,
|
||||
kbpos, fpr, fprlen );
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@ -514,20 +520,12 @@ search( PACKET *pkt, KBPOS *kbpos, int secret )
|
||||
int
|
||||
find_keyblock_byname( KBPOS *kbpos, const char *username )
|
||||
{
|
||||
PACKET pkt;
|
||||
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
|
||||
int rc;
|
||||
|
||||
rc = get_pubkey_byname( NULL, pk, username, NULL );
|
||||
if( rc ) {
|
||||
free_public_key(pk);
|
||||
return rc;
|
||||
}
|
||||
|
||||
init_packet( &pkt );
|
||||
pkt.pkttype = PKT_PUBLIC_KEY;
|
||||
pkt.pkt.public_key = pk;
|
||||
rc = search( &pkt, kbpos, 0 );
|
||||
if (!rc)
|
||||
rc = search( pk, NULL, kbpos, 0 );
|
||||
free_public_key(pk);
|
||||
return rc;
|
||||
}
|
||||
@ -540,30 +538,22 @@ find_keyblock_byname( KBPOS *kbpos, const char *username )
|
||||
int
|
||||
find_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk )
|
||||
{
|
||||
PACKET pkt;
|
||||
int rc;
|
||||
|
||||
init_packet( &pkt );
|
||||
pkt.pkttype = PKT_PUBLIC_KEY;
|
||||
pkt.pkt.public_key = pk;
|
||||
rc = search( &pkt, kbpos, 0 );
|
||||
rc = search( pk, NULL, kbpos, 0 );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Combined function to search for a key and get the position
|
||||
* of the keyblock.
|
||||
* Combined function to search for a secret key and get the position
|
||||
* of the keyblock.
|
||||
*/
|
||||
int
|
||||
find_keyblock_bysk( KBPOS *kbpos, PKT_secret_key *sk )
|
||||
find_secret_keyblock_bypk (KBPOS *kbpos, PKT_public_key *pk)
|
||||
{
|
||||
PACKET pkt;
|
||||
int rc;
|
||||
|
||||
init_packet( &pkt );
|
||||
pkt.pkttype = PKT_SECRET_KEY;
|
||||
pkt.pkt.secret_key = sk;
|
||||
rc = search( &pkt, kbpos, 0 );
|
||||
rc = search (pk, NULL, kbpos, 1);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -575,113 +565,27 @@ find_keyblock_bysk( KBPOS *kbpos, PKT_secret_key *sk )
|
||||
int
|
||||
find_secret_keyblock_byname( KBPOS *kbpos, const char *username )
|
||||
{
|
||||
PACKET pkt;
|
||||
PKT_secret_key *sk = m_alloc_clear( sizeof *sk );
|
||||
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
|
||||
int rc;
|
||||
|
||||
rc = get_seckey_byname( sk, username, 0 );
|
||||
if( rc ) {
|
||||
free_secret_key(sk);
|
||||
return rc;
|
||||
}
|
||||
|
||||
init_packet( &pkt );
|
||||
pkt.pkttype = PKT_SECRET_KEY;
|
||||
pkt.pkt.secret_key = sk;
|
||||
rc = search( &pkt, kbpos, 1 );
|
||||
free_secret_key(sk);
|
||||
rc = get_pubkey_byname( NULL, pk, username, NULL );
|
||||
if (!rc)
|
||||
rc = search (pk, NULL, kbpos, 1);
|
||||
free_public_key (pk);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Locate a keyblock in a database which is capable of direct access
|
||||
* Put all information into KBPOS, which can be later be to access this
|
||||
* key block.
|
||||
* This function looks into all registered keyblock sources.
|
||||
*
|
||||
* Returns: 0 if found,
|
||||
* -1 if not found
|
||||
* G10ERR_UNSUPPORTED if no resource is able to handle this
|
||||
* or another errorcode.
|
||||
/*
|
||||
* This function locates the secret keyblock without doing a public
|
||||
* keyring check fist. It is useful in certain situations and much
|
||||
* faster than the generic solution.
|
||||
*/
|
||||
int
|
||||
locate_keyblock_by_fpr( KBPOS *kbpos, const byte *fpr, int fprlen, int secret )
|
||||
find_secret_keyblock_direct (KBPOS *kbpos, u32 *keyid)
|
||||
{
|
||||
RESTBL *rentry;
|
||||
int i, rc, any=0, last_rc=-1;
|
||||
|
||||
|
||||
for(i=0, rentry = resource_table; i < MAX_RESOURCES; i++, rentry++ ) {
|
||||
if( rentry->used && !rentry->secret == !secret ) {
|
||||
kbpos->rt = rentry->rt;
|
||||
switch( rentry->rt ) {
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
any = 1;
|
||||
rc = do_gdbm_locate( rentry->dbf, kbpos, fpr, fprlen );
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
rc = G10ERR_UNSUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if( !rc ) {
|
||||
kbpos->resno = i;
|
||||
kbpos->fp = NULL;
|
||||
return 0;
|
||||
}
|
||||
else if( rc != -1 && rc != G10ERR_UNSUPPORTED ) {
|
||||
log_error("error searching resource %d: %s\n",
|
||||
i, g10_errstr(rc));
|
||||
last_rc = rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (last_rc == -1 && !any)? G10ERR_UNSUPPORTED : last_rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid, int shortkid, int secret )
|
||||
{
|
||||
RESTBL *rentry;
|
||||
int i, rc, any=0, last_rc=-1;
|
||||
|
||||
if( shortkid )
|
||||
return G10ERR_UNSUPPORTED;
|
||||
|
||||
for(i=0, rentry = resource_table; i < MAX_RESOURCES; i++, rentry++ ) {
|
||||
if( rentry->used && !rentry->secret == !secret ) {
|
||||
kbpos->rt = rentry->rt;
|
||||
switch( rentry->rt ) {
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
any = 1;
|
||||
rc = do_gdbm_locate_by_keyid( rentry->dbf, kbpos, keyid );
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
rc = G10ERR_UNSUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if( !rc ) {
|
||||
kbpos->resno = i;
|
||||
kbpos->fp = NULL;
|
||||
return 0;
|
||||
}
|
||||
else if( rc != -1 && rc != G10ERR_UNSUPPORTED ) {
|
||||
log_error("error searching resource %d: %s\n",
|
||||
i, g10_errstr(rc));
|
||||
last_rc = rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (last_rc == -1 && !any)? G10ERR_UNSUPPORTED : last_rc;
|
||||
int rc;
|
||||
rc = search (NULL, keyid, kbpos, 1);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -1065,21 +969,16 @@ scan_user_file_read( SCAN_USER_HANDLE hd, byte *fpr )
|
||||
****************************************************************/
|
||||
|
||||
static int
|
||||
cmp_seckey( PKT_secret_key *req_sk, PKT_secret_key *sk )
|
||||
cmp_seckey( PKT_public_key *req_pk, PKT_secret_key *sk )
|
||||
{
|
||||
int n,i;
|
||||
|
||||
assert( req_sk->pubkey_algo == sk->pubkey_algo );
|
||||
if (req_pk->pubkey_algo != sk->pubkey_algo)
|
||||
return -1;
|
||||
|
||||
n = pubkey_get_nskey( req_sk->pubkey_algo );
|
||||
for(i=0; i < n; i++ ) {
|
||||
/* Note: becuase v4 protected keys have nothing in the
|
||||
* mpis except for the first one, we skip all NULL MPIs.
|
||||
* This might not be always correct in cases where the both
|
||||
* keys do not match in their secret parts but we can ignore that
|
||||
* because the need for this function is quite ugly. */
|
||||
if( req_sk->skey[1] && sk->skey[i]
|
||||
&& mpi_cmp( req_sk->skey[i], sk->skey[i] ) )
|
||||
n = pubkey_get_npkey (req_pk->pubkey_algo);
|
||||
for (i=0; i < n; i++ ) {
|
||||
if( mpi_cmp (req_pk->pkey[i], sk->skey[i]) )
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -1104,16 +1003,15 @@ cmp_pubkey( PKT_public_key *req_pk, PKT_public_key *pk )
|
||||
* search one keyring, return 0 if found, -1 if not found or an errorcode.
|
||||
*/
|
||||
static int
|
||||
keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
|
||||
keyring_search( PKT_public_key *req_pk, u32 *req_keyid,
|
||||
KBPOS *kbpos, IOBUF iobuf, const char *fname )
|
||||
{
|
||||
int rc;
|
||||
PACKET pkt;
|
||||
int save_mode;
|
||||
off_t offset;
|
||||
int pkttype = req->pkttype;
|
||||
PKT_public_key *req_pk = req->pkt.public_key;
|
||||
PKT_secret_key *req_sk = req->pkt.secret_key;
|
||||
off_t offset, main_offset;
|
||||
|
||||
assert (!!req_pk ^ !!req_keyid); /* exactly one must be specified */
|
||||
init_packet(&pkt);
|
||||
save_mode = set_packet_list_mode(0);
|
||||
kbpos->rt = rt_RING;
|
||||
@ -1135,29 +1033,57 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
|
||||
}
|
||||
#endif
|
||||
|
||||
while( !(rc=search_packet(iobuf, &pkt, pkttype, &offset)) ) {
|
||||
if( pkt.pkttype == PKT_SECRET_KEY ) {
|
||||
main_offset = 0;
|
||||
while ( !(rc=search_packet(iobuf, &pkt, &offset)) ) {
|
||||
if (pkt.pkttype == PKT_PUBLIC_KEY || pkt.pkttype == PKT_SECRET_KEY) {
|
||||
main_offset = offset;
|
||||
}
|
||||
|
||||
if (pkt.pkttype == PKT_SECRET_KEY || pkt.pkttype == PKT_SECRET_SUBKEY) {
|
||||
PKT_secret_key *sk = pkt.pkt.secret_key;
|
||||
|
||||
if( req_sk->timestamp == sk->timestamp
|
||||
&& req_sk->pubkey_algo == sk->pubkey_algo
|
||||
&& !cmp_seckey( req_sk, sk) )
|
||||
break; /* found */
|
||||
if (req_keyid) {
|
||||
u32 aki[2];
|
||||
|
||||
keyid_from_sk (sk, aki);
|
||||
if (aki[0] == req_keyid[0] && aki[1] == req_keyid[1])
|
||||
break; /* found */
|
||||
}
|
||||
else {
|
||||
/* We can't compare the timestamps here because they
|
||||
might differ */
|
||||
if( !cmp_seckey (req_pk, sk) )
|
||||
break; /* found */
|
||||
}
|
||||
}
|
||||
else if( pkt.pkttype == PKT_PUBLIC_KEY ) {
|
||||
else if (pkt.pkttype == PKT_PUBLIC_KEY
|
||||
|| pkt.pkttype == PKT_PUBLIC_SUBKEY) {
|
||||
PKT_public_key *pk = pkt.pkt.public_key;
|
||||
|
||||
if( req_pk->timestamp == pk->timestamp
|
||||
&& req_pk->pubkey_algo == pk->pubkey_algo
|
||||
&& !cmp_pubkey( req_pk, pk ) )
|
||||
break; /* found */
|
||||
if (req_keyid) {
|
||||
u32 aki[2];
|
||||
|
||||
keyid_from_pk (pk, aki);
|
||||
if (aki[0] == req_keyid[0] && aki[1] == req_keyid[1])
|
||||
break; /* found */
|
||||
}
|
||||
else {
|
||||
if( req_pk->timestamp == pk->timestamp
|
||||
&& req_pk->pubkey_algo == pk->pubkey_algo
|
||||
&& !cmp_pubkey( req_pk, pk ) )
|
||||
break; /* found */
|
||||
}
|
||||
}
|
||||
else
|
||||
BUG();
|
||||
free_packet(&pkt);
|
||||
}
|
||||
if( !rc ) {
|
||||
kbpos->offset = offset;
|
||||
if (pkt.pkttype == PKT_SECRET_SUBKEY
|
||||
|| pkt.pkttype == PKT_PUBLIC_SUBKEY)
|
||||
kbpos->offset = main_offset;
|
||||
else
|
||||
kbpos->offset = offset;
|
||||
kbpos->valid = 1;
|
||||
}
|
||||
|
||||
@ -1710,6 +1636,7 @@ do_gdbm_locate( GDBM_FILE dbf, KBPOS *kbpos, const byte *fpr, int fprlen )
|
||||
* locate by keyid.
|
||||
* FIXME: we must have a way to enumerate thru the list opf fingerprints
|
||||
*/
|
||||
#if 0 /* not used */
|
||||
static int
|
||||
do_gdbm_locate_by_keyid( GDBM_FILE dbf, KBPOS *kbpos, u32 *keyid )
|
||||
{
|
||||
@ -1752,7 +1679,7 @@ do_gdbm_locate_by_keyid( GDBM_FILE dbf, KBPOS *kbpos, u32 *keyid )
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* not used */
|
||||
|
||||
|
||||
static int
|
||||
|
@ -551,7 +551,8 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig,
|
||||
}
|
||||
else {
|
||||
if (!opt.quiet)
|
||||
log_info ("no subkey for subkey revocation packet\n");
|
||||
log_info ("key %08lX: no subkey for subkey revocation packet\n",
|
||||
(ulong)keyid_from_pk (pk, NULL));
|
||||
rc = G10ERR_SIG_CLASS;
|
||||
}
|
||||
}
|
||||
@ -574,7 +575,9 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig,
|
||||
md_close(md);
|
||||
}
|
||||
else {
|
||||
log_info ("no subkey for key signature packet\n");
|
||||
if (!opt.quiet)
|
||||
log_info ("key %08lX: no subkey for subkey binding packet\n",
|
||||
(ulong)keyid_from_pk (pk, NULL));
|
||||
rc = G10ERR_SIG_CLASS;
|
||||
}
|
||||
}
|
||||
@ -607,8 +610,10 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig,
|
||||
md_close(md);
|
||||
}
|
||||
else {
|
||||
log_info ("no user ID for key signature packet of class %02x\n",
|
||||
sig->sig_class );
|
||||
if (!opt.quiet)
|
||||
log_info ("key %08lX: no user ID for key signature packet "
|
||||
"of class %02x\n",
|
||||
(ulong)keyid_from_pk (pk, NULL), sig->sig_class );
|
||||
rc = G10ERR_SIG_CLASS;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
2001-08-30 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* cipher.h (DEK): Added use_mdc.
|
||||
|
||||
2001-08-24 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* cipher.h (md_write): Made buf arg const.
|
||||
|
@ -64,6 +64,7 @@ typedef struct {
|
||||
int algo;
|
||||
int keylen;
|
||||
int algo_info_printed;
|
||||
int use_mdc;
|
||||
byte key[32]; /* this is the largest used keylen (256 bit) */
|
||||
} DEK;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user