Sponsoring The Perl Toolchain Summit 2025: Help make this important event another success Learn more

use strict;
=encoding utf-8
=head1 NAME
Crypt::Perl::PK - Public-key cryptography logic
=head1 SYNOPSIS
#Will be an instance of the appropriate Crypt::Perl key class,
#i.e., one of:
#
# Crypt::Perl::RSA::PrivateKey
# Crypt::Perl::RSA::PublicKey
# Crypt::Perl::ECDSA::PrivateKey
# Crypt::Perl::ECDSA::PublicKey
# Crypt::Perl::Ed25519::PrivateKey
# Crypt::Perl::Ed25519::PublicKey
#
my $key_obj = Crypt::Perl::PK::parse_jwk( { .. } );
#Likewise. Feed it public or private, DER or PEM format,
#RSA or ECDSA.
my $key_obj = Crypt::Perl::PK::parse_key( $octet_string );
=head1 DISCUSSION
As of now there’s not much of interest to find here except
=cut
use Module::Load ();
sub parse_key {
my ($der_or_pem) = @_;
if (ref $der_or_pem) {
die Crypt::Perl::X::create('Generic', "Need unblessed octet string, not “$der_or_pem”!");
}
my $obj;
for my $alg ( qw( RSA Ed25519 ECDSA ) ) {
my $module = "Crypt::Perl::$alg\::Parse";
Module::Load::load($module);
try {
$obj = $module->can('private')->($der_or_pem);
}
catch {
try {
$obj = $module->can('public')->($der_or_pem);
}
};
return $obj if $obj;
}
die Crypt::Perl::X::create('Generic', "Unrecognized key: “$der_or_pem”");
}
sub parse_jwk {
my ($hr) = @_;
if ('HASH' ne ref $hr) {
die( (caller 0)[3] . " needs a HASH reference, not $hr" );
}
my $kty = $hr->{'kty'};
if ($kty) {
my $module;
if ($kty eq 'RSA') {
$module = 'Crypt::Perl::RSA::Parse';
}
elsif ($kty eq 'OKP') {
if ($hr->{'crv'} ne 'Ed25519') {
die Crypt::Perl::X::create('Generic', "Unrecognized “crv” ($hr->{'crv'}) for key type “$kty”!");
}
$module = 'Crypt::Perl::Ed25519::Parse';
}
elsif ($kty eq 'EC') {
$module = 'Crypt::Perl::ECDSA::Parse';
}
else {
die Crypt::Perl::X::create('UnknownJWKkty', $kty);
}
Module::Load::load($module);
return $module->can('jwk')->($hr);
}
die Crypt::Perl::X::create('InvalidJWK', %$hr);
}
1;