From 19ad13571cfb0c1708b18064541646ddaa4ef6ac Mon Sep 17 00:00:00 2001 From: Richard Steinmetz Date: Tue, 24 Sep 2024 10:33:07 +0200 Subject: [PATCH] fix: gracefully parse non-standard trusted certificates Signed-off-by: Richard Steinmetz --- .reuse/dep5 | 2 +- lib/private/Security/Certificate.php | 10 ++++++++ .../openSslTrustedCertificate.crt | 25 +++++++++++++++++++ tests/lib/Security/CertificateTest.php | 7 +++++- 4 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 tests/data/certificates/openSslTrustedCertificate.crt diff --git a/.reuse/dep5 b/.reuse/dep5 index 6a528130022bf..ee8987b07ec61 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -7,7 +7,7 @@ Files: lib/l10n/*.js lib/l10n/*.json core/l10n/*.js core/l10n/*.json apps/admin_ Copyright: 2016 ownCloud, Inc., 2016-2024 Nextcloud translators License: AGPL-3.0-only OR AGPL-3.0-or-later -Files: tests/data/block-aligned-plus-one.txt tests/data/block-aligned.txt tests/data/data.tar.gz tests/data/data.zip tests/data/desktopapp.png tests/data/desktopapp.svg tests/data/certificates/badCertificate.crt tests/data/certificates/expiredCertificate.crt tests/data/certificates/goodCertificate.crt tests/data/integritycheck/app/AnotherFile.txt tests/data/integritycheck/app/subfolder/file.txt tests/data/integritycheck/appWithInvalidData/AnotherFile.txt tests/data/integritycheck/appWithInvalidData/UnecessaryFile apps/user_ldap/tests/Integration/data/avatar-invalid.gif apps/user_ldap/tests/Integration/data/avatar-valid.jpg apps/user_ldap/img/copy.png apps/user_ldap/img/copy.svg +Files: tests/data/block-aligned-plus-one.txt tests/data/block-aligned.txt tests/data/data.tar.gz tests/data/data.zip tests/data/desktopapp.png tests/data/desktopapp.svg tests/data/certificates/badCertificate.crt tests/data/certificates/expiredCertificate.crt tests/data/certificates/goodCertificate.crt tests/data/certificates/openSslTrustedCertificate.crt tests/data/integritycheck/app/AnotherFile.txt tests/data/integritycheck/app/subfolder/file.txt tests/data/integritycheck/appWithInvalidData/AnotherFile.txt tests/data/integritycheck/appWithInvalidData/UnecessaryFile apps/user_ldap/tests/Integration/data/avatar-invalid.gif apps/user_ldap/tests/Integration/data/avatar-valid.jpg apps/user_ldap/img/copy.png apps/user_ldap/img/copy.svg Copyright: 2015 ownCloud, Inc. License: AGPL-3.0-only diff --git a/lib/private/Security/Certificate.php b/lib/private/Security/Certificate.php index b9d84caeca30c..1551694c21f3e 100644 --- a/lib/private/Security/Certificate.php +++ b/lib/private/Security/Certificate.php @@ -41,6 +41,16 @@ public function __construct(string $data, string $name) { } $info = openssl_x509_parse($data); + if (!is_array($info)) { + // There is a non-standardized certificate format only used by OpenSSL. Replace all + // separators and try again. + $data = str_replace( + ['-----BEGIN TRUSTED CERTIFICATE-----', '-----END TRUSTED CERTIFICATE-----'], + ['-----BEGIN CERTIFICATE-----', '-----END CERTIFICATE-----'], + $data, + ); + $info = openssl_x509_parse($data); + } if (!is_array($info)) { throw new \Exception('Certificate could not get parsed.'); } diff --git a/tests/data/certificates/openSslTrustedCertificate.crt b/tests/data/certificates/openSslTrustedCertificate.crt new file mode 100644 index 0000000000000..21af3485995ef --- /dev/null +++ b/tests/data/certificates/openSslTrustedCertificate.crt @@ -0,0 +1,25 @@ +-----BEGIN TRUSTED CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaDAMMAoGCCsGAQUFBwMB +-----END TRUSTED CERTIFICATE----- diff --git a/tests/lib/Security/CertificateTest.php b/tests/lib/Security/CertificateTest.php index c787cc3355fcd..3b83397432183 100644 --- a/tests/lib/Security/CertificateTest.php +++ b/tests/lib/Security/CertificateTest.php @@ -40,7 +40,12 @@ public function testBogusData(): void { $certificate->getIssueDate(); } - + public function testOpenSslTrustedCertificateFormat(): void { + $trustedCertificate = file_get_contents(__DIR__ . '/../../data/certificates/openSslTrustedCertificate.crt'); + $certificate = new Certificate($trustedCertificate, 'TrustedCertificate'); + $this->assertSame('thawte, Inc.', $certificate->getOrganization()); + } + public function testCertificateStartingWithFileReference(): void { $this->expectException(\Exception::class); $this->expectExceptionMessage('Certificate could not get parsed.');