1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-05-17 08:43:24 +02:00

Initial commit.

This commit is contained in:
Neal H. Walfield 2016-02-01 09:49:16 +01:00
parent e8d2d53053
commit 28fe48cf92
15 changed files with 1866 additions and 146 deletions

View File

@ -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) \

View File

@ -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(&notation->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," ]");
} }

View File

@ -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);

View File

@ -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;
} }

View File

@ -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
View File

@ -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:

View File

@ -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;
}

View File

@ -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

File diff suppressed because it is too large Load Diff

44
g10/mailing-list.h Normal file
View 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

View File

@ -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 );

View File

@ -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,8 +142,11 @@ 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;
}
} }
@ -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);

View File

@ -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 );

View File

@ -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)
{ {

View File

@ -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);