From 5e5f67179949c5b0fe8b2fdee414485d9c3b027d Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Thu, 14 Mar 2024 22:08:45 -0300 Subject: [PATCH] Use email as SAN (Subject Alternative Name) Signed-off-by: Vitor Mattos --- lib/Controller/AccountController.php | 11 +++++++++-- lib/Handler/Pkcs12Handler.php | 6 +++--- lib/Service/AccountService.php | 5 +++-- lib/Service/SignFileService.php | 5 +++-- tests/Api/Controller/SignFileControllerTest.php | 10 ++++++---- tests/integration/features/account/signature.feature | 4 ++-- 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/lib/Controller/AccountController.php b/lib/Controller/AccountController.php index 419eb34547..441763d97f 100644 --- a/lib/Controller/AccountController.php +++ b/lib/Controller/AccountController.php @@ -141,20 +141,27 @@ public function signatureGenerate( string $signPassword ): JSONResponse { try { + $identify = $this->userSession->getUser()->getEMailAddress(); + if (!$identify) { + $identify = $this->userSession->getUser()->getUID() + . '@' + . $this->request->getServerHost(); + } $data = [ 'user' => [ - 'identify' => $this->userSession->getUser()->getUID(), + 'host' => $identify, 'name' => $this->userSession->getUser()->getDisplayName(), ], 'signPassword' => $signPassword, 'userId' => $this->userSession->getUser()->getUID() ]; $this->accountService->validateCertificateData($data); - $this->pkcs12Handler->generateCertificate( + $certificate = $this->pkcs12Handler->generateCertificate( $data['user'], $data['signPassword'], $this->userSession->getUser()->getDisplayName() ); + $this->pkcs12Handler->savePfx($this->userSession->getUser()->getUID(), $certificate); return new JSONResponse([], Http::STATUS_OK); } catch (\Exception $exception) { diff --git a/lib/Handler/Pkcs12Handler.php b/lib/Handler/Pkcs12Handler.php index cf51efc16b..b4fd734a70 100644 --- a/lib/Handler/Pkcs12Handler.php +++ b/lib/Handler/Pkcs12Handler.php @@ -301,14 +301,14 @@ public function isHandlerOk(): bool { /** * Generate certificate * - * @param array $user Example: ['identify' => '', 'name' => ''] + * @param array $user Example: ['host' => '', 'name' => ''] * @param string $signPassword Password of signature * @param string $friendlyName Friendly name * @param bool $isTempFile */ public function generateCertificate(array $user, string $signPassword, string $friendlyName, bool $isTempFile = false): string { $content = $this->certificateEngineHandler->getEngine() - ->setHosts([$user['identify']]) + ->setHosts([$user['host']]) ->setCommonName($user['name']) ->setFriendlyName($friendlyName) ->setPassword($signPassword) @@ -319,6 +319,6 @@ public function generateCertificate(array $user, string $signPassword, string $f if ($isTempFile) { return $content; } - return $this->savePfx($user['identify'], $content); + return $content; } } diff --git a/lib/Service/AccountService.php b/lib/Service/AccountService.php index 9a8dd6626c..b6ccd9c6dd 100644 --- a/lib/Service/AccountService.php +++ b/lib/Service/AccountService.php @@ -227,14 +227,15 @@ public function createToSign(string $uuid, string $email, string $password, ?str } if ($signPassword) { - $this->pkcs12Handler->generateCertificate( + $certificate = $this->pkcs12Handler->generateCertificate( [ - 'identify' => $newUser->getPrimaryEMailAddress(), + 'host' => $newUser->getPrimaryEMailAddress(), 'name' => $newUser->getDisplayName() ], $signPassword, $newUser->getDisplayName() ); + $this->pkcs12Handler->savePfx($newUser->getPrimaryEMailAddress(), $certificate); } } diff --git a/lib/Service/SignFileService.php b/lib/Service/SignFileService.php index 38db477e29..cc180e79aa 100644 --- a/lib/Service/SignFileService.php +++ b/lib/Service/SignFileService.php @@ -349,15 +349,16 @@ private function getPfxFile(): string { $tempPassword = sha1((string) time()); $this->setPassword($tempPassword); try { - return $this->pkcs12Handler->generateCertificate( + $certificate = $this->pkcs12Handler->generateCertificate( [ - 'identify' => $this->userUniqueIdentifier, + 'host' => $this->userUniqueIdentifier, 'name' => $this->friendlyName, ], $tempPassword, $this->friendlyName, true ); + $this->pkcs12Handler->savePfx($this->userUniqueIdentifier, $certificate); } catch (TypeError $e) { throw new LibresignException($this->l10n->t('Failure to generate certificate')); } catch (EmptyRootCertificateException $e) { diff --git a/tests/Api/Controller/SignFileControllerTest.php b/tests/Api/Controller/SignFileControllerTest.php index d28d222e58..00a868c3fd 100644 --- a/tests/Api/Controller/SignFileControllerTest.php +++ b/tests/Api/Controller/SignFileControllerTest.php @@ -217,14 +217,15 @@ public function testSignUsingFileIdWithEmptyCertificatePassword() { 'userManager' => $user, ]); $pkcs12Handler = \OC::$server->get(\OCA\Libresign\Handler\Pkcs12Handler::class); - $pkcs12Handler->generateCertificate( + $certificate = $pkcs12Handler->generateCertificate( [ - 'identify' => 'person@test.coop', + 'host' => 'person@test.coop', 'name' => 'John Doe', ], 'secretPassword', 'username' ); + $pkcs12Handler->savePfx('person@test.coop', $certificate); $signers = $this->getSignersFromFileId($file->getId()); $this->request @@ -276,14 +277,15 @@ public function testSignUsingFileIdWithSuccess() { 'userManager' => $user, ]); $pkcs12Handler = \OC::$server->get(\OCA\Libresign\Handler\Pkcs12Handler::class); - $pkcs12Handler->generateCertificate( + $certificate = $pkcs12Handler->generateCertificate( [ - 'identify' => 'person@test.coop', + 'host' => 'person@test.coop', 'name' => 'John Doe', ], 'secretPassword', 'username' ); + $pkcs12Handler->savePfx('person@test.coop', $certificate); $mock = $this->createMock(JSignPDF::class); $mock->method('sign')->willReturn('content'); diff --git a/tests/integration/features/account/signature.feature b/tests/integration/features/account/signature.feature index 94871c13cd..837ff748c8 100644 --- a/tests/integration/features/account/signature.feature +++ b/tests/integration/features/account/signature.feature @@ -44,7 +44,7 @@ Feature: account/signature | key | value | | name | /C=BR/ST=State of Company/O=Organization/CN=signer1-displayname | | subject | {"CN": "signer1-displayname","C": "BR","ST": "State of Company","O": "Organization"} | - | (jq).extensions.subjectAltName | DNS:signer1 | + | (jq).extensions.subjectAltName | email:signer@domain.test | | issuer | {"CN": "Common Name","C": "BR","ST": "State of Company","O": "Organization"} | | (jq).extensions.keyUsage | Digital Signature, Key Encipherment, Certificate Sign | | (jq).extensions.extendedKeyUsage | TLS Web Client Authentication, E-mail Protection | @@ -64,7 +64,7 @@ Feature: account/signature | key | value | | name | /CN=Common Name/O=Organization/C=BR/ST=State of Company | | subject | {"CN": "Common Name","C": "BR","ST": "State of Company","O": "Organization"} | - | (jq).extensions.subjectAltName | DNS:signer1 | + | (jq).extensions.subjectAltName | email:signer@domain.test | | issuer | {"CN": "Common Name","C": "BR","ST": "State of Company","O": "Organization"} | | (jq).extensions.keyUsage | Digital Signature, Key Encipherment, Certificate Sign | | (jq).extensions.extendedKeyUsage | TLS Web Client Authentication, E-mail Protection |