File Coverage

lib/Crypt/Perl/PK.pm
Criterion Covered Total %
statement 36 44 81.8
branch 9 16 56.2
condition n/a
subroutine 9 9 100.0
pod 0 2 0.0
total 54 71 76.0


line stmt bran cond sub pod time code
1             package Crypt::Perl::PK;
2              
3 4     4   242570 use strict;
  4         23  
  4         133  
4 4     4   26 use warnings;
  4         8  
  4         141  
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   546 use Try::Tiny;
  4         2594  
  4         181  
38              
39 4     4   848 use Module::Load ();
  4         2130  
  4         59  
40              
41 4     4   710 use Crypt::Perl::X ();
  4         7  
  4         1408  
42              
43             sub parse_key {
44 20     20 0 371424 my ($der_or_pem) = @_;
45              
46 20 50       137 if (ref $der_or_pem) {
47 0         0 die Crypt::Perl::X::create('Generic', "Need unblessed octet string, not “$der_or_pem”!");
48             }
49              
50 20         57 my $obj;
51              
52 20         95 for my $alg ( qw( RSA Ed25519 ECDSA ) ) {
53 39         125 my $module = "Crypt::Perl::$alg\::Parse";
54 39         279 Module::Load::load($module);
55              
56             try {
57 39     39   3913 $obj = $module->can('private')->($der_or_pem);
58             }
59             catch {
60             try {
61 21         936 $obj = $module->can('public')->($der_or_pem);
62             }
63 39     21   4097 };
  21         567  
64              
65 39 100       1221 return $obj if $obj;
66             }
67              
68 0         0 die Crypt::Perl::X::create('Generic', "Unrecognized key: “$der_or_pem”");
69             }
70              
71             sub parse_jwk {
72 4     4 0 3223 my ($hr) = @_;
73              
74 4 50       20 if ('HASH' ne ref $hr) {
75 0         0 die Crypt::Perl::X::create('InvalidJWK', $hr);
76             }
77              
78 4         10 my $kty = $hr->{'kty'};
79              
80 4 50       12 if ($kty) {
81 4         8 my $module;
82              
83 4 100       17 if ($kty eq 'RSA') {
    50          
    50          
84 2         5 $module = 'Crypt::Perl::RSA::Parse';
85              
86             }
87             elsif ($kty eq 'OKP') {
88 0 0       0 if ($hr->{'crv'} ne 'Ed25519') {
89 0         0 die Crypt::Perl::X::create('Generic', "Unrecognized “crv” ($hr->{'crv'}) for key type “$kty”!");
90             }
91              
92 0         0 $module = 'Crypt::Perl::Ed25519::Parse';
93             }
94             elsif ($kty eq 'EC') {
95 2         4 $module = 'Crypt::Perl::ECDSA::Parse';
96             }
97             else {
98 0         0 die Crypt::Perl::X::create('UnknownJTKkty', $kty);
99             }
100              
101 4         19 Module::Load::load($module);
102              
103 4         248 return $module->can('jwk')->($hr);
104             }
105              
106 0           die Crypt::Perl::X::create('InvalidJWK', %$hr);
107             }
108              
109             1;