Alt-Crypt-OpenSSL-PKCS12-Broadbean

 view release on metacpan or  search on metacpan

Changes.md  view on Meta::CPAN

# Revision history for Perl extension Crypt::OpenSSL::PKCS12.

# 1.93 2024-09-28

- Inclusion of PR: [#51](https://github.com/dsully/perl-crypt-openssl-pkcs12/pull/44) aimed at addressing the following issues observed with previous release: `1.92`, thanks to @timlegge for the contribution
  - [#48](https://github.com/dsully/perl-crypt-openssl-pkcs12/issues/48)
  - [#49](https://github.com/dsully/perl-crypt-openssl-pkcs12/issues/49)
  - [#40](https://github.com/dsully/perl-crypt-openssl-pkcs12/issues/50)

# 1.92 2024-09-08

Addition of new feature supporting the OpenSSL info option, all via PR [#44](https://github.com/dsully/perl-crypt-openssl-pkcs12/pull/44) from @timlegge

## 1.91 Mon Jun 24 22:00:13 CEST 2024

Due to a mistake with the release numbering, the two trial releases, should not have been `1.10` and `1.11`, but `1.91` and `1.92` respectively. So there will be a jump from 1.9 to 1.91, since 1.9 is equivalent to 1.90.

This release contains changes tested on the two previous trial releases.

In addition the following changes have been adopted:

- PR: [#47](https://github.com/dsully/perl-crypt-openssl-pkcs12/pull/47) from @timlegge, improving support for building with OpenSSL located in non-standard locations

## 1.11 (TRIAL) Wed Jun  5 20:21:54 CEST 2024

- Improved support for older versions of OpenSSL via PR [#46](https://github.com/dsully/perl-crypt-openssl-pkcs12/pull/46) from @timlegge
  This should address reports on failing tests from CPAN testers, see also: [#45](https://github.com/dsully/perl-crypt-openssl-pkcs12/issues/45)

- Minor cleanup to repository files used for varies tools

## 1.10 (TRIAL) Fri Apr 26 16:09:56 CEST 2024

- Improved support for OpenSSL 3.0 via RT: [42](https://github.com/dsully/perl-crypt-openssl-pkcs12/pull/42) from @timlegge

- Distribution tooling changed from `Module::Install` to `Dist::Zilla`

## 1.9 Sat Nov 20 12:49:34 CET 2021

- Added new feature from `create_as_string` via PR #39 from James Rouzier (@jrouzierinverse), which returns the PKCS data as a string, for futher handling

- Bumped Perl requirement from Perl 5.6 to 5.8, due to use of UTF-8 in test suite

- POD cleaned up, more to come

Changes.md  view on Meta::CPAN

## 1.5  Wed May 19 22:03:48 CEST 2021

- Addressed minor issue with the implementation added in 1.4, fix lifted from Crypt::OpenSSL::X509 - Thanks Shoichi Kaji

- Added section on contributors to the POD

## 1.4  Sun Apr 11 16:23:54 CEST 2021

- Addressed issue with homebrew path reported for Crypt::OpenSSL::X509

  REF: https://github.com/dsully/perl-crypt-openssl-x509/issues/81

  The pattern is the same in this distribution

## 1.3  Thu Jun  4 21:39:30 CEST 2020

- Maintenance release addressing the broken inc/ configuration pointed out in: RT:77784 by HMBRAND

  REF: https://rt.cpan.org/Ticket/Display.html?id=77784

## 1.2  Sat Oct 27 09:37:04 CEST 2018

LICENSE  view on Meta::CPAN


Source code for a work means the preferred form of the work for making
modifications to it.  For an executable file, complete source code means
all the source code for all modules it contains; but, as a special
exception, it need not include source code for modules which are standard
libraries that accompany the operating system on which the executable
file runs, or for standard header files or definitions files that
accompany that operating system.

  4. You may not copy, modify, sublicense, distribute or transfer the
Program except as expressly provided under this General Public License.
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
the Program is void, and will automatically terminate your rights to use
the Program under this License.  However, parties who have received
copies, or rights to use copies, from you under this General Public
License will not have their licenses terminated so long as such parties
remain in full compliance.

  5. By copying, distributing or modifying the Program (or any work based
on the Program) you indicate your acceptance of this license to do so,
and all its terms and conditions.

MANIFEST  view on Meta::CPAN

certs/test_le_1.1.p12
certs/v3-certs-RC2.p12
certs/v3-certs-TDES.p12
cpanfile
cpanfile.snapshot
dist.ini
lib/Alt/Crypt/OpenSSL/PKCS12/Broadbean.pm
lib/Crypt/OpenSSL/PKCS12.pm
maint/Makefile_header.PL
ppport.h
t/00-openssl-version.t
t/author-pod-syntax.t
t/pkcs12-from-scratch.t
t/pkcs12-info-arbitrary-bag-attributes.t
t/pkcs12-info-key-bag.t
t/pkcs12-info-le_1.1.t
t/pkcs12-info-multiple-pkcs7-sections.t
t/pkcs12-info-openssl-81-test_cmp_cli.t
t/pkcs12-info-safe-contents-bag.t
t/pkcs12-info-secret-bag.t
t/pkcs12-info-v3-certs-RC2.t
t/pkcs12-info-v3-certs-TDES.t
t/pkcs12-string.t
t/pkcs12.t
t/pod-coverage.t
t/pod.t
t/release-kwalitee.t
t/release-meta-json.t

Makefile.PL  view on Meta::CPAN

# This Makefile.PL for Alt-Crypt-OpenSSL-PKCS12-Broadbean was generated by
# Dist::Zilla::Plugin::MakeMaker::Awesome 0.49.
# Don't edit it but the dist.ini and plugins used to construct it.

use strict;
use warnings;

use ExtUtils::MakeMaker;

use Config;
use Crypt::OpenSSL::Guess qw(openssl_lib_paths openssl_inc_paths);

my %args = (
  LIBS => [openssl_lib_paths().' -lssl -lcrypto'],
  INC => openssl_inc_paths(),
);

my $cc_option_flags = " -O2 -g";
my $cc_defines      = '';

if ($Config::Config{cc} =~ /gcc/i) {
  $cc_option_flags .= $ENV{AUTHOR_TESTING} ? ' -Wall -Werror' : ' -Wall';
} else {
  $cc_option_flags .= '';
}

Makefile.PL  view on Meta::CPAN


  if ($Config{perl_version} <= 20) {
    $cc_option_flags .= ' -Wno-error=pointer-bool-conversion';
  }
}

if ($Config{myuname} =~ /sunos|solaris/i) {
  $args{OPTIMIZE} = $cc_option_flags;
} elsif ($Config{myuname} =~ /strawberry-{0,1}perl/i) {
  if ($Config{PERL_VERSION} <= 24) {
    $args{LIBS} = [openssl_lib_paths() . ' -leay32'];
  }
  $cc_defines .= ' -DOPENSSL_NO_SCRYPT';
  $args{DEFINE} = $cc_defines;
} elsif ($Config{myuname} =~ /darwin/ ) {
  $args{LDDLFLAGS} = openssl_lib_paths() . ' ' . $Config{lddlflags};
} else {
  $args{LDDLFLAGS} = openssl_lib_paths() . ' ' . $Config{lddlflags};
  $args{OPTIMIZE} = $cc_option_flags;
}

# HACK HACK HACK - dakkar 2024-09-26
#
# we need to cheat a lot to get MakeMaker to build a Makefile that
# will build the correct XS library... here, I tell *only this part*
# of the MakeMaker process, that we are really Crypt::OpenSSL::PKCS12,
# and not the Alt::*
#

PKCS12.xs  view on Meta::CPAN

#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#define NEED_newCONSTSUB
#include "ppport.h"

#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/provider.h>
OSSL_PROVIDER *legacy   = NULL;
OSSL_PROVIDER *deflt    = NULL;
#endif
#define NOKEYS          0x1
#define NOCERTS         0x2
#define INFO            0x4
#define CLCERTS         0x8
#define CACERTS         0x10

#if OPENSSL_VERSION_NUMBER < 0x10100000L

PKCS12.xs  view on Meta::CPAN

#define CONST_STACK_OF(o) const STACK_OF(o)
#define CONST_X509_NAME const X509_NAME
#define CONST_ASN1_INTEGER const ASN1_INTEGER
#define CONST_ASN1_OBJECT const ASN1_OBJECT
#define CONST_ASN1_OCTET_STRING const ASN1_OCTET_STRING
#define CONST_VOID const void
#endif

const EVP_CIPHER *enc;
int dump_certs_pkeys_bags(pTHX_ BIO *out, CONST_STACK_OF(PKCS12_SAFEBAG) *bags,
                           const char *pass, int passlen, int options,
                           char *pempass, const EVP_CIPHER *enc, HV* hash);
static int alg_print(pTHX_ BIO *bio, CONST_X509_ALGOR *alg, HV* hash);
void print_attribute(pTHX_ BIO *out, CONST_ASN1_TYPE *av, char **value);
int print_attribs(pTHX_ BIO *out, CONST_STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name, HV *hash);
void hex_prin(BIO *out, unsigned char *buf, int len);
void dump_cert_text(BIO *out, X509 *x);
SV * get_cert_subject_name(pTHX_ X509 *x);
SV * get_cert_issuer_name(pTHX_ X509 *x);

#define CHECK_OPEN_SSL(p_result) if (!(p_result)) croakSSL(__FILE__, __LINE__);

PKCS12.xs  view on Meta::CPAN

     CHECK_OPEN_SSL(BIO_flush(p_stringBio) == 1);

     datasize = BIO_get_mem_data(p_stringBio, &datap);
     sv = newSVpv(datap, datasize);

     CHECK_OPEN_SSL(BIO_set_close(p_stringBio, BIO_CLOSE) == 1);
     BIO_free(p_stringBio);
     return sv;
}

static const char *ssl_error(pTHX) {
  BIO *bio;
  SV *sv;
  STRLEN l;

  CHECK_OPEN_SSL(bio = BIO_new(BIO_s_mem()));
  ERR_print_errors(bio);
  sv = extractBioString(aTHX_ bio);
  ERR_clear_error();
  return SvPV(sv, l);
}

/* these are trimmed from their openssl/apps/pkcs12.c counterparts */
int dump_certs_pkeys_bag (pTHX_ BIO *bio, PKCS12_SAFEBAG *bag, const char *pass, int passlen, int options, char *pempass, const EVP_CIPHER *enc, HV * bag_hv) {

  EVP_PKEY *pkey;
  X509 *x509;
  CONST_PKCS8_PRIV_KEY_INFO *p8 = NULL;
  CONST_STACK_OF(X509_ATTRIBUTE) *bag_attrs;
  CONST_STACK_OF(X509_ATTRIBUTE) *key_attrs;

  bag_attrs = PKCS12_SAFEBAG_get0_attrs(bag);

/* FIXME: Change NULL to default_enc and allow the encryption to ne overridden like no-des */

PKCS12.xs  view on Meta::CPAN

      }

      EVP_PKEY_free(pkey);

      break;

    case NID_pkcs8ShroudedKeyBag: ;

      if (options & NOKEYS) return 1;

      if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL)
        return 0;
      if ((pkey = EVP_PKCS82PKEY (p8)) == NULL) {
        PKCS8_PRIV_KEY_INFO_free((PKCS8_PRIV_KEY_INFO *) p8);
        return 0;
      }
      if (options & INFO) {
        CONST_X509_ALGOR *tp8alg;
#if OPENSSL_VERSION_NUMBER > 0x10100000L
        CONST_X509_SIG *tp8;

PKCS12.xs  view on Meta::CPAN

    case NID_safeContentsBag:
        if (options & INFO) {
          if(bag_hv) {
            SV * value = newSVpvn("safe_contents_bag", strlen("safe_contents_bag"));
            if((hv_store(bag_hv, "type", strlen("type"), value, 0)) == NULL)
              croak("unable to add type to the bag_hv");

            print_attribs(aTHX_ bio, bag_attrs, "bag_attributes", bag_hv);

            dump_certs_pkeys_bags(aTHX_ bio, PKCS12_SAFEBAG_get0_safes(bag),
                                    pass, passlen, options, pempass, enc, bag_hv);
          } else {
            BIO_printf(bio, "Safe Contents bag\n");
            print_attribs(aTHX_ bio, bag_attrs, "Bag Attributes", NULL);
            dump_certs_pkeys_bags(aTHX_ bio, PKCS12_SAFEBAG_get0_safes(bag),
                              pass, passlen, options, pempass, enc, NULL);
          }
        }
        break;
     default:
       if(bag_hv)
          return 1;
        BIO_printf(bio, "Warning unsupported bag type: ");
        i2a_ASN1_OBJECT(bio, PKCS12_SAFEBAG_get0_type(bag));
        BIO_printf(bio, "\n");
  }

  return 1;
}

int dump_certs_pkeys_bags(pTHX_ BIO *bio, CONST_STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, int passlen, int options, char *pempass, const EVP_CIPHER *enc, HV * hash) {

  int i;

  AV * bags_av = NULL;
  HV * bag_hv = NULL;
  if(hash) {
    bags_av = newAV();
  }
  for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
    if(hash)
      bag_hv = newHV();
    if (!dump_certs_pkeys_bag (aTHX_ bio, sk_PKCS12_SAFEBAG_value (bags, i), pass, passlen, options, pempass, enc, bag_hv)) {
      return 0;
    }
    if(hash)
      av_push(bags_av, newRV_inc((SV *) bag_hv));
  }

  if (hash) {
    SV **svp = NULL;
    char *type;
    if (hv_exists(bag_hv, "type", strlen("type"))) {

PKCS12.xs  view on Meta::CPAN

          croak("unable to add bags to the hash");
      } else {
        if((hv_store(hash, "bags", strlen("bags"), newRV_inc((SV *) bags_av), 0)) == NULL)
          croak("unable to add bags to the hash");
      }
    }
  }
  return 1;
}

int dump_certs_keys_p12(pTHX_ BIO *bio, PKCS12 *p12, char *pass, int passlen, int options, char *pempass, HV * orig_hash) {

  STACK_OF(PKCS7) *asafes;
  STACK_OF(PKCS12_SAFEBAG) *bags;

  int i, bagnid;
  PKCS7 *p7;
  HV * bag_hv = NULL;
  HV * parameters_hv = NULL;
  AV * pkcs7_bags_av = newAV();
  AV * pkcs7_enc_bags_av = newAV();

PKCS12.xs  view on Meta::CPAN

          av_push(pkcs7_enc_bags_av, newRV_inc((SV *) bag_hv));
        } else {
          BIO_printf(bio, "PKCS7 Encrypted data: ");
          if (p7->d.encrypted == NULL) {
            BIO_printf(bio, "<no data>\n");
          } else {
            alg_print(aTHX_ bio, p7->d.encrypted->enc_data->algorithm, NULL);
          }
        }
      }
      bags = PKCS12_unpack_p7encdata(p7, pass, passlen);

    } else {
      continue;
    }

    if (bags == NULL) return 0;

    if (!dump_certs_pkeys_bags(aTHX_ bio, bags, pass, passlen, options, pempass, enc, bag_hv)) {
      sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
      return 0;
    }

  if (orig_hash) {
    if((hv_store(orig_hash, "pkcs7_data", strlen("pkcs7_data"), newRV_inc((SV *) pkcs7_bags_av), 0)) == NULL)
      croak("unable to add bags to the hash");
    if((hv_store(orig_hash, "pkcs7_encrypted_data", strlen("pkcs7_encrypted_data"), newRV_inc((SV *) pkcs7_enc_bags_av), 0)) == NULL)
      croak("unable to add bags to the hash");
  }

PKCS12.xs  view on Meta::CPAN

    bio = BIO_new_file(str_ptr, "rb");
  } else {
    bio = BIO_new_mem_buf(str_ptr, str_len);
  }

  if (!bio) croak("Failed to create BIO");

  /* this can come in any number of ways */
  if ((RETVAL = d2i_PKCS12_bio(bio, 0)) == NULL) {
    BIO_free_all(bio);
    croak("%" SVf ": Couldn't create PKCS12 from d2i_PKCS12_BIO(): %s", SVfARG(class), ssl_error(aTHX));
  }

  BIO_free_all(bio);

  OUTPUT:
  RETVAL

