From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 75A8B1FF09B for ; Mon, 09 Nov 2026 11:38:07 +0100 (CET) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id EFC312164F; Mon, 09 Nov 2026 11:37:49 +0100 (CET) From: Thomas Ellmenreich To: pve-devel@lists.proxmox.com Subject: [PATCH common 2/3] tests: introduce tests for pem_to_der Date: Mon, 9 Nov 2026 11:37:32 +0100 Message-ID: <20261109103733.128704-3-t.ellmenreich@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261109103733.128704-1-t.ellmenreich@proxmox.com> References: <20261109103733.128704-1-t.ellmenreich@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1794220663428 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.350 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 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: 7FG7YPAVZQR2L435BKOKDH3ENHMCZDCG X-Message-ID-Hash: 7FG7YPAVZQR2L435BKOKDH3ENHMCZDCG X-MailFrom: t.ellmenreich@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 CC: Thomas Ellmenreich X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: To pin down the functionality of the pem_to_der subroutine, introduce a small testsuite. Also reduces the risk to future changes in subroutines used by the pem_to_der subroutine. Signed-off-by: Thomas Ellmenreich --- test/Makefile | 1 + test/pem_to_der_test.pl | 161 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100755 test/pem_to_der_test.pl diff --git a/test/Makefile b/test/Makefile index 9caba10..f111511 100644 --- a/test/Makefile +++ b/test/Makefile @@ -19,6 +19,7 @@ TESTS = lock_file.test \ ticket_test.test \ check_pem_test.test \ split_pem_test.test \ + pem_to_der_test.test \ all: diff --git a/test/pem_to_der_test.pl b/test/pem_to_der_test.pl new file mode 100755 index 0000000..c35e1f4 --- /dev/null +++ b/test/pem_to_der_test.pl @@ -0,0 +1,161 @@ +#!/usr/bin/perl +# Tests the PVE::Certificate::pem_to_der function for +# correctness and coverage of edgecases. +use strict; +use warnings; + +use lib '../src'; + +use Test::More; + +use PVE::Certificate; + +# Arrange +my $setup = [ + { + name => "single pem", + pem => q{-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Np +bmcgZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFi +b3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVu +aWFtLCBxdWlzIG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBu +aXNpIHV0IGFsaXF1aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0 +ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxp +dCBlc3NlIGNpbGx1bSBkb2xvcmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBF +eGNlcHRldXIgc2ludCBvY2NhZWNhdCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBz +dW50IGluIGN1bHBhIHF1aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlk +IGVzdCBsYWJvcnVtLg== +-----END CERTIFICATE----- +}, + expected_decoded_result => + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + }, + { + name => "single pem no terminating newline", + pem => q{-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0= +-----END CERTIFICATE-----}, + expected_decoded_result => "Lorem ipsum", + }, + { + name => "multiple pem", + pem => q{-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMw== +-----END CERTIFICATE----- +}, + expected_decoded_result => "Lorem ipsum 1", + }, + { + name => "multiple pem leading newline", + pem => q{ +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMw== +-----END CERTIFICATE----- +}, + expected_decoded_result => "Lorem ipsum 1", + }, + { + name => "multiple pem leading text", + pem => q{ +some leading +text that is expected +to be stripped +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMw== +-----END CERTIFICATE----- +}, + expected_decoded_result => "Lorem ipsum 1", + }, + { + name => "multiple pem interleaved text", + pem => q{ +some leading text +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMQ== +-----END CERTIFICATE----- +some leading text +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMg== +-----END CERTIFICATE----- +some leading text +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMw== +-----END CERTIFICATE----- +some end text +}, + expected_decoded_result => "Lorem ipsum 1", + }, + { + name => "multiple pem no newline after footer", + pem => q{ +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMQ== +-----END CERTIFICATE----------BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0gMw== +-----END CERTIFICATE----- +}, + expected_decoded_result => "Lorem ipsum 1", + }, + { + name => "all in one line", + pem => "-----BEGIN CERTIFICATE-----TG9yZW0gaXBzdW0=-----END CERTIFICATE-----", + expected_error => "header", + }, + { + name => "only newline after begin", + pem => q{-----BEGIN CERTIFICATE----- +TG9yZW0gaXBzdW0=-----END CERTIFICATE-----}, + expected_error => "footer", + }, + { + name => "only newline after content", + pem => q{-----BEGIN CERTIFICATE-----TG9yZW0gaXBzdW0= +-----END CERTIFICATE-----}, + expected_error => "header", + }, + { + name => "only newline after end", + pem => q{-----BEGIN CERTIFICATE-----TG9yZW0gaXBzdW0=-----END CERTIFICATE----- +}, + expected_error => "header", + }, +]; + +for my $data ($setup->@*) { + subtest $data->{name} => sub { + my $to_der_result = eval { PVE::Certificate::pem_to_der($data->{pem}) }; + my $to_der_error = $@; + if (defined($data->{expected_decoded_result})) { + is($to_der_result, $data->{expected_decoded_result}, "has correct decoded result"); + } else { + like( + $to_der_error, + qr/Could not convert PEM to DER, no $data->{expected_error} found./, + "has died with expected error", + ); + } + } +} + +done_testing(); -- 2.47.3