File Coverage

lib/Crypt/Perl/PK.pm
Criterion Covered Total %
statement 36 42 85.7
branch 9 14 64.2
condition 1 3 33.3
subroutine 9 9 100.0
pod 0 2 0.0
total 55 70 78.5


line stmt bran cond sub pod time code
1             package Crypt::Perl::PK;
2              
3 4     4   198739 use strict;
  4         18  
  4         94  
4 4     4   19 use warnings;
  4         5  
  4         107  
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   405 use Try::Tiny;
  4         1767  
  4         154  
38              
39 4     4   821 use Module::Load ();
  4         1711  
  4         60  
40              
41 4     4   575 use Crypt::Perl::X ();
  4         7  
  4         1182  
42              
43             sub parse_key {
44 19     19 0 382244 my ($der_or_pem) = @_;
45              
46 19 50       131 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 19         59 my $obj;
51              
52 19         85 for my $alg ( qw( RSA Ed25519 ECDSA ) ) {
53 36         144 my $module = "Crypt::Perl::$alg\::Parse";
54 36         240 Module::Load::load($module);
55              
56             try {
57 36     36   3075 $obj = $module->can('private')->($der_or_pem);
58             }
59             catch {
60             try {
61 19         722 $obj = $module->can('public')->($der_or_pem);
62             }
63 36     19   3229 };
  19         471  
64              
65 36 100       1132 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 2727 my ($hr) = @_;
73              
74 4 50       19 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       13 if ($kty) {
81 4         9 my $module;
82              
83 4 100 33     22 if ($kty eq 'RSA') {
    50          
    50          
84 2         5 $module = 'Crypt::Perl::RSA::Parse';
85              
86             }
87             elsif ($kty eq 'OKP' && $hr->{'crv'} eq 'Ed25519') {
88 0         0 $module = 'Crypt::Perl::Ed25519::Parse';
89             }
90             elsif ($kty eq 'EC') {
91 2         6 $module = 'Crypt::Perl::ECDSA::Parse';
92             }
93             else {
94 0         0 die Crypt::Perl::X::create('UnknownJTKkty', $kty);
95             }
96              
97 4         22 Module::Load::load($module);
98              
99 4         233 return $module->can('jwk')->($hr);
100             }
101              
102 0           die Crypt::Perl::X::create('InvalidJWK', %$hr);
103             }
104              
105             1;