From 75ffc9bf1501390b3a10a48b39582959d055ca77 Mon Sep 17 00:00:00 2001 From: Giovanni Bajo Date: Wed, 2 May 2012 19:58:06 +0200 Subject: [PATCH] Implement RSA-MD5. --- src/dnssec-openssl.c | 41 ++++++++++++++++++----------------------- src/dnssec.c | 27 ++++++++++++++++++--------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/dnssec-openssl.c b/src/dnssec-openssl.c index dc37294..06ac557 100644 --- a/src/dnssec-openssl.c +++ b/src/dnssec-openssl.c @@ -77,39 +77,34 @@ static int dsasha1_parse_key(BIGNUM *Q, BIGNUM *P, BIGNUM *G, BIGNUM *Y, struct keydata_to_bn(Y, &key_data, &p, 64+T*8); } +static int rsa_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len, int nid, int dlen) +{ + int validated = 0; + + RSA *rsa = RSA_new(); + rsa->e = BN_new(); + rsa->n = BN_new(); + if (rsasha1_parse_key(rsa->e, rsa->n, key_data, key_len) + && RSA_verify(nid, ctx->digest, dlen, ctx->sig, ctx->siglen, rsa)) + validated = 1; + + RSA_free(rsa); + return validated; +} + static int rsamd5_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len) { - return 0; + return rsa_verify(ctx, key_data, key_len, NID_md5, 16); } static int rsasha1_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len) { - int validated = 0; - - RSA *rsa = RSA_new(); - rsa->e = BN_new(); - rsa->n = BN_new(); - if (rsasha1_parse_key(rsa->e, rsa->n, key_data, key_len) - && RSA_verify(NID_sha1, ctx->digest, 20, ctx->sig, ctx->siglen, rsa)) - validated = 1; - - RSA_free(rsa); - return validated; + return rsa_verify(ctx, key_data, key_len, NID_sha1, 20); } static int rsasha256_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len) { - int validated = 0; - - RSA *rsa = RSA_new(); - rsa->e = BN_new(); - rsa->n = BN_new(); - if (rsasha1_parse_key(rsa->e, rsa->n, key_data, key_len) - && RSA_verify(NID_sha256, ctx->digest, 32, ctx->sig, ctx->siglen, rsa)) - validated = 1; - - RSA_free(rsa); - return validated; + return rsa_verify(ctx, key_data, key_len, NID_sha256, 32); } static int dsasha1_verify(VerifyAlgCtx *ctx, struct keydata *key_data, unsigned key_len) diff --git a/src/dnssec.c b/src/dnssec.c index b2abb94..3ad438d 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -649,16 +649,25 @@ static void dnssec_parserrsig(struct dns_header *header, size_t pktlen, } /* Compute keytag (checksum to quickly index a key). See RFC4034 */ -static int dnskey_keytag(unsigned char *rdata, int rdlen) +static int dnskey_keytag(int alg, unsigned char *rdata, int rdlen) { - unsigned long ac; - int i; + if (alg == 1) + { + /* Algorithm 1 (RSAMD5) has a different (older) keytag calculation algorithm. + See RFC4034, Appendix B.1 */ + return rdata[rdlen-3] * 256 + rdata[rdlen-2]; + } + else + { + unsigned long ac; + int i; - ac = 0; - for (i = 0; i < rdlen; ++i) - ac += (i & 1) ? rdata[i] : rdata[i] << 8; - ac += (ac >> 16) & 0xFFFF; - return ac & 0xFFFF; + ac = 0; + for (i = 0; i < rdlen; ++i) + ac += (i & 1) ? rdata[i] : rdata[i] << 8; + ac += (ac >> 16) & 0xFFFF; + return ac & 0xFFFF; + } } /* Check if the DS record (from cache) points to the DNSKEY record (from cache) */ @@ -712,7 +721,7 @@ int dnssec_parsekey(struct dns_header *header, size_t pktlen, char *owner, unsig crecp->uid = rdlen; crecp->addr.key.keydata = key; crecp->addr.key.algo = alg; - crecp->addr.key.keytag = dnskey_keytag(ordata, ordlen); + crecp->addr.key.keytag = dnskey_keytag(alg, ordata, ordlen); printf("DNSKEY: storing key for %s (keytag: %d)\n", owner, crecp->addr.key.keytag); } else