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