* (c) 1999 Straylight/Edgeware
*/
-/*----- Licensing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of Catacomb.
*
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
- *
+ *
* Catacomb 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 Library General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Library General Public
* License along with Catacomb; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
/*----- Header files ------------------------------------------------------*/
+#define _FILE_OFFSET_BITS 64
+
#include "config.h"
#include <ctype.h>
const struct seedalg { const char *p; grand *(*gen)(const void *, size_t); }
seedtab[] = {
- { "dsarand", dsarand_create },
- { "rmd128-mgf", rmd128_mgfrand },
- { "rmd160-mgf", rmd160_mgfrand },
- { "rmd256-mgf", rmd256_mgfrand },
- { "rmd320-mgf", rmd320_mgfrand },
- { "sha-mgf", sha_mgfrand },
- { "sha224-mgf", sha224_mgfrand },
- { "sha256-mgf", sha256_mgfrand },
- { "sha384-mgf", sha384_mgfrand },
- { "sha512-mgf", sha512_mgfrand },
- { "tiger-mgf", tiger_mgfrand },
+ { "dsarand", dsarand_create },
+ { "rmd128-mgf", rmd128_mgfrand },
+ { "rmd160-mgf", rmd160_mgfrand },
+ { "rmd256-mgf", rmd256_mgfrand },
+ { "rmd320-mgf", rmd320_mgfrand },
+ { "sha-mgf", sha_mgfrand },
+ { "sha224-mgf", sha224_mgfrand },
+ { "sha256-mgf", sha256_mgfrand },
+ { "sha384-mgf", sha384_mgfrand },
+ { "sha512-mgf", sha512_mgfrand },
+ { "tiger-mgf", tiger_mgfrand },
{ 0, 0 }
};
#define f_limlee 8u /* Generate Lim-Lee primes */
#define f_subgroup 16u /* Generate a subgroup */
#define f_retag 32u /* Remove any existing tag */
+#define f_kcdsa 64u /* Generate KCDSA primes */
/* --- @dolock@ --- *
*
{
key_filter kf;
key_attriter i;
+ key_data *kd;
const char *n, *v;
+ kf.f = KCAT_SHARE;
+ kf.m = KF_CATMASK;
+
/* --- Quick check if no parameters supplied --- */
if (!k->p)
key_data *kd = key_structfind(k->p->k, *pp);
if (!kd)
die(EXIT_FAILURE, "bad parameter key: parameter `%s' not found", *pp);
- if ((kd->e & KF_CATMASK) != KCAT_SHARE)
+ if (!KEY_MATCH(kd, &kf))
die(EXIT_FAILURE, "bad parameter key: subkey `%s' is not shared", *pp);
pp++;
}
/* --- Copy over the parameters --- */
- kf.f = KCAT_SHARE;
- kf.m = KF_CATMASK;
- key_setkeydata(k->kf, k->k, k->p->k);
+ kd = key_copydata(k->p->k, &kf);
+ assert(kd);
+ key_setkeydata(k->kf, k->k, kd);
+ key_drop(kd);
/* --- Copy over attributes --- */
qd_parse qd;
group *g;
const char *e;
-
+
if (strcmp(k->curve, "list") == 0) {
unsigned i, w;
LIST("Built-in prime fields", stdout, ptab[i].name, ptab[i].name);
if ((g = group_prime(&dp)) == 0)
die(EXIT_FAILURE, "invalid prime field");
if (!(k->f & f_quiet) && (e = G_CHECK(g, &rand_global)) != 0)
- moan("WARNING! group check failed: %s", e);
+ moan("WARNING! group check failed: %s", e);
G_DESTROYGROUP(g);
goto done;
}
-
+
if (!k->bits)
k->bits = 1024;
key_putattr(k->kf, k->k, "factors", d.buf);
dstr_destroy(&d);
}
+ } else if (k->f & f_kcdsa) {
+ if (!k->qbits)
+ k->qbits = 256;
+ rc = dh_kcdsagen(&dp, k->qbits, k->bits, 0,
+ 0, k->r, (k->f & f_quiet) ? 0 : pgen_ev, 0);
+ if (!rc) {
+ dstr d = DSTR_INIT;
+ mp *v = MP_NEW;
+
+ mp_writedstr(dp.q, &d, 10);
+ mp_div(&v, 0, dp.p, dp.q);
+ v = mp_lsr(v, v, 1);
+ dstr_puts(&d, ", ");
+ mp_writedstr(v, &d, 10);
+ mp_drop(v);
+ key_putattr(k->kf, k->k, "factors", d.buf);
+ dstr_destroy(&d);
+ }
} else
rc = dh_gen(&dp, k->qbits, k->bits, 0, k->r,
(k->f & f_quiet) ? 0 : pgen_ev, 0);
{
key_file f;
time_t exp = KEXP_EXPIRE;
+ uint32 kid = rand_global.ops->word(&rand_global);
const char *tag = 0, *ptag = 0;
const char *c = 0;
keyalg *alg = algtab;
{ "comment", OPTF_ARGREQ, 0, 'c' },
{ "tag", OPTF_ARGREQ, 0, 't' },
{ "rand-id", OPTF_ARGREQ, 0, 'R' },
+ { "key-id", OPTF_ARGREQ, 0, 'I' },
{ "curve", OPTF_ARGREQ, 0, 'C' },
{ "seedalg", OPTF_ARGREQ, 0, 'A' },
{ "seed", OPTF_ARGREQ, 0, 's' },
{ "quiet", 0, 0, 'q' },
{ "lim-lee", 0, 0, 'L' },
{ "subgroup", 0, 0, 'S' },
+ { "kcdsa", 0, 0, 'K' },
{ 0, 0, 0, 0 }
};
- int i = mdwopt(argc, argv, "+a:b:B:p:e:c:t:R:C:A:s:n:lqrLS",
+ int i = mdwopt(argc, argv, "+a:b:B:p:e:c:t:R:I:C:A:s:n:lqrLKS",
opt, 0, 0, 0);
if (i < 0)
break;
case 's': {
base64_ctx b;
dstr d = DSTR_INIT;
- if (seed) die(EXIT_FAILURE, "seed already set");
+ if (seed) die(EXIT_FAILURE, "seed already set");
base64_init(&b);
base64_decode(&b, optarg, strlen(optarg), &d);
base64_decode(&b, 0, 0, &d);
seed = optarg;
dstr_destroy(&d);
} break;
-
+
case 'n': {
base64_ctx b;
dstr d = DSTR_INIT;
unsigned n = strtoul(optarg, &p, 0);
if (n == 0 || *p != 0 || n % 8 != 0)
die(EXIT_FAILURE, "bad seed length `%s'", optarg);
- if (seed) die(EXIT_FAILURE, "seed already set");
+ if (seed) die(EXIT_FAILURE, "seed already set");
n /= 8;
p = xmalloc(n);
rand_get(RAND_GLOBAL, p, n);
seed = d.buf;
k.r = sa->gen(p, n);
} break;
-
+
+ /* --- Key id --- */
+
+ case 'I': {
+ char *p;
+ unsigned long id;
+
+ errno = 0;
+ id = strtoul(optarg, &p, 16);
+ if (errno || *p || id > MASK32)
+ die(EXIT_FAILURE, "bad key-id `%s'", optarg);
+ kid = id;
+ } break;
+
/* --- Other flags --- */
case 'R':
case 'L':
k.f |= f_limlee;
break;
+ case 'K':
+ k.f |= f_kcdsa;
+ break;
case 'S':
k.f |= f_subgroup;
break;
keyrand(&f, rtag);
for (;;) {
- uint32 id = rand_global.ops->word(&rand_global);
int err;
- if ((err = key_new(&f, id, argv[optind], exp, &k.k)) == 0)
+ if ((err = key_new(&f, kid, argv[optind], exp, &k.k)) == 0)
break;
else if (err != KERR_DUPID)
die(EXIT_FAILURE, "error adding new key: %s", key_strerror(err));
fputs(", 0x", stdout); mp_writefile(k->u.e.y, stdout, 16);
putchar('\n');
}
- break;
+ break;
/* --- Structured keys --- *
*
}
INDENT(ind);
fputs("}\n", stdout);
- } break;
+ } break;
}
#undef INDENT
if (!o->v) {
if (!(o->f & f_newline)) {
- printf("%8s %-20s %-20s %-10s %-10s\n",
+ printf("%8s %-20s %-20s %-10s %s\n",
"Id", "Tag", "Type", "Expire", "Delete");
}
- printf("%08lx %-20s %-20s %-10s %-10s\n",
+ printf("%08lx %-20s %-20s %-10s %s\n",
(unsigned long)k->id, k->tag ? k->tag : "<none>",
k->type, ebuf, dbuf);
o->f |= f_newline;
showkeydata(k->k, 0, o, &d);
dstr_destroy(&d);
}
-
+
o->f |= f_newline;
}
int e = key_readflags(optarg, &p, &o.kf.f, &o.kf.m);
if (e || *p)
die(EXIT_FAILURE, "bad filter string `%s'", optarg);
- } break;
+ } break;
default:
o.f |= f_bogus;
break;
doclose(&f);
return (0);
}
-
+
/* --- @cmd_comment@ --- */
static int cmd_comment(int argc, char *argv[])
key *k;
for (key_mkiter(&i, &f); (k = key_next(&i)) != 0; )
key_extract(&f, k, fp, &kf);
- } else {
+ } else {
for (i = 1; i < argc; i++) {
if ((k = key_bytag(&f, argv[i])) != 0)
key_extract(&f, k, fp, &kf);
{ "tidy", cmd_tidy, "tidy" },
{ "add", cmd_add,
"add [-OPTIONS] TYPE [ATTR...]\n\
- Options: [-lqrLS] [-a ALG] [-bB BITS] [-p PARAM] [-R TAG]\n\
- [-A SEEDALG] [-s SEED] [-n BITS]\n\
- [-e EXPIRE] [-t TAG] [-c COMMENT]", "\
+ Options: [-lqrLKS] [-a ALG] [-bB BITS] [-p PARAM] [-R TAG]\n\
+ [-A SEEDALG] [-s SEED] [-n BITS] [-I KEYID]\n\
+ [-e EXPIRE] [-t TAG] [-c COMMENT]", "\
Options:\n\
\n\
-a, --algorithm=ALG Generate keys suitable for ALG.\n\
-t, --tag=TAG Tag the key with the name TAG.\n\
-r, --retag Untag any key currently with that tag.\n\
-R, --rand-id=TAG Use key named TAG for the random number generator.\n\
+-I, --key-id=ID Force the key-id for the new key.\n\
-l, --lock Lock the generated key with a passphrase.\n\
-q, --quiet Don't give progress indicators while working.\n\
-L, --lim-lee Generate Lim-Lee primes for Diffie-Hellman groups.\n\
+-K, --kcdsa Generate KCDSA-style Lim-Lee primes for DH groups.\n\
-S, --subgroup Use a prime-order subgroup for Diffie-Hellman.\n\
" },
{ 0, 0, 0 }