mirror of
git://git.gnupg.org/gnupg.git
synced 2025-05-17 08:43:24 +02:00
Initial commit.
This commit is contained in:
parent
e8d2d53053
commit
28fe48cf92
@ -133,7 +133,8 @@ gpg2_SOURCES = gpg.c \
|
|||||||
call-agent.c call-agent.h \
|
call-agent.c call-agent.h \
|
||||||
trust.c $(trust_source) $(tofu_source) \
|
trust.c $(trust_source) $(tofu_source) \
|
||||||
$(card_source) \
|
$(card_source) \
|
||||||
exec.c exec.h
|
exec.c exec.h \
|
||||||
|
mailing-list.c mailing-list.h
|
||||||
|
|
||||||
gpgv2_SOURCES = gpgv.c \
|
gpgv2_SOURCES = gpgv.c \
|
||||||
$(common_source) \
|
$(common_source) \
|
||||||
|
@ -1037,6 +1037,87 @@ string_to_notation(const char *string,int is_utf8)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct notation *
|
||||||
|
blob_to_notation(const char *name, const char *data, size_t len)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
int saw_at=0;
|
||||||
|
struct notation *notation;
|
||||||
|
|
||||||
|
notation=xmalloc_clear(sizeof(*notation));
|
||||||
|
|
||||||
|
if(*name=='-')
|
||||||
|
{
|
||||||
|
notation->flags.ignore=1;
|
||||||
|
name++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*name=='!')
|
||||||
|
{
|
||||||
|
notation->flags.critical=1;
|
||||||
|
name++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If and when the IETF assigns some official name tags, we'll have
|
||||||
|
to add them here. */
|
||||||
|
|
||||||
|
for( s=name ; *s; s++ )
|
||||||
|
{
|
||||||
|
if( *s=='@')
|
||||||
|
saw_at++;
|
||||||
|
|
||||||
|
/* -notationname is legal without an = sign */
|
||||||
|
if(!*s && notation->flags.ignore)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (*s == '=')
|
||||||
|
{
|
||||||
|
log_error(_("a notation name may not contain an '=' character\n"));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isascii (*s) || (!isgraph(*s) && !isspace(*s)))
|
||||||
|
{
|
||||||
|
log_error(_("a notation name must have only printable characters"
|
||||||
|
" or spaces\n") );
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notation->name=xstrdup (name);
|
||||||
|
|
||||||
|
if(!saw_at && !opt.expert)
|
||||||
|
{
|
||||||
|
log_error(_("a user notation name must contain the '@' character\n"));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saw_at > 1)
|
||||||
|
{
|
||||||
|
log_error(_("a notation name must not contain more than"
|
||||||
|
" one '@' character\n"));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
notation->bdat = xmalloc (len);
|
||||||
|
memcpy (notation->bdat, data, len);
|
||||||
|
notation->blen = len;
|
||||||
|
|
||||||
|
/* The maximum size of a notation is 65k, i.e., we need 5 bytes of
|
||||||
|
space. */
|
||||||
|
notation->value=xmalloc(2+strlen(_("not human readable (65000 bytes)"))+2+1);
|
||||||
|
strcpy(notation->value,"[ ");
|
||||||
|
sprintf(¬ation->value[strlen (notation->value)],
|
||||||
|
_("not human readable (%zd bytes)"), len);
|
||||||
|
strcat(notation->value," ]");
|
||||||
|
|
||||||
|
return notation;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
free_notation(notation);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct notation *
|
struct notation *
|
||||||
sig_to_notation(PKT_signature *sig)
|
sig_to_notation(PKT_signature *sig)
|
||||||
{
|
{
|
||||||
@ -1083,9 +1164,12 @@ sig_to_notation(PKT_signature *sig)
|
|||||||
n->blen=n2;
|
n->blen=n2;
|
||||||
memcpy(n->bdat,&p[8+n1],n2);
|
memcpy(n->bdat,&p[8+n1],n2);
|
||||||
|
|
||||||
n->value=xmalloc(2+strlen(_("not human readable"))+2+1);
|
/* The maximum size of a notation is 65k, i.e., we need 5
|
||||||
|
bytes of space. */
|
||||||
|
n->value=xmalloc(2+strlen(_("not human readable (65000 bytes)"))+2+1);
|
||||||
strcpy(n->value,"[ ");
|
strcpy(n->value,"[ ");
|
||||||
strcat(n->value,_("not human readable"));
|
sprintf(&n->value[strlen (n->value)],
|
||||||
|
_("not human readable (%d bytes)"), n2);
|
||||||
strcat(n->value," ]");
|
strcat(n->value," ]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1431,7 +1431,7 @@ generate_card_keys (ctrl_t ctrl)
|
|||||||
the serialnumber and thus it won't harm. */
|
the serialnumber and thus it won't harm. */
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_keypair (ctrl, 1, NULL, info.serialno, want_backup);
|
generate_keypair (ctrl, 1, 0, NULL, info.serialno, want_backup);
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
agent_release_card_info (&info);
|
agent_release_card_info (&info);
|
||||||
|
@ -38,10 +38,10 @@
|
|||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "pkglue.h"
|
#include "pkglue.h"
|
||||||
|
#include "mailing-list.h"
|
||||||
|
|
||||||
|
|
||||||
static int encrypt_simple( const char *filename, int mode, int use_seskey );
|
static int encrypt_simple( const char *filename, int mode, int use_seskey );
|
||||||
static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out );
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Encrypt FILENAME with only the symmetric cipher. Take input from
|
* Encrypt FILENAME with only the symmetric cipher. Take input from
|
||||||
@ -419,7 +419,8 @@ setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
/* DEK is initialized. */
|
||||||
|
int
|
||||||
write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
|
write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
|
||||||
iobuf_t out)
|
iobuf_t out)
|
||||||
{
|
{
|
||||||
@ -628,7 +629,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
|||||||
if (DBG_CRYPTO)
|
if (DBG_CRYPTO)
|
||||||
log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );
|
log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );
|
||||||
|
|
||||||
rc = write_pubkey_enc_from_list (pk_list, cfx.dek, out);
|
rc = write_pubkey_enc_from_list (ctrl, pk_list, cfx.dek, out);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -822,7 +823,8 @@ encrypt_filter (void *opaque, int control,
|
|||||||
if (DBG_CRYPTO)
|
if (DBG_CRYPTO)
|
||||||
log_printhex ("DEK is: ", efx->cfx.dek->key, efx->cfx.dek->keylen);
|
log_printhex ("DEK is: ", efx->cfx.dek->key, efx->cfx.dek->keylen);
|
||||||
|
|
||||||
rc = write_pubkey_enc_from_list (efx->pk_list, efx->cfx.dek, a);
|
rc = write_pubkey_enc_from_list (efx->ctrl,
|
||||||
|
efx->pk_list, efx->cfx.dek, a);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@ -854,28 +856,19 @@ encrypt_filter (void *opaque, int control,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write pubkey-enc packets from the list of PKs to OUT.
|
|
||||||
*/
|
|
||||||
static int
|
static int
|
||||||
write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out)
|
write_pubkey_enc (PKT_public_key *pk, int flags, DEK *dek, iobuf_t out)
|
||||||
{
|
{
|
||||||
PACKET pkt;
|
|
||||||
PKT_public_key *pk;
|
|
||||||
PKT_pubkey_enc *enc;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
PKT_pubkey_enc *enc;
|
||||||
for ( ; pk_list; pk_list = pk_list->next )
|
|
||||||
{
|
|
||||||
gcry_mpi_t frame;
|
gcry_mpi_t frame;
|
||||||
|
PACKET pkt;
|
||||||
pk = pk_list->pk;
|
|
||||||
|
|
||||||
print_pubkey_algo_note ( pk->pubkey_algo );
|
print_pubkey_algo_note ( pk->pubkey_algo );
|
||||||
enc = xmalloc_clear ( sizeof *enc );
|
enc = xmalloc_clear ( sizeof *enc );
|
||||||
enc->pubkey_algo = pk->pubkey_algo;
|
enc->pubkey_algo = pk->pubkey_algo;
|
||||||
keyid_from_pk( pk, enc->keyid );
|
keyid_from_pk( pk, enc->keyid );
|
||||||
enc->throw_keyid = (opt.throw_keyids || (pk_list->flags&1));
|
enc->throw_keyid = (opt.throw_keyids || (flags&1));
|
||||||
|
|
||||||
if (opt.throw_keyids && (PGP6 || PGP7 || PGP8))
|
if (opt.throw_keyids && (PGP6 || PGP7 || PGP8))
|
||||||
{
|
{
|
||||||
@ -923,6 +916,54 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out)
|
|||||||
gpg_strerror (rc));
|
gpg_strerror (rc));
|
||||||
}
|
}
|
||||||
free_pubkey_enc(enc);
|
free_pubkey_enc(enc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write pubkey-enc packets from the list of PKs to OUT.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
write_pubkey_enc_from_list (ctrl_t ctrl, PK_LIST pk_list, DEK *dek, iobuf_t out)
|
||||||
|
{
|
||||||
|
PKT_public_key *pk;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
for ( ; pk_list; pk_list = pk_list->next )
|
||||||
|
{
|
||||||
|
pk = pk_list->pk;
|
||||||
|
|
||||||
|
if (pk->flags.mailing_list)
|
||||||
|
{
|
||||||
|
KBNODE kb = get_pubkeyblock (pk->main_keyid);
|
||||||
|
PK_LIST subscribers;
|
||||||
|
PK_LIST subscriber;
|
||||||
|
|
||||||
|
if (! kb)
|
||||||
|
{
|
||||||
|
log_error (_("failed to find keyblock corresponding to %s\n"),
|
||||||
|
keystr (pk->main_keyid));
|
||||||
|
return gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = mailing_list_subscribers (ctrl, kb, &subscribers);
|
||||||
|
release_kbnode (kb);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error (_("failed to list subscribers for %s\n"),
|
||||||
|
keystr (pk->main_keyid));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (subscriber = subscribers;
|
||||||
|
! rc && subscriber;
|
||||||
|
subscriber = subscriber->next)
|
||||||
|
rc = write_pubkey_enc (subscriber->pk, subscriber->flags, dek, out);
|
||||||
|
|
||||||
|
release_pk_list (subscribers);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = write_pubkey_enc (pk, pk_list->flags, dek, out);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
37
g10/getkey.c
37
g10/getkey.c
@ -2318,6 +2318,24 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sig->flags.notation && ! pk->flags.mailing_list)
|
||||||
|
/* If the mailing-list notation appears on any
|
||||||
|
self-sig (not only the latest one), we consider
|
||||||
|
the key to be a mailing list key. */
|
||||||
|
{
|
||||||
|
struct notation *notations = sig_to_notation (sig);
|
||||||
|
struct notation *n;
|
||||||
|
|
||||||
|
for (n = notations; n; n = n->next)
|
||||||
|
if (strcmp (n->name, "mailing-list@gnupg.org") == 0)
|
||||||
|
{
|
||||||
|
pk->flags.mailing_list = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free_notation (notations);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2467,6 +2485,24 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
|||||||
if (sig->version > sigversion)
|
if (sig->version > sigversion)
|
||||||
sigversion = sig->version;
|
sigversion = sig->version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sig->flags.notation && ! pk->flags.mailing_list)
|
||||||
|
/* If the mailing-list notation appears on any
|
||||||
|
self-sig (not only the latest one), we consider
|
||||||
|
the key to be a mailing list key. */
|
||||||
|
{
|
||||||
|
struct notation *notations = sig_to_notation (sig);
|
||||||
|
struct notation *n;
|
||||||
|
|
||||||
|
for (n = notations; n; n = n->next)
|
||||||
|
if (strcmp (n->name, "mailing-list@gnupg.org") == 0)
|
||||||
|
{
|
||||||
|
pk->flags.mailing_list = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free_notation (notations);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2777,6 +2813,7 @@ merge_selfsigs_subkey (KBNODE keyblock, KBNODE subnode)
|
|||||||
|
|
||||||
subpk->flags.valid = 0;
|
subpk->flags.valid = 0;
|
||||||
subpk->flags.exact = 0;
|
subpk->flags.exact = 0;
|
||||||
|
subpk->flags.mailing_list = mainpk->flags.mailing_list;
|
||||||
subpk->main_keyid[0] = mainpk->main_keyid[0];
|
subpk->main_keyid[0] = mainpk->main_keyid[0];
|
||||||
subpk->main_keyid[1] = mainpk->main_keyid[1];
|
subpk->main_keyid[1] = mainpk->main_keyid[1];
|
||||||
|
|
||||||
|
154
g10/gpg.c
154
g10/gpg.c
@ -60,6 +60,7 @@
|
|||||||
#include "asshelp.h"
|
#include "asshelp.h"
|
||||||
#include "call-dirmngr.h"
|
#include "call-dirmngr.h"
|
||||||
#include "tofu.h"
|
#include "tofu.h"
|
||||||
|
#include "mailing-list.h"
|
||||||
#include "../common/init.h"
|
#include "../common/init.h"
|
||||||
#include "../common/shareddefs.h"
|
#include "../common/shareddefs.h"
|
||||||
|
|
||||||
@ -110,6 +111,8 @@ enum cmd_and_opt_values
|
|||||||
aQuickKeygen,
|
aQuickKeygen,
|
||||||
aFullKeygen,
|
aFullKeygen,
|
||||||
aKeygen,
|
aKeygen,
|
||||||
|
aMailingListKeygen,
|
||||||
|
aQuickMailingListKeygen,
|
||||||
aSignEncr,
|
aSignEncr,
|
||||||
aSignEncrSym,
|
aSignEncrSym,
|
||||||
aSignSym,
|
aSignSym,
|
||||||
@ -118,6 +121,9 @@ enum cmd_and_opt_values
|
|||||||
aQuickSignKey,
|
aQuickSignKey,
|
||||||
aQuickLSignKey,
|
aQuickLSignKey,
|
||||||
aQuickAddUid,
|
aQuickAddUid,
|
||||||
|
aMailingListAddSub,
|
||||||
|
aMailingListRMSub,
|
||||||
|
aMailingListSubs,
|
||||||
aListConfig,
|
aListConfig,
|
||||||
aListGcryptConfig,
|
aListGcryptConfig,
|
||||||
aGPGConfList,
|
aGPGConfList,
|
||||||
@ -422,10 +428,20 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
ARGPARSE_c (aListSecretKeys, "list-secret-keys", N_("list secret keys")),
|
ARGPARSE_c (aListSecretKeys, "list-secret-keys", N_("list secret keys")),
|
||||||
ARGPARSE_c (aKeygen, "gen-key",
|
ARGPARSE_c (aKeygen, "gen-key",
|
||||||
N_("generate a new key pair")),
|
N_("generate a new key pair")),
|
||||||
|
ARGPARSE_c (aMailingListKeygen, "gen-mailing-list-key",
|
||||||
|
N_("generate a new key pair for a mailing list")),
|
||||||
ARGPARSE_c (aQuickKeygen, "quick-gen-key" ,
|
ARGPARSE_c (aQuickKeygen, "quick-gen-key" ,
|
||||||
N_("quickly generate a new key pair")),
|
N_("quickly generate a new key pair")),
|
||||||
|
ARGPARSE_c (aQuickMailingListKeygen, "quick-gen-mailing-list-key" ,
|
||||||
|
N_("quickly generate a new mailing list key pair")),
|
||||||
ARGPARSE_c (aQuickAddUid, "quick-adduid",
|
ARGPARSE_c (aQuickAddUid, "quick-adduid",
|
||||||
N_("quickly add a new user-id")),
|
N_("quickly add a new user-id")),
|
||||||
|
ARGPARSE_c (aMailingListAddSub, "mailing-list-add-sub",
|
||||||
|
N_("add a subscriber to a mailing list key")),
|
||||||
|
ARGPARSE_c (aMailingListRMSub, "mailing-list-rm-sub",
|
||||||
|
N_("remove a subscriber from a mailing list key")),
|
||||||
|
ARGPARSE_c (aMailingListSubs, "mailing-list-subs",
|
||||||
|
N_("list a mailing list's current subscribers")),
|
||||||
ARGPARSE_c (aFullKeygen, "full-gen-key" ,
|
ARGPARSE_c (aFullKeygen, "full-gen-key" ,
|
||||||
N_("full featured key pair generation")),
|
N_("full featured key pair generation")),
|
||||||
ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
|
ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
|
||||||
@ -2427,6 +2443,9 @@ main (int argc, char **argv)
|
|||||||
case aStore:
|
case aStore:
|
||||||
case aQuickKeygen:
|
case aQuickKeygen:
|
||||||
case aQuickAddUid:
|
case aQuickAddUid:
|
||||||
|
case aMailingListAddSub:
|
||||||
|
case aMailingListRMSub:
|
||||||
|
case aMailingListSubs:
|
||||||
case aExportOwnerTrust:
|
case aExportOwnerTrust:
|
||||||
case aImportOwnerTrust:
|
case aImportOwnerTrust:
|
||||||
case aRebuildKeydbCaches:
|
case aRebuildKeydbCaches:
|
||||||
@ -2434,6 +2453,8 @@ main (int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case aKeygen:
|
case aKeygen:
|
||||||
|
case aMailingListKeygen:
|
||||||
|
case aQuickMailingListKeygen:
|
||||||
case aFullKeygen:
|
case aFullKeygen:
|
||||||
case aEditKey:
|
case aEditKey:
|
||||||
case aDeleteSecretKeys:
|
case aDeleteSecretKeys:
|
||||||
@ -3765,8 +3786,13 @@ main (int argc, char **argv)
|
|||||||
case aDeleteSecretAndPublicKeys:
|
case aDeleteSecretAndPublicKeys:
|
||||||
case aQuickKeygen:
|
case aQuickKeygen:
|
||||||
case aQuickAddUid:
|
case aQuickAddUid:
|
||||||
|
case aMailingListAddSub:
|
||||||
|
case aMailingListRMSub:
|
||||||
|
case aMailingListSubs:
|
||||||
case aFullKeygen:
|
case aFullKeygen:
|
||||||
case aKeygen:
|
case aKeygen:
|
||||||
|
case aQuickMailingListKeygen:
|
||||||
|
case aMailingListKeygen:
|
||||||
case aImport:
|
case aImport:
|
||||||
case aExportSecret:
|
case aExportSecret:
|
||||||
case aExportSecretSub:
|
case aExportSecretSub:
|
||||||
@ -4082,32 +4108,64 @@ main (int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case aQuickKeygen:
|
case aQuickKeygen:
|
||||||
|
case aQuickMailingListKeygen:
|
||||||
|
{
|
||||||
|
int mailing_list = cmd == aQuickMailingListKeygen;
|
||||||
|
const char *option_help;
|
||||||
|
if (mailing_list)
|
||||||
|
option_help = "--quick-gen-mailing-list-key user-id";
|
||||||
|
else
|
||||||
|
option_help = "--quick-gen-key user-id";
|
||||||
|
|
||||||
if (argc != 1 )
|
if (argc != 1 )
|
||||||
wrong_args("--gen-key user-id");
|
wrong_args(option_help);
|
||||||
username = make_username (fname);
|
username = make_username (fname);
|
||||||
quick_generate_keypair (ctrl, username);
|
printf ("'%s'\n", username);
|
||||||
|
quick_generate_keypair (ctrl, username, mailing_list);
|
||||||
xfree (username);
|
xfree (username);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aKeygen: /* generate a key */
|
case aKeygen: /* generate a key */
|
||||||
if( opt.batch ) {
|
case aMailingListKeygen:
|
||||||
if( argc > 1 )
|
{
|
||||||
wrong_args("--gen-key [parameterfile]");
|
int mailing_list = cmd == aMailingListKeygen;
|
||||||
generate_keypair (ctrl, 0, argc? *argv : NULL, NULL, 0);
|
const char *option_help;
|
||||||
|
const char *option_help_short;
|
||||||
|
if (mailing_list)
|
||||||
|
{
|
||||||
|
option_help = "--gen-mailing-list-key [parameterfile]";
|
||||||
|
option_help_short = "--gen-mailing-list-key";
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
|
option_help = "--gen-key [parameterfile]";
|
||||||
|
option_help_short = "--gen-key";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( opt.batch )
|
||||||
|
{
|
||||||
|
if( argc > 1 )
|
||||||
|
wrong_args(option_help);
|
||||||
|
generate_keypair (ctrl, 0, mailing_list,
|
||||||
|
argc? *argv : NULL, NULL, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (opt.command_fd != -1 && argc)
|
if (opt.command_fd != -1 && argc)
|
||||||
{
|
{
|
||||||
if( argc > 1 )
|
if( argc > 1 )
|
||||||
wrong_args("--gen-key [parameterfile]");
|
wrong_args(option_help);
|
||||||
|
|
||||||
opt.batch = 1;
|
opt.batch = 1;
|
||||||
generate_keypair (ctrl, 0, argc? *argv : NULL, NULL, 0);
|
generate_keypair (ctrl, 0, mailing_list,
|
||||||
|
argc? *argv : NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
else if (argc)
|
else if (argc)
|
||||||
wrong_args ("--gen-key");
|
wrong_args (option_help_short);
|
||||||
else
|
else
|
||||||
generate_keypair (ctrl, 0, NULL, NULL, 0);
|
generate_keypair (ctrl, 0, mailing_list, NULL, NULL, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4116,13 +4174,13 @@ main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
wrong_args ("--full-gen-key [parameterfile]");
|
wrong_args ("--full-gen-key [parameterfile]");
|
||||||
generate_keypair (ctrl, 1, argc? *argv : NULL, NULL, 0);
|
generate_keypair (ctrl, 1, 0, argc? *argv : NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (argc)
|
if (argc)
|
||||||
wrong_args("--full-gen-key");
|
wrong_args("--full-gen-key");
|
||||||
generate_keypair (ctrl, 1, NULL, NULL, 0);
|
generate_keypair (ctrl, 1, 0, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4138,6 +4196,76 @@ main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case aMailingListAddSub:
|
||||||
|
case aMailingListRMSub:
|
||||||
|
{
|
||||||
|
int add = cmd == aMailingListAddSub;
|
||||||
|
const char *option_help;
|
||||||
|
KBNODE kb;
|
||||||
|
|
||||||
|
if (add)
|
||||||
|
option_help = "--mailing-list-add-sub mailing-list-keyid subcriber-keyid...";
|
||||||
|
else
|
||||||
|
option_help = "--mailing-list-rm-sub mailing-list-keyid subcriber-keyid...";
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
wrong_args (option_help);
|
||||||
|
|
||||||
|
rc = get_pubkey_byname (ctrl, NULL, NULL, argv[0], &kb, NULL, 1, 1);
|
||||||
|
if (rc)
|
||||||
|
log_error (_("key \"%s\" not found: %s\n"),
|
||||||
|
argv[0], gpg_strerror (rc));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; i < argc; i ++)
|
||||||
|
if (add)
|
||||||
|
mailing_list_add_subscriber (ctrl, kb, argv[i]);
|
||||||
|
else
|
||||||
|
mailing_list_rm_subscriber (ctrl, kb, argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case aMailingListSubs:
|
||||||
|
{
|
||||||
|
KBNODE kb = NULL;
|
||||||
|
PKT_public_key *pk;
|
||||||
|
PK_LIST pklist;
|
||||||
|
PK_LIST i;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (argc != 1)
|
||||||
|
wrong_args ("--mailing-list-subs mailing-list-keyid");
|
||||||
|
|
||||||
|
rc = get_pubkey_byname (ctrl, NULL, NULL, argv[0], &kb, NULL, 1, 1);
|
||||||
|
if (rc)
|
||||||
|
log_error (_("key \"%s\" not found: %s\n"),
|
||||||
|
argv[0], gpg_strerror (rc));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pk = kb->pkt->pkt.public_key;
|
||||||
|
|
||||||
|
rc = mailing_list_subscribers (ctrl, kb, &pklist);
|
||||||
|
if (rc)
|
||||||
|
log_error ("Failed to list %s's subscribers.\n",
|
||||||
|
keystr (pk->keyid));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = pklist; i; i = i->next, count ++)
|
||||||
|
es_printf ("%s\n", keystr (i->pk->keyid));
|
||||||
|
|
||||||
|
es_printf (" %d subscribers.\n", count);
|
||||||
|
|
||||||
|
release_pk_list (pklist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case aFastImport:
|
case aFastImport:
|
||||||
opt.import_options |= IMPORT_FAST;
|
opt.import_options |= IMPORT_FAST;
|
||||||
case aImport:
|
case aImport:
|
||||||
|
166
g10/keyedit.c
166
g10/keyedit.c
@ -49,6 +49,7 @@
|
|||||||
#include "call-agent.h"
|
#include "call-agent.h"
|
||||||
#include "host2net.h"
|
#include "host2net.h"
|
||||||
#include "tofu.h"
|
#include "tofu.h"
|
||||||
|
#include "mailing-list.h"
|
||||||
|
|
||||||
static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig,
|
static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig,
|
||||||
int verbose);
|
int verbose);
|
||||||
@ -92,6 +93,8 @@ static int menu_revsubkey (KBNODE pub_keyblock);
|
|||||||
static int enable_disable_key (KBNODE keyblock, int disable);
|
static int enable_disable_key (KBNODE keyblock, int disable);
|
||||||
#endif /*!NO_TRUST_MODELS*/
|
#endif /*!NO_TRUST_MODELS*/
|
||||||
static void menu_showphoto (KBNODE keyblock);
|
static void menu_showphoto (KBNODE keyblock);
|
||||||
|
static int menu_addsub (ctrl_t ctrl, KBNODE keyblock, const char *sub);
|
||||||
|
static int menu_rmsub (ctrl_t ctrl, KBNODE keyblock, const char *sub);
|
||||||
|
|
||||||
static int update_trust = 0;
|
static int update_trust = 0;
|
||||||
|
|
||||||
@ -1089,7 +1092,7 @@ sign_uids (ctrl_t ctrl, estream_t fp,
|
|||||||
node->pkt->pkt.user_id,
|
node->pkt->pkt.user_id,
|
||||||
NULL,
|
NULL,
|
||||||
pk,
|
pk,
|
||||||
0x13, 0, 0, 0,
|
0x13, 0, 0, 0, NULL,
|
||||||
keygen_add_std_prefs, primary_pk,
|
keygen_add_std_prefs, primary_pk,
|
||||||
NULL);
|
NULL);
|
||||||
else
|
else
|
||||||
@ -1098,7 +1101,7 @@ sign_uids (ctrl_t ctrl, estream_t fp,
|
|||||||
NULL,
|
NULL,
|
||||||
pk,
|
pk,
|
||||||
class, 0,
|
class, 0,
|
||||||
timestamp, duration,
|
timestamp, duration, NULL,
|
||||||
sign_mk_attrib, &attrib,
|
sign_mk_attrib, &attrib,
|
||||||
NULL);
|
NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -1369,7 +1372,7 @@ enum cmdids
|
|||||||
cmdSHOWPREF,
|
cmdSHOWPREF,
|
||||||
cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
|
cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
|
||||||
cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD,
|
cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD,
|
||||||
cmdCLEAN, cmdMINIMIZE, cmdGRIP, cmdNOP
|
cmdCLEAN, cmdMINIMIZE, cmdGRIP, cmdADDSUB, cmdRMSUB, cmdNOP
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
@ -1463,6 +1466,10 @@ static struct
|
|||||||
N_("compact unusable user IDs and remove unusable signatures from key")},
|
N_("compact unusable user IDs and remove unusable signatures from key")},
|
||||||
{ "minimize", cmdMINIMIZE, KEYEDIT_NOT_SK,
|
{ "minimize", cmdMINIMIZE, KEYEDIT_NOT_SK,
|
||||||
N_("compact unusable user IDs and remove all signatures from key")},
|
N_("compact unusable user IDs and remove all signatures from key")},
|
||||||
|
{ "addsub", cmdADDSUB, KEYEDIT_NEED_SK | KEYEDIT_ONLY_SK,
|
||||||
|
N_("add a subscriber to a mailing list")},
|
||||||
|
{ "rmsub", cmdRMSUB, KEYEDIT_NEED_SK | KEYEDIT_ONLY_SK,
|
||||||
|
N_("add a subscriber to a mailing list")},
|
||||||
|
|
||||||
{ NULL, cmdNONE, 0, NULL}
|
{ NULL, cmdNONE, 0, NULL}
|
||||||
};
|
};
|
||||||
@ -2182,6 +2189,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
|
|||||||
assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
|
assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
|
||||||
show_names (NULL, keyblock, keyblock->pkt->pkt.public_key,
|
show_names (NULL, keyblock, keyblock->pkt->pkt.public_key,
|
||||||
count ? NODFLG_SELUID : 0, 2);
|
count ? NODFLG_SELUID : 0, 2);
|
||||||
|
kbnode_dump (keyblock);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2269,6 +2277,23 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
|
|||||||
redisplay = modified = 1;
|
redisplay = modified = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case cmdADDSUB:
|
||||||
|
if (menu_addsub (ctrl, keyblock, arg_string))
|
||||||
|
{
|
||||||
|
redisplay = 1;
|
||||||
|
modified = 1;
|
||||||
|
merge_keys_and_selfsig (keyblock);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case cmdRMSUB:
|
||||||
|
if (menu_rmsub (ctrl, keyblock, arg_string))
|
||||||
|
{
|
||||||
|
redisplay = 1;
|
||||||
|
modified = 1;
|
||||||
|
merge_keys_and_selfsig (keyblock);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case cmdQUIT:
|
case cmdQUIT:
|
||||||
if (have_commands)
|
if (have_commands)
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -2639,6 +2664,17 @@ tty_print_notations (int indent, PKT_signature * sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
show_notations (PKT_signature * selfsig)
|
||||||
|
{
|
||||||
|
if (selfsig->flags.notation)
|
||||||
|
{
|
||||||
|
tty_printf (" ");
|
||||||
|
tty_printf (_("Notations: "));
|
||||||
|
tty_print_notations (5 + strlen (_("Notations: ")), selfsig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show preferences of a public keyblock.
|
* Show preferences of a public keyblock.
|
||||||
*/
|
*/
|
||||||
@ -2777,12 +2813,7 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
|
|||||||
tty_printf ("\n");
|
tty_printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selfsig->flags.notation)
|
show_notations (selfsig);
|
||||||
{
|
|
||||||
tty_printf (" ");
|
|
||||||
tty_printf (_("Notations: "));
|
|
||||||
tty_print_notations (5 + strlen (_("Notations: ")), selfsig);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2974,21 +3005,56 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
show_names (estream_t fp,
|
show_names (estream_t fp,
|
||||||
KBNODE keyblock, PKT_public_key * pk, unsigned int flag,
|
KBNODE keyblock, PKT_public_key * pk, unsigned int flag,
|
||||||
int with_prefs)
|
int with_prefs)
|
||||||
{
|
{
|
||||||
KBNODE node;
|
KBNODE node;
|
||||||
int i = 0;
|
int userids = 0;
|
||||||
|
int keys = 0;
|
||||||
|
|
||||||
for (node = keyblock; node; node = node->next)
|
for (node = keyblock; node; node = node->next)
|
||||||
{
|
{
|
||||||
if (node->pkt->pkttype == PKT_USER_ID && !is_deleted_kbnode (node))
|
if ((node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||||
|
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||||
|
&& !is_deleted_kbnode (node))
|
||||||
|
{
|
||||||
|
PKT_public_key *pk2 = node->pkt->pkt.public_key;
|
||||||
|
++ keys;
|
||||||
|
|
||||||
|
if (with_prefs && pk)
|
||||||
|
{
|
||||||
|
if (pk->version > 3 || pk2->selfsigversion > 3)
|
||||||
|
{
|
||||||
|
KBNODE signode;
|
||||||
|
|
||||||
|
for (signode = node->next;
|
||||||
|
signode && signode->pkt->pkttype == PKT_SIGNATURE;
|
||||||
|
signode = signode->next)
|
||||||
|
{
|
||||||
|
PKT_signature *selfsig = signode->pkt->pkt.signature;
|
||||||
|
|
||||||
|
if (selfsig->flags.notation)
|
||||||
|
{
|
||||||
|
tty_printf (" Self-sig from %s on %s %s:\n",
|
||||||
|
isotimestamp (pk->timestamp),
|
||||||
|
node == keyblock
|
||||||
|
? "primary key" : "subkey",
|
||||||
|
keystr (pk2->keyid));
|
||||||
|
show_notations (selfsig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tty_fprintf (fp, _("There are no preferences on a"
|
||||||
|
" PGP 2.x-style KEY.\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (node->pkt->pkttype == PKT_USER_ID && !is_deleted_kbnode (node))
|
||||||
{
|
{
|
||||||
PKT_user_id *uid = node->pkt->pkt.user_id;
|
PKT_user_id *uid = node->pkt->pkt.user_id;
|
||||||
++i;
|
++userids;
|
||||||
if (!flag || (flag && (node->flag & flag)))
|
if (!flag || (flag && (node->flag & flag)))
|
||||||
{
|
{
|
||||||
if (!(flag & NODFLG_MARK_A) && pk)
|
if (!(flag & NODFLG_MARK_A) && pk)
|
||||||
@ -2997,11 +3063,11 @@ show_names (estream_t fp,
|
|||||||
if (flag & NODFLG_MARK_A)
|
if (flag & NODFLG_MARK_A)
|
||||||
tty_fprintf (fp, " ");
|
tty_fprintf (fp, " ");
|
||||||
else if (node->flag & NODFLG_SELUID)
|
else if (node->flag & NODFLG_SELUID)
|
||||||
tty_fprintf (fp, "(%d)* ", i);
|
tty_fprintf (fp, "(%d)* ", userids);
|
||||||
else if (uid->is_primary)
|
else if (uid->is_primary)
|
||||||
tty_fprintf (fp, "(%d). ", i);
|
tty_fprintf (fp, "(%d). ", userids);
|
||||||
else
|
else
|
||||||
tty_fprintf (fp, "(%d) ", i);
|
tty_fprintf (fp, "(%d) ", userids);
|
||||||
tty_print_utf8_string2 (fp, uid->name, uid->len, 0);
|
tty_print_utf8_string2 (fp, uid->name, uid->len, 0);
|
||||||
tty_fprintf (fp, "\n");
|
tty_fprintf (fp, "\n");
|
||||||
if (with_prefs && pk)
|
if (with_prefs && pk)
|
||||||
@ -3590,7 +3656,7 @@ menu_adduid (kbnode_t pub_keyblock, int photo, const char *photo_name,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x13, 0, 0, 0,
|
err = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x13, 0, 0, 0, NULL,
|
||||||
keygen_add_std_prefs, pk, NULL);
|
keygen_add_std_prefs, pk, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
@ -3973,7 +4039,7 @@ menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = make_keysig_packet (&sig, pk, NULL, NULL, pk, 0x1F, 0, 0, 0,
|
rc = make_keysig_packet (&sig, pk, NULL, NULL, pk, 0x1F, 0, 0, 0, NULL,
|
||||||
keygen_add_revkey, &revkey, NULL);
|
keygen_add_revkey, &revkey, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -4080,12 +4146,13 @@ menu_expire (KBNODE pub_keyblock)
|
|||||||
|
|
||||||
if (mainkey)
|
if (mainkey)
|
||||||
rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL,
|
rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL,
|
||||||
main_pk, keygen_add_key_expire,
|
main_pk, NULL,
|
||||||
main_pk);
|
keygen_add_key_expire, main_pk);
|
||||||
else
|
else
|
||||||
rc =
|
rc =
|
||||||
update_keysig_packet (&newsig, sig, main_pk, NULL, sub_pk,
|
update_keysig_packet (&newsig, sig, main_pk, NULL, sub_pk,
|
||||||
main_pk, keygen_add_key_expire, sub_pk);
|
main_pk, NULL,
|
||||||
|
keygen_add_key_expire, sub_pk);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error ("make_keysig_packet failed: %s\n",
|
log_error ("make_keysig_packet failed: %s\n",
|
||||||
@ -4188,7 +4255,7 @@ menu_backsign (KBNODE pub_keyblock)
|
|||||||
PACKET *newpkt;
|
PACKET *newpkt;
|
||||||
|
|
||||||
rc = update_keysig_packet (&newsig, sig_pk->pkt->pkt.signature,
|
rc = update_keysig_packet (&newsig, sig_pk->pkt->pkt.signature,
|
||||||
main_pk, NULL, sub_pk, main_pk,
|
main_pk, NULL, sub_pk, main_pk, NULL,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
@ -4341,7 +4408,7 @@ menu_set_primary_uid (KBNODE pub_keyblock)
|
|||||||
{
|
{
|
||||||
int rc = update_keysig_packet (&newsig, sig,
|
int rc = update_keysig_packet (&newsig, sig,
|
||||||
main_pk, uid, NULL,
|
main_pk, uid, NULL,
|
||||||
main_pk,
|
main_pk, NULL,
|
||||||
change_primary_uid_cb,
|
change_primary_uid_cb,
|
||||||
action > 0 ? "x" : NULL);
|
action > 0 ? "x" : NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -4431,7 +4498,7 @@ menu_set_preferences (KBNODE pub_keyblock)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = update_keysig_packet (&newsig, sig,
|
rc = update_keysig_packet (&newsig, sig,
|
||||||
main_pk, uid, NULL, main_pk,
|
main_pk, uid, NULL, main_pk, NULL,
|
||||||
keygen_upd_std_prefs, NULL);
|
keygen_upd_std_prefs, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -4566,7 +4633,7 @@ menu_set_keyserver_url (const char *url, KBNODE pub_keyblock)
|
|||||||
|
|
||||||
rc = update_keysig_packet (&newsig, sig,
|
rc = update_keysig_packet (&newsig, sig,
|
||||||
main_pk, uid, NULL,
|
main_pk, uid, NULL,
|
||||||
main_pk,
|
main_pk, NULL,
|
||||||
keygen_add_keyserver_url, uri);
|
keygen_add_keyserver_url, uri);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -4765,7 +4832,7 @@ menu_set_notation (const char *string, KBNODE pub_keyblock)
|
|||||||
|
|
||||||
rc = update_keysig_packet (&newsig, sig,
|
rc = update_keysig_packet (&newsig, sig,
|
||||||
main_pk, uid, NULL,
|
main_pk, uid, NULL,
|
||||||
main_pk,
|
main_pk, NULL,
|
||||||
keygen_add_notations, notation);
|
keygen_add_notations, notation);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -5358,7 +5425,7 @@ reloop: /* (must use this, because we are modifing the list) */
|
|||||||
}
|
}
|
||||||
rc = make_keysig_packet (&sig, primary_pk,
|
rc = make_keysig_packet (&sig, primary_pk,
|
||||||
unode->pkt->pkt.user_id,
|
unode->pkt->pkt.user_id,
|
||||||
NULL, signerkey, 0x30, 0, 0, 0,
|
NULL, signerkey, 0x30, 0, 0, 0, NULL,
|
||||||
sign_mk_attrib, &attrib, NULL);
|
sign_mk_attrib, &attrib, NULL);
|
||||||
free_public_key (signerkey);
|
free_public_key (signerkey);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -5451,7 +5518,7 @@ menu_revuid (KBNODE pub_keyblock)
|
|||||||
node->flag &= ~NODFLG_SELUID;
|
node->flag &= ~NODFLG_SELUID;
|
||||||
|
|
||||||
rc = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x30, 0,
|
rc = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x30, 0,
|
||||||
timestamp, 0,
|
timestamp, 0, NULL,
|
||||||
sign_mk_attrib, &attrib, NULL);
|
sign_mk_attrib, &attrib, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -5516,7 +5583,7 @@ menu_revkey (KBNODE pub_keyblock)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rc = make_keysig_packet (&sig, pk, NULL, NULL, pk,
|
rc = make_keysig_packet (&sig, pk, NULL, NULL, pk,
|
||||||
0x20, 0, 0, 0,
|
0x20, 0, 0, 0, NULL,
|
||||||
revocation_reason_build_cb, reason, NULL);
|
revocation_reason_build_cb, reason, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -5578,8 +5645,8 @@ menu_revsubkey (KBNODE pub_keyblock)
|
|||||||
|
|
||||||
node->flag &= ~NODFLG_SELKEY;
|
node->flag &= ~NODFLG_SELKEY;
|
||||||
rc = make_keysig_packet (&sig, mainpk, NULL, subpk, mainpk,
|
rc = make_keysig_packet (&sig, mainpk, NULL, subpk, mainpk,
|
||||||
0x28, 0, 0, 0, sign_mk_attrib, &attrib,
|
0x28, 0, 0, 0, NULL,
|
||||||
NULL);
|
sign_mk_attrib, &attrib, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
write_status_error ("keysig", rc);
|
write_status_error ("keysig", rc);
|
||||||
@ -5676,3 +5743,40 @@ menu_showphoto (KBNODE keyblock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
menu_addsub (ctrl_t ctrl, KBNODE keyblock, const char *sub)
|
||||||
|
{
|
||||||
|
if (! sub || ! *sub)
|
||||||
|
/* XXX: testing hack, remove. */
|
||||||
|
// sub = "72DC07B5";
|
||||||
|
sub = "32C5067D";
|
||||||
|
|
||||||
|
if (! sub || ! *sub)
|
||||||
|
{
|
||||||
|
tty_printf (_("Usage: addsub KEYID\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mailing_list_add_subscriber (ctrl, keyblock, sub) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
menu_rmsub (ctrl_t ctrl, KBNODE keyblock, const char *sub)
|
||||||
|
{
|
||||||
|
PKT_public_key *pk = keyblock->pkt->pkt.public_key;
|
||||||
|
|
||||||
|
if (! sub || ! *sub)
|
||||||
|
sub = "E3AC040E";
|
||||||
|
|
||||||
|
if (! sub || ! *sub)
|
||||||
|
{
|
||||||
|
tty_printf (_("Usage: rmsub KEYID\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("rmsub %s %s\n", keystr (pk->keyid), sub);
|
||||||
|
|
||||||
|
return mailing_list_rm_subscriber (ctrl, keyblock, sub) == 0;
|
||||||
|
}
|
||||||
|
159
g10/keygen.c
159
g10/keygen.c
@ -89,7 +89,8 @@ enum para_name {
|
|||||||
pSERIALNO,
|
pSERIALNO,
|
||||||
pCARDBACKUPKEY,
|
pCARDBACKUPKEY,
|
||||||
pHANDLE,
|
pHANDLE,
|
||||||
pKEYSERVER
|
pKEYSERVER,
|
||||||
|
pMAILINGLIST
|
||||||
};
|
};
|
||||||
|
|
||||||
struct para_data_s {
|
struct para_data_s {
|
||||||
@ -102,6 +103,7 @@ struct para_data_s {
|
|||||||
unsigned int usage;
|
unsigned int usage;
|
||||||
struct revocation_key revkey;
|
struct revocation_key revkey;
|
||||||
char value[1];
|
char value[1];
|
||||||
|
int is_mailing_list;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -807,7 +809,7 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk,
|
|||||||
cache_public_key (sub_pk);
|
cache_public_key (sub_pk);
|
||||||
|
|
||||||
err = make_keysig_packet (&backsig, pk, NULL, sub_pk, sub_psk, 0x19,
|
err = make_keysig_packet (&backsig, pk, NULL, sub_pk, sub_psk, 0x19,
|
||||||
0, timestamp, 0, NULL, NULL, cache_nonce);
|
0, timestamp, 0, NULL, NULL, NULL, cache_nonce);
|
||||||
if (err)
|
if (err)
|
||||||
log_error ("make_keysig_packet failed for backsig: %s\n",
|
log_error ("make_keysig_packet failed for backsig: %s\n",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
@ -915,7 +917,7 @@ write_direct_sig (KBNODE root, PKT_public_key *psk,
|
|||||||
|
|
||||||
/* Make the signature. */
|
/* Make the signature. */
|
||||||
err = make_keysig_packet (&sig, pk, NULL,NULL, psk, 0x1F,
|
err = make_keysig_packet (&sig, pk, NULL,NULL, psk, 0x1F,
|
||||||
0, timestamp, 0,
|
0, timestamp, 0, NULL,
|
||||||
keygen_add_revkey, revkey, cache_nonce);
|
keygen_add_revkey, revkey, cache_nonce);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
@ -931,13 +933,13 @@ write_direct_sig (KBNODE root, PKT_public_key *psk,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Write a self-signature to the first user id in ROOT using the key
|
/* Write a self-signature to the first user id in ROOT using the key
|
||||||
PSK. USE and TIMESTAMP give the extra data we need for the
|
PSK. USE and TIMESTAMP give the extra data we need for the
|
||||||
signature. */
|
signature. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
write_selfsigs (KBNODE root, PKT_public_key *psk,
|
write_selfsigs (KBNODE root, PKT_public_key *psk,
|
||||||
unsigned int use, u32 timestamp, const char *cache_nonce)
|
unsigned int use, u32 timestamp,
|
||||||
|
int mailing_list, const char *cache_nonce)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
PACKET *pkt;
|
PACKET *pkt;
|
||||||
@ -945,6 +947,7 @@ write_selfsigs (KBNODE root, PKT_public_key *psk,
|
|||||||
PKT_user_id *uid;
|
PKT_user_id *uid;
|
||||||
KBNODE node;
|
KBNODE node;
|
||||||
PKT_public_key *pk;
|
PKT_public_key *pk;
|
||||||
|
struct notation *notations = NULL;
|
||||||
|
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info (_("writing self signature\n"));
|
log_info (_("writing self signature\n"));
|
||||||
@ -968,10 +971,95 @@ write_selfsigs (KBNODE root, PKT_public_key *psk,
|
|||||||
signature creation is able to retrieve the public key. */
|
signature creation is able to retrieve the public key. */
|
||||||
cache_public_key (pk);
|
cache_public_key (pk);
|
||||||
|
|
||||||
|
if (mailing_list)
|
||||||
|
/* Add the mailing-list notation. */
|
||||||
|
{
|
||||||
|
char *notation = "mailing-list@gnupg.org=1";
|
||||||
|
struct notation *notation_blob;
|
||||||
|
|
||||||
|
notation_blob = string_to_notation (notation, 0);
|
||||||
|
if (! notation_blob)
|
||||||
|
{
|
||||||
|
log_bug ("Failed to create notation: %s\n", notation);
|
||||||
|
return gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
notation_blob->next = notations;
|
||||||
|
notations = notation_blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mailing_list)
|
||||||
|
/* Add the subscriber-list-session-key notation. */
|
||||||
|
{
|
||||||
|
char *notation = "subscriber-list-session-key@gnupg.org";
|
||||||
|
struct pk_list pk_list;
|
||||||
|
/* The public key encrypted session key as a packet. */
|
||||||
|
iobuf_t pk_esk;
|
||||||
|
DEK session_key_initial;
|
||||||
|
char *buffer;
|
||||||
|
size_t len;
|
||||||
|
struct notation *notation_blob;
|
||||||
|
|
||||||
|
/* The initial session key encrypted with the new subscriber's
|
||||||
|
public key. */
|
||||||
|
/* Initialize PK_LIST with just the encryption key. */
|
||||||
|
pk_list.next = NULL;
|
||||||
|
pk_list.pk = pk;
|
||||||
|
/* Don't throw the key id. */
|
||||||
|
pk_list.flags = 0;
|
||||||
|
|
||||||
|
pk_esk = iobuf_temp ();
|
||||||
|
if (! pk_esk)
|
||||||
|
{
|
||||||
|
log_bug ("Out of memory allocating pk_esk\n");
|
||||||
|
return gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (&session_key_initial, 0, sizeof (session_key_initial));
|
||||||
|
session_key_initial.algo = default_cipher_algo ();
|
||||||
|
make_session_key (&session_key_initial);
|
||||||
|
|
||||||
|
/* We don't need ctrl: we are certain that pk_list doesn't
|
||||||
|
contain a mailing list key, which is the only thing that
|
||||||
|
write_pubkey_enc_from_list needs ctrl for. */
|
||||||
|
err = write_pubkey_enc_from_list (NULL, &pk_list,
|
||||||
|
&session_key_initial, pk_esk);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_bug ("Failed to generate PK-ESK packet: %s\n",
|
||||||
|
gpg_strerror (err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = iobuf_get_temp_buffer (pk_esk);
|
||||||
|
len = iobuf_get_temp_length (pk_esk);
|
||||||
|
|
||||||
|
notation_blob = blob_to_notation (notation, buffer, len);
|
||||||
|
if (! notation_blob)
|
||||||
|
{
|
||||||
|
log_bug ("Failed to create notation: %s=<SE-ESK packet, %zd bytes>\n",
|
||||||
|
notation, len);
|
||||||
|
return gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
FILE *fp = fopen ("/tmp/subscriber-list-session-key", "w");
|
||||||
|
fwrite (buffer, len, 1, fp);
|
||||||
|
fclose (fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
notation_blob->next = notations;
|
||||||
|
notations = notation_blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Make the signature. */
|
/* Make the signature. */
|
||||||
|
/* We pass a callback (keygen_add_std_prefs) to add some extra data
|
||||||
|
to the self-signature. */
|
||||||
err = make_keysig_packet (&sig, pk, uid, NULL, psk, 0x13,
|
err = make_keysig_packet (&sig, pk, uid, NULL, psk, 0x13,
|
||||||
0, timestamp, 0,
|
0, timestamp, 0, notations,
|
||||||
keygen_add_std_prefs, pk, cache_nonce);
|
keygen_add_std_prefs, pk, cache_nonce);
|
||||||
|
free_notation (notations);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_error ("make_keysig_packet failed: %s\n", gpg_strerror (err));
|
log_error ("make_keysig_packet failed: %s\n", gpg_strerror (err));
|
||||||
@ -991,9 +1079,10 @@ write_selfsigs (KBNODE root, PKT_public_key *psk,
|
|||||||
signature creation time. PRI_PSK is the key use for signing.
|
signature creation time. PRI_PSK is the key use for signing.
|
||||||
SUB_PSK is a key used to create a back-signature; that one is only
|
SUB_PSK is a key used to create a back-signature; that one is only
|
||||||
used if USE has the PUBKEY_USAGE_SIG capability. */
|
used if USE has the PUBKEY_USAGE_SIG capability. */
|
||||||
static int
|
int
|
||||||
write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk,
|
write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk,
|
||||||
unsigned int use, u32 timestamp, const char *cache_nonce)
|
unsigned int use, u32 timestamp, const char *cache_nonce,
|
||||||
|
struct notation *notations)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
PACKET *pkt;
|
PACKET *pkt;
|
||||||
@ -1029,7 +1118,7 @@ write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk,
|
|||||||
oduap.usage = use;
|
oduap.usage = use;
|
||||||
oduap.pk = sub_pk;
|
oduap.pk = sub_pk;
|
||||||
err = make_keysig_packet (&sig, pri_pk, NULL, sub_pk, pri_psk, 0x18,
|
err = make_keysig_packet (&sig, pri_pk, NULL, sub_pk, pri_psk, 0x18,
|
||||||
0, timestamp, 0,
|
0, timestamp, 0, notations,
|
||||||
keygen_add_key_flags_and_expire, &oduap,
|
keygen_add_key_flags_and_expire, &oduap,
|
||||||
cache_nonce);
|
cache_nonce);
|
||||||
if (err)
|
if (err)
|
||||||
@ -2471,7 +2560,7 @@ uid_already_in_keyblock (kbnode_t keyblock, const char *uid)
|
|||||||
the function prevents the creation of an already existing user
|
the function prevents the creation of an already existing user
|
||||||
ID. IF FULL is not set some prompts are not shown. */
|
ID. IF FULL is not set some prompts are not shown. */
|
||||||
static char *
|
static char *
|
||||||
ask_user_id (int mode, int full, KBNODE keyblock)
|
ask_user_id (int mode, int full, int mailing_list, KBNODE keyblock)
|
||||||
{
|
{
|
||||||
char *answer;
|
char *answer;
|
||||||
char *aname, *acomment, *amail, *uid;
|
char *aname, *acomment, *amail, *uid;
|
||||||
@ -2557,7 +2646,10 @@ ask_user_id (int mode, int full, KBNODE keyblock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!acomment) {
|
if (!acomment) {
|
||||||
if (full) {
|
if (mailing_list) {
|
||||||
|
xfree (acomment);
|
||||||
|
acomment = xstrdup ("mailing list");
|
||||||
|
} else if (full) {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
xfree(acomment);
|
xfree(acomment);
|
||||||
acomment = cpr_get("keygen.comment",_("Comment: "));
|
acomment = cpr_get("keygen.comment",_("Comment: "));
|
||||||
@ -2766,7 +2858,7 @@ generate_user_id (KBNODE keyblock, const char *uidstr)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p = ask_user_id (1, 1, keyblock);
|
p = ask_user_id (1, 1, 0, keyblock);
|
||||||
if (!p)
|
if (!p)
|
||||||
return NULL; /* Canceled. */
|
return NULL; /* Canceled. */
|
||||||
uid = uid_from_string (p);
|
uid = uid_from_string (p);
|
||||||
@ -2974,6 +3066,8 @@ get_parameter_u32( struct para_data_s *para, enum para_name key )
|
|||||||
return r->u.expire;
|
return r->u.expire;
|
||||||
if( r->key == pKEYUSAGE || r->key == pSUBKEYUSAGE )
|
if( r->key == pKEYUSAGE || r->key == pSUBKEYUSAGE )
|
||||||
return r->u.usage;
|
return r->u.usage;
|
||||||
|
if( r->key == pMAILINGLIST )
|
||||||
|
return r->u.is_mailing_list;
|
||||||
|
|
||||||
return (unsigned int)strtoul( r->u.value, NULL, 10 );
|
return (unsigned int)strtoul( r->u.value, NULL, 10 );
|
||||||
}
|
}
|
||||||
@ -3436,13 +3530,14 @@ quickgen_set_para (struct para_data_s *para, int for_subkey,
|
|||||||
* Unattended generation of a standard key.
|
* Unattended generation of a standard key.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
quick_generate_keypair (ctrl_t ctrl, const char *uid)
|
quick_generate_keypair (ctrl_t ctrl, const char *uid, int mailing_list)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
struct para_data_s *para = NULL;
|
struct para_data_s *para = NULL;
|
||||||
struct para_data_s *r;
|
struct para_data_s *r;
|
||||||
struct output_control_s outctrl;
|
struct output_control_s outctrl;
|
||||||
int use_tty;
|
int use_tty;
|
||||||
|
const char *mailing_list_comment = " (mailing list)";
|
||||||
|
|
||||||
memset (&outctrl, 0, sizeof outctrl);
|
memset (&outctrl, 0, sizeof outctrl);
|
||||||
|
|
||||||
@ -3452,9 +3547,12 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid)
|
|||||||
&& gnupg_isatty (fileno (stdout))
|
&& gnupg_isatty (fileno (stdout))
|
||||||
&& gnupg_isatty (fileno (stderr)));
|
&& gnupg_isatty (fileno (stderr)));
|
||||||
|
|
||||||
r = xmalloc_clear (sizeof *r + strlen (uid));
|
r = xmalloc_clear (sizeof *r + strlen (uid)
|
||||||
|
+ (mailing_list ? strlen (mailing_list_comment) : 0));
|
||||||
r->key = pUSERID;
|
r->key = pUSERID;
|
||||||
strcpy (r->u.value, uid);
|
strcpy (r->u.value, uid);
|
||||||
|
if (mailing_list_comment)
|
||||||
|
strcat (r->u.value, mailing_list_comment);
|
||||||
r->next = para;
|
r->next = para;
|
||||||
para = r;
|
para = r;
|
||||||
|
|
||||||
@ -3476,6 +3574,15 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mailing_list)
|
||||||
|
{
|
||||||
|
r = xcalloc (1, sizeof *r );
|
||||||
|
r->key = pMAILINGLIST;
|
||||||
|
r->u.is_mailing_list = 1;
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check whether such a user ID already exists. */
|
/* Check whether such a user ID already exists. */
|
||||||
{
|
{
|
||||||
KEYDB_HANDLE kdbhd;
|
KEYDB_HANDLE kdbhd;
|
||||||
@ -3545,7 +3652,7 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid)
|
|||||||
* mode).
|
* mode).
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
generate_keypair (ctrl_t ctrl, int full, int mailing_list, const char *fname,
|
||||||
const char *card_serialno, int card_backup_key)
|
const char *card_serialno, int card_backup_key)
|
||||||
{
|
{
|
||||||
unsigned int nbits;
|
unsigned int nbits;
|
||||||
@ -3577,6 +3684,15 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mailing_list)
|
||||||
|
{
|
||||||
|
r = xcalloc (1, sizeof *r );
|
||||||
|
r->key = pMAILINGLIST;
|
||||||
|
r->u.is_mailing_list = 1;
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
}
|
||||||
|
|
||||||
if (card_serialno)
|
if (card_serialno)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_CARD_SUPPORT
|
#ifdef ENABLE_CARD_SUPPORT
|
||||||
@ -3787,7 +3903,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
|||||||
r->next = para;
|
r->next = para;
|
||||||
para = r;
|
para = r;
|
||||||
|
|
||||||
uid = ask_user_id (0, full, NULL);
|
uid = ask_user_id (0, full, mailing_list, NULL);
|
||||||
if (!uid)
|
if (!uid)
|
||||||
{
|
{
|
||||||
log_error(_("Key generation canceled.\n"));
|
log_error(_("Key generation canceled.\n"));
|
||||||
@ -4071,6 +4187,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
|||||||
write_uid (pub_root, s );
|
write_uid (pub_root, s );
|
||||||
err = write_selfsigs (pub_root, pri_psk,
|
err = write_selfsigs (pub_root, pri_psk,
|
||||||
get_parameter_uint (para, pKEYUSAGE), timestamp,
|
get_parameter_uint (para, pKEYUSAGE), timestamp,
|
||||||
|
get_parameter_uint (para, pMAILINGLIST),
|
||||||
cache_nonce);
|
cache_nonce);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4088,7 +4205,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
|||||||
get_parameter_u32 (para, pKEYEXPIRE));
|
get_parameter_u32 (para, pKEYEXPIRE));
|
||||||
if (!err)
|
if (!err)
|
||||||
err = write_keybinding (pub_root, pri_psk, NULL,
|
err = write_keybinding (pub_root, pri_psk, NULL,
|
||||||
PUBKEY_USAGE_AUTH, timestamp, cache_nonce);
|
PUBKEY_USAGE_AUTH, timestamp, cache_nonce,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!err && get_parameter (para, pSUBKEYTYPE))
|
if (!err && get_parameter (para, pSUBKEYTYPE))
|
||||||
@ -4129,7 +4247,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
|||||||
if (!err)
|
if (!err)
|
||||||
err = write_keybinding (pub_root, pri_psk, sub_psk,
|
err = write_keybinding (pub_root, pri_psk, sub_psk,
|
||||||
get_parameter_uint (para, pSUBKEYUSAGE),
|
get_parameter_uint (para, pSUBKEYUSAGE),
|
||||||
timestamp, cache_nonce);
|
timestamp, cache_nonce, NULL);
|
||||||
did_sub = 1;
|
did_sub = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4334,7 +4452,8 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock)
|
|||||||
sub_psk = node->pkt->pkt.public_key;
|
sub_psk = node->pkt->pkt.public_key;
|
||||||
|
|
||||||
/* Write the binding signature. */
|
/* Write the binding signature. */
|
||||||
err = write_keybinding (keyblock, pri_psk, sub_psk, use, cur_time, NULL);
|
err = write_keybinding (keyblock, pri_psk, sub_psk, use, cur_time,
|
||||||
|
NULL, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -4437,7 +4556,7 @@ generate_card_subkeypair (kbnode_t pub_keyblock,
|
|||||||
sub_pk = node->pkt->pkt.public_key;
|
sub_pk = node->pkt->pkt.public_key;
|
||||||
assert (sub_pk);
|
assert (sub_pk);
|
||||||
err = write_keybinding (pub_keyblock, pri_pk, sub_pk,
|
err = write_keybinding (pub_keyblock, pri_pk, sub_pk,
|
||||||
use, cur_time, NULL);
|
use, cur_time, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
1040
g10/mailing-list.c
Normal file
1040
g10/mailing-list.c
Normal file
File diff suppressed because it is too large
Load Diff
44
g10/mailing-list.h
Normal file
44
g10/mailing-list.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* mailing-list.h - Manage an encrypted mailing list.
|
||||||
|
* Copyright (C) 2015 Neal H. Walfield <neal@walfield.org>
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef G10_MAILING_LIST_H
|
||||||
|
#define G10_MAILING_LIST_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "dek.h"
|
||||||
|
|
||||||
|
void kbnode_dump (KBNODE kb);
|
||||||
|
|
||||||
|
/* Get a copy of all the session keys and store them in *DEKS and the
|
||||||
|
total count in *NDEKS. On success, the caller must xfree
|
||||||
|
deksp. */
|
||||||
|
gpg_error_t mailing_list_get_subscriber_list_session_keys (
|
||||||
|
ctrl_t ctrl, KBNODE kb, DEK **deksp, int *ndeksp);
|
||||||
|
|
||||||
|
gpg_error_t mailing_list_add_subscriber (ctrl_t ctrl,
|
||||||
|
KBNODE ml_kb, const char *sub);
|
||||||
|
|
||||||
|
gpg_error_t mailing_list_rm_subscriber (ctrl_t ctrl, KBNODE ml_kb,
|
||||||
|
const char *sub_orig);
|
||||||
|
|
||||||
|
gpg_error_t mailing_list_subscribers (ctrl_t ctrl, KBNODE kb,
|
||||||
|
PK_LIST *pklistp);
|
||||||
|
|
||||||
|
#endif
|
16
g10/main.h
16
g10/main.h
@ -59,6 +59,7 @@ typedef struct
|
|||||||
DEK *symkey_dek;
|
DEK *symkey_dek;
|
||||||
STRING2KEY *symkey_s2k;
|
STRING2KEY *symkey_s2k;
|
||||||
cipher_filter_context_t cfx;
|
cipher_filter_context_t cfx;
|
||||||
|
ctrl_t ctrl;
|
||||||
} encrypt_filter_context_t;
|
} encrypt_filter_context_t;
|
||||||
|
|
||||||
|
|
||||||
@ -221,6 +222,8 @@ void display_online_help( const char *keyword );
|
|||||||
|
|
||||||
/*-- encode.c --*/
|
/*-- encode.c --*/
|
||||||
int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
|
int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
|
||||||
|
int write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
|
||||||
|
iobuf_t out);
|
||||||
int use_mdc (pk_list_t pk_list,int algo);
|
int use_mdc (pk_list_t pk_list,int algo);
|
||||||
int encrypt_symmetric (const char *filename );
|
int encrypt_symmetric (const char *filename );
|
||||||
int encrypt_store (const char *filename );
|
int encrypt_store (const char *filename );
|
||||||
@ -231,7 +234,11 @@ void encrypt_crypt_files (ctrl_t ctrl,
|
|||||||
int nfiles, char **files, strlist_t remusr);
|
int nfiles, char **files, strlist_t remusr);
|
||||||
int encrypt_filter (void *opaque, int control,
|
int encrypt_filter (void *opaque, int control,
|
||||||
iobuf_t a, byte *buf, size_t *ret_len);
|
iobuf_t a, byte *buf, size_t *ret_len);
|
||||||
|
int write_pubkey_enc_from_list(ctrl_t ctrl, PK_LIST pk_list, DEK *dek, iobuf_t out );
|
||||||
|
|
||||||
|
gpg_error_t symmetric_encrypt_buffer (DEK *dek, const char *password,
|
||||||
|
char *inbuffer, size_t inlen,
|
||||||
|
char **outbuffer, size_t *outlen);
|
||||||
|
|
||||||
/*-- sign.c --*/
|
/*-- sign.c --*/
|
||||||
int complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md,
|
int complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md,
|
||||||
@ -280,10 +287,15 @@ void show_basic_key_info (KBNODE keyblock);
|
|||||||
u32 parse_expire_string(const char *string);
|
u32 parse_expire_string(const char *string);
|
||||||
u32 ask_expire_interval(int object,const char *def_expire);
|
u32 ask_expire_interval(int object,const char *def_expire);
|
||||||
u32 ask_expiredate(void);
|
u32 ask_expiredate(void);
|
||||||
void quick_generate_keypair (ctrl_t ctrl, const char *uid);
|
void quick_generate_keypair (ctrl_t ctrl, const char *uid, int mailing_list);
|
||||||
void generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
void generate_keypair (ctrl_t ctrl, int full, int mailing_list,
|
||||||
|
const char *fname,
|
||||||
const char *card_serialno, int card_backup_key);
|
const char *card_serialno, int card_backup_key);
|
||||||
int keygen_set_std_prefs (const char *string,int personal);
|
int keygen_set_std_prefs (const char *string,int personal);
|
||||||
|
int write_keybinding (KBNODE root,
|
||||||
|
PKT_public_key *pri_psk, PKT_public_key *sub_psk,
|
||||||
|
unsigned int use, u32 timestamp, const char *cache_nonce,
|
||||||
|
struct notation *notation);
|
||||||
PKT_user_id *keygen_get_std_prefs (void);
|
PKT_user_id *keygen_get_std_prefs (void);
|
||||||
int keygen_add_key_expire( PKT_signature *sig, void *opaque );
|
int keygen_add_key_expire( PKT_signature *sig, void *opaque );
|
||||||
int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
|
int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
|
||||||
|
@ -69,6 +69,8 @@ struct mainproc_context
|
|||||||
md_filter_context_t mfx;
|
md_filter_context_t mfx;
|
||||||
int sigs_only; /* Process only signatures and reject all other stuff. */
|
int sigs_only; /* Process only signatures and reject all other stuff. */
|
||||||
int encrypt_only; /* Process only encryption messages. */
|
int encrypt_only; /* Process only encryption messages. */
|
||||||
|
int symkey_only; /* Just process a SK-ESK packet. */
|
||||||
|
int pubkey_only; /* Just process a PK-ESK packet. */
|
||||||
|
|
||||||
/* Name of the file with the complete signature or the file with the
|
/* Name of the file with the complete signature or the file with the
|
||||||
detached signature. This is currently only used to deduce the
|
detached signature. This is currently only used to deduce the
|
||||||
@ -140,9 +142,12 @@ release_list( CTX c )
|
|||||||
c->any.data = 0;
|
c->any.data = 0;
|
||||||
c->any.uncompress_failed = 0;
|
c->any.uncompress_failed = 0;
|
||||||
c->last_was_session_key = 0;
|
c->last_was_session_key = 0;
|
||||||
|
if (! (c->symkey_only || c->pubkey_only))
|
||||||
|
{
|
||||||
xfree (c->dek);
|
xfree (c->dek);
|
||||||
c->dek = NULL;
|
c->dek = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1242,6 +1247,49 @@ proc_signature_packets (ctrl_t ctrl, void *anchor, iobuf_t a,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
proc_symkey_packet (ctrl_t ctrl, iobuf_t a, DEK *dek)
|
||||||
|
{
|
||||||
|
CTX c = xmalloc_clear (sizeof *c);
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
c->ctrl = ctrl;
|
||||||
|
c->symkey_only = 1;
|
||||||
|
|
||||||
|
rc = do_proc_packets (ctrl, c, a);
|
||||||
|
if (! rc && ! c->dek)
|
||||||
|
rc = gpg_error (GPG_ERR_BAD_KEY);
|
||||||
|
|
||||||
|
if (c->dek)
|
||||||
|
*dek = *c->dek;
|
||||||
|
|
||||||
|
xfree (c->dek);
|
||||||
|
xfree (c);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
proc_pubkey_packet (ctrl_t ctrl, iobuf_t a, DEK *dek)
|
||||||
|
{
|
||||||
|
CTX c = xmalloc_clear (sizeof *c);
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
c->ctrl = ctrl;
|
||||||
|
c->pubkey_only = 1;
|
||||||
|
|
||||||
|
rc = do_proc_packets (ctrl, c, a);
|
||||||
|
if (! rc && ! c->dek)
|
||||||
|
rc = gpg_error (GPG_ERR_BAD_KEY);
|
||||||
|
|
||||||
|
if (c->dek)
|
||||||
|
*dek = *c->dek;
|
||||||
|
|
||||||
|
xfree (c->dek);
|
||||||
|
xfree (c);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
proc_signature_packets_by_fd (ctrl_t ctrl,
|
proc_signature_packets_by_fd (ctrl_t ctrl,
|
||||||
@ -1361,6 +1409,50 @@ do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a)
|
|||||||
default: newpkt = 0; break;
|
default: newpkt = 0; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (c->symkey_only)
|
||||||
|
{
|
||||||
|
switch (pkt->pkttype)
|
||||||
|
{
|
||||||
|
case PKT_PUBLIC_KEY:
|
||||||
|
case PKT_SECRET_KEY:
|
||||||
|
case PKT_USER_ID:
|
||||||
|
case PKT_SIGNATURE:
|
||||||
|
case PKT_PUBKEY_ENC:
|
||||||
|
case PKT_ENCRYPTED_MDC:
|
||||||
|
case PKT_PLAINTEXT:
|
||||||
|
case PKT_COMPRESSED:
|
||||||
|
case PKT_ONEPASS_SIG:
|
||||||
|
case PKT_GPG_CONTROL:
|
||||||
|
write_status_text (STATUS_UNEXPECTED, "0");
|
||||||
|
rc = GPG_ERR_UNEXPECTED;
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
case PKT_SYMKEY_ENC: proc_symkey_enc (c, pkt); break;
|
||||||
|
default: newpkt = 0; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c->pubkey_only)
|
||||||
|
{
|
||||||
|
switch (pkt->pkttype)
|
||||||
|
{
|
||||||
|
case PKT_PUBLIC_KEY:
|
||||||
|
case PKT_SECRET_KEY:
|
||||||
|
case PKT_USER_ID:
|
||||||
|
case PKT_SIGNATURE:
|
||||||
|
case PKT_SYMKEY_ENC:
|
||||||
|
case PKT_ENCRYPTED_MDC:
|
||||||
|
case PKT_PLAINTEXT:
|
||||||
|
case PKT_COMPRESSED:
|
||||||
|
case PKT_ONEPASS_SIG:
|
||||||
|
case PKT_GPG_CONTROL:
|
||||||
|
write_status_text (STATUS_UNEXPECTED, "0");
|
||||||
|
rc = GPG_ERR_UNEXPECTED;
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
case PKT_PUBKEY_ENC: proc_pubkey_enc (ctrl, c, pkt); break;
|
||||||
|
default: newpkt = 0; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (c->sigs_only)
|
else if (c->sigs_only)
|
||||||
{
|
{
|
||||||
switch (pkt->pkttype)
|
switch (pkt->pkttype)
|
||||||
@ -1472,6 +1564,7 @@ do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a)
|
|||||||
|
|
||||||
leave:
|
leave:
|
||||||
release_list (c);
|
release_list (c);
|
||||||
|
if (! (c->symkey_only || c->pubkey_only))
|
||||||
xfree(c->dek);
|
xfree(c->dek);
|
||||||
free_packet (pkt);
|
free_packet (pkt);
|
||||||
xfree (pkt);
|
xfree (pkt);
|
||||||
|
@ -299,6 +299,7 @@ typedef struct
|
|||||||
unsigned int backsig:2; /* 0=none, 1=bad, 2=good. */
|
unsigned int backsig:2; /* 0=none, 1=bad, 2=good. */
|
||||||
unsigned int serialno_valid:1;/* SERIALNO below is valid. */
|
unsigned int serialno_valid:1;/* SERIALNO below is valid. */
|
||||||
unsigned int exact:1; /* Found via exact (!) search. */
|
unsigned int exact:1; /* Found via exact (!) search. */
|
||||||
|
unsigned int mailing_list:1;
|
||||||
} flags;
|
} flags;
|
||||||
PKT_user_id *user_id; /* If != NULL: found by that uid. */
|
PKT_user_id *user_id; /* If != NULL: found by that uid. */
|
||||||
struct revocation_key *revkey;
|
struct revocation_key *revkey;
|
||||||
@ -417,6 +418,9 @@ void reset_literals_seen(void);
|
|||||||
int proc_packets (ctrl_t ctrl, void *ctx, iobuf_t a );
|
int proc_packets (ctrl_t ctrl, void *ctx, iobuf_t a );
|
||||||
int proc_signature_packets (ctrl_t ctrl, void *ctx, iobuf_t a,
|
int proc_signature_packets (ctrl_t ctrl, void *ctx, iobuf_t a,
|
||||||
strlist_t signedfiles, const char *sigfile );
|
strlist_t signedfiles, const char *sigfile );
|
||||||
|
int proc_symkey_packet (ctrl_t ctrl, iobuf_t a, DEK *dek);
|
||||||
|
int proc_pubkey_packet (ctrl_t ctrl, iobuf_t a, DEK *dek);
|
||||||
|
|
||||||
int proc_signature_packets_by_fd (ctrl_t ctrl,
|
int proc_signature_packets_by_fd (ctrl_t ctrl,
|
||||||
void *anchor, IOBUF a, int signed_data_fd );
|
void *anchor, IOBUF a, int signed_data_fd );
|
||||||
int proc_encryption_packets (ctrl_t ctrl, void *ctx, iobuf_t a);
|
int proc_encryption_packets (ctrl_t ctrl, void *ctx, iobuf_t a);
|
||||||
@ -615,6 +619,8 @@ void build_attribute_subpkt(PKT_user_id *uid,byte type,
|
|||||||
const void *buf,u32 buflen,
|
const void *buf,u32 buflen,
|
||||||
const void *header,u32 headerlen);
|
const void *header,u32 headerlen);
|
||||||
struct notation *string_to_notation(const char *string,int is_utf8);
|
struct notation *string_to_notation(const char *string,int is_utf8);
|
||||||
|
struct notation *blob_to_notation(const char *name,
|
||||||
|
const char *data, size_t len);
|
||||||
struct notation *sig_to_notation(PKT_signature *sig);
|
struct notation *sig_to_notation(PKT_signature *sig);
|
||||||
void free_notation(struct notation *notation);
|
void free_notation(struct notation *notation);
|
||||||
|
|
||||||
@ -676,6 +682,7 @@ int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
|||||||
PKT_user_id *uid, PKT_public_key *subpk,
|
PKT_user_id *uid, PKT_public_key *subpk,
|
||||||
PKT_public_key *pksk, int sigclass, int digest_algo,
|
PKT_public_key *pksk, int sigclass, int digest_algo,
|
||||||
u32 timestamp, u32 duration,
|
u32 timestamp, u32 duration,
|
||||||
|
struct notation *notations,
|
||||||
int (*mksubpkt)(PKT_signature *, void *),
|
int (*mksubpkt)(PKT_signature *, void *),
|
||||||
void *opaque,
|
void *opaque,
|
||||||
const char *cache_nonce);
|
const char *cache_nonce);
|
||||||
@ -685,6 +692,7 @@ gpg_error_t update_keysig_packet (PKT_signature **ret_sig,
|
|||||||
PKT_user_id *uid,
|
PKT_user_id *uid,
|
||||||
PKT_public_key *subpk,
|
PKT_public_key *subpk,
|
||||||
PKT_public_key *pksk,
|
PKT_public_key *pksk,
|
||||||
|
struct notation *notation,
|
||||||
int (*mksubpkt)(PKT_signature *, void *),
|
int (*mksubpkt)(PKT_signature *, void *),
|
||||||
void *opaque );
|
void *opaque );
|
||||||
|
|
||||||
|
@ -346,7 +346,7 @@ gen_desig_revoke (ctrl_t ctrl, const char *uname, strlist_t locusr)
|
|||||||
|
|
||||||
/* create it */
|
/* create it */
|
||||||
rc = make_keysig_packet( &sig, pk, NULL, NULL, pk2, 0x20, 0,
|
rc = make_keysig_packet( &sig, pk, NULL, NULL, pk2, 0x20, 0,
|
||||||
0, 0,
|
0, 0, NULL,
|
||||||
revocation_reason_build_cb, reason,
|
revocation_reason_build_cb, reason,
|
||||||
NULL);
|
NULL);
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
@ -473,7 +473,7 @@ create_revocation (const char *filename,
|
|||||||
push_armor_filter (afx, out);
|
push_armor_filter (afx, out);
|
||||||
|
|
||||||
rc = make_keysig_packet (&sig, psk, NULL, NULL, psk, 0x20, 0,
|
rc = make_keysig_packet (&sig, psk, NULL, NULL, psk, 0x20, 0,
|
||||||
0, 0,
|
0, 0, NULL,
|
||||||
revocation_reason_build_cb, reason, cache_nonce);
|
revocation_reason_build_cb, reason, cache_nonce);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
|
@ -747,6 +747,7 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr,
|
|||||||
memset( &zfx, 0, sizeof zfx);
|
memset( &zfx, 0, sizeof zfx);
|
||||||
memset( &mfx, 0, sizeof mfx);
|
memset( &mfx, 0, sizeof mfx);
|
||||||
memset( &efx, 0, sizeof efx);
|
memset( &efx, 0, sizeof efx);
|
||||||
|
efx.ctrl = ctrl;
|
||||||
init_packet( &pkt );
|
init_packet( &pkt );
|
||||||
|
|
||||||
if( filenames ) {
|
if( filenames ) {
|
||||||
@ -1369,6 +1370,7 @@ make_keysig_packet (PKT_signature **ret_sig, PKT_public_key *pk,
|
|||||||
PKT_public_key *pksk,
|
PKT_public_key *pksk,
|
||||||
int sigclass, int digest_algo,
|
int sigclass, int digest_algo,
|
||||||
u32 timestamp, u32 duration,
|
u32 timestamp, u32 duration,
|
||||||
|
struct notation *notations,
|
||||||
int (*mksubpkt)(PKT_signature *, void *), void *opaque,
|
int (*mksubpkt)(PKT_signature *, void *), void *opaque,
|
||||||
const char *cache_nonce)
|
const char *cache_nonce)
|
||||||
{
|
{
|
||||||
@ -1444,6 +1446,9 @@ make_keysig_packet (PKT_signature **ret_sig, PKT_public_key *pk,
|
|||||||
sig->expiredate=sig->timestamp+duration;
|
sig->expiredate=sig->timestamp+duration;
|
||||||
sig->sig_class = sigclass;
|
sig->sig_class = sigclass;
|
||||||
|
|
||||||
|
if (notations)
|
||||||
|
keygen_add_notations (sig, notations);
|
||||||
|
|
||||||
build_sig_subpkt_from_sig( sig );
|
build_sig_subpkt_from_sig( sig );
|
||||||
mk_notation_policy_etc (sig, pk, pksk);
|
mk_notation_policy_etc (sig, pk, pksk);
|
||||||
|
|
||||||
@ -1485,6 +1490,7 @@ update_keysig_packet( PKT_signature **ret_sig,
|
|||||||
PKT_user_id *uid,
|
PKT_user_id *uid,
|
||||||
PKT_public_key *subpk,
|
PKT_public_key *subpk,
|
||||||
PKT_public_key *pksk,
|
PKT_public_key *pksk,
|
||||||
|
struct notation *notations,
|
||||||
int (*mksubpkt)(PKT_signature *, void *),
|
int (*mksubpkt)(PKT_signature *, void *),
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
@ -1552,6 +1558,9 @@ update_keysig_packet( PKT_signature **ret_sig,
|
|||||||
if (mksubpkt)
|
if (mksubpkt)
|
||||||
rc = (*mksubpkt)(sig, opaque);
|
rc = (*mksubpkt)(sig, opaque);
|
||||||
|
|
||||||
|
if (!rc && notations)
|
||||||
|
keygen_add_notations (sig, notations);
|
||||||
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
hash_sigversion_to_magic (md, sig);
|
hash_sigversion_to_magic (md, sig);
|
||||||
gcry_md_final (md);
|
gcry_md_final (md);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user