# This is called at per-object destruction time.
void
DESTROY(pkcs12)

PKCS12.xs  view on Meta::CPAN


  PREINIT:
  BIO *bio;

  CODE:

  CHECK_OPEN_SSL(bio = BIO_new(BIO_s_mem()));

  if (!(i2d_PKCS12_bio(bio, pkcs12))) {
    sv_bio_error(aTHX_ bio);
    croak("i2d_PKCS12_bio: %s", ssl_error(aTHX));
  }

  RETVAL = extractBioString(aTHX_ bio);

  OUTPUT:
  RETVAL

SV*
mac_ok(pkcs12, pwd = "")
  Crypt::OpenSSL::PKCS12 pkcs12
  char *pwd

  CODE:

  if (!(PKCS12_verify_mac(pkcs12, pwd, strlen(pwd)))) {
    croak("PKCS12_verify_mac: \n%s", ssl_error(aTHX));
  }

  RETVAL = (PKCS12_verify_mac(pkcs12, pwd, strlen(pwd))) ? &PL_sv_yes : &PL_sv_no;

  OUTPUT:
  RETVAL

SV*
changepass(pkcs12, oldpwd = "", newpwd = "")
  Crypt::OpenSSL::PKCS12 pkcs12
  char *oldpwd
  char *newpwd

  CODE:

  if (!(PKCS12_newpass(pkcs12, oldpwd, newpwd))) {
    warn("PKCS12_newpass: %s %s\n%s", oldpwd, newpwd, ssl_error(aTHX));
    RETVAL = &PL_sv_no;
  } else {
    RETVAL = &PL_sv_yes;
  }

  OUTPUT:
  RETVAL

