From d2533fd9aacca7e004b58d4086bd4022448d6272 Mon Sep 17 00:00:00 2001 From: Patrick Bender Date: Thu, 23 May 2024 10:06:00 +0200 Subject: [PATCH] fix: Upload whole certificate chain when uploading a certificate for S/MIME in pkcs12 format. Include whole certificate chain in signed messages. Use whole certificate chain to verify certificates. Fixes #9190 Signed-off-by: Patrick Bender Signed-off-by: Richard Steinmetz --- lib/Service/SmimeService.php | 10 +- src/tests/data/user@imap.localhost.chain.crt | 61 ++++++++++++ src/tests/unit/util/pkcs12.spec.js | 2 +- src/util/pkcs12.js | 2 +- tests/Unit/Service/SmimeServiceTest.php | 34 +++++++ .../chain-leaf-only@imap.localhost.crt | 32 +++++++ .../chain-partial@imap.localhost.crt | 62 +++++++++++++ .../data/smime-certs/chain@imap.localhost.crt | 92 +++++++++++++++++++ 8 files changed, 291 insertions(+), 4 deletions(-) create mode 100644 src/tests/data/user@imap.localhost.chain.crt create mode 100644 tests/data/smime-certs/chain-leaf-only@imap.localhost.crt create mode 100644 tests/data/smime-certs/chain-partial@imap.localhost.crt create mode 100644 tests/data/smime-certs/chain@imap.localhost.crt diff --git a/lib/Service/SmimeService.php b/lib/Service/SmimeService.php index c9e0be73fc..5276e2682d 100644 --- a/lib/Service/SmimeService.php +++ b/lib/Service/SmimeService.php @@ -182,13 +182,16 @@ public function parseCertificate(string $certificate): SmimeCertificateInfo { } } + $decryptedCertificateFile = $this->tempManager->getTemporaryFile(); + file_put_contents($decryptedCertificateFile, $certificate); + $caBundle = [$this->certificateManager->getAbsoluteBundlePath()]; return new SmimeCertificateInfo( $certificateData['subject']['CN'] ?? null, $certificateData['subject']['emailAddress'] ?? $certificateData['subject']['CN'], $certificateData['validTo_time_t'], $purposes, - openssl_x509_checkpurpose($certificate, X509_PURPOSE_ANY, $caBundle) === true, + openssl_x509_checkpurpose($certificate, X509_PURPOSE_ANY, $caBundle, $decryptedCertificateFile) === true, ); } @@ -376,13 +379,16 @@ public function signMimePart(Horde_Mime_Part $part, ); } + $decryptedCertificateFile = $this->tempManager->getTemporaryFile(); + file_put_contents($decryptedCertificateFile, $decryptedCertificate); + $inPath = $this->tempManager->getTemporaryFile(); $outPath = $this->tempManager->getTemporaryFile(); file_put_contents($inPath, $part->toString([ 'canonical' => true, 'headers' => true, ])); - if (!openssl_pkcs7_sign($inPath, $outPath, $decryptedCertificate, $decryptedKey, null)) { + if (!openssl_pkcs7_sign($inPath, $outPath, $decryptedCertificate, $decryptedKey, null, PKCS7_DETACHED, $decryptedCertificateFile)) { throw new SmimeSignException('Failed to sign MIME part'); } diff --git a/src/tests/data/user@imap.localhost.chain.crt b/src/tests/data/user@imap.localhost.chain.crt new file mode 100644 index 0000000000..438b49552f --- /dev/null +++ b/src/tests/data/user@imap.localhost.chain.crt @@ -0,0 +1,61 @@ +-----BEGIN CERTIFICATE----- +MIIFUjCCAzqgAwIBAgIQPNReuUyM+DUIY0jIs9wXfjANBgkqhkiG9w0BAQsFADAU +MRIwEAYDVQQDDAlTL01JTUUgQ0EwHhcNMjMwMTI2MTAxMjIzWhcNMjQwMTI2MTAx +MjIzWjAzMQ0wCwYDVQQDDAR1c2VyMSIwIAYJKoZIhvcNAQkBFhN1c2VyQGltYXAu +bG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwVjeJ4l+ +pCov/MV4a8O6mMSpYx9pbbVnjmd5pYsArCXUL2n7Qhr3Qj1RVwZ6MddUcU8kM5FE +Vp5ycSVkaM7PNo8OW5OC+/zSgVDrUv5VAo8bqiYZ/MKCouNszPdX8u4rMMu/Y4aE +fPhTr1R0IhN9h7Y+OLm+c/JUo+m8fVq0RyE2NvlPhTbgo7tNoYE4e3oYlBsygwJD +EklZy2xoYxIB7mD4l4qz2Vl3itPaNoXIrwYDjd2qzvtWFovWQB0Bmf0hIlySC35F +tr0NhQ4DgKIOY5ccCx8j2KYXm/o9stsqApWCaaeiW+Q/rjkgw4hqANFHW2ypzPRh +5aXEU5iDMCuEpgn0W2Bp/JE+7qhsnHT5vkfperr05lvNsmHEzlRJDfYpk2+9yDD7 +Q28fLK65lyuru+KMzXHsS78qTFd7JvLp+vWaOxb2zG1ogLhqlRdLObfWIrIoqJPp +3uBZRBdEUT3MrZYC4MCHzPxSFD+xd9Eu/xpyhcSVrfjhn4Aot7/kpyzUrenSD14i +g0Jq6fXSE2g4wp3rTM7fhxCEDYjDSiSgt7O2QAFC4zymTX9CPf54QCK9qEFdiTdp +MyWz88Lg07m6Ey+op57OUL8KyJYwrc7ORFROOP3QXUU+TFjqmDUsbEdESPQ0Z2FO +OuKiwldAchZAXau5QsZOLfAJSLpMsUayOX8CAwEAAaOBgDB+MB0GA1UdDgQWBBS/ +P8Av04tJ+6Z0kqwioumY50NcyDAfBgNVHSMEGDAWgBST8/DtdlOT1x9VFvUptIoH +HYduFTAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDAeBgNVHREEFzAVgRN1 +c2VyQGltYXAubG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4ICAQDBvfQbG9XF0ion +5gV58tw9hSqqlgmi3wmCJRjgH4F/Dh8zabEGKMhnUNGwt8szwkmKgfo70hF0hiDF +ntT/lrIpZaaj+xaHLty4uexXlGVyDGeRiOn9hrwjfrrV/MpqP76U9iswWaH9uUdz +HuoNeqwaBiUj8C5OBsbLyo8MKHNvwPf/xrt9kjdYOmpKICeD2cC4RCjJ6J6QDV1k +pimigtziVHqepNRQZBxEtSgbtsfpfvKOIPw37fwK66BNL/Y3iXWnLpx+VP3LWR2N +igqCPXpXFG7vPH2y4Vj6TtdIjUpiG+WRW6TVxGSEjj81X5tyxlKBezuNhUty30Wr +8Ugpzt+8wjL7W1u+ZU0t3ZXZUo9ezmGeSLVFInJ9X3zdVOgB0wDffu5yWyUJh4FT +GVw1YGBo2wZS9wD6Hd4aLuy/Xkk5LdBohM57f3ncPgf+zz8g+29M0xEe7+SllWLH +0Enh+Ymyfs01bYIeYkjQCmVGWbKsOBqqvLXItFEFOG9H4UKkJOvjkqEpANQa7Epp +I99G7c6rHFjAC+oDuznsxB7RSGKywQpGG+TnDbn5H98BOzr2HOQwBL8jZR/XG1xk +o300Ya8us3kJquq9/FMAzReZfQL10ZxycHyhDJNJhs4X60M9AqG4guhUA8ZEI1Ik +aYAHcRXlsEqTNzseEXHIYWHosJLHRQ== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFCTCCAvGgAwIBAgIUIPN87gXhW2+tZ34jbBb/GY/C9yMwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJUy9NSU1FIENBMB4XDTIzMDEyNjA5NDMwNVoXDTMzMDEy +MzA5NDMwNVowFDESMBAGA1UEAwwJUy9NSU1FIENBMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEAyQpMnWNRa+VuJktOWdJhE8BZCrAF0oNpdKZrQ87gF0Rr +OWaOK6kOtYhTLRyiTXwJ1IM/F1OyEKqv0c5DE4WfZ62/6s74mrZb/CDqlX3RNVjb +5FXzu/v8E24WMrJi3NVGoJALsUVi5XWs7Y8uQu4+jozCZ/nbi/k4iLxg4gMXC8+s +PheUB+2pmTuLLHSOVXWNFzqwjPXHHGp7QeDEqbHkkB2XgFseVyyq+iUyAP1yhrao +tLhMc/eQT3OHNnACelDWSCTtWz0ocd9wK4qIY1AUG67LPQIa2aKZSZCe6c2VlFps +9q3AUviQT7UKw8Z1zpZWvTyIr5UdpYvcFEdAvEU+hbFzFJm8l0oK/lnekcqGEtoL +f0mxhMWJjR8ZioM5c1/nL+/2AQOgARvTPHjbDUQy5q1pTGHmOunU3iWuC2zJBCHR +u5GsrnqA9LGY7M18M5lRibq9IHFdUrjvvLJ7FYRaq8oM6zyZPOQUch8Azfsuh33s +vXir/ciwaDPK4GSl14PNIZM+puOZZpu9LhT5cCnWmpnP1P7zZ7AczD9v78WLl8vj +Ej7TUmwOTypx59+B/0KgGB3YWRr24GaHpg1OfgvYAsL0AhQRt4j6p8jwOcbCqze6 +5xDgNWg28yVggzrxmBFRE1nSTx3M/wL9i/dxmDBcLLGtQi9QTGSe1J1JoBcwcW8C +AwEAAaNTMFEwHQYDVR0OBBYEFJPz8O12U5PXH1UW9Sm0igcdh24VMB8GA1UdIwQY +MBaAFJPz8O12U5PXH1UW9Sm0igcdh24VMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggIBABmvRuFdofxMIsw/jOCiVKvZIvmaS2xd8vVOkGBbaDv6NgO2 +kJG80nfk2OPx3kFImFN2AhfMGYnFnWYaV3gpC4Hh36mG4T+C9CVGq9AJ0K1xxDrp +KpQ/XDiF3UKJ0Tj4XMN4RxuYKFWNbo1+FNwnByPr7B6J+1FVDjBx7X20qpIg/WQQ +AMpv+wY0K3E4o1GL9qkiChQiNL2o4jjffWrUlHqjcJ8G6upuO8EIIdmv9CPzrS0x +cvYVYE6kf9LcAxqUhmmIwX36RSru7Ayqb3GEaChhfaALJ7tDDjaZZnyXrVOrJrHZ +P5W4dvHyr6L3xssI+iJdvJI/mDD4FOEVD/9sxDAnqE8pQEMnWJNQVbqeMCK5C+b0 +QnQcJjsJjyE0plX9Bu76soUIL/z/ut9RpomEQ6wvMXqRXy3bPDgGxTnYbK2Zi1yq +lulOO4xqzfn9JX3qN+QDQUc4wpwtqGmkURUMTCd4am2lx1jAs/z4jA03l/8weBPh +2Yw10RtpucQLhpQHeEFz0iYGr0jMMZKieceFjzl4e/5VoChWYLOaf1GIAM+wMpAG +Zw6tNlgXBmKe38UKs3dD6NBU8rGdJni+ysyMKS7jLFEBauP2OEdGgUnnuY8WnHgi +4LC3+GEsTFdDgpSOJ6sUj7f6kQkXjOAHhngReX8Zv+l9pnENtdZiKJCz4Vl4 +-----END CERTIFICATE----- diff --git a/src/tests/unit/util/pkcs12.spec.js b/src/tests/unit/util/pkcs12.spec.js index 9c74d8553b..307bbff3c5 100644 --- a/src/tests/unit/util/pkcs12.spec.js +++ b/src/tests/unit/util/pkcs12.spec.js @@ -36,7 +36,7 @@ describe('pkcs12', () => { }) it('correctly handles PKCS#12 files with multiple cert bags', () => { - const certPem = readTestData('user@imap.localhost.crt').replaceAll('\n', '\r\n') + const certPem = readTestData('user@imap.localhost.chain.crt').replaceAll('\n', '\r\n') const keyPem = readTestData('user@imap.localhost.key').replaceAll('\n', '\r\n') const pkcs12Der = toArrayBuffer(readTestDataRaw('user@imap.localhost.chain.p12')) diff --git a/src/util/pkcs12.js b/src/util/pkcs12.js index 29a999329d..284b8b6181 100644 --- a/src/util/pkcs12.js +++ b/src/util/pkcs12.js @@ -51,7 +51,7 @@ export function convertPkcs12ToPem(pkcs12Der, password) { } return { - certificate: forge.pki.certificateToPem(certBags[0].cert), + certificate: certBags.map((certBag) => forge.pki.certificateToPem(certBag.cert)).join('\r\n'), privateKey: forge.pki.privateKeyToPem(keyBags[0].key), } } diff --git a/tests/Unit/Service/SmimeServiceTest.php b/tests/Unit/Service/SmimeServiceTest.php index 72c18c80d5..b06a4ea475 100644 --- a/tests/Unit/Service/SmimeServiceTest.php +++ b/tests/Unit/Service/SmimeServiceTest.php @@ -423,6 +423,36 @@ public function provideParseCertificateData(): array { false, ), ], + [ // Full chain: Leaf -> Intermediate CA -> CA + $this->getTestCertificate('chain@imap.localhost'), + new SmimeCertificateInfo( + 'chain', + 'chain@imap.localhost', + 4870519697, + new SmimeCertificatePurposes(true, true), + true, + ), + ], + [ // Partial chain: Leaf -> Intermediate CA + $this->getTestCertificate('chain-partial@imap.localhost'), + new SmimeCertificateInfo( + 'chain', + 'chain@imap.localhost', + 4870519697, + new SmimeCertificatePurposes(true, true), + true, + ), + ], + [ // Leaf only + $this->getTestCertificate('chain-leaf-only@imap.localhost'), + new SmimeCertificateInfo( + 'chain', + 'chain@imap.localhost', + 4870519697, + new SmimeCertificatePurposes(true, true), + false, + ), + ], ]; } @@ -435,6 +465,10 @@ public function testParseCertificate(SmimeCertificate $certificate, ->method('getAbsoluteBundlePath') ->willReturn(__DIR__ . '/../../data/smime-certs/imap.localhost.ca.crt'); + $this->tempManager->expects(self::once()) + ->method('getTemporaryFile') + ->willReturnCallback(fn () => $this->createTempFile()); + $this->assertEquals( $expected, $this->smimeService->parseCertificate($certificate->getCertificate()), diff --git a/tests/data/smime-certs/chain-leaf-only@imap.localhost.crt b/tests/data/smime-certs/chain-leaf-only@imap.localhost.crt new file mode 100644 index 0000000000..417fb98c95 --- /dev/null +++ b/tests/data/smime-certs/chain-leaf-only@imap.localhost.crt @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIRAJp/VZ0n301xLR86gjdy8BswDQYJKoZIhvcNAQELBQAw +MDEuMCwGA1UEAwwlaW1hcC5sb2NhbGhvc3QgUy9NSU1FIEludGVybWVkaWF0ZSBD +QTAgFw0yNDA1MjgxODA4MTdaGA8yMTI0MDUwNDE4MDgxN1owNTEOMAwGA1UEAwwF +Y2hhaW4xIzAhBgkqhkiG9w0BCQEWFGNoYWluQGltYXAubG9jYWxob3N0MIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApjW7+drIdItQX4Gjhta1+F4DFAYZ +TD6N+IHz/l30Dby8lUsKCVrss679W3C1mVz6LiXf4XlziIkZjluL10P85pYocU9V +EkPKkKNZlVRDYAdlWdxtoj5oL2BSTmM6vX8SVR1JL8WSwDfWy5t9T0aKR0aX37wF +BABLKB0uGG4JoiTRmG/2Mk/ILahJdzp3RFCeF5PVR5Vui04O17xRZ/lmWzrRPfqH ++F+OUQ9IqSzDGY9RZB9aaiAK48WcHYWJdFTjlm6ls2Mf16AdlbhPnqUSssDeWjjI +R82VGCkY2CSgcVk9IKWEsjhHFD0a753CiojkPGg9U54iA1FePt5fF3YlF1Hj2BU1 +xR2HxBYbOtNRYqH1+BtEHnekTAks5HvjSu2ugNPdcqY/0thh07UzfpMIsfSxr1Ah +KJQIr0fjtZJ0JAVeggHLDLD/gCE5ExN6rAX8mKi0HPrPqUzsYj8yMNNTBJC5D+v0 +nV5Zr+IArlh5aj8RGwatsFrXK48M+mxP2r9mNETpZ7siRhEmS3YLksQUbGkf2ONd +Wkqr7hdUqBFTaS+cLyqwadKkqoqTey9/UIDTg6dvpaZ35BjhhF2Z5raj3zlp4BZO +4oE1NG5UQcc0KIDqnY7pRmaZXEJSLfJc6x3TxexPtySJ2+P99BcHLCK2fVxDBIlT +dzmEa8ekosoTDccCAwEAAaOBgTB/MB0GA1UdDgQWBBRDpKyFDLYN6kl2ENsoghZO +HltYSjAfBgNVHSMEGDAWgBSghcPmLBtZC7bEWKBPG1ZV0Stc9zAMBgNVHRMBAf8E +AjAAMA4GA1UdDwEB/wQEAwIFoDAfBgNVHREEGDAWgRRjaGFpbkBpbWFwLmxvY2Fs +aG9zdDANBgkqhkiG9w0BAQsFAAOCAgEANKLkqq4IYKq3CjWgq4tuhYZ1KUTYdA2T +QDln4crzwrezY2dtyU87nbFEXi21c8q0d9NpK6cLK8D3+aRtVtdj7F1NokNw8jbG +hDqD9raSBnOHa8L102vb9JCYvECf5PVe37NGZrPjmtBt2wvma79DymcWBC+dU2ZU +stVpX6VJ2Ju872NRe053UQ7iGSbZBq2bTOwn+5RRb7QrIYkKETkaXjA7O+cvqVHZ +KPNX9fVu/vAlXsaU0+4Q7I+8NkFNSlPAfcgmzTQ/3ieKTSAWYKLJDrfZf0k5wX+p +HSDPpZkd3f3k751k/SGahyBcAFPm3FSUHMQSiDAYcN33i3Z9O8j9sGtUCJ52/WGi +T0Nw7EKMwm0lEx/Pa4VxoWXGtju6idQ+v3LkJbv8LeYHs7MlXRuHCDopNhiO7wFG +6VfM426J81dGEylMJamJdTlrCfDiQkT864Nt24HkQVgM/MpK4D/YiSOtKUeVJeLh +UxmPB2aP1k1pKJl9GyBdh48L1t12MoNadliH053v4GQ3QorIIRAuPZVP1I+EzIgi +3q/GbuFseJ6PtvZWctX0ZpIGgDEEVusF4wcn5+NkZCgsSAw7JaJU7bIkUi6948IP +e/8qNo5AU/S8X71wgblcgaN36DjVQraYjR6zQTfhWRUIJnA9E65yGPT1I5mNoUT2 +LKrGUdB8XKI= +-----END CERTIFICATE----- diff --git a/tests/data/smime-certs/chain-partial@imap.localhost.crt b/tests/data/smime-certs/chain-partial@imap.localhost.crt new file mode 100644 index 0000000000..73111e192d --- /dev/null +++ b/tests/data/smime-certs/chain-partial@imap.localhost.crt @@ -0,0 +1,62 @@ +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIRAJp/VZ0n301xLR86gjdy8BswDQYJKoZIhvcNAQELBQAw +MDEuMCwGA1UEAwwlaW1hcC5sb2NhbGhvc3QgUy9NSU1FIEludGVybWVkaWF0ZSBD +QTAgFw0yNDA1MjgxODA4MTdaGA8yMTI0MDUwNDE4MDgxN1owNTEOMAwGA1UEAwwF +Y2hhaW4xIzAhBgkqhkiG9w0BCQEWFGNoYWluQGltYXAubG9jYWxob3N0MIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApjW7+drIdItQX4Gjhta1+F4DFAYZ +TD6N+IHz/l30Dby8lUsKCVrss679W3C1mVz6LiXf4XlziIkZjluL10P85pYocU9V +EkPKkKNZlVRDYAdlWdxtoj5oL2BSTmM6vX8SVR1JL8WSwDfWy5t9T0aKR0aX37wF +BABLKB0uGG4JoiTRmG/2Mk/ILahJdzp3RFCeF5PVR5Vui04O17xRZ/lmWzrRPfqH ++F+OUQ9IqSzDGY9RZB9aaiAK48WcHYWJdFTjlm6ls2Mf16AdlbhPnqUSssDeWjjI +R82VGCkY2CSgcVk9IKWEsjhHFD0a753CiojkPGg9U54iA1FePt5fF3YlF1Hj2BU1 +xR2HxBYbOtNRYqH1+BtEHnekTAks5HvjSu2ugNPdcqY/0thh07UzfpMIsfSxr1Ah +KJQIr0fjtZJ0JAVeggHLDLD/gCE5ExN6rAX8mKi0HPrPqUzsYj8yMNNTBJC5D+v0 +nV5Zr+IArlh5aj8RGwatsFrXK48M+mxP2r9mNETpZ7siRhEmS3YLksQUbGkf2ONd +Wkqr7hdUqBFTaS+cLyqwadKkqoqTey9/UIDTg6dvpaZ35BjhhF2Z5raj3zlp4BZO +4oE1NG5UQcc0KIDqnY7pRmaZXEJSLfJc6x3TxexPtySJ2+P99BcHLCK2fVxDBIlT +dzmEa8ekosoTDccCAwEAAaOBgTB/MB0GA1UdDgQWBBRDpKyFDLYN6kl2ENsoghZO +HltYSjAfBgNVHSMEGDAWgBSghcPmLBtZC7bEWKBPG1ZV0Stc9zAMBgNVHRMBAf8E +AjAAMA4GA1UdDwEB/wQEAwIFoDAfBgNVHREEGDAWgRRjaGFpbkBpbWFwLmxvY2Fs +aG9zdDANBgkqhkiG9w0BAQsFAAOCAgEANKLkqq4IYKq3CjWgq4tuhYZ1KUTYdA2T +QDln4crzwrezY2dtyU87nbFEXi21c8q0d9NpK6cLK8D3+aRtVtdj7F1NokNw8jbG +hDqD9raSBnOHa8L102vb9JCYvECf5PVe37NGZrPjmtBt2wvma79DymcWBC+dU2ZU +stVpX6VJ2Ju872NRe053UQ7iGSbZBq2bTOwn+5RRb7QrIYkKETkaXjA7O+cvqVHZ +KPNX9fVu/vAlXsaU0+4Q7I+8NkFNSlPAfcgmzTQ/3ieKTSAWYKLJDrfZf0k5wX+p +HSDPpZkd3f3k751k/SGahyBcAFPm3FSUHMQSiDAYcN33i3Z9O8j9sGtUCJ52/WGi +T0Nw7EKMwm0lEx/Pa4VxoWXGtju6idQ+v3LkJbv8LeYHs7MlXRuHCDopNhiO7wFG +6VfM426J81dGEylMJamJdTlrCfDiQkT864Nt24HkQVgM/MpK4D/YiSOtKUeVJeLh +UxmPB2aP1k1pKJl9GyBdh48L1t12MoNadliH053v4GQ3QorIIRAuPZVP1I+EzIgi +3q/GbuFseJ6PtvZWctX0ZpIGgDEEVusF4wcn5+NkZCgsSAw7JaJU7bIkUi6948IP +e/8qNo5AU/S8X71wgblcgaN36DjVQraYjR6zQTfhWRUIJnA9E65yGPT1I5mNoUT2 +LKrGUdB8XKI= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFMjCCAxqgAwIBAgIQRknyt1KzW/+fU1oN1f82RjANBgkqhkiG9w0BAQsFADAj +MSEwHwYDVQQDDBhpbWFwLmxvY2FsaG9zdCBTL01JTUUgQ0EwIBcNMjQwNTI4MTgw +NDI0WhgPMjEyNDA1MDQxODA0MjRaMDAxLjAsBgNVBAMMJWltYXAubG9jYWxob3N0 +IFMvTUlNRSBJbnRlcm1lZGlhdGUgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDHVjW2Mu9DrEs6kAUJFk5BobDNlY4RdEnZwpn0QrdYGoCDH+B9N5/+ +4kw28PyW/4lt/eatbRfFEi22QmIWLyG2lVSguMelm9EuVwpBtYe4T7oBRL4c9aMZ +5ELuTPkyeNhvXvyruLIBwJfhIMmyCGJDlBhZD3xzXkPiKwUdQLICWFuBJ4Cp52ho +MWKWb97LjF+1aqar4jAcskmRdkgVC/Itiy0d9mL8PoI7S5OklgfOxAJF1YC1DUeX +rRvm5taq/w+sSC4vCtE/1cZuR5nZLu65ygI0juo62/NVQRIIdhJwUSclP3QDneZy +cSijGIg4/dujoacERIOwZRnierd14K8Wefn3KhO65EzcUdn+kIPCD6mfh/xqy4l1 +sq58EakIaiRCyfcyoFZiCjWx3ITO5DSnKKtMDyUeXfrPVffpFMPtoJjUI2hlNi2z +ZmKCRYGirgIwatGyEbrNAhT6RKZ81gD+T/uUwWMQuBScDMSWAF7iSW7xlmBICvAF +SbwOwwhMgOhhIKxLvcBpp5ufvJihtSywNERcjZAfxGgrxHjPlR0WqhIdTuXEbSXj +8nMmh5huMQCsKveLf+LCdzqOuAQgZ2wJOL2ofODxmPqz6rCLuxIFHmbyZeipSTeL +4NayOtGWDSeEQ0ijbnHeuLR2lJMt2qRFz1W+CCcvZBcDvuiv6DS0UwIDAQABo1Mw +UTAdBgNVHQ4EFgQUoIXD5iwbWQu2xFigTxtWVdErXPcwHwYDVR0jBBgwFoAUeG41 +dt1U80fe9wiUdao9aC1nisIwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsF +AAOCAgEANUxoceJB4vw9X267zOQLr8a0wGeM76l+s6CqCS9YMXjIpTklT18+aEEr +ltYQgZ/tH9VGp/6e02ZdDDMh8rwt9H1pmgpkyQrS9M8OVDns/6mAQ7pSNNZq+qrG +IewyosxGbHo5tI4fCTuOeiF6AxPWfmkUsSjLVIzTweZva3kY5IQtZlxKDOENAzCr +YWaRlrPAM0cRVSUu5XMqCidYKDsj+XuywqwK7eR9NFKmvPkt3WCAyh2w0uo5P7I2 +572mSuYbYsn+rodnp56Is04YLzW5ciH4PytTYxcbt92E+yx8UPO0RAxnWGhw0ntd +rBVWQw1StOVRISMG7soXXfcvmlzggZJMY5NKrT51FefIoDsa3RWBsGqZdZQGKbu+ +e/PY2/aM1xCgq5xHq0ElX6kUn4qZ/KYrqTLgfq76N0Ne1FfVONdpjGeJWPyzVlxL +MYQCNoH2Qcxe+uOzPjt/4Y0WoCn01mDbB+6estnobnN0O1ibr4IPiMVRFRDyE07k +CZs1HP9KKgkCV7Im5UStaajYDc6pbIID6u1GBjd3/Cvnj96e0yOaui+LiP4/VUaB +Yz2Nt5OAfAusrXjTlN+TrSj7q8WkJiWBc4RkgccZVG7MIY8EEmUwy3A6vpQ8wzHx +dqV/1GenR3yM4YK1ZQkClCHjlAVSPLpd62WlRAWYJzMAz/7SHPA= +-----END CERTIFICATE----- diff --git a/tests/data/smime-certs/chain@imap.localhost.crt b/tests/data/smime-certs/chain@imap.localhost.crt new file mode 100644 index 0000000000..ad7cfcee4c --- /dev/null +++ b/tests/data/smime-certs/chain@imap.localhost.crt @@ -0,0 +1,92 @@ +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIRAJp/VZ0n301xLR86gjdy8BswDQYJKoZIhvcNAQELBQAw +MDEuMCwGA1UEAwwlaW1hcC5sb2NhbGhvc3QgUy9NSU1FIEludGVybWVkaWF0ZSBD +QTAgFw0yNDA1MjgxODA4MTdaGA8yMTI0MDUwNDE4MDgxN1owNTEOMAwGA1UEAwwF +Y2hhaW4xIzAhBgkqhkiG9w0BCQEWFGNoYWluQGltYXAubG9jYWxob3N0MIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApjW7+drIdItQX4Gjhta1+F4DFAYZ +TD6N+IHz/l30Dby8lUsKCVrss679W3C1mVz6LiXf4XlziIkZjluL10P85pYocU9V +EkPKkKNZlVRDYAdlWdxtoj5oL2BSTmM6vX8SVR1JL8WSwDfWy5t9T0aKR0aX37wF +BABLKB0uGG4JoiTRmG/2Mk/ILahJdzp3RFCeF5PVR5Vui04O17xRZ/lmWzrRPfqH ++F+OUQ9IqSzDGY9RZB9aaiAK48WcHYWJdFTjlm6ls2Mf16AdlbhPnqUSssDeWjjI +R82VGCkY2CSgcVk9IKWEsjhHFD0a753CiojkPGg9U54iA1FePt5fF3YlF1Hj2BU1 +xR2HxBYbOtNRYqH1+BtEHnekTAks5HvjSu2ugNPdcqY/0thh07UzfpMIsfSxr1Ah +KJQIr0fjtZJ0JAVeggHLDLD/gCE5ExN6rAX8mKi0HPrPqUzsYj8yMNNTBJC5D+v0 +nV5Zr+IArlh5aj8RGwatsFrXK48M+mxP2r9mNETpZ7siRhEmS3YLksQUbGkf2ONd +Wkqr7hdUqBFTaS+cLyqwadKkqoqTey9/UIDTg6dvpaZ35BjhhF2Z5raj3zlp4BZO +4oE1NG5UQcc0KIDqnY7pRmaZXEJSLfJc6x3TxexPtySJ2+P99BcHLCK2fVxDBIlT +dzmEa8ekosoTDccCAwEAAaOBgTB/MB0GA1UdDgQWBBRDpKyFDLYN6kl2ENsoghZO +HltYSjAfBgNVHSMEGDAWgBSghcPmLBtZC7bEWKBPG1ZV0Stc9zAMBgNVHRMBAf8E +AjAAMA4GA1UdDwEB/wQEAwIFoDAfBgNVHREEGDAWgRRjaGFpbkBpbWFwLmxvY2Fs +aG9zdDANBgkqhkiG9w0BAQsFAAOCAgEANKLkqq4IYKq3CjWgq4tuhYZ1KUTYdA2T +QDln4crzwrezY2dtyU87nbFEXi21c8q0d9NpK6cLK8D3+aRtVtdj7F1NokNw8jbG +hDqD9raSBnOHa8L102vb9JCYvECf5PVe37NGZrPjmtBt2wvma79DymcWBC+dU2ZU +stVpX6VJ2Ju872NRe053UQ7iGSbZBq2bTOwn+5RRb7QrIYkKETkaXjA7O+cvqVHZ +KPNX9fVu/vAlXsaU0+4Q7I+8NkFNSlPAfcgmzTQ/3ieKTSAWYKLJDrfZf0k5wX+p +HSDPpZkd3f3k751k/SGahyBcAFPm3FSUHMQSiDAYcN33i3Z9O8j9sGtUCJ52/WGi +T0Nw7EKMwm0lEx/Pa4VxoWXGtju6idQ+v3LkJbv8LeYHs7MlXRuHCDopNhiO7wFG +6VfM426J81dGEylMJamJdTlrCfDiQkT864Nt24HkQVgM/MpK4D/YiSOtKUeVJeLh +UxmPB2aP1k1pKJl9GyBdh48L1t12MoNadliH053v4GQ3QorIIRAuPZVP1I+EzIgi +3q/GbuFseJ6PtvZWctX0ZpIGgDEEVusF4wcn5+NkZCgsSAw7JaJU7bIkUi6948IP +e/8qNo5AU/S8X71wgblcgaN36DjVQraYjR6zQTfhWRUIJnA9E65yGPT1I5mNoUT2 +LKrGUdB8XKI= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFMjCCAxqgAwIBAgIQRknyt1KzW/+fU1oN1f82RjANBgkqhkiG9w0BAQsFADAj +MSEwHwYDVQQDDBhpbWFwLmxvY2FsaG9zdCBTL01JTUUgQ0EwIBcNMjQwNTI4MTgw +NDI0WhgPMjEyNDA1MDQxODA0MjRaMDAxLjAsBgNVBAMMJWltYXAubG9jYWxob3N0 +IFMvTUlNRSBJbnRlcm1lZGlhdGUgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDHVjW2Mu9DrEs6kAUJFk5BobDNlY4RdEnZwpn0QrdYGoCDH+B9N5/+ +4kw28PyW/4lt/eatbRfFEi22QmIWLyG2lVSguMelm9EuVwpBtYe4T7oBRL4c9aMZ +5ELuTPkyeNhvXvyruLIBwJfhIMmyCGJDlBhZD3xzXkPiKwUdQLICWFuBJ4Cp52ho +MWKWb97LjF+1aqar4jAcskmRdkgVC/Itiy0d9mL8PoI7S5OklgfOxAJF1YC1DUeX +rRvm5taq/w+sSC4vCtE/1cZuR5nZLu65ygI0juo62/NVQRIIdhJwUSclP3QDneZy +cSijGIg4/dujoacERIOwZRnierd14K8Wefn3KhO65EzcUdn+kIPCD6mfh/xqy4l1 +sq58EakIaiRCyfcyoFZiCjWx3ITO5DSnKKtMDyUeXfrPVffpFMPtoJjUI2hlNi2z +ZmKCRYGirgIwatGyEbrNAhT6RKZ81gD+T/uUwWMQuBScDMSWAF7iSW7xlmBICvAF +SbwOwwhMgOhhIKxLvcBpp5ufvJihtSywNERcjZAfxGgrxHjPlR0WqhIdTuXEbSXj +8nMmh5huMQCsKveLf+LCdzqOuAQgZ2wJOL2ofODxmPqz6rCLuxIFHmbyZeipSTeL +4NayOtGWDSeEQ0ijbnHeuLR2lJMt2qRFz1W+CCcvZBcDvuiv6DS0UwIDAQABo1Mw +UTAdBgNVHQ4EFgQUoIXD5iwbWQu2xFigTxtWVdErXPcwHwYDVR0jBBgwFoAUeG41 +dt1U80fe9wiUdao9aC1nisIwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsF +AAOCAgEANUxoceJB4vw9X267zOQLr8a0wGeM76l+s6CqCS9YMXjIpTklT18+aEEr +ltYQgZ/tH9VGp/6e02ZdDDMh8rwt9H1pmgpkyQrS9M8OVDns/6mAQ7pSNNZq+qrG +IewyosxGbHo5tI4fCTuOeiF6AxPWfmkUsSjLVIzTweZva3kY5IQtZlxKDOENAzCr +YWaRlrPAM0cRVSUu5XMqCidYKDsj+XuywqwK7eR9NFKmvPkt3WCAyh2w0uo5P7I2 +572mSuYbYsn+rodnp56Is04YLzW5ciH4PytTYxcbt92E+yx8UPO0RAxnWGhw0ntd +rBVWQw1StOVRISMG7soXXfcvmlzggZJMY5NKrT51FefIoDsa3RWBsGqZdZQGKbu+ +e/PY2/aM1xCgq5xHq0ElX6kUn4qZ/KYrqTLgfq76N0Ne1FfVONdpjGeJWPyzVlxL +MYQCNoH2Qcxe+uOzPjt/4Y0WoCn01mDbB+6estnobnN0O1ibr4IPiMVRFRDyE07k +CZs1HP9KKgkCV7Im5UStaajYDc6pbIID6u1GBjd3/Cvnj96e0yOaui+LiP4/VUaB +Yz2Nt5OAfAusrXjTlN+TrSj7q8WkJiWBc4RkgccZVG7MIY8EEmUwy3A6vpQ8wzHx +dqV/1GenR3yM4YK1ZQkClCHjlAVSPLpd62WlRAWYJzMAz/7SHPA= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFKTCCAxGgAwIBAgIULxU6yIwVW8VHLmVVnEmIBmIyuvIwDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYaW1hcC5sb2NhbGhvc3QgUy9NSU1FIENBMCAXDTI0MDIy +MDA4Mjg0NloYDzIxMjQwMTI3MDgyODQ2WjAjMSEwHwYDVQQDDBhpbWFwLmxvY2Fs +aG9zdCBTL01JTUUgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCt +CpXuaKgAv/gWrtAfuHHJt5kFtBrD+aRZM9OCzj4YA0+W3UU89eV9sTp43z7D1GYn +i9GxIPVavaZNenzCqCkmWu5JhXB7FydnR3kj077YGA7FmWPSQQ6eOXqW6Z5lC2fA +1nMCc+RGWuZ3UgnlJXLlyj6JhlaRBVSrL9fKMBvbTylt4CsgzNeO0tmzU1weEdTQ +20OU+Nv9hJcYx2MEW0sd0TUxxvTEssvdDddObFqM4roeQTS8y/KkCZUOJN1NSQqU +ubs4v+1WPMaZFOAGuJzJI84JlueHJoPUB3sj4wPSHaCf3P08nUrumKfKT6KTVGn2 +zfZkFSoiLS857If7Sd6s18VlEj6gYp/TTsoSzzDPlGxq9S2yLeaUDSG6FmMpBxWH +1zPuA+inBp+ZS6RDUqECRKy87YeS5lfUX9qt2WtWH6nwbtCgy82lWcXbDtAZQQEk +6hNHBtmAkDqTls9++JIHium2FDxtN8XV0BrDnD/JQghDb8vZ/udeArG2/+DGnoDl +ah2bagEGRmz1b6aRkSL4Q8MswE8TysO3FfPQ+JIJxhrxiFaoa1ewD7eD+smcybNc +Bg/+9Qs0g6nt9zf44TOEaC8nV07QKFXxH38WzIw2j+H2pN9eSYAf4XxoHRsoiFPK +igwyhBgXlEg4zhoLVoL5f0Ieagrzv8IMArIlnfdcCwIDAQABo1MwUTAdBgNVHQ4E +FgQUeG41dt1U80fe9wiUdao9aC1nisIwHwYDVR0jBBgwFoAUeG41dt1U80fe9wiU +dao9aC1nisIwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAntHP +H3pE6yW1e+M0AGj7ODwMUadZvBkkEcLvyM/ScjwaMWhmBmFodwAYcCRSJNoIFjlm +KN3xnBbkvSFwQqJnlYz9YHLmSDnlKdv+I4lYxAvWZ11wa4NHvN8oYQDwdgfyAfkM +bqR1c8s4TKyr2l0aGW4DMux4C7jjGeiqItqAmtKu220IyrsnhH31hGOa5QRLicTH +gRIpZ8wao97asO1MEz7yQig9qMCXzBv72mpXNlOgpw6OW31My1VCVZnuJHajPh8u +5TnsXZcFkl7vFRn8G10XywZryBbH7DJlfQ9++kATEOtfZugQRG/S+ihLBeupd15r +G+MXq1YkwHq07pEY+5lzzoZa2jm7NUofLa6kawXbRguFKX04Ku/KQgtjSENT8t2T +uf5bs5GBIlAt3/DhDQUI/RZZBDfGIEhHz5vKd7Z+VuZvHEd+SRp5q5qkIzg1kAR6 +cNlpGO8lwMsTwjCBiq+ybtikZyDZx97vjXrxMaKkBNHQbq8ya0bBFF5LMxIO3jYd +FTlEw0Xc34wQD0228OISYR9M2KzB8AsgSFD0o7C9CQ0JGpla9+coyRcZ47brV04m +UG4hNvHJo51cnoe+uBGKn8ShkO6BIk4ayf4sKccoY8zlDt9B1LWHsjDbNUdYGgzv +nzrh2By7IzXf7DNdG7ZhM2M19QOTHxVa9pJqVaI= +-----END CERTIFICATE-----