#include <mLib/base32.h>
#include <mLib/base64.h>
#include <mLib/hex.h>
+#include <mLib/macros.h>
#include <mLib/mdwopt.h>
#include <mLib/quis.h>
#include <mLib/report.h>
#include "gfreduce.h"
#include "key.h"
#include "mp.h"
+#include "mpint.h"
#include "mpmont.h"
#include "mprand.h"
#include "mptext.h"
#include "x25519.h"
#include "x448.h"
#include "ed25519.h"
+#include "ed448.h"
#include "cc.h"
#include "sha-mgf.h"
unsigned bits, qbits; /* Bit length for the new key */
const char *curve; /* Elliptic curve name/info */
grand *r; /* Random number source */
+ mp *e; /* Public exponent */
key *p; /* Parameters key-data */
} keyopts;
copyparam(k, 0);
if (!k->bits)
k->bits = 1024;
+ if (k->bits < 64)
+ die(EXIT_FAILURE, "RSA key too tiny");
+ if (!k->e)
+ k->e = mp_fromulong(MP_NEW, 65537);
/* --- Generate the RSA parameters --- */
- if (rsa_gen(&rp, k->bits, k->r, 0,
- (k->f & f_quiet) ? 0 : pgen_ev, 0))
+ if (rsa_gen_e(&rp, k->bits, k->e, k->r, 0,
+ (k->f & f_quiet) ? 0 : pgen_ev, 0))
die(EXIT_FAILURE, "RSA key generation failed");
/* --- Run a test encryption --- */
group *g;
const char *e;
- if (strcmp(k->curve, "list") == 0) {
+ if (STRCMP(k->curve, ==, "list")) {
unsigned i, w;
LIST("Built-in prime fields", stdout, ptab[i].name, ptab[i].name);
exit(0);
/* --- Decide on a field --- */
if (!k->bits) k->bits = 128;
- if (k->curve && strcmp(k->curve, "list") == 0) {
+ if (k->curve && STRCMP(k->curve, ==, "list")) {
unsigned i, w;
LIST("Built-in binary fields", stdout,
bintab[i].name, bintab[i].name);
/* --- Decide on a curve --- */
if (!k->bits) k->bits = 256;
- if (k->curve && strcmp(k->curve, "list") == 0) {
+ if (k->curve && STRCMP(k->curve, ==, "list")) {
unsigned i, w;
LIST("Built-in elliptic curves", stdout,
ectab[i].name, ectab[i].name);
mp_drop(x);
}
-static void alg_x25519(keyopts *k)
-{
- key_data *kd, *kkd;
- octet priv[X25519_KEYSZ], pub[X25519_PUBSZ];
-
- copyparam(k, 0);
- k->r->ops->fill(k->r, priv, sizeof(priv));
- x25519(pub, priv, x25519_base);
- kkd = key_newstruct();
- key_structsteal(kkd, "priv",
- key_newbinary(KCAT_PRIV | KF_BURN, priv, sizeof(priv)));
- kd = key_newstruct();
- key_structsteal(kd, "private", kkd);
- key_structsteal(kd, "pub", key_newbinary(KCAT_PUB, pub, sizeof(pub)));
-
- key_setkeydata(k->kf, k->k, kd);
-}
-
-static void alg_x448(keyopts *k)
-{
- key_data *kd, *kkd;
- octet priv[X448_KEYSZ], pub[X448_PUBSZ];
-
- copyparam(k, 0);
- k->r->ops->fill(k->r, priv, sizeof(priv));
- x448(pub, priv, x448_base);
- kkd = key_newstruct();
- key_structsteal(kkd, "priv",
- key_newbinary(KCAT_PRIV | KF_BURN, priv, sizeof(priv)));
- kd = key_newstruct();
- key_structsteal(kd, "private", kkd);
- key_structsteal(kd, "pub", key_newbinary(KCAT_PUB, pub, sizeof(pub)));
-
- key_setkeydata(k->kf, k->k, kd);
-}
-
-static void alg_ed25519(keyopts *k)
-{
- key_data *kd, *kkd;
- octet priv[ED25519_KEYSZ], pub[ED25519_PUBSZ];
+#define XDHS(_) \
+ _(x25519, X25519, "X25519") \
+ _(x448, X448, "X448")
+
+#define XDHALG(xdh, XDH, name) \
+ \
+ static void alg_##xdh(keyopts *k) \
+ { \
+ key_data *kd, *kkd; \
+ octet priv[XDH##_KEYSZ], pub[XDH##_PUBSZ]; \
+ \
+ copyparam(k, 0); \
+ k->r->ops->fill(k->r, priv, sizeof(priv)); \
+ xdh(pub, priv, xdh##_base); \
+ kkd = key_newstruct(); \
+ key_structsteal(kkd, "priv", \
+ key_newbinary(KCAT_PRIV | KF_BURN, \
+ priv, sizeof(priv))); \
+ kd = key_newstruct(); \
+ key_structsteal(kd, "private", kkd); \
+ key_structsteal(kd, "pub", \
+ key_newbinary(KCAT_PUB, pub, sizeof(pub))); \
+ \
+ key_setkeydata(k->kf, k->k, kd); \
+ }
- copyparam(k, 0);
- k->r->ops->fill(k->r, priv, sizeof(priv));
- ed25519_pubkey(pub, priv, sizeof(priv));
- kkd = key_newstruct();
- key_structsteal(kkd, "priv",
- key_newbinary(KCAT_PRIV | KF_BURN, priv, sizeof(priv)));
- kd = key_newstruct();
- key_structsteal(kd, "private", kkd);
- key_structsteal(kd, "pub", key_newbinary(KCAT_PUB, pub, sizeof(pub)));
+XDHS(XDHALG)
+#undef XDHALG
+
+#define EDDSAS(_) \
+ _(ed25519, ED25519, "Ed25519") \
+ _(ed448, ED448, "Ed448")
+
+#define EDDSAALG(ed, ED, name) \
+ \
+ static void alg_##ed(keyopts *k) \
+ { \
+ key_data *kd, *kkd; \
+ octet priv[ED##_KEYSZ], pub[ED##_PUBSZ]; \
+ \
+ copyparam(k, 0); \
+ k->r->ops->fill(k->r, priv, sizeof(priv)); \
+ ed##_pubkey(pub, priv, sizeof(priv)); \
+ kkd = key_newstruct(); \
+ key_structsteal(kkd, "priv", \
+ key_newbinary(KCAT_PRIV | KF_BURN, \
+ priv, sizeof(priv))); \
+ kd = key_newstruct(); \
+ key_structsteal(kd, "private", kkd); \
+ key_structsteal(kd, "pub", \
+ key_newbinary(KCAT_PUB, pub, sizeof(pub))); \
+ \
+ key_setkeydata(k->kf, k->k, kd); \
+ }
- key_setkeydata(k->kf, k->k, kd);
-}
+EDDSAS(EDDSAALG)
+#undef EDDSAALG
/* --- The algorithm tables --- */
{ "bindh-param", alg_binparam, "Binary-field DH parameters" },
{ "ec-param", alg_ecparam, "Elliptic curve parameters" },
{ "ec", alg_ec, "Elliptic curve crypto" },
- { "x25519", alg_x25519, "X25519 key exchange" },
- { "x448", alg_x448, "X448 key exchange" },
- { "ed25519", alg_ed25519, "Ed25519 digital signatures" },
+#define XDHTAB(xdh, XDH, name) \
+ { #xdh, alg_##xdh, "" name " key exchange" },
+ XDHS(XDHTAB)
+#undef XDHTAB
+#define EDDSATAB(ed, ED, name) \
+ { #ed, alg_##ed, "" name " digital signatures" },
+ EDDSAS(EDDSATAB)
+#undef EDDSATAB
{ "empty", alg_empty, "Empty parametrs-only key" },
{ 0, 0 }
};
keyalg *alg = algtab;
const char *rtag = 0;
const struct seedalg *sa = SEEDALG_DEFAULT;
- keyopts k = { 0, 0, DSTR_INIT, 0, 0, 0, 0, 0 };
+ keyopts k = { 0, 0, DSTR_INIT, 0, 0, 0, 0, 0, 0 };
const char *seed = 0;
k.r = &rand_global;
{ "seedalg", OPTF_ARGREQ, 0, 'A' },
{ "seed", OPTF_ARGREQ, 0, 's' },
{ "newseed", OPTF_ARGREQ, 0, 'n' },
+ { "public-exponent", OPTF_ARGREQ, 0, 'E' },
{ "lock", 0, 0, 'l' },
{ "quiet", 0, 0, 'q' },
{ "lim-lee", 0, 0, 'L' },
{ "kcdsa", 0, 0, 'K' },
{ 0, 0, 0, 0 }
};
- int i = mdwopt(argc, argv, "+a:b:B:p:e:c:t:R:I:C:A:s:n:lqrLKS",
+ int i = mdwopt(argc, argv, "+a:b:B:p:e:c:t:R:I:C:A:s:n:E:lqrLKS",
opt, 0, 0, 0);
if (i < 0)
break;
keyalg *a;
size_t sz = strlen(optarg);
- if (strcmp(optarg, "list") == 0) {
+ if (STRCMP(optarg, ==, "list")) {
for (a = algtab; a->name; a++)
printf("%-10s %s\n", a->name, a->help);
return (0);
alg = 0;
for (a = algtab; a->name; a++) {
- if (strncmp(optarg, a->name, sz) == 0) {
+ if (STRNCMP(optarg, ==, a->name, sz)) {
if (a->name[sz] == 0) {
alg = a;
break;
/* --- Expiry dates get passed to @get_date@ for parsing --- */
case 'e':
- if (strcmp(optarg, "forever") == 0)
+ if (STRCMP(optarg, ==, "forever"))
exp = KEXP_FOREVER;
else {
exp = get_date(optarg, 0);
case 'A': {
const struct seedalg *ss;
- if (strcmp(optarg, "list") == 0) {
+ if (STRCMP(optarg, ==, "list")) {
printf("Seed algorithms:\n");
for (ss = seedtab; ss->p; ss++)
printf(" %s\n", ss->p);
if (seed) die(EXIT_FAILURE, "seed already set -- put -A first");
sa = 0;
for (ss = seedtab; ss->p; ss++) {
- if (strcmp(optarg, ss->p) == 0)
+ if (STRCMP(optarg, ==, ss->p))
sa = ss;
}
if (!sa)
kid = id;
} break;
+ /* --- Public exponent --- */
+
+ case 'E': {
+ char *p;
+ k.e = mp_readstring(k.e, optarg, &p, 0);
+ if (!k.e || *p || MP_CMP(k.e, <, MP_THREE) || MP_EVENP(k.e))
+ die(EXIT_FAILURE, "bad exponent `%s'", optarg);
+ } break;
+
/* --- Other flags --- */
case 'R':
if (k.f & f_retag) {
if ((kk = key_bytag(&f, tag)) != 0 &&
kk->tag &&
- strcmp(kk->tag, tag) == 0)
+ STRCMP(kk->tag, ==, tag))
key_settag(&f, kk, 0);
}
if ((err = key_settag(&f, k.k, tag)) != 0)
} \
} while (0)
+ if ((k->e&KF_ENCMASK) == KENC_ENCRYPT && o->v <= 4)
+ { fputs(" encrypted\n", stdout); return; }
+ if ((k->e&KF_ENCMASK) != KENC_STRUCT && !(k->e&KF_NONSECRET) && o->v <= 3)
+ { fputs(" secret\n", stdout); return; }
+
switch (k->e & KF_ENCMASK) {
/* --- Binary key data --- *
* key. Otherwise just say that it's encrypted and move on.
*/
- case KENC_ENCRYPT:
- if (o->v <= 3)
- fputs(" encrypted\n", stdout);
+ case KENC_ENCRYPT: {
+ key_data *kd;
+ if (key_punlock(&kd, k, d->buf))
+ printf(" <failed to unlock %s>\n", d->buf);
else {
- key_data *kd;
- if (key_punlock(&kd, k, d->buf))
- printf(" <failed to unlock %s>\n", d->buf);
- else {
- fputs(" encrypted", stdout);
- showkeydata(kd, ind, o, d);
- key_drop(kd);
- }
+ fputs(" encrypted", stdout);
+ showkeydata(kd, ind, o, d);
+ key_drop(kd);
}
- break;
+ } break;
/* --- Integer keys --- *
*
{
const struct fpres *fpres;
for (fpres = fprestab; fpres->name; fpres++)
- if (strcmp(fpres->name, name) == 0) return (fpres);
+ if (STRCMP(fpres->name, ==, name)) return (fpres);
die(EXIT_FAILURE, "unknown presentation syle `%s'", name);
}
argv += optind; argc -= optind;
if (rc) {
die(EXIT_FAILURE,
- "Usage: fingerprint [-a HASHALG] [-p STYLE] [-f FILTER] [TAG...]");
+ "Usage: fingerprint [-a HASH] [-p STYLE] [-f FILTER] [TAG...]");
}
doopen(&f, KOPEN_READ);
argv += optind; argc -= optind;
if (rc || argc != 2) {
die(EXIT_FAILURE,
- "Usage: verify [-a HASHALG] [-p STYLE] [-f FILTER] TAG FINGERPRINT");
+ "Usage: verify [-a HASH] [-p STYLE] [-f FILTER] TAG FINGERPRINT");
}
doopen(&f, KOPEN_READ);
if (!key_fingerprint(k, h, &kf))
die(EXIT_FAILURE, "key has no fingerprintable components (as filtered)");
fpr = GH_DONE(h, 0);
- if (memcmp(fpr, d.buf, ch->hashsz) != 0)
+ if (MEMCMP(fpr, !=, d.buf, ch->hashsz))
die(EXIT_FAILURE, "key fingerprint mismatch");
dstr_destroy(&d); dstr_destroy(&dd);
doclose(&f);
die(EXIT_FAILURE, "Usage: tag [-r] TAG [NEW-TAG]");
doopen(&f, KOPEN_WRITE);
if (flags & f_retag) {
- if ((k = key_bytag(&f, argv[1])) != 0 && strcmp(k->tag, argv[1]) == 0)
+ if ((k = key_bytag(&f, argv[1])) != 0 && STRCMP(k->tag, ==, argv[1]))
key_settag(&f, k, 0);
}
if ((k = key_bytag(&f, argv[0])) == 0)
argv += optind; argc -= optind;
if (rc || argc < 1)
die(EXIT_FAILURE, "Usage: extract [-f FILTER] FILE [TAG...]");
- if (strcmp(*argv, "-") == 0)
+ if (STRCMP(*argv, ==, "-"))
fp = stdout;
else {
outfile = *argv;
if (argc != 2)
die(EXIT_FAILURE, "Usage: merge FILE");
- if (strcmp(argv[1], "-") == 0)
+ if (STRCMP(argv[1], ==, "-"))
fp = stdin;
else if (!(fp = fopen(argv[1], "r"))) {
die(EXIT_FAILURE, "couldn't open `%s' for reading: %s",
-v, --verbose Show more information.\n\
" },
{ "fingerprint", cmd_finger,
- "fingerprint [-a HASHALG] [-p STYLE] [-f FILTER] [TAG...]", "\
+ "fingerprint [-a HASH] [-p STYLE] [-f FILTER] [TAG...]", "\
Options:\n\
\n\
-f, --filter=FILT Only hash key components matching FILT.\n\