[svn] GnuPG - r4970 - in trunk: . agent doc scd sm
svn author wk
cvs at cvs.gnupg.org
Thu Mar 26 20:27:05 CET 2009
Author: wk
Date: 2009-03-26 20:27:04 +0100 (Thu, 26 Mar 2009)
New Revision: 4970
Modified:
trunk/NEWS
trunk/agent/ChangeLog
trunk/agent/agent.h
trunk/agent/command.c
trunk/doc/gpgsm.texi
trunk/scd/ChangeLog
trunk/scd/apdu.c
trunk/scd/app-nks.c
trunk/scd/command.c
trunk/scd/scdaemon.h
trunk/sm/ChangeLog
trunk/sm/gpgsm.c
trunk/sm/gpgsm.h
trunk/sm/sign.c
Log:
Signing using Netkey 3 cards does now work.
Modified: trunk/agent/ChangeLog
===================================================================
--- trunk/agent/ChangeLog 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/agent/ChangeLog 2009-03-26 19:27:04 UTC (rev 4970)
@@ -1,5 +1,9 @@
2009-03-26 Werner Koch <wk at g10code.com>
+ * agent.h (MAX_DIGEST_LEN): Change to 64.
+ * command.c (cmd_sethash): Allow digest length of 48 and 64.
+ (cmd_sethash): Allow more hash algos.
+
* trustlist.c (reformat_name): New.
(agent_marktrusted): Use a reformatted name. Reload the table
before the update and always reload it at the end.
Modified: trunk/scd/ChangeLog
===================================================================
--- trunk/scd/ChangeLog 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/scd/ChangeLog 2009-03-26 19:27:04 UTC (rev 4970)
@@ -1,3 +1,16 @@
+2009-03-26 Werner Koch <wk at g10code.com>
+
+ * command.c (cmd_pksign): Allow more hash algorithms.
+
+ * scdaemon.h (MAX_DIGEST_LEN): Change to 64.
+
+ * apdu.c (open_ccid_reader): Clear the is_to flag.
+
+ * app-nks.c (filelist): Add field KID.
+ (do_getattr): Change standard authentication key.
+ (do_sign): Setup a security environment for TCOS 3 cards and support
+ all SHA-2 algorithms.
+
2009-03-24 Werner Koch <wk at g10code.com>
* command.c (struct server_local_s): Add flag
Modified: trunk/sm/ChangeLog
===================================================================
--- trunk/sm/ChangeLog 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/sm/ChangeLog 2009-03-26 19:27:04 UTC (rev 4970)
@@ -1,5 +1,12 @@
2009-03-26 Werner Koch <wk at g10code.com>
+ * gpgsm.c (main): s/def_digest_string/forced_digest_algo/ and
+ activate the --digest-algo option.
+ * gpgsm.h (struct opt): s/def_digest_algo/forced_digest_algo/.
+ * sign.c (gpgsm_sign): Implement --digest-algo.
+
+ * sign.c (MAX_DIGEST_LEN): Change to 64.
+
* call-agent.c (gpgsm_agent_marktrusted): Format the issuer name.
2009-03-25 Werner Koch <wk at g10code.com>
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/NEWS 2009-03-26 19:27:04 UTC (rev 4970)
@@ -17,7 +17,9 @@
* Better synchronization of several smartcard sessions.
+ * Support for the Telesec Netkey 3 cards.
+
Noteworthy changes in version 2.0.11 (2009-03-03)
-------------------------------------------------
Modified: trunk/agent/agent.h
===================================================================
--- trunk/agent/agent.h 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/agent/agent.h 2009-03-26 19:27:04 UTC (rev 4970)
@@ -42,7 +42,7 @@
#define MD_USER_TLS_MD5SHA1 (GCRY_MODULE_ID_USER+1)
/* Maximum length of a digest. */
-#define MAX_DIGEST_LEN 36
+#define MAX_DIGEST_LEN 64
/* A large struct name "opt" to keep global flags */
struct
Modified: trunk/agent/command.c
===================================================================
--- trunk/agent/command.c 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/agent/command.c 2009-03-26 19:27:04 UTC (rev 4970)
@@ -637,8 +637,14 @@
{
if (has_option (line, "--hash=sha1"))
algo = GCRY_MD_SHA1;
+ else if (has_option (line, "--hash=sha224"))
+ algo = GCRY_MD_SHA224;
else if (has_option (line, "--hash=sha256"))
algo = GCRY_MD_SHA256;
+ else if (has_option (line, "--hash=sha384"))
+ algo = GCRY_MD_SHA384;
+ else if (has_option (line, "--hash=sha512"))
+ algo = GCRY_MD_SHA512;
else if (has_option (line, "--hash=rmd160"))
algo = GCRY_MD_RMD160;
else if (has_option (line, "--hash=md5"))
@@ -671,7 +677,8 @@
n /= 2;
if (algo == MD_USER_TLS_MD5SHA1 && n == 36)
;
- else if (n != 16 && n != 20 && n != 24 && n != 32)
+ else if (n != 16 && n != 20 && n != 24
+ && n != 28 && n != 32 && n != 48 && n != 64)
return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash");
if (n > MAX_DIGEST_LEN)
Modified: trunk/doc/gpgsm.texi
===================================================================
--- trunk/doc/gpgsm.texi 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/doc/gpgsm.texi 2009-03-26 19:27:04 UTC (rev 4970)
@@ -568,6 +568,12 @@
@code{AES256} may be used instead of their OIDs. The default is
@code{3DES} (1.2.840.113549.3.7).
+ at item --digest-algo @code{name}
+Use @code{name} as the message digest algorithm. Usually this
+algorithm is deduced from the respective signing certificate. This
+option forces the use of the given algorithm and may lead to severe
+interoperability problems.
+
@end table
Modified: trunk/scd/apdu.c
===================================================================
--- trunk/scd/apdu.c 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/scd/apdu.c 2009-03-26 19:27:04 UTC (rev 4970)
@@ -1951,6 +1951,9 @@
reader_table[slot].send_apdu_reader = send_apdu_ccid;
reader_table[slot].check_keypad = check_ccid_keypad;
reader_table[slot].dump_status_reader = dump_ccid_reader_status;
+ /* Our CCID reader code does not support T=0 at all, thus reset the
+ flag. */
+ reader_table[slot].is_t0 = 0;
dump_reader_status (slot);
return slot;
@@ -2839,10 +2842,10 @@
if (lc != -1 && (lc > 255 || lc < 0))
{
- /* Data does not fit into an APDU. What we do now dependes on
+ /* Data does not fit into an APDU. What we do now depends on
the EXTENDED_MODE parameter. */
if (!extended_mode)
- return SW_WRONG_LENGTH; /* No way. to send such an APDU. */
+ return SW_WRONG_LENGTH; /* No way to send such an APDU. */
else if (extended_mode > 0)
return SW_HOST_NOT_SUPPORTED; /* FIXME. */
else if (extended_mode < 0)
Modified: trunk/scd/app-nks.c
===================================================================
--- trunk/scd/app-nks.c 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/scd/app-nks.c 2009-03-26 19:27:04 UTC (rev 4970)
@@ -19,11 +19,12 @@
/* Notes:
- - This is still work in progress. We are now targeting TCOS 3 cards
- but try to keep compatibility to TCOS 2. Both are not fully
- working as of now. TCOS 3 PIN management seems to work. Use GPA
- from SVN trunk to test it.
+ - We are now targeting TCOS 3 cards and it may happen that there is
+ a regression towards TCOS 2 cards. Please report.
+ - The TKS3 AUT key is not used by our authentication command but
+ accessible via the decrypt command.
+
- If required, we automagically switch between the NKS application
and the SigG application. This avoids to use the DINSIG
application which is somewhat limited, has no support for Secure
@@ -63,25 +64,26 @@
int fid; /* File ID. */
int nks_ver; /* 0 for NKS version 2, 3 for version 3. */
int certtype; /* Type of certificate or 0 if it is not a certificate. */
- int iskeypair; /* If true has the FID of the correspoding certificate. */
+ int iskeypair; /* If true has the FID of the corresponding certificate. */
int issignkey; /* True if file is a key usable for signing. */
int isenckey; /* True if file is a key usable for decryption. */
+ unsigned char kid; /* Corresponding key references. */
} filelist[] = {
- { 0, 0x4531, 0, 0, 0xC000, 1, 0 }, /* EF_PK.NKS.SIG */
- { 1, 0x4531, 3, 0, 0x0000, 1, 1 }, /* EF_PK.CH.SIG */
- { 0, 0xC000, 0, 101 }, /* EF_C.NKS.SIG */
- { 1, 0xC000, 0, 101 }, /* EF_C.CH.SIG */
+ { 0, 0x4531, 0, 0, 0xC000, 1, 0, 0x80 }, /* EF_PK.NKS.SIG */
+ { 1, 0x4531, 3, 0, 0x0000, 1, 1, 0x84 }, /* EF_PK.CH.SIG */
+ { 0, 0xC000, 0, 101 }, /* EF_C.NKS.SIG */
+ { 1, 0xC000, 0, 101 }, /* EF_C.CH.SIG */
{ 0, 0x4331, 0, 100 },
{ 0, 0x4332, 0, 100 },
- { 0, 0xB000, 0, 110 }, /* EF_PK.RCA.NKS */
- { 0, 0x45B1, 0, 0, 0xC200, 0, 1 }, /* EF_PK.NKS.ENC */
- { 0, 0xC200, 0, 101 }, /* EF_C.NKS.ENC */
+ { 0, 0xB000, 0, 110 }, /* EF_PK.RCA.NKS */
+ { 0, 0x45B1, 0, 0, 0xC200, 0, 1, 0x81 }, /* EF_PK.NKS.ENC */
+ { 0, 0xC200, 0, 101 }, /* EF_C.NKS.ENC */
{ 0, 0x43B1, 0, 100 },
{ 0, 0x43B2, 0, 100 },
- { 0, 0x4571, 3, 0, 0xc500, 0, 0 }, /* EF_PK.NKS.AUT */
- { 0, 0xC500, 3, 101 }, /* EF_C.NKS.AUT */
- { 0, 0x45B2, 3, 0, 0xC201, 0, 1 }, /* EF_PK.NKS.ENC1024 */
- { 0, 0xC201, 3, 101 }, /* EF_C.NKS.ENC1024 */
+ { 0, 0x4571, 3, 0, 0xc500, 0, 0, 0x82 }, /* EF_PK.NKS.AUT */
+ { 0, 0xC500, 3, 101 }, /* EF_C.NKS.AUT */
+ { 0, 0x45B2, 3, 0, 0xC201, 0, 1, 0x83 }, /* EF_PK.NKS.ENC1024 */
+ { 0, 0xC201, 3, 101 }, /* EF_C.NKS.ENC1024 */
/* { 1, 0xB000, 3, ... */
{ 0, 0 }
};
@@ -303,10 +305,12 @@
{
case 1: /* $AUTHKEYID */
{
- /* NetKey 3.0 cards define this key for authentication.
- FIXME: We don't have the readkey command, so this
- information is pretty useless. */
- char const tmp[] = "NKS-NKS3.4571";
+ /* NetKey 3.0 cards define an authentication key but according
+ to the specs this key is only usable for encryption and not
+ signing. it might work anyway but it has not yet been
+ tested - fixme. Thus for now we use the NKS signature key
+ for authentication. */
+ char const tmp[] = "NKS-NKS3.4531";
send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
}
break;
@@ -685,13 +689,18 @@
int rc, i;
int is_sigg = 0;
int fid;
- unsigned char data[35]; /* Must be large enough for a SHA-1 digest
- + the largest OID _prefix above. */
+ unsigned char kid;
+ unsigned char data[83]; /* Must be large enough for a SHA-1 digest
+ + the largest OID prefix. */
+ size_t datalen;
if (!keyidstr || !*keyidstr)
return gpg_error (GPG_ERR_INV_VALUE);
- if (indatalen != 20 && indatalen != 16 && indatalen != 35)
- return gpg_error (GPG_ERR_INV_VALUE);
+ switch (indatalen)
+ {
+ case 16: case 20: case 35: case 47: case 51: case 67: case 83: break;
+ default: return gpg_error (GPG_ERR_INV_VALUE);
+ }
/* Check that the provided ID is valid. This is not really needed
but we do it to enforce correct usage by the caller. */
@@ -721,22 +730,35 @@
return gpg_error (GPG_ERR_NOT_FOUND);
if (!filelist[i].issignkey)
return gpg_error (GPG_ERR_INV_ID);
+ kid = filelist[i].kid;
- /* Prepare the DER object from INDATA. */
- if (indatalen == 35)
+ /* Prepare the DER object from INDATA. */
+ if (app->app_local->nks_version > 2 && (indatalen == 35
+ || indatalen == 47
+ || indatalen == 51
+ || indatalen == 67
+ || indatalen == 83))
{
+ /* The caller send data matching the length of the ASN.1 encoded
+ hash for SHA-{1,224,256,384,512}. Assume that is okay. */
+ assert (indatalen <= sizeof data);
+ memcpy (data, indata, indatalen);
+ datalen = indatalen;
+ }
+ else if (indatalen == 35)
+ {
/* Alright, the caller was so kind to send us an already
- prepared DER object. Check that it is waht we want and that
- it matches the hash algorithm. */
+ prepared DER object. This is for TCOS 2. */
if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15))
;
- else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata, rmd160_prefix,15))
+ else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata,rmd160_prefix,15))
;
else
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
memcpy (data, indata, indatalen);
+ datalen = 35;
}
- else
+ else if (indatalen == 20)
{
if (hashalgo == GCRY_MD_SHA1)
memcpy (data, sha1_prefix, 15);
@@ -745,11 +767,32 @@
else
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
memcpy (data+15, indata, indatalen);
+ datalen = 35;
}
+ else
+ return gpg_error (GPG_ERR_INV_VALUE);
- rc = verify_pin (app, 0, NULL, pincb, pincb_arg);
+
+ /* Send an MSE for PSO:Computer_Signature. */
+ if (app->app_local->nks_version > 2)
+ {
+ unsigned char mse[6];
+
+ mse[0] = 0x80; /* Algorithm reference. */
+ mse[1] = 1;
+ mse[2] = 2; /* RSA, card does pkcs#1 v1.5 padding, no ASN.1 check. */
+ mse[3] = 0x84; /* Private key reference. */
+ mse[4] = 1;
+ mse[5] = kid;
+ rc = iso7816_manage_security_env (app->slot, 0x41, 0xB6,
+ mse, sizeof mse);
+ }
+ /* Verify using PW1.CH. */
if (!rc)
- rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
+ rc = verify_pin (app, 0, NULL, pincb, pincb_arg);
+ /* Compute the signature. */
+ if (!rc)
+ rc = iso7816_compute_ds (app->slot, data, datalen, outdata, outdatalen);
return rc;
}
Modified: trunk/scd/command.c
===================================================================
--- trunk/scd/command.c 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/scd/command.c 2009-03-26 19:27:04 UTC (rev 4970)
@@ -905,7 +905,7 @@
}
-/* PKSIGN [--hash=[rmd160|sha1|md5]] <hexified_id>
+/* PKSIGN [--hash=[rmd160|sha{1,224,256,384,512}|md5]] <hexified_id>
The --hash option is optional; the default is SHA1.
@@ -924,6 +924,14 @@
hash_algo = GCRY_MD_RMD160;
else if (has_option (line, "--hash=sha1"))
hash_algo = GCRY_MD_SHA1;
+ else if (has_option (line, "--hash=sha224"))
+ hash_algo = GCRY_MD_SHA224;
+ else if (has_option (line, "--hash=sha256"))
+ hash_algo = GCRY_MD_SHA256;
+ else if (has_option (line, "--hash=sha384"))
+ hash_algo = GCRY_MD_SHA384;
+ else if (has_option (line, "--hash=sha512"))
+ hash_algo = GCRY_MD_SHA512;
else if (has_option (line, "--hash=md5"))
hash_algo = GCRY_MD_MD5;
else if (!strstr (line, "--"))
Modified: trunk/scd/scdaemon.h
===================================================================
--- trunk/scd/scdaemon.h 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/scd/scdaemon.h 2009-03-26 19:27:04 UTC (rev 4970)
@@ -39,7 +39,7 @@
#define MD_USER_TLS_MD5SHA1 (GCRY_MODULE_ID_USER+1)
/* Maximum length of a digest. */
-#define MAX_DIGEST_LEN 36
+#define MAX_DIGEST_LEN 64
Modified: trunk/sm/gpgsm.c
===================================================================
--- trunk/sm/gpgsm.c 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/sm/gpgsm.c 2009-03-26 19:27:04 UTC (rev 4970)
@@ -843,8 +843,8 @@
int use_random_seed = 1;
int no_common_certs_import = 0;
int with_fpr = 0;
- char *def_digest_string = NULL;
- char *extra_digest_algo = NULL;
+ const char *forced_digest_algo = NULL;
+ const char *extra_digest_algo = NULL;
enum cmd_and_opt_values cmd = 0;
struct server_control_s ctrl;
certlist_t recplist = NULL;
@@ -1301,7 +1301,7 @@
break;
case oDigestAlgo:
- /* Dummy for now. */
+ forced_digest_algo = pargs.r.ret_str;
break;
case oExtraDigestAlgo:
@@ -1460,12 +1460,10 @@
|| !gcry_cipher_mode_from_oid (opt.def_cipher_algoid))
log_error (_("selected cipher algorithm is invalid\n"));
- if (def_digest_string)
+ if (forced_digest_algo)
{
- opt.def_digest_algo = gcry_md_map_name (def_digest_string);
- xfree (def_digest_string);
- def_digest_string = NULL;
- if (our_md_test_algo(opt.def_digest_algo) )
+ opt.forced_digest_algo = gcry_md_map_name (forced_digest_algo);
+ if (our_md_test_algo(opt.forced_digest_algo) )
log_error (_("selected digest algorithm is invalid\n"));
}
if (extra_digest_algo)
Modified: trunk/sm/gpgsm.h
===================================================================
--- trunk/sm/gpgsm.h 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/sm/gpgsm.h 2009-03-26 19:27:04 UTC (rev 4970)
@@ -33,7 +33,7 @@
#include "../common/estream.h"
#include "../common/audit.h"
-#define MAX_DIGEST_LEN 24
+#define MAX_DIGEST_LEN 64
struct keyserver_spec
{
@@ -92,9 +92,10 @@
const char *def_cipher_algoid; /* cipher algorithm to use if
nothing else is specified */
- int def_digest_algo; /* Ditto for hash algorithm */
int def_compress_algo; /* Ditto for compress algorithm */
+ int forced_digest_algo; /* User forced hash algorithm. */
+
char *def_recipient; /* userID of the default recipient */
int def_recipient_self; /* The default recipient is the default key */
Modified: trunk/sm/sign.c
===================================================================
--- trunk/sm/sign.c 2009-03-26 11:33:53 UTC (rev 4969)
+++ trunk/sm/sign.c 2009-03-26 19:27:04 UTC (rev 4970)
@@ -399,11 +399,22 @@
/* Figure out the hash algorithm to use. We do not want to use the
one for the certificate but if possible an OID for the plain
algorithm. */
+ if (opt.forced_digest_algo && opt.verbose)
+ log_info ("user requested hash algorithm %d\n", opt.forced_digest_algo);
for (i=0, cl=signerlist; cl; cl = cl->next, i++)
{
const char *oid = ksba_cert_get_digest_algo (cl->cert);
- cl->hash_algo = oid ? gcry_md_map_name (oid) : 0;
+ if (opt.forced_digest_algo)
+ {
+ oid = NULL;
+ cl->hash_algo = opt.forced_digest_algo;
+ }
+ else
+ {
+ oid = ksba_cert_get_digest_algo (cl->cert);
+ cl->hash_algo = oid ? gcry_md_map_name (oid) : 0;
+ }
switch (cl->hash_algo)
{
case GCRY_MD_SHA1: oid = "1.3.14.3.2.26"; break;
@@ -427,6 +438,7 @@
}
cl->hash_algo_oid = oid;
}
+
if (opt.verbose)
{
for (i=0, cl=signerlist; cl; cl = cl->next, i++)
More information about the Gnupg-commits
mailing list