|
|
2ff057 |
#include "system.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#include <beecrypt/beecrypt.h>
|
|
|
2ff057 |
#include <beecrypt/dsa.h>
|
|
|
2ff057 |
#include <beecrypt/endianness.h>
|
|
|
2ff057 |
#include <beecrypt/md5.h>
|
|
|
2ff057 |
#include <beecrypt/mp.h>
|
|
|
2ff057 |
#include <beecrypt/rsa.h>
|
|
|
2ff057 |
#include <beecrypt/rsapk.h>
|
|
|
2ff057 |
#include <beecrypt/sha1.h>
|
|
|
2ff057 |
#if HAVE_BEECRYPT_API_H
|
|
|
2ff057 |
#include <beecrypt/sha256.h>
|
|
|
2ff057 |
#include <beecrypt/sha384.h>
|
|
|
2ff057 |
#include <beecrypt/sha512.h>
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
|
|
|
2ff057 |
#include <rpm/rpmpgp.h>
|
|
|
2ff057 |
#include "rpmio/digest.h"
|
|
|
2ff057 |
#include "rpmio/rpmio_internal.h"
|
|
|
2ff057 |
#include "debug.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
/**
|
|
|
2ff057 |
* MD5/SHA1 digest private data.
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
struct DIGEST_CTX_s {
|
|
|
2ff057 |
rpmDigestFlags flags; /*!< Bit(s) to control digest operation. */
|
|
|
2ff057 |
int algo; /*!< Used hash algorithm */
|
|
|
2ff057 |
uint32_t datalen; /*!< No. bytes in block of plaintext data. */
|
|
|
2ff057 |
uint32_t paramlen; /*!< No. bytes of digest parameters. */
|
|
|
2ff057 |
uint32_t digestlen; /*!< No. bytes of digest. */
|
|
|
2ff057 |
void * param; /*!< Digest parameters. */
|
|
|
2ff057 |
int (*Reset) (void * param); /*!< Digest initialize. */
|
|
|
2ff057 |
int (*Update) (void * param, const byte * data, size_t size); /*!< Digest transform. */
|
|
|
2ff057 |
int (*Digest) (void * param, byte * digest); /*!< Digest finish. */
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
|
|
|
2ff057 |
/**************************** init ************************************/
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmInitCrypto(void) {
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmFreeCrypto(void) {
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/**************************** digest ************************************/
|
|
|
2ff057 |
|
|
|
2ff057 |
DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
DIGEST_CTX nctx = NULL;
|
|
|
2ff057 |
if (octx) {
|
|
|
2ff057 |
nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
|
|
|
2ff057 |
nctx->param = memcpy(xcalloc(1, nctx->paramlen), octx->param, nctx->paramlen);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return nctx;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
size_t rpmDigestLength(int hashalgo)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
switch (hashalgo) {
|
|
|
2ff057 |
case PGPHASHALGO_MD5:
|
|
|
2ff057 |
return 16;
|
|
|
2ff057 |
case PGPHASHALGO_SHA1:
|
|
|
2ff057 |
return 20;
|
|
|
2ff057 |
#if HAVE_BEECRYPT_API_H
|
|
|
2ff057 |
case PGPHASHALGO_SHA256:
|
|
|
2ff057 |
return 32;
|
|
|
2ff057 |
case PGPHASHALGO_SHA384:
|
|
|
2ff057 |
return 48;
|
|
|
2ff057 |
case PGPHASHALGO_SHA512:
|
|
|
2ff057 |
return 64;
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
DIGEST_CTX rpmDigestInit(int hashalgo, rpmDigestFlags flags)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
|
|
|
2ff057 |
|
|
|
2ff057 |
ctx->flags = flags;
|
|
|
2ff057 |
ctx->algo = hashalgo;
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (hashalgo) {
|
|
|
2ff057 |
case PGPHASHALGO_MD5:
|
|
|
2ff057 |
ctx->digestlen = 16;
|
|
|
2ff057 |
ctx->datalen = 64;
|
|
|
2ff057 |
ctx->paramlen = sizeof(md5Param);
|
|
|
2ff057 |
ctx->param = xcalloc(1, ctx->paramlen);
|
|
|
2ff057 |
ctx->Reset = (void *) md5Reset;
|
|
|
2ff057 |
ctx->Update = (void *) md5Update;
|
|
|
2ff057 |
ctx->Digest = (void *) md5Digest;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PGPHASHALGO_SHA1:
|
|
|
2ff057 |
ctx->digestlen = 20;
|
|
|
2ff057 |
ctx->datalen = 64;
|
|
|
2ff057 |
ctx->paramlen = sizeof(sha1Param);
|
|
|
2ff057 |
ctx->param = xcalloc(1, ctx->paramlen);
|
|
|
2ff057 |
ctx->Reset = (void *) sha1Reset;
|
|
|
2ff057 |
ctx->Update = (void *) sha1Update;
|
|
|
2ff057 |
ctx->Digest = (void *) sha1Digest;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
#if HAVE_BEECRYPT_API_H
|
|
|
2ff057 |
case PGPHASHALGO_SHA256:
|
|
|
2ff057 |
ctx->digestlen = 32;
|
|
|
2ff057 |
ctx->datalen = 64;
|
|
|
2ff057 |
ctx->paramlen = sizeof(sha256Param);
|
|
|
2ff057 |
ctx->param = xcalloc(1, ctx->paramlen);
|
|
|
2ff057 |
ctx->Reset = (void *) sha256Reset;
|
|
|
2ff057 |
ctx->Update = (void *) sha256Update;
|
|
|
2ff057 |
ctx->Digest = (void *) sha256Digest;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PGPHASHALGO_SHA384:
|
|
|
2ff057 |
ctx->digestlen = 48;
|
|
|
2ff057 |
ctx->datalen = 128;
|
|
|
2ff057 |
ctx->paramlen = sizeof(sha384Param);
|
|
|
2ff057 |
ctx->param = xcalloc(1, ctx->paramlen);
|
|
|
2ff057 |
ctx->Reset = (void *) sha384Reset;
|
|
|
2ff057 |
ctx->Update = (void *) sha384Update;
|
|
|
2ff057 |
ctx->Digest = (void *) sha384Digest;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PGPHASHALGO_SHA512:
|
|
|
2ff057 |
ctx->digestlen = 64;
|
|
|
2ff057 |
ctx->datalen = 128;
|
|
|
2ff057 |
ctx->paramlen = sizeof(sha512Param);
|
|
|
2ff057 |
ctx->param = xcalloc(1, ctx->paramlen);
|
|
|
2ff057 |
ctx->Reset = (void *) sha512Reset;
|
|
|
2ff057 |
ctx->Update = (void *) sha512Update;
|
|
|
2ff057 |
ctx->Digest = (void *) sha512Digest;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
case PGPHASHALGO_RIPEMD160:
|
|
|
2ff057 |
case PGPHASHALGO_MD2:
|
|
|
2ff057 |
case PGPHASHALGO_TIGER192:
|
|
|
2ff057 |
case PGPHASHALGO_HAVAL_5_160:
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
free(ctx);
|
|
|
2ff057 |
return NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
(*ctx->Reset)(ctx->param);
|
|
|
2ff057 |
return ctx;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (ctx == NULL)
|
|
|
2ff057 |
return -1;
|
|
|
2ff057 |
|
|
|
2ff057 |
return (*ctx->Update) (ctx->param, data, len);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
byte * digest;
|
|
|
2ff057 |
char * t;
|
|
|
2ff057 |
int i;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (ctx == NULL)
|
|
|
2ff057 |
return -1;
|
|
|
2ff057 |
digest = xmalloc(ctx->digestlen);
|
|
|
2ff057 |
|
|
|
2ff057 |
/* FIX: check rc */
|
|
|
2ff057 |
(void) (*ctx->Digest) (ctx->param, digest);
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Return final digest. */
|
|
|
2ff057 |
if (!asAscii) {
|
|
|
2ff057 |
if (lenp) *lenp = ctx->digestlen;
|
|
|
2ff057 |
if (datap) {
|
|
|
2ff057 |
*datap = digest;
|
|
|
2ff057 |
digest = NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
if (lenp) *lenp = (2*ctx->digestlen) + 1;
|
|
|
2ff057 |
if (datap) {
|
|
|
2ff057 |
const byte * s = (const byte *) digest;
|
|
|
2ff057 |
static const char hex[] = "0123456789abcdef";
|
|
|
2ff057 |
|
|
|
2ff057 |
*datap = t = xmalloc((2*ctx->digestlen) + 1);
|
|
|
2ff057 |
for (i = 0 ; i < ctx->digestlen; i++) {
|
|
|
2ff057 |
*t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
|
|
|
2ff057 |
*t++ = hex[ (unsigned)((*s++ ) & 0x0f) ];
|
|
|
2ff057 |
}
|
|
|
2ff057 |
*t = '\0';
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (digest) {
|
|
|
2ff057 |
memset(digest, 0, ctx->digestlen); /* In case it's sensitive */
|
|
|
2ff057 |
free(digest);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
memset(ctx->param, 0, ctx->paramlen); /* In case it's sensitive */
|
|
|
2ff057 |
free(ctx->param);
|
|
|
2ff057 |
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
|
|
2ff057 |
free(ctx);
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
|
|
|
2ff057 |
/****************************** RSA **************************************/
|
|
|
2ff057 |
|
|
|
2ff057 |
struct pgpDigSigRSA_s {
|
|
|
2ff057 |
mpnumber c;
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
struct pgpDigKeyRSA_s {
|
|
|
2ff057 |
rsapk rsa_pk;
|
|
|
2ff057 |
int nbytes;
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num, const uint8_t *p)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
struct pgpDigSigRSA_s *sig = pgpsig->data;
|
|
|
2ff057 |
int mlen = pgpMpiLen(p) - 2;
|
|
|
2ff057 |
int rc = 1;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!sig)
|
|
|
2ff057 |
sig = pgpsig->data = xcalloc(1, sizeof(*sig));
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (num) {
|
|
|
2ff057 |
case 0:
|
|
|
2ff057 |
if (!mpnsetbin(&sig->c, p + 2, mlen))
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
struct pgpDigKeyRSA_s *key = pgpkey->data;
|
|
|
2ff057 |
int mlen = pgpMpiLen(p) - 2;
|
|
|
2ff057 |
int rc = 1;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!key)
|
|
|
2ff057 |
key = pgpkey->data = xcalloc(1, sizeof(*key));
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (num) {
|
|
|
2ff057 |
case 0:
|
|
|
2ff057 |
key->nbytes = mlen;
|
|
|
2ff057 |
if (!mpbsetbin(&key->rsa_pk.n, p + 2, mlen))
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case 1:
|
|
|
2ff057 |
if (!mpnsetbin(&key->rsa_pk.e, p + 2, mlen))
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int pkcs1pad(mpnumber *rsahm, int nbytes, const char *prefix, uint8_t *hash, size_t hashlen)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
int datalen = strlen(prefix) / 2 + hashlen;
|
|
|
2ff057 |
byte *buf, *bp;
|
|
|
2ff057 |
int rc = 1;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (nbytes < 4 + datalen)
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
buf = xmalloc(nbytes);
|
|
|
2ff057 |
memset(buf, 0xff, nbytes);
|
|
|
2ff057 |
buf[0] = 0x00;
|
|
|
2ff057 |
buf[1] = 0x01;
|
|
|
2ff057 |
bp = buf + nbytes - datalen;
|
|
|
2ff057 |
bp[-1] = 0;
|
|
|
2ff057 |
for (; *prefix; prefix += 2)
|
|
|
2ff057 |
*bp++ = (rnibble(prefix[0]) << 4) | rnibble(prefix[1]);
|
|
|
2ff057 |
memcpy(bp, hash, hashlen);
|
|
|
2ff057 |
if (!mpnsetbin(rsahm, buf, nbytes))
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
buf = _free(buf);
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
struct pgpDigKeyRSA_s *key = pgpkey->data;
|
|
|
2ff057 |
struct pgpDigSigRSA_s *sig = pgpsig->data;
|
|
|
2ff057 |
const char * prefix = NULL;
|
|
|
2ff057 |
mpnumber rsahm;
|
|
|
2ff057 |
int rc = 1;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!sig || !key)
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (hash_algo) {
|
|
|
2ff057 |
case PGPHASHALGO_MD5:
|
|
|
2ff057 |
prefix = "3020300c06082a864886f70d020505000410";
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PGPHASHALGO_SHA1:
|
|
|
2ff057 |
prefix = "3021300906052b0e03021a05000414";
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PGPHASHALGO_MD2:
|
|
|
2ff057 |
prefix = "3020300c06082a864886f70d020205000410";
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PGPHASHALGO_SHA256:
|
|
|
2ff057 |
prefix = "3031300d060960864801650304020105000420";
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PGPHASHALGO_SHA384:
|
|
|
2ff057 |
prefix = "3041300d060960864801650304020205000430";
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PGPHASHALGO_SHA512:
|
|
|
2ff057 |
prefix = "3051300d060960864801650304020305000440";
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
memset(&rsahm, 0, sizeof(rsahm));
|
|
|
2ff057 |
if (pkcs1pad(&rsahm, key->nbytes, prefix, hash, hashlen) != 0)
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
|
|
|
2ff057 |
#if HAVE_BEECRYPT_API_H
|
|
|
2ff057 |
rc = rsavrfy(&key->rsa_pk.n, &key->rsa_pk.e, &sig->c, &rsahm) == 1 ? 0 : 1;
|
|
|
2ff057 |
#else
|
|
|
2ff057 |
rc = rsavrfy(&key->rsa_pk, &rsahm, &sig->c) == 1 ? 0 : 1;
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
mpnfree(&rsahm);
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static void pgpFreeSigRSA(pgpDigAlg pgpsig)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
struct pgpDigSigRSA_s *sig = pgpsig->data;
|
|
|
2ff057 |
if (sig) {
|
|
|
2ff057 |
mpnfree(&sig->c);
|
|
|
2ff057 |
pgpsig->data = _free(sig);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static void pgpFreeKeyRSA(pgpDigAlg pgpkey)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
struct pgpDigKeyRSA_s *key = pgpkey->data;
|
|
|
2ff057 |
if (key) {
|
|
|
2ff057 |
mpbfree(&key->rsa_pk.n);
|
|
|
2ff057 |
mpnfree(&key->rsa_pk.e);
|
|
|
2ff057 |
pgpkey->data = _free(key);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
|
|
|
2ff057 |
/****************************** DSA **************************************/
|
|
|
2ff057 |
|
|
|
2ff057 |
struct pgpDigSigDSA_s {
|
|
|
2ff057 |
mpnumber r;
|
|
|
2ff057 |
mpnumber s;
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
struct pgpDigKeyDSA_s {
|
|
|
2ff057 |
mpbarrett p;
|
|
|
2ff057 |
mpbarrett q;
|
|
|
2ff057 |
mpnumber g;
|
|
|
2ff057 |
mpnumber y;
|
|
|
2ff057 |
int qbytes;
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num, const uint8_t *p)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
struct pgpDigSigDSA_s *sig = pgpsig->data;
|
|
|
2ff057 |
int mlen = pgpMpiLen(p) - 2;
|
|
|
2ff057 |
int rc = 1;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!sig)
|
|
|
2ff057 |
sig = pgpsig->data = xcalloc(1, sizeof(*sig));
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (num) {
|
|
|
2ff057 |
case 0:
|
|
|
2ff057 |
if (!mpnsetbin(&sig->r, p + 2, mlen))
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case 1:
|
|
|
2ff057 |
if (!mpnsetbin(&sig->s, p + 2, mlen))
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
struct pgpDigKeyDSA_s *key = pgpkey->data;
|
|
|
2ff057 |
int mlen = pgpMpiLen(p) - 2;
|
|
|
2ff057 |
int rc = 1;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (!key)
|
|
|
2ff057 |
key = pgpkey->data = xcalloc(1, sizeof(*key));
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (num) {
|
|
|
2ff057 |
case 0:
|
|
|
2ff057 |
if (!mpbsetbin(&key->p, p + 2, mlen))
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case 1:
|
|
|
2ff057 |
key->qbytes = mlen;
|
|
|
2ff057 |
if (!mpbsetbin(&key->q, p + 2, mlen))
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case 2:
|
|
|
2ff057 |
if (!mpnsetbin(&key->g, p + 2, mlen))
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case 3:
|
|
|
2ff057 |
if (!mpnsetbin(&key->y, p + 2, mlen))
|
|
|
2ff057 |
rc = 0;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
struct pgpDigKeyDSA_s *key = pgpkey->data;
|
|
|
2ff057 |
struct pgpDigSigDSA_s *sig = pgpsig->data;
|
|
|
2ff057 |
mpnumber hm;
|
|
|
2ff057 |
int rc = 1;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (sig && key && hashlen >= key->qbytes) {
|
|
|
2ff057 |
mpnzero(&hm;;
|
|
|
2ff057 |
mpnsetbin(&hm, hash, key->qbytes);
|
|
|
2ff057 |
rc = dsavrfy(&key->p, &key->q, &key->g, &hm, &key->y, &sig->r, &sig->s) == 1 ? 0 : 1;
|
|
|
2ff057 |
mpnfree(&hm;;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static void pgpFreeSigDSA(pgpDigAlg pgpsig)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
struct pgpDigSigDSA_s *sig = pgpsig->data;
|
|
|
2ff057 |
if (sig) {
|
|
|
2ff057 |
mpnfree(&sig->r);
|
|
|
2ff057 |
mpnfree(&sig->s);
|
|
|
2ff057 |
pgpsig->data = _free(sig);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static void pgpFreeKeyDSA(pgpDigAlg pgpkey)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
struct pgpDigKeyDSA_s *key = pgpkey->data;
|
|
|
2ff057 |
if (key) {
|
|
|
2ff057 |
mpbfree(&key->p);
|
|
|
2ff057 |
mpbfree(&key->q);
|
|
|
2ff057 |
mpnfree(&key->g);
|
|
|
2ff057 |
mpnfree(&key->y);
|
|
|
2ff057 |
pgpkey->data = _free(key);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
|
|
|
2ff057 |
/****************************** NULL **************************************/
|
|
|
2ff057 |
|
|
|
2ff057 |
static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num, const uint8_t *p)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
|
|
|
2ff057 |
uint8_t *hash, size_t hashlen, int hash_algo)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
pgpDigAlg pgpPubkeyNew(int algo)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
pgpDigAlg ka = xcalloc(1, sizeof(*ka));;
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (algo) {
|
|
|
2ff057 |
case PGPPUBKEYALGO_RSA:
|
|
|
2ff057 |
ka->setmpi = pgpSetKeyMpiRSA;
|
|
|
2ff057 |
ka->free = pgpFreeKeyRSA;
|
|
|
2ff057 |
ka->mpis = 2;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PGPPUBKEYALGO_DSA:
|
|
|
2ff057 |
ka->setmpi = pgpSetKeyMpiDSA;
|
|
|
2ff057 |
ka->free = pgpFreeKeyDSA;
|
|
|
2ff057 |
ka->mpis = 4;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
ka->setmpi = pgpSetMpiNULL;
|
|
|
2ff057 |
ka->mpis = -1;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
ka->verify = pgpVerifyNULL; /* keys can't be verified */
|
|
|
2ff057 |
|
|
|
2ff057 |
return ka;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
pgpDigAlg pgpSignatureNew(int algo)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
pgpDigAlg sa = xcalloc(1, sizeof(*sa));
|
|
|
2ff057 |
|
|
|
2ff057 |
switch (algo) {
|
|
|
2ff057 |
case PGPPUBKEYALGO_RSA:
|
|
|
2ff057 |
sa->setmpi = pgpSetSigMpiRSA;
|
|
|
2ff057 |
sa->free = pgpFreeSigRSA;
|
|
|
2ff057 |
sa->verify = pgpVerifySigRSA;
|
|
|
2ff057 |
sa->mpis = 1;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case PGPPUBKEYALGO_DSA:
|
|
|
2ff057 |
sa->setmpi = pgpSetSigMpiDSA;
|
|
|
2ff057 |
sa->free = pgpFreeSigDSA;
|
|
|
2ff057 |
sa->verify = pgpVerifySigDSA;
|
|
|
2ff057 |
sa->mpis = 2;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
sa->setmpi = pgpSetMpiNULL;
|
|
|
2ff057 |
sa->verify = pgpVerifyNULL;
|
|
|
2ff057 |
sa->mpis = -1;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return sa;
|
|
|
2ff057 |
}
|