File Coverage

lib/Crypt/Perl/PK.pm
Criterion Covered Total %
statement 44 44 100.0
branch 16 16 100.0
condition n/a
subroutine 9 9 100.0
pod 0 2 0.0
total 69 71 97.1


line stmt bran cond sub pod time code
1             package Crypt::Perl::PK;
2              
3 4     4   135026 use strict;
  4         27  
  4         164  
4 4     4   24 use warnings;
  4         14  
  4         178  
5              
6             =encoding utf-8
7              
8             =head1 NAME
9              
10             Crypt::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              
32             As of now there’s not much of interest to find here except
33             parsing of Ls.
34              
35             =cut
36              
37 4     4   763 use Try::Tiny;
  4         3413  
  4         273  
38              
39 4     4   708 use Module::Load ();
  4         1725  
  4         92  
40              
41 4     4   632 use Crypt::Perl::X ();
  4         7  
  4         1876  
42              
43             sub parse_key {
44 22     22 0 539011 my ($der_or_pem) = @_;
45              
46 22 100       195 if (ref $der_or_pem) {
47 1         8 die Crypt::Perl::X::create('Generic', "Need unblessed octet string, not “$der_or_pem”!");
48             }
49              
50 21         462 my $obj;
51              
52 21         135 for my $alg ( qw( RSA Ed25519 ECDSA ) ) {
53 42         190 my $module = "Crypt::Perl::$alg\::Parse";
54 42         338 Module::Load::load($module);
55              
56             try {
57 42     42   4942 $obj = $module->can('private')->($der_or_pem);
58             }
59             catch {
60             try {
61 24         1283 $obj = $module->can('public')->($der_or_pem);
62             }
63 42     24   4869 };
  24         724  
64              
65 42 100       1283 return $obj if $obj;
66             }
67              
68 1         7 die Crypt::Perl::X::create('Generic', "Unrecognized key: “$der_or_pem”");
69             }
70              
71             sub parse_jwk {
72 9     9 0 13540 my ($hr) = @_;
73              
74 9 100       35 if ('HASH' ne ref $hr) {
75 1         5 die( (caller 0)[3] . " needs a HASH reference, not $hr" );
76             }
77              
78 8         19 my $kty = $hr->{'kty'};
79              
80 8 100       22 if ($kty) {
81 7         10 my $module;
82              
83 7 100       28 if ($kty eq 'RSA') {
    100          
    100          
84 2         5 $module = 'Crypt::Perl::RSA::Parse';
85              
86             }
87             elsif ($kty eq 'OKP') {
88 2 100       7 if ($hr->{'crv'} ne 'Ed25519') {
89 1         9 die Crypt::Perl::X::create('Generic', "Unrecognized “crv” ($hr->{'crv'}) for key type “$kty”!");
90             }
91              
92 1         2 $module = 'Crypt::Perl::Ed25519::Parse';
93             }
94             elsif ($kty eq 'EC') {
95 2         5 $module = 'Crypt::Perl::ECDSA::Parse';
96             }
97             else {
98 1         6 die Crypt::Perl::X::create('UnknownJWKkty', $kty);
99             }
100              
101 5         22 Module::Load::load($module);
102              
103 5         299 return $module->can('jwk')->($hr);
104             }
105              
106 1         7 die Crypt::Perl::X::create('InvalidJWK', %$hr);
107             }
108              
109             1;