-
-#include "dsa.h"
-#include "rsa.h"
-#include "pkcs1.h"
-
-#include "md4.h"
-#include "md5.h"
-#include "rmd128.h"
-#include "rmd160.h"
-#include "rmd256.h"
-#include "rmd320.h"
-#include "sha.h"
-#include "tiger.h"
-
-/*----- Digital signature algorithm ---------------------------------------*/
-
-static int dsasign(key *k, const void *m, size_t msz, dstr *d)
-{
- dsa_priv dp;
- key_packstruct ks[DSA_PRIVFETCHSZ];
- key_packdef *kp;
- size_t sz;
- octet *p;
- int e;
-
- kp = key_fetchinit(dsa_privfetch, ks, &dp);
- if ((e = key_fetch(kp, k)) != 0) {
- key_fetchdone(kp);
- return (e);
- }
- sz = mp_octets(dp.dp.q);
- if (sz < msz)
- die(EXIT_FAILURE, "hash function too wide for this signing key");
- DENSURE(d, sz * 2);
- p = (octet *)d->buf + d->len;
- rand_get(RAND_GLOBAL, p, sz);
- dsa_sign(&dp.dp, dp.x, m, msz, p, sz, p, sz, p + sz, sz);
- d->len += sz * 2;
- key_fetchdone(kp);
- return (0);
-}
-
-static int dsaverify(key *k, const void *m, size_t msz,
- const void *s, size_t ssz)
-{
- dsa_pub dp;
- key_packstruct ks[DSA_PUBFETCHSZ];
- key_packdef *kp;
- size_t sz;
- const octet *p = s;
- int e;
-
- kp = key_fetchinit(dsa_pubfetch, ks, &dp);
- if ((e = key_fetch(kp, k)) != 0) {
- key_fetchdone(kp);
- return (e);
- }
- sz = ssz / 2;
- e = dsa_verify(&dp.dp, dp.y, m, msz, p, sz, p + sz, sz);
- key_fetchdone(kp);
- return (e);
-}
-
-/*----- RSA signing -------------------------------------------------------*/
-
-static int rsasign(key *k, const void *m, size_t msz, dstr *d)
-{
- rsa_priv rp;
- rsa_privctx rpc;
- pkcs1 pk = { 0, 0, 0 };
- key_packstruct ks[RSA_PRIVFETCHSZ];
- key_packdef *kp;
- int e;
-
- kp = key_fetchinit(rsa_privfetch, ks, &rp);
- if ((e = key_fetch(kp, k)) != 0) {
- key_fetchdone(kp);
- return (e);
- }
- rsa_privcreate(&rpc, &rp, &rand_global);
- if (rsa_sign(&rpc, m, msz, d, pkcs1_sigencode, &pk) < 0)
- die(EXIT_FAILURE, "internal error in rsasign (key too small?)");
- rsa_privdestroy(&rpc);
- key_fetchdone(kp);
- return (0);
-}
-
-static int rsaverify(key *k, const void *m, size_t msz,
- const void *s, size_t ssz)
-{
- rsa_pub rp;
- rsa_pubctx rpc;
- pkcs1 pk = { 0, 0, 0 };
- key_packstruct ks[RSA_PUBFETCHSZ];
- key_packdef *kp;
- int ok = 0;
- dstr d = DSTR_INIT;
- int e;
-
- kp = key_fetchinit(rsa_pubfetch, ks, &rp);
- if ((e = key_fetch(kp, k)) != 0) {
- key_fetchdone(kp);
- return (e);
- }
- rsa_pubcreate(&rpc, &rp);
- if (rsa_verify(&rpc, s, ssz, &d, pkcs1_sigdecode, &pk) > 0 &&
- msz == d.len && memcmp(d.buf, m, msz) == 0)
- ok = 1;
- dstr_destroy(&d);
- rsa_pubdestroy(&rpc);
- key_fetchdone(kp);
- return (ok);
-}
-
-/*----- Algorithm choice --------------------------------------------------*/
-
-typedef struct sig {
- const char *name;
- const char *type;
- int (*sign)(key */*k*/, const void */*m*/, size_t /*msz*/, dstr */*d*/);
- int (*verify)(key */*k*/, const void */*m*/, size_t /*msz*/,
- const void */*s*/, size_t /*ssz*/);
-} sig;
-
-static const gchash *hashtab[] = {
- &rmd160, &tiger, &sha, &rmd128, &rmd256, &rmd320, &md5, &md4, 0 };
-static sig sigtab[] = {
- { "dsa", "dsig-dsa", dsasign, dsaverify },
- { "rsa", "dsig-rsa", rsasign, rsaverify },
- { 0, 0, 0 }
-};
-
-/* --- @gethash@ --- *
- *
- * Arguments: @const char *name@ = pointer to name string
- *
- * Returns: Pointer to appropriate hash class.
- *
- * Use: Chooses a hash function by name.
- */
-
-static const gchash *gethash(const char *name)
-{
- const gchash **g, *gg = 0;
- size_t sz = strlen(name);
- for (g = hashtab; *g; g++) {
- if (strncmp(name, (*g)->name, sz) == 0) {
- if ((*g)->name[sz] == 0) {
- gg = *g;
- break;
- } else if (gg)
- return (0);
- else
- gg = *g;
- }
- }
- return (gg);
-}
-
-/* --- @getsig@ --- *
- *
- * Arguments: @const char *name@ = pointer to name string
- *
- * Returns: Pointer to appropriate signature type.
- *
- * Use: Chooses a signature algorithm by name.
- */
-
-static sig *getsig(const char *name)
-{
- sig *s, *ss = 0;
- size_t sz = strlen(name);
- for (s = sigtab; s->name; s++) {
- if (strncmp(name, s->name, sz) == 0) {
- if (s->name[sz] == 0) {
- ss = s;
- break;
- } else if (ss)
- return (0);
- else
- ss = s;
- }
- }
- return (ss);
-}