SV*
create(pkcs12, cert_chain_pem = "", pk = "", pass = 0, file = 0, name = "PKCS12 Certificate")

lib/Crypt/OpenSSL/PKCS12.pm  view on Meta::CPAN

This distribution implements a subset of OpenSSL's PKCS12 API.

=head1 SUBROUTINES/METHODS

=over 4

=item * new( )

=item * legacy_support ( )

Check whether the openssl version installed supports the legacy provider.

=item * new_from_string( C<$string> )

=item * new_from_file( C<$filename> )

Create a new Crypt::OpenSSL::PKCS12 instance.

=item * certificate( [C<$pass>] )

Get the Base64 representation of the certificate.

lib/Crypt/OpenSSL/PKCS12.pm  view on Meta::CPAN


Create a new PKCS12 certificate string. $cert & $key may either be strings or filenames.

C<$friendly_name> is optional.

Returns a string holding the PKCS12 certicate.

=item * info( C<$pass> )

Returns a string containing the output of information about the pkcs12 file in
the same format as produced by the openssl command:

    openssl pkcs12 -in certs/test_le_1.1.p12 -info -nodes

=item * info_as_hash( C<$pass> )

Places the information about the pkcs12 file, the certificates and keys
in a hash.

The format of the hash is complex to represent the data in the PKCS12 file:

Essentially, the hash follows the format of the -info output.

lib/Crypt/OpenSSL/PKCS12.pm  view on Meta::CPAN

=item * An installation of OpenSSL, either version 1.X.X or version 3.X.X

=item * Perl 5.8

=back

=head1 SEE ALSO

=over

=item * OpenSSL(1) (L<HTTP version with OpenSSL.org|https://www.openssl.org/docs/man1.1.1/man1/openssl.html>)

=item * L<Crypt::OpenSSL::X509|https://metacpan.org/pod/Crypt::OpenSSL::X509>

=item * L<Crypt::OpenSSL::RSA|https://metacpan.org/pod/Crypt::OpenSSL::RSA>

=item * L<Crypt::OpenSSL::Bignum|https://metacpan.org/pod/Crypt::OpenSSL::Bignum>

=item * L<OpenSSL.org|https://www.openssl.org/>

=item * L<Wikipedia: PKCS12|https://en.wikipedia.org/wiki/PKCS_12>

=item * L<RFC:7292: "PKCS #12: Personal Information Exchange Syntax v1.1"|https://datatracker.ietf.org/doc/html/rfc7292>

=back

=head1 INCOMPATIBILITIES

Currently the library has been updated to support both OpenSSL 1.X.X and OpenSSL 3.X.X

=head1 BUGS AND LIMITATIONS

Please see the L<GitHub repository|https://github.com/dsully/perl-crypt-openssl-pkcs12/issues> for known issues.

=head1 AUTHOR

=over

=item * Dan Sully, E<lt>daniel@cpan.orgE<gt>

=back

Current maintainer

maint/Makefile_header.PL  view on Meta::CPAN

use Config;
use Crypt::OpenSSL::Guess qw(openssl_lib_paths openssl_inc_paths);

my %args = (
  LIBS => [openssl_lib_paths().' -lssl -lcrypto'],
  INC => openssl_inc_paths(),
);

my $cc_option_flags = " -O2 -g";
my $cc_defines      = '';

if ($Config::Config{cc} =~ /gcc/i) {
  $cc_option_flags .= $ENV{AUTHOR_TESTING} ? ' -Wall -Werror' : ' -Wall';
} else {
  $cc_option_flags .= '';
}

maint/Makefile_header.PL  view on Meta::CPAN


  if ($Config{perl_version} <= 20) {
    $cc_option_flags .= ' -Wno-error=pointer-bool-conversion';
  }
}

if ($Config{myuname} =~ /sunos|solaris/i) {
  $args{OPTIMIZE} = $cc_option_flags;
} elsif ($Config{myuname} =~ /strawberry-{0,1}perl/i) {
  if ($Config{PERL_VERSION} <= 24) {
    $args{LIBS} = [openssl_lib_paths() . ' -leay32'];
  }
  $cc_defines .= ' -DOPENSSL_NO_SCRYPT';
  $args{DEFINE} = $cc_defines;
} elsif ($Config{myuname} =~ /darwin/ ) {
  $args{LDDLFLAGS} = openssl_lib_paths() . ' ' . $Config{lddlflags};
} else {
  $args{LDDLFLAGS} = openssl_lib_paths() . ' ' . $Config{lddlflags};
  $args{OPTIMIZE} = $cc_option_flags;
}

# HACK HACK HACK - dakkar 2024-09-26
#
# we need to cheat a lot to get MakeMaker to build a Makefile that
# will build the correct XS library... here, I tell *only this part*
# of the MakeMaker process, that we are really Crypt::OpenSSL::PKCS12,
# and not the Alt::*
#

ppport.h  view on Meta::CPAN

    # On early perls, the implicit pass by reference doesn't work, so we have
    # to use the globals to initialize.
    eval q[sub dictionary_order($$) { _dictionary_order($a, $b) } ];
  } elsif ("$]" < "5.022" ) {
    eval q[sub dictionary_order($$) { _dictionary_order(@_) } ];
  } else {
    eval q[sub dictionary_order :prototype($$) { _dictionary_order(@_) } ];
  }
}

