Commit af1f72fc5d for openssl.org

commit af1f72fc5d5bd6662cc95546908a8e3ee44a3892
Author: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Date:   Tue Jun 2 20:24:38 2026 +0200

    test: add pkey -ec_conv_form coverage

    Cover the previously untested EC point conversion form path for
    uncompressed, compressed and hybrid output, as well as the non-EC key
    rejection. Verified by the leading octet of the encoded point in the
    SubjectPublicKeyInfo.

    Reviewed-by: Norbert Pocs <norbertp@openssl.org>
    Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
    MergeDate: Mon Jun 15 13:54:50 2026
    (Merged from https://github.com/openssl/openssl/pull/31370)

diff --git a/test/recipes/15-test_pkey.t b/test/recipes/15-test_pkey.t
index 4e205cf52b..c61b0548a3 100644
--- a/test/recipes/15-test_pkey.t
+++ b/test/recipes/15-test_pkey.t
@@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;

 setup("test_pkey");

-plan tests => 5;
+plan tests => 6;

 my @app = ('openssl', 'pkey');

@@ -127,3 +127,47 @@ subtest "=== pkey text output ===" => sub {
         run(app([@app, '-in', $in_key, '-text', '-noout']), capture => 1)),
         "pkey text output (even with -noout) contains \"Private-Key:\"");
 };
+
+subtest "=== pkey EC point conversion form ===" => sub {
+    plan skip_all => "EC not supported in this build" if disabled("ec");
+    plan tests => 8;
+
+    my $ec_key = 'ec_p256.pem';
+    ok(run(app(['openssl', 'genpkey', '-algorithm', 'EC',
+                '-pkeyopt', 'ec_paramgen_curve:P-256', '-out', $ec_key])),
+       "generate P-256 EC key");
+
+    # In a named-curve P-256 SubjectPublicKeyInfo the EC point starts at a
+    # fixed 26-byte offset, so its first octet identifies the conversion form:
+    # 0x04 uncompressed, 0x02/0x03 compressed, 0x06/0x07 hybrid.
+    sub point_lead {
+        open IN, '<', $_[0] or return -1;
+        binmode IN;
+        read IN, my $buf, 27;
+        close IN;
+        return ord substr($buf, 26, 1);
+    }
+
+    my $unc = 'pub_unc.der';
+    ok(run(app([@app, '-in', $ec_key, '-pubout', '-ec_conv_form', 'uncompressed',
+                '-outform', 'DER', '-out', $unc])),
+       "write uncompressed public key");
+    is(point_lead($unc), 0x04, "uncompressed point has 0x04 prefix");
+
+    my $comp = 'pub_comp.der';
+    ok(run(app([@app, '-in', $ec_key, '-pubout', '-ec_conv_form', 'compressed',
+                '-outform', 'DER', '-out', $comp])),
+       "write compressed public key");
+    my $clead = point_lead($comp);
+    ok($clead == 0x02 || $clead == 0x03, "compressed point has 0x02/0x03 prefix");
+
+    my $hyb = 'pub_hyb.der';
+    ok(run(app([@app, '-in', $ec_key, '-pubout', '-ec_conv_form', 'hybrid',
+                '-outform', 'DER', '-out', $hyb])),
+       "write hybrid public key");
+    my $hlead = point_lead($hyb);
+    ok($hlead == 0x06 || $hlead == 0x07, "hybrid point has 0x06/0x07 prefix");
+
+    ok(!run(app([@app, '-in', $in_key, '-ec_conv_form', 'compressed', '-noout'])),
+       "-ec_conv_form on a non-EC key fails");
+};