1997-12-31 13:32:54 +01:00
|
|
|
/* sign.c - sign data
|
2003-05-21 10:48:26 +02:00
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
|
|
|
* 2003 Free Software Foundation, Inc.
|
1997-12-31 13:32:54 +01:00
|
|
|
*
|
1998-12-23 13:41:40 +01:00
|
|
|
* This file is part of GnuPG.
|
1997-12-31 13:32:54 +01:00
|
|
|
*
|
1998-12-23 13:41:40 +01:00
|
|
|
* GnuPG is free software; you can redistribute it and/or modify
|
1997-12-31 13:32:54 +01:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
1998-12-23 13:41:40 +01:00
|
|
|
* GnuPG is distributed in the hope that it will be useful,
|
1997-12-31 13:32:54 +01:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <assert.h>
|
2002-06-29 15:46:34 +02:00
|
|
|
#include <unistd.h> /* need sleep() */
|
1997-12-31 13:32:54 +01:00
|
|
|
|
|
|
|
#include "options.h"
|
|
|
|
#include "packet.h"
|
|
|
|
#include "errors.h"
|
|
|
|
#include "iobuf.h"
|
|
|
|
#include "keydb.h"
|
2002-06-29 15:46:34 +02:00
|
|
|
#include "memory.h"
|
1997-12-31 13:32:54 +01:00
|
|
|
#include "util.h"
|
|
|
|
#include "main.h"
|
|
|
|
#include "filter.h"
|
|
|
|
#include "ttyio.h"
|
1998-08-05 18:51:59 +02:00
|
|
|
#include "trustdb.h"
|
2000-07-14 19:34:53 +02:00
|
|
|
#include "status.h"
|
1998-03-05 10:22:13 +01:00
|
|
|
#include "i18n.h"
|
1997-12-31 13:32:54 +01:00
|
|
|
|
|
|
|
|
2000-07-14 19:34:53 +02:00
|
|
|
#ifdef HAVE_DOSISH_SYSTEM
|
* armor.c, g10.c, kbnode.c, misc.c, pkclist.c, sign.c, build-packet.c,
getkey.c, keydb.c, openfile.c, plaintext.c, status.c, gpgv.c, keygen.c,
options.h, sig-check.c, tdbio.h, encode.c, mainproc.c, parse-packet.c,
signal.c, textfilter.c: Edit all preprocessor instructions to remove
whitespace before the '#'. This is not required by C89, but there are some
compilers out there that don't like it.
2003-05-24 23:50:33 +02:00
|
|
|
#define LF "\r\n"
|
|
|
|
void __stdcall Sleep(ulong);
|
|
|
|
#define sleep(a) Sleep((a)*1000)
|
2000-07-14 19:34:53 +02:00
|
|
|
#else
|
* armor.c, g10.c, kbnode.c, misc.c, pkclist.c, sign.c, build-packet.c,
getkey.c, keydb.c, openfile.c, plaintext.c, status.c, gpgv.c, keygen.c,
options.h, sig-check.c, tdbio.h, encode.c, mainproc.c, parse-packet.c,
signal.c, textfilter.c: Edit all preprocessor instructions to remove
whitespace before the '#'. This is not required by C89, but there are some
compilers out there that don't like it.
2003-05-24 23:50:33 +02:00
|
|
|
#define LF "\n"
|
2000-07-14 19:34:53 +02:00
|
|
|
#endif
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
static int recipient_digest_algo=0;
|
|
|
|
|
1999-11-13 17:43:23 +01:00
|
|
|
/****************
|
2002-06-29 15:46:34 +02:00
|
|
|
* Create a notation. It is assumed that the stings in STRLIST
|
|
|
|
* are already checked to contain only printable data and have a valid
|
|
|
|
* NAME=VALUE format.
|
1999-11-13 17:43:23 +01:00
|
|
|
*/
|
2002-06-29 15:46:34 +02:00
|
|
|
static void
|
2003-07-24 21:28:12 +02:00
|
|
|
mk_notation_policy_etc( PKT_signature *sig,
|
2002-06-29 15:46:34 +02:00
|
|
|
PKT_public_key *pk, PKT_secret_key *sk )
|
1999-11-13 17:43:23 +01:00
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
const char *string;
|
|
|
|
char *s=NULL;
|
|
|
|
byte *buf;
|
|
|
|
unsigned n1, n2;
|
|
|
|
STRLIST nd=NULL,pu=NULL;
|
|
|
|
struct expando_args args;
|
1999-11-13 17:43:23 +01:00
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
memset(&args,0,sizeof(args));
|
|
|
|
args.pk=pk;
|
|
|
|
args.sk=sk;
|
1999-11-13 17:43:23 +01:00
|
|
|
|
* gpgv.c: Remove extra semicolon (typo).
* options.skel: Note that keyserver.pgp.com isn't synchronized, and
explain the roundrobin a bit better.
* sig-check.c (check_key_signature2), import.c (import_one,
import_revoke_cert, chk_self_sigs, delete_inv_parts, collapse_uids,
merge_blocks): Make much quieter during import of slightly munged, but
recoverable, keys. Use log_error for unrecoverable import failures.
* keyring.c (keyring_rebuild_cache): Comment.
* sign.c (mk_notation_and_policy): Making a v3 signature with notations or
policy urls is an error, not an info (i.e. increment the errorcount).
Don't print the notation or policy url to stdout since it can be mixed
into the output stream when piping and munge the stream.
2003-08-22 01:20:58 +02:00
|
|
|
/* It is actually impossible to get here when making a v3 key
|
|
|
|
signature since keyedit.c:sign_uids will automatically bump a
|
|
|
|
signature with a notation or policy url up to v4, but it is
|
|
|
|
good to do these checks anyway. */
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
/* notation data */
|
|
|
|
if(IS_SIG(sig) && opt.sig_notation_data)
|
|
|
|
{
|
|
|
|
if(sig->version<4)
|
* gpgv.c: Remove extra semicolon (typo).
* options.skel: Note that keyserver.pgp.com isn't synchronized, and
explain the roundrobin a bit better.
* sig-check.c (check_key_signature2), import.c (import_one,
import_revoke_cert, chk_self_sigs, delete_inv_parts, collapse_uids,
merge_blocks): Make much quieter during import of slightly munged, but
recoverable, keys. Use log_error for unrecoverable import failures.
* keyring.c (keyring_rebuild_cache): Comment.
* sign.c (mk_notation_and_policy): Making a v3 signature with notations or
policy urls is an error, not an info (i.e. increment the errorcount).
Don't print the notation or policy url to stdout since it can be mixed
into the output stream when piping and munge the stream.
2003-08-22 01:20:58 +02:00
|
|
|
log_error(_("can't put notation data into v3 (PGP 2.x style) "
|
|
|
|
"signatures\n"));
|
2002-06-29 15:46:34 +02:00
|
|
|
else
|
|
|
|
nd=opt.sig_notation_data;
|
|
|
|
}
|
|
|
|
else if( IS_CERT(sig) && opt.cert_notation_data )
|
|
|
|
{
|
|
|
|
if(sig->version<4)
|
* gpgv.c: Remove extra semicolon (typo).
* options.skel: Note that keyserver.pgp.com isn't synchronized, and
explain the roundrobin a bit better.
* sig-check.c (check_key_signature2), import.c (import_one,
import_revoke_cert, chk_self_sigs, delete_inv_parts, collapse_uids,
merge_blocks): Make much quieter during import of slightly munged, but
recoverable, keys. Use log_error for unrecoverable import failures.
* keyring.c (keyring_rebuild_cache): Comment.
* sign.c (mk_notation_and_policy): Making a v3 signature with notations or
policy urls is an error, not an info (i.e. increment the errorcount).
Don't print the notation or policy url to stdout since it can be mixed
into the output stream when piping and munge the stream.
2003-08-22 01:20:58 +02:00
|
|
|
log_error(_("can't put notation data into v3 (PGP 2.x style) "
|
|
|
|
"key signatures\n"));
|
2002-06-29 15:46:34 +02:00
|
|
|
else
|
|
|
|
nd=opt.cert_notation_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( ; nd; nd = nd->next ) {
|
|
|
|
char *expanded;
|
|
|
|
|
|
|
|
string = nd->d;
|
|
|
|
s = strchr( string, '=' );
|
|
|
|
if( !s )
|
|
|
|
BUG(); /* we have already parsed this */
|
|
|
|
n1 = s - string;
|
|
|
|
s++;
|
|
|
|
|
|
|
|
expanded=pct_expando(s,&args);
|
|
|
|
if(!expanded)
|
|
|
|
{
|
|
|
|
log_error(_("WARNING: unable to %%-expand notation "
|
|
|
|
"(too large). Using unexpanded.\n"));
|
|
|
|
expanded=m_strdup(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
n2 = strlen(expanded);
|
|
|
|
buf = m_alloc( 8 + n1 + n2 );
|
|
|
|
buf[0] = 0x80; /* human readable */
|
|
|
|
buf[1] = buf[2] = buf[3] = 0;
|
|
|
|
buf[4] = n1 >> 8;
|
|
|
|
buf[5] = n1;
|
|
|
|
buf[6] = n2 >> 8;
|
|
|
|
buf[7] = n2;
|
|
|
|
memcpy(buf+8, string, n1 );
|
|
|
|
memcpy(buf+8+n1, expanded, n2 );
|
|
|
|
build_sig_subpkt( sig, SIGSUBPKT_NOTATION
|
|
|
|
| ((nd->flags & 1)? SIGSUBPKT_FLAG_CRITICAL:0),
|
|
|
|
buf, 8+n1+n2 );
|
|
|
|
m_free(expanded);
|
|
|
|
m_free(buf);
|
|
|
|
}
|
2000-07-25 17:38:12 +02:00
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
/* set policy URL */
|
|
|
|
if( IS_SIG(sig) && opt.sig_policy_url )
|
|
|
|
{
|
|
|
|
if(sig->version<4)
|
* gpgv.c: Remove extra semicolon (typo).
* options.skel: Note that keyserver.pgp.com isn't synchronized, and
explain the roundrobin a bit better.
* sig-check.c (check_key_signature2), import.c (import_one,
import_revoke_cert, chk_self_sigs, delete_inv_parts, collapse_uids,
merge_blocks): Make much quieter during import of slightly munged, but
recoverable, keys. Use log_error for unrecoverable import failures.
* keyring.c (keyring_rebuild_cache): Comment.
* sign.c (mk_notation_and_policy): Making a v3 signature with notations or
policy urls is an error, not an info (i.e. increment the errorcount).
Don't print the notation or policy url to stdout since it can be mixed
into the output stream when piping and munge the stream.
2003-08-22 01:20:58 +02:00
|
|
|
log_error(_("can't put a policy URL into v3 (PGP 2.x style) "
|
|
|
|
"signatures\n"));
|
2002-06-29 15:46:34 +02:00
|
|
|
else
|
|
|
|
pu=opt.sig_policy_url;
|
|
|
|
}
|
|
|
|
else if( IS_CERT(sig) && opt.cert_policy_url )
|
|
|
|
{
|
|
|
|
if(sig->version<4)
|
* gpgv.c: Remove extra semicolon (typo).
* options.skel: Note that keyserver.pgp.com isn't synchronized, and
explain the roundrobin a bit better.
* sig-check.c (check_key_signature2), import.c (import_one,
import_revoke_cert, chk_self_sigs, delete_inv_parts, collapse_uids,
merge_blocks): Make much quieter during import of slightly munged, but
recoverable, keys. Use log_error for unrecoverable import failures.
* keyring.c (keyring_rebuild_cache): Comment.
* sign.c (mk_notation_and_policy): Making a v3 signature with notations or
policy urls is an error, not an info (i.e. increment the errorcount).
Don't print the notation or policy url to stdout since it can be mixed
into the output stream when piping and munge the stream.
2003-08-22 01:20:58 +02:00
|
|
|
log_error(_("can't put a policy URL into v3 key (PGP 2.x style) "
|
|
|
|
"signatures\n"));
|
2002-06-29 15:46:34 +02:00
|
|
|
else
|
|
|
|
pu=opt.cert_policy_url;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(;pu;pu=pu->next)
|
|
|
|
{
|
|
|
|
string = pu->d;
|
|
|
|
|
|
|
|
s=pct_expando(string,&args);
|
|
|
|
if(!s)
|
|
|
|
{
|
|
|
|
log_error(_("WARNING: unable to %%-expand policy url "
|
|
|
|
"(too large). Using unexpanded.\n"));
|
|
|
|
s=m_strdup(string);
|
|
|
|
}
|
|
|
|
|
|
|
|
build_sig_subpkt(sig,SIGSUBPKT_POLICY|
|
|
|
|
((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0),
|
|
|
|
s,strlen(s));
|
|
|
|
|
|
|
|
m_free(s);
|
|
|
|
}
|
|
|
|
|
2003-07-24 21:28:12 +02:00
|
|
|
/* preferred keyserver URL */
|
|
|
|
if( IS_SIG(sig) && opt.sig_keyserver_url )
|
|
|
|
{
|
|
|
|
if(sig->version<4)
|
|
|
|
log_info("can't put a preferred keyserver URL into v3 signatures\n");
|
|
|
|
else
|
|
|
|
pu=opt.sig_keyserver_url;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(;pu;pu=pu->next)
|
|
|
|
{
|
|
|
|
string = pu->d;
|
|
|
|
|
|
|
|
s=pct_expando(string,&args);
|
|
|
|
if(!s)
|
|
|
|
{
|
2003-09-01 01:49:07 +02:00
|
|
|
log_error(_("WARNING: unable to %%-expand preferred keyserver URL"
|
|
|
|
" (too large). Using unexpanded.\n"));
|
2003-07-24 21:28:12 +02:00
|
|
|
s=m_strdup(string);
|
|
|
|
}
|
|
|
|
|
|
|
|
build_sig_subpkt(sig,SIGSUBPKT_PREF_KS|
|
|
|
|
((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0),
|
|
|
|
s,strlen(s));
|
|
|
|
|
|
|
|
m_free(s);
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
}
|
1999-11-13 17:43:23 +01:00
|
|
|
|
2000-07-25 17:38:12 +02:00
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
/*
|
|
|
|
* Helper to hash a user ID packet.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
hash_uid (MD_HANDLE md, int sigversion, const PKT_user_id *uid)
|
|
|
|
{
|
|
|
|
if ( sigversion >= 4 ) {
|
|
|
|
byte buf[5];
|
|
|
|
|
|
|
|
if(uid->attrib_data) {
|
|
|
|
buf[0] = 0xd1; /* indicates an attribute packet */
|
|
|
|
buf[1] = uid->attrib_len >> 24; /* always use 4 length bytes */
|
|
|
|
buf[2] = uid->attrib_len >> 16;
|
|
|
|
buf[3] = uid->attrib_len >> 8;
|
|
|
|
buf[4] = uid->attrib_len;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
buf[0] = 0xb4; /* indicates a userid packet */
|
|
|
|
buf[1] = uid->len >> 24; /* always use 4 length bytes */
|
|
|
|
buf[2] = uid->len >> 16;
|
|
|
|
buf[3] = uid->len >> 8;
|
|
|
|
buf[4] = uid->len;
|
|
|
|
}
|
|
|
|
md_write( md, buf, 5 );
|
1999-11-13 17:43:23 +01:00
|
|
|
}
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
if(uid->attrib_data)
|
|
|
|
md_write (md, uid->attrib_data, uid->attrib_len );
|
|
|
|
else
|
|
|
|
md_write (md, uid->name, uid->len );
|
1999-11-13 17:43:23 +01:00
|
|
|
}
|
1999-05-25 19:56:15 +02:00
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper to hash some parts from the signature
|
1999-05-25 19:56:15 +02:00
|
|
|
*/
|
|
|
|
static void
|
2002-06-29 15:46:34 +02:00
|
|
|
hash_sigversion_to_magic (MD_HANDLE md, const PKT_signature *sig)
|
1999-05-25 19:56:15 +02:00
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
if (sig->version >= 4)
|
|
|
|
md_putc (md, sig->version);
|
|
|
|
md_putc (md, sig->sig_class);
|
|
|
|
if (sig->version < 4) {
|
|
|
|
u32 a = sig->timestamp;
|
|
|
|
md_putc (md, (a >> 24) & 0xff );
|
|
|
|
md_putc (md, (a >> 16) & 0xff );
|
|
|
|
md_putc (md, (a >> 8) & 0xff );
|
|
|
|
md_putc (md, a & 0xff );
|
1999-05-25 19:56:15 +02:00
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
else {
|
|
|
|
byte buf[6];
|
|
|
|
size_t n;
|
|
|
|
|
|
|
|
md_putc (md, sig->pubkey_algo);
|
|
|
|
md_putc (md, sig->digest_algo);
|
|
|
|
if (sig->hashed) {
|
|
|
|
n = sig->hashed->len;
|
|
|
|
md_putc (md, (n >> 8) );
|
|
|
|
md_putc (md, n );
|
|
|
|
md_write (md, sig->hashed->data, n );
|
|
|
|
n += 6;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
md_putc (md, 0); /* always hash the length of the subpacket*/
|
|
|
|
md_putc (md, 0);
|
|
|
|
n = 6;
|
|
|
|
}
|
|
|
|
/* add some magic */
|
|
|
|
buf[0] = sig->version;
|
|
|
|
buf[1] = 0xff;
|
|
|
|
buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
|
|
|
|
buf[3] = n >> 16;
|
|
|
|
buf[4] = n >> 8;
|
|
|
|
buf[5] = n;
|
|
|
|
md_write (md, buf, 6);
|
1999-05-25 19:56:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-06-13 08:59:14 +02:00
|
|
|
static int
|
1998-06-29 14:30:57 +02:00
|
|
|
do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
2002-06-29 15:46:34 +02:00
|
|
|
MD_HANDLE md, int digest_algo )
|
1998-06-13 08:59:14 +02:00
|
|
|
{
|
|
|
|
MPI frame;
|
|
|
|
byte *dp;
|
|
|
|
int rc;
|
|
|
|
|
1999-01-12 11:20:24 +01:00
|
|
|
if( sk->timestamp > sig->timestamp ) {
|
|
|
|
ulong d = sk->timestamp - sig->timestamp;
|
|
|
|
log_info( d==1 ? _("key has been created %lu second "
|
|
|
|
"in future (time warp or clock problem)\n")
|
|
|
|
: _("key has been created %lu seconds "
|
|
|
|
"in future (time warp or clock problem)\n"), d );
|
2000-07-14 19:34:53 +02:00
|
|
|
if( !opt.ignore_time_conflict )
|
2002-06-29 15:46:34 +02:00
|
|
|
return G10ERR_TIME_CONFLICT;
|
1999-01-12 11:20:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-12-10 20:20:47 +01:00
|
|
|
print_pubkey_algo_note(sk->pubkey_algo);
|
1998-07-06 12:23:57 +02:00
|
|
|
|
1998-06-13 08:59:14 +02:00
|
|
|
if( !digest_algo )
|
2002-06-29 15:46:34 +02:00
|
|
|
digest_algo = md_get_algo(md);
|
1998-06-13 08:59:14 +02:00
|
|
|
|
1998-12-10 20:20:47 +01:00
|
|
|
print_digest_algo_note( digest_algo );
|
2002-06-29 15:46:34 +02:00
|
|
|
dp = md_read( md, digest_algo );
|
1998-06-13 08:59:14 +02:00
|
|
|
sig->digest_algo = digest_algo;
|
|
|
|
sig->digest_start[0] = dp[0];
|
|
|
|
sig->digest_start[1] = dp[1];
|
1998-06-29 14:30:57 +02:00
|
|
|
frame = encode_md_value( sk->pubkey_algo, md,
|
2002-06-29 15:46:34 +02:00
|
|
|
digest_algo, mpi_get_nbits(sk->skey[0]), 0 );
|
|
|
|
if (!frame)
|
|
|
|
return G10ERR_GENERAL;
|
|
|
|
rc = pubkey_sign( sk->pubkey_algo, sig->data, frame, sk->skey );
|
|
|
|
mpi_free(frame);
|
|
|
|
if (!rc && !opt.no_sig_create_check) {
|
|
|
|
/* check that the signature verification worked and nothing is
|
|
|
|
* fooling us e.g. by a bug in the signature create
|
|
|
|
* code or by deliberately introduced faults. */
|
|
|
|
PKT_public_key *pk = m_alloc_clear (sizeof *pk);
|
|
|
|
|
|
|
|
if( get_pubkey( pk, sig->keyid ) )
|
|
|
|
rc = G10ERR_NO_PUBKEY;
|
|
|
|
else {
|
|
|
|
frame = encode_md_value (pk->pubkey_algo, md,
|
|
|
|
sig->digest_algo,
|
|
|
|
mpi_get_nbits(pk->pkey[0]), 0);
|
|
|
|
if (!frame)
|
|
|
|
rc = G10ERR_GENERAL;
|
|
|
|
else
|
|
|
|
rc = pubkey_verify (pk->pubkey_algo, frame,
|
|
|
|
sig->data, pk->pkey,
|
|
|
|
NULL, NULL );
|
|
|
|
mpi_free (frame);
|
|
|
|
}
|
|
|
|
if (rc)
|
|
|
|
log_error (_("checking created signature failed: %s\n"),
|
|
|
|
g10_errstr (rc));
|
|
|
|
free_public_key (pk);
|
|
|
|
}
|
1998-06-13 08:59:14 +02:00
|
|
|
if( rc )
|
2002-06-29 15:46:34 +02:00
|
|
|
log_error(_("signing failed: %s\n"), g10_errstr(rc) );
|
1998-06-13 08:59:14 +02:00
|
|
|
else {
|
|
|
|
if( opt.verbose ) {
|
2002-08-19 10:28:00 +02:00
|
|
|
char *ustr = get_user_id_string_printable (sig->keyid);
|
2003-04-26 22:38:16 +02:00
|
|
|
log_info(_("%s/%s signature from: \"%s\"\n"),
|
|
|
|
pubkey_algo_to_string(sk->pubkey_algo),
|
|
|
|
digest_algo_to_string(sig->digest_algo),
|
|
|
|
ustr );
|
2002-06-29 15:46:34 +02:00
|
|
|
m_free(ustr);
|
1998-06-13 08:59:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1997-12-31 13:32:54 +01:00
|
|
|
|
1998-04-09 13:19:09 +02:00
|
|
|
int
|
2002-06-29 15:46:34 +02:00
|
|
|
complete_sig( PKT_signature *sig, PKT_secret_key *sk, MD_HANDLE md )
|
1997-12-31 13:32:54 +01:00
|
|
|
{
|
|
|
|
int rc=0;
|
|
|
|
|
1998-09-11 07:47:32 +02:00
|
|
|
if( !(rc=check_secret_key( sk, 0 )) )
|
1998-06-29 14:30:57 +02:00
|
|
|
rc = do_sign( sk, sig, md, 0 );
|
1997-12-31 13:32:54 +01:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
1998-05-15 20:49:19 +02:00
|
|
|
static int
|
2000-10-04 13:16:19 +02:00
|
|
|
hash_for(int pubkey_algo, int packet_version )
|
1998-05-15 20:49:19 +02:00
|
|
|
{
|
2002-11-25 05:06:04 +01:00
|
|
|
if( opt.def_digest_algo )
|
|
|
|
return opt.def_digest_algo;
|
|
|
|
else if( recipient_digest_algo )
|
|
|
|
return recipient_digest_algo;
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
else if(PGP2 && pubkey_algo == PUBKEY_ALGO_RSA && packet_version < 4 )
|
2002-11-25 05:06:04 +01:00
|
|
|
{
|
|
|
|
/* Old-style PGP only understands MD5 */
|
|
|
|
return DIGEST_ALGO_MD5;
|
|
|
|
}
|
|
|
|
else if( pubkey_algo == PUBKEY_ALGO_DSA )
|
|
|
|
{
|
|
|
|
/* We need a 160-bit hash for DSA, so we can't just take the first
|
|
|
|
in the pref list */
|
|
|
|
|
|
|
|
if(opt.personal_digest_prefs)
|
|
|
|
{
|
|
|
|
prefitem_t *prefs;
|
|
|
|
|
|
|
|
for(prefs=opt.personal_digest_prefs;prefs->type;prefs++)
|
|
|
|
if(md_digest_length(prefs->value)==20)
|
|
|
|
return prefs->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return DIGEST_ALGO_SHA1;
|
|
|
|
}
|
|
|
|
else if( opt.personal_digest_prefs )
|
|
|
|
{
|
|
|
|
/* It's not DSA, so we can use whatever the first hash algorithm
|
|
|
|
is in the pref list */
|
|
|
|
return opt.personal_digest_prefs[0].value;
|
|
|
|
}
|
|
|
|
else
|
1998-05-15 20:49:19 +02:00
|
|
|
return DEFAULT_DIGEST_ALGO;
|
|
|
|
}
|
1997-12-31 13:32:54 +01:00
|
|
|
|
1998-06-25 12:19:08 +02:00
|
|
|
static int
|
1998-06-29 14:30:57 +02:00
|
|
|
only_old_style( SK_LIST sk_list )
|
1998-06-25 12:19:08 +02:00
|
|
|
{
|
1998-06-29 14:30:57 +02:00
|
|
|
SK_LIST sk_rover = NULL;
|
1998-06-25 12:19:08 +02:00
|
|
|
int old_style = 0;
|
1997-12-31 13:32:54 +01:00
|
|
|
|
1998-06-25 12:19:08 +02:00
|
|
|
/* if there are only old style capable key we use the old sytle */
|
1998-06-29 14:30:57 +02:00
|
|
|
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
|
|
|
PKT_secret_key *sk = sk_rover->sk;
|
2002-06-29 15:46:34 +02:00
|
|
|
if( sk->pubkey_algo == PUBKEY_ALGO_RSA && sk->version < 4 )
|
1998-06-25 12:19:08 +02:00
|
|
|
old_style = 1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return old_style;
|
|
|
|
}
|
1997-12-31 13:32:54 +01:00
|
|
|
|
1998-08-05 18:51:59 +02:00
|
|
|
|
2000-07-14 19:34:53 +02:00
|
|
|
static void
|
|
|
|
print_status_sig_created ( PKT_secret_key *sk, PKT_signature *sig, int what )
|
|
|
|
{
|
|
|
|
byte array[MAX_FINGERPRINT_LEN], *p;
|
|
|
|
char buf[100+MAX_FINGERPRINT_LEN*2];
|
|
|
|
size_t i, n;
|
|
|
|
|
|
|
|
sprintf(buf, "%c %d %d %02x %lu ",
|
|
|
|
what, sig->pubkey_algo, sig->digest_algo, sig->sig_class,
|
|
|
|
(ulong)sig->timestamp );
|
|
|
|
|
|
|
|
fingerprint_from_sk( sk, array, &n );
|
|
|
|
p = buf + strlen(buf);
|
|
|
|
for(i=0; i < n ; i++ )
|
|
|
|
sprintf(p+2*i, "%02X", array[i] );
|
|
|
|
|
|
|
|
write_status_text( STATUS_SIG_CREATED, buf );
|
|
|
|
}
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Loop over the secret certificates in SK_LIST and build the one pass
|
|
|
|
* signature packets. OpenPGP says that the data should be bracket by
|
|
|
|
* the onepass-sig and signature-packet; so we build these onepass
|
|
|
|
* packet here in reverse order
|
|
|
|
*/
|
2000-10-04 13:16:19 +02:00
|
|
|
static int
|
2002-06-29 15:46:34 +02:00
|
|
|
write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass )
|
2000-10-04 13:16:19 +02:00
|
|
|
{
|
2002-06-29 15:46:34 +02:00
|
|
|
int skcount;
|
|
|
|
SK_LIST sk_rover;
|
2000-10-04 13:16:19 +02:00
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
for (skcount=0, sk_rover=sk_list; sk_rover; sk_rover = sk_rover->next)
|
|
|
|
skcount++;
|
2000-10-04 13:16:19 +02:00
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
for (; skcount; skcount--) {
|
|
|
|
PKT_secret_key *sk;
|
|
|
|
PKT_onepass_sig *ops;
|
|
|
|
PACKET pkt;
|
|
|
|
int i, rc;
|
2000-10-04 13:16:19 +02:00
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
for (i=0, sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
|
|
|
if (++i == skcount)
|
|
|
|
break;
|
2000-10-04 13:16:19 +02:00
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
sk = sk_rover->sk;
|
|
|
|
ops = m_alloc_clear (sizeof *ops);
|
|
|
|
ops->sig_class = sigclass;
|
|
|
|
ops->digest_algo = hash_for (sk->pubkey_algo, sk->version);
|
|
|
|
ops->pubkey_algo = sk->pubkey_algo;
|
|
|
|
keyid_from_sk (sk, ops->keyid);
|
|
|
|
ops->last = (skcount == 1);
|
|
|
|
|
|
|
|
init_packet(&pkt);
|
|
|
|
pkt.pkttype = PKT_ONEPASS_SIG;
|
|
|
|
pkt.pkt.onepass_sig = ops;
|
|
|
|
rc = build_packet (out, &pkt);
|
|
|
|
free_packet (&pkt);
|
|
|
|
if (rc) {
|
|
|
|
log_error ("build onepass_sig packet failed: %s\n",
|
|
|
|
g10_errstr(rc));
|
|
|
|
return rc;
|
2000-10-04 13:16:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2000-10-04 13:16:19 +02:00
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
/*
|
|
|
|
* Helper to write the plaintext (literal data) packet
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
write_plaintext_packet (IOBUF out, IOBUF inp, const char *fname, int ptmode)
|
|
|
|
{
|
|
|
|
PKT_plaintext *pt = NULL;
|
|
|
|
u32 filesize;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
if (!opt.no_literal) {
|
|
|
|
if (fname || opt.set_filename) {
|
|
|
|
char *s = make_basename (opt.set_filename? opt.set_filename
|
2002-10-29 15:37:12 +01:00
|
|
|
: fname,
|
|
|
|
iobuf_get_real_fname(inp));
|
2002-06-29 15:46:34 +02:00
|
|
|
pt = m_alloc (sizeof *pt + strlen(s) - 1);
|
|
|
|
pt->namelen = strlen (s);
|
|
|
|
memcpy (pt->name, s, pt->namelen);
|
|
|
|
m_free (s);
|
|
|
|
}
|
|
|
|
else { /* no filename */
|
|
|
|
pt = m_alloc (sizeof *pt - 1);
|
|
|
|
pt->namelen = 0;
|
2000-10-04 13:16:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
/* try to calculate the length of the data */
|
2003-05-21 10:48:26 +02:00
|
|
|
if (fname && *fname && !(*fname=='-' && !fname[1])) {
|
2002-06-29 15:46:34 +02:00
|
|
|
if( !(filesize = iobuf_get_filelength(inp)) )
|
|
|
|
log_info (_("WARNING: `%s' is an empty file\n"), fname);
|
|
|
|
|
|
|
|
/* we can't yet encode the length of very large files,
|
|
|
|
* so we switch to partial length encoding in this case */
|
|
|
|
if (filesize >= IOBUF_FILELENGTH_LIMIT)
|
|
|
|
filesize = 0;
|
|
|
|
|
|
|
|
/* because the text_filter modifies the length of the
|
|
|
|
* data, it is not possible to know the used length
|
|
|
|
* without a double read of the file - to avoid that
|
|
|
|
* we simple use partial length packets.
|
|
|
|
*/
|
|
|
|
if ( ptmode == 't' )
|
|
|
|
filesize = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
filesize = opt.set_filesize? opt.set_filesize : 0; /* stdin */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!opt.no_literal) {
|
|
|
|
PACKET pkt;
|
|
|
|
|
|
|
|
pt->timestamp = make_timestamp ();
|
|
|
|
pt->mode = ptmode;
|
|
|
|
pt->len = filesize;
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
pt->new_ctb = !pt->len && !RFC1991;
|
2002-06-29 15:46:34 +02:00
|
|
|
pt->buf = inp;
|
|
|
|
init_packet(&pkt);
|
|
|
|
pkt.pkttype = PKT_PLAINTEXT;
|
|
|
|
pkt.pkt.plaintext = pt;
|
|
|
|
/*cfx.datalen = filesize? calc_packet_length( &pkt ) : 0;*/
|
|
|
|
if( (rc = build_packet (out, &pkt)) )
|
|
|
|
log_error ("build_packet(PLAINTEXT) failed: %s\n",
|
|
|
|
g10_errstr(rc) );
|
|
|
|
pt->buf = NULL;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
byte copy_buffer[4096];
|
|
|
|
int bytes_copied;
|
|
|
|
|
|
|
|
while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
|
|
|
|
if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
|
|
|
|
rc = G10ERR_WRITE_FILE;
|
|
|
|
log_error ("copying input to output failed: %s\n",
|
|
|
|
g10_errstr(rc));
|
|
|
|
break;
|
|
|
|
}
|
2002-10-31 16:40:42 +01:00
|
|
|
wipememory(copy_buffer,4096); /* burn buffer */
|
2002-06-29 15:46:34 +02:00
|
|
|
}
|
|
|
|
/* fixme: it seems that we never freed pt/pkt */
|
|
|
|
|
2000-10-04 13:16:19 +02:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
/*
|
|
|
|
* Write the signatures from the SK_LIST to OUT. HASH must be a non-finalized
|
|
|
|
* hash which will not be changes here.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
write_signature_packets (SK_LIST sk_list, IOBUF out, MD_HANDLE hash,
|
|
|
|
int sigclass, u32 timestamp, u32 duration,
|
|
|
|
int status_letter)
|
|
|
|
{
|
|
|
|
SK_LIST sk_rover;
|
|
|
|
|
|
|
|
/* loop over the secret certificates */
|
|
|
|
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) {
|
|
|
|
PKT_secret_key *sk;
|
|
|
|
PKT_signature *sig;
|
|
|
|
MD_HANDLE md;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
sk = sk_rover->sk;
|
|
|
|
|
|
|
|
/* build the signature packet */
|
|
|
|
sig = m_alloc_clear (sizeof *sig);
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
if(opt.force_v3_sigs || RFC1991)
|
2002-06-29 15:46:34 +02:00
|
|
|
sig->version=3;
|
2003-07-24 21:28:12 +02:00
|
|
|
else if(duration || opt.sig_policy_url
|
|
|
|
|| opt.sig_notation_data || opt.sig_keyserver_url)
|
2002-06-29 15:46:34 +02:00
|
|
|
sig->version=4;
|
|
|
|
else
|
|
|
|
sig->version=sk->version;
|
|
|
|
keyid_from_sk (sk, sig->keyid);
|
|
|
|
sig->digest_algo = hash_for (sk->pubkey_algo, sk->version);
|
|
|
|
sig->pubkey_algo = sk->pubkey_algo;
|
|
|
|
if(timestamp)
|
|
|
|
sig->timestamp = timestamp;
|
|
|
|
else
|
|
|
|
sig->timestamp = make_timestamp();
|
|
|
|
if(duration)
|
|
|
|
sig->expiredate = sig->timestamp+duration;
|
|
|
|
sig->sig_class = sigclass;
|
|
|
|
|
|
|
|
md = md_copy (hash);
|
|
|
|
|
|
|
|
if (sig->version >= 4)
|
|
|
|
build_sig_subpkt_from_sig (sig);
|
2003-07-24 21:28:12 +02:00
|
|
|
mk_notation_policy_etc (sig, NULL, sk);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
hash_sigversion_to_magic (md, sig);
|
|
|
|
md_final (md);
|
|
|
|
|
|
|
|
rc = do_sign( sk, sig, md, hash_for (sig->pubkey_algo, sk->version) );
|
|
|
|
md_close (md);
|
|
|
|
|
|
|
|
if( !rc ) { /* and write it */
|
|
|
|
PACKET pkt;
|
|
|
|
|
|
|
|
init_packet(&pkt);
|
|
|
|
pkt.pkttype = PKT_SIGNATURE;
|
|
|
|
pkt.pkt.signature = sig;
|
|
|
|
rc = build_packet (out, &pkt);
|
|
|
|
if (!rc && is_status_enabled()) {
|
|
|
|
print_status_sig_created ( sk, sig, status_letter);
|
|
|
|
}
|
|
|
|
free_packet (&pkt);
|
|
|
|
if (rc)
|
|
|
|
log_error ("build signature packet failed: %s\n",
|
|
|
|
g10_errstr(rc) );
|
|
|
|
}
|
|
|
|
if( rc )
|
|
|
|
return rc;;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
1998-08-05 18:51:59 +02:00
|
|
|
|
1997-12-31 13:32:54 +01:00
|
|
|
/****************
|
1998-01-13 20:04:23 +01:00
|
|
|
* Sign the files whose names are in FILENAME.
|
|
|
|
* If DETACHED has the value true,
|
|
|
|
* make a detached signature. If FILENAMES->d is NULL read from stdin
|
1997-12-31 13:32:54 +01:00
|
|
|
* and ignore the detached mode. Sign the file with all secret keys
|
|
|
|
* which can be taken from LOCUSR, if this is NULL, use the default one
|
2002-06-29 15:46:34 +02:00
|
|
|
* If ENCRYPTFLAG is true, use REMUSER (or ask if it is NULL) to encrypt the
|
1997-12-31 13:32:54 +01:00
|
|
|
* signed data for these users.
|
1998-01-13 20:04:23 +01:00
|
|
|
* If OUTFILE is not NULL; this file is used for output and the function
|
|
|
|
* does not ask for overwrite permission; output is then always
|
|
|
|
* uncompressed, non-armored and in binary mode.
|
1997-12-31 13:32:54 +01:00
|
|
|
*/
|
|
|
|
int
|
1998-01-13 20:04:23 +01:00
|
|
|
sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
2002-06-29 15:46:34 +02:00
|
|
|
int encryptflag, STRLIST remusr, const char *outfile )
|
1997-12-31 13:32:54 +01:00
|
|
|
{
|
1998-01-13 20:04:23 +01:00
|
|
|
const char *fname;
|
1997-12-31 13:32:54 +01:00
|
|
|
armor_filter_context_t afx;
|
|
|
|
compress_filter_context_t zfx;
|
|
|
|
md_filter_context_t mfx;
|
|
|
|
text_filter_context_t tfx;
|
2003-04-15 17:46:13 +02:00
|
|
|
progress_filter_context_t pfx;
|
1998-01-02 21:40:10 +01:00
|
|
|
encrypt_filter_context_t efx;
|
1997-12-31 13:32:54 +01:00
|
|
|
IOBUF inp = NULL, out = NULL;
|
|
|
|
PACKET pkt;
|
1998-01-16 22:15:24 +01:00
|
|
|
int rc = 0;
|
1998-06-29 14:30:57 +02:00
|
|
|
PK_LIST pk_list = NULL;
|
|
|
|
SK_LIST sk_list = NULL;
|
|
|
|
SK_LIST sk_rover = NULL;
|
1998-01-13 20:04:23 +01:00
|
|
|
int multifile = 0;
|
2003-04-05 00:48:24 +02:00
|
|
|
u32 duration=0;
|
1997-12-31 13:32:54 +01:00
|
|
|
|
|
|
|
memset( &afx, 0, sizeof afx);
|
|
|
|
memset( &zfx, 0, sizeof zfx);
|
|
|
|
memset( &mfx, 0, sizeof mfx);
|
1998-01-02 21:40:10 +01:00
|
|
|
memset( &efx, 0, sizeof efx);
|
1997-12-31 13:32:54 +01:00
|
|
|
init_packet( &pkt );
|
|
|
|
|
1998-01-13 20:04:23 +01:00
|
|
|
if( filenames ) {
|
|
|
|
fname = filenames->d;
|
|
|
|
multifile = !!filenames->next;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fname = NULL;
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
if( fname && filenames->next && (!detached || encryptflag) )
|
1998-01-13 20:04:23 +01:00
|
|
|
log_bug("multiple files can only be detached signed");
|
|
|
|
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991)
|
2002-06-29 15:46:34 +02:00
|
|
|
duration=ask_expire_interval(1);
|
|
|
|
|
|
|
|
if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) )
|
1997-12-31 13:32:54 +01:00
|
|
|
goto leave;
|
1998-10-21 19:34:36 +02:00
|
|
|
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
if(PGP2 && !only_old_style(sk_list))
|
2002-06-29 15:46:34 +02:00
|
|
|
{
|
|
|
|
log_info(_("you can only detach-sign with PGP 2.x style keys "
|
|
|
|
"while in --pgp2 mode\n"));
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
compliance_failure();
|
2002-06-29 15:46:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if(encryptflag && (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )))
|
|
|
|
goto leave;
|
1997-12-31 13:32:54 +01:00
|
|
|
|
|
|
|
/* prepare iobufs */
|
1998-01-13 20:04:23 +01:00
|
|
|
if( multifile ) /* have list of filenames */
|
|
|
|
inp = NULL; /* we do it later */
|
2003-04-15 17:46:13 +02:00
|
|
|
else {
|
|
|
|
if( !(inp = iobuf_open(fname)) ) {
|
|
|
|
log_error("can't open %s: %s\n", fname? fname: "[stdin]",
|
|
|
|
strerror(errno) );
|
|
|
|
rc = G10ERR_OPEN_FILE;
|
|
|
|
goto leave;
|
|
|
|
}
|
|
|
|
|
|
|
|
handle_progress (&pfx, inp, fname);
|
1997-12-31 13:32:54 +01:00
|
|
|
}
|
|
|
|
|
1998-01-13 20:04:23 +01:00
|
|
|
if( outfile ) {
|
|
|
|
if( !(out = iobuf_create( outfile )) ) {
|
1998-11-10 13:59:59 +01:00
|
|
|
log_error(_("can't create %s: %s\n"), outfile, strerror(errno) );
|
2002-06-29 15:46:34 +02:00
|
|
|
rc = G10ERR_CREATE_FILE;
|
1998-01-13 20:04:23 +01:00
|
|
|
goto leave;
|
|
|
|
}
|
|
|
|
else if( opt.verbose )
|
1998-12-29 14:47:31 +01:00
|
|
|
log_info(_("writing to `%s'\n"), outfile );
|
1998-01-13 20:04:23 +01:00
|
|
|
}
|
1998-08-11 19:29:34 +02:00
|
|
|
else if( (rc = open_outfile( fname, opt.armor? 1: detached? 2:0, &out )))
|
1997-12-31 13:32:54 +01:00
|
|
|
goto leave;
|
|
|
|
|
|
|
|
/* prepare to calculate the MD over the input */
|
2003-02-23 00:58:39 +01:00
|
|
|
if( opt.textmode && !outfile && !multifile )
|
|
|
|
{
|
|
|
|
memset( &tfx, 0, sizeof tfx);
|
1997-12-31 13:32:54 +01:00
|
|
|
iobuf_push_filter( inp, text_filter, &tfx );
|
2003-02-23 00:58:39 +01:00
|
|
|
}
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
mfx.md = md_open(0, 0);
|
|
|
|
|
|
|
|
/* If we're encrypting and signing, it is reasonable to pick the
|
|
|
|
hash algorithm to use out of the recepient key prefs. */
|
|
|
|
if(pk_list)
|
|
|
|
{
|
|
|
|
if(opt.def_digest_algo)
|
|
|
|
{
|
|
|
|
if(!opt.expert &&
|
|
|
|
select_algo_from_prefs(pk_list,PREFTYPE_HASH,
|
|
|
|
opt.def_digest_algo,
|
|
|
|
NULL)!=opt.def_digest_algo)
|
|
|
|
log_info(_("forcing digest algorithm %s (%d) "
|
|
|
|
"violates recipient preferences\n"),
|
|
|
|
digest_algo_to_string(opt.def_digest_algo),
|
|
|
|
opt.def_digest_algo);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int hashlen=0,algo;
|
|
|
|
|
|
|
|
/* Of course, if the recipient asks for something
|
|
|
|
unreasonable (like a non-160-bit hash for DSA, for
|
|
|
|
example), then don't do it. Check all sk's - if any
|
|
|
|
are DSA, then the hash must be 160-bit. In the future
|
|
|
|
this can be more complex with different hashes for each
|
|
|
|
sk, but so long as there is only one signing algorithm
|
|
|
|
with hash restrictions, this is ok. -dms */
|
|
|
|
|
|
|
|
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
|
|
|
|
if(sk_rover->sk->pubkey_algo==PUBKEY_ALGO_DSA)
|
|
|
|
hashlen=20;
|
|
|
|
|
|
|
|
if((algo=
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
select_algo_from_prefs(pk_list,PREFTYPE_HASH,-1,
|
|
|
|
hashlen?&hashlen:NULL))>0)
|
2002-06-29 15:46:34 +02:00
|
|
|
recipient_digest_algo=algo;
|
|
|
|
}
|
|
|
|
}
|
1998-05-15 20:49:19 +02:00
|
|
|
|
1998-06-29 14:30:57 +02:00
|
|
|
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
|
|
|
PKT_secret_key *sk = sk_rover->sk;
|
2002-06-29 15:46:34 +02:00
|
|
|
md_enable(mfx.md, hash_for(sk->pubkey_algo, sk->version ));
|
1998-05-15 20:49:19 +02:00
|
|
|
}
|
|
|
|
|
1998-01-13 20:04:23 +01:00
|
|
|
if( !multifile )
|
|
|
|
iobuf_push_filter( inp, md_filter, &mfx );
|
1997-12-31 13:32:54 +01:00
|
|
|
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
if( detached && !encryptflag && !RFC1991 )
|
1998-09-18 17:24:53 +02:00
|
|
|
afx.what = 2;
|
|
|
|
|
1998-01-13 20:04:23 +01:00
|
|
|
if( opt.armor && !outfile )
|
1997-12-31 13:32:54 +01:00
|
|
|
iobuf_push_filter( out, armor_filter, &afx );
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
if( encryptflag ) {
|
1998-06-29 14:30:57 +02:00
|
|
|
efx.pk_list = pk_list;
|
1998-01-02 21:40:10 +01:00
|
|
|
/* fixme: set efx.cfx.datalen if known */
|
|
|
|
iobuf_push_filter( out, encrypt_filter, &efx );
|
1997-12-31 13:32:54 +01:00
|
|
|
}
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
if( opt.compress && !outfile && ( !detached || opt.compress_sigs) )
|
|
|
|
{
|
|
|
|
int compr_algo=opt.def_compress_algo;
|
|
|
|
|
|
|
|
/* If not forced by user */
|
|
|
|
if(compr_algo==-1)
|
|
|
|
{
|
|
|
|
/* If we're not encrypting, then select_algo_from_prefs
|
|
|
|
will fail and we'll end up with the default. If we are
|
|
|
|
encrypting, select_algo_from_prefs cannot fail since
|
|
|
|
there is an assumed preference for uncompressed data.
|
|
|
|
Still, if it did fail, we'll also end up with the
|
|
|
|
default. */
|
|
|
|
|
|
|
|
if((compr_algo=
|
|
|
|
select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
|
2002-11-25 05:24:41 +01:00
|
|
|
compr_algo=default_compress_algo();
|
2002-06-29 15:46:34 +02:00
|
|
|
}
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
else if(!opt.expert && pk_list
|
|
|
|
&& select_algo_from_prefs(pk_list,PREFTYPE_ZIP,
|
|
|
|
compr_algo,NULL)!=compr_algo)
|
2002-06-29 15:46:34 +02:00
|
|
|
log_info(_("forcing compression algorithm %s (%d) "
|
|
|
|
"violates recipient preferences\n"),
|
|
|
|
compress_algo_to_string(compr_algo),compr_algo);
|
|
|
|
|
|
|
|
/* algo 0 means no compression */
|
|
|
|
if( compr_algo )
|
|
|
|
{
|
|
|
|
zfx.algo = compr_algo;
|
1998-08-05 18:51:59 +02:00
|
|
|
iobuf_push_filter( out, compress_filter, &zfx );
|
2002-06-29 15:46:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write the one-pass signature packets if needed */
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
if (!detached && !RFC1991) {
|
2002-06-29 15:46:34 +02:00
|
|
|
rc = write_onepass_sig_packets (sk_list, out,
|
|
|
|
opt.textmode && !outfile ? 0x01:0x00);
|
|
|
|
if (rc)
|
|
|
|
goto leave;
|
1997-12-31 13:32:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* setup the inner packet */
|
|
|
|
if( detached ) {
|
1998-01-13 20:04:23 +01:00
|
|
|
if( multifile ) {
|
1998-02-12 00:22:09 +01:00
|
|
|
STRLIST sl;
|
1998-01-13 20:04:23 +01:00
|
|
|
|
|
|
|
if( opt.verbose )
|
1998-11-10 13:59:59 +01:00
|
|
|
log_info(_("signing:") );
|
1998-02-12 00:22:09 +01:00
|
|
|
/* must walk reverse trough this list */
|
|
|
|
for( sl = strlist_last(filenames); sl;
|
|
|
|
sl = strlist_prev( filenames, sl ) ) {
|
1998-01-13 20:04:23 +01:00
|
|
|
if( !(inp = iobuf_open(sl->d)) ) {
|
1998-11-10 13:59:59 +01:00
|
|
|
log_error(_("can't open %s: %s\n"),
|
|
|
|
sl->d, strerror(errno) );
|
2002-06-29 15:46:34 +02:00
|
|
|
rc = G10ERR_OPEN_FILE;
|
1998-01-13 20:04:23 +01:00
|
|
|
goto leave;
|
|
|
|
}
|
2003-04-15 17:46:13 +02:00
|
|
|
handle_progress (&pfx, inp, sl->d);
|
1998-01-13 20:04:23 +01:00
|
|
|
if( opt.verbose )
|
1998-12-29 14:47:31 +01:00
|
|
|
fprintf(stderr, " `%s'", sl->d );
|
2003-02-23 00:58:39 +01:00
|
|
|
if(opt.textmode)
|
|
|
|
{
|
|
|
|
memset( &tfx, 0, sizeof tfx);
|
|
|
|
iobuf_push_filter( inp, text_filter, &tfx );
|
|
|
|
}
|
1998-01-13 20:04:23 +01:00
|
|
|
iobuf_push_filter( inp, md_filter, &mfx );
|
|
|
|
while( iobuf_get(inp) != -1 )
|
|
|
|
;
|
|
|
|
iobuf_close(inp); inp = NULL;
|
|
|
|
}
|
|
|
|
if( opt.verbose )
|
|
|
|
putc( '\n', stderr );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* read, so that the filter can calculate the digest */
|
|
|
|
while( iobuf_get(inp) != -1 )
|
|
|
|
;
|
|
|
|
}
|
1997-12-31 13:32:54 +01:00
|
|
|
}
|
|
|
|
else {
|
2002-06-29 15:46:34 +02:00
|
|
|
rc = write_plaintext_packet (out, inp, fname,
|
|
|
|
opt.textmode && !outfile ? 't':'b');
|
1997-12-31 13:32:54 +01:00
|
|
|
}
|
|
|
|
|
2000-10-04 13:16:19 +02:00
|
|
|
/* catch errors from above */
|
1999-07-26 09:44:46 +02:00
|
|
|
if (rc)
|
1999-08-04 10:45:27 +02:00
|
|
|
goto leave;
|
1999-07-26 09:44:46 +02:00
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
/* write the signatures */
|
|
|
|
rc = write_signature_packets (sk_list, out, mfx.md,
|
2000-10-04 13:16:19 +02:00
|
|
|
opt.textmode && !outfile? 0x01 : 0x00,
|
2003-04-05 00:48:24 +02:00
|
|
|
0, duration, detached ? 'D':'S');
|
2002-06-29 15:46:34 +02:00
|
|
|
if( rc )
|
|
|
|
goto leave;
|
1997-12-31 13:32:54 +01:00
|
|
|
|
|
|
|
|
|
|
|
leave:
|
|
|
|
if( rc )
|
|
|
|
iobuf_cancel(out);
|
2002-06-29 15:46:34 +02:00
|
|
|
else {
|
1997-12-31 13:32:54 +01:00
|
|
|
iobuf_close(out);
|
2002-06-29 15:46:34 +02:00
|
|
|
if (encryptflag)
|
|
|
|
write_status( STATUS_END_ENCRYPTION );
|
|
|
|
}
|
1997-12-31 13:32:54 +01:00
|
|
|
iobuf_close(inp);
|
2002-06-29 15:46:34 +02:00
|
|
|
md_close( mfx.md );
|
1998-06-29 14:30:57 +02:00
|
|
|
release_sk_list( sk_list );
|
|
|
|
release_pk_list( pk_list );
|
2002-06-29 15:46:34 +02:00
|
|
|
recipient_digest_algo=0;
|
1997-12-31 13:32:54 +01:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-02-04 19:54:31 +01:00
|
|
|
|
|
|
|
/****************
|
|
|
|
* make a clear signature. note that opt.armor is not needed
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
|
|
|
|
{
|
|
|
|
armor_filter_context_t afx;
|
2003-04-15 17:46:13 +02:00
|
|
|
progress_filter_context_t pfx;
|
2002-06-29 15:46:34 +02:00
|
|
|
MD_HANDLE textmd = NULL;
|
1998-02-04 19:54:31 +01:00
|
|
|
IOBUF inp = NULL, out = NULL;
|
|
|
|
PACKET pkt;
|
|
|
|
int rc = 0;
|
1998-06-29 14:30:57 +02:00
|
|
|
SK_LIST sk_list = NULL;
|
|
|
|
SK_LIST sk_rover = NULL;
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
int old_style = RFC1991;
|
1998-07-06 12:23:57 +02:00
|
|
|
int only_md5 = 0;
|
2003-04-05 00:48:24 +02:00
|
|
|
u32 duration=0;
|
1998-02-04 19:54:31 +01:00
|
|
|
|
|
|
|
memset( &afx, 0, sizeof afx);
|
|
|
|
init_packet( &pkt );
|
|
|
|
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991)
|
2002-06-29 15:46:34 +02:00
|
|
|
duration=ask_expire_interval(1);
|
|
|
|
|
|
|
|
if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) )
|
1998-02-04 19:54:31 +01:00
|
|
|
goto leave;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
if( !old_style && !duration )
|
1998-06-29 14:30:57 +02:00
|
|
|
old_style = only_old_style( sk_list );
|
1998-02-04 19:54:31 +01:00
|
|
|
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
if(PGP2 && !only_old_style(sk_list))
|
2002-06-29 15:46:34 +02:00
|
|
|
{
|
|
|
|
log_info(_("you can only clearsign with PGP 2.x style keys "
|
|
|
|
"while in --pgp2 mode\n"));
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
compliance_failure();
|
2002-06-29 15:46:34 +02:00
|
|
|
}
|
|
|
|
|
1998-02-04 19:54:31 +01:00
|
|
|
/* prepare iobufs */
|
|
|
|
if( !(inp = iobuf_open(fname)) ) {
|
|
|
|
log_error("can't open %s: %s\n", fname? fname: "[stdin]",
|
|
|
|
strerror(errno) );
|
2002-06-29 15:46:34 +02:00
|
|
|
rc = G10ERR_OPEN_FILE;
|
1998-02-04 19:54:31 +01:00
|
|
|
goto leave;
|
|
|
|
}
|
2003-04-15 17:46:13 +02:00
|
|
|
handle_progress (&pfx, inp, fname);
|
1998-02-04 19:54:31 +01:00
|
|
|
|
|
|
|
if( outfile ) {
|
|
|
|
if( !(out = iobuf_create( outfile )) ) {
|
1998-11-10 13:59:59 +01:00
|
|
|
log_error(_("can't create %s: %s\n"), outfile, strerror(errno) );
|
2002-06-29 15:46:34 +02:00
|
|
|
rc = G10ERR_CREATE_FILE;
|
1998-02-04 19:54:31 +01:00
|
|
|
goto leave;
|
|
|
|
}
|
|
|
|
else if( opt.verbose )
|
1998-12-29 14:47:31 +01:00
|
|
|
log_info(_("writing to `%s'\n"), outfile );
|
1998-02-04 19:54:31 +01:00
|
|
|
}
|
1998-08-11 19:29:34 +02:00
|
|
|
else if( (rc = open_outfile( fname, 1, &out )) )
|
1998-02-04 19:54:31 +01:00
|
|
|
goto leave;
|
|
|
|
|
2000-07-14 19:34:53 +02:00
|
|
|
iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----" LF );
|
1998-07-06 12:23:57 +02:00
|
|
|
|
|
|
|
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
|
|
|
PKT_secret_key *sk = sk_rover->sk;
|
2002-06-29 15:46:34 +02:00
|
|
|
if( hash_for(sk->pubkey_algo, sk->version) == DIGEST_ALGO_MD5 )
|
1998-07-06 12:23:57 +02:00
|
|
|
only_md5 = 1;
|
|
|
|
else {
|
|
|
|
only_md5 = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
if( !(old_style && only_md5) ) {
|
|
|
|
const char *s;
|
1998-07-06 12:23:57 +02:00
|
|
|
int any = 0;
|
1999-10-26 14:14:37 +02:00
|
|
|
byte hashs_seen[256];
|
1998-07-06 12:23:57 +02:00
|
|
|
|
1999-10-26 14:14:37 +02:00
|
|
|
memset( hashs_seen, 0, sizeof hashs_seen );
|
1998-05-03 21:35:33 +02:00
|
|
|
iobuf_writestr(out, "Hash: " );
|
1998-07-06 12:23:57 +02:00
|
|
|
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
|
|
|
PKT_secret_key *sk = sk_rover->sk;
|
2000-10-04 13:16:19 +02:00
|
|
|
int i = hash_for(sk->pubkey_algo, sk->version);
|
1999-10-26 14:14:37 +02:00
|
|
|
|
|
|
|
if( !hashs_seen[ i & 0xff ] ) {
|
2002-06-29 15:46:34 +02:00
|
|
|
s = digest_algo_to_string( i );
|
|
|
|
if( s ) {
|
1999-10-26 14:14:37 +02:00
|
|
|
hashs_seen[ i & 0xff ] = 1;
|
|
|
|
if( any )
|
|
|
|
iobuf_put(out, ',' );
|
2002-06-29 15:46:34 +02:00
|
|
|
iobuf_writestr(out, s );
|
1999-10-26 14:14:37 +02:00
|
|
|
any = 1;
|
|
|
|
}
|
1998-07-06 12:23:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
assert(any);
|
2002-06-29 15:46:34 +02:00
|
|
|
iobuf_writestr(out, LF );
|
1998-04-30 18:56:17 +02:00
|
|
|
}
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
if( opt.not_dash_escaped )
|
|
|
|
iobuf_writestr( out,
|
|
|
|
"NotDashEscaped: You need GnuPG to verify this message" LF );
|
|
|
|
iobuf_writestr(out, LF );
|
1998-02-04 19:54:31 +01:00
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
textmd = md_open(0, 0);
|
1998-06-29 14:30:57 +02:00
|
|
|
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
|
|
|
PKT_secret_key *sk = sk_rover->sk;
|
2002-06-29 15:46:34 +02:00
|
|
|
md_enable(textmd, hash_for(sk->pubkey_algo, sk->version));
|
1998-05-15 20:49:19 +02:00
|
|
|
}
|
2000-07-14 19:34:53 +02:00
|
|
|
if ( DBG_HASHING )
|
2002-06-29 15:46:34 +02:00
|
|
|
md_start_debug( textmd, "clearsign" );
|
2003-01-16 20:20:10 +01:00
|
|
|
copy_clearsig_text( out, inp, textmd, !opt.not_dash_escaped,
|
|
|
|
opt.escape_from, (old_style && only_md5) );
|
1999-01-20 19:10:35 +01:00
|
|
|
/* fixme: check for read errors */
|
1998-02-04 19:54:31 +01:00
|
|
|
|
1999-01-20 19:10:35 +01:00
|
|
|
/* now write the armor */
|
1998-02-04 19:54:31 +01:00
|
|
|
afx.what = 2;
|
|
|
|
iobuf_push_filter( out, armor_filter, &afx );
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
/* write the signatures */
|
2003-04-05 00:48:24 +02:00
|
|
|
rc=write_signature_packets (sk_list, out, textmd, 0x01, 0, duration, 'C');
|
2002-06-29 15:46:34 +02:00
|
|
|
if( rc )
|
|
|
|
goto leave;
|
1998-02-04 19:54:31 +01:00
|
|
|
|
|
|
|
leave:
|
|
|
|
if( rc )
|
|
|
|
iobuf_cancel(out);
|
|
|
|
else
|
|
|
|
iobuf_close(out);
|
|
|
|
iobuf_close(inp);
|
2002-06-29 15:46:34 +02:00
|
|
|
md_close( textmd );
|
1998-06-29 14:30:57 +02:00
|
|
|
release_sk_list( sk_list );
|
1998-02-04 19:54:31 +01:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
/*
|
|
|
|
* Sign and conventionally encrypt the given file.
|
|
|
|
* FIXME: Far too much code is duplicated - revamp the whole file.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
sign_symencrypt_file (const char *fname, STRLIST locusr)
|
|
|
|
{
|
|
|
|
armor_filter_context_t afx;
|
2003-04-15 17:46:13 +02:00
|
|
|
progress_filter_context_t pfx;
|
2002-06-29 15:46:34 +02:00
|
|
|
compress_filter_context_t zfx;
|
|
|
|
md_filter_context_t mfx;
|
|
|
|
text_filter_context_t tfx;
|
|
|
|
cipher_filter_context_t cfx;
|
|
|
|
IOBUF inp = NULL, out = NULL;
|
|
|
|
PACKET pkt;
|
|
|
|
STRING2KEY *s2k = NULL;
|
|
|
|
int rc = 0;
|
|
|
|
SK_LIST sk_list = NULL;
|
|
|
|
SK_LIST sk_rover = NULL;
|
|
|
|
int algo;
|
2003-04-05 00:48:24 +02:00
|
|
|
u32 duration=0;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
memset( &afx, 0, sizeof afx);
|
|
|
|
memset( &zfx, 0, sizeof zfx);
|
|
|
|
memset( &mfx, 0, sizeof mfx);
|
|
|
|
memset( &tfx, 0, sizeof tfx);
|
|
|
|
memset( &cfx, 0, sizeof cfx);
|
|
|
|
init_packet( &pkt );
|
|
|
|
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991)
|
2002-06-29 15:46:34 +02:00
|
|
|
duration=ask_expire_interval(1);
|
|
|
|
|
|
|
|
rc = build_sk_list (locusr, &sk_list, 1, PUBKEY_USAGE_SIG);
|
|
|
|
if (rc)
|
|
|
|
goto leave;
|
|
|
|
|
|
|
|
/* prepare iobufs */
|
|
|
|
inp = iobuf_open(fname);
|
|
|
|
if( !inp ) {
|
|
|
|
log_error("can't open %s: %s\n", fname? fname: "[stdin]",
|
|
|
|
strerror(errno) );
|
|
|
|
rc = G10ERR_OPEN_FILE;
|
|
|
|
goto leave;
|
|
|
|
}
|
2003-04-15 17:46:13 +02:00
|
|
|
handle_progress (&pfx, inp, fname);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
/* prepare key */
|
|
|
|
s2k = m_alloc_clear( sizeof *s2k );
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
s2k->mode = RFC1991? 0:opt.s2k_mode;
|
2002-11-24 01:50:14 +01:00
|
|
|
s2k->hash_algo = opt.s2k_digest_algo;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
2002-11-25 05:24:41 +01:00
|
|
|
algo = default_cipher_algo();
|
2002-06-29 15:46:34 +02:00
|
|
|
if (!opt.quiet || !opt.batch)
|
|
|
|
log_info (_("%s encryption will be used\n"),
|
|
|
|
cipher_algo_to_string(algo) );
|
2003-04-10 11:56:47 +02:00
|
|
|
cfx.dek = passphrase_to_dek( NULL, 0, algo, s2k, 2, NULL, NULL);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
if (!cfx.dek || !cfx.dek->keylen) {
|
|
|
|
rc = G10ERR_PASSPHRASE;
|
|
|
|
log_error(_("error creating passphrase: %s\n"), g10_errstr(rc) );
|
|
|
|
goto leave;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now create the outfile */
|
|
|
|
rc = open_outfile (fname, opt.armor? 1:0, &out);
|
|
|
|
if (rc)
|
|
|
|
goto leave;
|
|
|
|
|
|
|
|
/* prepare to calculate the MD over the input */
|
|
|
|
if (opt.textmode)
|
|
|
|
iobuf_push_filter (inp, text_filter, &tfx);
|
|
|
|
mfx.md = md_open(0, 0);
|
|
|
|
|
|
|
|
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) {
|
|
|
|
PKT_secret_key *sk = sk_rover->sk;
|
|
|
|
md_enable (mfx.md, hash_for (sk->pubkey_algo, sk->version ));
|
|
|
|
}
|
|
|
|
|
|
|
|
iobuf_push_filter (inp, md_filter, &mfx);
|
|
|
|
|
|
|
|
/* Push armor output filter */
|
|
|
|
if (opt.armor)
|
|
|
|
iobuf_push_filter (out, armor_filter, &afx);
|
|
|
|
|
|
|
|
/* Write the symmetric key packet */
|
|
|
|
/*(current filters: armor)*/
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
if (!RFC1991) {
|
2002-06-29 15:46:34 +02:00
|
|
|
PKT_symkey_enc *enc = m_alloc_clear( sizeof *enc );
|
|
|
|
enc->version = 4;
|
|
|
|
enc->cipher_algo = cfx.dek->algo;
|
|
|
|
enc->s2k = *s2k;
|
|
|
|
pkt.pkttype = PKT_SYMKEY_ENC;
|
|
|
|
pkt.pkt.symkey_enc = enc;
|
|
|
|
if( (rc = build_packet( out, &pkt )) )
|
|
|
|
log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
|
|
|
|
m_free(enc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Push the encryption filter */
|
|
|
|
iobuf_push_filter( out, cipher_filter, &cfx );
|
|
|
|
|
|
|
|
/* Push the Zip filter */
|
2002-11-25 05:24:41 +01:00
|
|
|
if (opt.compress && default_compress_algo())
|
2002-06-29 15:46:34 +02:00
|
|
|
{
|
2002-11-25 05:24:41 +01:00
|
|
|
zfx.algo = default_compress_algo();
|
|
|
|
iobuf_push_filter( out, compress_filter, &zfx );
|
2002-06-29 15:46:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Write the one-pass signature packets */
|
|
|
|
/*(current filters: zip - encrypt - armor)*/
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 06:07:45 +02:00
|
|
|
if (!RFC1991) {
|
2002-06-29 15:46:34 +02:00
|
|
|
rc = write_onepass_sig_packets (sk_list, out,
|
|
|
|
opt.textmode? 0x01:0x00);
|
|
|
|
if (rc)
|
|
|
|
goto leave;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Pipe data through all filters; i.e. write the signed stuff */
|
|
|
|
/*(current filters: zip - encrypt - armor)*/
|
|
|
|
rc = write_plaintext_packet (out, inp, fname, opt.textmode ? 't':'b');
|
|
|
|
if (rc)
|
|
|
|
goto leave;
|
|
|
|
|
|
|
|
/* Write the signatures */
|
|
|
|
/*(current filters: zip - encrypt - armor)*/
|
|
|
|
rc = write_signature_packets (sk_list, out, mfx.md,
|
|
|
|
opt.textmode? 0x01 : 0x00,
|
2003-04-05 00:48:24 +02:00
|
|
|
0, duration, 'S');
|
2002-06-29 15:46:34 +02:00
|
|
|
if( rc )
|
|
|
|
goto leave;
|
|
|
|
|
|
|
|
|
|
|
|
leave:
|
|
|
|
if( rc )
|
|
|
|
iobuf_cancel(out);
|
|
|
|
else {
|
|
|
|
iobuf_close(out);
|
|
|
|
write_status( STATUS_END_ENCRYPTION );
|
|
|
|
}
|
|
|
|
iobuf_close(inp);
|
|
|
|
release_sk_list( sk_list );
|
|
|
|
md_close( mfx.md );
|
|
|
|
m_free(cfx.dek);
|
|
|
|
m_free(s2k);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
1998-02-04 19:54:31 +01:00
|
|
|
|
1998-07-29 21:35:05 +02:00
|
|
|
/****************
|
2002-06-29 15:46:34 +02:00
|
|
|
* Create a signature packet for the given public key certificate and
|
|
|
|
* the user id and return it in ret_sig. User signature class SIGCLASS
|
|
|
|
* user-id is not used (and may be NULL if sigclass is 0x20) If
|
|
|
|
* DIGEST_ALGO is 0 the function selects an appropriate one.
|
|
|
|
* SIGVERSION gives the minimal required signature packet version;
|
|
|
|
* this is needed so that special properties like local sign are not
|
|
|
|
* applied (actually: dropped) when a v3 key is used. TIMESTAMP is
|
|
|
|
* the timestamp to use for the signature. 0 means "now" */
|
1998-07-29 21:35:05 +02:00
|
|
|
int
|
|
|
|
make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
|
|
|
PKT_user_id *uid, PKT_public_key *subpk,
|
|
|
|
PKT_secret_key *sk,
|
|
|
|
int sigclass, int digest_algo,
|
2002-06-29 15:46:34 +02:00
|
|
|
int sigversion, u32 timestamp, u32 duration,
|
1998-07-29 21:35:05 +02:00
|
|
|
int (*mksubpkt)(PKT_signature *, void *), void *opaque
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PKT_signature *sig;
|
|
|
|
int rc=0;
|
2002-06-29 15:46:34 +02:00
|
|
|
MD_HANDLE md;
|
1998-07-29 21:35:05 +02:00
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F
|
1999-04-28 13:06:52 +02:00
|
|
|
|| sigclass == 0x20 || sigclass == 0x18
|
|
|
|
|| sigclass == 0x30 || sigclass == 0x28 );
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
if (opt.force_v4_certs)
|
|
|
|
sigversion = 4;
|
|
|
|
|
|
|
|
if (sigversion < sk->version)
|
|
|
|
sigversion = sk->version;
|
|
|
|
|
|
|
|
/* If you are making a signature on a v4 key using your v3 key, it
|
|
|
|
doesn't make sense to generate a v3 sig. After all, no v3-only
|
|
|
|
PGP implementation could understand the v4 key in the first
|
2002-08-20 14:45:57 +02:00
|
|
|
place. Note that this implies that a signature on an attribute
|
|
|
|
uid is usually going to be v4 as well, since they are not
|
|
|
|
generally found on v3 keys. */
|
2002-06-29 15:46:34 +02:00
|
|
|
if (sigversion < pk->version)
|
|
|
|
sigversion = pk->version;
|
|
|
|
|
|
|
|
if( !digest_algo )
|
|
|
|
{
|
|
|
|
/* Basically, this means use SHA1 always unless it's a v3 RSA
|
|
|
|
key making a v3 cert (use MD5), or the user specified
|
|
|
|
something (use whatever they said). They still must use a
|
|
|
|
160-bit hash with DSA, or the signature will fail. Note
|
|
|
|
that this still allows the caller of make_keysig_packet to
|
|
|
|
override the user setting if it must. */
|
|
|
|
|
|
|
|
if(opt.cert_digest_algo)
|
|
|
|
digest_algo=opt.cert_digest_algo;
|
|
|
|
else if((sk->pubkey_algo==PUBKEY_ALGO_RSA ||
|
|
|
|
sk->pubkey_algo==PUBKEY_ALGO_RSA_S) &&
|
|
|
|
pk->version<4 && sigversion < 4)
|
|
|
|
digest_algo = DIGEST_ALGO_MD5;
|
|
|
|
else
|
|
|
|
digest_algo = DIGEST_ALGO_SHA1;
|
|
|
|
}
|
|
|
|
|
|
|
|
md = md_open( digest_algo, 0 );
|
1998-07-29 21:35:05 +02:00
|
|
|
|
|
|
|
/* hash the public key certificate and the user id */
|
|
|
|
hash_public_key( md, pk );
|
1999-04-28 13:06:52 +02:00
|
|
|
if( sigclass == 0x18 || sigclass == 0x28 ) { /* subkey binding/revocation*/
|
1998-07-29 21:35:05 +02:00
|
|
|
hash_public_key( md, subpk );
|
|
|
|
}
|
2002-06-29 15:46:34 +02:00
|
|
|
else if( sigclass != 0x1F && sigclass != 0x20 ) {
|
|
|
|
hash_uid (md, sigversion, uid);
|
1998-07-29 21:35:05 +02:00
|
|
|
}
|
|
|
|
/* and make the signature packet */
|
2002-06-29 15:46:34 +02:00
|
|
|
sig = m_alloc_clear( sizeof *sig );
|
|
|
|
sig->version = sigversion;
|
|
|
|
sig->flags.exportable=1;
|
|
|
|
sig->flags.revocable=1;
|
1998-07-29 21:35:05 +02:00
|
|
|
keyid_from_sk( sk, sig->keyid );
|
|
|
|
sig->pubkey_algo = sk->pubkey_algo;
|
|
|
|
sig->digest_algo = digest_algo;
|
2002-06-29 15:46:34 +02:00
|
|
|
if(timestamp)
|
|
|
|
sig->timestamp=timestamp;
|
|
|
|
else
|
|
|
|
sig->timestamp=make_timestamp();
|
|
|
|
if(duration)
|
|
|
|
sig->expiredate=sig->timestamp+duration;
|
1998-07-29 21:35:05 +02:00
|
|
|
sig->sig_class = sigclass;
|
|
|
|
if( sig->version >= 4 )
|
|
|
|
build_sig_subpkt_from_sig( sig );
|
2003-07-24 21:28:12 +02:00
|
|
|
mk_notation_policy_etc( sig, pk, sk );
|
1998-07-29 21:35:05 +02:00
|
|
|
|
2003-04-30 07:33:52 +02:00
|
|
|
/* Crucial that the call to mksubpkt comes LAST before the calls
|
|
|
|
to finalize the sig as that makes it possible for the mksubpkt
|
|
|
|
function to get a reliable pointer to the subpacket area. */
|
1998-07-29 21:35:05 +02:00
|
|
|
if( sig->version >= 4 && mksubpkt )
|
|
|
|
rc = (*mksubpkt)( sig, opaque );
|
|
|
|
|
|
|
|
if( !rc ) {
|
2002-06-29 15:46:34 +02:00
|
|
|
hash_sigversion_to_magic (md, sig);
|
|
|
|
md_final(md);
|
1998-07-29 21:35:05 +02:00
|
|
|
|
|
|
|
rc = complete_sig( sig, sk, md );
|
|
|
|
}
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
md_close( md );
|
1998-07-29 21:35:05 +02:00
|
|
|
if( rc )
|
|
|
|
free_seckey_enc( sig );
|
|
|
|
else
|
|
|
|
*ret_sig = sig;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
1998-02-04 19:54:31 +01:00
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
/****************
|
|
|
|
* Create a new signature packet based on an existing one.
|
|
|
|
* Only user ID signatures are supported for now.
|
|
|
|
* TODO: Merge this with make_keysig_packet.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
update_keysig_packet( PKT_signature **ret_sig,
|
|
|
|
PKT_signature *orig_sig,
|
|
|
|
PKT_public_key *pk,
|
|
|
|
PKT_user_id *uid,
|
2002-12-04 19:50:10 +01:00
|
|
|
PKT_public_key *subpk,
|
2002-06-29 15:46:34 +02:00
|
|
|
PKT_secret_key *sk,
|
|
|
|
int (*mksubpkt)(PKT_signature *, void *),
|
|
|
|
void *opaque
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PKT_signature *sig;
|
|
|
|
int rc=0;
|
|
|
|
MD_HANDLE md;
|
|
|
|
|
2002-12-04 19:50:10 +01:00
|
|
|
if ((!orig_sig || !pk || !sk)
|
|
|
|
|| (orig_sig->sig_class >= 0x10 && orig_sig->sig_class <= 0x13 && !uid)
|
|
|
|
|| (orig_sig->sig_class == 0x18 && !subpk))
|
|
|
|
return G10ERR_GENERAL;
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
md = md_open( orig_sig->digest_algo, 0 );
|
|
|
|
|
|
|
|
/* hash the public key certificate and the user id */
|
|
|
|
hash_public_key( md, pk );
|
2002-12-04 19:50:10 +01:00
|
|
|
|
|
|
|
if( orig_sig->sig_class == 0x18 )
|
|
|
|
hash_public_key( md, subpk );
|
|
|
|
else
|
|
|
|
hash_uid (md, orig_sig->version, uid);
|
2002-06-29 15:46:34 +02:00
|
|
|
|
|
|
|
/* create a new signature packet */
|
|
|
|
sig = copy_signature (NULL, orig_sig);
|
2002-12-04 19:50:10 +01:00
|
|
|
|
|
|
|
/* We need to create a new timestamp so that new sig expiration
|
|
|
|
calculations are done correctly... */
|
|
|
|
sig->timestamp=make_timestamp();
|
|
|
|
|
|
|
|
/* ... but we won't make a timestamp earlier than the existing
|
|
|
|
one. */
|
|
|
|
while(sig->timestamp<=orig_sig->timestamp)
|
|
|
|
{
|
|
|
|
sleep(1);
|
|
|
|
sig->timestamp=make_timestamp();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Note that already expired sigs will remain expired (with a
|
|
|
|
duration of 0) since build-packet.c:build_sig_subpkt_from_sig
|
|
|
|
detects this case. */
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
if( sig->version >= 4 )
|
2002-12-04 19:50:10 +01:00
|
|
|
{
|
|
|
|
/* Put the updated timestamp into the sig. Note that this
|
|
|
|
will automagically lower any sig expiration dates to
|
|
|
|
correctly correspond to the differences in the timestamps
|
|
|
|
(i.e. the duration will shrink). */
|
2002-06-29 15:46:34 +02:00
|
|
|
build_sig_subpkt_from_sig( sig );
|
|
|
|
|
2002-12-04 19:50:10 +01:00
|
|
|
if (mksubpkt)
|
|
|
|
rc = (*mksubpkt)(sig, opaque);
|
|
|
|
}
|
|
|
|
|
2002-06-29 15:46:34 +02:00
|
|
|
if (!rc) {
|
|
|
|
hash_sigversion_to_magic (md, sig);
|
|
|
|
md_final(md);
|
|
|
|
|
|
|
|
rc = complete_sig( sig, sk, md );
|
|
|
|
}
|
|
|
|
|
|
|
|
md_close (md);
|
|
|
|
if( rc )
|
|
|
|
free_seckey_enc (sig);
|
|
|
|
else
|
|
|
|
*ret_sig = sig;
|
|
|
|
return rc;
|
|
|
|
}
|