* configure.ac: Require libksba 0.9.7.

* certreqgen.c (get_parameter_uint, create_request): Create
an extension for key usage when requested.

* gpgsm.c (main): Install emergency_cleanup also as an atexit
handler.

* verify.c (gpgsm_verify): Removed the separate error code
handling for KSBA.  We use shared error codes anyway.

* export.c (export_p12): Removed debugging code.

* encrypt.c (gpgsm_encrypt): Put the session key in to secure memory.
This commit is contained in:
Werner Koch 2004-06-06 13:00:59 +00:00
parent 438ece068b
commit f289f433b6
13 changed files with 118 additions and 69 deletions

View File

@ -1,3 +1,7 @@
2004-06-06 Werner Koch <wk@gnupg.org>
* configure.ac: Require libksba 0.9.7.
2004-04-29 Werner Koch <wk@gnupg.org> 2004-04-29 Werner Koch <wk@gnupg.org>
Released 1.9.8. Released 1.9.8.

2
NEWS
View File

@ -5,6 +5,8 @@ Noteworthy changes in version 1.9.9
allow gpg-agent to add a key to the trustlist.txt after user allow gpg-agent to add a key to the trustlist.txt after user
confirmation. confirmation.
* Creating PKCS#10 requests does now honor the key usage.
Noteworthy changes in version 1.9.8 (2004-04-29) Noteworthy changes in version 1.9.8 (2004-04-29)
------------------------------------------------ ------------------------------------------------

3
TODO
View File

@ -24,9 +24,6 @@ might want to have an agent context for each service request
* sm/decrypt.c * sm/decrypt.c
** replace leading zero in integer hack by a cleaner solution ** replace leading zero in integer hack by a cleaner solution
* sm/sign.c
** Don't hardcode the use of RSA.
* sm/gpgsm.c * sm/gpgsm.c
** Support --output for all commands ** Support --output for all commands
** mark all unimplemented commands and options. ** mark all unimplemented commands and options.

View File

@ -36,7 +36,7 @@ NEED_LIBGCRYPT_VERSION=1.1.94
NEED_LIBASSUAN_VERSION=0.6.6 NEED_LIBASSUAN_VERSION=0.6.6
NEED_KSBA_VERSION=0.9.4 NEED_KSBA_VERSION=0.9.7
NEED_OPENSC_VERSION=0.8.0 NEED_OPENSC_VERSION=0.8.0

View File

@ -1,3 +1,20 @@
2004-06-06 Werner Koch <wk@gnupg.org>
* certreqgen.c (get_parameter_uint, create_request): Create
an extension for key usage when requested.
2004-05-12 Werner Koch <wk@gnupg.org>
* gpgsm.c (main): Install emergency_cleanup also as an atexit
handler.
* verify.c (gpgsm_verify): Removed the separate error code
handling for KSBA. We use shared error codes anyway.
* export.c (export_p12): Removed debugging code.
* encrypt.c (gpgsm_encrypt): Put the session key in to secure memory.
2004-05-11 Werner Koch <wk@gnupg.org> 2004-05-11 Werner Koch <wk@gnupg.org>
* sign.c (gpgsm_sign): Include the error source in the final error * sign.c (gpgsm_sign): Include the error source in the final error

View File

