From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id 3D9911FF0EA for ; Fri, 14 Aug 2026 16:30:37 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 0ACE4226AB; Fri, 14 Aug 2026 16:30:37 +0200 (CEST) Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Fri, 14 Aug 2026 16:30:30 +0200 Message-Id: Subject: Re: [PATCH common v4 2/3] pem parser: add testsuite for check_ and split_pem From: "Elias Huhsovitz" To: "Thomas Ellmenreich" , X-Mailer: aerc 0.20.0 References: <20260805141114.190477-1-t.ellmenreich@proxmox.com> <20260805141114.190477-3-t.ellmenreich@proxmox.com> In-Reply-To: <20260805141114.190477-3-t.ellmenreich@proxmox.com> X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1786717811829 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.144 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust RDNS_NONE 1.274 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: CTFNPTVQAQUZAQUOPOMG5FONUFEF6VUQ X-Message-ID-Hash: CTFNPTVQAQUZAQUOPOMG5FONUFEF6VUQ X-MailFrom: e.huhsovitz@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Ran tests using prove check_pem_test.test prove split_pem_test.test Tests seem to cover all important code paths. Reviewed-by: Elias Huhsovitz Tested-by: Elias Huhsovitz On Wed Aug 5, 2026 at 4:11 PM CEST, Thomas Ellmenreich wrote: > having made considerable changes to both check_pem and split_pem > in the previous commit, this commit introduces tests for both methods. > > Signed-off-by: Thomas Ellmenreich > --- > test/Makefile | 2 + > test/check_pem_test.pl | 365 +++++++++++++++++++++++++++++++++++++++++ > test/split_pem_test.pl | 279 +++++++++++++++++++++++++++++++ > 3 files changed, 646 insertions(+) > create mode 100755 test/check_pem_test.pl > create mode 100755 test/split_pem_test.pl > > diff --git a/test/Makefile b/test/Makefile > index 961a0da..e5a5f42 100644 > --- a/test/Makefile > +++ b/test/Makefile > @@ -15,6 +15,8 @@ TESTS =3D lock_file.test \ > section_config_property_isolation_test.test \ > file-test.test \ > cmd-test.test \ > + check_pem_test.test \ > + split_pem_test.test \ > =20 > all: > =20 > diff --git a/test/check_pem_test.pl b/test/check_pem_test.pl > new file mode 100755 > index 0000000..b9f11a0 > --- /dev/null > +++ b/test/check_pem_test.pl > @@ -0,0 +1,365 @@ > +#!/usr/bin/perl > +# Tests the PVE::Certificate::check_pem function for > +# correctness and coverage of edgecases. > +use strict; > +use warnings; > + > +use lib '../src'; > + > +use Test::More; > + > +use PVE::Certificate; > + > +# Arrange > +my $setup =3D [ > + { > + expected_success =3D> 1, > + name =3D> "full pem", > + pem =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > +MIIBsjCCAVugAwIBAgIJAO2g8Z0dXk9tMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT > +AlVTMQswCQYDVQQIDAJDQTEQMA4GA1UEBwwHQmVya2VsZXkxEDAOBgNVBAoMB1Rl > +c3QgQ0EwHhcNMjAwMTAxMDAwMDAwWhcNMzAwMTAxMDAwMDAwWjBFMQswCQYDVQQG > +EwJVUzELMAkGA1UECAwCQ0ExEDAOBgNVBAcMB0JlcmtlbGV5MRAwDgYDVQQKDAdU > +ZXN0IENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEv5Q8q1p7qZ2gqkQ0Qn5x > +0n9yqv8n8n7n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8aNT > +MFEwHQYDVR0OBBYEFOu2Y0bq8v3z7qkq1m1Qwqkq1m1QMB8GA1UdIwQYMBaAFOu2 > +Y0bq8v3z7qkq1m1Qwqkq1m1QMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwID > +SAAwRQIhANfakefakefakefakefakefakefakefakefake > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "other label pem", > + label =3D> "SOME LABEL", > + pem =3D> <<'EOF', > +-----BEGIN SOME LABEL----- > +MIIBsjCCAVugAwIBAgIJAO2g8Z0dXk9tMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT > +AlVTMQswCQYDVQQIDAJDQTEQMA4GA1UEBwwHQmVya2VsZXkxEDAOBgNVBAoMB1Rl > +c3QgQ0EwHhcNMjAwMTAxMDAwMDAwWhcNMzAwMTAxMDAwMDAwWjBFMQswCQYDVQQG > +EwJVUzELMAkGA1UECAwCQ0ExEDAOBgNVBAcMB0JlcmtlbGV5MRAwDgYDVQQKDAdU > +ZXN0IENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEv5Q8q1p7qZ2gqkQ0Qn5x > +0n9yqv8n8n7n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8aNT > +MFEwHQYDVR0OBBYEFOu2Y0bq8v3z7qkq1m1Qwqkq1m1QMB8GA1UdIwQYMBaAFOu2 > +Y0bq8v3z7qkq1m1Qwqkq1m1QMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwID > +SAAwRQIhANfakefakefakefakefakefakefakefakefake > +-----END SOME LABEL----- > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "simple pem", > + pem =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > +test > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "spaced out pem", > + pem =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > + > +test > + > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "only newline pem", > + pem =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "many newlines pem", > + pem =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > + > + > + > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 0, > + name =3D> "no content pem", > + pem =3D> <<'EOF', > +-----BEGIN CERTIFICATE----------END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "preceding content pem", > + pem =3D> <<'EOF', > +some extended content > +-----BEGIN CERTIFICATE----- > +test > +-----END CERTIFICATE----- > +EOF > + > + expected_result =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > +test > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 0, > + name =3D> "following content pem", > + pem =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > +test > +-----END CERTIFICATE----- > +some extended content > +EOF > + }, > + { > + expected_success =3D> 0, > + name =3D> "empty pem", > + pem =3D> <<'EOF', > + > +EOF > + }, > + { > + expected_success =3D> 0, > + name =3D> "upsidedown pem", > + pem =3D> <<'EOF', > +-----END CERTIFICATE----- > +test > +-----BEGIN CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "multi pem", > + multiple =3D> 1, > + pem =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > +12JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +-----BEGIN CERTIFICATE----- > +22JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +-----BEGIN CERTIFICATE----- > +32JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +-----BEGIN CERTIFICATE----- > +42JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 0, > + name =3D> "multiple as single pem", > + pem =3D> <<'EOF', > +Subject: CN=3Dsome.test.content > +Issuer: CN=3DOrg Issuing CA 3 > +-----BEGIN CERTIFICATE----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +Subject: CN=3DOrg Issuing CA 3 > +Issuer: CN=3DOrg Root CA > +-----BEGIN CERTIFICATE----- > +2WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "big pem different label", > + multiple =3D> 1, > + label =3D> "LABEL", > + pem =3D> <<'EOF', > +Subject: CN=3Dsome.test.content > +Issuer: CN=3DOrg Issuing CA 3 > +-----BEGIN LABEL----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END LABEL----- > +Subject: CN=3DOrg Issuing CA 3 > +Issuer: CN=3DOrg Root CA > +-----BEGIN LABEL----- > +2WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END LABEL----- > +Subject: CN=3DOrg Root CA > +Issuer: CN=3DOrg Root CA > +-----BEGIN LABEL----- > +3WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END LABEL----- > +EOF > + > + expected_result =3D> <<'EOF', > +-----BEGIN LABEL----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END LABEL----- > +-----BEGIN LABEL----- > +2WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END LABEL----- > +-----BEGIN LABEL----- > +3WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END LABEL----- > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "other real pem", > + pem =3D> <<'EOF', > +Subject: CN=3DSome subject with 2 Points,O=3DA Organization,L=3DSome Lat= ion,C=3DTT > +Issuer: CN=3DThe Orgs Name RootCA 2015,O=3DThe Orgs name Institutions Ce= rt. Authority,L=3DLocation,C=3DTT > +-----BEGIN CERTIFICATE----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + expected_result =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 0, > + name =3D> "invalid single pem", > + pem =3D> <<'EOF', > +Subject: CN=3DSome subject with 2 Points,O=3DA Organization,L=3DSome Lat= ion,C=3DTT > +Issuer: CN=3DThe Orgs Name RootCA 2015,O=3DThe Orgs name Institutions Ce= rt. Authority,L=3DLocation,C=3DTT > +-----BEGIN CERTIFICATE----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdthese !?''*:;$%&/ are not allowedWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 0, > + name =3D> "invalid multi pem", > + multiple =3D> 1, > + pem =3D> <<'EOF', > +Subject: CN=3DSome subject with 2 Points,O=3DA Organization,L=3DSome Lat= ion,C=3DTT > +Issuer: CN=3DThe Orgs Name RootCA 2015,O=3DThe Orgs name Institutions Ce= rt. Authority,L=3DLocation,C=3DTT > +-----BEGIN CERTIFICATE----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdthese !?''*:;$%&/ are not allowedWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +Subject: CN=3DSome subject with 2 Points,O=3DA Organization,L=3DSome Lat= ion,C=3DTT > +Issuer: CN=3DThe Orgs Name RootCA 2015,O=3DThe Orgs name Institutions Ce= rt. Authority,L=3DLocation,C=3DTT > +-----BEGIN CERTIFICATE----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > + > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "single as multiple pem", > + multiple =3D> 1, > + pem =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdtheseZ2RmaXVwYWJ2aXV1YXdlYmxmamlraWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "single as multiple pem", > + multiple =3D> 1, > + pem =3D> <<'EOF', > +Subject: CN=3DSome subject with 2 Points,O=3DA Organization,L=3DSome Lat= ion,C=3DTT > +Issuer: CN=3DThe Orgs Name RootCA 2015,O=3DThe Orgs name Institutions Ce= rt. Authority,L=3DLocation,C=3DTT > +-----BEGIN CERTIFICATE----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdtheseZ2RmaXVwYWJ2aXV1YXdlYmxmamlraWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + expected_result =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdtheseZ2RmaXVwYWJ2aXV1YXdlYmxmamlraWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + }, > +]; > + > +for my $data ($setup->@*) { > + subtest $data->{name} =3D> sub { > + # Act > + my $check_result =3D PVE::Certificate::check_pem( > + $data->{pem}, > + noerr =3D> 1, > + multiple =3D> $data->{multiple}, > + label =3D> $data->{label}, > + ); > + > + # Assert > + if ($data->{expected_success}) { > + ok($check_result, "is successful"); > + > + my $expected_result =3D > + $data->{expected_result} > + ? $data->{expected_result} > + : $data->{pem}; > + is( > + $check_result, $expected_result, "has correct result con= tent", > + ); > + } else { > + is($check_result, undef, "has correctly returned undef"); > + eval { > + PVE::Certificate::check_pem( > + $data->{pem}, > + multiple =3D> $data->{multiple}, > + label =3D> $data->{label}, > + ); > + }; > + ok($@, "has correctly thrown an error"); > + } > + } > +} > + > +done_testing(); > diff --git a/test/split_pem_test.pl b/test/split_pem_test.pl > new file mode 100755 > index 0000000..4239e5c > --- /dev/null > +++ b/test/split_pem_test.pl > @@ -0,0 +1,279 @@ > +#!/usr/bin/perl > +# Tests the PVE::Certificate::split_pem function for > +# correctness and coverage of edgecases. > +use strict; > +use warnings; > + > +use lib '../src'; > + > +use Test::More; > + > +use PVE::Certificate; > + > +# Arrange > +my $setup =3D [ > + { > + expected_success =3D> 1, > + name =3D> "single pem", > + pem =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > +MIIBsjCCAVugAwIBAgIJAO2g8Z0dXk9tMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT > +AlVTMQswCQYDVQQIDAJDQTEQMA4GA1UEBwwHQmVya2VsZXkxEDAOBgNVBAoMB1Rl > +c3QgQ0EwHhcNMjAwMTAxMDAwMDAwWhcNMzAwMTAxMDAwMDAwWjBFMQswCQYDVQQG > +EwJVUzELMAkGA1UECAwCQ0ExEDAOBgNVBAcMB0JlcmtlbGV5MRAwDgYDVQQKDAdU > +ZXN0IENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEv5Q8q1p7qZ2gqkQ0Qn5x > +0n9yqv8n8n7n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8n8aNT > +MFEwHQYDVR0OBBYEFOu2Y0bq8v3z7qkq1m1Qwqkq1m1QMB8GA1UdIwQYMBaAFOu2 > +Y0bq8v3z7qkq1m1Qwqkq1m1QMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwID > +SAAwRQIhANfakefakefakefakefakefakefakefakefake > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "no extra text pem", > + pem =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > +12JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +-----BEGIN CERTIFICATE----- > +22JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +-----BEGIN CERTIFICATE----- > +32JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +-----BEGIN CERTIFICATE----- > +42JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + > + expected_result =3D> [ > + <<'EOF', > +-----BEGIN CERTIFICATE----- > +12JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + > + <<'EOF', > +-----BEGIN CERTIFICATE----- > +22JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + > + <<'EOF', > +-----BEGIN CERTIFICATE----- > +32JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + > + <<'EOF', > +-----BEGIN CERTIFICATE----- > +42JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + ], > + }, > + { > + expected_success =3D> 1, > + name =3D> "leading and interleaved text pem", > + pem =3D> <<'EOF', > +Subject: CN=3Dsome.test.content > +Issuer: CN=3DOrg Issuing CA 3 > +-----BEGIN CERTIFICATE----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +Subject: CN=3DOrg Issuing CA 3 > +Issuer: CN=3DOrg Root CA > +-----BEGIN CERTIFICATE----- > +2WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +Subject: CN=3DOrg Root CA > +Issuer: CN=3DOrg Root CA > +-----BEGIN CERTIFICATE----- > +3WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + > + expected_result =3D> [ > + <<'EOF', > +Subject: CN=3Dsome.test.content > +Issuer: CN=3DOrg Issuing CA 3 > +-----BEGIN CERTIFICATE----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + > + <<'EOF', > +Subject: CN=3DOrg Issuing CA 3 > +Issuer: CN=3DOrg Root CA > +-----BEGIN CERTIFICATE----- > +2WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + > + <<'EOF', > +Subject: CN=3DOrg Root CA > +Issuer: CN=3DOrg Root CA > +-----BEGIN CERTIFICATE----- > +3WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + ], > + }, > + { > + expected_success =3D> 1, > + name =3D> "massive glob pem", > + pem =3D> <<'EOF', > +Subject: CN=3Dsome.test.content > +Issuer: CN=3DOrg Issuing CA 3 > +-----BEGIN CERTIFICATE----- > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +Subject: CN=3DOrg Issuing CA 3 > +Issuer: CN=3DOrg Root CA > +-----BEGIN CERTIFICATE----- > +2WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +Subject: CN=3DOrg Root CA > +Issuer: CN=3DOrg Root CA > +-----BEGIN CERTIFICATE----- > +3WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "no beginning pem", > + pem =3D> <<'EOF', > +Subject: CN=3Dsome.test.content > +Issuer: CN=3DOrg Issuing CA 3 > +2WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +Subject: CN=3DOrg Root CA > +Issuer: CN=3DOrg Root CA > +3WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + > + expected_result =3D> [ > + <<'EOF', > +Subject: CN=3Dsome.test.content > +Issuer: CN=3DOrg Issuing CA 3 > +2WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + > + <<'EOF', > +Subject: CN=3DOrg Root CA > +Issuer: CN=3DOrg Root CA > +3WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + ], > + > + }, > + { > + expected_success =3D> 0, > + name =3D> "not a pem pem", > + pem =3D> <<'EOF', > +Subject: CN=3Dsome.test.content > +Issuer: CN=3DOrg Issuing CA 3 > +1WtzZGhmbGtqYXNoZ2RmaXVwYWJ2aXV1YXdlYmxmamlraGFzZGtmYWlzdXBkdW5i > +dmFpdXdlYmdmw7ZrYWpkc2JoZmdpYXNkbmJpZnVhYmdzaWprZmdyYXNkaHJmaW9h > +dXNkbmF1c2JmZ3ZramFzZGJma2phc2RibmZpanVhIHNkb3ZuYmF3b3VlYmZnb2F3 > +c2JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +Subject: CN=3DOrg Issuing CA 3 > +Issuer: CN=3DOrg Root CA > +EOF > + }, > + { > + expected_success =3D> 1, > + name =3D> "following text pem", > + pem =3D> <<'EOF', > +-----BEGIN CERTIFICATE----- > +32JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +-----BEGIN CERTIFICATE----- > +42JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +some more text that we would like to remove > +EOF > + > + expected_result =3D> [ > + <<'EOF', > +-----BEGIN CERTIFICATE----- > +32JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + > + <<'EOF', > +-----BEGIN CERTIFICATE----- > +42JlZ2tseTxzZWl2IGF3ZWlidm4=3D > +-----END CERTIFICATE----- > +EOF > + ], > + }, > +]; > + > +for my $data ($setup->@*) { > + subtest $data->{name} =3D> sub { > + # Act > + my @split_result =3D PVE::Certificate::split_pem( > + $data->{pem}, label =3D> $data->{label}, > + ); > + > + # Assert > + if ($data->{expected_success}) { > + ok(@split_result, "is successful"); > + my $expected_result =3D > + $data->{expected_result} > + ? $data->{expected_result} > + : [$data->{pem}]; > + > + is_deeply( > + \@split_result, \@$expected_result, "has correct split o= utput", > + ); > + } else { > + is_deeply(\@split_result, [], "has correctly returned empty"= ); > + } > + } > +} > + > +done_testing();