[openssl] master update
Richard Levitte
levitte at openssl.org
Wed Apr 24 09:57:46 UTC 2019
The branch master has been updated
via 07822c515574223c2958fcddd52191cfbf9aefcd (commit)
via c54492ecf8331fd87f6ac163f9fc5b576af128e8 (commit)
from bacc3081309ef4489b78d1ee8bf04122785ba588 (commit)
- Log -----------------------------------------------------------------
commit 07822c515574223c2958fcddd52191cfbf9aefcd
Author: Shane Lontis <shane.lontis at oracle.com>
Date: Tue Apr 23 19:17:40 2019 +1000
added openssl app 'kdf' and 'mac' to the NEWS and CHANGES docs
Reviewed-by: Tim Hudson <tjh at openssl.org>
Reviewed-by: Richard Levitte <levitte at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8762)
commit c54492ecf8331fd87f6ac163f9fc5b576af128e8
Author: Shane Lontis <shane.lontis at oracle.com>
Date: Tue Apr 16 20:10:04 2019 +1000
Added app for EVP_KDF
Reviewed-by: Tim Hudson <tjh at openssl.org>
Reviewed-by: Richard Levitte <levitte at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8762)
-----------------------------------------------------------------------
Summary of changes:
CHANGES | 6 ++
NEWS | 4 ++
apps/build.info | 2 +-
apps/kdf.c | 158 ++++++++++++++++++++++++++++++++++++++++++
doc/man1/kdf.pod | 167 +++++++++++++++++++++++++++++++++++++++++++++
doc/man1/openssl.pod | 8 ++-
doc/man3/EVP_KDF_CTX.pod | 5 +-
test/recipes/20-test_kdf.t | 78 +++++++++++++++++++++
8 files changed, 423 insertions(+), 5 deletions(-)
create mode 100644 apps/kdf.c
create mode 100644 doc/man1/kdf.pod
create mode 100644 test/recipes/20-test_kdf.t
diff --git a/CHANGES b/CHANGES
index d0e2d3a..a5d6950 100644
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,12 @@
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
+ *) Added command 'openssl kdf' that uses the EVP_KDF API.
+ [Shane Lontis]
+
+ *) Added command 'openssl mac' that uses the EVP_MAC API.
+ [Shane Lontis]
+
*) Added OPENSSL_info() to get diverse built-in OpenSSL data, such
as default directories. Also added the command 'openssl info'
for scripting purposes.
diff --git a/NEWS b/NEWS
index 0800b76..6c79bc2 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,8 @@
Major changes between OpenSSL 1.1.1 and OpenSSL 3.0.0 [under development]
+ o Added 'openssl mac' that uses the EVP_MAC API.
+ o Added 'openssl kdf' that uses the EVP_KDF API.
o Add OPENSSL_info() and 'openssl info' to get built-in data.
o Add support for enabling instrumentation through trace and debug
output.
@@ -15,6 +17,8 @@
o Added EVP_MAC, an EVP layer MAC API, and a generic EVP_PKEY to EVP_MAC
bridge.
o Removed the heartbeat message in DTLS feature.
+ o Added EVP_KDF, an EVP layer KDF API, and a generic EVP_PKEY to EVP_KDF
+ bridge.
Major changes between OpenSSL 1.1.1 and OpenSSL 1.1.1a [20 Nov 2018]
diff --git a/apps/build.info b/apps/build.info
index 30847a0..cbb70fc 100644
--- a/apps/build.info
+++ b/apps/build.info
@@ -2,7 +2,7 @@
qw(openssl.c
asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c dhparam.c
dsa.c dsaparam.c ec.c ecparam.c enc.c engine.c errstr.c gendsa.c
- genpkey.c genrsa.c mac.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c
+ genpkey.c genrsa.c kdf.c mac.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c
pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c
rsautl.c s_client.c s_server.c s_time.c sess_id.c smime.c speed.c
spkac.c srp.c ts.c verify.c version.c x509.c rehash.c storeutl.c
diff --git a/apps/kdf.c b/apps/kdf.c
new file mode 100644
index 0000000..684fd44
--- /dev/null
+++ b/apps/kdf.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <string.h>
+
+#include "apps.h"
+#include "progs.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/kdf.h>
+
+typedef enum OPTION_choice {
+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+ OPT_KDFOPT, OPT_BIN, OPT_KEYLEN, OPT_OUT
+} OPTION_CHOICE;
+
+const OPTIONS kdf_options[] = {
+ {OPT_HELP_STR, 1, '-', "Usage: %s [options] kdf_name\n"},
+ {OPT_HELP_STR, 1, '-', "kdf_name\t KDF algorithm.\n"},
+ {"help", OPT_HELP, '-', "Display this summary"},
+ {"kdfopt", OPT_KDFOPT, 's', "KDF algorithm control parameters in n:v form. "
+ "See 'Supported Controls' in the EVP_KDF_ docs"},
+ {"keylen", OPT_KEYLEN, 's', "The size of the output derived key"},
+ {"out", OPT_OUT, '>', "Output to filename rather than stdout"},
+ {"binary", OPT_BIN, '-', "Output in binary format (Default is hexadecimal "
+ "output)"},
+ {NULL}
+};
+
+static int kdf_ctrl_string(EVP_KDF_CTX *ctx, const char *value)
+{
+ int rv;
+ char *stmp, *vtmp = NULL;
+
+ stmp = OPENSSL_strdup(value);
+ if (stmp == NULL)
+ return -1;
+ vtmp = strchr(stmp, ':');
+ if (vtmp != NULL) {
+ *vtmp = 0;
+ vtmp++;
+ }
+ rv = EVP_KDF_ctrl_str(ctx, stmp, vtmp);
+ OPENSSL_free(stmp);
+ return rv;
+}
+
+int kdf_main(int argc, char **argv)
+{
+ int ret = 1, i, id, out_bin = 0;
+ OPTION_CHOICE o;
+ STACK_OF(OPENSSL_STRING) *opts = NULL;
+ char *prog, *hexout = NULL;
+ const char *outfile = NULL;
+ unsigned char *dkm_bytes = NULL;
+ size_t dkm_len = 0;
+ BIO *out = NULL;
+ EVP_KDF_CTX *ctx = NULL;
+
+ prog = opt_init(argc, argv, kdf_options);
+ while ((o = opt_next()) != OPT_EOF) {
+ switch (o) {
+ default:
+opthelp:
+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+ goto err;
+ case OPT_HELP:
+ opt_help(kdf_options);
+ ret = 0;
+ goto err;
+ case OPT_BIN:
+ out_bin = 1;
+ break;
+ case OPT_KEYLEN:
+ dkm_len = (size_t)atoi(opt_arg());
+ break;
+ case OPT_OUT:
+ outfile = opt_arg();
+ break;
+ case OPT_KDFOPT:
+ if (opts == NULL)
+ opts = sk_OPENSSL_STRING_new_null();
+ if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg()))
+ goto opthelp;
+ break;
+ }
+ }
+ argc = opt_num_rest();
+ argv = opt_rest();
+
+ if (argc != 1) {
+ BIO_printf(bio_err, "Invalid number of extra arguments\n");
+ goto opthelp;
+ }
+
+ id = OBJ_sn2nid(argv[0]);
+ if (id == NID_undef) {
+ BIO_printf(bio_err, "Invalid KDF name %s\n", argv[0]);
+ goto opthelp;
+ }
+
+ ctx = EVP_KDF_CTX_new_id(id);
+ if (ctx == NULL)
+ goto err;
+
+ if (opts != NULL) {
+ for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
+ char *opt = sk_OPENSSL_STRING_value(opts, i);
+ if (kdf_ctrl_string(ctx, opt) <= 0) {
+ BIO_printf(bio_err, "KDF parameter error '%s'\n", opt);
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ }
+ }
+
+ out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
+ if (out == NULL)
+ goto err;
+
+ if (dkm_len <= 0) {
+ BIO_printf(bio_err, "Invalid derived key length.\n");
+ goto err;
+ }
+ dkm_bytes = app_malloc(dkm_len, "out buffer");
+ if (dkm_bytes == NULL)
+ goto err;
+
+ if (!EVP_KDF_derive(ctx, dkm_bytes, dkm_len)) {
+ BIO_printf(bio_err, "EVP_KDF_derive failed\n");
+ goto err;
+ }
+
+ if (out_bin) {
+ BIO_write(out, dkm_bytes, dkm_len);
+ } else {
+ hexout = OPENSSL_buf2hexstr(dkm_bytes, dkm_len);
+ BIO_printf(out, "%s\n\n", hexout);
+ }
+
+ ret = 0;
+err:
+ if (ret != 0)
+ ERR_print_errors(bio_err);
+ OPENSSL_clear_free(dkm_bytes, dkm_len);
+ sk_OPENSSL_STRING_free(opts);
+ EVP_KDF_CTX_free(ctx);
+ BIO_free(out);
+ OPENSSL_free(hexout);
+ return ret;
+}
diff --git a/doc/man1/kdf.pod b/doc/man1/kdf.pod
new file mode 100644
index 0000000..0ff7762
--- /dev/null
+++ b/doc/man1/kdf.pod
@@ -0,0 +1,167 @@
+=pod
+
+=head1 NAME
+
+openssl-kdf,
+kdf - perform Key Derivation Function operations
+
+=head1 SYNOPSIS
+
+B<openssl kdf>
+[B<-help>]
+[B<-kdfopt> I<nm:v>]
+[B<-keylen> I<num>]
+[B<-out> I<filename>]
+[B<-binary>]
+I<kdf_name>
+
+=head1 DESCRIPTION
+
+The key derivation functions generate a derived key from either a secret or
+password.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-help>
+
+Print a usage message.
+
+=item B<-keylen> I<num>
+
+The output size of the derived key. This field is required.
+
+=item B<-out> I<filename>
+
+Filename to output to, or standard output by default.
+
+=item B<-binary>
+
+Output the derived key in binary form. Uses hexadecimal text format if not specified.
+
+=item B<-kdfopt> I<nm:v>
+
+Passes options to the KDF algorithm.
+A comprehensive list of controls can be found in the EVP_KDF_CTX implementation
+documentation.
+Common control strings used by EVP_KDF_ctrl_str() are:
+
+=over 4
+
+=item B<key:>I<string>
+
+Specifies the secret key as an alphanumeric string (use if the key contains
+printable characters only).
+The string length must conform to any restrictions of the KDF algorithm.
+A key must be specified for most KDF algorithms.
+
+=item B<hexkey:>I<string>
+
+Specifies the secret key in hexadecimal form (two hex digits per byte).
+The key length must conform to any restrictions of the KDF algorithm.
+A key must be specified for most KDF algorithms.
+
+=item B<pass:>I<string>
+
+Specifies the password as an alphanumeric string (use if the password contains
+printable characters only).
+The password must be specified for PBKDF2 and scrypt.
+
+=item B<hexpass:>I<string>
+
+Specifies the password in hexadecimal form (two hex digits per byte).
+The password must be specified for PBKDF2 and scrypt.
+
+=item B<digest:>I<string>
+
+Specifies the name of a digest as an alphanumeric string.
+To see the list of supported digests, use the command I<list -digest-commands>.
+
+=back
+
+=item I<kdf_name>
+
+Specifies the name of a supported KDF algorithm which will be used.
+The supported algorithms names are TLS1-PRF, HKDF, SSKDF, PBKDF2, SSHKDF and id-scrypt.
+
+=back
+
+=head1 EXAMPLES
+
+Use TLS1-PRF to create a hex-encoded derived key from a secret key and seed:
+
+ openssl kdf -keylen 16 -kdfopt digest:SHA256 -kdfopt key:secret \
+ -kdfopt seed:seed TLS1-PRF
+
+Use HKDF to create a hex-encoded derived key from a secret key, salt and info:
+
+ openssl kdf -keylen 10 -kdfopt digest:SHA256 -kdfopt key:secret \
+ -kdfopt salt:salt -kdfopt info:label HKDF
+
+Use SSKDF with KMAC to create a hex-encoded derived key from a secret key, salt and info:
+
+ openssl kdf -keylen 64 -kdfopt mac:KMAC128 -kdfopt maclen:20 \
+ -kdfopt hexkey:b74a149a161545 -kdfopt hexinfo:348a37a2 \
+ -kdfopt hexsalt:3638271ccd68a2 SSKDF
+
+Use SSKDF with HMAC to create a hex-encoded derived key from a secret key, salt and info:
+
+ openssl kdf -keylen 16 -kdfopt mac:HMAC -kdfopt digest:SHA256 \
+ -kdfopt hexkey:b74a149a -kdfopt hexinfo:348a37a2 \
+ -kdfopt hexsalt:3638271c SSKDF
+
+Use SSKDF with Hash to create a hex-encoded derived key from a secret key, salt and info:
+
+ openssl kdf -keylen 14 -kdfopt digest:SHA256 \
+ -kdfopt hexkey:6dbdc23f045488 \
+ -kdfopt hexinfo:a1b2c3d4 SSKDF
+
+Use SSHKDF to create a hex-encoded derived key from a secret key, hash and session_id:
+
+ openssl kdf -keylen 16 -kdfopt digest:SHA256 \
+ -kdfopt hexkey:0102030405 \
+ -kdfopt hexxcghash:06090A \
+ -kdfopt hexsession_id:01020304 \
+ -kdfopt type:A SSHKDF
+
+Use PBKDF2 to create a hex-encoded derived key from a password and salt:
+
+ openssl kdf -keylen 32 -kdfopt digest:SHA256 -kdfopt pass:password \
+ -kdfopt salt:salt -kdfopt iter:2 PBKDF2
+
+Use scrypt to create a hex-encoded derived key from a password and salt:
+
+ openssl kdf -keylen 64 -kdfopt pass:password -kdfopt salt:NaCl \
+ -kdfopt N:1024 -kdfopt r:8 -kdfopt p:16 \
+ -kdfopt maxmem_bytes:10485760 id-scrypt
+
+=head1 NOTES
+
+The KDF mechanisms that are available will depend on the options
+used when building OpenSSL.
+
+=head1 SEE ALSO
+
+L<EVP_KDF_CTX(3)>,
+L<EVP_KDF_SCRYPT(7)>
+L<EVP_KDF_TLS1_PRF(7)>
+L<EVP_KDF_PBKDF2(7)>
+L<EVP_KDF_HKDF(7)>
+L<EVP_KDF_SS(7)>
+L<EVP_KDF_SSHKDF(7)>
+
+=head1 HISTORY
+
+Added in OpenSSL 3.0
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the OpenSSL license (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man1/openssl.pod b/doc/man1/openssl.pod
index e41c76a..41d04da 100644
--- a/doc/man1/openssl.pod
+++ b/doc/man1/openssl.pod
@@ -171,6 +171,10 @@ Generation of RSA Private Key. Superseded by L<genpkey(1)>.
Display diverse information built into the OpenSSL libraries.
+=item B<kdf>
+
+Key Derivation Functions.
+
=item B<mac>
Message Authentication Code Calculation.
@@ -616,7 +620,7 @@ L<crl(1)>, L<crl2pkcs7(1)>, L<dgst(1)>,
L<dhparam(1)>, L<dsa(1)>, L<dsaparam(1)>,
L<ec(1)>, L<ecparam(1)>,
L<enc(1)>, L<engine(1)>, L<errstr(1)>, L<gendsa(1)>, L<genpkey(1)>,
-L<genrsa(1)>, L<mac(1)>, L<nseq(1)>, L<ocsp(1)>,
+L<genrsa(1)>, L<kdf(1)>, L<mac(1)>, L<nseq(1)>, L<ocsp(1)>,
L<passwd(1)>,
L<pkcs12(1)>, L<pkcs7(1)>, L<pkcs8(1)>,
L<pkey(1)>, L<pkeyparam(1)>, L<pkeyutl(1)>, L<prime(1)>,
@@ -636,7 +640,7 @@ manual pages.
=head1 COPYRIGHT
-Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
diff --git a/doc/man3/EVP_KDF_CTX.pod b/doc/man3/EVP_KDF_CTX.pod
index 4ca8d94..f646528 100644
--- a/doc/man3/EVP_KDF_CTX.pod
+++ b/doc/man3/EVP_KDF_CTX.pod
@@ -151,9 +151,9 @@ The value string is expected to be the name of a MAC.
This control expects one argument: C<EVP_MD *md>
For MAC implementations that use a message digest as an underlying computation
-algorithm, this control set what the digest algorithm should be.
+algorithm, this control sets what the digest algorithm should be.
-EVP_KDF_ctrl_str() type string: "md"
+EVP_KDF_ctrl_str() type string: "digest"
The value string is expected to be the name of a digest.
@@ -232,6 +232,7 @@ L<EVP_KDF_TLS1_PRF(7)>
L<EVP_KDF_PBKDF2(7)>
L<EVP_KDF_HKDF(7)>
L<EVP_KDF_SS(7)>
+L<EVP_KDF_SSHKDF(7)>
=head1 HISTORY
diff --git a/test/recipes/20-test_kdf.t b/test/recipes/20-test_kdf.t
new file mode 100644
index 0000000..62cbb05
--- /dev/null
+++ b/test/recipes/20-test_kdf.t
@@ -0,0 +1,78 @@
+#! /usr/bin/env perl
+# Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+
+use strict;
+use warnings;
+
+use OpenSSL::Test;
+use OpenSSL::Test::Utils;
+
+setup("test_kdf");
+
+my @kdf_tests = (
+ { cmd => [qw{openssl kdf -keylen 16 -kdfopt digest:SHA256 -kdfopt secret:secret -kdfopt seed:seed TLS1-PRF}],
+ expected => '8E:4D:93:25:30:D7:65:A0:AA:E9:74:C3:04:73:5E:CC',
+ desc => 'TLS1-PRF SHA256' },
+ { cmd => [qw{openssl kdf -keylen 16 -kdfopt digest:MD5-SHA1 -kdfopt secret:secret -kdfopt seed:seed TLS1-PRF}],
+ expected => '65:6F:31:CB:04:03:D6:51:E2:E8:71:F8:20:04:AB:BA',
+ desc => 'TLS1-PRF MD5-SHA1' },
+ { cmd => [qw{openssl kdf -keylen 10 -kdfopt digest:SHA256 -kdfopt key:secret -kdfopt salt:salt -kdfopt info:label HKDF}],
+ expected => '2a:c4:36:9f:52:59:96:f8:de:13',
+ desc => 'HKDF SHA256' },
+ { cmd => [qw{openssl kdf -keylen 32 -kdfopt digest:SHA256 -kdfopt pass:password -kdfopt salt:salt -kdfopt iter:2 PBKDF2}],
+ expected => 'ae:4d:0c:95:af:6b:46:d3:2d:0a:df:f9:28:f0:6d:d0:2a:30:3f:8e:f3:c2:51:df:d6:e2:d8:5a:95:47:4c:43',
+ desc => 'PBKDF2 SHA256'},
+ { cmd => [qw{openssl kdf -keylen 64 -kdfopt mac:KMAC128 -kdfopt maclen:20 -kdfopt hexkey:b74a149a161546f8c20b06ac4ed4 -kdfopt hexinfo:348a37a27ef1282f5f020dcc -kdfopt hexsalt:3638271ccd68a25dc24ecddd39ef3f89 SSKDF}],
+ expected => 'e9:c1:84:53:a0:62:b5:3b:db:fc:bb:5a:34:bd:b8:e5:e7:07:ee:bb:5d:d1:34:42:43:d8:cf:c2:c2:e6:33:2f:91:bd:a5:86:f3:7d:e4:8a:65:d4:c5:14:fd:ef:aa:1e:67:54:f3:73:d2:38:e1:95:ae:15:7e:1d:e8:14:98:03',
+ desc => 'SSKDF KMAC128'},
+ { cmd => [qw{openssl kdf -keylen 16 -kdfopt mac:HMAC -kdfopt digest:SHA256 -kdfopt hexkey:b74a149a161546f8c20b06ac4ed4 -kdfopt hexinfo:348a37a27ef1282f5f020dcc -kdfopt hexsalt:3638271ccd68a25dc24ecddd39ef3f89 SSKDF}],
+ expected => '44:f6:76:e8:5c:1b:1a:8b:bc:3d:31:92:18:63:1c:a3',
+ desc => 'SSKDF HMAC SHA256'},
+ { cmd => [qw{openssl kdf -keylen 14 -kdfopt digest:SHA224 -kdfopt hexkey:6dbdc23f045488e4062757b06b9ebae183fc5a5946d80db93fec6f62ec07e3727f0126aed12ce4b262f47d48d54287f81d474c7c3b1850e9 -kdfopt hexinfo:a1b2c3d4e54341565369643c832e9849dcdba71e9a3139e606e095de3c264a66e98a165854cd07989b1ee0ec3f8dbe SSKDF}],
+ expected => 'a4:62:de:16:a8:9d:e8:46:6e:f5:46:0b:47:b8',
+ desc => 'SSKDF HASH SHA224'},
+ { cmd => [qw{openssl kdf -keylen 16 -kdfopt md:SHA256 -kdfopt hexkey:0102030405 -kdfopt hexxcghash:06090A -kdfopt hexsession_id:01020304 -kdfopt type:A SSHKDF}],
+ expected => '5C:49:94:47:3B:B1:53:3A:58:EB:19:42:04:D3:78:16',
+ desc => 'SSHKDF SHA256'},
+);
+
+my @scrypt_tests = (
+ { cmd => [qw{openssl kdf -keylen 64 -kdfopt pass:password -kdfopt salt:NaCl -kdfopt N:1024 -kdfopt r:8 -kdfopt p:16 -kdfopt maxmem_bytes:10485760 id-scrypt}],
+ expected => 'fd:ba:be:1c:9d:34:72:00:78:56:e7:19:0d:01:e9:fe:7c:6a:d7:cb:c8:23:78:30:e7:73:76:63:4b:37:31:62:2e:af:30:d9:2e:22:a3:88:6f:f1:09:27:9d:98:30:da:c7:27:af:b9:4a:83:ee:6d:83:60:cb:df:a2:cc:06:40',
+ desc => 'SCRYPT' },
+);
+
+push @kdf_tests, @scrypt_tests unless disabled("scrypt");
+
+plan tests => scalar @kdf_tests;
+
+foreach (@kdf_tests) {
+ ok(compareline($_->{cmd}, $_->{expected}), $_->{desc});
+}
+
+# Check that the stdout output matches the expected value.
+sub compareline {
+ my ($cmdarray, $expect) = @_;
+ if (defined($expect)) {
+ $expect = uc $expect;
+ }
+
+ my @lines = run(app($cmdarray), capture => 1);
+
+ if (defined($expect)) {
+ if ($lines[0] =~ m|^\Q${expect}\E\R$|) {
+ return 1;
+ } else {
+ print "Got: $lines[0]";
+ print "Exp: $expect\n";
+ return 0;
+ }
+ }
+ return 0;
+}
More information about the openssl-commits
mailing list