mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Simplify abstraction of verification algorithms (it was too flexible)
This commit is contained in:
committed by
Simon Kelley
parent
1f0dc5835b
commit
3af1ea8cbc
@@ -32,15 +32,16 @@ typedef struct VerifyAlgCtx VerifyAlgCtx;
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int (*set_signature)(VerifyAlgCtx *ctx, unsigned char *data, unsigned len);
|
int digest_algo;
|
||||||
int (*get_digestalgo)(VerifyAlgCtx *ctx);
|
|
||||||
void (*set_digest)(VerifyAlgCtx *ctx, unsigned char *digest);
|
|
||||||
int (*verify)(VerifyAlgCtx *ctx, struct keydata *key, unsigned key_len);
|
int (*verify)(VerifyAlgCtx *ctx, struct keydata *key, unsigned key_len);
|
||||||
} VerifyAlg;
|
} VerifyAlg;
|
||||||
|
|
||||||
struct VerifyAlgCtx
|
struct VerifyAlgCtx
|
||||||
{
|
{
|
||||||
const VerifyAlg *vtbl;
|
const VerifyAlg *vtbl;
|
||||||
|
unsigned char *sig;
|
||||||
|
size_t siglen;
|
||||||
|
unsigned char digest[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
int verifyalg_supported(int algo);
|
int verifyalg_supported(int algo);
|
||||||
@@ -53,6 +54,7 @@ int verifyalg_algonum(VerifyAlgCtx *a);
|
|||||||
/* RFC4034 digest algorithms */
|
/* RFC4034 digest algorithms */
|
||||||
#define DIGESTALG_SHA1 1
|
#define DIGESTALG_SHA1 1
|
||||||
#define DIGESTALG_SHA256 2
|
#define DIGESTALG_SHA256 2
|
||||||
|
#define DIGESTALG_MD5 256
|
||||||
|
|
||||||
int digestalg_supported(int algo);
|
int digestalg_supported(int algo);
|
||||||
int digestalg_begin(int algo);
|
int digestalg_begin(int algo);
|
||||||
|
|||||||
@@ -6,37 +6,10 @@
|
|||||||
#include <openssl/dsa.h>
|
#include <openssl/dsa.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
|
||||||
typedef struct VACTX_rsasha1
|
|
||||||
{
|
|
||||||
VerifyAlgCtx base;
|
|
||||||
unsigned char *sig;
|
|
||||||
unsigned siglen;
|
|
||||||
unsigned char digest[20];
|
|
||||||
} VACTX_rsasha1;
|
|
||||||
|
|
||||||
typedef struct VACTX_rsasha256
|
|
||||||
{
|
|
||||||
VerifyAlgCtx base;
|
|
||||||
unsigned char *sig;
|
|
||||||
unsigned siglen;
|
|
||||||
unsigned char digest[32];
|
|
||||||
} VACTX_rsasha256;
|
|
||||||
|
|
||||||
typedef struct VACTX_dsasha1
|
|
||||||
{
|
|
||||||
VerifyAlgCtx base;
|
|
||||||
unsigned char *sig;
|
|
||||||
unsigned siglen;
|
|
||||||
unsigned char digest[20];
|
|
||||||
} VACTX_dsasha1;
|
|
||||||
|
|
||||||
|
|
||||||
#define POOL_SIZE 1
|
#define POOL_SIZE 1
|
||||||
static union _Pool
|
static union _Pool
|
||||||
{
|
{
|
||||||
VACTX_rsasha1 rsasha1;
|
VerifyAlgCtx ctx;
|
||||||
VACTX_rsasha256 rsasha256;
|
|
||||||
VACTX_dsasha1 dsasha1;
|
|
||||||
} Pool[POOL_SIZE];
|
} Pool[POOL_SIZE];
|
||||||
static char pool_used = 0;
|
static char pool_used = 0;
|
||||||
|
|
||||||
@@ -50,62 +23,6 @@ static void print_hex(unsigned char *data, unsigned len)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rsasha1_set_signature(VerifyAlgCtx *ctx_, unsigned char *data, unsigned len)
|
|
||||||
{
|
|
||||||
VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
|
|
||||||
ctx->sig = data;
|
|
||||||
ctx->siglen = len;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rsasha256_set_signature(VerifyAlgCtx *ctx_, unsigned char *data, unsigned len)
|
|
||||||
{
|
|
||||||
VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
|
|
||||||
ctx->sig = data;
|
|
||||||
ctx->siglen = len;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dsasha1_set_signature(VerifyAlgCtx *ctx_, unsigned char *data, unsigned len)
|
|
||||||
{
|
|
||||||
VACTX_dsasha1 *ctx = (VACTX_dsasha1 *)ctx_;
|
|
||||||
ctx->sig = data;
|
|
||||||
ctx->siglen = len;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rsasha1_get_digestalgo(VerifyAlgCtx *ctx_)
|
|
||||||
{
|
|
||||||
(void)ctx_;
|
|
||||||
return DIGESTALG_SHA1;
|
|
||||||
}
|
|
||||||
static int rsasha256_get_digestalgo(VerifyAlgCtx *ctx_)
|
|
||||||
{
|
|
||||||
(void)ctx_;
|
|
||||||
return DIGESTALG_SHA256;
|
|
||||||
}
|
|
||||||
static int dsasha1_get_digestalgo(VerifyAlgCtx *ctx_)
|
|
||||||
{
|
|
||||||
(void)ctx_;
|
|
||||||
return DIGESTALG_SHA1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rsasha1_set_digest(VerifyAlgCtx *ctx_, unsigned char *digest)
|
|
||||||
{
|
|
||||||
VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
|
|
||||||
memcpy(ctx->digest, digest, sizeof(ctx->digest));
|
|
||||||
}
|
|
||||||
static void rsasha256_set_digest(VerifyAlgCtx *ctx_, unsigned char *digest)
|
|
||||||
{
|
|
||||||
VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
|
|
||||||
memcpy(ctx->digest, digest, sizeof(ctx->digest));
|
|
||||||
}
|
|
||||||
static void dsasha1_set_digest(VerifyAlgCtx *ctx_, unsigned char *digest)
|
|
||||||
{
|
|
||||||
VACTX_dsasha1 *ctx = (VACTX_dsasha1 *)ctx_;
|
|
||||||
memcpy(ctx->digest, digest, sizeof(ctx->digest));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int keydata_to_bn(BIGNUM *ret, struct keydata **key_data, unsigned char **p, unsigned len)
|
static int keydata_to_bn(BIGNUM *ret, struct keydata **key_data, unsigned char **p, unsigned len)
|
||||||
{
|
{
|
||||||
size_t cnt;
|
size_t cnt;
|
||||||
@@ -160,9 +77,13 @@ static int dsasha1_parse_key(BIGNUM *Q, BIGNUM *P, BIGNUM *G, BIGNUM *Y, struct
|
|||||||
keydata_to_bn(Y, &key_data, &p, 64+T*8);
|
keydata_to_bn(Y, &key_data, &p, 64+T*8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rsasha1_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned key_len)
|
static int rsamd5_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rsasha1_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len)
|
||||||
{
|
{
|
||||||
VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
|
|
||||||
int validated = 0;
|
int validated = 0;
|
||||||
|
|
||||||
RSA *rsa = RSA_new();
|
RSA *rsa = RSA_new();
|
||||||
@@ -176,9 +97,8 @@ static int rsasha1_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned
|
|||||||
return validated;
|
return validated;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rsasha256_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned key_len)
|
static int rsasha256_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len)
|
||||||
{
|
{
|
||||||
VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
|
|
||||||
int validated = 0;
|
int validated = 0;
|
||||||
|
|
||||||
RSA *rsa = RSA_new();
|
RSA *rsa = RSA_new();
|
||||||
@@ -192,7 +112,7 @@ static int rsasha256_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsign
|
|||||||
return validated;
|
return validated;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsasha1_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned key_len)
|
static int dsasha1_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len)
|
||||||
{
|
{
|
||||||
static unsigned char asn1_signature[] =
|
static unsigned char asn1_signature[] =
|
||||||
{
|
{
|
||||||
@@ -202,7 +122,6 @@ static int dsasha1_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned
|
|||||||
0x02, 21, // large integer (21 bytes)
|
0x02, 21, // large integer (21 bytes)
|
||||||
0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // S
|
0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // S
|
||||||
};
|
};
|
||||||
VACTX_dsasha1 *ctx = (VACTX_dsasha1 *)ctx_;
|
|
||||||
int validated = 0;
|
int validated = 0;
|
||||||
|
|
||||||
/* A DSA signature is made of 2 bignums (R & S). We could parse them manually with BN_bin2bn(),
|
/* A DSA signature is made of 2 bignums (R & S). We could parse them manually with BN_bin2bn(),
|
||||||
@@ -227,13 +146,11 @@ static int dsasha1_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define VALG_UNSUPPORTED() { \
|
#define VALG_UNSUPPORTED() { \
|
||||||
0,0,0,0 \
|
0,0 \
|
||||||
} /**/
|
} /**/
|
||||||
|
|
||||||
#define VALG_VTABLE(alg) { \
|
#define VALG_VTABLE(alg, digest) { \
|
||||||
alg ## _set_signature, \
|
digest, \
|
||||||
alg ## _get_digestalgo, \
|
|
||||||
alg ## _set_digest, \
|
|
||||||
alg ## _verify \
|
alg ## _verify \
|
||||||
} /**/
|
} /**/
|
||||||
|
|
||||||
@@ -241,34 +158,36 @@ static int dsasha1_verify(VerifyAlgCtx *ctx_, struct keydata *key_data, unsigned
|
|||||||
https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xml */
|
https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xml */
|
||||||
static const VerifyAlg valgs[] =
|
static const VerifyAlg valgs[] =
|
||||||
{
|
{
|
||||||
VALG_UNSUPPORTED(), /* 0: reserved */
|
VALG_UNSUPPORTED(), /* 0: reserved */
|
||||||
VALG_UNSUPPORTED(), /* 1: RSAMD5 */
|
VALG_VTABLE(rsamd5, DIGESTALG_MD5), /* 1: RSAMD5 */
|
||||||
VALG_UNSUPPORTED(), /* 2: DH */
|
VALG_UNSUPPORTED(), /* 2: DH */
|
||||||
VALG_VTABLE(dsasha1), /* 3: DSA */
|
VALG_VTABLE(dsasha1, DIGESTALG_SHA1), /* 3: DSA */
|
||||||
VALG_UNSUPPORTED(), /* 4: ECC */
|
VALG_UNSUPPORTED(), /* 4: ECC */
|
||||||
VALG_VTABLE(rsasha1), /* 5: RSASHA1 */
|
VALG_VTABLE(rsasha1, DIGESTALG_SHA1), /* 5: RSASHA1 */
|
||||||
VALG_UNSUPPORTED(), /* 6: DSA-NSEC3-SHA1 */
|
VALG_UNSUPPORTED(), /* 6: DSA-NSEC3-SHA1 */
|
||||||
VALG_VTABLE(rsasha1), /* 7: RSASHA1-NSEC3-SHA1 */
|
VALG_VTABLE(rsasha1, DIGESTALG_SHA1), /* 7: RSASHA1-NSEC3-SHA1 */
|
||||||
VALG_VTABLE(rsasha256), /* 8: RSASHA256 */
|
VALG_VTABLE(rsasha256, DIGESTALG_SHA256), /* 8: RSASHA256 */
|
||||||
VALG_UNSUPPORTED(), /* 9: unassigned */
|
VALG_UNSUPPORTED(), /* 9: unassigned */
|
||||||
VALG_UNSUPPORTED(), /* 10: RSASHA512 */
|
VALG_UNSUPPORTED(), /* 10: RSASHA512 */
|
||||||
VALG_UNSUPPORTED(), /* 11: unassigned */
|
VALG_UNSUPPORTED(), /* 11: unassigned */
|
||||||
VALG_UNSUPPORTED(), /* 12: ECC-GOST */
|
VALG_UNSUPPORTED(), /* 12: ECC-GOST */
|
||||||
VALG_UNSUPPORTED(), /* 13: ECDSAP256SHA256 */
|
VALG_UNSUPPORTED(), /* 13: ECDSAP256SHA256 */
|
||||||
VALG_UNSUPPORTED(), /* 14: ECDSAP384SHA384 */
|
VALG_UNSUPPORTED(), /* 14: ECDSAP384SHA384 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* TODO: remove if we don't need this anymore
|
||||||
|
(to be rechecked if we ever remove OpenSSL) */
|
||||||
static const int valgctx_size[] =
|
static const int valgctx_size[] =
|
||||||
{
|
{
|
||||||
0, /* 0: reserved */
|
0, /* 0: reserved */
|
||||||
0, /* 1: RSAMD5 */
|
sizeof(VerifyAlgCtx), /* 1: RSAMD5 */
|
||||||
0, /* 2: DH */
|
0, /* 2: DH */
|
||||||
sizeof(VACTX_dsasha1), /* 3: DSA */
|
sizeof(VerifyAlgCtx), /* 3: DSA */
|
||||||
0, /* 4: ECC */
|
0, /* 4: ECC */
|
||||||
sizeof(VACTX_rsasha1), /* 5: RSASHA1 */
|
sizeof(VerifyAlgCtx), /* 5: RSASHA1 */
|
||||||
0, /* 6: DSA-NSEC3-SHA1 */
|
0, /* 6: DSA-NSEC3-SHA1 */
|
||||||
sizeof(VACTX_rsasha1), /* 7: RSASHA1-NSEC3-SHA1 */
|
sizeof(VerifyAlgCtx), /* 7: RSASHA1-NSEC3-SHA1 */
|
||||||
sizeof(VACTX_rsasha256), /* 8: RSASHA256 */
|
sizeof(VerifyAlgCtx), /* 8: RSASHA256 */
|
||||||
0, /* 9: unassigned */
|
0, /* 9: unassigned */
|
||||||
0, /* 10: RSASHA512 */
|
0, /* 10: RSASHA512 */
|
||||||
0, /* 11: unassigned */
|
0, /* 11: unassigned */
|
||||||
@@ -330,16 +249,20 @@ static EVP_MD_CTX digctx;
|
|||||||
|
|
||||||
int digestalg_supported(int algo)
|
int digestalg_supported(int algo)
|
||||||
{
|
{
|
||||||
return (algo == DIGESTALG_SHA1 || algo == DIGESTALG_SHA256);
|
return (algo == DIGESTALG_SHA1 ||
|
||||||
|
algo == DIGESTALG_SHA256 ||
|
||||||
|
algo == DIGESTALG_MD5);
|
||||||
}
|
}
|
||||||
|
|
||||||
int digestalg_begin(int algo)
|
int digestalg_begin(int algo)
|
||||||
{
|
{
|
||||||
EVP_MD_CTX_init(&digctx);
|
EVP_MD_CTX_init(&digctx);
|
||||||
if (algo == 1)
|
if (algo == DIGESTALG_SHA1)
|
||||||
EVP_DigestInit_ex(&digctx, EVP_sha1(), NULL);
|
EVP_DigestInit_ex(&digctx, EVP_sha1(), NULL);
|
||||||
else if (algo == 2)
|
else if (algo == DIGESTALG_SHA256)
|
||||||
EVP_DigestInit_ex(&digctx, EVP_sha256(), NULL);
|
EVP_DigestInit_ex(&digctx, EVP_sha256(), NULL);
|
||||||
|
else if (algo == DIGESTALG_MD5)
|
||||||
|
EVP_DigestInit_ex(&digctx, EVP_md5(), NULL);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -561,8 +561,8 @@ static int begin_rrsig_validation(struct dns_header *header, size_t pktlen,
|
|||||||
VerifyAlgCtx *alg = verifyalg_alloc(sigalg);
|
VerifyAlgCtx *alg = verifyalg_alloc(sigalg);
|
||||||
if (!alg)
|
if (!alg)
|
||||||
return 0;
|
return 0;
|
||||||
if (!alg->vtbl->set_signature(alg, sig, sigrdlen))
|
alg->sig = sig;
|
||||||
return 0;
|
alg->siglen = sigrdlen;
|
||||||
|
|
||||||
sigtype = htons(sigtype);
|
sigtype = htons(sigtype);
|
||||||
sigclass = htons(sigclass);
|
sigclass = htons(sigclass);
|
||||||
@@ -575,7 +575,7 @@ static int begin_rrsig_validation(struct dns_header *header, size_t pktlen,
|
|||||||
unsigned char owner_wire[MAXCDNAME];
|
unsigned char owner_wire[MAXCDNAME];
|
||||||
int owner_wire_len = convert_domain_to_wire(owner, owner_wire);
|
int owner_wire_len = convert_domain_to_wire(owner, owner_wire);
|
||||||
|
|
||||||
digestalg_begin(alg->vtbl->get_digestalgo(alg));
|
digestalg_begin(alg->vtbl->digest_algo);
|
||||||
digestalg_add_data(sigrdata, 18+signer_name_rdlen);
|
digestalg_add_data(sigrdata, 18+signer_name_rdlen);
|
||||||
for (i = 0; i < rrsetidx; ++i)
|
for (i = 0; i < rrsetidx; ++i)
|
||||||
{
|
{
|
||||||
@@ -590,7 +590,8 @@ static int begin_rrsig_validation(struct dns_header *header, size_t pktlen,
|
|||||||
if (!digestalg_add_rdata(ntohs(sigtype), header, pktlen, p))
|
if (!digestalg_add_rdata(ntohs(sigtype), header, pktlen, p))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
alg->vtbl->set_digest(alg, digestalg_final());
|
int digest_len = digestalg_len();
|
||||||
|
memcpy(alg->digest, digestalg_final(), digest_len);
|
||||||
|
|
||||||
/* We don't need the owner name anymore; now extract the signer name */
|
/* We don't need the owner name anymore; now extract the signer name */
|
||||||
if (!extract_name_no_compression(sigrdata+18, signer_name_rdlen, signer_name))
|
if (!extract_name_no_compression(sigrdata+18, signer_name_rdlen, signer_name))
|
||||||
|
|||||||
Reference in New Issue
Block a user