mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
Start support of TCOS 3 cards.
Support restriction attribute. Fix utf-8 printing problems. Use AES by default.
This commit is contained in:
parent
b60bfbe25c
commit
a6a9181818
2
NEWS
2
NEWS
@ -25,6 +25,8 @@ Noteworthy changes in version 2.0.10 (unreleased)
|
|||||||
* New control statement %ask-passphrase for the unattended key
|
* New control statement %ask-passphrase for the unattended key
|
||||||
generation of gpg2.
|
generation of gpg2.
|
||||||
|
|
||||||
|
* gpgsm now uses AES by default.
|
||||||
|
|
||||||
|
|
||||||
Noteworthy changes in version 2.0.9 (2008-03-26)
|
Noteworthy changes in version 2.0.9 (2008-03-26)
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
3
TODO
3
TODO
@ -66,7 +66,8 @@
|
|||||||
We should check the card status in open-card to make this smoother.
|
We should check the card status in open-card to make this smoother.
|
||||||
Needs to be integrated with the status file update, though. It is
|
Needs to be integrated with the status file update, though. It is
|
||||||
not a real problem because application will get a card removed
|
not a real problem because application will get a card removed
|
||||||
status and should the send a reset to try solving the problem.
|
status and should then send a reset to try solving the problem.
|
||||||
|
** Resolve fixme in do_sign of app-dinsig.
|
||||||
|
|
||||||
** Add a regression test to check the extkeyusage.
|
** Add a regression test to check the extkeyusage.
|
||||||
|
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2008-06-26 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* estream.c (es_write_sanitized): Loose check for control
|
||||||
|
characters to better cope with utf-8. The range 0x80..0x9f is
|
||||||
|
nowadays not anymore accidently used for control charaters.
|
||||||
|
|
||||||
2008-06-25 Marcus Brinkmann <marcus@g10code.de>
|
2008-06-25 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
Revert last three changes related to handle translation.
|
Revert last three changes related to handle translation.
|
||||||
|
@ -3074,7 +3074,7 @@ es_write_sanitized (estream_t ES__RESTRICT stream,
|
|||||||
for (; length; length--, p++, count++)
|
for (; length; length--, p++, count++)
|
||||||
{
|
{
|
||||||
if (*p < 0x20
|
if (*p < 0x20
|
||||||
|| (*p >= 0x7f && *p < 0xa0)
|
|| *p == 0x7f
|
||||||
|| (delimiters
|
|| (delimiters
|
||||||
&& (strchr (delimiters, *p) || *p == '\\')))
|
&& (strchr (delimiters, *p) || *p == '\\')))
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2008-06-26 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* stringhelp.c (print_sanitized_buffer2): Loose check for control
|
||||||
|
characters to better cope with utf-8. The range 0x80..0x9f is
|
||||||
|
nowadays not anymore accidently used for control charaters.
|
||||||
|
|
||||||
2008-06-13 Werner Koch <wk@g10code.com>
|
2008-06-13 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* dotlock.c: Reformat code and implement locking for W32.
|
* dotlock.c: Reformat code and implement locking for W32.
|
||||||
|
@ -406,9 +406,8 @@ print_sanitized_buffer2 (FILE *fp, const void *buffer, size_t length,
|
|||||||
|
|
||||||
for (; length; length--, p++, count++)
|
for (; length; length--, p++, count++)
|
||||||
{
|
{
|
||||||
/* Fixme: Check whether *p < 0xa0 is correct for utf8 encoding. */
|
|
||||||
if (*p < 0x20
|
if (*p < 0x20
|
||||||
|| (*p >= 0x7f && *p < 0xa0)
|
|| *p == 0x7f
|
||||||
|| *p == delim
|
|| *p == delim
|
||||||
|| *p == delim2
|
|| *p == delim2
|
||||||
|| ((delim || delim2) && *p=='\\'))
|
|| ((delim || delim2) && *p=='\\'))
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2008-06-25 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* app-dinsig.c (do_sign): Allow for SHA256.
|
||||||
|
|
||||||
2008-06-24 Werner Koch <wk@g10code.com>
|
2008-06-24 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* app-common.h (app_ctx_s): Renamed reset_mode parameter of
|
* app-common.h (app_ctx_s): Renamed reset_mode parameter of
|
||||||
|
112
scd/app-dinsig.c
112
scd/app-dinsig.c
@ -1,5 +1,5 @@
|
|||||||
/* app-dinsig.c - The DINSIG (DIN V 66291-1) card application.
|
/* app-dinsig.c - The DINSIG (DIN V 66291-1) card application.
|
||||||
* Copyright (C) 2002, 2004, 2005, 2007 Free Software Foundation, Inc.
|
* Copyright (C) 2002, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -397,14 +397,20 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
|
|||||||
static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
|
static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
|
||||||
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
|
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
|
||||||
0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
|
0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
|
||||||
|
static unsigned char sha256_prefix[19] = /* OID is 2.16.840.1.101.3.4.2.1 */
|
||||||
|
{ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
|
||||||
|
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
|
||||||
|
0x00, 0x04, 0x20 };
|
||||||
int rc;
|
int rc;
|
||||||
int fid;
|
int fid;
|
||||||
unsigned char data[35]; /* Must be large enough for a SHA-1 digest
|
unsigned char data[19+32]; /* Must be large enough for a SHA-256 digest
|
||||||
+ the largest OID _prefix above. */
|
+ the largest OID _prefix above. */
|
||||||
|
int datalen;
|
||||||
|
|
||||||
if (!keyidstr || !*keyidstr)
|
if (!keyidstr || !*keyidstr)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
if (indatalen != 20 && indatalen != 16 && indatalen != 35)
|
if (indatalen != 20 && indatalen != 16 && indatalen != 32
|
||||||
|
&& indatalen != (15+20) && indatalen != (19+32))
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
/* Check that the provided ID is vaid. This is not really needed
|
/* Check that the provided ID is vaid. This is not really needed
|
||||||
@ -421,7 +427,8 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
|
|||||||
return gpg_error (GPG_ERR_NOT_FOUND);
|
return gpg_error (GPG_ERR_NOT_FOUND);
|
||||||
|
|
||||||
/* Prepare the DER object from INDATA. */
|
/* Prepare the DER object from INDATA. */
|
||||||
if (indatalen == 35)
|
datalen = 35;
|
||||||
|
if (indatalen == 15+20)
|
||||||
{
|
{
|
||||||
/* Alright, the caller was so kind to send us an already
|
/* Alright, the caller was so kind to send us an already
|
||||||
prepared DER object. Check that it is what we want and that
|
prepared DER object. Check that it is what we want and that
|
||||||
@ -434,24 +441,103 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
|
|||||||
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
|
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
|
||||||
memcpy (data, indata, indatalen);
|
memcpy (data, indata, indatalen);
|
||||||
}
|
}
|
||||||
else
|
else if (indatalen == 19+32)
|
||||||
{
|
{
|
||||||
if (hashalgo == GCRY_MD_SHA1)
|
/* Alright, the caller was so kind to send us an already
|
||||||
memcpy (data, sha1_prefix, 15);
|
prepared DER object. Check that it is what we want and that
|
||||||
else if (hashalgo == GCRY_MD_RMD160)
|
it matches the hash algorithm. */
|
||||||
memcpy (data, rmd160_prefix, 15);
|
datalen = indatalen;
|
||||||
|
if (hashalgo == GCRY_MD_SHA256 && !memcmp (indata, sha256_prefix, 19))
|
||||||
|
;
|
||||||
|
else if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha256_prefix, 19))
|
||||||
|
{
|
||||||
|
/* Fixme: This is a kludge. A better solution is not to use
|
||||||
|
SHA1 as default but use an autodetection. However this
|
||||||
|
needs changes in all app-*.c */
|
||||||
|
hashalgo = GCRY_MD_SHA256;
|
||||||
|
datalen = indatalen;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
|
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
|
||||||
memcpy (data+15, indata, indatalen);
|
memcpy (data, indata, indatalen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int len = 15;
|
||||||
|
if (hashalgo == GCRY_MD_SHA1)
|
||||||
|
memcpy (data, sha1_prefix, len);
|
||||||
|
else if (hashalgo == GCRY_MD_RMD160)
|
||||||
|
memcpy (data, rmd160_prefix, len);
|
||||||
|
else if (hashalgo == GCRY_MD_SHA256)
|
||||||
|
{
|
||||||
|
len = 19;
|
||||||
|
datalen = len + indatalen;
|
||||||
|
memcpy (data, sha256_prefix, len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
|
||||||
|
memcpy (data+len, indata, indatalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = verify_pin (app, pincb, pincb_arg);
|
rc = verify_pin (app, pincb, pincb_arg);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
|
rc = iso7816_compute_ds (app->slot, data, datalen, outdata, outdatalen);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#warning test function - works but may brick your card
|
||||||
|
/* Handle the PASSWD command. CHVNOSTR is currently ignored; we
|
||||||
|
always use VHV0. RESET_MODE is not yet implemented. */
|
||||||
|
static gpg_error_t
|
||||||
|
do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
|
||||||
|
unsigned int flags,
|
||||||
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
|
void *pincb_arg)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
char *pinvalue;
|
||||||
|
const char *oldpin;
|
||||||
|
size_t oldpinlen;
|
||||||
|
|
||||||
|
if ((flags & APP_CHANGE_FLAG_RESET))
|
||||||
|
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
|
|
||||||
|
if ((flags & APP_CHANGE_FLAG_NULLPIN))
|
||||||
|
{
|
||||||
|
/* With the nullpin flag, we do not verify the PIN - it would fail
|
||||||
|
if the Nullpin is still set. */
|
||||||
|
oldpin = "\0\0\0\0\0";
|
||||||
|
oldpinlen = 6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = verify_pin (app, pincb, pincb_arg);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
oldpin = NULL;
|
||||||
|
oldpinlen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TRANSLATORS: Do not translate the "|*|" prefixes but
|
||||||
|
keep it at the start of the string. We need this elsewhere
|
||||||
|
to get some infos on the string. */
|
||||||
|
err = pincb (pincb_arg, _("|N|Initial New PIN"), &pinvalue);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error (_("error getting new PIN: %s\n"), gpg_strerror (err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = iso7816_change_reference_data (app->slot, 0x81,
|
||||||
|
oldpin, oldpinlen,
|
||||||
|
pinvalue, strlen (pinvalue));
|
||||||
|
xfree (pinvalue);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Select the DINSIG application on the card in SLOT. This function
|
/* Select the DINSIG application on the card in SLOT. This function
|
||||||
must be used before any other DINSIG application functions. */
|
must be used before any other DINSIG application functions. */
|
||||||
@ -475,7 +561,7 @@ app_select_dinsig (app_t app)
|
|||||||
app->fnc.sign = do_sign;
|
app->fnc.sign = do_sign;
|
||||||
app->fnc.auth = NULL;
|
app->fnc.auth = NULL;
|
||||||
app->fnc.decipher = NULL;
|
app->fnc.decipher = NULL;
|
||||||
app->fnc.change_pin = NULL;
|
app->fnc.change_pin = NULL /*do_change_pin*/;
|
||||||
app->fnc.check_pin = NULL;
|
app->fnc.check_pin = NULL;
|
||||||
|
|
||||||
app->force_chv1 = 1;
|
app->force_chv1 = 1;
|
||||||
|
13
sm/ChangeLog
13
sm/ChangeLog
@ -1,3 +1,16 @@
|
|||||||
|
2008-06-25 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* sign.c (gpgsm_sign): Revamp the hash algorithm selection.
|
||||||
|
* gpgsm.h (struct certlist_s): Add field HASH_ALGO and HASH_ALGO_OID.
|
||||||
|
|
||||||
|
* qualified.c (gpgsm_qualified_consent): Fix double free.
|
||||||
|
|
||||||
|
* gpgsm.c (main): Change default cipher algo to AES.
|
||||||
|
|
||||||
|
* keylist.c (print_utf8_extn_raw, print_utf8_extn): New.
|
||||||
|
(list_cert_raw, list_cert_std): Print the TeleSec restriction
|
||||||
|
extension.
|
||||||
|
|
||||||
2008-06-23 Werner Koch <wk@g10code.com>
|
2008-06-23 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* encrypt.c (encode_session_key): Replace xmalloc by xtrymalloc.
|
* encrypt.c (encode_session_key): Replace xmalloc by xtrymalloc.
|
||||||
|
@ -987,7 +987,7 @@ main ( int argc, char **argv)
|
|||||||
create_dotlock (NULL); /* register locking cleanup */
|
create_dotlock (NULL); /* register locking cleanup */
|
||||||
i18n_init();
|
i18n_init();
|
||||||
|
|
||||||
opt.def_cipher_algoid = "3DES"; /*des-EDE3-CBC*/
|
opt.def_cipher_algoid = "AES"; /*des-EDE3-CBC*/
|
||||||
|
|
||||||
opt.homedir = default_homedir ();
|
opt.homedir = default_homedir ();
|
||||||
|
|
||||||
|
@ -207,6 +207,8 @@ struct certlist_s
|
|||||||
ksba_cert_t cert;
|
ksba_cert_t cert;
|
||||||
int is_encrypt_to; /* True if the certificate has been set through
|
int is_encrypt_to; /* True if the certificate has been set through
|
||||||
the --encrypto-to option. */
|
the --encrypto-to option. */
|
||||||
|
int hash_algo; /* Used to track the hash algorithm to use. */
|
||||||
|
const char *hash_algo_oid; /* And the corresponding OID. */
|
||||||
};
|
};
|
||||||
typedef struct certlist_s *certlist_t;
|
typedef struct certlist_s *certlist_t;
|
||||||
|
|
||||||
|
122
sm/keylist.c
122
sm/keylist.c
@ -1,6 +1,6 @@
|
|||||||
/* keylist.c - Print certificates in various formats.
|
/* keylist.c - Print certificates in various formats.
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003,
|
* Copyright (C) 1998, 1999, 2000, 2001, 2003,
|
||||||
* 2004, 2005 Free Software Foundation, Inc.
|
* 2004, 2005, 2008 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -35,6 +35,7 @@
|
|||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
|
#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
#include "tlv.h"
|
||||||
|
|
||||||
struct list_external_parm_s
|
struct list_external_parm_s
|
||||||
{
|
{
|
||||||
@ -77,12 +78,18 @@ struct
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Do not print this extension in the list of extensions. This is set
|
||||||
|
for oids which are already available via ksba fucntions. */
|
||||||
|
#define OID_FLAG_SKIP 1
|
||||||
|
/* The extension is a simple UTF8String and should be printed. */
|
||||||
|
#define OID_FLAG_UTF8 2
|
||||||
|
|
||||||
/* A table mapping OIDs to a descriptive string. */
|
/* A table mapping OIDs to a descriptive string. */
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
char *oid;
|
char *oid;
|
||||||
char *name;
|
char *name;
|
||||||
unsigned int flag;
|
unsigned int flag; /* A flag as described above. */
|
||||||
} oidtranstbl[] = {
|
} oidtranstbl[] = {
|
||||||
|
|
||||||
/* Algorithms. */
|
/* Algorithms. */
|
||||||
@ -115,6 +122,10 @@ static struct
|
|||||||
{ "0.2.262.1.10.12.4", "telesecCRLFilteredExt" },
|
{ "0.2.262.1.10.12.4", "telesecCRLFilteredExt" },
|
||||||
{ "0.2.262.1.10.12.5", "telesecCRLFilterExt"},
|
{ "0.2.262.1.10.12.5", "telesecCRLFilterExt"},
|
||||||
{ "0.2.262.1.10.12.6", "telesecNamingAuthorityExt" },
|
{ "0.2.262.1.10.12.6", "telesecNamingAuthorityExt" },
|
||||||
|
#define OIDSTR_restriction \
|
||||||
|
"1.3.36.8.3.8"
|
||||||
|
{ OIDSTR_restriction, "restriction", OID_FLAG_UTF8 },
|
||||||
|
|
||||||
|
|
||||||
/* PKIX private extensions. */
|
/* PKIX private extensions. */
|
||||||
{ "1.3.6.1.5.5.7.1.1", "authorityInfoAccess" },
|
{ "1.3.6.1.5.5.7.1.1", "authorityInfoAccess" },
|
||||||
@ -135,12 +146,12 @@ static struct
|
|||||||
{ "1.3.6.1.5.5.7.48.5", "caRepository" },
|
{ "1.3.6.1.5.5.7.48.5", "caRepository" },
|
||||||
|
|
||||||
/* X.509 id-ce */
|
/* X.509 id-ce */
|
||||||
{ "2.5.29.14", "subjectKeyIdentifier", 1},
|
{ "2.5.29.14", "subjectKeyIdentifier", OID_FLAG_SKIP},
|
||||||
{ "2.5.29.15", "keyUsage", 1 },
|
{ "2.5.29.15", "keyUsage", OID_FLAG_SKIP},
|
||||||
{ "2.5.29.16", "privateKeyUsagePeriod" },
|
{ "2.5.29.16", "privateKeyUsagePeriod" },
|
||||||
{ "2.5.29.17", "subjectAltName", 1 },
|
{ "2.5.29.17", "subjectAltName", OID_FLAG_SKIP},
|
||||||
{ "2.5.29.18", "issuerAltName", 1 },
|
{ "2.5.29.18", "issuerAltName", OID_FLAG_SKIP},
|
||||||
{ "2.5.29.19", "basicConstraints", 1},
|
{ "2.5.29.19", "basicConstraints", OID_FLAG_SKIP},
|
||||||
{ "2.5.29.20", "cRLNumber" },
|
{ "2.5.29.20", "cRLNumber" },
|
||||||
{ "2.5.29.21", "cRLReason" },
|
{ "2.5.29.21", "cRLReason" },
|
||||||
{ "2.5.29.22", "expirationDate" },
|
{ "2.5.29.22", "expirationDate" },
|
||||||
@ -150,13 +161,13 @@ static struct
|
|||||||
{ "2.5.29.28", "issuingDistributionPoint" },
|
{ "2.5.29.28", "issuingDistributionPoint" },
|
||||||
{ "2.5.29.29", "certificateIssuer" },
|
{ "2.5.29.29", "certificateIssuer" },
|
||||||
{ "2.5.29.30", "nameConstraints" },
|
{ "2.5.29.30", "nameConstraints" },
|
||||||
{ "2.5.29.31", "cRLDistributionPoints", 1 },
|
{ "2.5.29.31", "cRLDistributionPoints", OID_FLAG_SKIP},
|
||||||
{ "2.5.29.32", "certificatePolicies", 1 },
|
{ "2.5.29.32", "certificatePolicies", OID_FLAG_SKIP},
|
||||||
{ "2.5.29.32.0", "anyPolicy" },
|
{ "2.5.29.32.0", "anyPolicy" },
|
||||||
{ "2.5.29.33", "policyMappings" },
|
{ "2.5.29.33", "policyMappings" },
|
||||||
{ "2.5.29.35", "authorityKeyIdentifier", 1 },
|
{ "2.5.29.35", "authorityKeyIdentifier", OID_FLAG_SKIP},
|
||||||
{ "2.5.29.36", "policyConstraints" },
|
{ "2.5.29.36", "policyConstraints" },
|
||||||
{ "2.5.29.37", "extKeyUsage", 1 },
|
{ "2.5.29.37", "extKeyUsage", OID_FLAG_SKIP},
|
||||||
{ "2.5.29.46", "freshestCRL" },
|
{ "2.5.29.46", "freshestCRL" },
|
||||||
{ "2.5.29.54", "inhibitAnyPolicy" },
|
{ "2.5.29.54", "inhibitAnyPolicy" },
|
||||||
|
|
||||||
@ -561,6 +572,59 @@ print_names_raw (estream_t fp, int indent, ksba_name_t name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_utf8_extn_raw (estream_t fp, int indent,
|
||||||
|
const unsigned char *der, size_t derlen)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
int class, tag, constructed, ndef;
|
||||||
|
size_t objlen, hdrlen;
|
||||||
|
|
||||||
|
if (indent < 0)
|
||||||
|
indent = - indent;
|
||||||
|
|
||||||
|
err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
|
||||||
|
&ndef, &objlen, &hdrlen);
|
||||||
|
if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
|
||||||
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
es_fprintf (fp, "%*s[%s]\n", indent, "", gpg_strerror (err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
es_fprintf (fp, "%*s(%.*s)\n", indent, "", objlen, der);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_utf8_extn (estream_t fp, int indent,
|
||||||
|
const unsigned char *der, size_t derlen)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
int class, tag, constructed, ndef;
|
||||||
|
size_t objlen, hdrlen;
|
||||||
|
int indent_all;
|
||||||
|
|
||||||
|
if ((indent_all = (indent < 0)))
|
||||||
|
indent = - indent;
|
||||||
|
|
||||||
|
err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
|
||||||
|
&ndef, &objlen, &hdrlen);
|
||||||
|
if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
|
||||||
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
es_fprintf (fp, "%*s[Error - %s]\n",
|
||||||
|
indent_all? indent:0, "", gpg_strerror (err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
es_fprintf (fp, "%*s\"", indent_all? indent:0, "");
|
||||||
|
/* Fixme: we should implement word wrapping */
|
||||||
|
es_write_sanitized (fp, der, objlen, "\"", NULL);
|
||||||
|
es_fputs ("\"\n", fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* List one certificate in raw mode useful to have a closer look at
|
/* List one certificate in raw mode useful to have a closer look at
|
||||||
the certificate. This one does no beautification and only minimal
|
the certificate. This one does no beautification and only minimal
|
||||||
output sanitation. It is mainly useful for debugging. */
|
output sanitation. It is mainly useful for debugging. */
|
||||||
@ -581,6 +645,7 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
|
|||||||
const char *oid, *s;
|
const char *oid, *s;
|
||||||
ksba_name_t name, name2;
|
ksba_name_t name, name2;
|
||||||
unsigned int reason;
|
unsigned int reason;
|
||||||
|
const unsigned char *cert_der = NULL;
|
||||||
|
|
||||||
es_fprintf (fp, " ID: 0x%08lX\n",
|
es_fprintf (fp, " ID: 0x%08lX\n",
|
||||||
gpgsm_get_short_fingerprint (cert));
|
gpgsm_get_short_fingerprint (cert));
|
||||||
@ -892,11 +957,19 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
|
|||||||
unsigned int flag;
|
unsigned int flag;
|
||||||
|
|
||||||
s = get_oid_desc (oid, &flag);
|
s = get_oid_desc (oid, &flag);
|
||||||
|
if ((flag & OID_FLAG_SKIP))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!(flag & 1))
|
es_fprintf (fp, " %s: %s%s%s%s [%d octets]\n",
|
||||||
es_fprintf (fp, " %s: %s%s%s%s [%d octets]\n",
|
i? "critExtn":" extn",
|
||||||
i? "critExtn":" extn",
|
oid, s?" (":"", s?s:"", s?")":"", (int)len);
|
||||||
oid, s?" (":"", s?s:"", s?")":"", (int)len);
|
if ((flag & OID_FLAG_UTF8))
|
||||||
|
{
|
||||||
|
if (!cert_der)
|
||||||
|
cert_der = ksba_cert_get_image (cert, NULL);
|
||||||
|
assert (cert_der);
|
||||||
|
print_utf8_extn_raw (fp, -15, cert_der+off, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -938,6 +1011,10 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
|
|||||||
int is_ca, chainlen;
|
int is_ca, chainlen;
|
||||||
unsigned int kusage;
|
unsigned int kusage;
|
||||||
char *string, *p, *pend;
|
char *string, *p, *pend;
|
||||||
|
size_t off, len;
|
||||||
|
const char *oid;
|
||||||
|
const unsigned char *cert_der = NULL;
|
||||||
|
|
||||||
|
|
||||||
es_fprintf (fp, " ID: 0x%08lX\n",
|
es_fprintf (fp, " ID: 0x%08lX\n",
|
||||||
gpgsm_get_short_fingerprint (cert));
|
gpgsm_get_short_fingerprint (cert));
|
||||||
@ -1053,6 +1130,21 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
|
|||||||
es_putc ('\n', fp);
|
es_putc ('\n', fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Print restrictions. */
|
||||||
|
for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
|
||||||
|
&oid, NULL, &off, &len));idx++)
|
||||||
|
{
|
||||||
|
if (!strcmp (oid, OIDSTR_restriction) )
|
||||||
|
{
|
||||||
|
if (!cert_der)
|
||||||
|
cert_der = ksba_cert_get_image (cert, NULL);
|
||||||
|
assert (cert_der);
|
||||||
|
es_fputs (" restriction: ", fp);
|
||||||
|
print_utf8_extn (fp, 15, cert_der+off, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print policies. */
|
||||||
err = ksba_cert_get_cert_policies (cert, &string);
|
err = ksba_cert_get_cert_policies (cert, &string);
|
||||||
if (gpg_err_code (err) != GPG_ERR_NO_DATA)
|
if (gpg_err_code (err) != GPG_ERR_NO_DATA)
|
||||||
{
|
{
|
||||||
|
@ -215,7 +215,6 @@ gpgsm_qualified_consent (ctrl_t ctrl, ksba_cert_t cert)
|
|||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
i18n_switchback (orig_codeset);
|
i18n_switchback (orig_codeset);
|
||||||
xfree (orig_codeset);
|
|
||||||
xfree (subject);
|
xfree (subject);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
|
113
sm/sign.c
113
sm/sign.c
@ -1,5 +1,5 @@
|
|||||||
/* sign.c - Sign a message
|
/* sign.c - Sign a message
|
||||||
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -396,6 +396,44 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
|||||||
release_signerlist = 1;
|
release_signerlist = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
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;
|
||||||
|
switch (cl->hash_algo)
|
||||||
|
{
|
||||||
|
case GCRY_MD_SHA1: oid = "1.3.14.3.2.26"; break;
|
||||||
|
case GCRY_MD_RMD160: oid = "1.3.36.3.2.1"; break;
|
||||||
|
case GCRY_MD_SHA224: oid = "2.16.840.1.101.3.4.2.4"; break;
|
||||||
|
case GCRY_MD_SHA256: oid = "2.16.840.1.101.3.4.2.1"; break;
|
||||||
|
case GCRY_MD_SHA384: oid = "2.16.840.1.101.3.4.2.2"; break;
|
||||||
|
case GCRY_MD_SHA512: oid = "2.16.840.1.101.3.4.2.3"; break;
|
||||||
|
/* case GCRY_MD_WHIRLPOOL: oid = "No OID yet"; break; */
|
||||||
|
|
||||||
|
case GCRY_MD_MD5: /* We don't want to use MD5. */
|
||||||
|
case 0: /* No algorithm found in cert. */
|
||||||
|
default: /* Other algorithms. */
|
||||||
|
log_info (_("hash algorithm %d (%s) for signer %d not supported;"
|
||||||
|
" using %s\n"),
|
||||||
|
cl->hash_algo, oid? oid: "?", i,
|
||||||
|
gcry_md_algo_name (GCRY_MD_SHA1));
|
||||||
|
cl->hash_algo = GCRY_MD_SHA1;
|
||||||
|
oid = "1.3.14.3.2.26";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cl->hash_algo_oid = oid;
|
||||||
|
}
|
||||||
|
if (opt.verbose)
|
||||||
|
{
|
||||||
|
for (i=0, cl=signerlist; cl; cl = cl->next, i++)
|
||||||
|
log_info (_("hash algorithm used for signer %d: %s (%s)\n"),
|
||||||
|
i, gcry_md_algo_name (cl->hash_algo), cl->hash_algo_oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Gather certificates of signers and store them in the CMS object. */
|
/* Gather certificates of signers and store them in the CMS object. */
|
||||||
for (cl=signerlist; cl; cl = cl->next)
|
for (cl=signerlist; cl; cl = cl->next)
|
||||||
@ -419,7 +457,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
/* Set the hash algorithm we are going to use */
|
/* Set the hash algorithm we are going to use */
|
||||||
err = ksba_cms_add_digest_algo (cms, "1.3.14.3.2.26" /*SHA-1*/);
|
err = ksba_cms_add_digest_algo (cms, cl->hash_algo_oid);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_debug ("ksba_cms_add_digest_algo failed: %s\n",
|
log_debug ("ksba_cms_add_digest_algo failed: %s\n",
|
||||||
@ -458,7 +496,8 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare hashing (actually we are figuring out what we have set above)*/
|
/* Prepare hashing (actually we are figuring out what we have set
|
||||||
|
above). */
|
||||||
rc = gcry_md_open (&data_md, 0, 0);
|
rc = gcry_md_open (&data_md, 0, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -474,10 +513,6 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
|||||||
if (!algo)
|
if (!algo)
|
||||||
{
|
{
|
||||||
log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
|
log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
|
||||||
if (algoid
|
|
||||||
&& ( !strcmp (algoid, "1.2.840.113549.1.1.2")
|
|
||||||
||!strcmp (algoid, "1.2.840.113549.2.2")))
|
|
||||||
log_info (_("(this is the MD2 algorithm)\n"));
|
|
||||||
rc = gpg_error (GPG_ERR_BUG);
|
rc = gpg_error (GPG_ERR_BUG);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -485,26 +520,23 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (detached)
|
if (detached)
|
||||||
{ /* we hash the data right now so that we can store the message
|
{ /* We hash the data right now so that we can store the message
|
||||||
digest. ksba_cms_build() takes this as an flag that detached
|
digest. ksba_cms_build() takes this as an flag that detached
|
||||||
data is expected. */
|
data is expected. */
|
||||||
unsigned char *digest;
|
unsigned char *digest;
|
||||||
size_t digest_len;
|
size_t digest_len;
|
||||||
/* Fixme do this for all signers and get the algo to use from
|
|
||||||
the signer's certificate - does not make much sense, but we
|
|
||||||
should do this consistent as we have already done it above. */
|
|
||||||
algo = GCRY_MD_SHA1;
|
|
||||||
hash_data (data_fd, data_md);
|
hash_data (data_fd, data_md);
|
||||||
digest = gcry_md_read (data_md, algo);
|
|
||||||
digest_len = gcry_md_get_algo_dlen (algo);
|
|
||||||
if ( !digest || !digest_len)
|
|
||||||
{
|
|
||||||
log_error ("problem getting the hash of the data\n");
|
|
||||||
rc = gpg_error (GPG_ERR_BUG);
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
|
for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
|
||||||
{
|
{
|
||||||
|
digest = gcry_md_read (data_md, cl->hash_algo);
|
||||||
|
digest_len = gcry_md_get_algo_dlen (cl->hash_algo);
|
||||||
|
if ( !digest || !digest_len )
|
||||||
|
{
|
||||||
|
log_error ("problem getting the hash of the data\n");
|
||||||
|
rc = gpg_error (GPG_ERR_BUG);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
err = ksba_cms_set_message_digest (cms, signer, digest, digest_len);
|
err = ksba_cms_set_message_digest (cms, signer, digest, digest_len);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
@ -559,30 +591,26 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stopreason == KSBA_SR_BEGIN_DATA)
|
if (stopreason == KSBA_SR_BEGIN_DATA)
|
||||||
{ /* hash the data and store the message digest */
|
{
|
||||||
|
/* Hash the data and store the message digest. */
|
||||||
unsigned char *digest;
|
unsigned char *digest;
|
||||||
size_t digest_len;
|
size_t digest_len;
|
||||||
|
|
||||||
assert (!detached);
|
assert (!detached);
|
||||||
/* Fixme: get the algo to use from the signer's certificate
|
|
||||||
- does not make much sense, but we should do this
|
|
||||||
consistent as we have already done it above. Code is
|
|
||||||
mostly duplicated above. */
|
|
||||||
|
|
||||||
algo = GCRY_MD_SHA1;
|
|
||||||
rc = hash_and_copy_data (data_fd, data_md, writer);
|
rc = hash_and_copy_data (data_fd, data_md, writer);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
digest = gcry_md_read (data_md, algo);
|
|
||||||
digest_len = gcry_md_get_algo_dlen (algo);
|
|
||||||
if ( !digest || !digest_len)
|
|
||||||
{
|
|
||||||
log_error ("problem getting the hash of the data\n");
|
|
||||||
rc = gpg_error (GPG_ERR_BUG);
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
|
for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
|
||||||
{
|
{
|
||||||
|
digest = gcry_md_read (data_md, cl->hash_algo);
|
||||||
|
digest_len = gcry_md_get_algo_dlen (cl->hash_algo);
|
||||||
|
if ( !digest || !digest_len )
|
||||||
|
{
|
||||||
|
log_error ("problem getting the hash of the data\n");
|
||||||
|
rc = gpg_error (GPG_ERR_BUG);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
err = ksba_cms_set_message_digest (cms, signer,
|
err = ksba_cms_set_message_digest (cms, signer,
|
||||||
digest, digest_len);
|
digest, digest_len);
|
||||||
if (err)
|
if (err)
|
||||||
@ -595,11 +623,11 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (stopreason == KSBA_SR_NEED_SIG)
|
else if (stopreason == KSBA_SR_NEED_SIG)
|
||||||
{ /* calculate the signature for all signers */
|
{
|
||||||
|
/* Compute the signature for all signers. */
|
||||||
gcry_md_hd_t md;
|
gcry_md_hd_t md;
|
||||||
|
|
||||||
algo = GCRY_MD_SHA1;
|
rc = gcry_md_open (&md, 0, 0);
|
||||||
rc = gcry_md_open (&md, algo, 0);
|
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error ("md_open failed: %s\n", gpg_strerror (rc));
|
log_error ("md_open failed: %s\n", gpg_strerror (rc));
|
||||||
@ -615,6 +643,13 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
|||||||
|
|
||||||
if (signer)
|
if (signer)
|
||||||
gcry_md_reset (md);
|
gcry_md_reset (md);
|
||||||
|
{
|
||||||
|
certlist_t cl_tmp;
|
||||||
|
|
||||||
|
for (cl_tmp=signerlist; cl_tmp; cl_tmp = cl_tmp->next)
|
||||||
|
gcry_md_enable (md, cl_tmp->hash_algo);
|
||||||
|
}
|
||||||
|
|
||||||
rc = ksba_cms_hash_signed_attrs (cms, signer);
|
rc = ksba_cms_hash_signed_attrs (cms, signer);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -625,7 +660,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = gpgsm_create_cms_signature (ctrl, cl->cert,
|
rc = gpgsm_create_cms_signature (ctrl, cl->cert,
|
||||||
md, algo, &sigval);
|
md, cl->hash_algo, &sigval);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
gcry_md_close (md);
|
gcry_md_close (md);
|
||||||
@ -656,7 +691,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
|||||||
rc = asprintf (&buf, "%c %d %d 00 %s %s",
|
rc = asprintf (&buf, "%c %d %d 00 %s %s",
|
||||||
detached? 'D':'S',
|
detached? 'D':'S',
|
||||||
pkalgo,
|
pkalgo,
|
||||||
algo,
|
cl->hash_algo,
|
||||||
signed_at,
|
signed_at,
|
||||||
fpr);
|
fpr);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user