mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-26 15:37:03 +01:00
* gpgsm.c (emergency_cleanup): New.
(main): Initialize the signal handler. * sign.c (gpgsm_sign): Reset the hash context for subsequent signers and release it at the end.
This commit is contained in:
parent
1d81b994b8
commit
850a4d5214
27
sm/ChangeLog
27
sm/ChangeLog
@ -1,3 +1,30 @@
|
||||
2002-08-09 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* gpgsm.c (emergency_cleanup): New.
|
||||
(main): Initialize the signal handler.
|
||||
|
||||
* sign.c (gpgsm_sign): Reset the hash context for subsequent
|
||||
signers and release it at the end.
|
||||
|
||||
2002-08-05 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* server.c (cmd_signer): New command "SIGNER"
|
||||
(register_commands): Register it.
|
||||
(cmd_sign): Pass the signer list to gpgsm_sign.
|
||||
* certlist.c (gpgsm_add_to_certlist): Add SECRET argument, check
|
||||
for secret key if set and changed all callers.
|
||||
* sign.c (gpgsm_sign): New argument SIGNERLIST and implemt
|
||||
multiple signers.
|
||||
* gpgsm.c (main): Support more than one -u.
|
||||
|
||||
* server.c (cmd_recipient): Return reason code 1 for No_Public_Key
|
||||
which is actually what gets returned from add_to_certlist.
|
||||
|
||||
2002-07-26 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* certcheck.c (gpgsm_check_cert_sig): Implement proper cleanup.
|
||||
(gpgsm_check_cms_signature): Ditto.
|
||||
|
||||
2002-07-22 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* keydb.c (keydb_add_resource): Register a lock file.
|
||||
|
@ -138,12 +138,16 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
|
||||
if (!n)
|
||||
{
|
||||
log_error ("libksba did not return a proper S-Exp\n");
|
||||
gcry_md_close (md);
|
||||
ksba_free (p);
|
||||
return GNUPG_Bug;
|
||||
}
|
||||
rc = gcry_sexp_sscan ( &s_sig, NULL, p, n);
|
||||
ksba_free (p);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc));
|
||||
gcry_md_close (md);
|
||||
return map_gcry_err (rc);
|
||||
}
|
||||
|
||||
@ -152,29 +156,42 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
|
||||
if (!n)
|
||||
{
|
||||
log_error ("libksba did not return a proper S-Exp\n");
|
||||
gcry_md_close (md);
|
||||
ksba_free (p);
|
||||
gcry_sexp_release (s_sig);
|
||||
return GNUPG_Bug;
|
||||
}
|
||||
rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n);
|
||||
ksba_free (p);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc));
|
||||
gcry_md_close (md);
|
||||
gcry_sexp_release (s_sig);
|
||||
return map_gcry_err (rc);
|
||||
}
|
||||
|
||||
rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame);
|
||||
if (rc)
|
||||
{
|
||||
/* fixme: clean up some things */
|
||||
gcry_md_close (md);
|
||||
gcry_sexp_release (s_sig);
|
||||
gcry_sexp_release (s_pkey);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* put hash into the S-Exp s_hash */
|
||||
if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) )
|
||||
BUG ();
|
||||
|
||||
gcry_mpi_release (frame);
|
||||
|
||||
rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
|
||||
if (DBG_CRYPTO)
|
||||
log_debug ("gcry_pk_verify: %s\n", gcry_strerror (rc));
|
||||
gcry_md_close (md);
|
||||
gcry_sexp_release (s_sig);
|
||||
gcry_sexp_release (s_hash);
|
||||
gcry_sexp_release (s_pkey);
|
||||
return map_gcry_err (rc);
|
||||
}
|
||||
|
||||
@ -208,15 +225,19 @@ gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval,
|
||||
if (!n)
|
||||
{
|
||||
log_error ("libksba did not return a proper S-Exp\n");
|
||||
ksba_free (p);
|
||||
gcry_sexp_release (s_sig);
|
||||
return GNUPG_Bug;
|
||||
}
|
||||
if (DBG_X509)
|
||||
log_printhex ("public key: ", p, n);
|
||||
|
||||
rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n);
|
||||
ksba_free (p);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc));
|
||||
gcry_sexp_release (s_sig);
|
||||
return map_gcry_err (rc);
|
||||
}
|
||||
|
||||
@ -224,17 +245,22 @@ gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval,
|
||||
rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame);
|
||||
if (rc)
|
||||
{
|
||||
/* fixme: clean up some things */
|
||||
gcry_sexp_release (s_sig);
|
||||
gcry_sexp_release (s_pkey);
|
||||
return rc;
|
||||
}
|
||||
/* put hash into the S-Exp s_hash */
|
||||
if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) )
|
||||
BUG ();
|
||||
|
||||
gcry_mpi_release (frame);
|
||||
|
||||
|
||||
rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
|
||||
if (DBG_CRYPTO)
|
||||
log_debug ("gcry_pk_verify: %s\n", gcry_strerror (rc));
|
||||
gcry_sexp_release (s_sig);
|
||||
gcry_sexp_release (s_hash);
|
||||
gcry_sexp_release (s_sig);
|
||||
return map_gcry_err (rc);
|
||||
}
|
||||
|
||||
|
@ -133,10 +133,12 @@ same_subject_issuer (const char *subject, const char *issuer, KsbaCert cert)
|
||||
|
||||
|
||||
|
||||
/* add a certificate to a list of certificate and make sure that it is
|
||||
a valid certificate */
|
||||
/* Add a certificate to a list of certificate and make sure that it is
|
||||
a valid certificate. With SECRET set to true a secret key must be
|
||||
avaibale for the certificate. */
|
||||
int
|
||||
gpgsm_add_to_certlist (CTRL ctrl, const char *name, CERTLIST *listaddr)
|
||||
gpgsm_add_to_certlist (CTRL ctrl, const char *name, int secret,
|
||||
CERTLIST *listaddr)
|
||||
{
|
||||
int rc;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
@ -161,7 +163,8 @@ gpgsm_add_to_certlist (CTRL ctrl, const char *name, CERTLIST *listaddr)
|
||||
rc = keydb_get_cert (kh, &cert);
|
||||
if (!rc)
|
||||
{
|
||||
rc = gpgsm_cert_use_encrypt_p (cert);
|
||||
rc = secret? gpgsm_cert_use_sign_p (cert)
|
||||
: gpgsm_cert_use_encrypt_p (cert);
|
||||
if (rc == GNUPG_Wrong_Key_Usage)
|
||||
{
|
||||
/* There might be another certificate with the
|
||||
@ -206,7 +209,8 @@ gpgsm_add_to_certlist (CTRL ctrl, const char *name, CERTLIST *listaddr)
|
||||
if (!keydb_get_cert (kh, &cert2))
|
||||
{
|
||||
int tmp = (same_subject_issuer (subject, issuer, cert2)
|
||||
&& (gpgsm_cert_use_encrypt_p (cert2)
|
||||
&& ((secret? gpgsm_cert_use_sign_p (cert2):
|
||||
gpgsm_cert_use_encrypt_p (cert2))
|
||||
== GNUPG_Wrong_Key_Usage));
|
||||
ksba_cert_release (cert2);
|
||||
if (tmp)
|
||||
@ -218,6 +222,19 @@ gpgsm_add_to_certlist (CTRL ctrl, const char *name, CERTLIST *listaddr)
|
||||
xfree (subject);
|
||||
xfree (issuer);
|
||||
|
||||
if (!rc && secret)
|
||||
{
|
||||
char *p;
|
||||
|
||||
rc = GNUPG_No_Secret_Key;
|
||||
p = gpgsm_get_keygrip_hexstring (cert);
|
||||
if (p)
|
||||
{
|
||||
if (!gpgsm_agent_havekey (p))
|
||||
rc = 0;
|
||||
xfree (p);
|
||||
}
|
||||
}
|
||||
if (!rc)
|
||||
rc = gpgsm_validate_path (ctrl, cert, NULL);
|
||||
if (!rc)
|
||||
|
143
sm/gpgsm.c
143
sm/gpgsm.c
@ -403,6 +403,7 @@ static char *build_list (const char *text,
|
||||
static void set_cmd (enum cmd_and_opt_values *ret_cmd,
|
||||
enum cmd_and_opt_values new_cmd );
|
||||
|
||||
static void emergency_cleanup (void);
|
||||
static int check_special_filename (const char *fname);
|
||||
static int open_read (const char *filename);
|
||||
static FILE *open_fwrite (const char *filename);
|
||||
@ -601,6 +602,7 @@ main ( int argc, char **argv)
|
||||
enum cmd_and_opt_values cmd = 0;
|
||||
struct server_control_s ctrl;
|
||||
CERTLIST recplist = NULL;
|
||||
CERTLIST signerlist = NULL;
|
||||
|
||||
/* trap_unaligned ();*/
|
||||
set_strusage (my_strusage);
|
||||
@ -626,7 +628,7 @@ main ( int argc, char **argv)
|
||||
|
||||
may_coredump = disable_core_dumps ();
|
||||
|
||||
/* Fixme: init_signals();*/
|
||||
gnupg_init_signals (0, emergency_cleanup);
|
||||
|
||||
create_dotlock (NULL); /* register locking cleanup */
|
||||
i18n_init();
|
||||
@ -922,9 +924,10 @@ main ( int argc, char **argv)
|
||||
case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break;
|
||||
case oTextmode: /*fixme:opt.textmode=1;*/ break;
|
||||
|
||||
case oUser: /* store the local users */
|
||||
opt.local_user = pargs.r.ret_str;
|
||||
add_to_strlist ( &locusr, pargs.r.ret_str);
|
||||
case oUser: /* store the local users, the first one is the default */
|
||||
if (!opt.local_user)
|
||||
opt.local_user = pargs.r.ret_str;
|
||||
add_to_strlist (&locusr, pargs.r.ret_str);
|
||||
break;
|
||||
|
||||
case oNoSecmemWarn:
|
||||
@ -1059,15 +1062,39 @@ main ( int argc, char **argv)
|
||||
keydb_add_resource (sl->d, 0, 0);
|
||||
FREE_STRLIST(nrings);
|
||||
|
||||
|
||||
for (sl = locusr; sl; sl = sl->next)
|
||||
{
|
||||
int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 1, &signerlist);
|
||||
if (rc)
|
||||
{
|
||||
log_error (_("can't sign using `%s': %s\n"),
|
||||
sl->d, gnupg_strerror (rc));
|
||||
gpgsm_status2 (&ctrl, STATUS_INV_RECP,
|
||||
rc == -1? "1":
|
||||
rc == GNUPG_No_Public_Key? "1":
|
||||
rc == GNUPG_Ambiguous_Name? "2":
|
||||
rc == GNUPG_Wrong_Key_Usage? "3":
|
||||
rc == GNUPG_Certificate_Revoked? "4":
|
||||
rc == GNUPG_Certificate_Expired? "5":
|
||||
rc == GNUPG_No_CRL_Known? "6":
|
||||
rc == GNUPG_CRL_Too_Old? "7":
|
||||
rc == GNUPG_No_Policy_Match? "8":
|
||||
rc == GNUPG_No_Secret_Key? "9":
|
||||
"0",
|
||||
sl->d, NULL);
|
||||
}
|
||||
}
|
||||
for (sl = remusr; sl; sl = sl->next)
|
||||
{
|
||||
int rc = gpgsm_add_to_certlist (&ctrl, sl->d, &recplist);
|
||||
int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 0, &recplist);
|
||||
if (rc)
|
||||
{
|
||||
log_error (_("can't encrypt to `%s': %s\n"),
|
||||
sl->d, gnupg_strerror (rc));
|
||||
gpgsm_status2 (&ctrl, STATUS_INV_RECP,
|
||||
rc == -1? "1":
|
||||
rc == GNUPG_No_Public_Key? "1":
|
||||
rc == GNUPG_Ambiguous_Name? "2":
|
||||
rc == GNUPG_Wrong_Key_Usage? "3":
|
||||
rc == GNUPG_Certificate_Revoked? "4":
|
||||
@ -1109,69 +1136,25 @@ main ( int argc, char **argv)
|
||||
break;
|
||||
|
||||
case aSign: /* sign the given file */
|
||||
/* FIXME: W we don't handle --output yet. We should also allow
|
||||
/* FIXME: We don't handle --output yet. We should also allow
|
||||
to concatenate multiple files for signing because that is
|
||||
what gpg does.*/
|
||||
if (!argc)
|
||||
gpgsm_sign (&ctrl, 0, detached_sig, stdout); /* create from stdin */
|
||||
gpgsm_sign (&ctrl, signerlist,
|
||||
0, detached_sig, stdout); /* create from stdin */
|
||||
else if (argc == 1)
|
||||
gpgsm_sign (&ctrl, open_read (*argv),
|
||||
detached_sig, stdout); /* from file */
|
||||
gpgsm_sign (&ctrl, signerlist,
|
||||
open_read (*argv), detached_sig, stdout); /* from file */
|
||||
else
|
||||
wrong_args (_("--sign [datafile]"));
|
||||
break;
|
||||
#if 0
|
||||
sl = NULL;
|
||||
if (detached_sig)
|
||||
{ /* sign all files */
|
||||
for (; argc; argc--, argv++ )
|
||||
add_to_strlist ( &sl, *argv );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (argc > 1 )
|
||||
wrong_args (_("--sign [filename]"));
|
||||
if (argc)
|
||||
{
|
||||
sl = xcalloc (1, sizeof *sl + strlen(fname));
|
||||
strcpy(sl->d, fname);
|
||||
}
|
||||
}
|
||||
if ( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
|
||||
log_error ("signing failed: %s\n", gpg_errstr(rc) );
|
||||
free_strlist(sl);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case aSignEncr: /* sign and encrypt the given file */
|
||||
log_error ("this command has not yet been implemented\n");
|
||||
#if 0
|
||||
if (argc > 1)
|
||||
wrong_args(_("--sign --encrypt [filename]"));
|
||||
if (argc)
|
||||
{
|
||||
sl = xcalloc( 1, sizeof *sl + strlen(fname));
|
||||
strcpy(sl->d, fname);
|
||||
}
|
||||
else
|
||||
sl = NULL;
|
||||
|
||||
if ( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
|
||||
log_error ("%s: sign+encrypt failed: %s\n",
|
||||
print_fname_stdin(fname), gpg_errstr(rc) );
|
||||
free_strlist(sl);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case aClearsign: /* make a clearsig */
|
||||
log_error ("this command has not yet been implemented\n");
|
||||
#if 0
|
||||
if (argc > 1)
|
||||
wrong_args (_("--clearsign [filename]"));
|
||||
if ( (rc = clearsign_file(fname, locusr, NULL)) )
|
||||
log_error ("%s: clearsign failed: %s\n",
|
||||
print_fname_stdin(fname), gpg_errstr(rc) );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case aVerify:
|
||||
@ -1199,8 +1182,6 @@ main ( int argc, char **argv)
|
||||
|
||||
case aVerifyFiles:
|
||||
log_error ("this command has not yet been implemented\n");
|
||||
/* if ((rc = verify_files( argc, argv ))) */
|
||||
/* log_error ("verify files failed: %s\n", gpg_errstr(rc) ); */
|
||||
break;
|
||||
|
||||
case aDecrypt:
|
||||
@ -1244,18 +1225,6 @@ main ( int argc, char **argv)
|
||||
|
||||
case aKeygen: /* generate a key */
|
||||
log_error ("this function is not yet available from the commandline\n");
|
||||
/* if (opt.batch) */
|
||||
/* { */
|
||||
/* if (argc > 1) */
|
||||
/* wrong_args("--gen-key [parameterfile]"); */
|
||||
/* generate_keypair (argc? *argv : NULL); */
|
||||
/* } */
|
||||
/* else */
|
||||
/* { */
|
||||
/* if (argc) */
|
||||
/* wrong_args ("--gen-key"); */
|
||||
/* generate_keypair(NULL); */
|
||||
/* } */
|
||||
break;
|
||||
|
||||
case aImport:
|
||||
@ -1279,16 +1248,6 @@ main ( int argc, char **argv)
|
||||
case aSendKeys:
|
||||
case aRecvKeys:
|
||||
log_error ("this command has not yet been implemented\n");
|
||||
/* sl = NULL; */
|
||||
/* for ( ; argc; argc--, argv++ ) */
|
||||
/* add_to_strlist (&sl, *argv); */
|
||||
/* if ( cmd == aSendKeys ) */
|
||||
/* ldap_export (sl); */
|
||||
/* else if (cmd == aRecvKeys ) */
|
||||
/* ldap_import (sl); */
|
||||
/* else */
|
||||
/* export_pubkeys (sl, (cmd == aExport)); */
|
||||
/* free_strlist (sl); */
|
||||
break;
|
||||
|
||||
|
||||
@ -1305,34 +1264,26 @@ main ( int argc, char **argv)
|
||||
|
||||
|
||||
default:
|
||||
log_error ("invalid command\n");
|
||||
#if 0
|
||||
if (argc > 1)
|
||||
wrong_args(_("[filename]"));
|
||||
/* Issue some output for the unix newbie */
|
||||
if ( !fname && !opt.outfile && isatty( fileno(stdin) )
|
||||
&& isatty (fileno(stdout) ) && isatty (fileno(stderr) ) )
|
||||
log_info (_("Go ahead and type your message ...\n"));
|
||||
|
||||
if ( !(a = iobuf_open(fname)) )
|
||||
log_error (_("can't open `%s'\n"), print_fname_stdin(fname));
|
||||
else
|
||||
{
|
||||
if (!opt.no_armor)
|
||||
iobuf_close(a);
|
||||
}
|
||||
#endif
|
||||
log_error ("invalid command (there is no implicit command)\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
gpgsm_release_certlist (recplist);
|
||||
gpgsm_release_certlist (signerlist);
|
||||
FREE_STRLIST(remusr);
|
||||
FREE_STRLIST(locusr);
|
||||
gpgsm_exit(0);
|
||||
return 8; /*NEVER REACHED*/
|
||||
}
|
||||
|
||||
/* Note: This function is used by signal handlers!. */
|
||||
static void
|
||||
emergency_cleanup (void)
|
||||
{
|
||||
gcry_control (GCRYCTL_TERM_SECMEM );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gpgsm_exit (int rc)
|
||||
@ -1351,7 +1302,7 @@ gpgsm_exit (int rc)
|
||||
if (opt.debug)
|
||||
gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
|
||||
#endif
|
||||
gcry_control (GCRYCTL_TERM_SECMEM );
|
||||
emergency_cleanup ();
|
||||
rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0;
|
||||
exit (rc);
|
||||
}
|
||||
|
@ -197,7 +197,8 @@ int gpgsm_cert_use_encrypt_p (KsbaCert cert);
|
||||
int gpgsm_cert_use_verify_p (KsbaCert cert);
|
||||
int gpgsm_cert_use_decrypt_p (KsbaCert cert);
|
||||
int gpgsm_cert_use_cert_p (KsbaCert cert);
|
||||
int gpgsm_add_to_certlist (CTRL ctrl, const char *name, CERTLIST *listaddr);
|
||||
int gpgsm_add_to_certlist (CTRL ctrl, const char *name, int secret,
|
||||
CERTLIST *listaddr);
|
||||
void gpgsm_release_certlist (CERTLIST list);
|
||||
int gpgsm_find_cert (const char *name, KsbaCert *r_cert);
|
||||
|
||||
@ -218,7 +219,8 @@ int gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp);
|
||||
|
||||
/*-- sign.c --*/
|
||||
int gpgsm_get_default_cert (KsbaCert *r_cert);
|
||||
int gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp);
|
||||
int gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
|
||||
int data_fd, int detached, FILE *out_fp);
|
||||
|
||||
/*-- encrypt.c --*/
|
||||
int gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int in_fd, FILE *out_fp);
|
||||
|
54
sm/server.c
54
sm/server.c
@ -43,6 +43,7 @@ struct server_local_s {
|
||||
int list_internal;
|
||||
int list_external;
|
||||
CERTLIST recplist;
|
||||
CERTLIST signerlist;
|
||||
};
|
||||
|
||||
|
||||
@ -182,7 +183,9 @@ reset_notify (ASSUAN_CONTEXT ctx)
|
||||
CTRL ctrl = assuan_get_pointer (ctx);
|
||||
|
||||
gpgsm_release_certlist (ctrl->server_local->recplist);
|
||||
gpgsm_release_certlist (ctrl->server_local->signerlist);
|
||||
ctrl->server_local->recplist = NULL;
|
||||
ctrl->server_local->signerlist = NULL;
|
||||
close_message_fd (ctrl);
|
||||
assuan_close_input_fd (ctx);
|
||||
assuan_close_output_fd (ctx);
|
||||
@ -239,10 +242,11 @@ cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
|
||||
CTRL ctrl = assuan_get_pointer (ctx);
|
||||
int rc;
|
||||
|
||||
rc = gpgsm_add_to_certlist (ctrl, line, &ctrl->server_local->recplist);
|
||||
rc = gpgsm_add_to_certlist (ctrl, line, 0, &ctrl->server_local->recplist);
|
||||
if (rc)
|
||||
gpgsm_status2 (ctrl, STATUS_INV_RECP,
|
||||
rc == -1? "1":
|
||||
rc == GNUPG_No_Public_Key? "1":
|
||||
rc == GNUPG_Ambiguous_Name? "2":
|
||||
rc == GNUPG_Wrong_Key_Usage? "3":
|
||||
rc == GNUPG_Certificate_Revoked? "4":
|
||||
@ -256,6 +260,47 @@ cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
|
||||
return map_to_assuan_status (rc);
|
||||
}
|
||||
|
||||
/* SIGNER <userID>
|
||||
|
||||
Set the signer's keys for the signature creation. <userID> should
|
||||
be the internal representation of the key; the server may accept any
|
||||
other way of specification [we will support this]. If this is a
|
||||
valid and usable signing key the server does respond with OK,
|
||||
otherwise it returns an ERR with the reason why the key can't be
|
||||
used, the signing will then not be done for this key. If the policy
|
||||
is not to sign at all if not all signer keys are valid, the client
|
||||
has to take care of this. All SIGNER commands are cumulative until
|
||||
a RESET but they are *not* reset by an SIGN command becuase it can
|
||||
be expected that set of signers are used for more than one sign
|
||||
operation.
|
||||
|
||||
Note that this command returns an INV_RECP status which is a bit
|
||||
strange, but they are very similar. */
|
||||
static int
|
||||
cmd_signer (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
CTRL ctrl = assuan_get_pointer (ctx);
|
||||
int rc;
|
||||
|
||||
rc = gpgsm_add_to_certlist (ctrl, line, 1, &ctrl->server_local->signerlist);
|
||||
if (rc)
|
||||
gpgsm_status2 (ctrl, STATUS_INV_RECP,
|
||||
rc == -1? "1":
|
||||
rc == GNUPG_No_Public_Key? "1":
|
||||
rc == GNUPG_Ambiguous_Name? "2":
|
||||
rc == GNUPG_Wrong_Key_Usage? "3":
|
||||
rc == GNUPG_Certificate_Revoked? "4":
|
||||
rc == GNUPG_Certificate_Expired? "5":
|
||||
rc == GNUPG_No_CRL_Known? "6":
|
||||
rc == GNUPG_CRL_Too_Old? "7":
|
||||
rc == GNUPG_No_Policy_Match? "8":
|
||||
rc == GNUPG_No_Secret_Key? "9":
|
||||
"0",
|
||||
line, NULL);
|
||||
|
||||
return map_to_assuan_status (rc);
|
||||
}
|
||||
|
||||
|
||||
/* ENCRYPT
|
||||
|
||||
@ -407,7 +452,9 @@ cmd_sign (ASSUAN_CONTEXT ctx, char *line)
|
||||
out_fp = fdopen ( dup(out_fd), "w");
|
||||
if (!out_fp)
|
||||
return set_error (General_Error, "fdopen() failed");
|
||||
rc = gpgsm_sign (assuan_get_pointer (ctx), inp_fd, detached, out_fp);
|
||||
|
||||
rc = gpgsm_sign (assuan_get_pointer (ctx), ctrl->server_local->signerlist,
|
||||
inp_fd, detached, out_fp);
|
||||
fclose (out_fp);
|
||||
|
||||
/* close and reset the fd */
|
||||
@ -676,6 +723,7 @@ register_commands (ASSUAN_CONTEXT ctx)
|
||||
int (*handler)(ASSUAN_CONTEXT, char *line);
|
||||
} table[] = {
|
||||
{ "RECIPIENT", 0, cmd_recipient },
|
||||
{ "SIGNER", 0, cmd_signer },
|
||||
{ "ENCRYPT", 0, cmd_encrypt },
|
||||
{ "DECRYPT", 0, cmd_decrypt },
|
||||
{ "VERIFY", 0, cmd_verify },
|
||||
@ -776,6 +824,8 @@ gpgsm_server (void)
|
||||
|
||||
gpgsm_release_certlist (ctrl.server_local->recplist);
|
||||
ctrl.server_local->recplist = NULL;
|
||||
gpgsm_release_certlist (ctrl.server_local->signerlist);
|
||||
ctrl.server_local->signerlist = NULL;
|
||||
|
||||
assuan_deinit_server (ctx);
|
||||
}
|
||||
|
247
sm/sign.c
247
sm/sign.c
@ -1,5 +1,5 @@
|
||||
/* sign.c - Sign a message
|
||||
* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -228,8 +228,6 @@ get_default_signer (void)
|
||||
return cert;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Depending on the options in CTRL add the certificate CERT as well as
|
||||
other certificate up in the chain to the Root-CA to the CMS
|
||||
object. */
|
||||
@ -290,10 +288,11 @@ add_certificate_list (CTRL ctrl, KsbaCMS cms, KsbaCert cert)
|
||||
|
||||
Sign the data received on DATA-FD in embedded mode or in detached
|
||||
mode when DETACHED is true. Write the signature to OUT_FP. The
|
||||
key used to sign is the default one - we will extend the function
|
||||
to take a list of fingerprints in the future. */
|
||||
keys used to sign are taken from SIGNERLIST or the default one will
|
||||
be used if the value of this argument is NULL. */
|
||||
int
|
||||
gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
|
||||
gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
|
||||
int data_fd, int detached, FILE *out_fp)
|
||||
{
|
||||
int i, rc;
|
||||
KsbaError err;
|
||||
@ -301,13 +300,14 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
|
||||
KsbaWriter writer;
|
||||
KsbaCMS cms = NULL;
|
||||
KsbaStopReason stopreason;
|
||||
KsbaCert cert = NULL;
|
||||
KEYDB_HANDLE kh = NULL;
|
||||
GCRY_MD_HD data_md = NULL;
|
||||
int signer;
|
||||
const char *algoid;
|
||||
int algo;
|
||||
time_t signed_at;
|
||||
CERTLIST cl;
|
||||
int release_signerlist = 0;
|
||||
|
||||
kh = keydb_new (0);
|
||||
if (!kh)
|
||||
@ -353,47 +353,60 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
|
||||
/* gather certificates of signers and store in theCMS object */
|
||||
/* fixme: process a list of fingerprints and store the certificate of
|
||||
each given fingerprint */
|
||||
cert = get_default_signer ();
|
||||
if (!cert)
|
||||
/* If no list of signers is given, use a default one. */
|
||||
if (!signerlist)
|
||||
{
|
||||
log_error ("no default signer found\n");
|
||||
rc = seterr (General_Error);
|
||||
goto leave;
|
||||
KsbaCert cert = get_default_signer ();
|
||||
if (!cert)
|
||||
{
|
||||
log_error ("no default signer found\n");
|
||||
rc = seterr (General_Error);
|
||||
goto leave;
|
||||
}
|
||||
signerlist = xtrycalloc (1, sizeof *signerlist);
|
||||
if (!signerlist)
|
||||
{
|
||||
rc = GNUPG_Out_Of_Core;
|
||||
ksba_cert_release (cert);
|
||||
goto leave;
|
||||
}
|
||||
signerlist->cert = cert;
|
||||
release_signerlist = 1;
|
||||
}
|
||||
rc = gpgsm_cert_use_sign_p (cert);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
err = ksba_cms_add_signer (cms, cert);
|
||||
if (err)
|
||||
{
|
||||
log_error ("ksba_cms_add_signer failed: %s\n", ksba_strerror (err));
|
||||
rc = map_ksba_err (err);
|
||||
goto leave;
|
||||
}
|
||||
rc = add_certificate_list (ctrl, cms, cert);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to store list of certificates: %s\n",
|
||||
gnupg_strerror(rc));
|
||||
goto leave;
|
||||
}
|
||||
ksba_cert_release (cert); cert = NULL;
|
||||
|
||||
/* Gather certificates of signers and store them in the CMS object. */
|
||||
for (cl=signerlist; cl; cl = cl->next)
|
||||
{
|
||||
rc = gpgsm_cert_use_sign_p (cl->cert);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
err = ksba_cms_add_signer (cms, cl->cert);
|
||||
if (err)
|
||||
{
|
||||
log_error ("ksba_cms_add_signer failed: %s\n", ksba_strerror (err));
|
||||
rc = map_ksba_err (err);
|
||||
goto leave;
|
||||
}
|
||||
rc = add_certificate_list (ctrl, cms, cl->cert);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to store list of certificates: %s\n",
|
||||
gnupg_strerror(rc));
|
||||
goto leave;
|
||||
}
|
||||
/* Set the hash algorithm we are going to use */
|
||||
err = ksba_cms_add_digest_algo (cms, "1.3.14.3.2.26" /*SHA-1*/);
|
||||
if (err)
|
||||
{
|
||||
log_debug ("ksba_cms_add_digest_algo failed: %s\n",
|
||||
ksba_strerror (err));
|
||||
rc = map_ksba_err (err);
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the hash algorithm we are going to use */
|
||||
err = ksba_cms_add_digest_algo (cms, "1.3.14.3.2.26" /*SHA-1*/);
|
||||
if (err)
|
||||
{
|
||||
log_debug ("ksba_cms_add_digest_algo failed: %s\n", ksba_strerror (err));
|
||||
rc = map_ksba_err (err);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Prepare hashing (actually we are figuring out what we have set above)*/
|
||||
data_md = gcry_md_open (0, 0);
|
||||
if (!data_md)
|
||||
@ -417,7 +430,6 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
|
||||
gcry_md_enable (data_md, algo);
|
||||
}
|
||||
|
||||
signer = 0;
|
||||
if (detached)
|
||||
{ /* we hash the data right now so that we can store the message
|
||||
digest. ksba_cms_build() takes this as an flag that detached
|
||||
@ -437,24 +449,30 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
|
||||
rc = GNUPG_Bug;
|
||||
goto leave;
|
||||
}
|
||||
err = ksba_cms_set_message_digest (cms, signer, digest, digest_len);
|
||||
if (err)
|
||||
for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
|
||||
{
|
||||
log_error ("ksba_cms_set_message_digest failed: %s\n",
|
||||
ksba_strerror (err));
|
||||
rc = map_ksba_err (err);
|
||||
goto leave;
|
||||
err = ksba_cms_set_message_digest (cms, signer, digest, digest_len);
|
||||
if (err)
|
||||
{
|
||||
log_error ("ksba_cms_set_message_digest failed: %s\n",
|
||||
ksba_strerror (err));
|
||||
rc = map_ksba_err (err);
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signed_at = gnupg_get_time ();
|
||||
err = ksba_cms_set_signing_time (cms, signer, signed_at);
|
||||
if (err)
|
||||
for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
|
||||
{
|
||||
log_error ("ksba_cms_set_signing_time failed: %s\n",
|
||||
ksba_strerror (err));
|
||||
rc = map_ksba_err (err);
|
||||
goto leave;
|
||||
err = ksba_cms_set_signing_time (cms, signer, signed_at);
|
||||
if (err)
|
||||
{
|
||||
log_error ("ksba_cms_set_signing_time failed: %s\n",
|
||||
ksba_strerror (err));
|
||||
rc = map_ksba_err (err);
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
@ -473,10 +491,10 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
|
||||
size_t digest_len;
|
||||
|
||||
assert (!detached);
|
||||
/* Fixme do this for all signers and get the algo to use from
|
||||
the signer's certificate - does not make mich sense, bu we
|
||||
should do this consistent as we have already done it above.
|
||||
Code is mostly duplicated above. */
|
||||
/* 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);
|
||||
@ -490,13 +508,17 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
|
||||
rc = GNUPG_Bug;
|
||||
goto leave;
|
||||
}
|
||||
err = ksba_cms_set_message_digest (cms, signer, digest, digest_len);
|
||||
if (err)
|
||||
for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
|
||||
{
|
||||
log_error ("ksba_cms_set_message_digest failed: %s\n",
|
||||
ksba_strerror (err));
|
||||
rc = map_ksba_err (err);
|
||||
goto leave;
|
||||
err = ksba_cms_set_message_digest (cms, signer,
|
||||
digest, digest_len);
|
||||
if (err)
|
||||
{
|
||||
log_error ("ksba_cms_set_message_digest failed: %s\n",
|
||||
ksba_strerror (err));
|
||||
rc = map_ksba_err (err);
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (stopreason == KSBA_SR_NEED_SIG)
|
||||
@ -504,7 +526,6 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
|
||||
GCRY_MD_HD md;
|
||||
|
||||
algo = GCRY_MD_SHA1;
|
||||
signer = 0;
|
||||
md = gcry_md_open (algo, 0);
|
||||
if (DBG_HASHING)
|
||||
gcry_md_start_debug (md, "sign.attr");
|
||||
@ -515,70 +536,67 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
|
||||
goto leave;
|
||||
}
|
||||
ksba_cms_set_hash_function (cms, HASH_FNC, md);
|
||||
rc = ksba_cms_hash_signed_attrs (cms, signer);
|
||||
if (rc)
|
||||
{
|
||||
log_debug ("hashing signed attrs failed: %s\n",
|
||||
ksba_strerror (rc));
|
||||
gcry_md_close (md);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
{ /* This is all an temporary hack */
|
||||
char *sigval;
|
||||
|
||||
ksba_cert_release (cert);
|
||||
cert = get_default_signer ();
|
||||
if (!cert)
|
||||
{
|
||||
log_error ("oops - failed to get cert again\n");
|
||||
rc = seterr (General_Error);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
sigval = NULL;
|
||||
rc = gpgsm_create_cms_signature (cert, md, algo, &sigval);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
err = ksba_cms_set_sig_val (cms, signer, sigval);
|
||||
xfree (sigval);
|
||||
if (err)
|
||||
{
|
||||
log_error ("failed to store the signature: %s\n",
|
||||
ksba_strerror (err));
|
||||
rc = map_ksba_err (err);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* And write a status message */
|
||||
for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
|
||||
{
|
||||
char *sigval = NULL;
|
||||
char *buf, *fpr;
|
||||
|
||||
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
|
||||
|
||||
if (signer)
|
||||
gcry_md_reset (md);
|
||||
rc = ksba_cms_hash_signed_attrs (cms, signer);
|
||||
if (rc)
|
||||
{
|
||||
log_debug ("hashing signed attrs failed: %s\n",
|
||||
ksba_strerror (rc));
|
||||
gcry_md_close (md);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
rc = gpgsm_create_cms_signature (cl->cert, md, algo, &sigval);
|
||||
if (rc)
|
||||
{
|
||||
gcry_md_close (md);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
err = ksba_cms_set_sig_val (cms, signer, sigval);
|
||||
xfree (sigval);
|
||||
if (err)
|
||||
{
|
||||
log_error ("failed to store the signature: %s\n",
|
||||
ksba_strerror (err));
|
||||
rc = map_ksba_err (err);
|
||||
gcry_md_close (md);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* write a status message */
|
||||
fpr = gpgsm_get_fingerprint_hexstring (cl->cert, GCRY_MD_SHA1);
|
||||
if (!fpr)
|
||||
{
|
||||
rc = seterr (Out_Of_Core);
|
||||
gcry_md_close (md);
|
||||
goto leave;
|
||||
}
|
||||
rc = asprintf (&buf, "%c %d %d 00 %lu %s",
|
||||
detached? 'D':'S',
|
||||
GCRY_PK_RSA, /* FIXME: get pk algo from cert */
|
||||
algo,
|
||||
(ulong)signed_at,
|
||||
fpr);
|
||||
detached? 'D':'S',
|
||||
GCRY_PK_RSA, /* FIXME: get pk algo from cert */
|
||||
algo,
|
||||
(ulong)signed_at,
|
||||
fpr);
|
||||
xfree (fpr);
|
||||
if (rc < 0)
|
||||
{
|
||||
rc = seterr (Out_Of_Core);
|
||||
gcry_md_close (md);
|
||||
goto leave;
|
||||
}
|
||||
rc = 0;
|
||||
gpgsm_status (ctrl, STATUS_SIG_CREATED, buf );
|
||||
gpgsm_status (ctrl, STATUS_SIG_CREATED, buf);
|
||||
free (buf); /* yes, we must use the regular free() here */
|
||||
}
|
||||
gcry_md_close (md);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
while (stopreason != KSBA_SR_READY);
|
||||
@ -594,7 +612,8 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
|
||||
|
||||
|
||||
leave:
|
||||
ksba_cert_release (cert);
|
||||
if (release_signerlist)
|
||||
gpgsm_release_certlist (signerlist);
|
||||
ksba_cms_release (cms);
|
||||
gpgsm_destroy_writer (b64writer);
|
||||
keydb_release (kh);
|
||||
|
10
sm/verify.c
10
sm/verify.c
@ -1,5 +1,5 @@
|
||||
/* verify.c - Verify a messages signature
|
||||
* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -248,7 +248,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
|
||||
|
||||
cert = NULL;
|
||||
err = 0;
|
||||
for (signer=0; signer < 1; signer++)
|
||||
for (signer=0; ; signer++)
|
||||
{
|
||||
char *issuer = NULL;
|
||||
KsbaSexp sigval = NULL;
|
||||
@ -265,7 +265,11 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
|
||||
break;
|
||||
}
|
||||
if (err)
|
||||
break;
|
||||
{
|
||||
if (signer && err == -1)
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
if (DBG_X509)
|
||||
{
|
||||
log_debug ("signer %d - issuer: `%s'\n",
|
||||
|
Loading…
x
Reference in New Issue
Block a user