sub _dictionary_order { # Sort caselessly, ignoring punct
    my ($valid_a, $valid_b) = @_;

    my ($lc_a, $lc_b);
    my ($squeezed_a, $squeezed_b);

    $valid_a = '' unless defined $valid_a;
    $valid_b = '' unless defined $valid_b;

    $lc_a = lc $valid_a;
    $lc_b = lc $valid_b;

ppport.h  view on Meta::CPAN

LOOKBEHIND_END_t8_pb|||Viu
LOOKBEHIND_END_t8|||Viu
LOOKBEHIND_END_tb_p8|||Viu
LOOKBEHIND_END_tb_pb|||Viu
LOOKBEHIND_END_tb|||Viu
LOOKBEHIND_END|||Viu
looks_like_bool|5.027008||Viu
looks_like_number|5.003007|5.003007|
LOOP_PAT_MODS|5.009005||Viu
lop|5.005000||Viu
lossless_NV_to_IV|5.031001||Vniu
LOWEST_ANYOF_HRx_BYTE|5.031002||Viu
L_R_TZSET|5.009005|5.009005|Vn
lsbit_pos32|5.035003||cVnu
lsbit_pos|5.035004||Viu
lsbit_pos64|5.035003||cVnu
lsbit_pos_uintmax|5.035003||Viu
lseek|5.005000||Viu
LSEEKSIZE|5.006000|5.006000|Vn
lstat|5.005000||Viu
LvFLAGS|5.015006||Viu

t/00-openssl-version.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;

use Crypt::OpenSSL::Guess qw/openssl_version find_openssl_prefix find_openssl_exec/;

my ($major, $minor, $patch) = openssl_version();

$patch = defined $patch ? $patch : "";

ok($major, "Found OpenSSL version");
#diag("OpenSSL version: $major.$minor $patch\n");

my $prefix = find_openssl_prefix();
my $ssl_exec = find_openssl_exec($prefix);

my $ssl_version_string = `$ssl_exec version`;

diag(`$ssl_exec version`);

done_testing;

t/pkcs12-from-scratch.t  view on Meta::CPAN

use strict;
use warnings;

use Test::More tests => 30;
use File::Spec::Functions qw(:ALL);
use Data::Dumper;
use Crypt::OpenSSL::Guess;
use Crypt::OpenSSL::PKCS10 qw( :const );

my ($major, $minor, $patch) = openssl_version();

my $req = Crypt::OpenSSL::PKCS10->new;
$req->set_subject("/C=RO/O=UTI/OU=ssi");
$req->add_ext(Crypt::OpenSSL::PKCS10::NID_key_usage,"critical,digitalSignature,keyEncipherment");
$req->add_ext(Crypt::OpenSSL::PKCS10::NID_ext_key_usage,"serverAuth, nsSGC, msSGC, 1.3.4");
$req->add_ext(Crypt::OpenSSL::PKCS10::NID_subject_alt_name,"email:steve\@openssl.org");
$req->add_ext_final();
$req->sign();
$req->write_pem_req('t/scratch-csr.pem');
$req->write_pem_pk('t/scratch-key.pem');

#my $cert_result = `openssl x509 -req -signkey t/scratch-key.pem -in t/scratch-csr.pem -out t/scratch-cert.pem -CAcreateserial -days 365 -sha256`;
my $prefix = find_openssl_prefix();
my $pkcs12_result = `$prefix/bin/openssl pkcs12 -export -out certs/scratch-pkcs12.p12 -inkey certs/test-key.pem -in certs/test-cert.pem -certfile certs/test-ca.pem -passout pass:testing`;
#my $out = system("openssl pkcs12 -export -out certs/scratch-pkcs12.p12 -inkey certs/test-key.pem -in certs/test-cert.pem -passout pass:testing");

unlink 't/scratch-cert.pem';
unlink 't/scratch-csr.pem';
unlink 't/scratch-key.pem';

BEGIN { use_ok('Crypt::OpenSSL::PKCS12') };

{
    my $certdata = "тест";
    is length $certdata, 8;

t/pkcs12-from-scratch.t  view on Meta::CPAN


my $pemkey = $pkcs12->private_key($pass);

ok($pemkey, 'Asserting PEM key');

ok($pkcs12->mac_ok($pass), 'Asserting mac');

ok($pkcs12->as_string, 'Asserting PKCS12 as string');

SKIP: {
    # https://github.com/openssl/openssl/issues/19092
    if ($major =~ /^3\./) {
        skip("OpenSSL 3.x cannot change pkcs12 passwords", 3);
    } else {
        # try changing the password
        ok($pkcs12->changepass($pass, 'foo'), 'Changing password');

        ok($pkcs12->mac_ok('foo'), 'Reasserting mac');

        ok($pkcs12->changepass('foo', $pass), 'Changing password again');
    }

t/pkcs12-info-arbitrary-bag-attributes.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;
use Digest::SHA qw/sha256_hex/;
use Crypt::OpenSSL::Guess qw/openssl_version find_openssl_prefix find_openssl_exec/;

my ($major, $minor, $patch) = openssl_version();
BEGIN { use_ok('Crypt::OpenSSL::PKCS12') };
my $openssl_output =<< 'OPENSSL_END';
MAC: sha1, Iteration 100000
MAC length: 20, salt length: 20
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
Bag Attributes
    friendlyName: wile e coyote
    localKeyID: 54 69 6D 65 20 31 36 35 39 38 30 32 39 34 31 36 33 32 
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCP18SdkO7OL1I3

t/pkcs12-info-arbitrary-bag-attributes.t  view on Meta::CPAN

YCOmZv9yiDFR0bXVqx8YqmVEIy9pYBtJbEzB73efOXQDmNOb1+hpD5LBiOPE3jf2
AUgzUwsJ9f3uXqTDQc7suhHOrUNNcQxW2OsJuo3FnsipfJ//Uty1PNExwf/3w7yT
Ueg7KSbfS3UQVJITCHQuTS2vjZWsNOMHQ7RxfJUCgYEAjyu2b6Lzae8ZDUSHbeBP
faZHOjkkUK2W8Ee3xGNBAmArnJp+yx0BLa6ZD2xWX3NAeGtRJK/l/lgYsb7/kAvi
iS81NOQKkH8bC2SfqRkrlUjgGnYz2DVhQrbHw/BuiaIffqeY19WPSjyH1f9GPgog
NnkSzXchhFTmhMqqxQ1wlPc=
-----END PRIVATE KEY-----
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
Certificate bag
Bag Attributes
    friendlyName: ssl.com ev root certification authority rsa r2
    2.16.840.1.113894.746875.1.1: <Unsupported tag 6>
subject=C = US, ST = Texas, L = Houston, O = SSL Corporation, CN = SSL.com EV Root Certification Authority RSA R2
issuer=C = US, ST = Texas, L = Houston, O = SSL Corporation, CN = SSL.com EV Root Certification Authority RSA R2
-----BEGIN CERTIFICATE-----
MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV
BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE
CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy
dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy
MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G
A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD

t/pkcs12-info-arbitrary-bag-attributes.t  view on Meta::CPAN

BAYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUF
BwMJBgorBgEEAYI3FAICBgRVHSUAMA0GCSqGSIb3DQEBCwUAA4IBAQAW02o5QNdq
Rwd5te62ZW4dslBwO6ibzY1FtSqwC9ZUk0Mpfk2OMaM1jIePG0y0Sw4RKDBp+oH1
LMcN4AgrnOEVA87xwoOJrtZ8EGtSbYF/UQVZR0jXLV7f/Xr7XiDBh0lnsMlQKAu8
P8Y+hgY/lEKJ/Kb2uUz/ci3ZkTlu5XqOQmi3ChwcAMPLR3XCPP9NgAv3jhv/OvSF
7CC3FFndvnQmb1OMpndYh9foJzgFReVEMk0DKRa/1Xz1GNsjHJNpEEOdwo1qEuN/
/mfhK4REoKOunLGlI3vMjXKrD/V0JYAWASYDng7FrUHec4glOqwiQI/T4du6dvQf
SLUzQIGHRMDH
-----END CERTIFICATE-----
OPENSSL_END
my $prefix = find_openssl_prefix();
my $ssl_exec = find_openssl_exec($prefix);
my $ssl_version_string = `$ssl_exec version`;

if ($major eq '1.0' && $ssl_version_string !~ /LibreSSL/) {
  $openssl_output =~ s/MAC: sha1, Iteration 10000/MAC Iteration 10000/g;
  $openssl_output =~ s/MAC length: .*/MAC verified OK/;
}
if ($major ge '3.2' && $ssl_version_string !~ /LibreSSL/) {
  $openssl_output =~ s/2.16.840.1.113894.746875.1.1/Trusted key usage (Oracle)/g;
}

my $pass   = "1234";
my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_file('certs/test.pfx');

my $info = $pkcs12->info($pass);

ok(sha256_hex($info) eq sha256_hex($openssl_output), "Output matches OpenSSL");

my $info_hash = $pkcs12->info_as_hash($pass);

if ($major gt '1.0') {
  like($info_hash->{mac}{digest}, qr/sha1/, "MAC Digest is sha1");
  like($info_hash->{mac}{length}, qr/20/, "MAC length is 20");
  like($info_hash->{mac}{salt_length}, qr/20/, "MAC salt_length is 20");
}

like($info_hash->{mac}{iteration}, qr/10000/, "MAC Iteration is 10000");

t/pkcs12-info-arbitrary-bag-attributes.t  view on Meta::CPAN


  like(@$bags[0]->{cert}, qr/CERTIFICATE/, "pkcs7_encrypted_data found certificate");

  my $num = 2;
  if ($major ge '3.1') {
      $num = 2;
  }
  is(keys %$bag_attributes, $num, "  Number of bag attributes in bag match");
  foreach my $attribute (keys %$bag_attributes) {
        like($bag_attributes->{'Trusted key usage (Oracle)'}, qr/<Unsupported tag 6>/, "    Trusted key usage (Oracle) matches") if $attribute eq "Trusted key usage (Oracle)";
        like($bag_attributes->{friendlyName}, qr/ssl.com ev root certification authority rsa r2/, "    friendlyName matches") if $attribute eq "friendlyName";
  }

  like(@$bags[0]->{cert}, qr/VSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg/, "  pkcs7_encrypted_data key matches");
  like(@$bags[0]->{type}, qr/certificate_bag/, "  pkcs7_encrypted_data bag type matches");

  like(@$bags[0]->{issuer}, qr/C = US, ST = Texas, L = Houston, O = SSL Corporation, CN = SSL.com EV Root Certification Authority RSA R2/, "  pkcs7_encrypted_data issuer matches");
  like(@$bags[0]->{subject}, qr/C = US, ST = Texas, L = Houston, O = SSL Corporation, CN = SSL.com EV Root Certification Authority RSA R2/, "  pkcs7_encrypted_data subject matches");

  $bag_attributes = @$bags[1]->{bag_attributes};

t/pkcs12-info-key-bag.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;
use Digest::SHA qw/sha256_hex/;
use Crypt::OpenSSL::Guess qw/openssl_version/;

my ($major, $minor, $patch) = openssl_version();
BEGIN { use_ok('Crypt::OpenSSL::PKCS12') };
my $openssl_output =<< 'OPENSSL_END';
MAC: sha256, Iteration 2048
MAC length: 32, salt length: 8
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
Certificate bag
Bag Attributes
    localKeyID: B2 36 02 16 22 C6 18 EF B1 5B D0 69 DB CD 25 B9 89 62 5D 94 
subject=C = CA, ST = New Brunswick, L = Moncton, O = Crypt::OpenSSL::PKCS12, CN = Crypt::OpenSSL::PKCS12
issuer=C = CA, ST = New Brunswick, L = Moncton, O = Crypt::OpenSSL::PKCS12, CN = Crypt::OpenSSL::PKCS12
-----BEGIN CERTIFICATE-----
MIIF0zCCA7ugAwIBAgIUNRGGesA4c//y3afo9bFyNDSNF18wDQYJKoZIhvcNAQEL

t/pkcs12-info-key-bag.t  view on Meta::CPAN

9eGM0sArB/L4U/cBbzHF8l9/JM/f/Jy3jPMXm2CgHHN77JozgdMCuTk8P8kTTsFw
sYkCggEBAOzK9ySOcHzC6Oz5Y2l5y/hkyicVu07iXFJiUYbpyAx3qrUF+19SaVV1
vyIdxJCXdolFLNkK4hDLz4Y3zXZfJR3Gl1AGNQr9OyYnx1JoPUhVT1mgnLfONTPK
sxwdpf6W+B4etSiZPoomkoWs2rR8hHUh9gLv/2SbmaGOW0dknQ/gJ26qu4VX+kqq
/21lMgINUthroQThJiRj2XT+x906IPZ+LP+q2S0bwBizv15dq3jymaaZ9iJN3U3F
hTos7Fbfu48vwE86PnHJ0B7MNu7uCPmFtkAszCbyncplcYKLaBUQuC90gJ/5cUjE
4U5P3ZCBWZcIHhRZJ3R1KYinfNU3gNI=
-----END PRIVATE KEY-----
OPENSSL_END
if ($major eq '1.0') {
  $openssl_output =~ s/MAC: sha.*, Iteration 2048/MAC Iteration 2048/g;
  $openssl_output =~ s/MAC length: .*/MAC verified OK/;
}

my $pass   = "testing";
my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_file('certs/keyStore.p12');

my $info = $pkcs12->info($pass);

ok(sha256_hex($info) eq sha256_hex($openssl_output), "Output matches OpenSSL");

my $info_hash = $pkcs12->info_as_hash($pass);

if ($major gt '1.0') {
  like($info_hash->{mac}{digest}, qr/sha256/, "MAC Digest is sha256");
  like($info_hash->{mac}{length}, qr/32/, "MAC length is 32");
  like($info_hash->{mac}{salt_length}, qr/8/, "MAC salt_length is 8");
}

like($info_hash->{mac}{iteration}, qr/2048/, "MAC Iteration is 2048");

t/pkcs12-info-le_1.1.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;
use Digest::SHA qw/sha256_hex/;
use Crypt::OpenSSL::Guess qw/openssl_version/;

my ($major, $minor, $patch) = openssl_version();
BEGIN { use_ok('Crypt::OpenSSL::PKCS12') };
my $openssl_output =<< 'OPENSSL_END';
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
Bag Attributes
    localKeyID: CD 93 42 14 8F 01 1B D4 CB C7 11 42 E7 32 15 DE 17 DE 39 07 
    friendlyName: Test PKCS12
subject=C = US, ST = California, O = ElectricRain, CN = test.electricrain.com
issuer=C = US, ST = California, L = Daly City, O = ElectricRain, CN = test.electricrain.com
-----BEGIN CERTIFICATE-----

t/pkcs12-info-le_1.1.t  view on Meta::CPAN

HlUPI36CBIoHbZRM/l2Zg4sbAXJkGdBmQR3wJdn7x8/fAkEAyJQIcPIPlLsbuh6X
/n6rz7T6ZellpPR2Li0XzUmvZsUBMeWbupVjQ6fXTxmwE/he4KZq/dFfyFkD/wRO
Jg7EaQJABKvmQSkvDnGM4IvtzNGcur+ol89p3K88ewRu9VEwk8XQHwCsdpE0js6O
u09wpKYUduQEHif0upFD3XJkES6TzwJADA76QvAKh8KH9DSKpr4uzhnvQ9k4RyZ7
RGNpnunjJaaKX9mR9zGr+hFJHHRK5ah068SVghToUT8owlgb6qXQoQJBAKG7DquK
edjrMOH641LwWMcQSK3FhAQbt4qUUytEdSEYTy4ObpScWrxEt67lcWu4yIJxu7e4
0HErfonOx1g+Ox0=
-----END PRIVATE KEY-----
OPENSSL_END
if ($major eq '1.0') {
  $openssl_output =~ s/MAC: sha1, Iteration 2048/MAC Iteration 2048/g;
  $openssl_output =~ s/MAC length: .*/MAC verified OK/;
}
my $pass   = "testing";
#my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_file('certs/test.p12');
my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_file('certs/test_le_1.1.p12');

SKIP: {
    if (! $pkcs12->legacy_support) {
        skip("The Legacy provider cannot be loaded.  Unable to process Legacy PKCS12 files", 5);
    }
#my $certificate = $pkcs12->certificate($pass);

my $info = $pkcs12->info($pass);

ok(sha256_hex($info) eq sha256_hex($openssl_output), "Output matches OpenSSL");

my $info_hash = $pkcs12->info_as_hash($pass);

if ($major gt '1.0') {
  like($info_hash->{mac}{digest}, qr/sha1/, "MAC Digest is sha1");
  like($info_hash->{mac}{length}, qr/20/, "MAC length is 20");
  like($info_hash->{mac}{salt_length}, qr/8/, "MAC salt_length is 8");
}

like($info_hash->{mac}{iteration}, qr/2048/, "MAC Iteration is 2048");

t/pkcs12-info-multiple-pkcs7-sections.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;
use Digest::SHA qw/sha256_hex/;
use Crypt::OpenSSL::Guess qw/openssl_version find_openssl_prefix find_openssl_exec/;

my ($major, $minor, $patch) = openssl_version();
BEGIN { use_ok('Crypt::OpenSSL::PKCS12') };
my $openssl_output =<< 'OPENSSL_END';
MAC: sha1, Iteration 2000
MAC length: 20, salt length: 20
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2000
Bag Attributes
    localKeyID: 01 00 00 00 
    friendlyName: 3f71af65-1687-444a-9f46-c8be194c3e8e
    Microsoft CSP Name: Microsoft Enhanced Cryptographic Provider v1.0
Key Attributes
    X509v3 Key Usage: 10 

t/pkcs12-info-multiple-pkcs7-sections.t  view on Meta::CPAN

b3VzQHdpbmRvd3MteAAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAuH7i
qY0/MLozwFb39ILYAJDHE+HToZBQbHQP4YtienrUStk60rIp0WH65lam7m/JhgAc
Itc/tV1L8mEnLrvvKcA+NeIL8sDOtM28azvgcOi0P3roeLLLRCuiykUaKmUcZEDm
9cDYKIpJf7QetWQ3uuGTk9iRzpH79x2ix35BnyWQRr3INZzmX/+9YRvPBXKYl/89
F/w1ORYArpI9XtjfuPWaGQmM4f1WRHE2t3qRyKFFri7QiZdpcSx5zvsRHSyjfUMo
Ks+b6upk+P01lIhg/ewwYngGab+fZhF15pTNN2hx8PdNGcrGzrkNKCmJKrWCa2xc
zuMA+z8SCuC1tYTKmA==
-----END CERTIFICATE-----
OPENSSL_END
if ($major eq '1.0') {
  $openssl_output =~ s/MAC: sha1, Iteration 2000/MAC Iteration 2000/g;
  $openssl_output =~ s/MAC length: .*/MAC verified OK/;
}

my $prefix = find_openssl_prefix();
my $ssl_exec = find_openssl_exec($prefix);
my $ssl_version_string = `$ssl_exec version`;

SKIP: {

    skip ("Pre OpenSSL 1.1.0 release does not support utf8 passwords", 20) if ($major le '1.0');

    skip("LibreSSL does not support UTF8 passwords", 15) if ($ssl_version_string =~ /LibreSSL/);

my $pass   = "σύνθημα γνώρισμα";
my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_file('certs/shibboleth.pfx');

my $info = $pkcs12->info($pass);
ok(sha256_hex($info) eq sha256_hex($openssl_output), "Output matches OpenSSL");

my $info_hash = $pkcs12->info_as_hash($pass);

if ($major gt '1.0') {
  like($info_hash->{mac}{digest}, qr/sha1/, "MAC Digest is sha1");
  like($info_hash->{mac}{length}, qr/20/, "MAC length is 20");
  like($info_hash->{mac}{salt_length}, qr/20/, "MAC salt_length is 20");
}

like($info_hash->{mac}{iteration}, qr/2000/, "MAC Iteration is 2000");

t/pkcs12-info-openssl-81-test_cmp_cli.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;
use Digest::SHA qw/sha256_hex/;
use Crypt::OpenSSL::Guess qw/openssl_version/;

my ($major, $minor, $patch) = openssl_version();
BEGIN { use_ok('Crypt::OpenSSL::PKCS12') };
my $openssl_output =<< 'OPENSSL_END';
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
Certificate bag
Bag Attributes
    localKeyID: CF 6B 1F EF D7 B4 D2 96 04 94 60 F6 29 16 75 3A E3 C8 5D 9F 
subject=C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = leaf
issuer=C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = subinterCA
-----BEGIN CERTIFICATE-----
MIIDfjCCAmagAwIBAgIJAKRNsDKacUqNMA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNV

t/pkcs12-info-openssl-81-test_cmp_cli.t  view on Meta::CPAN

J27DjPbyYBA9sFVtQaSKo9V8Jre+FRigu+2dRkKxegYXcJUEnJ2kYXNcjQKBgQC2
3cmDvY+gzxhkSKYjRHjrYXjEdeURi0Tq2MkL68b99Trk/grD6KOslC/13pgRf5Gx
xd2DnVuMsmXk6+4BK2ikIs5kE9HcSL5uhsVE2RbiDJhkctJzompmptKim41iR4Q0
Qq/K48W9bd/kXE8lvGRuL1R1kIqUERcCH84gwat6BwKBgELxtLvOToo0PLyra4L+
b+DotEzGlvwbiOytwujK4mzfMNyQGNC4slAg4xdxAFY3WH4Mp6QXZ5yvd8kAnIS/
ilTgK3av9lNgUx0lPIBuPDSao6NRHiex06G3+8Ju3RBbcddhNxV0KcWoG16UqcjX
YqgLSMA70QAkZnqQT83Abp1C
-----END PRIVATE KEY-----
OPENSSL_END
if ($major eq '1.0') {
  $openssl_output =~ s/MAC: sha1, Iteration 2048/MAC Iteration 2048/g;
  $openssl_output =~ s/MAC length: .*/MAC verified OK/;
}
my $pass   = "12345";
my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_file('certs/signer.p12');

my $info = $pkcs12->info($pass);

ok(sha256_hex($info) eq sha256_hex($openssl_output), "Output matches OpenSSL");

my $info_hash = $pkcs12->info_as_hash($pass);

if ($major gt '1.0') {
  like($info_hash->{mac}{digest}, qr/sha1/, "MAC Digest is sha1");
  like($info_hash->{mac}{length}, qr/20/, "MAC length is 20");
  like($info_hash->{mac}{salt_length}, qr/8/, "MAC salt_length is 8");
}

like($info_hash->{mac}{iteration}, qr/2048/, "MAC Iteration is 2048");

t/pkcs12-info-safe-contents-bag.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;
use Digest::SHA qw/sha256_hex/;
use Crypt::OpenSSL::Guess qw/openssl_version/;

my ($major, $minor, $patch) = openssl_version();
BEGIN { use_ok('Crypt::OpenSSL::PKCS12') };
my $openssl_output =<< 'OPENSSL_END';
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 20
PKCS7 Data
Safe Contents bag
Bag Attributes: <No Attributes>
Certificate bag
Bag Attributes
    localKeyID: 01 
subject=CN = RSAKeyTransferCapi1
issuer=CN = RSAKeyTransferCapi1

t/pkcs12-info-safe-contents-bag.t  view on Meta::CPAN

cjEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMrQRt46f23Hj8Wk4B0ffZDb
WW9YYzTVcIrsuOUta7kSwLXsljOoK0q6xMKGDHZvL98ckFxKcqVK39BBravl8q/R
4q2IYVlw6BjcPU0Au2xM6UxetOPv7dgNFMPSlepHGuQwy7ILBxWC8TljafvpDBSq
X4W447FAEdgfvUHssUldAgMBAAGjDzANMAsGA1UdDwQEAwIFIDANBgkqhkiG9w0B
AQsFAAOBgQC67Spa4tEe5CCcBpTHkOcuPorTELJQayd9fAAbCfZg1I26hGrFu++X
ZTYTrfU9diT8myszfyXLM3QieQDP774v2skrT3ac8r8777SF8oKoW/sJRUt5fOUo
beVgwhn7Ddb84EQq2/7092fprIHPPpcBuvge/HOg7YhXat/xJBO4Jw==
-----END CERTIFICATE-----
OPENSSL_END
if ($major eq '1.0') {
  $openssl_output =~ s/MAC: sha1, Iteration 2048/MAC Iteration 2048/g;
  $openssl_output =~ s/MAC length: .*/MAC verified OK/;
}

SKIP: {

    skip ("Pre OpenSSL 1.1.0h release cannot parse this p12 file", 22) if ($major le '1.0' or ($major le '1.1' and $patch lt 'h'));
 
my $pass   = "hi";
my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_file('certs/safe_contents.p12');

my $info = $pkcs12->info($pass);

ok(sha256_hex($info) eq sha256_hex($openssl_output), "Output matches OpenSSL");

my $info_hash = $pkcs12->info_as_hash($pass);

if ($major gt '1.0') {
  like($info_hash->{mac}{digest}, qr/sha1/, "MAC Digest is sha1");
  like($info_hash->{mac}{length}, qr/20/, "MAC length is 20");
  like($info_hash->{mac}{salt_length}, qr/20/, "MAC salt_length is 208");
}

like($info_hash->{mac}{iteration}, qr/2048/, "MAC Iteration is 2048");

t/pkcs12-info-secret-bag.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;
use Digest::SHA qw/sha256_hex/;
use Crypt::OpenSSL::Guess qw/openssl_version find_openssl_prefix find_openssl_exec/;

my ($major, $minor, $patch) = openssl_version();
BEGIN { use_ok('Crypt::OpenSSL::PKCS12') };
my $openssl_output =<< 'OPENSSL_END';
MAC: sha1, Iteration 1000
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 1000
Secret bag
Bag Attributes
    localKeyID: 31 32 33 34 35 36 37 38 39 30 
    1.2.3.4.5: MyCustomAttribute
    friendlyName: george
Bag Type: 1.3.5.7.9
Bag Value: 56 65 72 79 53 65 63 72 65 74 4D 65 73 73 61 67 65 
OPENSSL_END

if ($major eq '1.0') {
  $openssl_output =~ s/MAC: sha1, Iteration 2048/MAC Iteration 2048/g;
  $openssl_output =~ s/MAC length: .*/MAC verified OK/;
}

my $prefix = find_openssl_prefix();
my $ssl_exec = find_openssl_exec($prefix);
my $ssl_version_string = `$ssl_exec version`;

SKIP: {

    skip ("Pre OpenSSL 3.0.0 release secret bags unsupported", 22) if ($major lt '3.0');
    skip ("LibreSSL does not support secret bags", 22) if ($ssl_version_string =~ /LibreSSL/);

my $pass   = "Password1";
my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_file('certs/secretbag.p12');

my $info = $pkcs12->info($pass);

ok(sha256_hex($info) eq sha256_hex($openssl_output), "Output matches OpenSSL");

my $info_hash = $pkcs12->info_as_hash($pass);

if ($major gt '1.0') {
  like($info_hash->{mac}{digest}, qr/sha1/, "MAC Digest is sha1");
  like($info_hash->{mac}{length}, qr/20/, "MAC length is 20");
  like($info_hash->{mac}{salt_length}, qr/8/, "MAC salt_length is 8");
}

like($info_hash->{mac}{iteration}, qr/1000/, "MAC Iteration is 1000");

t/pkcs12-info-v3-certs-RC2.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;
use Digest::SHA qw/sha256_hex/;
use Crypt::OpenSSL::Guess qw/openssl_version/;

SKIP: {

skip ("PKCS12 files has a certificate date that cannot be parsed in some LibreSSL versions", 24) unless $ENV{AUTHOR_TESTING};

my ($major, $minor, $patch) = openssl_version();
BEGIN { use_ok('Crypt::OpenSSL::PKCS12') };
my $openssl_output =<< 'OPENSSL_END';
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
Bag Attributes: <No Attributes>
subject=C = US, O = National Aeronautics and Space Administration, serialNumber = 16 + CN = Steve Schoch
issuer=C = US, O = National Aeronautics and Space Administration
-----BEGIN CERTIFICATE-----
MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx
NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz

t/pkcs12-info-v3-certs-RC2.t  view on Meta::CPAN

AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK
Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x
DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR
MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB
AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21
X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3
WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO
-----END CERTIFICATE-----
Certificate bag
Bag Attributes: <No Attributes>
subject=emailAddress = cooke@issl.atl.hp.com, C = US, OU = Hewlett Packard Company (ISSL), CN = Paul A. Cooke
issuer=C = Ca, L = Nepean, OU = No Liability Accepted, O = For Demo Purposes Only, CN = Entrust Demo Web CA
-----BEGIN CERTIFICATE-----
MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD
YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0
ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu
dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1
WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV
BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx
FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA
6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT
G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ
YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm
b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc
F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz
lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap
jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU=
-----END CERTIFICATE-----
OPENSSL_END
if ($major eq '1.0') {
  $openssl_output =~ s/MAC: sha1, Iteration 2048/MAC Iteration 2048/g;
  $openssl_output =~ s/MAC length: .*/MAC verified OK/;
}
my $pass   = "v3-certs";
my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_file('certs/v3-certs-RC2.p12');

SKIP: {
    if (! $pkcs12->legacy_support) {
        skip("The Legacy provider cannot be loaded.  Unable to process Legacy PKCS12 files", 5);
    }

my $info = $pkcs12->info($pass);
ok(sha256_hex($info) eq sha256_hex($openssl_output), "Output matches OpenSSL");

my $info_hash = $pkcs12->info_as_hash($pass);

if ($major gt '1.0') {
  like($info_hash->{mac}{digest}, qr/sha1/, "MAC Digest is sha1");
  like($info_hash->{mac}{length}, qr/20/, "MAC length is 20");
  like($info_hash->{mac}{salt_length}, qr/8/, "MAC salt_length is 8");
}

like($info_hash->{mac}{iteration}, qr/2048/, "MAC Iteration is 2048");

t/pkcs12-info-v3-certs-RC2.t  view on Meta::CPAN

  like(@$bags[0]->{type}, qr/certificate_bag/, "pkcs7_encrypted_data bag type matches");

  like(@$bags[0]->{issuer}, qr/C = US, O = National Aeronautics and Space Administration/, "pkcs7_encrypted_data issuer matches");
  like(@$bags[0]->{subject}, qr/C = US, O = National Aeronautics and Space Administration, serialNumber = 16 \+ CN = Steve Schoch/, "pkcs7_encrypted_data subject matches");

  like(@$bags[1]->{cert}, qr/CERTIFICATE/, "pkcs7_encrypted_data found certificate 1");
  like(@$bags[1]->{cert}, qr/dWwgQS4gQ29va2UwXDANBgkqhkiG9w0B/, "pkcs7_encrypted_data key matches");
  like(@$bags[1]->{type}, qr/certificate_bag/, "pkcs7_encrypted_data bag type matches");

  like(@$bags[1]->{issuer}, qr/C = Ca, L = Nepean, OU = No Liability Accepted, O = For Demo Purposes Only, CN = Entrust Demo Web CA/, "pkcs7_encrypted_data issuer matches");
  like(@$bags[1]->{subject}, qr/emailAddress = cooke\@issl.atl.hp.com, C = US, OU = Hewlett Packard Company \(ISSL\), CN = Paul A. Cooke/, "pkcs7_encrypted_data subject matches");


  $bag_attributes = @$bags[1]->{bag_attributes};
  is(keys %$bag_attributes, 0, "Zero bag attributes in bag");
}
}
}
done_testing;

t/pkcs12-info-v3-certs-TDES.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;
use Digest::SHA qw/sha256_hex/;
use Crypt::OpenSSL::Guess qw/openssl_version find_openssl_prefix find_openssl_exec/;

my ($major, $minor, $patch) = openssl_version();
BEGIN { use_ok('Crypt::OpenSSL::PKCS12') };
my $openssl_output =<< 'OPENSSL_END';
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
Certificate bag
Bag Attributes: <No Attributes>
subject=C = US, O = National Aeronautics and Space Administration, serialNumber = 16 + CN = Steve Schoch
issuer=C = US, O = National Aeronautics and Space Administration
-----BEGIN CERTIFICATE-----
MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx
NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz

t/pkcs12-info-v3-certs-TDES.t  view on Meta::CPAN

AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK
Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x
DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR
MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB
AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21
X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3
WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO
-----END CERTIFICATE-----
Certificate bag
Bag Attributes: <No Attributes>
subject=emailAddress = cooke@issl.atl.hp.com, C = US, OU = Hewlett Packard Company (ISSL), CN = Paul A. Cooke
issuer=C = Ca, L = Nepean, OU = No Liability Accepted, O = For Demo Purposes Only, CN = Entrust Demo Web CA
-----BEGIN CERTIFICATE-----
MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD
YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0
ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu
dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1
WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV
BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx
FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA
6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT
G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ
YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm
b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc
F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz
lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap
jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU=
-----END CERTIFICATE-----
OPENSSL_END
if ($major eq '1.0') {
  $openssl_output =~ s/MAC: sha1, Iteration 2048/MAC Iteration 2048/g;
  $openssl_output =~ s/MAC length: .*/MAC verified OK/;
}
my $pass   = "v3-certs";
my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_file('certs/v3-certs-TDES.p12');

my $prefix = find_openssl_prefix();
my $ssl_exec = find_openssl_exec($prefix);

my $ssl_version_string = `$ssl_exec version`;

SKIP: {

    skip("LibreSSL bug unable to parse certificate date", 20) if ( $ssl_version_string =~ /LibreSSL/);

my $info = $pkcs12->info($pass);
ok(sha256_hex($info) eq sha256_hex($openssl_output), "Output matches OpenSSL");

my $info_hash = $pkcs12->info_as_hash($pass);

if ($major gt '1.0') {
  like($info_hash->{mac}{digest}, qr/sha1/, "MAC Digest is sha1");
  like($info_hash->{mac}{length}, qr/20/, "MAC length is 20");
  like($info_hash->{mac}{salt_length}, qr/8/, "MAC salt_length is 8");
}

like($info_hash->{mac}{iteration}, qr/2048/, "MAC Iteration is 2048");

t/pkcs12-info-v3-certs-TDES.t  view on Meta::CPAN

  like(@$bags[0]->{type}, qr/certificate_bag/, "pkcs7_encrypted_data bag type matches");

  like(@$bags[0]->{issuer}, qr/C = US, O = National Aeronautics and Space Administration/, "pkcs7_encrypted_data issuer matches");
  like(@$bags[0]->{subject}, qr/C = US, O = National Aeronautics and Space Administration, serialNumber = 16 \+ CN = Steve Schoch/, "pkcs7_encrypted_data subject matches");

  like(@$bags[1]->{cert}, qr/CERTIFICATE/, "pkcs7_encrypted_data found certificate 1");
  like(@$bags[1]->{cert}, qr/dWwgQS4gQ29va2UwXDANBgkqhkiG9w0B/, "pkcs7_encrypted_data key matches");
  like(@$bags[1]->{type}, qr/certificate_bag/, "pkcs7_encrypted_data bag type matches");

  like(@$bags[1]->{issuer}, qr/C = Ca, L = Nepean, OU = No Liability Accepted, O = For Demo Purposes Only, CN = Entrust Demo Web CA/, "pkcs7_encrypted_data issuer matches");
  like(@$bags[1]->{subject}, qr/emailAddress = cooke\@issl.atl.hp.com, C = US, OU = Hewlett Packard Company \(ISSL\), CN = Paul A. Cooke/, "pkcs7_encrypted_data subject matches");

  $bag_attributes = @$bags[1]->{bag_attributes};
  is(keys %$bag_attributes, 0, "Zero bag attributes in bag");
}
}
done_testing;

t/pkcs12-string.t  view on Meta::CPAN

        my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_string($certdata);
    };

    my $ok = $@ =~ /Source string must not be UTF-8 encoded/i;
    ok $ok, 'utf8 string refused in new_from_string()';
}

my $base   = 'certs';
my $pass   = 'testing';

my ($major, $minor, $patch) = openssl_version();

my $certfile;
if ($major le "1.1" )  {
    $certfile = catdir($base, 'test_le_1.1.p12');
} else {
    $certfile = catdir($base, 'test.p12');
}

diag("Attempting to read certificate string from file $certfile");

t/pkcs12-string.t  view on Meta::CPAN


my $pemkey = $pkcs12->private_key($pass);

ok($pemkey, 'Asserting PEM key');

ok($pkcs12->mac_ok($pass), 'Asserting mac');

ok($pkcs12->as_string, 'Asserting PKCS12 as string');

SKIP: {
    # https://github.com/openssl/openssl/issues/19092
    if ($major =~ /^3\./) {
        skip("OpenSSL 3.x cannot change pkcs12 passwords", 3);
    } else {
        # try changing the password
        ok($pkcs12->changepass($pass, 'foo'), 'Changing password');

        ok($pkcs12->mac_ok('foo'), 'Reasserting mac');

        ok($pkcs12->changepass('foo', $pass), 'Changing password again');
    }

t/pkcs12.t  view on Meta::CPAN

use Test::More tests => 17;
use File::Spec::Functions qw(:ALL);
use Data::Dumper;
use Crypt::OpenSSL::Guess;

BEGIN { use_ok('Crypt::OpenSSL::PKCS12') };

my $base   = 'certs';
my $pass   = 'testing';

my ($major, $minor, $patch) = openssl_version();

my $certfile;
if ($major le "1.1" )  {
    $certfile = catdir($base, 'test_le_1.1.p12');
} else {
    $certfile = catdir($base, 'test.p12');
}

diag("Attempting to read certificate from $certfile");

t/pkcs12.t  view on Meta::CPAN


my $pemkey = $pkcs12->private_key($pass);

ok($pemkey, 'Asserting PEM key');

ok($pkcs12->mac_ok($pass), 'Asserting mac');

ok($pkcs12->as_string, 'Asserting PKCS12 as string');

SKIP: {
    # https://github.com/openssl/openssl/issues/19092
    if ($major =~ /^3\./) {
        skip("OpenSSL 3.x cannot change pkcs12 passwords", 3);
    } else {
        # try changing the password
        ok($pkcs12->changepass($pass, 'foo'), 'Changing password');

        ok($pkcs12->mac_ok('foo'), 'Reasserting mac');

        ok($pkcs12->changepass('foo', $pass), 'Changing password again');
    }



( run in 0.981 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )