[pbs-devel] [PATCH proxmox 02/12] auth-api: move to Ed25519 signatures
Stefan Sterz
s.sterz at proxmox.com
Thu Feb 15 16:19:51 CET 2024
previously we used P-256 as the curve of our choice for ec signatures.
however, in the meantime Ed25519 has become a lot more wide-spread.
this simplifies our ec generation code significantly while keeping the
same security level. Ed25519 was also specifically designed and
reviewed to avoid implementation errors likely making it a more secure
choice
note that Ed25519 as a signature scheme always uses sha512, so signing
or verifying with a chosen digest is not supported.
as this mostly affects newly generated keys, this should not break any
existing setups.
Signed-off-by: Stefan Sterz <s.sterz at proxmox.com>
---
proxmox-auth-api/src/auth_key.rs | 52 +++++++++++++++++++-------------
proxmox-auth-api/src/ticket.rs | 2 +-
2 files changed, 32 insertions(+), 22 deletions(-)
diff --git a/proxmox-auth-api/src/auth_key.rs b/proxmox-auth-api/src/auth_key.rs
index 32120a3..f7a83bb 100644
--- a/proxmox-auth-api/src/auth_key.rs
+++ b/proxmox-auth-api/src/auth_key.rs
@@ -1,10 +1,8 @@
//! Auth key handling.
use anyhow::{bail, format_err, Error};
-use openssl::ec::{EcGroup, EcKey};
use openssl::hash::MessageDigest;
-use openssl::nid::Nid;
-use openssl::pkey::{HasPublic, PKey, PKeyRef, Private, Public};
+use openssl::pkey::{HasPublic, Id, PKey, PKeyRef, Private, Public};
use openssl::rsa::Rsa;
use openssl::sign::{Signer, Verifier};
@@ -33,14 +31,9 @@ impl PrivateKey {
/// Generate a new EC auth key.
pub fn generate_ec() -> Result<Self, Error> {
- let nid = Nid::X9_62_PRIME256V1;
- let group = EcGroup::from_curve_name(nid)
- .map_err(|err| format_err!("failed to get P-256 group - {err}"))?;
- let ec = EcKey::generate(&group)
- .map_err(|err| format_err!("failed to generate EC key for testing - {err}"))?;
Ok(Self {
- key: PKey::from_ec_key(ec)
- .map_err(|err| format_err!("failed to get PKey for EC key - {err}"))?,
+ key: PKey::generate_ed25519()
+ .map_err(|err| format_err!("failed to generate EC PKey - {err}"))?,
})
}
@@ -59,9 +52,10 @@ impl PrivateKey {
.map_err(|err| format_err!("failed to encode rsa private key as PEM - {err}"));
}
- if let Ok(ec) = self.key.ec_key() {
- return ec
- .private_key_to_pem()
+ if self.key.id() == Id::ED25519 {
+ return self
+ .key
+ .private_key_to_pem_pkcs8()
.map_err(|err| format_err!("failed to encode ec private key as PEM - {err}"));
}
@@ -77,8 +71,9 @@ impl PrivateKey {
.map_err(|err| format_err!("failed to encode rsa public key as PEM - {err}"));
}
- if let Ok(ec) = self.key.ec_key() {
- return ec
+ if self.key.id() == Id::ED25519 {
+ return self
+ .key
.public_key_to_pem()
.map_err(|err| format_err!("failed to encode ec public key as PEM - {err}"));
}
@@ -92,8 +87,15 @@ impl PrivateKey {
}
pub(self) fn sign(&self, digest: MessageDigest, data: &[u8]) -> Result<Vec<u8>, Error> {
- Signer::new(digest, &self.key)
- .map_err(|e| format_err!("could not create private key signer - {e}"))?
+ let mut signer = if self.key.id() == Id::ED25519 {
+ // ed25519 does not support signing with digest
+ Signer::new_without_digest(&self.key)
+ } else {
+ Signer::new(digest, &self.key)
+ }
+ .map_err(|e| format_err!("could not create private key signer - {e}"))?;
+
+ signer
.sign_oneshot_to_vec(data)
.map_err(|e| format_err!("could not sign with private key - {e}"))
}
@@ -121,8 +123,9 @@ impl PublicKey {
.map_err(|err| format_err!("failed to encode rsa public key as PEM - {err}"));
}
- if let Ok(ec) = self.key.ec_key() {
- return ec
+ if self.key.id() == Id::ED25519 {
+ return self
+ .key
.public_key_to_pem()
.map_err(|err| format_err!("failed to encode ec public key as PEM - {err}"));
}
@@ -192,8 +195,15 @@ impl Keyring {
signature: &[u8],
data: &[u8],
) -> Result<bool, Error> {
- Verifier::new(digest, key)
- .map_err(|err| format_err!("failed to create openssl verifier - {err}"))?
+ let mut verifier = if key.id() == Id::ED25519 {
+ // ed25519 does not support digests
+ Verifier::new_without_digest(key)
+ } else {
+ Verifier::new(digest, key)
+ }
+ .map_err(|err| format_err!("failed to create openssl verifier - {err}"))?;
+
+ verifier
.verify_oneshot(signature, data)
.map_err(|err| format_err!("openssl error verifying data - {err}"))
}
diff --git a/proxmox-auth-api/src/ticket.rs b/proxmox-auth-api/src/ticket.rs
index 81054f8..c8fc667 100644
--- a/proxmox-auth-api/src/ticket.rs
+++ b/proxmox-auth-api/src/ticket.rs
@@ -300,7 +300,7 @@ mod test {
}
#[test]
- fn test_tickets_ecdsa() {
+ fn test_tickets_ed25519() {
let keyring = Keyring::generate_new_ec().expect("failed to generate EC key for testing");
simple_test(&keyring, Some("secret aad data"), |_| true);
--
2.39.2
More information about the pbs-devel
mailing list