1package Crypt::Perl::PK; 2 3use strict; 4use warnings; 5 6=encoding utf-8 7 8=head1 NAME 9 10Crypt::Perl::PK - Public-key cryptography logic 11 12=head1 SYNOPSIS 13 14 #Will be an instance of the appropriate Crypt::Perl key class, 15 #i.e., one of: 16 # 17 # Crypt::Perl::RSA::PrivateKey 18 # Crypt::Perl::RSA::PublicKey 19 # Crypt::Perl::ECDSA::PrivateKey 20 # Crypt::Perl::ECDSA::PublicKey 21 # Crypt::Perl::Ed25519::PrivateKey 22 # Crypt::Perl::Ed25519::PublicKey 23 # 24 my $key_obj = Crypt::Perl::PK::parse_jwk( { .. } ); 25 26 #Likewise. Feed it public or private, DER or PEM format, 27 #RSA or ECDSA. 28 my $key_obj = Crypt::Perl::PK::parse_key( $octet_string ); 29 30=head1 DISCUSSION 31 32As of now there’s not much of interest to find here except 33parsing of L<JWK|https://tools.ietf.org/html/rfc7517>s. 34 35=cut 36 37use Try::Tiny; 38 39use Module::Load (); 40 41use Crypt::Perl::X (); 42 43sub parse_key { 44 my ($der_or_pem) = @_; 45 46 if (ref $der_or_pem) { 47 die Crypt::Perl::X::create('Generic', "Need unblessed octet string, not “$der_or_pem”!"); 48 } 49 50 my $obj; 51 52 for my $alg ( qw( RSA Ed25519 ECDSA ) ) { 53 my $module = "Crypt::Perl::$alg\::Parse"; 54 Module::Load::load($module); 55 56 try { 57 $obj = $module->can('private')->($der_or_pem); 58 } 59 catch { 60 try { 61 $obj = $module->can('public')->($der_or_pem); 62 } 63 }; 64 65 return $obj if $obj; 66 } 67 68 die Crypt::Perl::X::create('Generic', "Unrecognized key: “$der_or_pem”"); 69} 70 71sub parse_jwk { 72 my ($hr) = @_; 73 74 if ('HASH' ne ref $hr) { 75 die Crypt::Perl::X::create('InvalidJWK', $hr); 76 } 77 78 my $kty = $hr->{'kty'}; 79 80 if ($kty) { 81 my $module; 82 83 if ($kty eq 'RSA') { 84 $module = 'Crypt::Perl::RSA::Parse'; 85 86 } 87 elsif ($kty eq 'OKP') { 88 if ($hr->{'crv'} ne 'Ed25519') { 89 die Crypt::Perl::X::create('Generic', "Unrecognized “crv” ($hr->{'crv'}) for key type “$kty”!"); 90 } 91 92 $module = 'Crypt::Perl::Ed25519::Parse'; 93 } 94 elsif ($kty eq 'EC') { 95 $module = 'Crypt::Perl::ECDSA::Parse'; 96 } 97 else { 98 die Crypt::Perl::X::create('UnknownJTKkty', $kty); 99 } 100 101 Module::Load::load($module); 102 103 return $module->can('jwk')->($hr); 104 } 105 106 die Crypt::Perl::X::create('InvalidJWK', %$hr); 107} 108 1091; 110