xref: /freebsd/crypto/openssl/test/recipes/15-test_pkey.t (revision e7be843b4a162e68651d3911f0357ed464915629)
1*e7be843bSPierre Pronchery#! /usr/bin/env perl
2*e7be843bSPierre Pronchery# Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.
3*e7be843bSPierre Pronchery#
4*e7be843bSPierre Pronchery# Licensed under the Apache License 2.0 (the "License").  You may not use
5*e7be843bSPierre Pronchery# this file except in compliance with the License.  You can obtain a copy
6*e7be843bSPierre Pronchery# in the file LICENSE in the source distribution or at
7*e7be843bSPierre Pronchery# https://www.openssl.org/source/license.html
8*e7be843bSPierre Pronchery
9*e7be843bSPierre Proncheryuse strict;
10*e7be843bSPierre Proncheryuse warnings;
11*e7be843bSPierre Pronchery
12*e7be843bSPierre Proncheryuse OpenSSL::Test::Utils;
13*e7be843bSPierre Proncheryuse File::Copy;
14*e7be843bSPierre Proncheryuse File::Compare qw(compare_text);
15*e7be843bSPierre Proncheryuse OpenSSL::Test qw/:DEFAULT srctop_file/;
16*e7be843bSPierre Pronchery
17*e7be843bSPierre Proncherysetup("test_pkey");
18*e7be843bSPierre Pronchery
19*e7be843bSPierre Proncheryplan tests => 5;
20*e7be843bSPierre Pronchery
21*e7be843bSPierre Proncherymy @app = ('openssl', 'pkey');
22*e7be843bSPierre Pronchery
23*e7be843bSPierre Proncherymy $in_key = srctop_file('test', 'certs', 'root-key.pem');
24*e7be843bSPierre Proncherymy $pass = 'pass:password';
25*e7be843bSPierre Pronchery
26*e7be843bSPierre Proncherysubtest "=== pkey typical en-/decryption (using AES256-CBC) ===" => sub {
27*e7be843bSPierre Pronchery    plan tests => 4;
28*e7be843bSPierre Pronchery
29*e7be843bSPierre Pronchery    my $encrypted_key = 'encrypted_key.pem';
30*e7be843bSPierre Pronchery    my $decrypted_key = 'decrypted_key.pem';
31*e7be843bSPierre Pronchery
32*e7be843bSPierre Pronchery    ok(run(app([@app, '-aes256', '-in', $in_key, '-out', $encrypted_key,
33*e7be843bSPierre Pronchery                '-passout', $pass])),
34*e7be843bSPierre Pronchery       "encrypt key (using aes-256-cbc)");
35*e7be843bSPierre Pronchery
36*e7be843bSPierre Pronchery    ok(run(app(['openssl', 'asn1parse', '-in', $encrypted_key,
37*e7be843bSPierre Pronchery                '-offset', '34', '-length', '18'])), # incl. 2 bytes header
38*e7be843bSPierre Pronchery       "encrypted key has default PBKDF2 PARAM 'salt length' 16");
39*e7be843bSPierre Pronchery
40*e7be843bSPierre Pronchery    ok(run(app([@app, '-in', $encrypted_key, '-out', $decrypted_key,
41*e7be843bSPierre Pronchery                '-passin', $pass])),
42*e7be843bSPierre Pronchery       "decrypt key");
43*e7be843bSPierre Pronchery    is(compare_text($in_key, $decrypted_key), 0,
44*e7be843bSPierre Pronchery       "Same file contents after encrypting and decrypting in separate files");
45*e7be843bSPierre Pronchery};
46*e7be843bSPierre Pronchery
47*e7be843bSPierre Proncherysubtest "=== pkey handling of identical input and output files (using 3DES) and -traditional ===" => sub {
48*e7be843bSPierre Pronchery    plan skip_all => "DES not supported in this build" if disabled("des");
49*e7be843bSPierre Pronchery    plan tests => 4;
50*e7be843bSPierre Pronchery
51*e7be843bSPierre Pronchery    my $inout = 'inout.pem';
52*e7be843bSPierre Pronchery
53*e7be843bSPierre Pronchery    copy($in_key, $inout);
54*e7be843bSPierre Pronchery    ok(run(app([@app, '-des3', '-traditional', '-in', $inout, '-out', $inout,
55*e7be843bSPierre Pronchery                '-passout', $pass])),
56*e7be843bSPierre Pronchery       "encrypt using identical infile and outfile");
57*e7be843bSPierre Pronchery
58*e7be843bSPierre Pronchery    sub file_line_contains { grep /$_[0]/, ((open F, $_[1]), <F>, close F) }
59*e7be843bSPierre Pronchery    ok(file_line_contains("DEK-Info: DES-EDE3-CBC,", $inout),
60*e7be843bSPierre Pronchery       "traditional encoding contains \"DEK-Info: DES-EDE3-CBC,\"");
61*e7be843bSPierre Pronchery
62*e7be843bSPierre Pronchery    ok(run(app([@app, '-in', $inout, '-out', $inout, '-passin', $pass])),
63*e7be843bSPierre Pronchery       "decrypt using identical infile and outfile");
64*e7be843bSPierre Pronchery    is(compare_text($in_key, $inout), 0,
65*e7be843bSPierre Pronchery       "Same file contents after encrypting and decrypting using same file");
66*e7be843bSPierre Pronchery};
67*e7be843bSPierre Pronchery
68*e7be843bSPierre Proncherysubtest "=== pkey handling of public keys (Ed25519) ===" => sub {
69*e7be843bSPierre Pronchery    plan skip_all => "ECX not supported inthis build" if disabled("ecx");
70*e7be843bSPierre Pronchery    plan tests => 6;
71*e7be843bSPierre Pronchery
72*e7be843bSPierre Pronchery    my $in_ed_key = srctop_file('test', 'certs', 'root-ed25519.privkey.pem');
73*e7be843bSPierre Pronchery    my $in_pubkey = srctop_file('test', 'certs', 'root-ed25519.pubkey.pem');
74*e7be843bSPierre Pronchery
75*e7be843bSPierre Pronchery    my $pub_out1 = 'pub1.pem';
76*e7be843bSPierre Pronchery    ok(run(app([@app, '-in', $in_ed_key, '-pubout', '-out', $pub_out1])),
77*e7be843bSPierre Pronchery       "extract public key");
78*e7be843bSPierre Pronchery    is(compare_text($in_pubkey, $pub_out1), 0,
79*e7be843bSPierre Pronchery       "extracted public key is same as original public key");
80*e7be843bSPierre Pronchery
81*e7be843bSPierre Pronchery    my $pub_out2 = 'pub2.pem';
82*e7be843bSPierre Pronchery    ok(run(app([@app, '-in', $in_pubkey, '-pubin', '-pubout', '-out', $pub_out2])),
83*e7be843bSPierre Pronchery       "read public key from pubfile");
84*e7be843bSPierre Pronchery    is(compare_text($in_pubkey, $pub_out2), 0,
85*e7be843bSPierre Pronchery       "public key read using pubfile is same as original public key");
86*e7be843bSPierre Pronchery
87*e7be843bSPierre Pronchery    my $pub_out3 = 'pub3.pem';
88*e7be843bSPierre Pronchery    ok(run(app([@app, '-in', $in_ed_key, '-pubin', '-pubout', '-out', $pub_out3])),
89*e7be843bSPierre Pronchery       "extract public key from pkey file with -pubin");
90*e7be843bSPierre Pronchery    is(compare_text($in_pubkey, $pub_out3), 0,
91*e7be843bSPierre Pronchery       "public key extraced from pkey file with -pubin is same as original");
92*e7be843bSPierre Pronchery};
93*e7be843bSPierre Pronchery
94*e7be843bSPierre Pronchery
95*e7be843bSPierre Proncherysubtest "=== pkey handling of DER encoding ===" => sub {
96*e7be843bSPierre Pronchery    plan tests => 4;
97*e7be843bSPierre Pronchery
98*e7be843bSPierre Pronchery    my $der_out = 'key.der';
99*e7be843bSPierre Pronchery    my $pem_out = 'key.pem';
100*e7be843bSPierre Pronchery    ok(run(app([@app, '-in', $in_key, '-outform', 'DER',
101*e7be843bSPierre Pronchery                 '-out', $der_out])),
102*e7be843bSPierre Pronchery       "write DER-encoded pkey");
103*e7be843bSPierre Pronchery
104*e7be843bSPierre Pronchery    ok(run(app(['openssl', 'asn1parse', '-in', $der_out, '-inform', 'DER',
105*e7be843bSPierre Pronchery                 '-offset', '268', '-length', '5'])), # incl. 2 bytes header
106*e7be843bSPierre Pronchery       "see if length of the modulus encoding is included");
107*e7be843bSPierre Pronchery
108*e7be843bSPierre Pronchery    ok(run(app([@app, '-in', $der_out, '-inform', 'DER',
109*e7be843bSPierre Pronchery                 '-out', $pem_out])),
110*e7be843bSPierre Pronchery       "read DER-encoded key");
111*e7be843bSPierre Pronchery    is(compare_text($in_key, $pem_out), 0,
112*e7be843bSPierre Pronchery       "Same file contents after converting to DER and back");
113*e7be843bSPierre Pronchery};
114*e7be843bSPierre Pronchery
115*e7be843bSPierre Proncherysubtest "=== pkey text output ===" => sub {
116*e7be843bSPierre Pronchery    plan tests => 3;
117*e7be843bSPierre Pronchery
118*e7be843bSPierre Pronchery    ok((grep /BEGIN PRIVATE KEY/,
119*e7be843bSPierre Pronchery        run(app([@app, '-in', $in_key, '-text']), capture => 1)),
120*e7be843bSPierre Pronchery        "pkey text output contains PEM header");
121*e7be843bSPierre Pronchery
122*e7be843bSPierre Pronchery    ok(!(grep /BEGIN PRIVATE KEY/,
123*e7be843bSPierre Pronchery        run(app([@app, '-in', $in_key, '-text', '-noout']), capture => 1)),
124*e7be843bSPierre Pronchery        "pkey text output with -noout does not contain PEM header");
125*e7be843bSPierre Pronchery
126*e7be843bSPierre Pronchery    ok((grep /Private-Key:/,
127*e7be843bSPierre Pronchery        run(app([@app, '-in', $in_key, '-text', '-noout']), capture => 1)),
128*e7be843bSPierre Pronchery        "pkey text output (even with -noout) contains \"Private-Key:\"");
129*e7be843bSPierre Pronchery};
130