2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

Add PRIVATEOIDs for RSASHA256 and RSASHA512

Use the existing RSASHA256 and RSASHA512 implementation to provide
working PRIVATEOID example implementations.  We are using the OID
values normally associated with RSASHA256 (1.2.840.113549.1.1.11)
and RSASHA512 (1.2.840.113549.1.1.13).
This commit is contained in:
Mark Andrews
2025-04-01 00:12:52 +11:00
parent 10d094a289
commit e687710dc7
13 changed files with 175 additions and 5 deletions

View File

@@ -286,6 +286,8 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
case DST_ALG_NSEC3RSASHA1:
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA512:
case DST_ALG_RSASHA256PRIVATEOID:
case DST_ALG_RSASHA512PRIVATEOID:
case DST_ALG_ECDSA256:
case DST_ALG_ECDSA384:
case DST_ALG_ED25519:
@@ -309,6 +311,8 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
FALLTHROUGH;
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA512:
case DST_ALG_RSASHA256PRIVATEOID:
case DST_ALG_RSASHA512PRIVATEOID:
ctx->size = 2048;
if (verbose > 0) {
fprintf(stderr,
@@ -462,6 +466,8 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
FALLTHROUGH;
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA512:
case DST_ALG_RSASHA256PRIVATEOID:
case DST_ALG_RSASHA512PRIVATEOID:
if (ctx->size != 0 &&
(ctx->size < min_rsa || ctx->size > MAX_RSA))
{

View File

@@ -356,6 +356,8 @@ create_key(ksr_ctx_t *ksr, dns_kasp_t *kasp, dns_kasp_key_t *kaspkey,
FALLTHROUGH;
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA512:
case DST_ALG_RSASHA256PRIVATEOID:
case DST_ALG_RSASHA512PRIVATEOID:
if (ksr->size != 0 &&
(ksr->size < min_rsa || ksr->size > MAX_RSA))
{

View File

@@ -212,6 +212,10 @@ private_type_record() {
_algorithm=$2
_keyfile=$3
_secalg=$2
case $_secalg in
256) _secalg=254 ;; # RSASHA256OID
257) _secalg=254 ;; # RSASHA512OID
esac
_id=$(keyfile_to_key_id "$_keyfile")

View File

@@ -3481,7 +3481,7 @@ status=$((status + ret))
echo_i "check that 'dnssec-keygen -S' works for all supported algorithms ($n)"
ret=0
alg=1
until test $alg -eq 256; do
until test $alg -eq 258; do
zone="keygen-$alg."
case $alg in
2) # Diffie Helman
@@ -3498,10 +3498,20 @@ until test $alg -eq 256; do
15 | 16)
key1=$($KEYGEN -a "$alg" "$zone" 2>"keygen-$alg.err" || true)
;;
256)
key1=$($KEYGEN -a "RSASHA256OID" "$zone" 2>"keygen-$alg.err" || true)
;;
257)
key1=$($KEYGEN -a "RSASHA512OID" "$zone" 2>"keygen-$alg.err" || true)
;;
*)
key1=$($KEYGEN -a "$alg" "$zone" 2>"keygen-$alg.err" || true)
;;
esac
if grep "unknown algorithm" "keygen-$alg.err" >/dev/null; then
alg=$((alg + 1))
continue
fi
if grep "unsupported algorithm" "keygen-$alg.err" >/dev/null; then
alg=$((alg + 1))
continue

View File

@@ -392,6 +392,10 @@ class Key:
def get_dnsalg(self) -> int:
alg = int(self.get_metadata("Algorithm"))
if alg == isctest.vars.algorithms.RSASHA256OID.dst:
return isctest.vars.algorithms.RSASHA256OID.number
if alg == isctest.vars.algorithms.RSASHA512OID.dst:
return isctest.vars.algorithms.RSASHA512OID.number
return alg
def ttl(self) -> int:

View File

