From 3a99cf9a671f074844e399f1e37df489f6149a2c Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Tue, 5 May 2026 16:29:32 +0200 Subject: [PATCH] feat(identityproof): Ed25519 app keys Add Manager::generateEd25519AppKey: persist a sodium-generated Ed25519 keypair (raw 32-byte public, 64-byte secret) under the same appdata layout the existing RSA path uses. Used by OCMSignatoryManager for the slotted RFC 9421 signing keys. Signed-off-by: Micke Nordin --- .../Security/IdentityProof/Manager.php | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/private/Security/IdentityProof/Manager.php b/lib/private/Security/IdentityProof/Manager.php index ef0faeb6ad6..d6ebe3813b2 100644 --- a/lib/private/Security/IdentityProof/Manager.php +++ b/lib/private/Security/IdentityProof/Manager.php @@ -178,6 +178,30 @@ class Manager { return $this->generateKey($this->generateAppKeyId($app, $name), $options); } + /** + * Generate an Ed25519 keypair via libsodium. Returns raw 32-byte public + * + 64-byte secret (sodium seed||publickey), no PEM. Overwrites if + * already present. + */ + public function generateEd25519AppKey(string $app, string $name): Key { + $keyPair = sodium_crypto_sign_keypair(); + $publicKey = sodium_crypto_sign_publickey($keyPair); + $privateKey = sodium_crypto_sign_secretkey($keyPair); + + $id = $this->generateAppKeyId($app, $name); + try { + $this->appData->newFolder($id); + } catch (\Exception) { + } + $folder = $this->appData->getFolder($id); + $folder->newFile('private') + ->putContent($this->crypto->encrypt($privateKey)); + $folder->newFile('public') + ->putContent($publicKey); + + return new Key($publicKey, $privateKey); + } + public function deleteAppKey(string $app, string $name): bool { try { $folder = $this->appData->getFolder($this->generateAppKeyId($app, $name));