@ -129,6 +129,9 @@ struct reqgen_ctrl_s {
}; };
static const char oidstr_keyUsage[] = "2.5.29.15";
static int proc_parameters (ctrl_t ctrl, static int proc_parameters (ctrl_t ctrl,
struct para_data_s *para, struct para_data_s *para,
struct reqgen_ctrl_s *outctrl); struct reqgen_ctrl_s *outctrl);
@ -179,10 +182,10 @@ get_parameter_algo (struct para_data_s *para, enum para_name key)
return gcry_pk_map_name (r->u.value); return gcry_pk_map_name (r->u.value);
} }
/* parse the usage parameter. Returns 0 on success. Note that we /* Parse the usage parameter. Returns 0 on success. Note that we
only care about sign and encrypt and don't (yet) allow all the only care about sign and encrypt and don't (yet) allow all the
other X.509 usage to be specified; instead we will use a fixed other X.509 usage to be specified; instead we will use a fixed
mapping to the X.509 usage flags */ mapping to the X.509 usage flags. */
static int static int
parse_parameter_usage (struct para_data_s *para, enum para_name key) parse_parameter_usage (struct para_data_s *para, enum para_name key)
{ {
@ -222,6 +225,9 @@ get_parameter_uint (struct para_data_s *para, enum para_name key)
if (!r) if (!r)
return 0; return 0;
if (r->key == pKEYUSAGE)
return r->u.usage;
return (unsigned int)strtoul (r->u.value, NULL, 10); return (unsigned int)strtoul (r->u.value, NULL, 10);
} }
@ -516,6 +522,7 @@ create_request (ctrl_t ctrl,
ksba_stop_reason_t stopreason; ksba_stop_reason_t stopreason;
int rc = 0; int rc = 0;
const char *s; const char *s;
unsigned int use;
err = ksba_certreq_new (&cr); err = ksba_certreq_new (&cr);
if (err) if (err)
@ -576,6 +583,35 @@ create_request (ctrl_t ctrl,
rc = err; rc = err;
goto leave; goto leave;
} }
use = get_parameter_uint (para, pKEYUSAGE);
if (use == GCRY_PK_USAGE_SIGN)
{
/* For signing only we encode the bits:
KSBA_KEYUSAGE_DIGITAL_SIGNATURE
KSBA_KEYUSAGE_NON_REPUDIATION */
err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1,
"\x03\x02\x06\xC0", 4);
}
else if (use == GCRY_PK_USAGE_ENCR)
{
/* For encrypt only we encode the bits:
KSBA_KEYUSAGE_KEY_ENCIPHERMENT
KSBA_KEYUSAGE_DATA_ENCIPHERMENT */
err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1,
"\x03\x02\x04\x30", 4);
}
else
err = 0; /* Both or none given: don't request one. */
if (err)
{
log_error ("error setting the key usage: %s\n",
gpg_strerror (err));
rc = err;
goto leave;
}
do do
{ {

View File

@ -77,7 +77,7 @@ prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
if (seskeylen == 24) if (seskeylen == 24)
{ {
/* Smells like a 3-des key. This might happen because a SC has /* Smells like a 3-des key. This might happen because a SC has
already done the unpacking. fixme! */ already done the unpacking. */
} }
else else
{ {
@ -90,18 +90,18 @@ prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
/* FIXME: Actually the leading zero is required but due to the way /* FIXME: Actually the leading zero is required but due to the way
we encode the output in libgcrypt as an MPI we are not able to we encode the output in libgcrypt as an MPI we are not able to
encode that leading zero. However, when using a Smartcard we are encode that leading zero. However, when using a Smartcard we are
doing it the rightway and therefore we have to skip the zero. This doing it the right way and therefore we have to skip the zero. This
should be fixed in gpg-agent of course. */ should be fixed in gpg-agent of course. */
if (!seskey[n]) if (!seskey[n])
n++; n++;
if (seskey[n] != 2 ) /* wrong block type version */ if (seskey[n] != 2 ) /* Wrong block type version. */
{ {
rc = gpg_error (GPG_ERR_INV_SESSION_KEY); rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
goto leave; goto leave;
} }
for (n++; n < seskeylen && seskey[n]; n++) /* skip the random bytes */ for (n++; n < seskeylen && seskey[n]; n++) /* Skip the random bytes. */
; ;
n++; /* and the zero byte */ n++; /* and the zero byte */
if (n >= seskeylen ) if (n >= seskeylen )

View File

@ -398,8 +398,8 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
goto leave; goto leave;
} }
/* create a session key */ /* Create a session key */
dek = xtrycalloc (1, sizeof *dek); /* hmmm: should we put it into secmem?*/ dek = xtrycalloc_secure (1, sizeof *dek);
if (!dek) if (!dek)
rc = OUT_OF_CORE (errno); rc = OUT_OF_CORE (errno);
else else

View File

@ -669,7 +669,7 @@ export_p12 (const unsigned char *certimg, size_t certimglen,
protect tool to figure out better error codes for protect tool to figure out better error codes for
CHILD_ERR. */ CHILD_ERR. */
buffer[pos++] = c; buffer[pos++] = c;
if (pos >= 5 /*sizeof buffer - 1*/ || c == '\n') if (pos >= sizeof buffer - 5 || c == '\n')
{ {
buffer[pos - (c == '\n')] = 0; buffer[pos - (c == '\n')] = 0;
if (cont_line) if (cont_line)

View File

@ -1197,11 +1197,17 @@ main ( int argc, char **argv)
set_debug (debug_level); set_debug (debug_level);
/* FIXME: should set filenames of libgcrypt explicitly /* Although we alwasy use gpgsm_exit, we better install a regualr
* gpg_opt_homedir = opt.homedir; */ exit handler so that at least the secure memory gets wiped
out. */
if (atexit (emergency_cleanup))
{
log_error ("atexit failed\n");
gpgsm_exit (2);
}
/* must do this after dropping setuid, because the mapping functions /* Must do this after dropping setuid, because the mapping functions
may try to load an module and we may have disabled an algorithm */ may try to load an module and we may have disabled an algorithm. */
if ( !gcry_cipher_map_name (opt.def_cipher_algoid) if ( !gcry_cipher_map_name (opt.def_cipher_algoid)
|| !gcry_cipher_mode_from_oid (opt.def_cipher_algoid)) || !gcry_cipher_mode_from_oid (opt.def_cipher_algoid))
log_error (_("selected cipher algorithm is invalid\n")); log_error (_("selected cipher algorithm is invalid\n"));
@ -1218,7 +1224,7 @@ main ( int argc, char **argv)
if (log_get_errorcount(0)) if (log_get_errorcount(0))
gpgsm_exit(2); gpgsm_exit(2);
/* set the random seed file */ /* Set the random seed file. */
if (use_random_seed) { if (use_random_seed) {
char *p = make_filename (opt.homedir, "random_seed", NULL); char *p = make_filename (opt.homedir, "random_seed", NULL);
gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p); gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);

View File

@ -412,7 +412,7 @@ lock_all (KEYDB_HANDLE hd)
int i, rc = 0; int i, rc = 0;
/* Fixme: This locking scheme may lead to deadlock if the resources /* Fixme: This locking scheme may lead to deadlock if the resources
are not added in the same order all processes. We are are not added in the same order by all processes. We are
currently only allowing one resource so it is not a problem. */ currently only allowing one resource so it is not a problem. */
for (i=0; i < hd->used; i++) for (i=0; i < hd->used; i++)
{ {
@ -1051,7 +1051,7 @@ classify_user_id (const char *name,
* we set it to the correct value right at the end of this function */ * we set it to the correct value right at the end of this function */
memset (desc, 0, sizeof *desc); memset (desc, 0, sizeof *desc);
*force_exact = 0; *force_exact = 0;
/* skip leading spaces. Fixme: what about trailing white space? */ /* Skip leading spaces. Fixme: what about trailing white space? */
for(s = name; *s && spacep (s); s++ ) for(s = name; *s && spacep (s); s++ )
; ;

View File

@ -456,8 +456,8 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
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 /* Fixme do this for all signers and get the algo to use from
the signer's certificate - does not make mich sense, bu we the signer's certificate - does not make mich sense, but we
should do this consistent as we have already done it above */ should do this consistent as we have already done it above. */
algo = GCRY_MD_SHA1; algo = GCRY_MD_SHA1;
hash_data (data_fd, data_md); hash_data (data_fd, data_md);
digest = gcry_md_read (data_md, algo); digest = gcry_md_read (data_md, algo);

View File

@ -86,7 +86,6 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
int i, rc; int i, rc;
Base64Context b64reader = NULL; Base64Context b64reader = NULL;
Base64Context b64writer = NULL; Base64Context b64writer = NULL;
gpg_error_t err;
ksba_reader_t reader; ksba_reader_t reader;
ksba_writer_t writer = NULL; ksba_writer_t writer = NULL;
ksba_cms_t cms = NULL; ksba_cms_t cms = NULL;
@ -135,19 +134,15 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
} }
} }
err = ksba_cms_new (&cms); rc = ksba_cms_new (&cms);
if (err) if (rc)
{ goto leave;
rc = gpg_error (GPG_ERR_ENOMEM);
goto leave;
}
err = ksba_cms_set_reader_writer (cms, reader, writer); rc = ksba_cms_set_reader_writer (cms, reader, writer);
if (err) if (rc)
{ {
log_error ("ksba_cms_set_reader_writer failed: %s\n", log_error ("ksba_cms_set_reader_writer failed: %s\n",
gpg_strerror (err)); gpg_strerror (rc));
rc = err;
goto leave; goto leave;
} }
@ -163,11 +158,10 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
is_detached = 0; is_detached = 0;
do do
{ {
err = ksba_cms_parse (cms, &stopreason); rc = ksba_cms_parse (cms, &stopreason);
if (err) if (rc)
{ {
log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (err)); log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
rc = err;
goto leave; goto leave;
} }
@ -238,7 +232,6 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
} }
cert = NULL; cert = NULL;
err = 0;
for (signer=0; ; signer++) for (signer=0; ; signer++)
{ {
char *issuer = NULL; char *issuer = NULL;
@ -249,18 +242,18 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
size_t msgdigestlen; size_t msgdigestlen;
char *ctattr; char *ctattr;
err = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial); rc = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial);
if (!signer && gpg_err_code (err) == GPG_ERR_NO_DATA if (!signer && gpg_err_code (rc) == GPG_ERR_NO_DATA
&& data_fd == -1 && is_detached) && data_fd == -1 && is_detached)
{ {
log_info ("certs-only message accepted\n"); log_info ("certs-only message accepted\n");
err = 0; rc = 0;
break; break;
} }
if (err) if (rc)
{ {
if (signer && err == -1) if (signer && rc == -1)
err = 0; rc = 0;
break; break;
} }
@ -275,19 +268,18 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
log_printf ("\n"); log_printf ("\n");
} }
err = ksba_cms_get_signing_time (cms, signer, sigtime); rc = ksba_cms_get_signing_time (cms, signer, sigtime);
if (gpg_err_code (err) == GPG_ERR_NO_DATA) if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
*sigtime = 0; *sigtime = 0;
else if (err) else if (rc)
{ {
log_error ("error getting signing time: %s\n", gpg_strerror (err)); log_error ("error getting signing time: %s\n", gpg_strerror (rc));
*sigtime = 0; /* FIXME: we can't encode an error in the time *sigtime = 0; /* (we can't encode an error in the time string.) */
string. */
} }
err = ksba_cms_get_message_digest (cms, signer, rc = ksba_cms_get_message_digest (cms, signer,
&msgdigest, &msgdigestlen); &msgdigest, &msgdigestlen);
if (!err) if (!rc)
{ {
size_t is_enabled; size_t is_enabled;
@ -304,24 +296,26 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
goto next_signer; goto next_signer;
} }
} }
else if (gpg_err_code (err) == GPG_ERR_NO_DATA) else if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
{ {
assert (!msgdigest); assert (!msgdigest);
err = 0; rc = 0;
algoid = NULL; algoid = NULL;
algo = 0; algo = 0;
} }
else /* real error */ else /* real error */
break; break;
err = ksba_cms_get_sigattr_oids (cms, signer, rc = ksba_cms_get_sigattr_oids (cms, signer,
"1.2.840.113549.1.9.3",&ctattr); "1.2.840.113549.1.9.3", &ctattr);
if (!err) if (!rc)
{ {
const char *s; const char *s;
if (DBG_X509) if (DBG_X509)
log_debug ("signer %d - content-type attribute: %s", signer, ctattr); log_debug ("signer %d - content-type attribute: %s",
signer, ctattr);
s = ksba_cms_get_content_oid (cms, 1); s = ksba_cms_get_content_oid (cms, 1);
if (!s || strcmp (ctattr, s)) if (!s || strcmp (ctattr, s))
{ {
@ -334,13 +328,13 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
ksba_free (ctattr); ksba_free (ctattr);
ctattr = NULL; ctattr = NULL;
} }
else if (err != -1) else if (rc != -1)
{ {
log_error ("error getting content-type attribute: %s\n", log_error ("error getting content-type attribute: %s\n",
gpg_strerror (err)); gpg_strerror (rc));
goto next_signer; goto next_signer;
} }
err = 0; rc = 0;
sigval = ksba_cms_get_sig_val (cms, signer); sigval = ksba_cms_get_sig_val (cms, signer);
@ -523,13 +517,6 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
cert = NULL; cert = NULL;
} }
rc = 0; rc = 0;
if (err)
{ /* FIXME: still needed? */
log_error ("ksba error: %s\n", gpg_strerror (err));
rc = err;
}
leave: leave:
ksba_cms_release (cms); ksba_cms_release (cms);