mirror of
https://github.com/NLnetLabs/domain.git
synced 2026-08-17 21:15:41 +02:00
Key generation a signing for RSASHA512. (#659)
This commit is contained in:
+57
-16
@@ -446,7 +446,8 @@ pub mod sign {
|
||||
}
|
||||
|
||||
let pkey = match secret {
|
||||
SecretKeyBytes::RsaSha256(s) => {
|
||||
SecretKeyBytes::RsaSha256(s)
|
||||
| SecretKeyBytes::RsaSha512(s) => {
|
||||
let n = num(&s.n)?;
|
||||
let e = num(&s.e)?;
|
||||
|
||||
@@ -458,12 +459,20 @@ pub mod sign {
|
||||
.expect("should not fail");
|
||||
let rsa_public =
|
||||
PKey::from_rsa(rsa_public).expect("should not fail");
|
||||
let p = PublicKey::Rsa(
|
||||
MessageDigest::sha256(),
|
||||
rsa_public,
|
||||
public.flags(),
|
||||
)
|
||||
.dnskey();
|
||||
let digest =
|
||||
if matches!(secret, SecretKeyBytes::RsaSha256(_)) {
|
||||
MessageDigest::sha256()
|
||||
} else if matches!(
|
||||
secret,
|
||||
SecretKeyBytes::RsaSha512(_)
|
||||
) {
|
||||
MessageDigest::sha512()
|
||||
} else {
|
||||
unreachable!();
|
||||
};
|
||||
let p =
|
||||
PublicKey::Rsa(digest, rsa_public, public.flags())
|
||||
.dnskey();
|
||||
if p != *public {
|
||||
return Err(FromBytesError::InvalidKey);
|
||||
}
|
||||
@@ -585,9 +594,10 @@ pub mod sign {
|
||||
pub fn to_bytes(&self) -> SecretKeyBytes {
|
||||
// TODO: Consider security implications of secret data in 'Vec's.
|
||||
match self.algorithm {
|
||||
SecurityAlgorithm::RSASHA256 => {
|
||||
SecurityAlgorithm::RSASHA256
|
||||
| SecurityAlgorithm::RSASHA512 => {
|
||||
let key = self.pkey.rsa().unwrap();
|
||||
SecretKeyBytes::RsaSha256(RsaSecretKeyBytes {
|
||||
let secret_key_bytes = RsaSecretKeyBytes {
|
||||
n: key.n().to_vec().into(),
|
||||
e: key.e().to_vec().into(),
|
||||
d: key.d().to_vec().into(),
|
||||
@@ -596,7 +606,14 @@ pub mod sign {
|
||||
d_p: key.dmp1().unwrap().to_vec().into(),
|
||||
d_q: key.dmq1().unwrap().to_vec().into(),
|
||||
q_i: key.iqmp().unwrap().to_vec().into(),
|
||||
})
|
||||
};
|
||||
if self.algorithm == SecurityAlgorithm::RSASHA256 {
|
||||
SecretKeyBytes::RsaSha256(secret_key_bytes)
|
||||
} else if self.algorithm == SecurityAlgorithm::RSASHA512 {
|
||||
SecretKeyBytes::RsaSha512(secret_key_bytes)
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
SecurityAlgorithm::ECDSAP256SHA256 => {
|
||||
let key = self.pkey.ec_key().unwrap();
|
||||
@@ -641,6 +658,13 @@ pub mod sign {
|
||||
s.sign_oneshot_to_vec(data)
|
||||
}
|
||||
|
||||
SecurityAlgorithm::RSASHA512 => {
|
||||
let mut s =
|
||||
Signer::new(MessageDigest::sha512(), &self.pkey)?;
|
||||
s.set_rsa_padding(openssl::rsa::Padding::PKCS1)?;
|
||||
s.sign_oneshot_to_vec(data)
|
||||
}
|
||||
|
||||
SecurityAlgorithm::ECDSAP256SHA256 => {
|
||||
let mut s =
|
||||
Signer::new(MessageDigest::sha256(), &self.pkey)?;
|
||||
@@ -687,18 +711,24 @@ pub mod sign {
|
||||
|
||||
fn dnskey(&self) -> Dnskey<Vec<u8>> {
|
||||
match self.algorithm {
|
||||
SecurityAlgorithm::RSASHA256 => {
|
||||
SecurityAlgorithm::RSASHA256
|
||||
| SecurityAlgorithm::RSASHA512 => {
|
||||
let key = self.pkey.rsa().expect("should not fail");
|
||||
let n = key.n().to_owned().expect("should not fail");
|
||||
let e = key.e().to_owned().expect("should not fail");
|
||||
let key = Rsa::from_public_components(n, e)
|
||||
.expect("should not fail");
|
||||
let key = PKey::from_rsa(key).expect("should not fail");
|
||||
let public = PublicKey::Rsa(
|
||||
MessageDigest::sha256(),
|
||||
key,
|
||||
self.flags,
|
||||
);
|
||||
let digest = if self.algorithm
|
||||
== SecurityAlgorithm::RSASHA256
|
||||
{
|
||||
MessageDigest::sha256()
|
||||
} else if self.algorithm == SecurityAlgorithm::RSASHA512 {
|
||||
MessageDigest::sha512()
|
||||
} else {
|
||||
unreachable!();
|
||||
};
|
||||
let public = PublicKey::Rsa(digest, key, self.flags);
|
||||
public.dnskey()
|
||||
}
|
||||
SecurityAlgorithm::ECDSAP256SHA256
|
||||
@@ -756,6 +786,10 @@ pub mod sign {
|
||||
Ok(Signature::RsaSha256(signature))
|
||||
}
|
||||
|
||||
SecurityAlgorithm::RSASHA512 => {
|
||||
Ok(Signature::RsaSha512(signature))
|
||||
}
|
||||
|
||||
SecurityAlgorithm::ECDSAP256SHA256 => signature
|
||||
.try_into()
|
||||
.map(Signature::EcdsaP256Sha256)
|
||||
@@ -827,6 +861,7 @@ pub mod sign {
|
||||
|
||||
const KEYS: &[(SecurityAlgorithm, u16)] = &[
|
||||
(SecurityAlgorithm::RSASHA256, 60616),
|
||||
(SecurityAlgorithm::RSASHA512, 46731),
|
||||
(SecurityAlgorithm::ECDSAP256SHA256, 42253),
|
||||
(SecurityAlgorithm::ECDSAP384SHA384, 33566),
|
||||
(SecurityAlgorithm::ED25519, 56037),
|
||||
@@ -840,6 +875,9 @@ pub mod sign {
|
||||
SecurityAlgorithm::RSASHA256 => {
|
||||
GenerateParams::RsaSha256 { bits: 3072 }
|
||||
}
|
||||
SecurityAlgorithm::RSASHA512 => {
|
||||
GenerateParams::RsaSha512 { bits: 3072 }
|
||||
}
|
||||
SecurityAlgorithm::ECDSAP256SHA256 => {
|
||||
GenerateParams::EcdsaP256Sha256
|
||||
}
|
||||
@@ -862,6 +900,9 @@ pub mod sign {
|
||||
SecurityAlgorithm::RSASHA256 => {
|
||||
GenerateParams::RsaSha256 { bits: 3072 }
|
||||
}
|
||||
SecurityAlgorithm::RSASHA512 => {
|
||||
GenerateParams::RsaSha512 { bits: 3072 }
|
||||
}
|
||||
SecurityAlgorithm::ECDSAP256SHA256 => {
|
||||
GenerateParams::EcdsaP256Sha256
|
||||
}
|
||||
|
||||
+59
-7
@@ -329,6 +329,18 @@ pub mod sign {
|
||||
rng: Arc<dyn ring::rand::SecureRandom + Send + Sync>,
|
||||
},
|
||||
|
||||
/// An RSA/SHA-512 keypair.
|
||||
RsaSha512 {
|
||||
/// They RSA key.
|
||||
key: RsaKeyPair,
|
||||
|
||||
/// Flags from [`Dnskey`].
|
||||
flags: u16,
|
||||
|
||||
/// Random number generator.
|
||||
rng: Arc<dyn ring::rand::SecureRandom + Send + Sync>,
|
||||
},
|
||||
|
||||
/// An ECDSA P-256/SHA-256 keypair.
|
||||
EcdsaP256Sha256 {
|
||||
/// The ECDSA key.
|
||||
@@ -370,12 +382,20 @@ pub mod sign {
|
||||
{
|
||||
let rng = Arc::new(SystemRandom::new());
|
||||
match secret {
|
||||
SecretKeyBytes::RsaSha256(s) => {
|
||||
SecretKeyBytes::RsaSha256(s)
|
||||
| SecretKeyBytes::RsaSha512(s) => {
|
||||
let rsa_public = signature::RsaPublicKeyComponents {
|
||||
n: s.n.to_vec(),
|
||||
e: s.e.to_vec(),
|
||||
};
|
||||
let p = PublicKey::Rsa(&signature::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY, rsa_public).dnskey(public.flags());
|
||||
let p = if matches!(secret, SecretKeyBytes::RsaSha256(_))
|
||||
{
|
||||
PublicKey::Rsa(&signature::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY, rsa_public).dnskey(public.flags())
|
||||
} else if matches!(secret, SecretKeyBytes::RsaSha512(_)) {
|
||||
PublicKey::Rsa(&signature::RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY, rsa_public).dnskey(public.flags())
|
||||
} else {
|
||||
unreachable!();
|
||||
};
|
||||
// Ensure that the public and private key match.
|
||||
if p != *public {
|
||||
return Err(FromBytesError::InvalidKey);
|
||||
@@ -398,13 +418,26 @@ pub mod sign {
|
||||
dQ: s.d_q.expose_secret(),
|
||||
qInv: s.q_i.expose_secret(),
|
||||
};
|
||||
ring::signature::RsaKeyPair::from_components(&components)
|
||||
.map_err(|_| FromBytesError::InvalidKey)
|
||||
.map(|key| Self::RsaSha256 {
|
||||
let key_pair =
|
||||
ring::signature::RsaKeyPair::from_components(
|
||||
&components,
|
||||
)
|
||||
.map_err(|_| FromBytesError::InvalidKey);
|
||||
if matches!(secret, SecretKeyBytes::RsaSha256(_)) {
|
||||
key_pair.map(|key| Self::RsaSha256 {
|
||||
key,
|
||||
flags: public.flags(),
|
||||
rng,
|
||||
})
|
||||
} else if matches!(secret, SecretKeyBytes::RsaSha512(_)) {
|
||||
key_pair.map(|key| Self::RsaSha512 {
|
||||
key,
|
||||
flags: public.flags(),
|
||||
rng,
|
||||
})
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
SecretKeyBytes::EcdsaP256Sha256(s) => {
|
||||
@@ -477,6 +510,7 @@ pub mod sign {
|
||||
fn algorithm(&self) -> SecurityAlgorithm {
|
||||
match self {
|
||||
Self::RsaSha256 { .. } => SecurityAlgorithm::RSASHA256,
|
||||
Self::RsaSha512 { .. } => SecurityAlgorithm::RSASHA512,
|
||||
Self::EcdsaP256Sha256 { .. } => {
|
||||
SecurityAlgorithm::ECDSAP256SHA256
|
||||
}
|
||||
@@ -489,14 +523,21 @@ pub mod sign {
|
||||
|
||||
fn dnskey(&self) -> Dnskey<Vec<u8>> {
|
||||
match self {
|
||||
Self::RsaSha256 { key, flags, rng: _ } => {
|
||||
Self::RsaSha256 { key, flags, rng: _ }
|
||||
| Self::RsaSha512 { key, flags, rng: _ } => {
|
||||
let components: ring::rsa::PublicKeyComponents<Vec<u8>> =
|
||||
key.public().into();
|
||||
let n = components.n;
|
||||
let e = components.e;
|
||||
let public_key =
|
||||
signature::RsaPublicKeyComponents { n, e };
|
||||
let public = PublicKey::Rsa(&signature::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY, public_key);
|
||||
let public = if matches!(self, Self::RsaSha256 { .. }) {
|
||||
PublicKey::Rsa(&signature::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY, public_key)
|
||||
} else if matches!(self, Self::RsaSha512 { .. }) {
|
||||
PublicKey::Rsa(&signature::RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY, public_key)
|
||||
} else {
|
||||
unreachable!();
|
||||
};
|
||||
public.dnskey(*flags)
|
||||
}
|
||||
|
||||
@@ -563,6 +604,16 @@ pub mod sign {
|
||||
.map_err(|_| SignError)
|
||||
}
|
||||
|
||||
Self::RsaSha512 { key, flags: _, rng } => {
|
||||
let mut buf = vec![0u8; key.public().modulus_len()];
|
||||
let pad = &ring::signature::RSA_PKCS1_SHA512;
|
||||
key.sign(pad, &**rng, data, &mut buf)
|
||||
.map(|()| {
|
||||
Signature::RsaSha512(buf.into_boxed_slice())
|
||||
})
|
||||
.map_err(|_| SignError)
|
||||
}
|
||||
|
||||
Self::EcdsaP256Sha256 { key, flags: _, rng } => key
|
||||
.sign(&**rng, data)
|
||||
.map(|sig| Box::<[u8]>::from(sig.as_ref()))
|
||||
@@ -689,6 +740,7 @@ pub mod sign {
|
||||
|
||||
const KEYS: &[(SecurityAlgorithm, u16)] = &[
|
||||
(SecurityAlgorithm::RSASHA256, 60616),
|
||||
(SecurityAlgorithm::RSASHA512, 46731),
|
||||
(SecurityAlgorithm::ECDSAP256SHA256, 42253),
|
||||
(SecurityAlgorithm::ECDSAP384SHA384, 33566),
|
||||
(SecurityAlgorithm::ED25519, 56037),
|
||||
|
||||
@@ -520,6 +520,9 @@ pub enum SecretKeyBytes {
|
||||
/// An RSA/SHA-256 keypair.
|
||||
RsaSha256(RsaSecretKeyBytes),
|
||||
|
||||
/// An RSA/SHA-256 keypair.
|
||||
RsaSha512(RsaSecretKeyBytes),
|
||||
|
||||
/// An ECDSA P-256/SHA-256 keypair.
|
||||
///
|
||||
/// The private key is a single 32-byte big-endian integer.
|
||||
@@ -548,6 +551,7 @@ impl SecretKeyBytes {
|
||||
pub fn algorithm(&self) -> SecurityAlgorithm {
|
||||
match self {
|
||||
Self::RsaSha256(_) => SecurityAlgorithm::RSASHA256,
|
||||
Self::RsaSha512(_) => SecurityAlgorithm::RSASHA512,
|
||||
Self::EcdsaP256Sha256(_) => SecurityAlgorithm::ECDSAP256SHA256,
|
||||
Self::EcdsaP384Sha384(_) => SecurityAlgorithm::ECDSAP384SHA384,
|
||||
Self::Ed25519(_) => SecurityAlgorithm::ED25519,
|
||||
@@ -572,6 +576,11 @@ impl SecretKeyBytes {
|
||||
k.format_as_bind(w)
|
||||
}
|
||||
|
||||
Self::RsaSha512(k) => {
|
||||
writeln!(w, "Algorithm: 10 (RSASHA512)")?;
|
||||
k.format_as_bind(w)
|
||||
}
|
||||
|
||||
Self::EcdsaP256Sha256(s) => {
|
||||
let s = s.expose_secret();
|
||||
writeln!(w, "Algorithm: 13 (ECDSAP256SHA256)")?;
|
||||
@@ -675,6 +684,9 @@ impl SecretKeyBytes {
|
||||
(8, "(RSASHA256)") => {
|
||||
RsaSecretKeyBytes::parse_from_bind(data).map(Self::RsaSha256)
|
||||
}
|
||||
(10, "(RSASHA512)") => {
|
||||
RsaSecretKeyBytes::parse_from_bind(data).map(Self::RsaSha512)
|
||||
}
|
||||
(13, "(ECDSAP256SHA256)") => {
|
||||
parse_pkey(data).map(Self::EcdsaP256Sha256)
|
||||
}
|
||||
@@ -1094,6 +1106,7 @@ mod tests {
|
||||
};
|
||||
const KEYS: &[(SecurityAlgorithm, u16)] = &[
|
||||
(SecurityAlgorithm::RSASHA256, 60616),
|
||||
(SecurityAlgorithm::RSASHA512, 46731),
|
||||
(SecurityAlgorithm::ECDSAP256SHA256, 42253),
|
||||
(SecurityAlgorithm::ECDSAP384SHA384, 33566),
|
||||
(SecurityAlgorithm::ED25519, 56037),
|
||||
@@ -1139,6 +1152,14 @@ mod tests {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
SecurityAlgorithm::RSASHA512 => {
|
||||
if cfg!(feature = "openssl") {
|
||||
GenerateParams::RsaSha512 { bits: 2048 }
|
||||
} else {
|
||||
// No support for RSASHA256 in Ring.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
SecurityAlgorithm::ECDSAP256SHA256 => {
|
||||
GenerateParams::EcdsaP256Sha256
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
test. IN DNSKEY 256 3 10 AwEAAaOjLFFjqsv8lg/FBU8LCktei3/t3+C+s42cxmUOv4xvI/NPZ35i5zqTIoi4v0+EthzbcfnDvqVPdM1MRlVYRcWewuc18rrUZB6k1+igzcj5XuuilktNkHFfBOWinEYqzv/0KDuUSk5eMVG11DEQXx7qRPjH74WJ96sBcXzXm+GEcaYXXn/forV2khWtlGxDC6I9J6Zcwf8ACk5t6yiNBmvoljNR201clsgAgg7t+52X+echuEmkAybwVtL73tFw9JUnUeBA9Pm0pvq8hTNPXs/XhCnMw1wVRyECleOvBt2lx7s3suXXOljPdgjFZZTO2Mij8I3aYAafUEBzjcYssSU= ;{id = 46731 (zsk), size = 2048b}
|
||||
@@ -0,0 +1,10 @@
|
||||
Private-key-format: v1.2
|
||||
Algorithm: 10 (RSASHA512)
|
||||
Modulus: o6MsUWOqy/yWD8UFTwsKS16Lf+3f4L6zjZzGZQ6/jG8j809nfmLnOpMiiLi/T4S2HNtx+cO+pU90zUxGVVhFxZ7C5zXyutRkHqTX6KDNyPle66KWS02QcV8E5aKcRirO//QoO5RKTl4xUbXUMRBfHupE+MfvhYn3qwFxfNeb4YRxphdef9+itXaSFa2UbEMLoj0nplzB/wAKTm3rKI0Ga+iWM1HbTVyWyACCDu37nZf55yG4SaQDJvBW0vve0XD0lSdR4ED0+bSm+ryFM09ez9eEKczDXBVHIQKV468G3aXHuzey5dc6WM92CMVllM7YyKPwjdpgBp9QQHONxiyxJQ==
|
||||
PublicExponent: AQAB
|
||||
PrivateExponent: Bzb3CcGcsrC4xwo3QTRp6EfLW8EXqVePIBPE9YiwblcqHRynof1nV4BMOf33RWDDDMOqI0p7mdtGeZS+1x10uhFVY49P2+foYCeBc3q/h/hitH3vJXPOhgkb9Kn2POu/Q662pWXU3t6tSv561Az2PK00jEl4aIlcN5hxMgFpmIhFt8/oeT+4Z/h9N66jBM1e6z8TqM6jkqyJQ96hEtElDw+hZyxL84qJcfqPAraADJh1M9J5VzAauFhcKZ2LeUaDcb2DNiWhgMAbW7gfvx9QB58udavUSSAA3iqxo3aIMqvYqbxPnKb5KGvpNRTERgNPgNuF9Elzs2/6QNCyuYSYww==
|
||||
Prime1: 5KIn8oSsNA22EJvzhWq0Hx+jMI4bPvGOrBfmD42FKvClPtA1sAMqsabQrE2t0lYzRBnHa7ad/TpQRBTFsydy8IFTHEDeISxo3Dch8Hr+Q474TCNTEHduX3pkniTZMMdzkcC9jD9d4NGKufMz57DVejoCjEao0ZyD/WATjGd1OCM=
|
||||
Prime2: tzlkY2ryyYncIZlHtPP374MWzmUWSZHimZTDOP3Al6R87q7uWoa1G518049p//v/PZiT6rR5QFBgxS3H3B7Dhc4Ew8MED1lyO71+AvTpY/8/VsgIkJDnDKtOpY7jr/jd4avk7Ga4n+IpnNrJaLxGfcXHjJs8Xb2MiIpDbe0QIhc=
|
||||
Exponent1: jmpvxcJc3gPYcBoko+umjWiQp3Mth5TCUXKFjRSTaf8Cf9EEUEJ4urZ1b47ngojNYFNKhE75tL45N19VEta04xk7ovLJKxLVsq7pBjom3gBVrF+ooy4x42mC+XtsitUCqTzNFWp3WM5Nwqy6nUzqfTtbUPPGvuLm2NKa+q+LNc8=
|
||||
Exponent2: lf/pXK7QxwgS7HrFRrI4t5+1SxFc9qv1PFCapoyvYDYshWc3AWuo10vORpDxcb1HT5Ea/5nybiGfp618IowY+/EW24FLUJmkuJ3AjQEeFVyA6TXoNRo73ZZdU5Kwen8ef0Mvrg3GdjY8ZQqEuzbv6sXBQS5RdFjatWmkHFlozM8=
|
||||
Coefficient: S/x4RWc2cB8lR4rn14cvah+lwo+opkyoumRxfoUqWKILxvMA2hRwhMtB90dP7TxzdN3VqmXZ4m4ygWEAKgrtXC1qhzKnXPJjWAgn/ElmsuVdW7azCexNN1PZxFRNIwLElrbTlLur/C9SvBBUtlUA2Z965mqjWMgd9ooYxjn3B44=
|
||||
Reference in New Issue
Block a user