From cvs at cvs.gnupg.org Thu Jan 3 20:29:05 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 03 Jan 2013 20:29:05 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-65-gf395a3e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-0 has been updated via f395a3e7ef78e93084a572cf39c1bb2d85ce5f45 (commit) via c291ebaf6f083de9d0a4baf5e384f27601e0253c (commit) from f484d8b28bccce7652362fa7940e53af04a412c8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f395a3e7ef78e93084a572cf39c1bb2d85ce5f45 Author: Werner Koch Date: Thu Jan 3 20:19:23 2013 +0100 gpg: Detect Keybox files and print a diagnostic. * g10/keydb.c (KEYDB_RESOURCE_TYPE_KEYBOX): New. (keydb_add_resource): Handle scheme "gnupg-kbx:". Detect Keybox magic. Print wanrning note for Keybox. (keydb_new, keydb_release, keydb_get_resource_name) (lock_all, unlock_all, keydb_get_keyblock) (keydb_update_keyblock, keydb_insert_keyblock, keydb_delete_keyblock) (keydb_locate_writable, keydb_rebuild_caches, keydb_search_reset) (keydb_search2): Ignore Keybox type in switches. * g10/gpg.h (G10ERR_UNSUPPORTED): Map to correct gpg-error value. -- GnuPG 2.1 will support Keybox files in GPG and thus users might see weird error messages if they accidentally use a keybox file with 2.0. Better print a note here. diff --git a/g10/gpg.h b/g10/gpg.h index c39d215..7049656 100644 --- a/g10/gpg.h +++ b/g10/gpg.h @@ -114,7 +114,7 @@ struct server_control_s #define G10ERR_TRUSTDB GPG_ERR_TRUSTDB #define G10ERR_UNEXPECTED GPG_ERR_UNEXPECTED #define G10ERR_UNKNOWN_PACKET GPG_ERR_UNKNOWN_PACKET -#define G10ERR_UNSUPPORTED GPG_ERR_UNSUPPORTED +#define G10ERR_UNSUPPORTED GPG_ERR_NOT_SUPPORTED #define G10ERR_UNU_PUBKEY GPG_ERR_UNUSABLE_PUBKEY #define G10ERR_UNU_SECKEY GPG_ERR_UNUSABLE_SECKEY #define G10ERR_WRONG_SECKEY GPG_ERR_WRONG_SECKEY diff --git a/g10/keydb.c b/g10/keydb.c index 9e8b8c4..450ada7 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -1,6 +1,6 @@ /* keydb.c - key database dispatcher * Copyright (C) 2001, 2002, 2003, 2004, 2005, - * 2008, 2009 Free Software Foundation, Inc. + * 2008, 2009, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -41,7 +41,8 @@ static int active_handles; typedef enum { KEYDB_RESOURCE_TYPE_NONE = 0, - KEYDB_RESOURCE_TYPE_KEYRING + KEYDB_RESOURCE_TYPE_KEYRING, + KEYDB_RESOURCE_TYPE_KEYBOX } KeydbResourceType; #define MAX_KEYDB_RESOURCES 40 @@ -236,6 +237,11 @@ keydb_add_resource (const char *url, int flags, int secret) rt = KEYDB_RESOURCE_TYPE_KEYRING; resname += 11; } + else if (strlen (resname) > 10 && !strncmp (resname, "gnupg-kbx:", 10) ) + { + rt = KEYDB_RESOURCE_TYPE_KEYBOX; + resname += 10; + } #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__) else if (strchr (resname, ':')) { log_error ("invalid key resource URL `%s'\n", url ); @@ -267,6 +273,11 @@ keydb_add_resource (const char *url, int flags, int secret) if (fread( &magic, 4, 1, fp) == 1 ) { if (magic == 0x13579ace || magic == 0xce9a5713) ; /* GDBM magic - no more support */ + else if (fread (&magic, 4, 1, fp) == 1 + && !memcmp (&magic, "\x01", 1) + && fread (&magic, 4, 1, fp) == 1 + && !memcmp (&magic, "KBXf", 4)) + rt = KEYDB_RESOURCE_TYPE_KEYBOX; else rt = KEYDB_RESOURCE_TYPE_KEYRING; } @@ -314,6 +325,10 @@ keydb_add_resource (const char *url, int flags, int secret) } break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + rc = G10ERR_UNSUPPORTED; + goto leave; + default: log_error ("resource type of `%s' not supported\n", url); rc = G10ERR_GENERAL; @@ -335,6 +350,9 @@ keydb_add_resource (const char *url, int flags, int secret) else log_error (_("keyblock resource `%s': %s\n"), filename, g10_errstr(rc)); + if (rt == KEYDB_RESOURCE_TYPE_KEYBOX) + log_error ("Note: This version of GPG does not support" + " the Keybox format\n"); } else if (secret) any_secret = 1; @@ -364,6 +382,7 @@ keydb_new (int secret) switch (all_resources[i].type) { case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ + case KEYDB_RESOURCE_TYPE_KEYBOX: /* ignore */ break; case KEYDB_RESOURCE_TYPE_KEYRING: hd->active[j].type = all_resources[i].type; @@ -398,6 +417,7 @@ keydb_release (KEYDB_HANDLE hd) for (i=0; i < hd->used; i++) { switch (hd->active[i].type) { case KEYDB_RESOURCE_TYPE_NONE: + case KEYDB_RESOURCE_TYPE_KEYBOX: break; case KEYDB_RESOURCE_TYPE_KEYRING: keyring_release (hd->active[i].u.kr); @@ -435,6 +455,7 @@ keydb_get_resource_name (KEYDB_HANDLE hd) switch (hd->active[idx].type) { case KEYDB_RESOURCE_TYPE_NONE: + case KEYDB_RESOURCE_TYPE_KEYBOX: s = NULL; break; case KEYDB_RESOURCE_TYPE_KEYRING: @@ -455,6 +476,7 @@ lock_all (KEYDB_HANDLE hd) for (i=0; !rc && i < hd->used; i++) { switch (hd->active[i].type) { case KEYDB_RESOURCE_TYPE_NONE: + case KEYDB_RESOURCE_TYPE_KEYBOX: break; case KEYDB_RESOURCE_TYPE_KEYRING: rc = keyring_lock (hd->active[i].u.kr, 1); @@ -467,6 +489,7 @@ lock_all (KEYDB_HANDLE hd) for (i--; i >= 0; i--) { switch (hd->active[i].type) { case KEYDB_RESOURCE_TYPE_NONE: + case KEYDB_RESOURCE_TYPE_KEYBOX: break; case KEYDB_RESOURCE_TYPE_KEYRING: keyring_lock (hd->active[i].u.kr, 0); @@ -491,6 +514,7 @@ unlock_all (KEYDB_HANDLE hd) for (i=hd->used-1; i >= 0; i--) { switch (hd->active[i].type) { case KEYDB_RESOURCE_TYPE_NONE: + case KEYDB_RESOURCE_TYPE_KEYBOX: break; case KEYDB_RESOURCE_TYPE_KEYRING: keyring_lock (hd->active[i].u.kr, 0); @@ -520,6 +544,7 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) switch (hd->active[hd->found].type) { case KEYDB_RESOURCE_TYPE_NONE: + case KEYDB_RESOURCE_TYPE_KEYBOX: rc = G10ERR_GENERAL; /* oops */ break; case KEYDB_RESOURCE_TYPE_KEYRING: @@ -553,6 +578,7 @@ keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb) switch (hd->active[hd->found].type) { case KEYDB_RESOURCE_TYPE_NONE: + case KEYDB_RESOURCE_TYPE_KEYBOX: rc = G10ERR_GENERAL; /* oops */ break; case KEYDB_RESOURCE_TYPE_KEYRING: @@ -593,6 +619,7 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb) switch (hd->active[idx].type) { case KEYDB_RESOURCE_TYPE_NONE: + case KEYDB_RESOURCE_TYPE_KEYBOX: rc = G10ERR_GENERAL; /* oops */ break; case KEYDB_RESOURCE_TYPE_KEYRING: @@ -628,6 +655,7 @@ keydb_delete_keyblock (KEYDB_HANDLE hd) switch (hd->active[hd->found].type) { case KEYDB_RESOURCE_TYPE_NONE: + case KEYDB_RESOURCE_TYPE_KEYBOX: rc = G10ERR_GENERAL; /* oops */ break; case KEYDB_RESOURCE_TYPE_KEYRING: @@ -683,6 +711,7 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) switch (hd->active[hd->current].type) { case KEYDB_RESOURCE_TYPE_NONE: + case KEYDB_RESOURCE_TYPE_KEYBOX: BUG(); break; case KEYDB_RESOURCE_TYPE_KEYRING: @@ -712,6 +741,7 @@ keydb_rebuild_caches (int noisy) switch (all_resources[i].type) { case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ + case KEYDB_RESOURCE_TYPE_KEYBOX: /* ignore */ break; case KEYDB_RESOURCE_TYPE_KEYRING: rc = keyring_rebuild_cache (all_resources[i].token,noisy); @@ -742,6 +772,7 @@ keydb_search_reset (KEYDB_HANDLE hd) for (i=0; !rc && i < hd->used; i++) { switch (hd->active[i].type) { case KEYDB_RESOURCE_TYPE_NONE: + case KEYDB_RESOURCE_TYPE_KEYBOX: break; case KEYDB_RESOURCE_TYPE_KEYRING: rc = keyring_search_reset (hd->active[i].u.kr); @@ -768,6 +799,7 @@ keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, while (rc == -1 && hd->current >= 0 && hd->current < hd->used) { switch (hd->active[hd->current].type) { case KEYDB_RESOURCE_TYPE_NONE: + case KEYDB_RESOURCE_TYPE_KEYBOX: BUG(); /* we should never see it here */ break; case KEYDB_RESOURCE_TYPE_KEYRING: commit c291ebaf6f083de9d0a4baf5e384f27601e0253c Author: Werner Koch Date: Thu Jan 3 20:11:54 2013 +0100 Remove trailing white space from some files. -- diff --git a/g10/gpg.h b/g10/gpg.h index e152b27..c39d215 100644 --- a/g10/gpg.h +++ b/g10/gpg.h @@ -17,7 +17,7 @@ * along with this program; if not, see . */ #ifndef GNUPG_G10_GPG_H -#define GNUPG_G10_GPG_H +#define GNUPG_G10_GPG_H /* Note, that this file should be the first one after the system header files. This is required to set the error source to the @@ -41,8 +41,8 @@ #define MAX_FINGERPRINT_LEN 20 -/* - Forward declarations. +/* + Forward declarations. */ /* Object used to keep state locally to server.c . */ @@ -67,7 +67,7 @@ struct server_control_s -/* +/* Compatibility stuff to be faded out over time. */ @@ -78,45 +78,45 @@ struct server_control_s /* Mapping of the old error codes to the gpg-error ones. Fixme: This is just a temporary solution: We need to do all these gpg_error() calls in the code. */ -#define G10ERR_BAD_KEY GPG_ERR_BAD_KEY -#define G10ERR_BAD_PASS GPG_ERR_BAD_PASS -#define G10ERR_BAD_PUBKEY GPG_ERR_BAD_PUBKEY +#define G10ERR_BAD_KEY GPG_ERR_BAD_KEY +#define G10ERR_BAD_PASS GPG_ERR_BAD_PASS +#define G10ERR_BAD_PUBKEY GPG_ERR_BAD_PUBKEY #define G10ERR_BAD_SIGN GPG_ERR_BAD_SIGNATURE -#define G10ERR_BAD_URI GPG_ERR_BAD_URI -#define G10ERR_CHECKSUM GPG_ERR_CHECKSUM -#define G10ERR_CIPHER_ALGO GPG_ERR_CIPHER_ALGO -#define G10ERR_CLOSE_FILE GPG_ERR_CLOSE_FILE -#define G10ERR_COMPR_ALGO GPG_ERR_COMPR_ALGO -#define G10ERR_CREATE_FILE GPG_ERR_CREATE_FILE -#define G10ERR_DIGEST_ALGO GPG_ERR_DIGEST_ALGO +#define G10ERR_BAD_URI GPG_ERR_BAD_URI +#define G10ERR_CHECKSUM GPG_ERR_CHECKSUM +#define G10ERR_CIPHER_ALGO GPG_ERR_CIPHER_ALGO +#define G10ERR_CLOSE_FILE GPG_ERR_CLOSE_FILE +#define G10ERR_COMPR_ALGO GPG_ERR_COMPR_ALGO +#define G10ERR_CREATE_FILE GPG_ERR_CREATE_FILE +#define G10ERR_DIGEST_ALGO GPG_ERR_DIGEST_ALGO #define G10ERR_FILE_EXISTS GPG_ERR_EEXIST -#define G10ERR_GENERAL GPG_ERR_GENERAL -#define G10ERR_INV_ARG GPG_ERR_INV_ARG -#define G10ERR_INV_KEYRING GPG_ERR_INV_KEYRING -#define G10ERR_INV_USER_ID GPG_ERR_INV_USER_ID -#define G10ERR_INVALID_ARMOR GPG_ERR_INV_ARMOR -#define G10ERR_INVALID_PACKET GPG_ERR_INV_PACKET -#define G10ERR_KEYRING_OPEN GPG_ERR_KEYRING_OPEN -#define G10ERR_KEYSERVER GPG_ERR_KEYSERVER -#define G10ERR_NO_DATA GPG_ERR_NO_DATA -#define G10ERR_NO_PUBKEY GPG_ERR_NO_PUBKEY -#define G10ERR_NO_SECKEY GPG_ERR_NO_SECKEY -#define G10ERR_NO_USER_ID GPG_ERR_NO_USER_ID -#define G10ERR_NOT_PROCESSED GPG_ERR_NOT_PROCESSED -#define G10ERR_OPEN_FILE GPG_ERR_OPEN_FILE -#define G10ERR_PASSPHRASE GPG_ERR_PASSPHRASE -#define G10ERR_PUBKEY_ALGO GPG_ERR_PUBKEY_ALGO -#define G10ERR_READ_FILE GPG_ERR_READ_FILE -#define G10ERR_RENAME_FILE GPG_ERR_RENAME_FILE -#define G10ERR_RESOURCE_LIMIT GPG_ERR_RESOURCE_LIMIT -#define G10ERR_SIG_CLASS GPG_ERR_SIG_CLASS -#define G10ERR_TIME_CONFLICT GPG_ERR_TIME_CONFLICT -#define G10ERR_TRUSTDB GPG_ERR_TRUSTDB -#define G10ERR_UNEXPECTED GPG_ERR_UNEXPECTED -#define G10ERR_UNKNOWN_PACKET GPG_ERR_UNKNOWN_PACKET -#define G10ERR_UNSUPPORTED GPG_ERR_UNSUPPORTED -#define G10ERR_UNU_PUBKEY GPG_ERR_UNUSABLE_PUBKEY -#define G10ERR_UNU_SECKEY GPG_ERR_UNUSABLE_SECKEY -#define G10ERR_WRONG_SECKEY GPG_ERR_WRONG_SECKEY +#define G10ERR_GENERAL GPG_ERR_GENERAL +#define G10ERR_INV_ARG GPG_ERR_INV_ARG +#define G10ERR_INV_KEYRING GPG_ERR_INV_KEYRING +#define G10ERR_INV_USER_ID GPG_ERR_INV_USER_ID +#define G10ERR_INVALID_ARMOR GPG_ERR_INV_ARMOR +#define G10ERR_INVALID_PACKET GPG_ERR_INV_PACKET +#define G10ERR_KEYRING_OPEN GPG_ERR_KEYRING_OPEN +#define G10ERR_KEYSERVER GPG_ERR_KEYSERVER +#define G10ERR_NO_DATA GPG_ERR_NO_DATA +#define G10ERR_NO_PUBKEY GPG_ERR_NO_PUBKEY +#define G10ERR_NO_SECKEY GPG_ERR_NO_SECKEY +#define G10ERR_NO_USER_ID GPG_ERR_NO_USER_ID +#define G10ERR_NOT_PROCESSED GPG_ERR_NOT_PROCESSED +#define G10ERR_OPEN_FILE GPG_ERR_OPEN_FILE +#define G10ERR_PASSPHRASE GPG_ERR_PASSPHRASE +#define G10ERR_PUBKEY_ALGO GPG_ERR_PUBKEY_ALGO +#define G10ERR_READ_FILE GPG_ERR_READ_FILE +#define G10ERR_RENAME_FILE GPG_ERR_RENAME_FILE +#define G10ERR_RESOURCE_LIMIT GPG_ERR_RESOURCE_LIMIT +#define G10ERR_SIG_CLASS GPG_ERR_SIG_CLASS +#define G10ERR_TIME_CONFLICT GPG_ERR_TIME_CONFLICT +#define G10ERR_TRUSTDB GPG_ERR_TRUSTDB +#define G10ERR_UNEXPECTED GPG_ERR_UNEXPECTED +#define G10ERR_UNKNOWN_PACKET GPG_ERR_UNKNOWN_PACKET +#define G10ERR_UNSUPPORTED GPG_ERR_UNSUPPORTED +#define G10ERR_UNU_PUBKEY GPG_ERR_UNUSABLE_PUBKEY +#define G10ERR_UNU_SECKEY GPG_ERR_UNUSABLE_SECKEY +#define G10ERR_WRONG_SECKEY GPG_ERR_WRONG_SECKEY #endif /*GNUPG_G10_GPG_H*/ diff --git a/g10/keydb.c b/g10/keydb.c index 398be19..9e8b8c4 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -1,5 +1,5 @@ /* keydb.c - key database dispatcher - * Copyright (C) 2001, 2002, 2003, 2004, 2005, + * Copyright (C) 2001, 2002, 2003, 2004, 2005, * 2008, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. @@ -34,7 +34,7 @@ #include "main.h" /*try_make_homedir ()*/ #include "packet.h" #include "keyring.h" -#include "keydb.h" +#include "keydb.h" #include "i18n.h" static int active_handles; @@ -91,7 +91,7 @@ maybe_create_keyring (char *filename, int force) /* If we don't want to create a new file at all, there is no need to go any further - bail out right here. */ - if (!force) + if (!force) return gpg_error (GPG_ERR_ENOENT); /* First of all we try to create the home directory. Note, that we @@ -114,9 +114,9 @@ maybe_create_keyring (char *filename, int force) save_slash = *last_slash_in_filename; *last_slash_in_filename = 0; if (access(filename, F_OK)) - { + { static int tried; - + if (!tried) { tried = 1; @@ -144,8 +144,8 @@ maybe_create_keyring (char *filename, int force) if (opt.verbose) log_info ("can't allocate lock for `%s'\n", filename ); - if (!force) - return gpg_error (GPG_ERR_ENOENT); + if (!force) + return gpg_error (GPG_ERR_ENOENT); else return gpg_error (GPG_ERR_GENERAL); } @@ -175,7 +175,7 @@ maybe_create_keyring (char *filename, int force) else iobuf = iobuf_create (filename); umask (oldmask); - if (!iobuf) + if (!iobuf) { rc = gpg_error_from_syserror (); log_error ( _("error creating keyring `%s': %s\n"), @@ -293,7 +293,7 @@ keydb_add_resource (const char *url, int flags, int secret) { if (used_resources >= MAX_KEYDB_RESOURCES) rc = G10ERR_RESOURCE_LIMIT; - else + else { if(flags&2) primary_keyring=token; @@ -352,10 +352,10 @@ keydb_new (int secret) { KEYDB_HANDLE hd; int i, j; - + hd = xmalloc_clear (sizeof *hd); hd->found = -1; - + assert (used_resources <= MAX_KEYDB_RESOURCES); for (i=j=0; i < used_resources; i++) { @@ -379,12 +379,12 @@ keydb_new (int secret) } } hd->used = j; - + active_handles++; return hd; } -void +void keydb_release (KEYDB_HANDLE hd) { int i; @@ -423,19 +423,19 @@ keydb_get_resource_name (KEYDB_HANDLE hd) int idx; const char *s = NULL; - if (!hd) + if (!hd) return NULL; - if ( hd->found >= 0 && hd->found < hd->used) + if ( hd->found >= 0 && hd->found < hd->used) idx = hd->found; - else if ( hd->current >= 0 && hd->current < hd->used) + else if ( hd->current >= 0 && hd->current < hd->used) idx = hd->current; else idx = 0; switch (hd->active[idx].type) { case KEYDB_RESOURCE_TYPE_NONE: - s = NULL; + s = NULL; break; case KEYDB_RESOURCE_TYPE_KEYRING: s = keyring_get_resource_name (hd->active[idx].u.kr); @@ -447,7 +447,7 @@ keydb_get_resource_name (KEYDB_HANDLE hd) -static int +static int lock_all (KEYDB_HANDLE hd) { int i, rc = 0; @@ -504,7 +504,7 @@ unlock_all (KEYDB_HANDLE hd) /* * Return the last found keyring. Caller must free it. * The returned keyblock has the kbode flag bit 0 set for the node with - * the public key used to locate the keyblock or flag bit 1 set for + * the public key used to locate the keyblock or flag bit 1 set for * the user ID node. */ int @@ -515,7 +515,7 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) if (!hd) return G10ERR_INV_ARG; - if ( hd->found < 0 || hd->found >= hd->used) + if ( hd->found < 0 || hd->found >= hd->used) return -1; /* nothing found */ switch (hd->active[hd->found].type) { @@ -530,7 +530,7 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) return rc; } -/* +/* * update the current keyblock with KB */ int @@ -541,7 +541,7 @@ keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb) if (!hd) return G10ERR_INV_ARG; - if ( hd->found < 0 || hd->found >= hd->used) + if ( hd->found < 0 || hd->found >= hd->used) return -1; /* nothing found */ if( opt.dry_run ) @@ -565,8 +565,8 @@ keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb) } -/* - * Insert a new KB into one of the resources. +/* + * Insert a new KB into one of the resources. */ int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb) @@ -574,15 +574,15 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb) int rc = -1; int idx; - if (!hd) + if (!hd) return G10ERR_INV_ARG; if( opt.dry_run ) return 0; - if ( hd->found >= 0 && hd->found < hd->used) + if ( hd->found >= 0 && hd->found < hd->used) idx = hd->found; - else if ( hd->current >= 0 && hd->current < hd->used) + else if ( hd->current >= 0 && hd->current < hd->used) idx = hd->current; else return G10ERR_GENERAL; @@ -605,7 +605,7 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb) } -/* +/* * The current keyblock will be deleted. */ int @@ -616,7 +616,7 @@ keydb_delete_keyblock (KEYDB_HANDLE hd) if (!hd) return G10ERR_INV_ARG; - if ( hd->found < 0 || hd->found >= hd->used) + if ( hd->found < 0 || hd->found >= hd->used) return -1; /* nothing found */ if( opt.dry_run ) @@ -643,7 +643,7 @@ keydb_delete_keyblock (KEYDB_HANDLE hd) /* * Locate the default writable key resource, so that the next * operation (which is only relevant for inserts) will be done on this - * resource. + * resource. */ int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) @@ -654,7 +654,7 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) if (!hd) return G10ERR_INV_ARG; - + rc = keydb_search_reset (hd); /* this does reset hd->current */ if (rc) return rc; @@ -678,9 +678,9 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) return rc; } - for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) + for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) { - switch (hd->active[hd->current].type) + switch (hd->active[hd->current].type) { case KEYDB_RESOURCE_TYPE_NONE: BUG(); @@ -691,7 +691,7 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) break; } } - + return -1; } @@ -702,7 +702,7 @@ void keydb_rebuild_caches (int noisy) { int i, rc; - + for (i=0; i < used_resources; i++) { if (all_resources[i].secret) @@ -725,10 +725,10 @@ keydb_rebuild_caches (int noisy) -/* +/* * Start the next search on this handle right at the beginning */ -int +int keydb_search_reset (KEYDB_HANDLE hd) { int i, rc = 0; @@ -736,7 +736,7 @@ keydb_search_reset (KEYDB_HANDLE hd) if (!hd) return G10ERR_INV_ARG; - hd->current = 0; + hd->current = 0; hd->found = -1; /* and reset all resources */ for (i=0; !rc && i < hd->used; i++) { @@ -748,15 +748,15 @@ keydb_search_reset (KEYDB_HANDLE hd) break; } } - return rc; + return rc; } -/* +/* * Search through all keydb resources, starting at the current position, * for a keyblock which contains one of the keys described in the DESC array. */ -int +int keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc, size_t *descindex) { @@ -776,12 +776,12 @@ keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, break; } if (rc == -1) /* EOF -> switch to next resource */ - hd->current++; + hd->current++; else if (!rc) hd->found = hd->current; } - return rc; + return rc; } int ----------------------------------------------------------------------- Summary of changes: g10/gpg.h | 84 ++++++++++++++++++++-------------------- g10/keydb.c | 122 +++++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 119 insertions(+), 87 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 7 02:49:43 2013 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 07 Jan 2013 02:49:43 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-66-g00c9082 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-0 has been updated via 00c908263206f65a59a4f3e525d716888be132b9 (commit) from f395a3e7ef78e93084a572cf39c1bb2d85ce5f45 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 00c908263206f65a59a4f3e525d716888be132b9 Author: NIIBE Yutaka Date: Mon Jan 7 10:41:21 2013 +0900 Update Japanese Translation. * po/ja.po: Fix wrong translations for designated revocation. Reported by Hideki Saito. diff --git a/po/ja.po b/po/ja.po index caa3a31..d84195d 100644 --- a/po/ja.po +++ b/po/ja.po @@ -1,5 +1,5 @@ # Japanese messages for GnuPG -# Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2002, 2003, 2004, 2013 Free Software Foundation, Inc. # IIDA Yosiaki , 1999, 2000, 2002, 2003, 2004. # Yoshihiro Kajiki , 1999. # This file is distributed under the same license as the GnuPG package. @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: GNU gnupg 2.0.20\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2012-12-30 00:20+0900\n" +"PO-Revision-Date: 2013-01-07 10:40+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: Japanese \n" "Language: ja\n" @@ -2439,11 +2439,11 @@ msgstr "?%s: ???????ID??? - ???\n" #, c-format msgid "WARNING: key %s may be revoked: fetching revocation key %s\n" -msgstr "*??*: ?%s??????????: ???%s?????\n" +msgstr "*??*: ?%s???????: ???%s???????\n" #, c-format msgid "WARNING: key %s may be revoked: revocation key %s not present.\n" -msgstr "*??*: ?%s??????????: ???%s????\n" +msgstr "*??*: ?%s???????: ???%s????????\n" #, c-format msgid "key %s: \"%s\" revocation certificate added\n" @@ -2878,8 +2878,7 @@ msgid "" msgstr "" "* `sign' ????? `l' ?????????????? (lsign)?\n" " `t' ????????? (tsign)?`nr' ???????????\n" -" (nrsign)?????????????? (ltsign, tnrsign, ????)????" -"??\n" +" (nrsign)?????????????? (ltsign, tnrsign, ??)??????\n" msgid "Key is revoked." msgstr "????????????" @@ -3007,7 +3006,7 @@ msgstr "%s ? %s ?????????????????: %s\n" #, c-format msgid "This key may be revoked by %s key %s" -msgstr "?????%s?%s?????????????" +msgstr "?????%s?%s??????????" msgid "(sensitive)" msgstr "(????)" ----------------------------------------------------------------------- Summary of changes: po/ja.po | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 7 02:56:49 2013 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 07 Jan 2013 02:56:49 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-124-gbb51edc Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via bb51edc31e6595e38fcbd91d470de57d3a1a7150 (commit) from 05a4458e5721a0afd600f0ec908e739fa83d58f2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bb51edc31e6595e38fcbd91d470de57d3a1a7150 Author: NIIBE Yutaka Date: Mon Jan 7 10:41:21 2013 +0900 Update Japanese Translation. * po/ja.po: Fix wrong translations for designated revocation. Reported by Hideki Saito. Conflicts: po/ja.po diff --git a/po/ja.po b/po/ja.po index 60e3f52..7b3d446 100644 --- a/po/ja.po +++ b/po/ja.po @@ -1,5 +1,5 @@ # Japanese messages for GnuPG -# Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2002, 2003, 2004, 2013 Free Software Foundation, Inc. # IIDA Yosiaki , 1999, 2000, 2002, 2003, 2004. # Yoshihiro Kajiki , 1999. # This file is distributed under the same license as the GnuPG package. @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: GNU gnupg 2.0.20\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2012-12-30 00:20+0900\n" +"PO-Revision-Date: 2013-01-07 10:40+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: Japanese \n" "Language: ja\n" @@ -2558,11 +2558,11 @@ msgstr "?%s: ???????ID??? - ???\n" #, c-format msgid "WARNING: key %s may be revoked: fetching revocation key %s\n" -msgstr "*??*: ?%s??????????: ???%s?????\n" +msgstr "*??*: ?%s???????: ???%s???????\n" #, c-format msgid "WARNING: key %s may be revoked: revocation key %s not present.\n" -msgstr "*??*: ?%s??????????: ???%s????\n" +msgstr "*??*: ?%s???????: ???%s????????\n" #, c-format msgid "key %s: \"%s\" revocation certificate added\n" @@ -3076,7 +3076,7 @@ msgstr "%s ? %s ?????????????????: %s\n" #, c-format msgid "This key may be revoked by %s key %s" -msgstr "?????%s?%s?????????????" +msgstr "?????%s?%s??????????" msgid "(sensitive)" msgstr "(????)" ----------------------------------------------------------------------- Summary of changes: po/ja.po | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 7 21:23:22 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 07 Jan 2013 21:23:22 +0100 Subject: [git] GnuPG - branch, key-storage-work, updated. gnupg-2.1.0beta3-129-gf6d7b3f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, key-storage-work has been updated via f6d7b3f1ee5eed32bc3257c99cb878091d26c482 (commit) via 0baedfd25a4bdc6c8e7aefbd67006b063e2dc33f (commit) via fb31462e7e92d4b19256e6fd40b1b6ffcef2676c (commit) via 7d00e52bd58d9e40c18dcc0122b2c236ef3318f5 (commit) from 79f08fb0699f4a065e3a29bc7676a90534d7ba60 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f6d7b3f1ee5eed32bc3257c99cb878091d26c482 Author: Werner Koch Date: Mon Jan 7 21:14:52 2013 +0100 gpg: Set the node flags while retrieving a keyblock. * g10/keydb.c (parse_keyblock_image): Add args PK_NO and UID_NO and set the note flags accordingly. (keydb_get_keyblock): Transfer PK_NO and UID_NO to parse_keyblock_image. * kbx/keybox-search.c (blob_cmp_fpr, blob_cmp_fpr_part) (blob_cmp_name, blob_cmp_mail): Return the key/user number. (keybox_search): Set the key and user number into the found struct. (keybox_get_keyblock): Add args R_PK_NO and R_UID_NO and set them from the found struct. -- getkey.c needs to know whether the correct subkey was found. Thus we need to set the node flags the same way we did it with the keyring storage. diff --git a/g10/keydb.c b/g10/keydb.c index d293948..186f017 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -1,6 +1,6 @@ /* keydb.c - key database dispatcher * Copyright (C) 2001, 2002, 2003, 2004, 2005, - * 2008, 2009, 2011 Free Software Foundation, Inc. + * 2008, 2009, 2011, 2013 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -617,7 +617,8 @@ unlock_all (KEYDB_HANDLE hd) static gpg_error_t -parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock) +parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no, + const u32 *sigstatus, kbnode_t *r_keyblock) { gpg_error_t err; PACKET *pkt; @@ -625,6 +626,7 @@ parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock) kbnode_t node, *tail; int in_cert, save_mode; u32 n_sigs; + int pk_count, uid_count; *r_keyblock = NULL; @@ -636,6 +638,7 @@ parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock) in_cert = 0; n_sigs = 0; tail = NULL; + pk_count = uid_count = 0; while ((err = parse_packet (iobuf, pkt)) != -1) { if (gpg_err_code (err) == GPG_ERR_UNKNOWN_PACKET) @@ -714,6 +717,26 @@ parse_keyblock_image (iobuf_t iobuf, const u32 *sigstatus, kbnode_t *r_keyblock) } node = new_kbnode (pkt); + + switch (pkt->pkttype) + { + case PKT_PUBLIC_KEY: + case PKT_PUBLIC_SUBKEY: + case PKT_SECRET_KEY: + case PKT_SECRET_SUBKEY: + if (++pk_count == pk_no) + node->flag |= 1; + break; + + case PKT_USER_ID: + if (++uid_count == uid_no) + node->flag |= 2; + break; + + default: + break; + } + if (!keyblock) keyblock = node; else @@ -779,12 +802,14 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) { iobuf_t iobuf; u32 *sigstatus; + int pk_no, uid_no; err = keybox_get_keyblock (hd->active[hd->found].u.kb, - &iobuf, &sigstatus); + &iobuf, &pk_no, &uid_no, &sigstatus); if (!err) { - err = parse_keyblock_image (iobuf, sigstatus, ret_kb); + err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus, + ret_kb); xfree (sigstatus); iobuf_close (iobuf); } diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index a12216b..5e6432f 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -1,5 +1,6 @@ /* keybox-search.c - Search operations - * Copyright (C) 2001, 2002, 2003, 2004, 2012 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2012, + * 2013 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -233,6 +234,9 @@ blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) } +/* Returns 0 if not found or the number of the key which was found. + For X.509 this is always 1, for OpenPGP this is 1 for the primary + key and 2 and more for the subkeys. */ static int blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr) { @@ -259,7 +263,7 @@ blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr) { off = pos + idx*keyinfolen; if (!memcmp (buffer + off, fpr, 20)) - return 1; /* found */ + return idx+1; /* found */ } return 0; /* not found */ } @@ -291,7 +295,7 @@ blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr, { off = pos + idx*keyinfolen; if (!memcmp (buffer + off + fproff, fpr, fprlen)) - return 1; /* found */ + return idx+1; /* found */ } return 0; /* not found */ } @@ -352,15 +356,14 @@ blob_cmp_name (KEYBOXBLOB blob, int idx, if (substr) { if (ascii_memcasemem (buffer+off, len, name, namelen)) - return 1; /* found */ + return idx+1; /* found */ } else { if (len == namelen && !memcmp (buffer+off, name, len)) - return 1; /* found */ + return idx+1; /* found */ } } - return 0; /* not found */ } else { @@ -376,13 +379,16 @@ blob_cmp_name (KEYBOXBLOB blob, int idx, if (substr) { - return !!ascii_memcasemem (buffer+off, len, name, namelen); + if (ascii_memcasemem (buffer+off, len, name, namelen)) + return idx+1; /* found */ } else { - return len == namelen && !memcmp (buffer+off, name, len); + if (len == namelen && !memcmp (buffer+off, name, len)) + return idx+1; /* found */ } } + return 0; /* not found */ } @@ -458,12 +464,12 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr, if (substr) { if (ascii_memcasemem (buffer+off+1, len, name, namelen)) - return 1; /* found */ + return idx+1; /* found */ } else { if (len == namelen && !ascii_memcasecmp (buffer+off+1, name, len)) - return 1; /* found */ + return idx+1; /* found */ } } return 0; /* not found */ @@ -734,6 +740,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) int need_words, any_skip; KEYBOXBLOB blob = NULL; struct sn_array_s *sn_array = NULL; + int pk_no, uid_no; if (!hd) return gpg_error (GPG_ERR_INV_VALUE); @@ -850,6 +857,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) } + pk_no = uid_no = 0; for (;;) { unsigned int blobflags; @@ -875,19 +883,23 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) never_reached (); break; case KEYDB_SEARCH_MODE_EXACT: - if (has_username (blob, desc[n].u.name, 0)) + uid_no = has_username (blob, desc[n].u.name, 0); + if (uid_no) goto found; break; case KEYDB_SEARCH_MODE_MAIL: - if (has_mail (blob, desc[n].u.name, 0)) + uid_no = has_mail (blob, desc[n].u.name, 0); + if (uid_no) goto found; break; case KEYDB_SEARCH_MODE_MAILSUB: - if (has_mail (blob, desc[n].u.name, 1)) + uid_no = has_mail (blob, desc[n].u.name, 1); + if (uid_no) goto found; break; case KEYDB_SEARCH_MODE_SUBSTR: - if (has_username (blob, desc[n].u.name, 1)) + uid_no = has_username (blob, desc[n].u.name, 1); + if (uid_no) goto found; break; case KEYDB_SEARCH_MODE_MAILEND: @@ -914,16 +926,19 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) goto found; break; case KEYDB_SEARCH_MODE_SHORT_KID: - if (has_short_kid (blob, desc[n].u.kid[1])) + pk_no = has_short_kid (blob, desc[n].u.kid[1]); + if (pk_no) goto found; break; case KEYDB_SEARCH_MODE_LONG_KID: - if (has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1])) + pk_no = has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]); + if (pk_no) goto found; break; case KEYDB_SEARCH_MODE_FPR: case KEYDB_SEARCH_MODE_FPR20: - if (has_fingerprint (blob, desc[n].u.fpr)) + pk_no = has_fingerprint (blob, desc[n].u.fpr); + if (pk_no) goto found; break; case KEYDB_SEARCH_MODE_KEYGRIP: @@ -956,6 +971,8 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) if (!rc) { hd->found.blob = blob; + hd->found.pk_no = pk_no; + hd->found.uid_no = uid_no; } else if (rc == -1) { @@ -985,9 +1002,12 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) /* Return the last found keyblock. Returns 0 on success and stores a new iobuf at R_IOBUF and a signature status vector at R_SIGSTATUS - in that case. */ + in that case. R_UID_NO and R_PK_NO are used to retun the number of + the key or user id which was matched the search criteria; if not + known they are set to 0. */ gpg_error_t -keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, u32 **r_sigstatus) +keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, + int *r_pk_no, int *r_uid_no, u32 **r_sigstatus) { gpg_error_t err; const unsigned char *buffer, *p; @@ -1029,6 +1049,8 @@ keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, u32 **r_sigstatus) for (n=1; n <= n_sigs; n++, p += sigilen) sigstatus[n] = get32 (p); + *r_pk_no = hd->found.pk_no; + *r_uid_no = hd->found.uid_no; *r_sigstatus = sigstatus; *r_iobuf = iobuf_temp_with_content (buffer+image_off, image_len); return 0; diff --git a/kbx/keybox.h b/kbx/keybox.h index 03a9245..4f7e23d 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -81,8 +81,8 @@ int keybox_lock (KEYBOX_HANDLE hd, int yes); int _keybox_write_header_blob (FILE *fp); /*-- keybox-search.c --*/ -gpg_error_t keybox_get_keyblock (KEYBOX_HANDLE hd, - iobuf_t *r_iobuf, u32 **sigstatus); +gpg_error_t keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, + int *r_uid_no, int *r_pk_no, u32 **sigstatus); #ifdef KEYBOX_WITH_X509 int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert); #endif /*KEYBOX_WITH_X509*/ @@ -114,7 +114,6 @@ int keybox_compress (KEYBOX_HANDLE hd); /*-- --*/ #if 0 -int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb); int keybox_locate_writable (KEYBOX_HANDLE hd); int keybox_search_reset (KEYBOX_HANDLE hd); int keybox_search (KEYBOX_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc); commit 0baedfd25a4bdc6c8e7aefbd67006b063e2dc33f Author: Werner Koch Date: Mon Jan 7 16:51:24 2013 +0100 New function log_clock. * common/logging.c (log_clock): New. * g10/gpg.c (set_debug): Print clock debug flag. * g10/options.h (DBG_CLOCK_VALUE, DBG_CLOCK): New. -- To actually use log_clock you need to enable the code in logginc.c:log_check() and link against librt. --debug 4096 may then be used to enable it at runtime. diff --git a/common/logging.c b/common/logging.c index f91671e..a8acb52 100644 --- a/common/logging.c +++ b/common/logging.c @@ -857,6 +857,33 @@ log_printhex (const char *text, const void *buffer, size_t length) } +void +log_clock (const char *string) +{ +#if 0 + static unsigned long long initial; + struct timespec tv; + unsigned long long now; + + if (clock_gettime (CLOCK_REALTIME, &tv)) + { + log_debug ("error getting the realtime clock value\n"); + return; + } + now = tv.tv_sec * 1000000000ull; + now += tv.tv_nsec; + + if (!initial) + initial = now; + + log_debug ("[%llu] %s", now - initial, string); +#else + /* You need to link with -ltr to enable the above code. */ + log_debug ("[not enabled in the source] %s", string); +#endif +} + + #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) void bug_at( const char *file, int line, const char *func ) diff --git a/common/logging.h b/common/logging.h index b0d662b..89913e6 100644 --- a/common/logging.h +++ b/common/logging.h @@ -96,5 +96,7 @@ void log_flush (void); by the hexdump and a final LF. */ void log_printhex (const char *text, const void *buffer, size_t length); +void log_clock (const char *string); + #endif /*LIBJNLIB_LOGGING_H*/ diff --git a/g10/gpg.c b/g10/gpg.c index 5773d5e..7e4339b 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1029,7 +1029,7 @@ set_debug (const char *level) gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); if (opt.debug) - log_info ("enabled debug flags:%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + log_info ("enabled debug flags:%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", (opt.debug & DBG_PACKET_VALUE )? " packet":"", (opt.debug & DBG_MPI_VALUE )? " mpi":"", (opt.debug & DBG_CIPHER_VALUE )? " cipher":"", @@ -1042,7 +1042,8 @@ set_debug (const char *level) (opt.debug & DBG_HASHING_VALUE)? " hashing":"", (opt.debug & DBG_EXTPROG_VALUE)? " extprog":"", (opt.debug & DBG_CARD_IO_VALUE)? " cardio":"", - (opt.debug & DBG_ASSUAN_VALUE )? " assuan":""); + (opt.debug & DBG_ASSUAN_VALUE )? " assuan":"", + (opt.debug & DBG_CLOCK_VALUE )? " clock":""); } @@ -3114,6 +3115,8 @@ main (int argc, char **argv) } set_debug (debug_level); + if (DBG_CLOCK) + log_clock ("start"); /* Do these after the switch(), so they can override settings. */ if(PGP2) @@ -4097,6 +4100,8 @@ void g10_exit( int rc ) { gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); + if (DBG_CLOCK) + log_clock ("stop"); if ( (opt.debug & DBG_MEMSTAT_VALUE) ) { gcry_control (GCRYCTL_DUMP_MEMORY_STATS); diff --git a/g10/keydb.c b/g10/keydb.c index dff58cc..d293948 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -1156,6 +1156,9 @@ keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, if (!hd) return gpg_error (GPG_ERR_INV_ARG); + if (DBG_CLOCK) + log_clock ("keydb_search enter"); + rc = -1; while ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) && hd->current >= 0 && hd->current < hd->used) @@ -1182,6 +1185,8 @@ keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, hd->found = hd->current; } + if (DBG_CLOCK) + log_clock ("keydb_search leave"); return ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) ? gpg_error (GPG_ERR_NOT_FOUND) : rc); diff --git a/g10/options.h b/g10/options.h index e67d0ce..d4824bc 100644 --- a/g10/options.h +++ b/g10/options.h @@ -271,6 +271,7 @@ struct { #define DBG_HASHING_VALUE 512 /* debug hashing operations */ #define DBG_EXTPROG_VALUE 1024 /* debug external program calls */ #define DBG_CARD_IO_VALUE 2048 /* debug smart card I/O. */ +#define DBG_CLOCK_VALUE 4096 /* Fixme: For now alias this value. */ #define DBG_ASSUAN_VALUE DBG_EXTPROG_VALUE @@ -286,6 +287,7 @@ struct { #define DBG_EXTPROG (opt.debug & DBG_EXTPROG_VALUE) #define DBG_CARD_IO (opt.debug & DBG_CARD_IO_VALUE) #define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE) +#define DBG_CLOCK (opt.debug & DBG_CLOCK_VALUE) /* FIXME: We need to check whey we did not put this into opt. */ #define DBG_MEMORY memory_debug_mode commit fb31462e7e92d4b19256e6fd40b1b6ffcef2676c Author: Werner Koch Date: Mon Jan 7 15:41:10 2013 +0100 gpg: Allow searching for user ids in a keybox. * kbx/keybox-search.c (blob_cmp_name): Add arg X509 and adjust for PGP use. Change callers. (blob_cmp_mail): Add arg X509 and find the mailbox offset for PGP. Chnage callers. (has_subject_or_alt): Rename to has_username. (has_username): Allow blobtype PGP. (has_mail): Ditto. diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index d683e14..a12216b 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -299,7 +299,7 @@ blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr, static int blob_cmp_name (KEYBOXBLOB blob, int idx, - const char *name, size_t namelen, int substr) + const char *name, size_t namelen, int substr, int x509) { const unsigned char *buffer; size_t length; @@ -336,10 +336,9 @@ blob_cmp_name (KEYBOXBLOB blob, int idx, return 0; /* out of bounds */ if (idx < 0) - { /* compare all names starting with that (negated) index */ - idx = -idx; - - for ( ;idx < nuids; idx++) + { /* Compare all names. Note that for X.509 we start with index 1 + so to skip the issuer at index 0. */ + for (idx = !!x509; idx < nuids; idx++) { size_t mypos = pos; @@ -387,10 +386,12 @@ blob_cmp_name (KEYBOXBLOB blob, int idx, } -/* compare all email addresses of the subject. With SUBSTR given as - True a substring search is done in the mail address */ +/* Compare all email addresses of the subject. With SUBSTR given as + True a substring search is done in the mail address. If X509 + states whether thr search is done on an X.509 blob. */ static int -blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr) +blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr, + int x509) { const unsigned char *buffer; size_t length; @@ -431,7 +432,9 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr) if (namelen < 1) return 0; - for (idx=1 ;idx < nuids; idx++) + /* Note that for X.509 we start at index 1 becuase index 0 is used + for the issuer name. */ + for (idx=!!x509 ;idx < nuids; idx++) { size_t mypos = pos; @@ -440,6 +443,12 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr) len = get32 (buffer+mypos+4); if (off+len > length) return 0; /* error: better stop here out of bounds */ + if (!x509) + { + /* For OpenPGP we need to forward to the mailbox part. */ + for ( ;len && buffer[off] != '<'; len--, off++) + ; + } if (len < 2 || buffer[off] != '<') continue; /* empty name or trailing 0 not stored */ len--; /* one back */ @@ -589,7 +598,7 @@ has_issuer (KEYBOXBLOB blob, const char *name) return 0; namelen = strlen (name); - return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0); + return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1); } static inline int @@ -607,7 +616,7 @@ has_issuer_sn (KEYBOXBLOB blob, const char *name, namelen = strlen (name); return (blob_cmp_sn (blob, sn, snlen) - && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0)); + && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1)); } static inline int @@ -631,22 +640,25 @@ has_subject (KEYBOXBLOB blob, const char *name) return 0; namelen = strlen (name); - return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0); + return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0, 1); } + static inline int -has_subject_or_alt (KEYBOXBLOB blob, const char *name, int substr) +has_username (KEYBOXBLOB blob, const char *name, int substr) { size_t namelen; + int btype; return_val_if_fail (name, 0); - if (blob_get_type (blob) != BLOBTYPE_X509) + btype = blob_get_type (blob); + if (btype != BLOBTYPE_PGP && btype != BLOBTYPE_X509) return 0; namelen = strlen (name); - return blob_cmp_name (blob, -1 /* all subject names*/, name, - namelen, substr); + return blob_cmp_name (blob, -1 /* all subject/user names */, name, + namelen, substr, (btype == BLOBTYPE_X509)); } @@ -654,16 +666,21 @@ static inline int has_mail (KEYBOXBLOB blob, const char *name, int substr) { size_t namelen; + int btype; return_val_if_fail (name, 0); - if (blob_get_type (blob) != BLOBTYPE_X509) + btype = blob_get_type (blob); + if (btype != BLOBTYPE_PGP && btype != BLOBTYPE_X509) return 0; + if (btype == BLOBTYPE_PGP && *name == '<') + name++; /* Hack to remove the leading '<' for gpg. */ + namelen = strlen (name); if (namelen && name[namelen-1] == '>') namelen--; - return blob_cmp_mail (blob, name, namelen, substr); + return blob_cmp_mail (blob, name, namelen, substr, (btype == BLOBTYPE_X509)); } @@ -858,7 +875,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) never_reached (); break; case KEYDB_SEARCH_MODE_EXACT: - if (has_subject_or_alt (blob, desc[n].u.name, 0)) + if (has_username (blob, desc[n].u.name, 0)) goto found; break; case KEYDB_SEARCH_MODE_MAIL: @@ -870,7 +887,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) goto found; break; case KEYDB_SEARCH_MODE_SUBSTR: - if (has_subject_or_alt (blob, desc[n].u.name, 1)) + if (has_username (blob, desc[n].u.name, 1)) goto found; break; case KEYDB_SEARCH_MODE_MAILEND: commit 7d00e52bd58d9e40c18dcc0122b2c236ef3318f5 Author: Werner Koch Date: Mon Jan 7 15:37:50 2013 +0100 gpg: Allow generation of more than 4096 keys in one run. * g10/getkey.c (cache_public_key): Make room in the cache if needed. -- To create the selfsigs, the key generation code makes use of the key cache. However, after 4096 the cache is filled up and then disabled. Thus generating more than 4096 keys in one run was not possible. We now clear the first half the inserted keys every time the cache gets full. diff --git a/g10/getkey.c b/g10/getkey.c index 002a2be..0030f42 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -128,7 +128,7 @@ void cache_public_key (PKT_public_key * pk) { #if MAX_PK_CACHE_ENTRIES - pk_cache_entry_t ce; + pk_cache_entry_t ce, ce2; u32 keyid[2]; if (pk_cache_disabled) @@ -158,11 +158,25 @@ cache_public_key (PKT_public_key * pk) if (pk_cache_entries >= MAX_PK_CACHE_ENTRIES) { - /* fixme: Use another algorithm to free some cache slots. */ - pk_cache_disabled = 1; - if (opt.verbose > 1) - log_info (_("too many entries in pk cache - disabled\n")); - return; + int n; + + /* Remove the last 50% of the entries. */ + for (ce = pk_cache, n = 0; ce && n < pk_cache_entries/2; n++) + ce = ce->next; + if (ce != pk_cache && ce->next) + { + ce2 = ce->next; + ce->next = NULL; + ce = ce2; + for (; ce; ce = ce2) + { + ce2 = ce->next; + free_public_key (ce->pk); + xfree (ce); + pk_cache_entries--; + } + } + assert (pk_cache_entries < MAX_PK_CACHE_ENTRIES); } pk_cache_entries++; ce = xmalloc (sizeof *ce); ----------------------------------------------------------------------- Summary of changes: common/logging.c | 27 ++++++++++++ common/logging.h | 2 + g10/getkey.c | 26 +++++++++--- g10/gpg.c | 9 +++- g10/keydb.c | 38 +++++++++++++++-- g10/options.h | 2 + kbx/keybox-search.c | 113 ++++++++++++++++++++++++++++++++++----------------- kbx/keybox.h | 5 +- 8 files changed, 170 insertions(+), 52 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 8 14:51:39 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 08 Jan 2013 14:51:39 +0100 Subject: [git] GnuPG - branch, key-storage-work, updated. gnupg-2.1.0beta3-132-g4927923 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, key-storage-work has been updated via 492792378dc7a79316ef742b2ffaa46c6cda282a (commit) via 5c565512b8af73bee2a176530663154b9277ef1c (commit) via f3f5721e6843a08d1011875400f385b8cd5fe226 (commit) from f6d7b3f1ee5eed32bc3257c99cb878091d26c482 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 492792378dc7a79316ef742b2ffaa46c6cda282a Author: Werner Koch Date: Tue Jan 8 14:44:49 2013 +0100 gpg: Cache keybox searches. * common/iobuf.c (iobuf_seek): Fix for temp streams. * g10/pubkey-enc.c (get_session_key, get_it): Add some log_clock calls. * g10/keydb.c (dump_search_desc): New. (enum_keyblock_states, struct keyblock_cache): New. (keyblock_cache_clear): New. (keydb_get_keyblock, keydb_search): Implement a keyblock cache. (keydb_update_keyblock, keydb_insert_keyblock, keydb_delete_keyblock) (keydb_rebuild_caches, keydb_search_reset): Clear the cache. -- Gpg uses the key database at several places without a central coordination. This leads to several scans of the keybox for the same key. To improve that we now use a simple cache to store a retrieved keyblock in certain cases. In theory this caching could also be done for old keyrings, but it is a bit more work and questionable whether it is needed; the keybox scheme is anyway much faster than keyrings. Using a keybox with 20000 384 bit ECDSA/ECHD keypairs and a 252 byte sample text we get these values for encrypt and decrypt operations on an Core i5 4*3.33Ghz system. The option --trust-model=always is used. Times are given in milliseconds wall time. | | enc | dec | dec,q | |-----------+-----+-----+-------| | key 1 | 48 | 96 | 70 | | key 10000 | 60 | 98 | 80 | | key 20000 | 69 | 106 | 88 | | 10 keys | 540 | 290 | 70 | The 10 keys test uses a mix of keys, the first one is used for decryption but all keys are looked up so that information about are printed. The last column gives decryption results w/o information printing (--quiet). The keybox is always scanned sequentially without using any index. By adding an index to the keybox it will be possible to further reduce the time required for keys stored to the end of the file. diff --git a/common/iobuf.c b/common/iobuf.c index 3ba3582..a305830 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -2311,7 +2311,7 @@ iobuf_seek (iobuf_t a, off_t newpos) } clearerr (fp); } - else + else if (a->use != 3) /* Not a temp stream. */ { for (; a; a = a->chain) { @@ -2338,7 +2338,8 @@ iobuf_seek (iobuf_t a, off_t newpos) } #endif } - a->d.len = 0; /* discard buffer */ + if (a->use != 3) + a->d.len = 0; /* Discard the buffer unless it is a temp stream. */ a->d.start = 0; a->nbytes = 0; a->nlimit = 0; diff --git a/g10/keydb.c b/g10/keydb.c index 7166203..79ab5af 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -72,10 +72,42 @@ struct keydb_handle }; +/* This is a simple cache used to return the last result of a + successful long kid search. This works only for keybox resources + because (due to lack of a copy_keyblock function) we need to store + an image of the keyblock which is fortunately instantly available + for keyboxes. */ +enum keyblock_cache_states { + KEYBLOCK_CACHE_EMPTY, + KEYBLOCK_CACHE_PREPARED, + KEYBLOCK_CACHE_FILLED +}; + +struct { + enum keyblock_cache_states state; + u32 kid[2]; + iobuf_t iobuf; /* Image of the keyblock. */ + u32 *sigstatus; + int pk_no; + int uid_no; +} keyblock_cache; + + static int lock_all (KEYDB_HANDLE hd); static void unlock_all (KEYDB_HANDLE hd); +static void +keyblock_cache_clear (void) +{ + keyblock_cache.state = KEYBLOCK_CACHE_EMPTY; + xfree (keyblock_cache.sigstatus); + keyblock_cache.sigstatus = NULL; + iobuf_close (keyblock_cache.iobuf); + keyblock_cache.iobuf = NULL; +} + + /* Handle the creation of a keyring or a keybox if it does not yet exist. Take into acount that other processes might have the keyring/keybox already locked. This lock check does not work if @@ -427,6 +459,9 @@ keydb_new (void) KEYDB_HANDLE hd; int i, j; + if (DBG_CLOCK) + log_clock ("keydb_new"); + hd = xmalloc_clear (sizeof *hd); hd->found = -1; @@ -787,6 +822,19 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) if (!hd) return gpg_error (GPG_ERR_INV_ARG); + if (keyblock_cache.state == KEYBLOCK_CACHE_FILLED) + { + iobuf_seek (keyblock_cache.iobuf, 0); + err = parse_keyblock_image (keyblock_cache.iobuf, + keyblock_cache.pk_no, + keyblock_cache.uid_no, + keyblock_cache.sigstatus, + ret_kb); + if (err) + keyblock_cache_clear (); + return err; + } + if (hd->found < 0 || hd->found >= hd->used) return gpg_error (GPG_ERR_VALUE_NOT_FOUND); @@ -810,13 +858,27 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) { err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus, ret_kb); - xfree (sigstatus); - iobuf_close (iobuf); + if (!err && keyblock_cache.state == KEYBLOCK_CACHE_PREPARED) + { + keyblock_cache.state = KEYBLOCK_CACHE_FILLED; + keyblock_cache.sigstatus = sigstatus; + keyblock_cache.iobuf = iobuf; + keyblock_cache.pk_no = pk_no; + keyblock_cache.uid_no = uid_no; + } + else + { + xfree (sigstatus); + iobuf_close (iobuf); + } } } break; } + if (keyblock_cache.state != KEYBLOCK_CACHE_FILLED) + keyblock_cache_clear (); + return err; } @@ -914,6 +976,8 @@ keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb) if (!hd) return gpg_error (GPG_ERR_INV_ARG); + keyblock_cache_clear (); + if (hd->found < 0 || hd->found >= hd->used) return gpg_error (GPG_ERR_VALUE_NOT_FOUND); @@ -957,6 +1021,8 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb) if (!hd) return gpg_error (GPG_ERR_INV_ARG); + keyblock_cache_clear (); + if (opt.dry_run) return 0; @@ -1017,6 +1083,8 @@ keydb_delete_keyblock (KEYDB_HANDLE hd) if (!hd) return gpg_error (GPG_ERR_INV_ARG); + keyblock_cache_clear (); + if (hd->found < 0 || hd->found >= hd->used) return gpg_error (GPG_ERR_VALUE_NOT_FOUND); @@ -1113,6 +1181,8 @@ keydb_rebuild_caches (int noisy) { int i, rc; + keyblock_cache_clear (); + for (i=0; i < used_resources; i++) { if (!keyring_is_writable (all_resources[i].token)) @@ -1145,6 +1215,11 @@ keydb_search_reset (KEYDB_HANDLE hd) if (!hd) return gpg_error (GPG_ERR_INV_ARG); + keyblock_cache_clear (); + + if (DBG_CLOCK) + log_clock ("keydb_search_reset"); + hd->current = 0; hd->found = -1; /* Now reset all resources. */ @@ -1166,6 +1241,52 @@ keydb_search_reset (KEYDB_HANDLE hd) } +static void +dump_search_desc (const char *text, KEYDB_SEARCH_DESC *desc, size_t ndesc) +{ + int n; + const char *s; + + for (n=0; n < ndesc; n++) + { + switch (desc[n].mode) + { + case KEYDB_SEARCH_MODE_NONE: s = "none"; break; + case KEYDB_SEARCH_MODE_EXACT: s = "exact"; break; + case KEYDB_SEARCH_MODE_SUBSTR: s = "substr"; break; + case KEYDB_SEARCH_MODE_MAIL: s = "mail"; break; + case KEYDB_SEARCH_MODE_MAILSUB: s = "mailsub"; break; + case KEYDB_SEARCH_MODE_MAILEND: s = "mailend"; break; + case KEYDB_SEARCH_MODE_WORDS: s = "words"; break; + case KEYDB_SEARCH_MODE_SHORT_KID: s = "short_kid"; break; + case KEYDB_SEARCH_MODE_LONG_KID: s = "long_kid"; break; + case KEYDB_SEARCH_MODE_FPR16: s = "fpr16"; break; + case KEYDB_SEARCH_MODE_FPR20: s = "fpr20"; break; + case KEYDB_SEARCH_MODE_FPR: s = "fpr"; break; + case KEYDB_SEARCH_MODE_ISSUER: s = "issuer"; break; + case KEYDB_SEARCH_MODE_ISSUER_SN: s = "issuer_sn"; break; + case KEYDB_SEARCH_MODE_SN: s = "sn"; break; + case KEYDB_SEARCH_MODE_SUBJECT: s = "subject"; break; + case KEYDB_SEARCH_MODE_KEYGRIP: s = "keygrip"; break; + case KEYDB_SEARCH_MODE_FIRST: s = "first"; break; + case KEYDB_SEARCH_MODE_NEXT: s = "next"; break; + default: s = "?"; break; + } + if (!n) + log_debug ("%s: mode=%s", text, s); + else + log_debug ("%*s mode=%s", (int)strlen (text), "", s); + if (desc[n].mode == KEYDB_SEARCH_MODE_LONG_KID) + log_printf (" %08lX%08lX", (unsigned long)desc[n].u.kid[0], + (unsigned long)desc[n].u.kid[1]); + else if (desc[n].mode == KEYDB_SEARCH_MODE_SHORT_KID) + log_printf (" %08lX", (unsigned long)desc[n].u.kid[1]); + else if (desc[n].mode == KEYDB_SEARCH_MODE_SUBSTR) + log_printf (" '%s'", desc[n].u.name); + } +} + + /* * Search through all keydb resources, starting at the current * position, for a keyblock which contains one of the keys described @@ -1184,6 +1305,19 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, if (DBG_CLOCK) log_clock ("keydb_search enter"); + if (DBG_CACHE) + dump_search_desc ("keydb_search", desc, ndesc); + + if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID + && keyblock_cache.state == KEYBLOCK_CACHE_FILLED + && keyblock_cache.kid[0] == desc[0].u.kid[0] + && keyblock_cache.kid[1] == desc[0].u.kid[1]) + { + if (DBG_CLOCK) + log_clock ("keydb_search leave (cached)"); + return 0; + } + rc = -1; while ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) && hd->current >= 0 && hd->current < hd->used) @@ -1210,11 +1344,22 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, hd->found = hd->current; } + rc = ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) + ? gpg_error (GPG_ERR_NOT_FOUND) + : rc); + + keyblock_cache_clear (); + if (!rc && ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID) + { + keyblock_cache.state = KEYBLOCK_CACHE_PREPARED; + keyblock_cache.kid[0] = desc[0].u.kid[0]; + keyblock_cache.kid[1] = desc[0].u.kid[1]; + } + if (DBG_CLOCK) - log_clock ("keydb_search leave"); - return ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) - ? gpg_error (GPG_ERR_NOT_FOUND) - : rc); + log_clock (rc? "keydb_search leave (not found)" + : "keydb_search leave (found)"); + return rc; } diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 254e810..a69536e 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -77,6 +77,9 @@ get_session_key (PKT_pubkey_enc * k, DEK * dek) PKT_public_key *sk = NULL; int rc; + if (DBG_CLOCK) + log_clock ("get_session_key enter"); + rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC); if (rc) goto leave; @@ -129,6 +132,8 @@ get_session_key (PKT_pubkey_enc * k, DEK * dek) leave: free_public_key (sk); + if (DBG_CLOCK) + log_clock ("get_session_key leave"); return rc; } @@ -149,6 +154,9 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) size_t fpn; const int pkalgo = map_pk_openpgp_to_gcry (sk->pubkey_algo); + if (DBG_CLOCK) + log_clock ("decryption start"); + /* Get the keygrip. */ err = hexkeygrip_from_pk (sk, &keygrip); if (err) @@ -321,6 +329,8 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } + if (DBG_CLOCK) + log_clock ("decryption ready"); if (DBG_CIPHER) log_printhex ("DEK is:", dek->key, dek->keylen); commit 5c565512b8af73bee2a176530663154b9277ef1c Author: Werner Koch Date: Tue Jan 8 14:35:27 2013 +0100 Make log_clock easier to read. * common/logging.c (log_clock): Print in microseconds. diff --git a/common/logging.c b/common/logging.c index a8acb52..cdfd659 100644 --- a/common/logging.c +++ b/common/logging.c @@ -876,7 +876,7 @@ log_clock (const char *string) if (!initial) initial = now; - log_debug ("[%llu] %s", now - initial, string); + log_debug ("[%6llu] %s", (now - initial)/1000, string); #else /* You need to link with -ltr to enable the above code. */ log_debug ("[not enabled in the source] %s", string); commit f3f5721e6843a08d1011875400f385b8cd5fe226 Author: Werner Koch Date: Tue Jan 8 09:43:21 2013 +0100 gpg: Remove a function wrapper. * g10/keydb.h (keydb_search): Remove macro. * g10/keydb.c (keydb_search2): Rename to keydb_search. Change all callers. diff --git a/g10/delkey.c b/g10/delkey.c index 950af0e..22f2219 100644 --- a/g10/delkey.c +++ b/g10/delkey.c @@ -68,7 +68,7 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail ) || desc.mode == KEYDB_SEARCH_MODE_FPR16 || desc.mode == KEYDB_SEARCH_MODE_FPR20); if (!rc) - rc = keydb_search (hd, &desc, 1); + rc = keydb_search (hd, &desc, 1, NULL); if (rc) { log_error (_("key \"%s\" not found: %s\n"), username, g10_errstr (rc)); write_status_text( STATUS_DELETE_PROBLEM, "1" ); diff --git a/g10/export.c b/g10/export.c index d8d9c05..7fbcb34 100644 --- a/g10/export.c +++ b/g10/export.c @@ -803,7 +803,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, kek = NULL; } - while (!(err = keydb_search2 (kdbhd, desc, ndesc, &descindex))) + while (!(err = keydb_search (kdbhd, desc, ndesc, &descindex))) { int skip_until_subkey = 0; u32 keyid[2]; diff --git a/g10/getkey.c b/g10/getkey.c index 0030f42..60429b6 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -2465,7 +2465,7 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret) int no_suitable_key = 0; rc = 0; - while (!(rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems))) + while (!(rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems, NULL))) { /* If we are searching for the first key we have to make sure that the next iteration does not do an implicit reset. @@ -2890,7 +2890,7 @@ have_secret_key_with_kid (u32 *keyid) desc.mode = KEYDB_SEARCH_MODE_LONG_KID; desc.u.kid[0] = keyid[0]; desc.u.kid[1] = keyid[1]; - while (!result && !(err = keydb_search (kdbhd, &desc, 1))) + while (!result && !(err = keydb_search (kdbhd, &desc, 1, NULL))) { desc.mode = KEYDB_SEARCH_MODE_NEXT; err = keydb_get_keyblock (kdbhd, &keyblock); diff --git a/g10/keydb.c b/g10/keydb.c index 186f017..7166203 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -1173,8 +1173,8 @@ keydb_search_reset (KEYDB_HANDLE hd) * keyring was found. */ gpg_error_t -keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, - size_t ndesc, size_t *descindex) +keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, + size_t ndesc, size_t *descindex) { gpg_error_t rc; @@ -1225,7 +1225,7 @@ keydb_search_first (KEYDB_HANDLE hd) memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_FIRST; - return keydb_search (hd, &desc, 1); + return keydb_search (hd, &desc, 1, NULL); } gpg_error_t @@ -1235,7 +1235,7 @@ keydb_search_next (KEYDB_HANDLE hd) memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_NEXT; - return keydb_search (hd, &desc, 1); + return keydb_search (hd, &desc, 1, NULL); } gpg_error_t @@ -1247,7 +1247,7 @@ keydb_search_kid (KEYDB_HANDLE hd, u32 *kid) desc.mode = KEYDB_SEARCH_MODE_LONG_KID; desc.u.kid[0] = kid[0]; desc.u.kid[1] = kid[1]; - return keydb_search (hd, &desc, 1); + return keydb_search (hd, &desc, 1, NULL); } gpg_error_t @@ -1258,5 +1258,5 @@ keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr) memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_FPR; memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN); - return keydb_search (hd, &desc, 1); + return keydb_search (hd, &desc, 1, NULL); } diff --git a/g10/keydb.h b/g10/keydb.h index 3ba9573..fb36c81 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -144,9 +144,8 @@ gpg_error_t keydb_delete_keyblock (KEYDB_HANDLE hd); gpg_error_t keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved); void keydb_rebuild_caches (int noisy); gpg_error_t keydb_search_reset (KEYDB_HANDLE hd); -#define keydb_search(a,b,c) keydb_search2((a),(b),(c),NULL) -gpg_error_t keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, - size_t ndesc, size_t *descindex); +gpg_error_t keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, + size_t ndesc, size_t *descindex); gpg_error_t keydb_search_first (KEYDB_HANDLE hd); gpg_error_t keydb_search_next (KEYDB_HANDLE hd); gpg_error_t keydb_search_kid (KEYDB_HANDLE hd, u32 *kid); diff --git a/g10/keyserver.c b/g10/keyserver.c index 0be1e3f..0ec616b 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -1142,7 +1142,7 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) } } - while (!(rc = keydb_search (kdbhd, desc, ndesc))) + while (!(rc = keydb_search (kdbhd, desc, ndesc, NULL))) { if (!users) desc[0].mode = KEYDB_SEARCH_MODE_NEXT; diff --git a/g10/revoke.c b/g10/revoke.c index 396b6d4..6e47691 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -222,7 +222,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr ) kdbhd = keydb_new (); rc = classify_user_id (uname, &desc, 1); if (!rc) - rc = keydb_search (kdbhd, &desc, 1); + rc = keydb_search (kdbhd, &desc, 1, NULL); if (rc) { log_error (_("key \"%s\" not found: %s\n"),uname, g10_errstr (rc)); goto leave; @@ -463,7 +463,7 @@ gen_revoke (const char *uname) kdbhd = keydb_new (); rc = classify_user_id (uname, &desc, 1); if (!rc) - rc = keydb_search (kdbhd, &desc, 1); + rc = keydb_search (kdbhd, &desc, 1, NULL); if (rc) { log_error (_("secret key \"%s\" not found: %s\n"), diff --git a/g10/trustdb.c b/g10/trustdb.c index 6b228d2..24ed9df 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -2110,7 +2110,7 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust, desc.mode = KEYDB_SEARCH_MODE_FIRST; desc.skipfnc = search_skipfnc; desc.skipfncvalue = full_trust; - rc = keydb_search (hd, &desc, 1); + rc = keydb_search (hd, &desc, 1, NULL); if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND) { keys[nkeys].keyblock = NULL; @@ -2184,7 +2184,8 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust, release_kbnode (keyblock); keyblock = NULL; } - while ( !(rc = keydb_search (hd, &desc, 1)) ); + while (!(rc = keydb_search (hd, &desc, 1, NULL))); + if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND) { log_error ("keydb_search_next failed: %s\n", g10_errstr(rc)); ----------------------------------------------------------------------- Summary of changes: common/iobuf.c | 5 +- common/logging.c | 2 +- g10/delkey.c | 2 +- g10/export.c | 2 +- g10/getkey.c | 4 +- g10/keydb.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++---- g10/keydb.h | 5 +- g10/keyserver.c | 2 +- g10/pubkey-enc.c | 10 +++ g10/revoke.c | 4 +- g10/trustdb.c | 5 +- 11 files changed, 183 insertions(+), 27 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Jan 8 22:10:10 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 08 Jan 2013 22:10:10 +0100 Subject: [git] GnuPG - branch, key-storage-work, updated. gnupg-2.1.0beta3-134-gb11f84b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, key-storage-work has been updated via b11f84b858bad867f1062977a7aba30299157e90 (commit) via bbcdb3d3cefa06b2bff367054c6518f611d7abb7 (commit) from 492792378dc7a79316ef742b2ffaa46c6cda282a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b11f84b858bad867f1062977a7aba30299157e90 Author: Werner Koch Date: Tue Jan 8 18:15:49 2013 +0100 kbx: Switch from MD5 to SHA-1 for the checksum. * kbx/keybox-blob.c (put_membuf): Use a NULL buf to store zero bytes. (create_blob_finish): Write just the needed space. (create_blob_finish): Switch to SHA-1. * kbx/keybox-dump.c (print_checksum): New. (_keybox_dump_blob): Print the checksum and the verification status. -- The checksum was never used in the past. Due to fast SHA-1 computations in modern CPUs we now use SHA-1. Eventually we will support a First blob flag to enable the use of a secret or public HMAC-SHA1. The first may be used for authentication of keyblocks and the latter to mitigate collission attacks on SHA-1. It is not clear whether this will be useful at all. diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index 62d1c9f..6493527 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -261,7 +261,10 @@ put_membuf (struct membuf *mb, const void *buf, size_t len) } mb->buf = p; } - memcpy (mb->buf + mb->len, buf, len); + if (buf) + memcpy (mb->buf + mb->len, buf, len); + else + memset (mb->buf + mb->len, 0, len); mb->len += len; } @@ -311,6 +314,7 @@ put32 (struct membuf *mb, u32 a ) put_membuf (mb, tmp, 4); } + /* Store a value in the fixup list */ static void @@ -638,12 +642,10 @@ create_blob_finish (KEYBOXBLOB blob) struct membuf *a = blob->buf; unsigned char *p; unsigned char *pp; - int i; size_t n; - /* write a placeholder for the checksum */ - for (i = 0; i < 16; i++ ) - put32 (a, 0); /* Hmmm: why put32() ?? */ + /* Write a placeholder for the checksum */ + put_membuf (a, NULL, 20); /* get the memory area */ n = 0; /* (Just to avoid compiler warning.) */ @@ -671,8 +673,8 @@ create_blob_finish (KEYBOXBLOB blob) } } - /* calculate and store the MD5 checksum */ - gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16); + /* Compute and store the SHA-1 checksum. */ + gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 20, p, n - 20); pp = xtrymalloc (n); if ( !pp ) diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c index b603814..c397f9c 100644 --- a/kbx/keybox-dump.c +++ b/kbx/keybox-dump.c @@ -80,6 +80,57 @@ print_string (FILE *fp, const byte *p, size_t n, int delim) static int +print_checksum (const byte *buffer, size_t length, size_t unhashed, FILE *fp) +{ + const byte *p; + int i; + int hashlen; + unsigned char digest[20]; + + fprintf (fp, "Checksum: "); + if (unhashed && unhashed < 20) + { + fputs ("[specified unhashed sized too short]\n", fp); + return 0; + } + if (!unhashed) + { + unhashed = 16; + hashlen = 16; + } + else + hashlen = 20; + if (length < 5+unhashed) + { + fputs ("[blob too short for a checksum]\n", fp); + return 0; + } + + p = buffer + length - hashlen; + for (i=0; i < hashlen; p++, i++) + fprintf (fp, "%02x", *p); + + if (hashlen == 16) /* Compatibility method. */ + { + gcry_md_hash_buffer (GCRY_MD_MD5, digest, buffer, length - 16); + if (!memcmp (buffer + length - 16, digest, 16)) + fputs (" [valid]\n", fp); + else + fputs (" [bad]\n", fp); + } + else + { + gcry_md_hash_buffer (GCRY_MD_SHA1, digest, buffer, length - unhashed); + if (!memcmp (buffer + length - hashlen, digest, hashlen)) + fputs (" [valid]\n", fp); + else + fputs (" [bad]\n", fp); + } + return 0; +} + + +static int dump_header_blob (const byte *buffer, size_t length, FILE *fp) { unsigned long n; @@ -108,12 +159,13 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) { const byte *buffer; size_t length; - int type; + int type, i; ulong n, nkeys, keyinfolen; ulong nuids, uidinfolen; ulong nsigs, siginfolen; ulong rawdata_off, rawdata_len; ulong nserial; + ulong unhashed; const byte *p; buffer = _keybox_get_blob_image (blob, &length); @@ -189,8 +241,12 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) fprintf( fp, "Data-Offset: %lu\n", rawdata_off ); fprintf( fp, "Data-Length: %lu\n", rawdata_len ); if (rawdata_off > length || rawdata_len > length - || rawdata_off+rawdata_off > length) + || rawdata_off+rawdata_len > length + || rawdata_len + 4 > length + || rawdata_off+rawdata_len + 4 > length) fprintf (fp, "[Error: raw data larger than blob]\n"); + unhashed = get32 (buffer + rawdata_off + rawdata_len); + fprintf (fp, "Unhashed: %lu\n", unhashed); nkeys = get16 (buffer + 16); fprintf (fp, "Key-Count: %lu\n", nkeys ); @@ -205,7 +261,6 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) p = buffer + 20; for (n=0; n < nkeys; n++, p += keyinfolen) { - int i; ulong kidoff, kflags; fprintf (fp, "Key-Fpr[%lu]: ", n ); @@ -347,13 +402,17 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) n = get32 (p ); p += 4; fprintf (fp, "Reserved-Space: %lu\n", n ); - /* check that the keyblock is at the correct offset and other bounds */ - /*fprintf (fp, "Blob-Checksum: [MD5-hash]\n");*/ + if (unhashed >= 24) + { + n = get32 ( buffer + length - unhashed); + fprintf (fp, "Storage-Flags: %08lx\n", n ); + } + print_checksum (buffer, length, unhashed, fp); return 0; } -/* Compute the SHA_1 checksum of teh rawdata in BLOB and aput it into +/* Compute the SHA-1 checksum of the rawdata in BLOB and put it into DIGEST. */ static int hash_blob_rawdata (KEYBOXBLOB blob, unsigned char *digest) commit bbcdb3d3cefa06b2bff367054c6518f611d7abb7 Author: Werner Koch Date: Tue Jan 8 17:40:56 2013 +0100 kbx: Update blob specification -- Mainly formatting updates. The only actual change is the checksum which is now declared as SHA-1. diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index 855deaf..62d1c9f 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -17,93 +17,119 @@ * along with this program; if not, see . */ +/* +* The keybox data format + + The KeyBox uses an augmented OpenPGP/X.509 key format. This makes + random access to a keyblock/certificate easier and also gives the + opportunity to store additional information (e.g. the fingerprint) + along with the key. All integers are stored in network byte order, + offsets are counted from the beginning of the Blob. + +** Overview of blob types + + | Byte 4 | Blob type | + |--------+--------------| + | 0 | Empty blob | + | 1 | First blob | + | 2 | OpenPGP blob | + | 3 | X.509 blob | + +** The First blob + + The first blob of a plain KBX file has a special format: + + - u32 Length of this blob + - byte Blob type (1) + - byte Version number (1) + - byte RFU + - byte RFU + - b4 Magic 'KBXf' + - u32 RFU + - u32 file_created_at + - u32 last_maintenance_run + - u32 RFU + - u32 RFU + +** The OpenPGP and X.509 blobs + + The OpenPGP and X.509 blobs are very similiar, things which are + X.509 specific are noted like [X.509: xxx] + + - u32 Length of this blob (including these 4 bytes) + - byte Blob type + 2 = OpenPGP + 3 = X509 + - byte Version number of this blob type + 1 = The only defined value + - u16 Blob flags + bit 0 = contains secret key material (not used) + bit 1 = ephemeral blob (e.g. used while quering external resources) + - u32 Offset to the OpenPGP keyblock or the X.509 DER encoded + certificate + - u32 The length of the keyblock or certificate + - u16 [NKEYS] Number of keys (at least 1!) [X509: always 1] + - u16 Size of the key information structure (at least 28). + - NKEYS times: + - b20 The fingerprint of the key. + Fingerprints are always 20 bytes, MD5 left padded with zeroes. + - u32 Offset to the n-th key's keyID (a keyID is always 8 byte) + or 0 if not known which is the case only for X.509. + - u16 Key flags + bit 0 = qualified signature (not yet implemented} + - u16 RFU + - bN Optional filler up to the specified length of this + structure. + - u16 Size of the serial number (may be zero) + - bN The serial number. N as giiven above. + - u16 Number of user IDs + - u16 [NUIDS] Size of user ID information structure + - NUIDS times: + + For X509, the first user ID is the Issuer, the second the + Subject and the others are subjectAltNames. For OpenPGP we only + store the information from UserID packets here. + + - u32 Blob offset to the n-th user ID + - u32 Length of this user ID. + - u16 User ID flags. + (not yet used) + - byte Validity + - byte RFU + + - u16 [NSIGS] Number of signatures + - u16 Size of signature information (4) + - NSIGS times: + - u32 Expiration time of signature with some special values: + - 0x00000000 = not checked + - 0x00000001 = missing key + - 0x00000002 = bad signature + - 0x10000000 = valid and expires at some date in 1978. + - 0xffffffff = valid and does not expire + - u8 Assigned ownertrust [X509: not used] + - u8 All_Validity + OpenPGP: See ../g10/trustdb/TRUST_* [not yet used] + X509: Bit 4 set := key has been revoked. + Note that this value matches TRUST_FLAG_REVOKED + - u16 RFU + - u32 Recheck_after + - u32 Latest timestamp in the keyblock (useful for KS syncronsiation?) + - u32 Blob created at + - u32 [NRES] Size of reserved space (not including this field) + - bN Reserved space of size NRES for future use. + - bN Arbitrary space for example used to store data which is not + part of the keyblock or certificate. For example the v3 key + IDs go here. + - bN Space for the keyblock or certifciate. + - bN RFU + - b20 SHA-1 checksum (useful for KS syncronisation?) + Note, that KBX versions before GnuPG 2.1 used an MD5 + checksum. However it was only created but never checked. + Thus we do not expect problems if we switch to SHA-1. If + the checksum fails and the first 4 bytes are zero, we can + try again with MD5. SHA-1 has the advantage that it is + faster on CPUs with dedicated SHA-1 support. -/* The keybox data formats - -The KeyBox uses an augmented OpenPGP/X.509 key format. This makes -random access to a keyblock/certificate easier and also gives the -opportunity to store additional information (e.g. the fingerprint) -along with the key. All integers are stored in network byte order, -offsets are counted from the beginning of the Blob. - -The first record of a plain KBX file has a special format: - - u32 length of the first record - byte Blob type (1) - byte version number (1) - byte reserved - byte reserved - u32 magic 'KBXf' - u32 reserved - u32 file_created_at - u32 last_maintenance_run - u32 reserved - u32 reserved - -The OpenPGP and X.509 blob are very similiar, things which are -X.509 specific are noted like [X.509: xxx] - - u32 length of this blob (including these 4 bytes) - byte Blob type (2) [X509: 3] - byte version number of this blob type (1) - u16 Blob flags - bit 0 = contains secret key material (not used) - bit 1 = ephemeral blob (e.g. used while quering external resources) - - u32 offset to the OpenPGP keyblock or X509 DER encoded certificate - u32 and its length - u16 number of keys (at least 1!) [X509: always 1] - u16 size of additional key information - n times: - b20 The keys fingerprint - (fingerprints are always 20 bytes, MD5 left padded with zeroes) - u32 offset to the n-th key's keyID (a keyID is always 8 byte) - or 0 if not known which is the case only for X509. - u16 special key flags - bit 0 = qualified signature (not yet implemented} - u16 reserved - u16 size of serialnumber(may be zero) - n u16 (see above) bytes of serial number - u16 number of user IDs - u16 size of additional user ID information - n times: - u32 offset to the n-th user ID - u32 length of this user ID. - u16 special user ID flags. - bit 0 = - byte validity - byte reserved - [For X509, the first user ID is the Issuer, the second the Subject - and the others are subjectAltNames] - u16 number of signatures - u16 size of signature information (4) - u32 expiration time of signature with some special values: - 0x00000000 = not checked - 0x00000001 = missing key - 0x00000002 = bad signature - 0x10000000 = valid and expires at some date in 1978. - 0xffffffff = valid and does not expire - u8 assigned ownertrust [X509: not used] - u8 all_validity - OpenPGP: see ../g10/trustdb/TRUST_* [not yet used] - X509: Bit 4 set := key has been revoked. Note that this value - matches TRUST_FLAG_REVOKED - u16 reserved - u32 recheck_after - u32 Newest timestamp in the keyblock (useful for KS syncronsiation?) - u32 Blob created at - u32 size of reserved space (not including this field) - reserved space - - Here we might want to put other data - - Here comes the keyblock - - maybe we put a signature here later. - - b16 MD5 checksum (useful for KS syncronisation), we might also want to use - a mac here. - b4 reserved */ ----------------------------------------------------------------------- Summary of changes: kbx/keybox-blob.c | 214 ++++++++++++++++++++++++++++++----------------------- kbx/keybox-dump.c | 71 ++++++++++++++++-- 2 files changed, 186 insertions(+), 99 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 9 01:25:42 2013 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 09 Jan 2013 01:25:42 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-125-ga776f66 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via a776f660363d20b6cc023609c4547e0aa8825d97 (commit) from bb51edc31e6595e38fcbd91d470de57d3a1a7150 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a776f660363d20b6cc023609c4547e0aa8825d97 Author: NIIBE Yutaka Date: Tue Jan 8 15:22:31 2013 +0900 SCD: Support not-so-smart card readers. * scd/ccid-driver.c (struct ccid_driver_s): Add auto_voltage, auto_param, and auto_pps. (parse_ccid_descriptor): Set auto_voltage, auto_param, and auto_pps. Support non-autoconf readers. (update_param_by_atr): New. (ccid_get_atr): Use 5V for PowerOn when auto_voltage is not supported. Use 0x10 when nonnull_nad for SetParameters. Call update_param_by_atr for parsing ATR, and use param for SetParameters. Send PPS if reader requires it and card is negotiable. When bNadValue in the return values of SetParameters == 0, clear handle->nonnull_nad flag. -- This change is to support more card readers by the internal driver. Tested with 08e6:3478 Gemplus PinPad Smart Card Reader. diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 3fe932c..5b3bcaf 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -264,6 +264,9 @@ struct ccid_driver_s unsigned char apdu_level:2; /* Reader supports short APDU level exchange. With a value of 2 short and extended level is supported.*/ + unsigned int auto_voltage:1; + unsigned int auto_param:1; + unsigned int auto_pps:1; unsigned int auto_ifsd:1; unsigned int powered_off:1; unsigned int has_pinpad:2; @@ -758,7 +761,7 @@ parse_ccid_descriptor (ccid_driver_t handle, { unsigned int i; unsigned int us; - int have_t1 = 0, have_tpdu=0, have_auto_conf = 0; + int have_t1 = 0, have_tpdu=0; handle->nonnull_nad = 0; @@ -767,6 +770,9 @@ parse_ccid_descriptor (ccid_driver_t handle, handle->ifsd = 0; handle->has_pinpad = 0; handle->apdu_level = 0; + handle->auto_voltage = 0; + handle->auto_param = 0; + handle->auto_pps = 0; DEBUGOUT_3 ("idVendor: %04X idProduct: %04X bcdDevice: %04X\n", handle->id_vendor, handle->id_product, handle->bcd_device); if (buflen < 54 || buf[0] < 54) @@ -842,22 +848,31 @@ parse_ccid_descriptor (ccid_driver_t handle, DEBUGOUT_1 (" dwFeatures %08X\n", us); if ((us & 0x0002)) { - DEBUGOUT (" Auto configuration based on ATR\n"); - have_auto_conf = 1; + DEBUGOUT (" Auto configuration based on ATR (assumes auto voltage)\n"); + handle->auto_voltage = 1; } if ((us & 0x0004)) DEBUGOUT (" Auto activation on insert\n"); if ((us & 0x0008)) - DEBUGOUT (" Auto voltage selection\n"); + { + DEBUGOUT (" Auto voltage selection\n"); + handle->auto_voltage = 1; + } if ((us & 0x0010)) DEBUGOUT (" Auto clock change\n"); if ((us & 0x0020)) DEBUGOUT (" Auto baud rate change\n"); if ((us & 0x0040)) - DEBUGOUT (" Auto parameter negotiation made by CCID\n"); + { + DEBUGOUT (" Auto parameter negotiation made by CCID\n"); + handle->auto_param = 1; + } else if ((us & 0x0080)) - DEBUGOUT (" Auto PPS made by CCID\n"); - else if ((us & (0x0040 | 0x0080))) + { + DEBUGOUT (" Auto PPS made by CCID\n"); + handle->auto_pps = 1; + } + if ((us & (0x0040 | 0x0080)) == (0x0040 | 0x0080)) DEBUGOUT (" WARNING: conflicting negotiation features\n"); if ((us & 0x0100)) @@ -935,11 +950,10 @@ parse_ccid_descriptor (ccid_driver_t handle, DEBUGOUT_LF (); } - if (!have_t1 || !(have_tpdu || handle->apdu_level) || !have_auto_conf) + if (!have_t1 || !(have_tpdu || handle->apdu_level)) { DEBUGOUT ("this drivers requires that the reader supports T=1, " - "TPDU or APDU level exchange and auto configuration - " - "this is not available\n"); + "TPDU or APDU level exchange - this is not available\n"); return -1; } @@ -2338,6 +2352,151 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits) } +/* Parse ATR string (of ATRLEN) and update parameters at PARAM. + Calling this routine, it should prepare default values at PARAM + beforehand. This routine assumes that card is accessed by T=1 + protocol. It doesn't analyze historical bytes at all. + + Returns < 0 value on error: + -1 for parse error or integrity check error + -2 for card doesn't support T=1 protocol + -3 for parameters are nod explicitly defined by ATR + -4 for this driver doesn't support CRC + + Returns >= 0 on success: + 0 for card is negotiable mode + 1 for card is specific mode (and not negotiable) + */ +static int +update_param_by_atr (unsigned char *param, unsigned char *atr, size_t atrlen) +{ + int i = -1; + int t, y, chk; + int historical_bytes_num, negotiable = 1; + +#define NEXTBYTE() do { i++; if (atrlen <= i) return -1; } while (0) + + NEXTBYTE (); + + if (atr[i] == 0x3F) + param[1] |= 0x02; /* Convention is inverse. */ + NEXTBYTE (); + + y = (atr[i] >> 4); + historical_bytes_num = atr[i] & 0x0f; + NEXTBYTE (); + + if ((y & 1)) + { + param[0] = atr[i]; /* TA1 - Fi & Di */ + NEXTBYTE (); + } + + if ((y & 2)) + NEXTBYTE (); /* TB1 - ignore */ + + if ((y & 4)) + { + param[2] = atr[i]; /* TC1 - Guard Time */ + NEXTBYTE (); + } + + if ((y & 8)) + { + y = (atr[i] >> 4); /* TD1 */ + t = atr[i] & 0x0f; + NEXTBYTE (); + + if ((y & 1)) + { /* TA2 - PPS mode */ + if ((atr[i] & 0x0f) != 1) + return -2; /* Wrong card protocol (!= 1). */ + + if ((atr[i] & 0x10) != 0x10) + return -3; /* Transmission parameters are implicitly defined. */ + + negotiable = 0; /* TA2 means specific mode. */ + NEXTBYTE (); + } + + if ((y & 2)) + NEXTBYTE (); /* TB2 - ignore */ + + if ((y & 4)) + NEXTBYTE (); /* TC2 - ignore */ + + if ((y & 8)) + { + y = (atr[i] >> 4); /* TD2 */ + t = atr[i] & 0x0f; + NEXTBYTE (); + } + else + y = 0; + + while (y) + { + if ((y & 1)) + { /* TAx */ + if (t == 1) + param[5] = atr[i]; /* IFSC */ + else if (t == 15) + /* XXX: check voltage? */ + param[4] = (atr[i] >> 6); /* ClockStop */ + + NEXTBYTE (); + } + + if ((y & 2)) + { + if (t == 1) + param[3] = atr[i]; /* TBx - BWI & CWI */ + NEXTBYTE (); + } + + if ((y & 4)) + { + if (t == 1) + param[1] |= (atr[i] & 0x01); /* TCx - LRC/CRC */ + NEXTBYTE (); + + if (param[1] & 0x01) + return -4; /* CRC not supported yet. */ + } + + if ((y & 8)) + { + y = (atr[i] >> 4); /* TDx */ + t = atr[i] & 0x0f; + NEXTBYTE (); + } + else + y = 0; + } + } + + i += historical_bytes_num - 1; + NEXTBYTE (); + if (atrlen != i+1) + return -1; + +#undef NEXTBYTE + + chk = 0; + do + { + chk ^= atr[i]; + i--; + } + while (i > 0); + + if (chk != 0) + return -1; + + return negotiable; +} + + /* Return the ATR of the card. This is not a cached value and thus an actual reset is done. */ int @@ -2354,6 +2513,15 @@ ccid_get_atr (ccid_driver_t handle, unsigned int edc; int tried_iso = 0; int got_param; + unsigned char param[7] = { /* For Protocol T=1 */ + 0x11, /* bmFindexDindex */ + 0x10, /* bmTCCKST1 */ + 0x00, /* bGuardTimeT1 */ + 0x4d, /* bmWaitingIntegersT1 */ + 0x00, /* bClockStop */ + 0x20, /* bIFSC */ + 0x00 /* bNadValue */ + }; /* First check whether a card is available. */ rc = ccid_slot_status (handle, &statusbits); @@ -2368,7 +2536,8 @@ ccid_get_atr (ccid_driver_t handle, msg[0] = PC_to_RDR_IccPowerOn; msg[5] = 0; /* slot */ msg[6] = seqno = handle->seqno++; - msg[7] = 0; /* power select (0=auto, 1=5V, 2=3V, 3=1.8V) */ + /* power select (0=auto, 1=5V, 2=3V, 3=1.8V) */ + msg[7] = handle->auto_voltage ? 0 : 1; msg[8] = 0; /* RFU */ msg[9] = 0; /* RFU */ set_msg_len (msg, 0); @@ -2410,23 +2579,73 @@ ccid_get_atr (ccid_driver_t handle, *atrlen = n; } + param[6] = handle->nonnull_nad? ((1 << 4) | 0): 0; + rc = update_param_by_atr (param, msg+10, msglen - 10); + if (rc < 0) + { + DEBUGOUT_1 ("update_param_by_atr failed: %d\n", rc); + return CCID_DRIVER_ERR_CARD_IO_ERROR; + } + got_param = 0; - msg[0] = PC_to_RDR_GetParameters; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 0; /* RFU */ - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - set_msg_len (msg, 0); - msglen = 10; - rc = bulk_out (handle, msg, msglen, 0); - if (!rc) - rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Parameters, - seqno, 2000, 0); - if (rc) - DEBUGOUT ("GetParameters failed\n"); - else if (msglen == 17 && msg[9] == 1) - got_param = 1; + + if (handle->auto_param) + { + msg[0] = PC_to_RDR_GetParameters; + msg[5] = 0; /* slot */ + msg[6] = seqno = handle->seqno++; + msg[7] = 0; /* RFU */ + msg[8] = 0; /* RFU */ + msg[9] = 0; /* RFU */ + set_msg_len (msg, 0); + msglen = 10; + rc = bulk_out (handle, msg, msglen, 0); + if (!rc) + rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Parameters, + seqno, 2000, 0); + if (rc) + DEBUGOUT ("GetParameters failed\n"); + else if (msglen == 17 && msg[9] == 1) + got_param = 1; + } + else if (handle->auto_pps) + ; + else if (rc == 1) /* It's negotiable, send PPS. */ + { + msg[0] = PC_to_RDR_XfrBlock; + msg[5] = 0; /* slot */ + msg[6] = seqno = handle->seqno++; + msg[7] = 0; + msg[8] = 0; + msg[9] = 0; + msg[10] = 0xff; /* PPSS */ + msg[11] = 0x11; /* PPS0: PPS1, Protocol T=1 */ + msg[12] = param[0]; /* PPS1: Fi / Di */ + msg[13] = 0xff ^ 0x11 ^ param[0]; /* PCK */ + set_msg_len (msg, 4); + msglen = 10 + 4; + + rc = bulk_out (handle, msg, msglen, 0); + if (rc) + return rc; + + rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_DataBlock, + seqno, 5000, 0); + if (rc) + return rc; + + if (msglen != 10 + 4) + { + DEBUGOUT_1 ("Setting PPS failed: %d\n", msglen); + return CCID_DRIVER_ERR_CARD_IO_ERROR; + } + + if (msg[10] != 0xff || msg[11] != 0x11 || msg[12] != param[0]) + { + DEBUGOUT_1 ("Setting PPS failed: 0x%02x\n", param[0]); + return CCID_DRIVER_ERR_CARD_IO_ERROR; + } + } /* Setup parameters to select T=1. */ msg[0] = PC_to_RDR_SetParameters; @@ -2437,16 +2656,7 @@ ccid_get_atr (ccid_driver_t handle, msg[9] = 0; /* RFU */ if (!got_param) - { - /* FIXME: Get those values from the ATR. */ - msg[10]= 0x01; /* Fi/Di */ - msg[11]= 0x10; /* LRC, direct convention. */ - msg[12]= 0; /* Extra guardtime. */ - msg[13]= 0x41; /* BWI/CWI */ - msg[14]= 0; /* No clock stoppping. */ - msg[15]= 254; /* IFSC */ - msg[16]= 0; /* Does not support non default NAD values. */ - } + memcpy (&msg[10], param, 7); set_msg_len (msg, 7); msglen = 10 + 7; @@ -2463,6 +2673,12 @@ ccid_get_atr (ccid_driver_t handle, else handle->ifsc = 128; /* Something went wrong, assume 128 bytes. */ + if (handle->nonnull_nad && msglen > 16 && msg[16] == 0) + { + DEBUGOUT ("Use Null-NAD, clearing handle->nonnull_nad.\n"); + handle->nonnull_nad = 0; + } + handle->t1_ns = 0; handle->t1_nr = 0; ----------------------------------------------------------------------- Summary of changes: scd/ccid-driver.c | 290 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 253 insertions(+), 37 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 9 08:52:38 2013 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 09 Jan 2013 08:52:38 +0100 Subject: [git] GnuPG - branch, scd-work, created. gnupg-2.1.0beta3-130-g943ce30 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, scd-work has been created at 943ce30e29cdd803588d1b6c316f52986f2a7d8b (commit) - Log ----------------------------------------------------------------- commit 943ce30e29cdd803588d1b6c316f52986f2a7d8b Author: NIIBE Yutaka Date: Wed Jan 9 16:40:41 2013 +0900 SCD: Support fixed length PIN input for keypad (PC/SC). * scd/apdu.c (pcsc_keypad_verify): SUpport fixed length PIN input for keypad. (pcsc_keypad_modify): Likewise. * scd/ccid-driver.c (ccid_transceive_secure): Clean up. diff --git a/scd/apdu.c b/scd/apdu.c index 8c968b7..4c73283 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -2042,7 +2042,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, { int sw; unsigned char *pin_verify; - int len = PIN_VERIFY_STRUCTURE_SIZE; + int len = PIN_VERIFY_STRUCTURE_SIZE + pininfo->fixedlen; unsigned char result[2]; size_t resultlen = 2; @@ -2050,7 +2050,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, && (sw = reset_pcsc_reader (slot))) return sw; - if (pininfo->fixedlen != 0) + if (pininfo->fixedlen < 0 || pininfo->fixedlen >= 16) return SW_NOT_SUPPORTED; if (!pininfo->minlen) @@ -2071,7 +2071,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, pin_verify[0] = 0x00; /* bTimerOut */ pin_verify[1] = 0x00; /* bTimerOut2 */ pin_verify[2] = 0x82; /* bmFormatString: Byte, pos=0, left, ASCII. */ - pin_verify[3] = 0x00; /* bmPINBlockString */ + pin_verify[3] = pininfo->fixedlen; /* bmPINBlockString */ pin_verify[4] = 0x00; /* bmPINLengthFormat */ pin_verify[5] = pininfo->maxlen; /* wPINMaxExtraDigit */ pin_verify[6] = pininfo->minlen; /* wPINMaxExtraDigit */ @@ -2085,7 +2085,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, pin_verify[12] = 0x00; /* bTeoPrologue[0] */ pin_verify[13] = 0x00; /* bTeoPrologue[1] */ pin_verify[14] = 0x00; /* bTeoPrologue[2] */ - pin_verify[15] = 0x05; /* ulDataLength */ + pin_verify[15] = pininfo->fixedlen + 0x05; /* ulDataLength */ pin_verify[16] = 0x00; /* ulDataLength */ pin_verify[17] = 0x00; /* ulDataLength */ pin_verify[18] = 0x00; /* ulDataLength */ @@ -2093,7 +2093,9 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, pin_verify[20] = ins; /* abData[1] */ pin_verify[21] = p0; /* abData[2] */ pin_verify[22] = p1; /* abData[3] */ - pin_verify[23] = 0x00; /* abData[4] */ + pin_verify[23] = pininfo->fixedlen; /* abData[4] */ + if (pininfo->fixedlen) + memset (&pin_verify[24], 0xff, pininfo->fixedlen); if (DBG_CARD_IO) log_debug ("send secure: c=%02X i=%02X p1=%02X p2=%02X len=%d pinmax=%d\n", @@ -2123,7 +2125,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, { int sw; unsigned char *pin_modify; - int len = PIN_MODIFY_STRUCTURE_SIZE; + int len = PIN_MODIFY_STRUCTURE_SIZE + 2 * pininfo->fixedlen; unsigned char result[2]; size_t resultlen = 2; @@ -2131,7 +2133,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, && (sw = reset_pcsc_reader (slot))) return sw; - if (pininfo->fixedlen != 0) + if (pininfo->fixedlen < 0 || pininfo->fixedlen >= 16) return SW_NOT_SUPPORTED; if (!pininfo->minlen) @@ -2152,10 +2154,10 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, pin_modify[0] = 0x00; /* bTimerOut */ pin_modify[1] = 0x00; /* bTimerOut2 */ pin_modify[2] = 0x82; /* bmFormatString: Byte, pos=0, left, ASCII. */ - pin_modify[3] = 0x00; /* bmPINBlockString */ + pin_modify[3] = pininfo->fixedlen; /* bmPINBlockString */ pin_modify[4] = 0x00; /* bmPINLengthFormat */ pin_modify[5] = 0x00; /* bInsertionOffsetOld */ - pin_modify[6] = 0x00; /* bInsertionOffsetNew */ + pin_modify[6] = pininfo->fixedlen; /* bInsertionOffsetNew */ pin_modify[7] = pininfo->maxlen; /* wPINMaxExtraDigit */ pin_modify[8] = pininfo->minlen; /* wPINMaxExtraDigit */ pin_modify[9] = (p0 == 0 ? 0x03 : 0x01); @@ -2177,7 +2179,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, pin_modify[17] = 0x00; /* bTeoPrologue[0] */ pin_modify[18] = 0x00; /* bTeoPrologue[1] */ pin_modify[19] = 0x00; /* bTeoPrologue[2] */ - pin_modify[20] = 0x05; /* ulDataLength */ + pin_modify[20] = 2 * pininfo->fixedlen + 0x05; /* ulDataLength */ pin_modify[21] = 0x00; /* ulDataLength */ pin_modify[22] = 0x00; /* ulDataLength */ pin_modify[23] = 0x00; /* ulDataLength */ @@ -2185,7 +2187,9 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, pin_modify[25] = ins; /* abData[1] */ pin_modify[26] = p0; /* abData[2] */ pin_modify[27] = p1; /* abData[3] */ - pin_modify[28] = 0x00; /* abData[4] */ + pin_modify[28] = 2 * pininfo->fixedlen; /* abData[4] */ + if (pininfo->fixedlen) + memset (&pin_modify[29], 0xff, 2 * pininfo->fixedlen); if (DBG_CARD_IO) log_debug ("send secure: c=%02X i=%02X p1=%02X p2=%02X len=%d pinmax=%d\n", diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 3244c71..83b419a 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -3411,14 +3411,9 @@ ccid_transceive_secure (ccid_driver_t handle, } else { - if (pininfo->fixedlen == 0) - msg[13] = 0x00; /* bmPINBlockString: - 0 bits of pin length to insert. - 0 bytes of PIN block size. */ - else - msg[13] = pininfo->fixedlen; /* bmPINBlockString: - 0 bits of pin length to insert. - PIN block size by fixedlen. */ + msg[13] = pininfo->fixedlen; /* bmPINBlockString: + 0 bits of pin length to insert. + PIN block size by fixedlen. */ msg[14] = 0x00; /* bmPINLengthFormat: Units are bytes, position is 0. */ } @@ -3427,10 +3422,7 @@ ccid_transceive_secure (ccid_driver_t handle, if (apdu_buf[1] == 0x24) { msg[msglen++] = 0; /* bInsertionOffsetOld */ - if (pininfo->fixedlen == 0) - msg[msglen++] = 0; /* bInsertionOffsetNew */ - else - msg[msglen++] = pininfo->fixedlen; /* bInsertionOffsetNew */ + msg[msglen++] = pininfo->fixedlen; /* bInsertionOffsetNew */ } /* The following is a little endian word. */ commit 638b84f93b6325b3db016e7a0621554d6d8a1c7f Author: NIIBE Yutaka Date: Wed Jan 9 16:23:55 2013 +0900 SCD: Support fixed length PIN input for keypad. * scd/iso7816.h (struct pininfo_s): Remove MODE and add FIXEDLEN. * scd/app-dinsig.c (verify_pin): Initialize FIXEDLEN to unknown. * scd/app-nks.c (verify_pin): Likewise. * scd/app-openpgp.c (verify_a_chv, verify_chv3, do_change_pin): Likewise. * scd/apdu.c (check_pcsc_keypad): Add comment. (pcsc_keypad_verify, pcsc_keypad_modify): PC/SC driver only support readers with the feature of variable length input (yet). (apdu_check_keypad): Set FIXEDLEN. * scd/ccid-driver.c (ccid_transceive_secure): Add GEMPC_PINPAD specific settings. Support fixed length PIN input for keypad. diff --git a/scd/apdu.c b/scd/apdu.c index 1e776df..8c968b7 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -1986,7 +1986,7 @@ check_pcsc_keypad (int slot, int command, pininfo_t *pininfo) size_t len = 256; int sw; - (void)pininfo; + (void)pininfo; /* XXX: Identify reader and set pininfo->fixedlen. */ check_again: if (command == ISO7816_VERIFY) @@ -2050,7 +2050,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, && (sw = reset_pcsc_reader (slot))) return sw; - if (pininfo->mode != 1) + if (pininfo->fixedlen != 0) return SW_NOT_SUPPORTED; if (!pininfo->minlen) @@ -2131,7 +2131,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, && (sw = reset_pcsc_reader (slot))) return sw; - if (pininfo->mode != 1) + if (pininfo->fixedlen != 0) return SW_NOT_SUPPORTED; if (!pininfo->minlen) @@ -3397,7 +3397,7 @@ apdu_check_keypad (int slot, int command, pininfo_t *pininfo) return SW_HOST_NO_DRIVER; if (opt.enable_keypad_varlen) - pininfo->mode = 0; + pininfo->fixedlen = 0; if (reader_table[slot].check_keypad) return reader_table[slot].check_keypad (slot, command, pininfo); diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c index f3f7d4b..9d4ebe2 100644 --- a/scd/app-dinsig.c +++ b/scd/app-dinsig.c @@ -288,7 +288,7 @@ verify_pin (app_t app, return 0; /* No need to verify it again. */ memset (&pininfo, 0, sizeof pininfo); - pininfo.mode = 1; + pininfo.fixedlen = -1; pininfo.minlen = 6; pininfo.maxlen = 8; diff --git a/scd/app-nks.c b/scd/app-nks.c index 4e7a43c..8a48871 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -788,7 +788,7 @@ verify_pin (app_t app, int pwid, const char *desc, desc = "PIN"; memset (&pininfo, 0, sizeof pininfo); - pininfo.mode = 1; + pininfo.fixedlen = -1; pininfo.minlen = 6; pininfo.maxlen = 16; diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 968ef98..dcc3120 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1516,7 +1516,7 @@ verify_a_chv (app_t app, } memset (&pininfo, 0, sizeof pininfo); - pininfo.mode = 1; + pininfo.fixedlen = -1; pininfo.minlen = minlen; @@ -1712,7 +1712,7 @@ verify_chv3 (app_t app, char *prompt; memset (&pininfo, 0, sizeof pininfo); - pininfo.mode = 1; + pininfo.fixedlen = -1; pininfo.minlen = minlen; rc = build_enter_admin_pin_prompt (app, &prompt); @@ -1923,7 +1923,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, (void)ctrl; memset (&pininfo, 0, sizeof pininfo); - pininfo.mode = 1; + pininfo.fixedlen = -1; pininfo.minlen = minlen; if (reset_mode && chvno == 3) diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index c16c7ac..3244c71 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -3361,23 +3361,27 @@ ccid_transceive_secure (ccid_driver_t handle, cherry_mode = 1; break; case VENDOR_GEMPC: - enable_varlen = 0; if (handle->id_product == GEMPC_PINPAD) - break; + { + enable_varlen = 0; + pininfo->minlen = 4; + pininfo->maxlen = 8; + break; + } /* fall through */ default: return CCID_DRIVER_ERR_NOT_SUPPORTED; } if (enable_varlen) - pininfo->mode = 0; - - if (pininfo->mode != 0 && pininfo->mode != 1) - return CCID_DRIVER_ERR_NOT_SUPPORTED; + pininfo->fixedlen = 0; if (testmode) return 0; /* Success */ + if (pininfo->fixedlen < 0 || pininfo->fixedlen >= 16) + return CCID_DRIVER_ERR_NOT_SUPPORTED; + msg = send_buffer; if (handle->id_vendor == VENDOR_SCM) { @@ -3407,9 +3411,14 @@ ccid_transceive_secure (ccid_driver_t handle, } else { - msg[13] = 0x00; /* bmPINBlockString: - 0 bits of pin length to insert. - 0 bytes of PIN block size. */ + if (pininfo->fixedlen == 0) + msg[13] = 0x00; /* bmPINBlockString: + 0 bits of pin length to insert. + 0 bytes of PIN block size. */ + else + msg[13] = pininfo->fixedlen; /* bmPINBlockString: + 0 bits of pin length to insert. + PIN block size by fixedlen. */ msg[14] = 0x00; /* bmPINLengthFormat: Units are bytes, position is 0. */ } @@ -3418,7 +3427,10 @@ ccid_transceive_secure (ccid_driver_t handle, if (apdu_buf[1] == 0x24) { msg[msglen++] = 0; /* bInsertionOffsetOld */ - msg[msglen++] = 0; /* bInsertionOffsetNew */ + if (pininfo->fixedlen == 0) + msg[msglen++] = 0; /* bInsertionOffsetNew */ + else + msg[msglen++] = pininfo->fixedlen; /* bInsertionOffsetNew */ } /* The following is a little endian word. */ @@ -3457,10 +3469,18 @@ ccid_transceive_secure (ccid_driver_t handle, msg[msglen++] = 2; /* bMsgIndex3. */ } + /* Calculate Lc. */ + n = pininfo->fixedlen; + if (apdu_buf[1] == 0x24) + n += pininfo->fixedlen; + /* bTeoProlog follows: */ msg[msglen++] = handle->nonnull_nad? ((1 << 4) | 0): 0; msg[msglen++] = ((handle->t1_ns & 1) << 6); /* I-block */ - msg[msglen++] = 0; /* The apdulen will be filled in by the reader. */ + if (n) + msg[msglen++] = n + 5; /* apdulen should be filled for fixed length. */ + else + msg[msglen++] = 0; /* The apdulen will be filled in by the reader. */ /* APDU follows: */ msg[msglen++] = apdu_buf[0]; /* CLA */ msg[msglen++] = apdu_buf[1]; /* INS */ @@ -3468,6 +3488,12 @@ ccid_transceive_secure (ccid_driver_t handle, msg[msglen++] = apdu_buf[3]; /* P2 */ if (cherry_mode) msg[msglen++] = 0; + else if (pininfo->fixedlen != 0) + { + msg[msglen++] = n; + memset (&msg[msglen], 0xff, n); + msglen += n; + } /* An EDC is not required. */ set_msg_len (msg, msglen - 10); diff --git a/scd/iso7816.h b/scd/iso7816.h index e6dfecd..bf195ea 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -34,7 +34,12 @@ ccid-driver.c for details. */ struct pininfo_s { - int mode; /* 0: Use variable length input. 1: Use fixed length input. */ + int fixedlen; /* + * -1: Variable length input is not supported, + * no information of fixed length yet. + * 0: Use variable length input. + * >0: Fixed length of PIN. + */ int minlen; int maxlen; }; commit a3be9e586f9a58295dbae0a23ec230d1f7d6af93 Author: NIIBE Yutaka Date: Wed Jan 9 14:10:08 2013 +0900 SCD: API cleanup for keypad handling. * scd/iso7816.h (struct pininfo_s): Rename from iso7816_pininfo_s. Change meaning of MODE. (pininfo_t): Rename from iso7816_pininfo_t. * scd/sc-copykeys.c: Include "iso7816.h". * scd/scdaemon.c, scd/command.c: Likewise. * scd/ccid-driver.c: Include "scdaemon.h" and "iso7816.h". (ccid_transceive_secure): Follow the change of PININFO_T. * scd/app.c: Include "apdu.h" after "iso7816.h". * scd/iso7816.c (iso7816_check_keypad, iso7816_verify_kp) (iso7816_change_reference_data_kp): Follow the change of API. * scd/apdu.c (struct reader_table_s): Change API of CHECK_KEYPAD, KEYPAD_VERIFY, KEYPAD_MODIFY to have arg of PININFO_T. (check_pcsc_keypad, check_ccid_keypad): Likewise. (apdu_check_keypad, apdu_keypad_verify, apdu_keypad_modify): Likewise. (pcsc_keypad_verify, pcsc_keypad_modify, ct_send_apdu) (pcsc_send_apdu_direct, pcsc_send_apdu_wrapped, pcsc_send_apdu) (send_apdu_ccid, ccid_keypad_operation, my_rapdu_send_apdu, send_apdu) (send_le): Follow the change of API. * scd/apdu.h (apdu_check_keypad, apdu_keypad_verify) (apdu_keypad_modify): Change the API. * scd/app-dinsig.c, scd/app-nks.c, scd/app-openpgp.c: Follow the change. diff --git a/scd/apdu.c b/scd/apdu.c index 9f4c288..1e776df 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -60,10 +60,9 @@ #include "exechelp.h" #endif /* GNUPG_MAJOR_VERSION != 1 */ +#include "iso7816.h" #include "apdu.h" #include "ccid-driver.h" -#include "iso7816.h" - /* Due to conflicting use of threading libraries we usually can't link against libpcsclite. Instead we use a wrapper program. */ @@ -83,8 +82,6 @@ #define DLSTDCALL #endif -#define pininfo_s iso7816_pininfo_s - /* A structure to collect information pertaining to one reader slot. */ struct reader_table_s { @@ -99,12 +96,12 @@ struct reader_table_s { int (*reset_reader)(int); int (*get_status_reader)(int, unsigned int *); int (*send_apdu_reader)(int,unsigned char *,size_t, - unsigned char *, size_t *, struct pininfo_s *); - int (*check_keypad)(int, int, int, int, int); + unsigned char *, size_t *, pininfo_t *); + int (*check_keypad)(int, int, pininfo_t *); void (*dump_status_reader)(int); int (*set_progress_cb)(int, gcry_handler_progress_t, void*); - int (*keypad_verify)(int, int, int, int, int, struct pininfo_s *); - int (*keypad_modify)(int, int, int, int, int, struct pininfo_s *); + int (*keypad_verify)(int, int, int, int, int, pininfo_t *); + int (*keypad_modify)(int, int, int, int, int, pininfo_t *); struct { ccid_driver_t handle; @@ -322,12 +319,11 @@ static int reset_pcsc_reader (int slot); static int apdu_get_status_internal (int slot, int hang, int no_atr_reset, unsigned int *status, unsigned int *changed); -static int check_pcsc_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max); +static int check_pcsc_keypad (int slot, int command, pininfo_t *pininfo); static int pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, - struct pininfo_s *pininfo); + pininfo_t *pininfo); static int pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, - struct pininfo_s *pininfo); + pininfo_t *pininfo); @@ -600,7 +596,7 @@ ct_get_status (int slot, unsigned int *status) set to BUFLEN. Returns: CT API error code. */ static int ct_send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen, struct pininfo_s *pininfo) + unsigned char *buffer, size_t *buflen, pininfo_t *pininfo) { int rc; unsigned char dad[1], sad[1]; @@ -1031,7 +1027,7 @@ pcsc_get_status (int slot, unsigned int *status) static int pcsc_send_apdu_direct (int slot, unsigned char *apdu, size_t apdulen, unsigned char *buffer, size_t *buflen, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { long err; struct pcsc_io_request_s send_pci; @@ -1067,7 +1063,7 @@ pcsc_send_apdu_direct (int slot, unsigned char *apdu, size_t apdulen, static int pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen, unsigned char *buffer, size_t *buflen, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { long err; reader_table_t slotp; @@ -1187,7 +1183,7 @@ pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen, static int pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, unsigned char *buffer, size_t *buflen, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { #ifdef NEED_PCSC_WRAPPER return pcsc_send_apdu_wrapped (slot, apdu, apdulen, buffer, buflen, pininfo); @@ -1984,16 +1980,13 @@ open_pcsc_reader (const char *portstr) /* Check whether the reader supports the ISO command code COMMAND on the keypad. Return 0 on success. */ static int -check_pcsc_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max) +check_pcsc_keypad (int slot, int command, pininfo_t *pininfo) { unsigned char buf[256]; size_t len = 256; int sw; - (void)pin_mode; - (void)pinlen_min; - (void)pinlen_max; + (void)pininfo; check_again: if (command == ISO7816_VERIFY) @@ -2045,7 +2038,7 @@ check_pcsc_keypad (int slot, int command, int pin_mode, #define PIN_VERIFY_STRUCTURE_SIZE 24 static int pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { int sw; unsigned char *pin_verify; @@ -2126,7 +2119,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, #define PIN_MODIFY_STRUCTURE_SIZE 29 static int pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { int sw; unsigned char *pin_modify; @@ -2297,7 +2290,7 @@ get_status_ccid (int slot, unsigned int *status) static int send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, unsigned char *buffer, size_t *buflen, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { long err; size_t maxbuflen; @@ -2313,10 +2306,7 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, maxbuflen = *buflen; if (pininfo) err = ccid_transceive_secure (reader_table[slot].ccid.handle, - apdu, apdulen, - pininfo->mode, - pininfo->minlen, - pininfo->maxlen, + apdu, apdulen, pininfo, buffer, maxbuflen, buflen); else err = ccid_transceive (reader_table[slot].ccid.handle, @@ -2334,22 +2324,19 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, on the keypad. Return 0 on success. For a description of the pin parameters, see ccid-driver.c */ static int -check_ccid_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max) +check_ccid_keypad (int slot, int command, pininfo_t *pininfo) { unsigned char apdu[] = { 0, 0, 0, 0x81 }; apdu[1] = command; - return ccid_transceive_secure (reader_table[slot].ccid.handle, - apdu, sizeof apdu, - pin_mode, pinlen_min, pinlen_max, - NULL, 0, NULL); + return ccid_transceive_secure (reader_table[slot].ccid.handle, apdu, + sizeof apdu, pininfo, NULL, 0, NULL); } static int ccid_keypad_operation (int slot, int class, int ins, int p0, int p1, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { unsigned char apdu[4]; int err, sw; @@ -2361,8 +2348,7 @@ ccid_keypad_operation (int slot, int class, int ins, int p0, int p1, apdu[2] = p0; apdu[3] = p1; err = ccid_transceive_secure (reader_table[slot].ccid.handle, - apdu, sizeof apdu, - pininfo->mode, pininfo->minlen, pininfo->maxlen, + apdu, sizeof apdu, pininfo, result, 2, &resultlen); if (err) return err; @@ -2580,7 +2566,7 @@ my_rapdu_get_status (int slot, unsigned int *status) static int my_rapdu_send_apdu (int slot, unsigned char *apdu, size_t apdulen, unsigned char *buffer, size_t *buflen, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { int err; reader_table_t slotp; @@ -3405,57 +3391,46 @@ apdu_get_status (int slot, int hang, the keypad. Return 0 on success. For a description of the pin parameters, see ccid-driver.c */ int -apdu_check_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max) +apdu_check_keypad (int slot, int command, pininfo_t *pininfo) { if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; + if (opt.enable_keypad_varlen) + pininfo->mode = 0; + if (reader_table[slot].check_keypad) - return reader_table[slot].check_keypad (slot, command, - pin_mode, pinlen_min, pinlen_max); + return reader_table[slot].check_keypad (slot, command, pininfo); else return SW_HOST_NOT_SUPPORTED; } int -apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, int pin_mode, - int pinlen_min, int pinlen_max) +apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, + pininfo_t *pininfo) { - struct pininfo_s pininfo; - - pininfo.mode = pin_mode; - pininfo.minlen = pinlen_min; - pininfo.maxlen = pinlen_max; - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; if (reader_table[slot].keypad_verify) return reader_table[slot].keypad_verify (slot, class, ins, p0, p1, - &pininfo); + pininfo); else return SW_HOST_NOT_SUPPORTED; } int -apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, int pin_mode, - int pinlen_min, int pinlen_max) +apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, + pininfo_t *pininfo) { - struct pininfo_s pininfo; - - pininfo.mode = pin_mode; - pininfo.minlen = pinlen_min; - pininfo.maxlen = pinlen_max; - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; if (reader_table[slot].keypad_modify) return reader_table[slot].keypad_modify (slot, class, ins, p0, p1, - &pininfo); + pininfo); else return SW_HOST_NOT_SUPPORTED; } @@ -3465,7 +3440,7 @@ apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, int pin_mode, function should be called in locked state. */ static int send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen, struct pininfo_s *pininfo) + unsigned char *buffer, size_t *buflen, pininfo_t *pininfo) { if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; @@ -3497,7 +3472,7 @@ static int send_le (int slot, int class, int ins, int p0, int p1, int lc, const char *data, int le, unsigned char **retbuf, size_t *retbuflen, - struct pininfo_s *pininfo, int extended_mode) + pininfo_t *pininfo, int extended_mode) { #define SHORT_RESULT_BUFFER_SIZE 258 /* We allocate 8 extra bytes as a safety margin towards a driver bug. */ diff --git a/scd/apdu.h b/scd/apdu.h index 6bf6176..c69fe36 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -114,12 +114,11 @@ int apdu_set_progress_cb (int slot, gcry_handler_progress_t cb, void *cb_arg); int apdu_reset (int slot); int apdu_get_status (int slot, int hang, unsigned int *status, unsigned int *changed); -int apdu_check_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max); +int apdu_check_keypad (int slot, int command, pininfo_t *pininfo); int apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, - int pin_mode, int pinlen_min, int pinlen_max); + pininfo_t *pininfo); int apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, - int pin_mode, int pinlen_min, int pinlen_max); + pininfo_t *pininfo); int apdu_send_simple (int slot, int extended_mode, int class, int ins, int p0, int p1, int lc, const char *data); diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c index 50db78e..f3f7d4b 100644 --- a/scd/app-dinsig.c +++ b/scd/app-dinsig.c @@ -282,7 +282,7 @@ verify_pin (app_t app, { const char *s; int rc; - iso7816_pininfo_t pininfo; + pininfo_t pininfo; if ( app->did_chv1 && !app->force_chv1 ) return 0; /* No need to verify it again. */ diff --git a/scd/app-nks.c b/scd/app-nks.c index 28ccb9a..4e7a43c 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -781,7 +781,7 @@ verify_pin (app_t app, int pwid, const char *desc, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { - iso7816_pininfo_t pininfo; + pininfo_t pininfo; int rc; if (!desc) @@ -1144,7 +1144,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *pwidstr, int is_sigg; const char *newdesc; int pwid; - iso7816_pininfo_t pininfo; + pininfo_t pininfo; (void)ctrl; diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 5928ec6..968ef98 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1489,7 +1489,7 @@ verify_a_chv (app_t app, int rc = 0; char *prompt_buffer = NULL; const char *prompt; - iso7816_pininfo_t pininfo; + pininfo_t pininfo; int minlen = 6; assert (chvno == 1 || chvno == 2); @@ -1707,7 +1707,7 @@ verify_chv3 (app_t app, if (!app->did_chv3) { - iso7816_pininfo_t pininfo; + pininfo_t pininfo; int minlen = 8; char *prompt; @@ -1917,7 +1917,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, char *pinvalue = NULL; int reset_mode = !!(flags & APP_CHANGE_FLAG_RESET); int set_resetcode = 0; - iso7816_pininfo_t pininfo; + pininfo_t pininfo; int use_keypad = 0; int minlen = 6; diff --git a/scd/app.c b/scd/app.c index dfb5991..e6a663e 100644 --- a/scd/app.c +++ b/scd/app.c @@ -26,8 +26,8 @@ #include "scdaemon.h" #include "app-common.h" -#include "apdu.h" #include "iso7816.h" +#include "apdu.h" #include "tlv.h" /* This table is used to keep track of locks on a per reader base. diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 710d0e2..c16c7ac 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -89,6 +89,8 @@ #include +#include "scdaemon.h" +#include "iso7816.h" #include "ccid-driver.h" #define DRVNAME "ccid-driver: " @@ -3296,7 +3298,7 @@ ccid_transceive (ccid_driver_t handle, int ccid_transceive_secure (ccid_driver_t handle, const unsigned char *apdu_buf, size_t apdu_buflen, - int pin_mode, int pinlen_min, int pinlen_max, + pininfo_t *pininfo, unsigned char *resp, size_t maxresplen, size_t *nresp) { int rc; @@ -3307,7 +3309,7 @@ ccid_transceive_secure (ccid_driver_t handle, size_t dummy_nresp; int testmode; int cherry_mode = 0; - int enable_varlen = opt.enable_keypad_varlen; + int enable_varlen = 0; testmode = !resp && !nresp; @@ -3322,18 +3324,15 @@ ccid_transceive_secure (ccid_driver_t handle, else return CCID_DRIVER_ERR_NO_KEYPAD; - if (pin_mode != 1) - return CCID_DRIVER_ERR_NOT_SUPPORTED; - - if (!pinlen_min) - pinlen_min = 1; - if (!pinlen_max) - pinlen_max = 25; + if (!pininfo->minlen) + pininfo->minlen = 1; + if (!pininfo->maxlen) + pininfo->maxlen = 25; /* Note that the 25 is the maximum value the SPR532 allows. */ - if (pinlen_min < 1 || pinlen_min > 25 - || pinlen_max < 1 || pinlen_max > 25 - || pinlen_min > pinlen_max) + if (pininfo->minlen < 1 || pininfo->minlen > 25 + || pininfo->maxlen < 1 || pininfo->maxlen > 25 + || pininfo->minlen > pininfo->maxlen) return CCID_DRIVER_ERR_INV_VALUE; /* We have only tested a few readers so better don't risk anything @@ -3347,7 +3346,7 @@ ccid_transceive_secure (ccid_driver_t handle, break; case VENDOR_VASCO: /* Tested with DIGIPASS 920 */ enable_varlen = 1; - pinlen_max = 15; + pininfo->maxlen = 15; break; case VENDOR_CHERRY: enable_varlen = 1; @@ -3370,6 +3369,12 @@ ccid_transceive_secure (ccid_driver_t handle, return CCID_DRIVER_ERR_NOT_SUPPORTED; } + if (enable_varlen) + pininfo->mode = 0; + + if (pininfo->mode != 0 && pininfo->mode != 1) + return CCID_DRIVER_ERR_NOT_SUPPORTED; + if (testmode) return 0; /* Success */ @@ -3417,8 +3422,8 @@ ccid_transceive_secure (ccid_driver_t handle, } /* The following is a little endian word. */ - msg[msglen++] = pinlen_max; /* wPINMaxExtraDigit-Maximum. */ - msg[msglen++] = pinlen_min; /* wPINMaxExtraDigit-Minimum. */ + msg[msglen++] = pininfo->maxlen; /* wPINMaxExtraDigit-Maximum. */ + msg[msglen++] = pininfo->minlen; /* wPINMaxExtraDigit-Minimum. */ if (apdu_buf[1] == 0x24) msg[msglen++] = apdu_buf[2] == 0 ? 0x03 : 0x01; @@ -3431,7 +3436,7 @@ ccid_transceive_secure (ccid_driver_t handle, msg[msglen] = 0x02; /* bEntryValidationCondition: Validation key pressed */ - if (pinlen_min && pinlen_max && pinlen_min == pinlen_max) + if (pininfo->minlen && pininfo->maxlen && pininfo->minlen == pininfo->maxlen) msg[msglen] |= 0x01; /* Max size reached. */ msglen++; diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h index e0f4895..217bb72 100644 --- a/scd/ccid-driver.h +++ b/scd/ccid-driver.h @@ -93,8 +93,7 @@ int ccid_transceive (ccid_driver_t handle, unsigned char *resp, size_t maxresplen, size_t *nresp); int ccid_transceive_secure (ccid_driver_t handle, const unsigned char *apdu, size_t apdulen, - int pin_mode, - int pinlen_min, int pinlen_max, + pininfo_t *pininfo, unsigned char *resp, size_t maxresplen, size_t *nresp); int ccid_transceive_escape (ccid_driver_t handle, const unsigned char *data, size_t datalen, diff --git a/scd/command.c b/scd/command.c index 40e61a4..343830a 100644 --- a/scd/command.c +++ b/scd/command.c @@ -34,6 +34,7 @@ #include #include #include "app-common.h" +#include "iso7816.h" #include "apdu.h" /* Required for apdu_*_reader (). */ #include "atr.h" #include "exechelp.h" diff --git a/scd/iso7816.c b/scd/iso7816.c index 966a741..b2324b4 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -269,12 +269,11 @@ iso7816_apdu_direct (int slot, const void *apdudata, size_t apdudatalen, /* Check whether the reader supports the ISO command code COMMAND on the keypad. Returns 0 on success. */ gpg_error_t -iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo) +iso7816_check_keypad (int slot, int command, pininfo_t *pininfo) { int sw; - sw = apdu_check_keypad (slot, command, - pininfo->mode, pininfo->minlen, pininfo->maxlen); + sw = apdu_check_keypad (slot, command, pininfo); return iso7816_map_sw (sw); } @@ -283,12 +282,11 @@ iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo) vector CHVNO. With PININFO non-NULL the keypad of the reader will be used. Returns 0 on success. */ gpg_error_t -iso7816_verify_kp (int slot, int chvno, iso7816_pininfo_t *pininfo) +iso7816_verify_kp (int slot, int chvno, pininfo_t *pininfo) { int sw; - sw = apdu_keypad_verify (slot, 0x00, CMD_VERIFY, 0, chvno, - pininfo->mode, pininfo->minlen, pininfo->maxlen); + sw = apdu_keypad_verify (slot, 0x00, CMD_VERIFY, 0, chvno, pininfo); return map_sw (sw); } @@ -309,14 +307,12 @@ iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen) data" is done, otherwise an "exchange reference data". */ gpg_error_t iso7816_change_reference_data_kp (int slot, int chvno, int is_exchange, - iso7816_pininfo_t *pininfo) + pininfo_t *pininfo) { int sw; sw = apdu_keypad_modify (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, - is_exchange ? 1 : 0, - chvno, pininfo->mode, pininfo->minlen, - pininfo->maxlen); + is_exchange ? 1 : 0, chvno, pininfo); return map_sw (sw); } diff --git a/scd/iso7816.h b/scd/iso7816.h index a4e5b70..e6dfecd 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -32,13 +32,13 @@ /* Information to be passed to keypad equipped readers. See ccid-driver.c for details. */ -struct iso7816_pininfo_s +struct pininfo_s { - int mode; /* A mode of 0 means: Do not use the keypad. */ + int mode; /* 0: Use variable length input. 1: Use fixed length input. */ int minlen; int maxlen; }; -typedef struct iso7816_pininfo_s iso7816_pininfo_t; +typedef struct pininfo_s pininfo_t; gpg_error_t iso7816_map_sw (int sw); @@ -58,16 +58,16 @@ gpg_error_t iso7816_apdu_direct (int slot, int handle_more, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_check_keypad (int slot, int command, - iso7816_pininfo_t *pininfo); + pininfo_t *pininfo); gpg_error_t iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen); -gpg_error_t iso7816_verify_kp (int slot, int chvno, iso7816_pininfo_t *pininfo); +gpg_error_t iso7816_verify_kp (int slot, int chvno, pininfo_t *pininfo); gpg_error_t iso7816_change_reference_data (int slot, int chvno, const char *oldchv, size_t oldchvlen, const char *newchv, size_t newchvlen); gpg_error_t iso7816_change_reference_data_kp (int slot, int chvno, int is_exchange, - iso7816_pininfo_t *pininfo); + pininfo_t *pininfo); gpg_error_t iso7816_reset_retry_counter (int slot, int chvno, const char *newchv, size_t newchvlen); gpg_error_t iso7816_reset_retry_counter_with_rc (int slot, int chvno, diff --git a/scd/sc-copykeys.c b/scd/sc-copykeys.c index 3f34d69..e503d36 100644 --- a/scd/sc-copykeys.c +++ b/scd/sc-copykeys.c @@ -33,6 +33,7 @@ #include "../common/ttyio.h" #include "../common/simple-pwquery.h" +#include "iso7816.h" #include "apdu.h" /* for open_reader */ #include "atr.h" #include "app-common.h" diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 1b61894..f8a86c8 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -48,6 +48,7 @@ #include "i18n.h" #include "sysutils.h" #include "app-common.h" +#include "iso7816.h" #include "apdu.h" #include "ccid-driver.h" #include "mkdtemp.h" commit d75de701f52ad2c0dd27bee16446ae9ca8f52c32 Author: NIIBE Yutaka Date: Mon Jan 7 14:20:55 2013 +0900 SCD: Clean up. Remove PADLEN for keypad input. * scd/apdu.c (struct pininfo_s): Use iso7816_pininfo_s. (struct reader_table_s): Remove last arg from check_keypad method. (check_pcsc_keypad, check_pcsc_keypad): Remove PIN_PADLEN. (pcsc_keypad_verify, pcsc_keypad_modify): Don't check PIN_PADLEN. (send_apdu_ccid, ccid_keypad_operation): Remove PIN_PADLEN. (apdu_check_keypad, apdu_keypad_verify, apdu_keypad_modify): Likewise. * scd/apdu.h (apdu_check_keypad, apdu_keypad_verify) (apdu_keypad_modify): Remove PIN_PADLEN. * scd/ccid-driver.c (ccid_transceive_secure): Remove PIN_PADLEN. * scd/ccid-driver.h (ccid_transceive_secure): Remove PIN_PADLEN. * scd/iso7816.c (iso7816_check_keypad, iso7816_verify_kp) (iso7816_change_reference_data_kp): Remove PADLEN. * scd/iso7816.h (struct iso7816_pininfo_s): Remove PADLEN, PADCHAR. -- In the OpenPGPcard specification, password comes with no padding. In GnuPG, we support keypad input for OpenPGPcard only. Thus, it is useless to try to support padding for keypad input. diff --git a/scd/apdu.c b/scd/apdu.c index 68d4e99..9f4c288 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -83,15 +83,7 @@ #define DLSTDCALL #endif - -/* Helper to pass parameters related to keypad based operations. */ -struct pininfo_s -{ - int mode; - int minlen; - int maxlen; - int padlen; -}; +#define pininfo_s iso7816_pininfo_s /* A structure to collect information pertaining to one reader slot. */ @@ -108,7 +100,7 @@ struct reader_table_s { int (*get_status_reader)(int, unsigned int *); int (*send_apdu_reader)(int,unsigned char *,size_t, unsigned char *, size_t *, struct pininfo_s *); - int (*check_keypad)(int, int, int, int, int, int); + int (*check_keypad)(int, int, int, int, int); void (*dump_status_reader)(int); int (*set_progress_cb)(int, gcry_handler_progress_t, void*); int (*keypad_verify)(int, int, int, int, int, struct pininfo_s *); @@ -331,7 +323,7 @@ static int apdu_get_status_internal (int slot, int hang, int no_atr_reset, unsigned int *status, unsigned int *changed); static int check_pcsc_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max, int pin_padlen); + int pinlen_min, int pinlen_max); static int pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, struct pininfo_s *pininfo); static int pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, @@ -1993,7 +1985,7 @@ open_pcsc_reader (const char *portstr) on the keypad. Return 0 on success. */ static int check_pcsc_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max, int pin_padlen) + int pinlen_min, int pinlen_max) { unsigned char buf[256]; size_t len = 256; @@ -2002,7 +1994,6 @@ check_pcsc_keypad (int slot, int command, int pin_mode, (void)pin_mode; (void)pinlen_min; (void)pinlen_max; - (void)pin_padlen; check_again: if (command == ISO7816_VERIFY) @@ -2069,9 +2060,6 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, if (pininfo->mode != 1) return SW_NOT_SUPPORTED; - if (pininfo->padlen != 0) - return SW_NOT_SUPPORTED; - if (!pininfo->minlen) pininfo->minlen = 1; if (!pininfo->maxlen) @@ -2153,9 +2141,6 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, if (pininfo->mode != 1) return SW_NOT_SUPPORTED; - if (pininfo->padlen != 0) - return SW_NOT_SUPPORTED; - if (!pininfo->minlen) pininfo->minlen = 1; if (!pininfo->maxlen) @@ -2332,7 +2317,6 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, pininfo->mode, pininfo->minlen, pininfo->maxlen, - pininfo->padlen, buffer, maxbuflen, buflen); else err = ccid_transceive (reader_table[slot].ccid.handle, @@ -2351,14 +2335,14 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, parameters, see ccid-driver.c */ static int check_ccid_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max, int pin_padlen) + int pinlen_min, int pinlen_max) { unsigned char apdu[] = { 0, 0, 0, 0x81 }; apdu[1] = command; return ccid_transceive_secure (reader_table[slot].ccid.handle, apdu, sizeof apdu, - pin_mode, pinlen_min, pinlen_max, pin_padlen, + pin_mode, pinlen_min, pinlen_max, NULL, 0, NULL); } @@ -2379,7 +2363,6 @@ ccid_keypad_operation (int slot, int class, int ins, int p0, int p1, err = ccid_transceive_secure (reader_table[slot].ccid.handle, apdu, sizeof apdu, pininfo->mode, pininfo->minlen, pininfo->maxlen, - pininfo->padlen, result, 2, &resultlen); if (err) return err; @@ -3423,15 +3406,14 @@ apdu_get_status (int slot, int hang, parameters, see ccid-driver.c */ int apdu_check_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max, int pin_padlen) + int pinlen_min, int pinlen_max) { if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; if (reader_table[slot].check_keypad) return reader_table[slot].check_keypad (slot, command, - pin_mode, pinlen_min, pinlen_max, - pin_padlen); + pin_mode, pinlen_min, pinlen_max); else return SW_HOST_NOT_SUPPORTED; } @@ -3439,14 +3421,13 @@ apdu_check_keypad (int slot, int command, int pin_mode, int apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, int pin_mode, - int pinlen_min, int pinlen_max, int pin_padlen) + int pinlen_min, int pinlen_max) { struct pininfo_s pininfo; pininfo.mode = pin_mode; pininfo.minlen = pinlen_min; pininfo.maxlen = pinlen_max; - pininfo.padlen = pin_padlen; if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; @@ -3461,14 +3442,13 @@ apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, int pin_mode, int apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, int pin_mode, - int pinlen_min, int pinlen_max, int pin_padlen) + int pinlen_min, int pinlen_max) { struct pininfo_s pininfo; pininfo.mode = pin_mode; pininfo.minlen = pinlen_min; pininfo.maxlen = pinlen_max; - pininfo.padlen = pin_padlen; if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; diff --git a/scd/apdu.h b/scd/apdu.h index bf55346..6bf6176 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -115,13 +115,11 @@ int apdu_reset (int slot); int apdu_get_status (int slot, int hang, unsigned int *status, unsigned int *changed); int apdu_check_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max, int pin_padlen); + int pinlen_min, int pinlen_max); int apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, - int pin_mode, int pinlen_min, int pinlen_max, - int pin_padlen); + int pin_mode, int pinlen_min, int pinlen_max); int apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, - int pin_mode, int pinlen_min, int pinlen_max, - int pin_padlen); + int pin_mode, int pinlen_min, int pinlen_max); int apdu_send_simple (int slot, int extended_mode, int class, int ins, int p0, int p1, int lc, const char *data); diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index f545c71..710d0e2 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -3288,7 +3288,7 @@ ccid_transceive (ccid_driver_t handle, The APDU should me made up of 4 bytes without Lc. PINLEN_MIN and PINLEN_MAX define the limits for the pin length. 0 - may be used t enable reasonable defaults. PIN_PADLEN should be 0. + may be used t enable reasonable defaults. When called with RESP and NRESP set to NULL, the function will merely check whether the reader supports the secure command for the @@ -3297,7 +3297,6 @@ int ccid_transceive_secure (ccid_driver_t handle, const unsigned char *apdu_buf, size_t apdu_buflen, int pin_mode, int pinlen_min, int pinlen_max, - int pin_padlen, unsigned char *resp, size_t maxresplen, size_t *nresp) { int rc; @@ -3326,9 +3325,6 @@ ccid_transceive_secure (ccid_driver_t handle, if (pin_mode != 1) return CCID_DRIVER_ERR_NOT_SUPPORTED; - if (pin_padlen != 0) - return CCID_DRIVER_ERR_NOT_SUPPORTED; - if (!pinlen_min) pinlen_min = 1; if (!pinlen_max) diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h index 121cb94..e0f4895 100644 --- a/scd/ccid-driver.h +++ b/scd/ccid-driver.h @@ -94,7 +94,7 @@ int ccid_transceive (ccid_driver_t handle, int ccid_transceive_secure (ccid_driver_t handle, const unsigned char *apdu, size_t apdulen, int pin_mode, - int pinlen_min, int pinlen_max, int pin_padlen, + int pinlen_min, int pinlen_max, unsigned char *resp, size_t maxresplen, size_t *nresp); int ccid_transceive_escape (ccid_driver_t handle, const unsigned char *data, size_t datalen, diff --git a/scd/iso7816.c b/scd/iso7816.c index 45f5e08..966a741 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -274,8 +274,7 @@ iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo) int sw; sw = apdu_check_keypad (slot, command, - pininfo->mode, pininfo->minlen, pininfo->maxlen, - pininfo->padlen); + pininfo->mode, pininfo->minlen, pininfo->maxlen); return iso7816_map_sw (sw); } @@ -289,8 +288,7 @@ iso7816_verify_kp (int slot, int chvno, iso7816_pininfo_t *pininfo) int sw; sw = apdu_keypad_verify (slot, 0x00, CMD_VERIFY, 0, chvno, - pininfo->mode, pininfo->minlen, pininfo->maxlen, - pininfo->padlen); + pininfo->mode, pininfo->minlen, pininfo->maxlen); return map_sw (sw); } @@ -318,7 +316,7 @@ iso7816_change_reference_data_kp (int slot, int chvno, int is_exchange, sw = apdu_keypad_modify (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, is_exchange ? 1 : 0, chvno, pininfo->mode, pininfo->minlen, - pininfo->maxlen, pininfo->padlen); + pininfo->maxlen); return map_sw (sw); } diff --git a/scd/iso7816.h b/scd/iso7816.h index 336208a..a4e5b70 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -37,8 +37,6 @@ struct iso7816_pininfo_s int mode; /* A mode of 0 means: Do not use the keypad. */ int minlen; int maxlen; - int padlen; - int padchar; }; typedef struct iso7816_pininfo_s iso7816_pininfo_t; commit 23edafc0327a39331535dd162024e09a90d6733c Author: NIIBE Yutaka Date: Wed Jan 9 13:24:57 2013 +0900 SCD: Add option enable-keypad-varlen and support for GEMPC_PINPAD. * scd/scdaemon.h (opt): Add enable_keypad_varlen. * scd/scdaemon.c (cmd_and_opt_values): Add oEnableKeypadVarlen. (opts, main): Add oEnableKeypadVarlen. * scd/ccid-driver.c (GEMPC_PINPAD): New. (ccid_transceive_secure): Add enable_varlen handling. Enable GEMPC_PINPAD. -- Note that GEMPC_PINPAD doesn't support variable length keypad input. The feature of fixed length keypad input will be added soon. diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 5b3bcaf..f545c71 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -220,6 +220,7 @@ enum { #define SCM_SPR532 0xe003 #define CHERRY_ST2000 0x003e #define VASCO_920 0x0920 +#define GEMPC_PINPAD 0x3478 /* A list and a table with special transport descriptions. */ enum { @@ -3307,6 +3308,7 @@ ccid_transceive_secure (ccid_driver_t handle, size_t dummy_nresp; int testmode; int cherry_mode = 0; + int enable_varlen = opt.enable_keypad_varlen; testmode = !resp && !nresp; @@ -3345,11 +3347,14 @@ ccid_transceive_secure (ccid_driver_t handle, case VENDOR_SCM: /* Tested with SPR 532. */ case VENDOR_KAAN: /* Tested with KAAN Advanced (1.02). */ case VENDOR_FSIJ: /* Tested with the gnuk code (2011-01-05). */ + enable_varlen = 1; break; case VENDOR_VASCO: /* Tested with DIGIPASS 920 */ + enable_varlen = 1; pinlen_max = 15; break; case VENDOR_CHERRY: + enable_varlen = 1; /* The CHERRY XX44 keyboard echos an asterisk for each entered character on the keyboard channel. We use a special variant of PC_to_RDR_Secure which directs these characters to the @@ -3360,6 +3365,11 @@ ccid_transceive_secure (ccid_driver_t handle, if (handle->id_product != CHERRY_ST2000) cherry_mode = 1; break; + case VENDOR_GEMPC: + enable_varlen = 0; + if (handle->id_product == GEMPC_PINPAD) + break; + /* fall through */ default: return CCID_DRIVER_ERR_NOT_SUPPORTED; } diff --git a/scd/scdaemon.c b/scd/scdaemon.c index af4c9c1..1b61894 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -95,6 +95,7 @@ enum cmd_and_opt_values oAllowAdmin, oDenyAdmin, oDisableApplication, + oEnableKeypadVarlen, oDebugDisableTicker }; @@ -148,6 +149,8 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oDenyAdmin, "deny-admin", N_("deny the use of admin card commands")), ARGPARSE_s_s (oDisableApplication, "disable-application", "@"), + ARGPARSE_s_n (oEnableKeypadVarlen, "enable-keypad-varlen", + N_("use variable length input for keypad")), ARGPARSE_end () }; @@ -587,6 +590,8 @@ main (int argc, char **argv ) add_to_strlist (&opt.disabled_applications, pargs.r.ret_str); break; + case oEnableKeypadVarlen: opt.enable_keypad_varlen = 1; break; + default: pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR; break; diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 74e8b7d..8f048d5 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -57,6 +57,7 @@ struct const char *reader_port; /* NULL or reder port to use. */ int disable_ccid; /* Disable the use of the internal CCID driver. */ int disable_keypad; /* Do not use a keypad. */ + int enable_keypad_varlen; /* Use variable length input for keypad. */ int allow_admin; /* Allow the use of admin commands for certain cards. */ strlist_t disabled_applications; /* Card applications we do not ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Jan 10 03:00:04 2013 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 10 Jan 2013 03:00:04 +0100 Subject: [git] GnuPG - branch, scd-work, updated. gnupg-2.1.0beta3-131-g4ef0063 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, scd-work has been updated via 4ef0063efedf6c4e02f3e6b4e355810b400aae15 (commit) from 943ce30e29cdd803588d1b6c316f52986f2a7d8b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4ef0063efedf6c4e02f3e6b4e355810b400aae15 Author: NIIBE Yutaka Date: Thu Jan 10 10:49:27 2013 +0900 SCD: Add support of Covadis VEGA_ALPHA reader. * scd/ccid-driver.c: Add 2013. (VENDER_VEGA, VEGA_ALPHA):New. (ccid_transceive_secure): VEGA_ALPHA is same firmware as GEMPC_PINPAD. Change bNumberMessage to 0x01, as it works better (was: 0xff). diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 83b419a..95e85d9 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -1,6 +1,6 @@ /* ccid-driver.c - USB ChipCardInterfaceDevices driver * Copyright (C) 2003, 2004, 2005, 2006, 2007 - * 2008, 2009 Free Software Foundation, Inc. + * 2008, 2009, 2013 Free Software Foundation, Inc. * Written by Werner Koch. * * This file is part of GnuPG. @@ -209,6 +209,7 @@ enum { VENDOR_SCM = 0x04e6, VENDOR_OMNIKEY= 0x076b, VENDOR_GEMPC = 0x08e6, + VENDER_VEGA = 0x0982, VENDOR_KAAN = 0x0d46, VENDOR_FSIJ = 0x234b, VENDOR_VASCO = 0x1a44 @@ -222,7 +223,8 @@ enum { #define SCM_SPR532 0xe003 #define CHERRY_ST2000 0x003e #define VASCO_920 0x0920 -#define GEMPC_PINPAD 0x3478 +#define GEMPC_PINPAD 0x3478 +#define VEGA_ALPHA 0x0008 /* A list and a table with special transport descriptions. */ enum { @@ -2382,7 +2384,7 @@ update_param_by_atr (unsigned char *param, unsigned char *atr, size_t atrlen) NEXTBYTE (); if (atr[i] == 0x3F) - param[1] |= 0x02; /* Convention is inverse. */ + param[1] |= 0x02; /* Convention is inverse. */ NEXTBYTE (); y = (atr[i] >> 4); @@ -2391,91 +2393,91 @@ update_param_by_atr (unsigned char *param, unsigned char *atr, size_t atrlen) if ((y & 1)) { - param[0] = atr[i]; /* TA1 - Fi & Di */ + param[0] = atr[i]; /* TA1 - Fi & Di */ NEXTBYTE (); } if ((y & 2)) - NEXTBYTE (); /* TB1 - ignore */ + NEXTBYTE (); /* TB1 - ignore */ if ((y & 4)) { - param[2] = atr[i]; /* TC1 - Guard Time */ + param[2] = atr[i]; /* TC1 - Guard Time */ NEXTBYTE (); } if ((y & 8)) { - y = (atr[i] >> 4); /* TD1 */ + y = (atr[i] >> 4); /* TD1 */ t = atr[i] & 0x0f; NEXTBYTE (); if ((y & 1)) - { /* TA2 - PPS mode */ - if ((atr[i] & 0x0f) != 1) - return -2; /* Wrong card protocol (!= 1). */ + { /* TA2 - PPS mode */ + if ((atr[i] & 0x0f) != 1) + return -2; /* Wrong card protocol (!= 1). */ - if ((atr[i] & 0x10) != 0x10) - return -3; /* Transmission parameters are implicitly defined. */ + if ((atr[i] & 0x10) != 0x10) + return -3; /* Transmission parameters are implicitly defined. */ - negotiable = 0; /* TA2 means specific mode. */ - NEXTBYTE (); - } + negotiable = 0; /* TA2 means specific mode. */ + NEXTBYTE (); + } if ((y & 2)) - NEXTBYTE (); /* TB2 - ignore */ + NEXTBYTE (); /* TB2 - ignore */ if ((y & 4)) - NEXTBYTE (); /* TC2 - ignore */ + NEXTBYTE (); /* TC2 - ignore */ if ((y & 8)) - { - y = (atr[i] >> 4); /* TD2 */ - t = atr[i] & 0x0f; - NEXTBYTE (); - } + { + y = (atr[i] >> 4); /* TD2 */ + t = atr[i] & 0x0f; + NEXTBYTE (); + } else - y = 0; + y = 0; while (y) - { - if ((y & 1)) - { /* TAx */ - if (t == 1) - param[5] = atr[i]; /* IFSC */ - else if (t == 15) - /* XXX: check voltage? */ - param[4] = (atr[i] >> 6); /* ClockStop */ - - NEXTBYTE (); - } - - if ((y & 2)) - { - if (t == 1) - param[3] = atr[i]; /* TBx - BWI & CWI */ - NEXTBYTE (); - } - - if ((y & 4)) - { - if (t == 1) - param[1] |= (atr[i] & 0x01); /* TCx - LRC/CRC */ - NEXTBYTE (); - - if (param[1] & 0x01) - return -4; /* CRC not supported yet. */ - } - - if ((y & 8)) - { - y = (atr[i] >> 4); /* TDx */ - t = atr[i] & 0x0f; - NEXTBYTE (); - } - else - y = 0; - } + { + if ((y & 1)) + { /* TAx */ + if (t == 1) + param[5] = atr[i]; /* IFSC */ + else if (t == 15) + /* XXX: check voltage? */ + param[4] = (atr[i] >> 6); /* ClockStop */ + + NEXTBYTE (); + } + + if ((y & 2)) + { + if (t == 1) + param[3] = atr[i]; /* TBx - BWI & CWI */ + NEXTBYTE (); + } + + if ((y & 4)) + { + if (t == 1) + param[1] |= (atr[i] & 0x01); /* TCx - LRC/CRC */ + NEXTBYTE (); + + if (param[1] & 0x01) + return -4; /* CRC not supported yet. */ + } + + if ((y & 8)) + { + y = (atr[i] >> 4); /* TDx */ + t = atr[i] & 0x0f; + NEXTBYTE (); + } + else + y = 0; + } } i += historical_bytes_num - 1; @@ -2604,16 +2606,16 @@ ccid_get_atr (ccid_driver_t handle, msglen = 10; rc = bulk_out (handle, msg, msglen, 0); if (!rc) - rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Parameters, - seqno, 2000, 0); + rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Parameters, + seqno, 2000, 0); if (rc) - DEBUGOUT ("GetParameters failed\n"); + DEBUGOUT ("GetParameters failed\n"); else if (msglen == 17 && msg[9] == 1) - got_param = 1; + got_param = 1; } else if (handle->auto_pps) ; - else if (rc == 1) /* It's negotiable, send PPS. */ + else if (rc == 1) /* It's negotiable, send PPS. */ { msg[0] = PC_to_RDR_XfrBlock; msg[5] = 0; /* slot */ @@ -2621,33 +2623,33 @@ ccid_get_atr (ccid_driver_t handle, msg[7] = 0; msg[8] = 0; msg[9] = 0; - msg[10] = 0xff; /* PPSS */ - msg[11] = 0x11; /* PPS0: PPS1, Protocol T=1 */ - msg[12] = param[0]; /* PPS1: Fi / Di */ + msg[10] = 0xff; /* PPSS */ + msg[11] = 0x11; /* PPS0: PPS1, Protocol T=1 */ + msg[12] = param[0]; /* PPS1: Fi / Di */ msg[13] = 0xff ^ 0x11 ^ param[0]; /* PCK */ set_msg_len (msg, 4); msglen = 10 + 4; rc = bulk_out (handle, msg, msglen, 0); if (rc) - return rc; + return rc; rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_DataBlock, - seqno, 5000, 0); + seqno, 5000, 0); if (rc) - return rc; + return rc; if (msglen != 10 + 4) - { - DEBUGOUT_1 ("Setting PPS failed: %d\n", msglen); - return CCID_DRIVER_ERR_CARD_IO_ERROR; - } + { + DEBUGOUT_1 ("Setting PPS failed: %d\n", msglen); + return CCID_DRIVER_ERR_CARD_IO_ERROR; + } if (msg[10] != 0xff || msg[11] != 0x11 || msg[12] != param[0]) - { - DEBUGOUT_1 ("Setting PPS failed: 0x%02x\n", param[0]); - return CCID_DRIVER_ERR_CARD_IO_ERROR; - } + { + DEBUGOUT_1 ("Setting PPS failed: 0x%02x\n", param[0]); + return CCID_DRIVER_ERR_CARD_IO_ERROR; + } } /* Setup parameters to select T=1. */ @@ -3298,7 +3300,7 @@ ccid_transceive (ccid_driver_t handle, int ccid_transceive_secure (ccid_driver_t handle, const unsigned char *apdu_buf, size_t apdu_buflen, - pininfo_t *pininfo, + pininfo_t *pininfo, unsigned char *resp, size_t maxresplen, size_t *nresp) { int rc; @@ -3360,16 +3362,17 @@ ccid_transceive_secure (ccid_driver_t handle, if (handle->id_product != CHERRY_ST2000) cherry_mode = 1; break; - case VENDOR_GEMPC: - if (handle->id_product == GEMPC_PINPAD) - { - enable_varlen = 0; - pininfo->minlen = 4; - pininfo->maxlen = 8; - break; - } - /* fall through */ default: + if ((handle->id_vendor == VENDOR_GEMPC && + handle->id_product == GEMPC_PINPAD) + || (handle->id_vendor == VENDOR_VEGA && + handle->id_product == VEGA_ALPHA)) + { + enable_varlen = 0; + pininfo->minlen = 4; + pininfo->maxlen = 8; + break; + } return CCID_DRIVER_ERR_NOT_SUPPORTED; } @@ -3412,8 +3415,8 @@ ccid_transceive_secure (ccid_driver_t handle, else { msg[13] = pininfo->fixedlen; /* bmPINBlockString: - 0 bits of pin length to insert. - PIN block size by fixedlen. */ + 0 bits of pin length to insert. + PIN block size by fixedlen. */ msg[14] = 0x00; /* bmPINLengthFormat: Units are bytes, position is 0. */ } @@ -3445,7 +3448,7 @@ ccid_transceive_secure (ccid_driver_t handle, msglen++; if (apdu_buf[1] == 0x20) - msg[msglen++] = 0xff; /* bNumberMessage: Default. */ + msg[msglen++] = 0x01; /* bNumberMessage. */ else msg[msglen++] = 0x03; /* bNumberMessage. */ ----------------------------------------------------------------------- Summary of changes: scd/ccid-driver.c | 189 +++++++++++++++++++++++++++-------------------------- 1 files changed, 96 insertions(+), 93 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 11 02:50:24 2013 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 11 Jan 2013 02:50:24 +0100 Subject: [git] GnuPG - branch, scd-work, updated. gnupg-2.1.0beta3-134-gf0584de Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, scd-work has been updated via f0584de7d4ea5e5ed71dfa8ac1a8623c236e4800 (commit) via d1db6bb510d9905d7830f4abdc364eae94fedab8 (commit) via f42f1404b91c730babf498181bab32881cff454d (commit) from 4ef0063efedf6c4e02f3e6b4e355810b400aae15 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f0584de7d4ea5e5ed71dfa8ac1a8623c236e4800 Author: NIIBE Yutaka Date: Fri Jan 11 10:41:38 2013 +0900 SCD: Defaults to use pinpad if the reader has the capability. * scd/app-openpgp.c (struct app_local_s): Remove VARLEN. (parse_login_data): "P=0" means to disable pinpad. (check_keypad_request): Default is to use pinpad if available. diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 1188770..9c85c61 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -195,7 +195,6 @@ struct app_local_s { struct { unsigned int specified:1; - unsigned int varlen:1; int fixedlen_user; int fixedlen_admin; } keypad; @@ -619,9 +618,8 @@ parse_login_data (app_t app) app->app_local->flags.no_sync = 0; app->app_local->flags.def_chv2 = 0; app->app_local->keypad.specified = 0; - app->app_local->keypad.varlen = 0; - app->app_local->keypad.fixedlen_user = 6; - app->app_local->keypad.fixedlen_admin = 8; + app->app_local->keypad.fixedlen_user = -1; + app->app_local->keypad.fixedlen_admin = -1; /* Read the DO. */ relptr = get_one_do (app, 0x005E, &buffer, &buflen, NULL); @@ -668,8 +666,8 @@ parse_login_data (app_t app) buflen--; if (buflen && !(*buffer == '\n' || *buffer == '\x18')) goto next; + /* Disable use of pinpad. */ app->app_local->keypad.specified = 1; - app->app_local->keypad.varlen = 1; } else if (digitp (buffer)) { @@ -1534,34 +1532,36 @@ do_readcert (app_t app, const char *certid, } -/* Decide if we use keypad of reader for PIN input according to the - user preference on the card. Returns 0 if we use keypad, 1 otherwise. */ +/* Decide if we use the keypad of the reader for PIN input according + to the user preference on the card, and the capability of the + reader. This routine is only called when the reader has keypad. + Returns 0 if we use keypad, 1 otherwise. */ static int check_keypad_request (app_t app, pininfo_t *pininfo, int admin_pin) { - /* User specifies no preference on card, then, use pinentry. */ - if (app->app_local->keypad.specified == 0) - return 1; - - if (app->app_local->keypad.varlen) - if (pininfo->fixedlen == 0) - return 0; + if (app->app_local->keypad.specified == 0) /* No preference on card. */ + if (pininfo->fixedlen == 0) /* Reader has varlen capability. */ + return 0; /* Then, use pinpad. */ else - /* On card, user specifies varlen but reader doesn't have the feature. */ + /* + * Reader has limited capability, and it may not match PIN of + * the card. + */ return 1; + + if (admin_pin) + pininfo->fixedlen = app->app_local->keypad.fixedlen_admin; else - { - if (admin_pin) - pininfo->fixedlen = app->app_local->keypad.fixedlen_admin; - else - pininfo->fixedlen = app->app_local->keypad.fixedlen_user; + pininfo->fixedlen = app->app_local->keypad.fixedlen_user; - if (pininfo->fixedlen < pininfo->minlen - || pininfo->fixedlen > pininfo->maxlen) - return 1; + if (pininfo->fixedlen < 0 /* User requests disable pinpad. */ + || pininfo->fixedlen < pininfo->minlen + || pininfo->fixedlen > pininfo->maxlen + /* Reader doesn't have the capability to input a PIN which + * length is FIXEDLEN. */) + return 1; - return 0; - } + return 0; } commit d1db6bb510d9905d7830f4abdc364eae94fedab8 Author: NIIBE Yutaka Date: Thu Jan 10 15:58:43 2013 +0900 SCD: handle keypad request on the card. * scd/app-openpgp.c: Add 2013. (struct app_local_s): Add keypad structure. (parse_login_data): Add parsing keypad request on the card. (check_keypad_request): New. (verify_a_chv, verify_chv3, do_change_pin): Call check_keypad_request to determine use of keypad. diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index dcc3120..1188770 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1,6 +1,6 @@ /* app-openpgp.c - The OpenPGP card application. * Copyright (C) 2003, 2004, 2005, 2007, 2008, - * 2009 Free Software Foundation, Inc. + * 2009, 2013 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -191,6 +191,15 @@ struct app_local_s { unsigned int def_chv2:1; /* Use 123456 for CHV2. */ } flags; + /* Keypad request specified on card. */ + struct + { + unsigned int specified:1; + unsigned int varlen:1; + int fixedlen_user; + int fixedlen_admin; + } keypad; + struct { unsigned int n_bits; /* Size of the modulus in bits. The rest @@ -581,17 +590,23 @@ count_bits (const unsigned char *a, size_t len) Everything up to a LF is considered a mailbox or account name. If the first LF is followed by DC4 (0x14) control sequence are expected up to the next LF. Control sequences are separated by FS - (0x18) and consist of key=value pairs. There is one key defined: + (0x18) and consist of key=value pairs. There are two keys defined: F= - Were FLAGS is a plain hexadecimal number representing flag values. + Where FLAGS is a plain hexadecimal number representing flag values. The lsb is here the rightmost bit. Defined flags bits are: Bit 0 = CHV1 and CHV2 are not syncronized Bit 1 = CHV2 has been been set to the default PIN of "123456" (this implies that bit 0 is also set). + P= + + Where KEYPAD_REQUEST is 0 or a pair of two integers: ,. + 0 means use keypad with variable length input. , means use + keypad with fixed length input. N for user PIN, M for admin PIN. + */ static void parse_login_data (app_t app) @@ -603,6 +618,10 @@ parse_login_data (app_t app) /* Set defaults. */ app->app_local->flags.no_sync = 0; app->app_local->flags.def_chv2 = 0; + app->app_local->keypad.specified = 0; + app->app_local->keypad.varlen = 0; + app->app_local->keypad.fixedlen_user = 6; + app->app_local->keypad.fixedlen_admin = 8; /* Read the DO. */ relptr = get_one_do (app, 0x005E, &buffer, &buflen, NULL); @@ -628,11 +647,56 @@ parse_login_data (app_t app) any leading digits but bail out on invalid characters. */ for (p=buffer+2, len = buflen-2; len && hexdigitp (p); p++, len--) lastdig = xtoi_1 (p); + buffer = p; + buflen = len; if (len && !(*p == '\n' || *p == '\x18')) goto next; /* Invalid characters in field. */ app->app_local->flags.no_sync = !!(lastdig & 1); app->app_local->flags.def_chv2 = (lastdig & 3) == 3; } + else if (buflen > 1 && *buffer == 'P' && buffer[1] == '=') + { + /* Keypad request control sequence found. */ + buffer += 2; + buflen -= 2; + + if (buflen) + { + if (*buffer == '0') + { + buffer++; + buflen--; + if (buflen && !(*buffer == '\n' || *buffer == '\x18')) + goto next; + app->app_local->keypad.specified = 1; + app->app_local->keypad.varlen = 1; + } + else if (digitp (buffer)) + { + char *q; + int n, m; + + n = strtol (buffer, &q, 10); + if (*q++ != ',' || !digitp (q)) + goto next; + m = strtol (q, &q, 10); + buffer = q; + if (buflen < ((unsigned char *)q - buffer)) + { + buflen = 0; + break; + } + else + buflen -= ((unsigned char *)q - buffer); + + if (buflen && !(*buffer == '\n' || *buffer == '\x18')) + goto next; + app->app_local->keypad.specified = 1; + app->app_local->keypad.fixedlen_user = n; + app->app_local->keypad.fixedlen_admin = m; + } + } + } next: for (; buflen && *buffer != '\x18'; buflen--, buffer++) if (*buffer == '\n') @@ -1470,6 +1534,37 @@ do_readcert (app_t app, const char *certid, } +/* Decide if we use keypad of reader for PIN input according to the + user preference on the card. Returns 0 if we use keypad, 1 otherwise. */ +static int +check_keypad_request (app_t app, pininfo_t *pininfo, int admin_pin) +{ + /* User specifies no preference on card, then, use pinentry. */ + if (app->app_local->keypad.specified == 0) + return 1; + + if (app->app_local->keypad.varlen) + if (pininfo->fixedlen == 0) + return 0; + else + /* On card, user specifies varlen but reader doesn't have the feature. */ + return 1; + else + { + if (admin_pin) + pininfo->fixedlen = app->app_local->keypad.fixedlen_admin; + else + pininfo->fixedlen = app->app_local->keypad.fixedlen_user; + + if (pininfo->fixedlen < pininfo->minlen + || pininfo->fixedlen > pininfo->maxlen) + return 1; + + return 0; + } +} + + /* Verify a CHV either using using the pinentry or if possibile by using a keypad. PINCB and PINCB_ARG describe the usual callback for the pinentry. CHVNO must be either 1 or 2. SIGCOUNT is only @@ -1537,7 +1632,8 @@ verify_a_chv (app_t app, if (!opt.disable_keypad - && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) ) + && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) + && !check_keypad_request (app, &pininfo, 0)) { /* The reader supports the verify command through the keypad. Note that the pincb appends a text to the prompt telling the @@ -1720,7 +1816,8 @@ verify_chv3 (app_t app, return rc; if (!opt.disable_keypad - && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) ) + && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) + && !check_keypad_request (app, &pininfo, 1)) { /* The reader supports the verify command through the keypad. */ rc = pincb (pincb_arg, prompt, NULL); @@ -1970,7 +2067,8 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, if (!opt.disable_keypad && !iso7816_check_keypad (app->slot, - ISO7816_CHANGE_REFERENCE_DATA, &pininfo)) + ISO7816_CHANGE_REFERENCE_DATA, &pininfo) + && !check_keypad_request (app, &pininfo, chvno == 3)) use_keypad = 1; if (reset_mode) commit f42f1404b91c730babf498181bab32881cff454d Author: NIIBE Yutaka Date: Thu Jan 10 15:52:24 2013 +0900 SCD: Minor fix of ccid-driver. * scd/ccid-driver.c (VENDOR_VEGA): Fix typo. diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 95e85d9..e9f39f4 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -209,7 +209,7 @@ enum { VENDOR_SCM = 0x04e6, VENDOR_OMNIKEY= 0x076b, VENDOR_GEMPC = 0x08e6, - VENDER_VEGA = 0x0982, + VENDOR_VEGA = 0x0982, VENDOR_KAAN = 0x0d46, VENDOR_FSIJ = 0x234b, VENDOR_VASCO = 0x1a44 ----------------------------------------------------------------------- Summary of changes: scd/app-openpgp.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++--- scd/ccid-driver.c | 2 +- 2 files changed, 105 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 11 06:25:42 2013 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 11 Jan 2013 06:25:42 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-126-g4dddf32 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 4dddf32c83f52483d95d7770232e9e808558e702 (commit) from a776f660363d20b6cc023609c4547e0aa8825d97 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: scd/apdu.c | 33 ++++++++++++++++++++++++++++++--- 1 files changed, 30 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 11 06:25:44 2013 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 11 Jan 2013 06:25:44 +0100 Subject: [git] GnuPG - branch, scd-work, updated. gnupg-2.1.0beta3-137-gaba76f9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, scd-work has been updated via aba76f91cbfe0f758e3cb61484ac5a7318cc31d6 (commit) via ff4f9ea82f045b27ccdf36564bc8a9a83641dcb2 (commit) via 4dddf32c83f52483d95d7770232e9e808558e702 (commit) from f0584de7d4ea5e5ed71dfa8ac1a8623c236e4800 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit aba76f91cbfe0f758e3cb61484ac5a7318cc31d6 Author: NIIBE Yutaka Date: Fri Jan 11 13:19:17 2013 +0900 SCD: Better interoperability. * scd/apdu.c: Fill bTeoPrologue[2] field. -- ccid-1.4.5 or older requires this field is filled by application. diff --git a/scd/apdu.c b/scd/apdu.c index f78463a..c9d24ee 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -2084,7 +2084,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, pin_verify[11] = 0x00; /* bMsgIndex */ pin_verify[12] = 0x00; /* bTeoPrologue[0] */ pin_verify[13] = 0x00; /* bTeoPrologue[1] */ - pin_verify[14] = 0x00; /* bTeoPrologue[2] */ + pin_verify[14] = pininfo->fixedlen + 0x05; /* bTeoPrologue[2] */ pin_verify[15] = pininfo->fixedlen + 0x05; /* ulDataLength */ pin_verify[16] = 0x00; /* ulDataLength */ pin_verify[17] = 0x00; /* ulDataLength */ @@ -2178,7 +2178,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, pin_modify[16] = 0x00; /* bMsgIndex3 */ pin_modify[17] = 0x00; /* bTeoPrologue[0] */ pin_modify[18] = 0x00; /* bTeoPrologue[1] */ - pin_modify[19] = 0x00; /* bTeoPrologue[2] */ + pin_modify[19] = 2 * pininfo->fixedlen + 0x05; /* bTeoPrologue[2] */ pin_modify[20] = 2 * pininfo->fixedlen + 0x05; /* ulDataLength */ pin_modify[21] = 0x00; /* ulDataLength */ pin_modify[22] = 0x00; /* ulDataLength */ commit ff4f9ea82f045b27ccdf36564bc8a9a83641dcb2 Merge: f0584de 4dddf32 Author: NIIBE Yutaka Date: Fri Jan 11 11:26:16 2013 +0900 Merge branch 'scd-serialize-bugfix' into scd-work Conflicts: scd/apdu.c diff --cc scd/apdu.c index 4c73283,278e08a..f78463a --- a/scd/apdu.c +++ b/scd/apdu.c @@@ -3400,11 -3428,19 +3400,20 @@@ apdu_check_keypad (int slot, int comman if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; + if (opt.enable_keypad_varlen) + pininfo->fixedlen = 0; + if (reader_table[slot].check_keypad) - return reader_table[slot].check_keypad (slot, command, pininfo); + { + int sw; + + if ((sw = lock_slot (slot))) + return sw; + - sw = reader_table[slot].check_keypad (slot, command, - pin_mode, pinlen_min, pinlen_max, - pin_padlen); ++ sw = reader_table[slot].check_keypad (slot, command, pininfo); + unlock_slot (slot); + return sw; + } else return SW_HOST_NOT_SUPPORTED; } @@@ -3418,8 -3461,17 +3427,17 @@@ apdu_keypad_verify (int slot, int class return SW_HOST_NO_DRIVER; if (reader_table[slot].keypad_verify) - return reader_table[slot].keypad_verify (slot, class, ins, p0, p1, - pininfo); + { + int sw; + + if ((sw = lock_slot (slot))) + return sw; + + sw = reader_table[slot].keypad_verify (slot, class, ins, p0, p1, - &pininfo); ++ pininfo); + unlock_slot (slot); + return sw; + } else return SW_HOST_NOT_SUPPORTED; } @@@ -3433,8 -3492,17 +3451,17 @@@ apdu_keypad_modify (int slot, int class return SW_HOST_NO_DRIVER; if (reader_table[slot].keypad_modify) - return reader_table[slot].keypad_modify (slot, class, ins, p0, p1, + { + int sw; + + if ((sw = lock_slot (slot))) + return sw; + + sw = reader_table[slot].keypad_modify (slot, class, ins, p0, p1, - &pininfo); + pininfo); + unlock_slot (slot); + return sw; + } else return SW_HOST_NOT_SUPPORTED; } ----------------------------------------------------------------------- Summary of changes: scd/apdu.c | 39 +++++++++++++++++++++++++++++++++------ 1 files changed, 33 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 11 13:43:54 2013 From: cvs at cvs.gnupg.org (by Christian Aistleitner) Date: Fri, 11 Jan 2013 13:43:54 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.13-2-gff5cfad Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via ff5cfadc2c402ebc3884ad2575bc5a51f0067f56 (commit) from faf217497902e6176c64e6db0191f35ccef97c57 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ff5cfadc2c402ebc3884ad2575bc5a51f0067f56 Author: Christian Aistleitner Date: Sun Oct 14 20:33:00 2012 +0200 Fix honoring --cert-digest-algo when recreating a cert * g10/sign.c (update_keysig_packet): Override original signature's digest algo in hashed data. diff --git a/g10/sign.c b/g10/sign.c index 6788f74..6587a60 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1514,6 +1514,7 @@ update_keysig_packet( PKT_signature **ret_sig, /* create a new signature packet */ sig = copy_signature (NULL, orig_sig); + sig->digest_algo = digest_algo; /* We need to create a new timestamp so that new sig expiration calculations are done correctly... */ ----------------------------------------------------------------------- Summary of changes: g10/sign.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 11 13:56:56 2013 From: cvs at cvs.gnupg.org (by Christian Aistleitner) Date: Fri, 11 Jan 2013 13:56:56 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-128-g60c5876 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 60c58766aeb847b769372fa981f79abac6014500 (commit) via 7a638c094fa1aa7ed1d9caf085af9980a2664d64 (commit) from 4dddf32c83f52483d95d7770232e9e808558e702 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 60c58766aeb847b769372fa981f79abac6014500 Author: Christian Aistleitner Date: Sun Oct 14 20:30:20 2012 +0200 gpg: Fix honoring --cert-digest-algo when recreating a cert * g10/sign.c (update_keysig_packet): Override original signature's digest algo in hashed data and for hash computation. diff --git a/g10/sign.c b/g10/sign.c index 6ff7df6..501f1ff 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1604,6 +1604,8 @@ update_keysig_packet( PKT_signature **ret_sig, /* create a new signature packet */ sig = copy_signature (NULL, orig_sig); + sig->digest_algo=digest_algo; + /* We need to create a new timestamp so that new sig expiration calculations are done correctly... */ sig->timestamp=make_timestamp(); commit 7a638c094fa1aa7ed1d9caf085af9980a2664d64 Author: Werner Koch Date: Mon Jan 7 09:58:35 2013 +0100 Fix spurious cruft from configure summary output. * configure.ac (build_scdaemon_extra): Remove $tmp cruft. diff --git a/configure.ac b/configure.ac index db51121..5881df1 100644 --- a/configure.ac +++ b/configure.ac @@ -1519,7 +1519,7 @@ fi build_scdaemon_extra="" if test "$build_scdaemon" = "yes"; then if test $have_libusb = no; then - build_scdaemon_extra="${tmp}without internal CCID driver" + build_scdaemon_extra="without internal CCID driver" fi if test -n "$build_scdaemon_extra"; then build_scdaemon_extra="(${build_scdaemon_extra})" ----------------------------------------------------------------------- Summary of changes: configure.ac | 2 +- g10/sign.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 11 13:58:58 2013 From: cvs at cvs.gnupg.org (by Christian Aistleitner) Date: Fri, 11 Jan 2013 13:58:58 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-67-g3cfe527 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-0 has been updated via 3cfe527fa57167d0477c0f6250ca28e8f4dd1b0e (commit) from 00c908263206f65a59a4f3e525d716888be132b9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3cfe527fa57167d0477c0f6250ca28e8f4dd1b0e Author: Christian Aistleitner Date: Sun Oct 14 20:31:41 2012 +0200 gpg: Fix honoring --cert-digest-algo when recreating a cert * g10/sign.c (update_keysig_packet): Override original signature's digest algo in hashed data and for hash computation. diff --git a/g10/sign.c b/g10/sign.c index 6cccfed..91f7f84 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1532,6 +1532,8 @@ update_keysig_packet( PKT_signature **ret_sig, /* create a new signature packet */ sig = copy_signature (NULL, orig_sig); + sig->digest_algo=digest_algo; + /* We need to create a new timestamp so that new sig expiration calculations are done correctly... */ sig->timestamp=make_timestamp(); ----------------------------------------------------------------------- Summary of changes: g10/sign.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 11 15:44:33 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 11 Jan 2013 15:44:33 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.13-3-g37f1a42 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via 37f1a427440b9bb4374bf7d878f17190df75918b (commit) from ff5cfadc2c402ebc3884ad2575bc5a51f0067f56 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 37f1a427440b9bb4374bf7d878f17190df75918b Author: Werner Koch Date: Fri Jan 11 15:10:38 2013 +0100 Fix idea.c for big endian CPUs. * cipher/idea.c: Replace use of WORDS_BIGENDIAN by BIG_ENDIAN_HOST. -- GnuPG-bug-id: 1461 diff --git a/cipher/idea.c b/cipher/idea.c index 8cda764..a2d8dfe 100644 --- a/cipher/idea.c +++ b/cipher/idea.c @@ -178,7 +178,7 @@ cipher( byte *outbuf, const byte *inbuf, u16 *key ) u16 x1, x2, x3,x4, s2, s3; u16 *in, *out; int r = IDEA_ROUNDS; - #define MUL(x,y) \ +#define MUL(x,y) \ do {u16 _t16; u32 _t32; \ if( (_t16 = (y)) ) { \ if( (x = (x)&0xffff) ) { \ @@ -201,12 +201,12 @@ cipher( byte *outbuf, const byte *inbuf, u16 *key ) x2 = *in++; x3 = *in++; x4 = *in; - #ifndef WORDS_BIGENDIAN +#ifndef BIG_ENDIAN_HOST x1 = (x1>>8) | (x1<<8); x2 = (x2>>8) | (x2<<8); x3 = (x3>>8) | (x3<<8); x4 = (x4>>8) | (x4<<8); - #endif +#endif do { MUL(x1, *key++); x2 += *key++; @@ -234,18 +234,18 @@ cipher( byte *outbuf, const byte *inbuf, u16 *key ) MUL(x4, *key); out = (u16*)outbuf; - #ifndef WORDS_BIGENDIAN +#ifndef BIG_ENDIAN_HOST *out++ = (x1>>8) | (x1<<8); *out++ = (x3>>8) | (x3<<8); *out++ = (x2>>8) | (x2<<8); *out = (x4>>8) | (x4<<8); - #else +#else *out++ = x1; *out++ = x3; *out++ = x2; *out = x4; - #endif - #undef MUL +#endif +#undef MUL } ----------------------------------------------------------------------- Summary of changes: cipher/idea.c | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 11 15:50:59 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 11 Jan 2013 15:50:59 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.13-4-gb4d4acf Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via b4d4acf491105687c98178b6f4efed2ca9bdc98f (commit) from 37f1a427440b9bb4374bf7d878f17190df75918b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b4d4acf491105687c98178b6f4efed2ca9bdc98f Author: Werner Koch Date: Fri Jan 11 15:42:32 2013 +0100 Automake 1.13 compatibility fix. * configure.ac: s/AM_CONFIG_HEADER/AC_CONFIG_HEADERS/. -- GnuPG-bug-id: 1459 diff --git a/configure.ac b/configure.ac index c23cab2..87bd18f 100644 --- a/configure.ac +++ b/configure.ac @@ -46,7 +46,7 @@ AC_CONFIG_SRCDIR(g10/gpg.c) AC_CANONICAL_HOST AM_INIT_AUTOMAKE([std-options]) AB_INIT -AM_CONFIG_HEADER(config.h) +AC_CONFIG_HEADERS(config.h) AC_GNU_SOURCE ----------------------------------------------------------------------- Summary of changes: configure.ac | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Sat Jan 12 17:47:15 2013 From: cvs at cvs.gnupg.org (by Ben Kibbey) Date: Sat, 12 Jan 2013 17:47:15 +0100 Subject: [git] Pinentry - branch, master, updated. pinentry-0.8.2-2-gd33537a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The standard pinentry collection". The branch, master has been updated via d33537aef0358313cbcf1d010b227d93f3430900 (commit) from 1ff0a843c4b418b88ccd6665a469d7ebfdd23cd1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d33537aef0358313cbcf1d010b227d93f3430900 Author: Ben Kibbey Date: Sat Jan 5 18:27:11 2013 -0500 Fix initializing the timeout timer. When timeout == 0 a segfault would occur. diff --git a/qt4/pinentrydialog.cpp b/qt4/pinentrydialog.cpp index 95096d4..a8dbb42 100644 --- a/qt4/pinentrydialog.cpp +++ b/qt4/pinentrydialog.cpp @@ -147,12 +147,14 @@ PinEntryDialog::PinEntryDialog( QWidget* parent, const char* name, _ok->setIcon( style()->standardIcon( QStyle::SP_DialogOkButton ) ); _cancel->setIcon( style()->standardIcon( QStyle::SP_DialogCancelButton ) ); } - + if (timeout > 0) { _timer = new QTimer(this); connect(_timer, SIGNAL(timeout()), this, SLOT(slotTimeout())); _timer->start(timeout*1000); } + else + _timer = NULL; connect( buttons, SIGNAL(accepted()), this, SLOT(accept()) ); connect( buttons, SIGNAL(rejected()), this, SLOT(reject()) ); @@ -268,7 +270,9 @@ void PinEntryDialog::updateQuality(const secqstring & txt ) int percent; QPalette pal; - _timer->stop(); + if (_timer) + _timer->stop(); + if (!_have_quality_bar || !_pinentry_info) return; secstring pinStr = toUtf8(txt); ----------------------------------------------------------------------- Summary of changes: qt4/pinentrydialog.cpp | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) hooks/post-receive -- The standard pinentry collection http://git.gnupg.org From cvs at cvs.gnupg.org Sun Jan 13 04:20:52 2013 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Sun, 13 Jan 2013 04:20:52 +0100 Subject: [git] GnuPG - branch, scd-work, updated. gnupg-2.1.0beta3-138-g675ddb4 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, scd-work has been updated via 675ddb4e53057d4d5cd94ebe4521dce6fcdb52be (commit) from aba76f91cbfe0f758e3cb61484ac5a7318cc31d6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 675ddb4e53057d4d5cd94ebe4521dce6fcdb52be Author: NIIBE Yutaka Date: Sun Jan 13 12:12:10 2013 +0900 SCD: Support P=N format for login data. * scd/app-openpgp.c (parse_login_data): Support P=N format. diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 9c85c61..dc35295 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -602,9 +602,9 @@ count_bits (const unsigned char *a, size_t len) P= - Where KEYPAD_REQUEST is 0 or a pair of two integers: ,. - 0 means use keypad with variable length input. , means use - keypad with fixed length input. N for user PIN, M for admin PIN. + Where KEYPAD_REQUEST is in the format of: or ,. + N for user PIN, M for admin PIN. If M is missing it means M=N. + 0 means to force not to use keypad. */ static void @@ -660,24 +660,22 @@ parse_login_data (app_t app) if (buflen) { - if (*buffer == '0') - { - buffer++; - buflen--; - if (buflen && !(*buffer == '\n' || *buffer == '\x18')) - goto next; - /* Disable use of pinpad. */ - app->app_local->keypad.specified = 1; - } - else if (digitp (buffer)) + if (digitp (buffer)) { char *q; int n, m; n = strtol (buffer, &q, 10); - if (*q++ != ',' || !digitp (q)) - goto next; - m = strtol (q, &q, 10); + if (q >= (char *)buffer + buflen + || *q == '\x18' || *q == '\n') + m = n; + else + { + if (*q++ != ',' || !digitp (q)) + goto next; + m = strtol (q, &q, 10); + } + buffer = q; if (buflen < ((unsigned char *)q - buffer)) { @@ -1540,14 +1538,16 @@ static int check_keypad_request (app_t app, pininfo_t *pininfo, int admin_pin) { if (app->app_local->keypad.specified == 0) /* No preference on card. */ - if (pininfo->fixedlen == 0) /* Reader has varlen capability. */ - return 0; /* Then, use pinpad. */ - else - /* - * Reader has limited capability, and it may not match PIN of - * the card. - */ - return 1; + { + if (pininfo->fixedlen == 0) /* Reader has varlen capability. */ + return 0; /* Then, use pinpad. */ + else + /* + * Reader has limited capability, and it may not match PIN of + * the card. + */ + return 1; + } if (admin_pin) pininfo->fixedlen = app->app_local->keypad.fixedlen_admin; ----------------------------------------------------------------------- Summary of changes: scd/app-openpgp.c | 48 ++++++++++++++++++++++++------------------------ 1 files changed, 24 insertions(+), 24 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Jan 25 15:28:11 2013 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 25 Jan 2013 15:28:11 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-129-g1999446 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 19994466449a93704d38d429ca1ea36f63da0bf0 (commit) from 60c58766aeb847b769372fa981f79abac6014500 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 19994466449a93704d38d429ca1ea36f63da0bf0 Author: NIIBE Yutaka Date: Fri Jan 25 14:17:29 2013 +0900 agent: Fix a bug of handling return code from npth_join. * agent/call-pinentry.c (agent_popup_message_stop): Fix npth_join return code. -- pth_join returns TRUE (1) on success. But npth_join (and pthread_join) returns 0 on success, returns error number on error. diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index c37831a..c6b6b52 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -1266,9 +1266,9 @@ agent_popup_message_stop (ctrl_t ctrl) /* Now wait for the thread to terminate. */ rc = npth_join (popup_tid, NULL); - if (!rc) + if (rc) log_debug ("agent_popup_message_stop: pth_join failed: %s\n", - strerror (errno)); + strerror (rc)); /* Thread IDs are opaque, but we try our best here by resetting it to the same content that a static global variable has. */ memset (&popup_tid, '\0', sizeof (popup_tid)); ----------------------------------------------------------------------- Summary of changes: agent/call-pinentry.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Jan 28 04:40:48 2013 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 28 Jan 2013 04:40:48 +0100 Subject: [git] GnuPG - branch, scd-work, updated. gnupg-2.1.0beta3-139-gc5f73c3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, scd-work has been updated via c5f73c39b509e12dd6d481b471d422ad10de7d58 (commit) from 675ddb4e53057d4d5cd94ebe4521dce6fcdb52be (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c5f73c39b509e12dd6d481b471d422ad10de7d58 Author: NIIBE Yutaka Date: Mon Jan 28 11:46:40 2013 +0900 SCD: Add vendor specific initalization. * scd/ccid-driver.c (ccid_vendor_specific_init): New. (ccid_open_reader): Call ccid_vendor_specific_init. diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index e9f39f4..6d6c3db 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -303,6 +303,9 @@ static int bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, size_t *nread, int expected_type, int seqno, int timeout, int no_debug); static int abort_cmd (ccid_driver_t handle, int seqno); +static int send_escape_cmd (ccid_driver_t handle, const unsigned char *data, + size_t datalen, unsigned char *result, + size_t resultmax, size_t *resultlen); /* Convert a little endian stored 4 byte value into an unsigned integer. */ @@ -1525,6 +1528,29 @@ ccid_get_reader_list (void) } +/* Vendor specific custom initialization. */ +static int +ccid_vendor_specific_init (ccid_driver_t handle) +{ + if (handle->id_vendor == VENDOR_VEGA && handle->id_product == VEGA_ALPHA) + { + /* + * Vega alpha has a feature to show retry counter on the pinpad + * display. But it assumes that the card returns the value of + * retry counter by VERIFY with empty data (return code of + * 63Cx). Unfortunately, existing OpenPGP cards don't support + * VERIFY command with empty data. This vendor specific command + * sequence is to disable the feature. + */ + const unsigned char cmd[] = "\xb5\x01\x00\x03\x00"; + + return send_escape_cmd (handle, cmd, sizeof (cmd), NULL, 0, NULL); + } + + return 0; +} + + /* Open the reader with the internal number READERNO and return a pointer to be used as handle in HANDLE. Returns 0 on success. */ int @@ -1633,6 +1659,8 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid) } } + rc = ccid_vendor_specific_init (*handle); + leave: free (ifcdesc_extra); if (rc) ----------------------------------------------------------------------- Summary of changes: scd/ccid-driver.c | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 30 02:39:02 2013 From: cvs at cvs.gnupg.org (by David Shaw) Date: Wed, 30 Jan 2013 02:39:02 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.13-5-g1edc1b3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via 1edc1b3751496885b236f5ab1194ad667c96b174 (commit) from b4d4acf491105687c98178b6f4efed2ca9bdc98f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1edc1b3751496885b236f5ab1194ad667c96b174 Author: David Shaw Date: Tue Jan 29 20:31:01 2013 -0500 Fix DNS check for recent OS X releases * configure.ac: OS X now needs BIND_8_COMPAT and -lresolv diff --git a/configure.ac b/configure.ac index 87bd18f..bbf6e65 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # configure.ac script for GnuPG # Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, -# 2008, 2009, 2010, 2012 Free Software Foundation, Inc. +# 2008, 2009, 2010, 2012, 2013 Free Software Foundation, Inc. # # This file is part of GnuPG. # @@ -722,7 +722,8 @@ if test x"$use_dns_pka" = xyes || test x"$use_dns_srv" = xyes || test x"$use_dns # define in bind 8 for some reason. if test x"$have_resolver" != xyes ; then - AC_MSG_CHECKING([whether I can make the resolver usable with BIND_8_COMPAT]) + AC_MSG_CHECKING([whether I can make the resolver usable with BIND_8_COMPAT and libresolv]) + LIBS="$LIBS -lresolv" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define BIND_8_COMPAT #include #include ----------------------------------------------------------------------- Summary of changes: configure.ac | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Jan 30 19:05:46 2013 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 30 Jan 2013 19:05:46 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-132-g65eb989 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 65eb98966a569a91c97d0c23ba5582a9a7558de0 (commit) via 50a7badbdacac8ba472b35090c1aab4568434d04 (commit) via 1cd6445eec4c3642ad92afb02f3563a01cc10c10 (commit) from 19994466449a93704d38d429ca1ea36f63da0bf0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 65eb98966a569a91c97d0c23ba5582a9a7558de0 Author: Werner Koch Date: Wed Jan 30 18:54:23 2013 +0100 Convert doc/DETAILS to org-mode -- Also restructure the file and fix some obviously wrong things. diff --git a/doc/DETAILS b/doc/DETAILS index 8b20c21..6d30efe 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -1,11 +1,26 @@ - -*- text -*- -Format of colon listings -======================== -First an example: - +# doc/DETAILS -*- org -*- +#+TITLE: GnuPG Details +# Globally disable superscripts and subscripts: +#+OPTIONS: ^:{} +# + +# Note: This file uses org-mode; it should be easy to read as plain +# text but be aware of some markup peculiarities: Verbatim code is +# enclosed in #+begin-example, #+end-example blocks or marked by a +# colon as the first non-white-space character, words bracketed with +# equal signs indicate a monospace font, and the usual /italics/, +# *bold*, and _underline_ conventions are recognized. + +This is the DETAILS file for GnuPG which specifies some internals and +parts of the external API for GPG and GPGSM. + +* Format of the colon listings + The format is a based on colon separated record, each recods starts + with a tag string and extends to the end of the line. Here is an + example: +#+begin_example $ gpg --with-colons --list-keys \ --with-fingerprint --with-fingerprint wk at gnupg.org - pub:f:1024:17:6C7EE1B8621CC013:899817715:1055898235::m:::scESC: fpr:::::::::ECAF7590EB3443B5C7CF3ACB6C7EE1B8621CC013: uid:f::::::::Werner Koch : @@ -14,810 +29,884 @@ sub:f:1536:16:06AD222CADF6A6E1:919537416:1036177416:::::e: fpr:::::::::CF8BCC4B18DE08FCD8A1615906AD222CADF6A6E1: sub:r:1536:20:5CE086B5B5A18FF4:899817788:1025961788:::::esc: fpr:::::::::AB059359A3B81F410FCFF97F5CE086B5B5A18FF4: +#+end_example + +The double =--with-fingerprint= prints the fingerprint for the subkeys +too. Old versions of gpg used a lighly different format and required +the use of the option =--fixed-list-mode= to conform to format +described here. + +** Description of the fields +*** Field 1 - Type of record + + - pub :: Public key + - crt :: X.509 certificate + - crs :: X.509 certificate and private key available + - sub :: Subkey (secondary key) + - sec :: Secret key + - ssb :: Secret subkey (secondary key) + - uid :: User id (only field 10 is used). + - uat :: User attribute (same as user id except for field 10). + - sig :: Signature + - rev :: Revocation signature + - fpr :: Fingerprint (fingerprint is in field 10) + - pkd :: Public key data [*] + - grp :: Keygrip + - rvk :: Revocation key + - tru :: Trust database information [*] + - spk :: Signature subpacket [*] + - cfg :: Configuration data [*] + + Records marked with an asterisk are described at [[*Special%20field%20formats][*Special fields]]. + +*** Field 2 - Validity + + This is a letter describing the computed validity of a key. + Currently this is a single letter, but be prepared that additional + information may follow in some future versions. Note that GnuPG < + 2.1 does not set this field for secret key listings. + + - o :: Unknown (this key is new to the system) + - i :: The key is invalid (e.g. due to a missing self-signature) + - d :: The key has been disabled + (deprecated - use the 'D' in field 12 instead) + - r :: The key has been revoked + - e :: The key has expired + - - :: Unknown validity (i.e. no value assigned) + - q :: Undefined validity. '-' and 'q' may safely be treated as + the same value for most purposes + - n :: The key is not valid + - m :: The key is marginal valid. + - f :: The key is fully valid + - u :: The key is ultimately valid. This often means that the + secret key is available, but any key may be marked as + ultimately valid. + - w :: The key has a well known private part. + - s :: The key has special validity. This means that it might be + self-signed and expected to be used in the STEED sytem. + + If the validity information is given for a UID or UAT record, it + describes the validity calculated based on this user ID. If given + for a key record it describes the validity taken from the best + rated user ID. + + For X.509 certificates a 'u' is used for a trusted root + certificate (i.e. for the trust anchor) and an 'f' for all other + valid certificates. + +*** Field 3 - Key length + + The length of key in bits. + +*** Field 4 - Public key algorithm + + The values here are those from the OpenPGP specs or if they are + greather than 255 the algorithm ids as used by Libgcrypt. + +*** Field 5 - KeyID + + This is the 64 bit keyid as specified by OpenPGP and the last 64 + bit of the SHA-1 fingerprint of an X.509 certifciate. + +*** Field 6 - Creation date + + The creation date of the key is given in UTC. For UID and UAT + records, this is used for the self-signature date. Note that the + date is usally printed in seconds since epoch, however, we are + migrating to an ISO 8601 format (e.g. "19660205T091500"). This is + currently only relevant for X.509. A simple way to detect the new + format is to scan for the 'T'. Note that old versions of gpg + without using the =--fixed-list-mode= option used a "yyyy-mm-tt" + format. + +*** Field 7 - Expiration date + + Key or UID/UAT expiration date or empty if it does not expire. + +*** Field 8 - Certificate S/N, UID hash, trust signature info + + Used for serial number in crt records. For UID and UAT records, + this is a hash of the user ID contents used to represent that + exact user ID. For trust signatures, this is the trust depth + seperated by the trust value by a space. + +*** Field 9 - Ownertrust + + This is only used on primary keys. This is a single letter, but + be prepared that additional information may follow in future + versions. For trust signatures with a regular expression, this is + the regular expression value, quoted as in field 10. + +*** Field 10 - User-ID + The value is quoted like a C string to avoid control characters + (the colon is quoted =\x3a=). For a "pub" record this field is + not used on --fixed-list-mode. A UAT record puts the attribute + subpacket count here, a space, and then the total attribute + subpacket size. In gpgsm the issuer name comes here. A FPR + record stores the fingerprint here. The fingerprint of a + revocation key is stored here. +*** Field 11 - Signature class + + Signature class as per RFC-4880. This is a 2 digit hexnumber + followed by either the letter 'x' for an exportable signature or + the letter 'l' for a local-only signature. The class byte of an + revocation key is also given here, 'x' and 'l' is used the same + way. This field if not used for X.509. -The double --with-fingerprint prints the fingerprint for the subkeys -too. --fixed-list-mode is the modern listing way printing dates in -seconds since Epoch and does not merge the first userID with the pub -record; gpg2 does this by default and the option is a dummy. - - - 1. Field: Type of record - pub = public key - crt = X.509 certificate - crs = X.509 certificate and private key available - sub = subkey (secondary key) - sec = secret key - ssb = secret subkey (secondary key) - uid = user id (only field 10 is used). - uat = user attribute (same as user id except for field 10). - sig = signature - rev = revocation signature - fpr = fingerprint: (fingerprint is in field 10) - pkd = public key data (special field format, see below) - grp = keygrip - rvk = revocation key - tru = trust database information - spk = signature subpacket - - 2. Field: A letter describing the calculated validity. This is a single - letter, but be prepared that additional information may follow - in some future versions. (not used for secret keys) - o = Unknown (this key is new to the system) - i = The key is invalid (e.g. due to a missing self-signature) - d = The key has been disabled - (deprecated - use the 'D' in field 12 instead) - r = The key has been revoked - e = The key has expired - - = Unknown validity (i.e. no value assigned) - q = Undefined validity - '-' and 'q' may safely be treated as the same - value for most purposes - n = The key is not valid - m = The key is marginal valid. - f = The key is fully valid - u = The key is ultimately valid. This often means - that the secret key is available, but any key may - be marked as ultimately valid. - w = The key has a well known private part. - s = The key has special validity. This means that it - might be self-signed and expected to be used in - the STEED sytem. - - If the validity information is given for a UID or UAT - record, it describes the validity calculated based on this - user ID. If given for a key record it describes the best - validity taken from the best rated user ID. - - For X.509 certificates a 'u' is used for a trusted root - certificate (i.e. for the trust anchor) and an 'f' for all - other valid certificates. - - 3. Field: length of key in bits. - - 4. Field: Algorithm: 1 = RSA - 16 = Elgamal (encrypt only) - 17 = DSA (sometimes called DH, sign only) - 20 = Elgamal (sign and encrypt - don't use them!) - (for other id's see include/cipher.h) - - 5. Field: KeyID - - 6. Field: Creation Date (in UTC). For UID and UAT records, this is - the self-signature date. Note that the date is usally - printed in seconds since epoch, however, we are migrating - to an ISO 8601 format (e.g. "19660205T091500"). This is - currently only relevant for X.509. A simple way to detect - the new format is to scan for the 'T'. - - 7. Field: Key or user ID/user attribute expiration date or empty if none. - - 8. Field: Used for serial number in crt records (used to be the Local-ID). - For UID and UAT records, this is a hash of the user ID contents - used to represent that exact user ID. For trust signatures, - this is the trust depth seperated by the trust value by a - space. - - 9. Field: Ownertrust (primary public keys only) - This is a single letter, but be prepared that additional - information may follow in some future versions. For trust - signatures with a regular expression, this is the regular - expression value, quoted as in field 10. - -10. Field: User-ID. The value is quoted like a C string to avoid - control characters (the colon is quoted "\x3a"). - For a "pub" record this field is not used on --fixed-list-mode. - A UAT record puts the attribute subpacket count here, a - space, and then the total attribute subpacket size. - In gpgsm the issuer name comes here - An FPR record stores the fingerprint here. - The fingerprint of an revocation key is stored here. - -11. Field: Signature class as per RFC-4880. This is a 2 digit - hexnumber followed by either the letter 'x' for an - exportable signature or the letter 'l' for a local-only - signature. The class byte of an revocation key is also - given here, 'x' and 'l' is used the same way. IT is not - used for X.509. - -12. Field: Key capabilities: - e = encrypt - s = sign - c = certify - a = authentication - A key may have any combination of them in any order. In - addition to these letters, the primary key has uppercase - versions of the letters to denote the _usable_ - capabilities of the entire key, and a potential letter 'D' - to indicate a disabled key. - -13. Field: Used in FPR records for S/MIME keys to store the - fingerprint of the issuer certificate. This is useful to - build the certificate path based on certificates stored in - the local keyDB; it is only filled if the issuer - certificate is available. The root has been reached if - this is the same string as the fingerprint. The advantage - of using this value is that it is guaranteed to have been - been build by the same lookup algorithm as gpgsm uses. - For "uid" records this lists the preferences in the same - way the gpg's --edit-key menu does. - For "sig" records, this is the fingerprint of the key that - issued the signature. Note that this is only filled in if - the signature verified correctly. Note also that for - various technical reasons, this fingerprint is only - available if --no-sig-cache is used. - -14. Field Flag field used in the --edit menu output: - -15. Field Used in sec/sbb to print the serial number of a token - (internal protect mode 1002) or a '#' if that key is a - simple stub (internal protect mode 1001) -16. Field: For sig records, this is the used hash algorithm: - 2 = SHA-1 - 8 = SHA-256 - (for other id's see include/cipher.h) - -All dates are displayed in the format yyyy-mm-dd unless you use the -option --fixed-list-mode in which case they are displayed as seconds -since Epoch. More fields may be added later, so parsers should be -prepared for this. When parsing a number the parser should stop at the -first non-number character so that additional information can later be -added. - -If field 1 has the tag "pkd", a listing looks like this: -pkd:0:1024:B665B1435F4C2 .... FF26ABB: - ! ! !-- the value - ! !------ for information number of bits in the value - !--------- index (eg. DSA goes from 0 to 3: p,q,g,y) - - -Example for a "tru" trust base record: - - tru:o:0:1166697654:1:3:1:5 - - The fields are: - - 2: Reason for staleness of trust. If this field is empty, then the - trustdb is not stale. This field may have multiple flags in it: - - o: Trustdb is old - t: Trustdb was built with a different trust model than the one we - are using now. - - 3: Trust model: - 0: Classic trust model, as used in PGP 2.x. - 1: PGP trust model, as used in PGP 6 and later. This is the same - as the classic trust model, except for the addition of trust - signatures. - - GnuPG before version 1.4 used the classic trust model by default. - GnuPG 1.4 and later uses the PGP trust model by default. - - 4: Date trustdb was created in seconds since 1970-01-01. - 5: Date trustdb will expire in seconds since 1970-01-01. - 6: Number of marginally trusted users to introduce a new key signer - (gpg's option --marginals-needed) - 7: Number of completely trusted users to introduce a new key signer. - (gpg's option --completes-needed) - 8: Maximum depth of a certification chain. - *gpg's option --max-cert-depth) - -The "spk" signature subpacket records have the fields: - - 2: Subpacket number as per RFC-4880 and later. - 3: Flags in hex. Currently the only two bits assigned are 1, to - indicate that the subpacket came from the hashed part of the - signature, and 2, to indicate the subpacket was marked critical. - 4: Length of the subpacket. Note that this is the length of the - subpacket, and not the length of field 5 below. Due to the need - for %-encoding, the length of field 5 may be up to 3x this value. - 5: The subpacket data. Printable ASCII is shown as ASCII, but other - values are rendered as %XX where XX is the hex value for the byte. - - -Format of the "--status-fd" output -================================== -Every line is prefixed with "[GNUPG:] ", followed by a keyword with -the type of the status line and a some arguments depending on the -type (maybe none); an application should always be prepared to see -more arguments in future versions. - - - NEWSIG - May be issued right before a signature verification starts. This - is useful to define a context for parsing ERROR status - messages. No arguments are currently defined. - - GOODSIG - The signature with the keyid is good. For each signature only - one of the codes GOODSIG, BADSIG, EXPSIG, EXPKEYSIG, REVKEYSIG - or ERRSIG will be emitted. In the past they were used as a - marker for a new signature; new code should use the NEWSIG - status instead. The username is the primary one encoded in - UTF-8 and %XX escaped. The fingerprint may be used instead of - the long keyid if it is available. This is the case with CMS - and might eventually also be available for OpenPGP. - - EXPSIG - The signature with the keyid is good, but the signature is - expired. The username is the primary one encoded in UTF-8 and - %XX escaped. The fingerprint may be used instead of the long - keyid if it is available. This is the case with CMS and might - eventually also be available for OpenPGP. - - EXPKEYSIG - The signature with the keyid is good, but the signature was - made by an expired key. The username is the primary one - encoded in UTF-8 and %XX escaped. The fingerprint may be used - instead of the long keyid if it is available. This is the - case with CMS and might eventually also be available for - OpenPGP. - - REVKEYSIG - The signature with the keyid is good, but the signature was - made by a revoked key. The username is the primary one encoded - in UTF-8 and %XX escaped. The fingerprint may be used instead - of the long keyid if it is available. This is the case with - CMS and might eventually also be available for OpenPGP. - - BADSIG - The signature with the keyid has not been verified okay. The - username is the primary one encoded in UTF-8 and %XX - escaped. The fingerprint may be used instead of the long keyid - if it is available. This is the case with CMS and might - eventually also be available for OpenPGP. - - ERRSIG \ - - It was not possible to check the signature. This may be - caused by a missing public key or an unsupported algorithm. A - RC of 4 indicates unknown algorithm, a 9 indicates a missing - public key. The other fields give more information about this - signature. sig_class is a 2 byte hex-value. The fingerprint - may be used instead of the long keyid if it is available. - This is the case with CMS and might eventually also be - available for OpenPGP. - - Note, that TIMESTAMP may either be a number with seconds since - epoch or an ISO 8601 string which can be detected by the - presence of the letter 'T' inside. - - VALIDSIG - - [ ] - - The signature with the keyid is good. This is the same as - GOODSIG but has the fingerprint as the argument. Both status - lines are emitted for a good signature. All arguments here - are on one long line. sig-timestamp is the signature creation - time in seconds after the epoch. expire-timestamp is the - signature expiration time in seconds after the epoch (zero - means "does not expire"). sig-version, pubkey-algo, hash-algo, - and sig-class (a 2-byte hex value) are all straight from the - signature packet. PRIMARY-KEY-FPR is the fingerprint of the - primary key or identical to the first argument. This is - useful to get back to the primary key without running gpg - again for this purpose. - - The primary-key-fpr parameter is used for OpenPGP and not - available for CMS signatures. The sig-version as well as the - sig class is not defined for CMS and currently set to 0 and 00. - - Note, that *-TIMESTAMP may either be a number with seconds - since epoch or an ISO 8601 string which can be detected by the - presence of the letter 'T' inside. - - SIG_ID - This is emitted only for signatures of class 0 or 1 which - have been verified okay. The string is a signature id - and may be used in applications to detect replay attacks - of signed messages. Note that only DLP algorithms give - unique ids - others may yield duplicated ones when they - have been created in the same second. - - Note, that SIG-TIMESTAMP may either be a number with seconds - since epoch or an ISO 8601 string which can be detected by the - presence of the letter 'T' inside. - - ENC_TO - The message is encrypted to this LONG_KEYID. KEYTYPE is the - numerical value of the public key algorithm or 0 if it is not - known, KEYLENGTH is the length of the key or 0 if it is not - known (which is currently always the case). Gpg prints this - line always; Gpgsm only if it knows the certificate. - - NODATA - No data has been found. Codes for what are: - 1 - No armored data. - 2 - Expected a packet but did not found one. - 3 - Invalid packet found, this may indicate a non OpenPGP - message. - 4 - signature expected but not found - You may see more than one of these status lines. - - UNEXPECTED - Unexpected data has been encountered - 0 - not further specified - - - TRUST_UNDEFINED - TRUST_NEVER - TRUST_MARGINAL [0 []] - TRUST_FULLY [0 []] - TRUST_ULTIMATE [0 []] - For good signatures one of these status lines are emitted to - indicate the validity of the key used to create the signature. - The error token values are currently only emitted by gpgsm. - VALIDATION_MODEL describes the algorithm used to check the - validity of the key. The defaults are the standard Web of - Trust model for gpg and the the standard X.509 model for - gpgsm. The defined values are - - "pgp" for the standard PGP WoT. - "shell" for the standard X.509 model. - "chain" for the chain model. - "steed" for the STEED model. - - Note that we use the term "TRUST_" in the status names for - historic reasons; we now speak of validity. - - PKA_TRUST_GOOD - PKA_TRUST_BAD - Depending on the outcome of the PKA check one of the above - status codes is emitted in addition to a TRUST_* status. - Without PKA info available or - - KEYEXPIRED - The key has expired. expire-timestamp is the expiration time - in seconds since Epoch. This status line is not very useful - because it will also be emitted for expired subkeys even if - this subkey is not used. To check whether a key used to sign - a message has expired, the EXPKEYSIG status line is to be - used. - - Note, that TIMESTAMP may either be a number with seconds since - epoch or an ISO 8601 string which can be detected by the - presence of the letter 'T' inside. - - KEYREVOKED - The used key has been revoked by its owner. No arguments yet. - - BADARMOR - The ASCII armor is corrupted. No arguments yet. - - RSA_OR_IDEA - Obsolete. This status message used to be emitted for requests - to use the IDEA or RSA algorithms. It has been dropped from - GnuPG 2.1 after the respective patents expired. - - SHM_INFO - SHM_GET - SHM_GET_BOOL - SHM_GET_HIDDEN - - GET_BOOL - GET_LINE - GET_HIDDEN - GOT_IT - - NEED_PASSPHRASE - Issued whenever a passphrase is needed. - keytype is the numerical value of the public key algorithm - or 0 if this is not applicable, keylength is the length - of the key or 0 if it is not known (this is currently always the case). - - NEED_PASSPHRASE_SYM - Issued whenever a passphrase for symmetric encryption is needed. - - NEED_PASSPHRASE_PIN [] - Issued whenever a PIN is requested to unlock a card. - - MISSING_PASSPHRASE - No passphrase was supplied. An application which encounters this - message may want to stop parsing immediately because the next message - will probably be a BAD_PASSPHRASE. However, if the application - is a wrapper around the key edit menu functionality it might not - make sense to stop parsing but simply ignoring the following - BAD_PASSPHRASE. - - BAD_PASSPHRASE - The supplied passphrase was wrong or not given. In the latter case - you may have seen a MISSING_PASSPHRASE. - - GOOD_PASSPHRASE - The supplied passphrase was good and the secret key material - is therefore usable. - - NO_PUBKEY - NO_SECKEY - The key is not available - - IMPORT_CHECK - This status is emitted in interactive mode right before - the "import.okay" prompt. - - IMPORTED - The keyid and name of the signature just imported - - IMPORT_OK [] - The key with the primary key's FINGERPRINT has been imported. - Reason flags: - 0 := Not actually changed - 1 := Entirely new key. - 2 := New user IDs - 4 := New signatures - 8 := New subkeys - 16 := Contains private key. - The flags may be ORed. - - IMPORT_PROBLEM [] - Issued for each import failure. Reason codes are: - 0 := "No specific reason given". - 1 := "Invalid Certificate". - 2 := "Issuer Certificate missing". - 3 := "Certificate Chain too long". - 4 := "Error storing certificate". - - IMPORT_RES - - - Final statistics on import process (this is one long line) - - FILE_START - Start processing a file . indicates the performed - operation: - 1 - verify - 2 - encrypt - 3 - decrypt - - FILE_DONE - Marks the end of a file processing which has been started - by FILE_START. - - BEGIN_DECRYPTION - END_DECRYPTION - Mark the start and end of the actual decryption process. These - are also emitted when in --list-only mode. - - DECRYPTION_INFO - Print information about the symmetric encryption algorithm and - the MDC method. This will be emitted even if the decryption - fails. - - DECRYPTION_FAILED - The symmetric decryption failed - one reason could be a wrong - passphrase for a symmetrical encrypted message. - - DECRYPTION_OKAY - The decryption process succeeded. This means, that either the - correct secret key has been used or the correct passphrase - for a conventional encrypted message was given. The program - itself may return an errorcode because it may not be possible to - verify a signature for some reasons. - - BEGIN_ENCRYPTION - END_ENCRYPTION - Mark the start and end of the actual encryption process. - - BEGIN_SIGNING - Mark the start of the actual signing process. This may be used - as an indication that all requested secret keys are ready for - use. - - DELETE_PROBLEM reason_code - Deleting a key failed. Reason codes are: - 1 - No such key - 2 - Must delete secret key first - 3 - Ambigious specification - - PROGRESS what char cur total - Used by the primegen and Public key functions to indicate progress. - "char" is the character displayed with no --status-fd enabled, with - the linefeed replaced by an 'X'. "cur" is the current amount - done and "total" is amount to be done; a "total" of 0 indicates that - the total amount is not known. The condition - TOATL && CUR == TOTAL - may be used to detect the end of an operation. - Well known values for WHAT: - "pk_dsa" - DSA key generation - "pk_elg" - Elgamal key generation - "primegen" - Prime generation - "need_entropy" - Waiting for new entropy in the RNG - "file:XXX" - processing file XXX - (note that current gpg versions leave out the - "file:" prefix). - "tick" - generic tick without any special meaning - useful - for letting clients know that the server is - still working. - "starting_agent" - A gpg-agent was started because it is not - running as a daemon. - "learncard" Send by the agent and gpgsm while learing - the data of a smartcard. - "card_busy" A smartcard is still working - - SIG_CREATED - A signature has been created using these parameters. - type: 'D' = detached - 'C' = cleartext - 'S' = standard - (only the first character should be checked) - class: 2 hex digits with the signature class - - Note, that TIMESTAMP may either be a number with seconds since - epoch or an ISO 8601 string which can be detected by the - presence of the letter 'T' inside. - - KEY_CREATED [] - A key has been created - type: 'B' = primary and subkey - 'P' = primary - 'S' = subkey - The fingerprint is one of the primary key for type B and P and - the one of the subkey for S. Handle is an arbitrary - non-whitespace string used to match key parameters from batch - key creation run. - - KEY_NOT_CREATED [] - The key from batch run has not been created due to errors. - - - SESSION_KEY : - The session key used to decrypt the message. This message will - only be emitted when the special option --show-session-key - is used. The format is suitable to be passed to the option - --override-session-key - - NOTATION_NAME - NOTATION_DATA - name and string are %XX escaped; the data may be split - among several NOTATION_DATA lines. - - USERID_HINT - Give a hint about the user ID for a certain keyID. - - POLICY_URL - string is %XX escaped - - BEGIN_STREAM - END_STREAM - Issued by pipemode. - - INV_RECP - INV_SGNR - Issued for each unusable recipient/sender. The reasons codes - currently in use are: - 0 := "No specific reason given". - 1 := "Not Found" - 2 := "Ambigious specification" - 3 := "Wrong key usage" - 4 := "Key revoked" - 5 := "Key expired" - 6 := "No CRL known" - 7 := "CRL too old" - 8 := "Policy mismatch" - 9 := "Not a secret key" - 10 := "Key not trusted" - 11 := "Missing certificate" - 12 := "Missing issuer certificate" - - Note that for historical reasons the INV_RECP status is also - used for gpgsm's SIGNER command where it relates to signer's - of course. Newer GnuPG versions are using INV_SGNR; - applications should ignore the INV_RECP during the sender's - command processing once they have seen an INV_SGNR. We use - different code so that we can distinguish them while doing an - encrypt+sign. - - - NO_RECP - NO_SGNR - Issued when no recipients/senders are usable. - - ALREADY_SIGNED - Warning: This is experimental and might be removed at any time. - - TRUNCATED - The output was truncated to MAXNO items. This status code is issued - for certain external requests - - ERROR [] - - This is a generic error status message, it might be followed - by error location specific data. and - should not contain spaces. The error code is - a either a string commencing with a letter or such a string - prefixed with a numerical error code and an underscore; e.g.: - "151011327_EOF". - - SUCCESS [] - Postive confirimation that an operation succeeded. - is optional but if given should not contain spaces. - Used only with a few commands. - - - ATTRIBUTE - - This is one long line issued for each attribute subpacket when - an attribute packet is seen during key listing. is the - fingerprint of the key. is the length of the - attribute subpacket. is the attribute type - (1==image). / indicates that this is the Nth - indexed subpacket of count total subpackets in this attribute - packet. and are from the - self-signature on the attribute packet. If the attribute - packet does not have a valid self-signature, then the - timestamp is 0. are a bitwise OR of: - 0x01 = this attribute packet is a primary uid - 0x02 = this attribute packet is revoked - 0x04 = this attribute packet is expired - - CARDCTRL [] - This is used to control smartcard operations. - Defined values for WHAT are: - 1 = Request insertion of a card. Serialnumber may be given - to request a specific card. Used by gpg 1.4 w/o scdaemon. - 2 = Request removal of a card. Used by gpg 1.4 w/o scdaemon. - 3 = Card with serialnumber detected - 4 = No card available. - 5 = No card reader available - 6 = No card support available - - PLAINTEXT - This indicates the format of the plaintext that is about to be - written. The format is a 1 byte hex code that shows the - format of the plaintext: 62 ('b') is binary data, 74 ('t') is - text data with no character set specified, and 75 ('u') is - text data encoded in the UTF-8 character set. The timestamp - is in seconds since the epoch. If a filename is available it - gets printed as the third argument, percent-escaped as usual. - - PLAINTEXT_LENGTH - This indicates the length of the plaintext that is about to be - written. Note that if the plaintext packet has partial length - encoding it is not possible to know the length ahead of time. - In that case, this status tag does not appear. - - SIG_SUBPACKET - This indicates that a signature subpacket was seen. The - format is the same as the "spk" record above. - - SC_OP_FAILURE [] - An operation on a smartcard definitely failed. Currently - there is no indication of the actual error code, but - application should be prepared to later accept more arguments. - Defined values for CODE are: - 0 - unspecified error (identically to a missing CODE) - 1 - canceled - 2 - bad PIN - - SC_OP_SUCCESS - A smart card operaion succeeded. This status is only printed - for certain operation and is mostly useful to check whether a - PIN change really worked. - - BACKUP_KEY_CREATED fingerprint fname - A backup key named FNAME has been created for the key with - KEYID. - - MOUNTPOINT - NAME is a percent-plus escaped filename describing the - mountpoint for the current operation (e.g. g13 --mount). This - may either be the specified mountpoint or one randomly choosen - by g13. - - PINENTRY_LAUNCHED - - This status line is emitted by gpg to notify a client that a - Pinentry has been launched. is the PID of the Pinentry. - It may be used to display a hint to the user but can't be used - to synchronize with Pinentry. Note that there is also an - Assuan inquiry line with the same name used internally or, if - enabled, send to the client instead of this status line. Such - an inquiry may be used to sync with Pinentry - -Status lines which are not anymore used: - - SIGEXPIRED removed on 2011-02-04. - This is deprecated in favor of KEYEXPIRED. - - - - -Format of the "--attribute-fd" output -===================================== - -When --attribute-fd is set, during key listings (--list-keys, ---list-secret-keys) GnuPG dumps each attribute packet to the file -descriptor specified. --attribute-fd is intended for use with ---status-fd as part of the required information is carried on the -ATTRIBUTE status tag (see above). - -The contents of the attribute data is specified by RFC 4880. For -convenience, here is the Photo ID format, as it is currently the only -attribute defined: - - Byte 0-1: The length of the image header. Due to a historical - accident (i.e. oops!) back in the NAI PGP days, this is - a little-endian number. Currently 16 (0x10 0x00). - - Byte 2: The image header version. Currently 0x01. +*** Field 12 - Key capabilities - Byte 3: Encoding format. 0x01 == JPEG. + The defined capabilities are: - Byte 4-15: Reserved, and currently unused. + - e :: Encrypt + - s :: Sign + - c :: Certify + - a :: Authentication - All other data after this header is raw image (JPEG) data. + A key may have any combination of them in any order. In addition + to these letters, the primary key has uppercase versions of the + letters to denote the _usable_ capabilities of the entire key, and + a potential letter 'D' to indicate a disabled key. +*** Field 13 - Issuer certificate fingerprint or other info -Format of the "--list-config" output -==================================== + Used in FPR records for S/MIME keys to store the fingerprint of + the issuer certificate. This is useful to build the certificate + path based on certificates stored in the local key database it is + only filled if the issuer certificate is available. The root has + been reached if this is the same string as the fingerprint. The + advantage of using this value is that it is guaranteed to have + been been build by the same lookup algorithm as gpgsm uses. ---list-config outputs information about the GnuPG configuration for -the benefit of frontends or other programs that call GnuPG. There are -several list-config items, all colon delimited like the rest of the ---with-colons output. The first field is always "cfg" to indicate -configuration information. The second field is one of (with -examples): + For "uid" records this field lists the preferences in the same way + gpg's --edit-key menu does. -version: the third field contains the version of GnuPG. + For "sig" records, this is the fingerprint of the key that issued + the signature. Note that this is only filled in if the signature + verified correctly. Note also that for various technical reasons, + this fingerprint is only available if --no-sig-cache is used. - cfg:version:1.3.5 +*** Field 14 - Flag field -pubkey: the third field contains the public key algorithmdcaiphers - this version of GnuPG supports, separated by semicolons. The - algorithm numbers are as specified in RFC-4880. Note that in - contrast to the --status-fd interface these are _not_ the - Libgcrypt identifiers. + Flag field used in the --edit menu output - cfg:pubkey:1;2;3;16;17 +*** Field 15 - S/N of a token -cipher: the third field contains the symmetric ciphers this version of - GnuPG supports, separated by semicolons. The cipher numbers - are as specified in RFC-4880. + Used in sec/sbb to print the serial number of a token (internal + protect mode 1002) or a '#' if that key is a simple stub (internal + protect mode 1001) - cfg:cipher:2;3;4;7;8;9;10 +*** Field 16 - Hash algorithm -digest: the third field contains the digest (hash) algorithms this - version of GnuPG supports, separated by semicolons. The - digest numbers are as specified in RFC-4880. + For sig records, this is the used hash algorithm. For example: + 2 = SHA-1, 8 = SHA-256. - cfg:digest:1;2;3;8;9;10 +** Special fields -compress: the third field contains the compression algorithms this - version of GnuPG supports, separated by semicolons. The - algorithm numbers are as specified in RFC-4880. - - cfg:compress:0;1;2;3 - -group: the third field contains the name of the group, and the fourth - field contains the values that the group expands to, separated - by semicolons. - -For example, a group of: - group mynames = paige 0x12345678 joe patti - -would result in: - cfg:group:mynames:patti;joe;0x12345678;paige - - -Key generation -============== -See the Libcrypt manual. +*** PKD - Public key data + If field 1 has the tag "pkd", a listing looks like this: +#+begin_example +pkd:0:1024:B665B1435F4C2 .... FF26ABB: + ! ! !-- the value + ! !------ for information number of bits in the value + !--------- index (eg. DSA goes from 0 to 3: p,q,g,y) +#+end_example -Unattended key generation -========================= -The the manual for a description. +*** TRU - Trust database information + Example for a "tru" trust base record: +#+begin_example + tru:o:0:1166697654:1:3:1:5 +#+end_example + - Field 2 :: Reason for staleness of trust. If this field is + empty, then the trustdb is not stale. This field may + have multiple flags in it: -Layout of the TrustDB -===================== -The TrustDB is built from fixed length records, where the first byte -describes the record type. All numeric values are stored in network -byte order. The length of each record is 40 bytes. The first record of -the DB is always of type 1 and this is the only record of this type. + - o :: Trustdb is old + - t :: Trustdb was built with a different trust model + than the one we are using now. -FIXME: The layout changed, document it here. + - Field 3 :: Trust model + - 0 :: Classic trust model, as used in PGP 2.x. + - 1 :: PGP trust model, as used in PGP 6 and later. + This is the same as the classic trust model, + except for the addition of trust signatures. + + GnuPG before version 1.4 used the classic trust model + by default. GnuPG 1.4 and later uses the PGP trust + model by default. + + - Field 4 :: Date trustdb was created in seconds since Epoch. + - Field 5 :: Date trustdb will expire in seconds since Epoch. + - Field 6 :: Number of marginally trusted users to introduce a new + key signer (gpg's option --marginals-needed). + - Field 7 :: Number of completely trusted users to introduce a new + key signer. (gpg's option --completes-needed) + + - Field 8 :: Maximum depth of a certification chain. (gpg's option + --max-cert-depth) + +*** SPK - Signature subpacket records + + - Field 2 :: Subpacket number as per RFC-4880 and later. + - Field 3 :: Flags in hex. Currently the only two bits assigned + are 1, to indicate that the subpacket came from the + hashed part of the signature, and 2, to indicate the + subpacket was marked critical. + - Field 4 :: Length of the subpacket. Note that this is the + length of the subpacket, and not the length of field + 5 below. Due to the need for %-encoding, the length + of field 5 may be up to 3x this value. + - Field 5 :: The subpacket data. Printable ASCII is shown as + ASCII, but other values are rendered as %XX where XX + is the hex value for the byte. + +*** CFG - Configuration data + + --list-config outputs information about the GnuPG configuration + for the benefit of frontends or other programs that call GnuPG. + There are several list-config items, all colon delimited like the + rest of the --with-colons output. The first field is always "cfg" + to indicate configuration information. The second field is one of + (with examples): + + - version :: The third field contains the version of GnuPG. + + : cfg:version:1.3.5 + + - pubkey :: The third field contains the public key algorithms + this version of GnuPG supports, separated by + semicolons. The algorithm numbers are as specified in + RFC-4880. Note that in contrast to the --status-fd + interface these are _not_ the Libgcrypt identifiers. + + : cfg:pubkey:1;2;3;16;17 + + - cipher :: The third field contains the symmetric ciphers this + version of GnuPG supports, separated by semicolons. + The cipher numbers are as specified in RFC-4880. + + : cfg:cipher:2;3;4;7;8;9;10 + + - digest :: The third field contains the digest (hash) algorithms + this version of GnuPG supports, separated by + semicolons. The digest numbers are as specified in + RFC-4880. + + : cfg:digest:1;2;3;8;9;10 + + - compress :: The third field contains the compression algorithms + this version of GnuPG supports, separated by + semicolons. The algorithm numbers are as specified + in RFC-4880. + + : cfg:compress:0;1;2;3 + + - group :: The third field contains the name of the group, and the + fourth field contains the values that the group expands + to, separated by semicolons. + + For example, a group of: + : group mynames = paige 0x12345678 joe patti + would result in: + : cfg:group:mynames:patti;joe;0x12345678;paige + + +* Format of the --status-fd output + + Every line is prefixed with "[GNUPG:] ", followed by a keyword with + the type of the status line and some arguments depending on the type + (maybe none); an application should always be prepared to see more + arguments in future versions. + +** General status codes +*** NEWSIG + May be issued right before a signature verification starts. This + is useful to define a context for parsing ERROR status messages. + No arguments are currently defined. + +*** GOODSIG + The signature with the keyid is good. For each signature only one + of the codes GOODSIG, BADSIG, EXPSIG, EXPKEYSIG, REVKEYSIG or + ERRSIG will be emitted. In the past they were used as a marker + for a new signature; new code should use the NEWSIG status + instead. The username is the primary one encoded in UTF-8 and %XX + escaped. The fingerprint may be used instead of the long keyid if + it is available. This is the case with CMS and might eventually + also be available for OpenPGP. + +*** EXPSIG + The signature with the keyid is good, but the signature is + expired. The username is the primary one encoded in UTF-8 and %XX + escaped. The fingerprint may be used instead of the long keyid if + it is available. This is the case with CMS and might eventually + also be available for OpenPGP. + +*** EXPKEYSIG + The signature with the keyid is good, but the signature was made + by an expired key. The username is the primary one encoded in + UTF-8 and %XX escaped. The fingerprint may be used instead of the + long keyid if it is available. This is the case with CMS and + might eventually also be available for OpenPGP. + +*** REVKEYSIG + The signature with the keyid is good, but the signature was made + by a revoked key. The username is the primary one encoded in UTF-8 + and %XX escaped. The fingerprint may be used instead of the long + keyid if it is available. This is the case with CMS and might + eventually also be? available for OpenPGP. + +*** BADSIG + The signature with the keyid has not been verified okay. The + username is the primary one encoded in UTF-8 and %XX escaped. The + fingerprint may be used instead of the long keyid if it is + available. This is the case with CMS and might eventually also be + available for OpenPGP. + +*** ERRSIG