static void bench_rsa_verify (void *p) { struct rsa_ctx *ctx = p; if (! rsa_sha256_verify_digest (&ctx->pub, ctx->digest, ctx->s)) die ("Internal error, rsa_sha256_verify_digest failed.\n"); }
static char * _verify_nettle_rsa(sldns_buffer* buf, unsigned int digest_size, char* sigblock, unsigned int sigblock_len, uint8_t* key, unsigned int keylen) { uint16_t exp_len = 0; size_t exp_offset = 0, mod_offset = 0; struct rsa_public_key pubkey; mpz_t signature; int res = 0; /* RSA pubkey parsing as per RFC 3110 sec. 2 */ if( keylen <= 1) { return "null RSA key"; } if (key[0] != 0) { /* 1-byte length */ exp_len = key[0]; exp_offset = 1; } else { /* 1-byte NUL + 2-bytes exponent length */ if (keylen < 3) { return "incorrect RSA key length"; } exp_len = READ_UINT16(key+1); if (exp_len == 0) return "null RSA exponent length"; exp_offset = 3; } /* Check that we are not over-running input length */ if (keylen < exp_offset + exp_len + 1) { return "RSA key content shorter than expected"; } mod_offset = exp_offset + exp_len; nettle_rsa_public_key_init(&pubkey); pubkey.size = keylen - mod_offset; nettle_mpz_set_str_256_u(pubkey.e, exp_len, &key[exp_offset]); nettle_mpz_set_str_256_u(pubkey.n, pubkey.size, &key[mod_offset]); /* Digest content of "buf" and verify its RSA signature in "sigblock"*/ nettle_mpz_init_set_str_256_u(signature, sigblock_len, (uint8_t*)sigblock); switch (digest_size) { case SHA1_DIGEST_SIZE: { uint8_t digest[SHA1_DIGEST_SIZE]; res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); res &= rsa_sha1_verify_digest(&pubkey, digest, signature); break; } case SHA256_DIGEST_SIZE: { uint8_t digest[SHA256_DIGEST_SIZE]; res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); res &= rsa_sha256_verify_digest(&pubkey, digest, signature); break; } case SHA512_DIGEST_SIZE: { uint8_t digest[SHA512_DIGEST_SIZE]; res = _digest_nettle(SHA512_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); res &= rsa_sha512_verify_digest(&pubkey, digest, signature); break; } default: break; } /* Clear and return */ nettle_rsa_public_key_clear(&pubkey); mpz_clear(signature); if (!res) { return "RSA signature verification failed"; } else { return NULL; } }