@@ -83,6 +83,8 @@ ECDSAP256SHA256 = Algorithm("ECDSAP256SHA256", 13, 13, 256)
ECDSAP384SHA384 = Algorithm("ECDSAP384SHA384", 14, 14, 384)
ED25519 = Algorithm("ED25519", 15, 15, 256)
ED448 = Algorithm("ED448", 16, 16, 456)
RSASHA256OID = Algorithm("RSASHA256OID", 254, 256, 2048)
RSASHA512OID = Algorithm("RSASHA512OID", 254, 257, 2048)
ALL_ALGORITHMS = [
RSASHA1,
@@ -92,6 +94,8 @@ ALL_ALGORITHMS = [
ECDSAP384SHA384,
ED25519,
ED448,
RSASHA256OID,
RSASHA512OID,
]
ALL_ALGORITHMS_BY_NUM = {alg.number: alg for alg in ALL_ALGORITHMS}
@@ -153,6 +157,8 @@ CRYPTO_SUPPORTED_VARS = {
"ECDSAP384SHA384_SUPPORTED": "0",
"ED25519_SUPPORTED": "0",
"ED448_SUPPORTED": "0",
"RSASHA256OID_SUPPORTED": "0",
"RSASHA512OID_SUPPORTED": "0",
}
SUPPORTED_ALGORITHMS: List[Algorithm] = []

View File

@@ -140,6 +140,14 @@ static const char *keystates[KEYSTATES_NVALUES] = {
static dst_func_t *dst_t_func[DST_MAX_ALGS] = { 0 };
/* length byte + 1.2.840.113549.1.1.11 BER encoded RFC 4055 */
static unsigned char oid_rsasha256[] = { 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b };
/* length byte + 1.2.840.113549.1.1.13 BER encoded RFC 4055 */
static unsigned char oid_rsasha512[] = { 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d };
void
gss_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
@@ -215,6 +223,18 @@ dst__lib_initialize(void) {
#if HAVE_GSSAPI
dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI]);
#endif /* HAVE_GSSAPI */
/*
* RSASHA256 using assigned OID 1.2.840.113549.1.1.11 as
* a private OID example.
*/
dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA256PRIVATEOID],
DST_ALG_RSASHA256PRIVATEOID);
/*
* RSASHA512 using assigned OID 1.2.840.113549.1.1.13 as
* a private OID example.
*/
dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA512PRIVATEOID],
DST_ALG_RSASHA512PRIVATEOID);
}
void
@@ -1311,6 +1331,12 @@ dst_key_sigsize(const dst_key_t *key, unsigned int *n) {
case DST_ALG_RSASHA512:
*n = (key->key_size + 7) / 8;
break;
case DST_ALG_RSASHA256PRIVATEOID:
*n = (key->key_size + 7) / 8 + sizeof(oid_rsasha256);
break;
case DST_ALG_RSASHA512PRIVATEOID:
*n = (key->key_size + 7) / 8 + sizeof(oid_rsasha512);
break;
case DST_ALG_ECDSA256:
*n = DNS_SIG_ECDSA256SIZE;
break;
@@ -2664,7 +2690,10 @@ dst_hmac_algorithm_totext(dst_algorithm_t alg) {
dns_secalg_t
dst_algorithm_tosecalg(dst_algorithm_t dst_alg) {
static dns_secalg_t dns_alg[DST_MAX_ALGS] = { 0 };
static dns_secalg_t dns_alg[DST_MAX_ALGS] = {
[DST_ALG_RSASHA256PRIVATEOID] = DNS_KEYALG_PRIVATEOID,
[DST_ALG_RSASHA512PRIVATEOID] = DNS_KEYALG_PRIVATEOID,
};
if (dst_alg < 256) {
return dst_alg;
@@ -2703,8 +2732,19 @@ dst_algorithm_fromprivateoid(isc_buffer_t *buffer) {
* length byte followed by the OID of that length.
*/
if (r.length > 0 && ((unsigned int)r.base[0] + 1) <= r.length) {
return 0;
if (r.base[0] + 1 == sizeof(oid_rsasha256) &&
memcmp(oid_rsasha256, r.base, sizeof(oid_rsasha256)) == 0)
{
return DST_ALG_RSASHA256PRIVATEOID;
}
if (r.base[0] + 1 == sizeof(oid_rsasha512) &&
memcmp(oid_rsasha512, r.base, sizeof(oid_rsasha512)) == 0)
{
return DST_ALG_RSASHA512PRIVATEOID;
}
}
return 0;
}

View File

@@ -332,6 +332,8 @@ check_data(const dst_private_t *priv, const unsigned int alg, bool old,
case DST_ALG_NSEC3RSASHA1:
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA512:
case DST_ALG_RSASHA256PRIVATEOID:
case DST_ALG_RSASHA512PRIVATEOID:
return check_rsa(priv, external);
case DST_ALG_ECDSA256:
case DST_ALG_ECDSA384:
@@ -694,6 +696,12 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
case DST_ALG_HMACSHA512:
fprintf(fp, "(HMAC_SHA512)\n");
break;
case DST_ALG_RSASHA256PRIVATEOID:
fprintf(fp, "(OID:RSASHA256)\n");
break;
case DST_ALG_RSASHA512PRIVATEOID:
fprintf(fp, "(OID:RSASHA512)\n");
break;
default:
fprintf(fp, "(?)\n");
break;

View File

@@ -116,7 +116,9 @@ typedef enum dst_algorithm {
/*
* Put PRIVATE DNS and PRIVATE OID identifiers here.
*/
DST_MAX_ALGS = 256,
DST_ALG_RSASHA256PRIVATEOID = 256, /* 1.2.840.113549.1.1.11 */
DST_ALG_RSASHA512PRIVATEOID = 257, /* 1.2.840.113549.1.1.13 */
DST_MAX_ALGS = 258,
} dst_algorithm_t;
/*% A buffer of this size is large enough to hold any key */

View File

@@ -430,6 +430,8 @@ dns_kasp_key_size(dns_kasp_key_t *key) {
case DST_ALG_NSEC3RSASHA1:
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA512:
case DST_ALG_RSASHA256PRIVATEOID:
case DST_ALG_RSASHA512PRIVATEOID:
min = (key->algorithm == DST_ALG_RSASHA512) ? 1024 : 512;
if (key->length > -1) {
size = (unsigned int)key->length;

View File

@@ -50,6 +50,14 @@ typedef struct rsa_components {
const BIGNUM *e, *n, *d, *p, *q, *dmp1, *dmq1, *iqmp;
} rsa_components_t;
/* length byte + 1.2.840.113549.1.1.11 BER encoded RFC 4055 */
static unsigned char oid_rsasha256[] = { 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b };
/* length byte + 1.2.840.113549.1.1.13 BER encoded RFC 4055 */
static unsigned char oid_rsasha512[] = { 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d };
static isc_result_t
opensslrsa_components_get(const dst_key_t *key, rsa_components_t *c,
bool private) {
@@ -154,6 +162,8 @@ opensslrsa_valid_key_alg(unsigned int key_alg) {
case DST_ALG_NSEC3RSASHA1:
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA512:
case DST_ALG_RSASHA256PRIVATEOID:
case DST_ALG_RSASHA512PRIVATEOID:
return true;
default:
return false;
@@ -181,12 +191,14 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
}
break;
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA256PRIVATEOID:
/* From RFC 5702 */
if (dctx->key->key_size < 512 || dctx->key->key_size > 4096) {
return ISC_R_FAILURE;
}
break;
case DST_ALG_RSASHA512:
case DST_ALG_RSASHA512PRIVATEOID:
/* From RFC 5702 */
if (dctx->key->key_size < 1024 || dctx->key->key_size > 4096) {
return ISC_R_FAILURE;
@@ -207,9 +219,11 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
type = isc__crypto_sha1; /* SHA1 + RSA */
break;
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA256PRIVATEOID:
type = isc__crypto_sha256; /* SHA256 + RSA */
break;
case DST_ALG_RSASHA512:
case DST_ALG_RSASHA512PRIVATEOID:
type = isc__crypto_sha512;
break;
default:
@@ -277,6 +291,12 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
* Account to the space the OIDs and DNS names consume.
*/
switch (key->key_alg) {
case DST_ALG_RSASHA256PRIVATEOID:
len = sizeof(oid_rsasha256);
break;
case DST_ALG_RSASHA512PRIVATEOID:
len = sizeof(oid_rsasha512);
break;
}
isc_buffer_availableregion(sig, &r);
@@ -289,6 +309,14 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
* Add OID and DNS names to start of signature.
*/
switch (key->key_alg) {
case DST_ALG_RSASHA256PRIVATEOID:
isc_buffer_putmem(sig, oid_rsasha256, sizeof(oid_rsasha256));
isc_region_consume(&r, sizeof(oid_rsasha256));
break;
case DST_ALG_RSASHA512PRIVATEOID:
isc_buffer_putmem(sig, oid_rsasha512, sizeof(oid_rsasha512));
isc_region_consume(&r, sizeof(oid_rsasha512));
break;
}
if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) {
@@ -348,6 +376,24 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
* Check identifying OID in front of public key material.
*/
switch (key->key_alg) {
case DST_ALG_RSASHA256PRIVATEOID:
if (length < sizeof(oid_rsasha256) ||
memcmp(base, oid_rsasha256, sizeof(oid_rsasha256)) != 0)
{
return DST_R_VERIFYFAILURE;
}
base += sizeof(oid_rsasha256);
length -= sizeof(oid_rsasha256);
break;
case DST_ALG_RSASHA512PRIVATEOID:
if (length < sizeof(oid_rsasha512) ||
memcmp(base, oid_rsasha512, sizeof(oid_rsasha512)) != 0)
{
return DST_R_VERIFYFAILURE;
}
base += sizeof(oid_rsasha512);
length -= sizeof(oid_rsasha512);
break;
}
status = EVP_VerifyFinal(evp_md_ctx, base, length, pkey);
@@ -712,12 +758,14 @@ opensslrsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
}
break;
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA256PRIVATEOID:
/* From RFC 5702 */
if (key->key_size < 512 || key->key_size > 4096) {
DST_RET(DST_R_INVALIDPARAM);
}
break;
case DST_ALG_RSASHA512:
case DST_ALG_RSASHA512PRIVATEOID:
/* From RFC 5702 */
if (key->key_size < 1024 || key->key_size > 4096) {
DST_RET(DST_R_INVALIDPARAM);
@@ -764,6 +812,20 @@ opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) {
* Add identifying OID and DNS names to front of public key material.
*/
switch (key->key_alg) {
case DST_ALG_RSASHA256PRIVATEOID:
if (r.length < sizeof(oid_rsasha256)) {
DST_RET(ISC_R_NOSPACE);
}
isc_buffer_putmem(data, oid_rsasha256, sizeof(oid_rsasha256));
isc_region_consume(&r, sizeof(oid_rsasha256));
break;
case DST_ALG_RSASHA512PRIVATEOID:
if (r.length < sizeof(oid_rsasha512)) {
DST_RET(ISC_R_NOSPACE);
}
isc_buffer_putmem(data, oid_rsasha512, sizeof(oid_rsasha512));
isc_region_consume(&r, sizeof(oid_rsasha512));
break;
}
ret = opensslrsa_components_get(key, &c, false);
@@ -825,6 +887,24 @@ opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
* Check identifying OID in front of public key material.
*/
switch (key->key_alg) {
case DST_ALG_RSASHA256PRIVATEOID:
if (r.length < sizeof(oid_rsasha256) ||
memcmp(r.base, oid_rsasha256, sizeof(oid_rsasha256)) != 0)
{
DST_RET(DST_R_INVALIDPUBLICKEY);
}
isc_region_consume(&r, sizeof(oid_rsasha256));
isc_buffer_forward(data, sizeof(oid_rsasha256));
break;
case DST_ALG_RSASHA512PRIVATEOID:
if (r.length < sizeof(oid_rsasha512) ||
memcmp(r.base, oid_rsasha512, sizeof(oid_rsasha512)) != 0)
{
DST_RET(DST_R_INVALIDPUBLICKEY);
}
isc_region_consume(&r, sizeof(oid_rsasha512));
isc_buffer_forward(data, sizeof(oid_rsasha512));
break;
}
length = r.length;
@@ -1264,11 +1344,13 @@ check_algorithm(unsigned short algorithm) {
len = sizeof(sha1_sig) - 1;
break;
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA256PRIVATEOID:
type = isc__crypto_sha256; /* SHA256 + RSA */
sig = sha256_sig;
len = sizeof(sha256_sig) - 1;
break;
case DST_ALG_RSASHA512:
case DST_ALG_RSASHA512PRIVATEOID:
type = isc__crypto_sha512;
sig = sha512_sig;
len = sizeof(sha512_sig) - 1;

View File

@@ -125,7 +125,9 @@
/*
* PRIVATEOID subtypes we support.
*/
#define PRIVATEOIDS /* currently empty */
#define PRIVATEOIDS \
{ DST_ALG_RSASHA256PRIVATEOID, "RSASHA256OID", 0 }, \
{ DST_ALG_RSASHA512PRIVATEOID, "RSASHA512OID", 0 },
/* RFC2535 section 7.1 */

View File

@@ -260,6 +260,8 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
case DST_ALG_NSEC3RSASHA1:
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA512:
case DST_ALG_RSASHA256PRIVATEOID:
case DST_ALG_RSASHA512PRIVATEOID:
if (isc_crypto_fips_mode()) {
min = 2048;
} else {