File Coverage

lib/Crypt/Perl/PK.pm
Criterion Covered Total %
statement 36 42 85.7
branch 8 14 57.1
condition 0 3 0.0
subroutine 9 9 100.0
pod 0 2 0.0
total 53 70 75.7


line stmt bran cond sub pod time code
1             package Crypt::Perl::PK;
2              
3 3     3   106348 use strict;
  3         8  
  3         66  
4 3     3   11 use warnings;
  3         5  
  3         64  
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 3     3   10 use Try::Tiny;
  3         5  
  3         104  
38              
39 3     3   370 use Module::Load ();
  3         882  
  3         56  
40              
41 3     3   291 use Crypt::Perl::X ();
  3         6  
  3         968  
42              
43             sub parse_key {
44 18     18 0 266852 my ($der_or_pem) = @_;
45              
46 18 50       116 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 18         47 my $obj;
51              
52 18         112 for my $alg ( qw( RSA ECDSA Ed25519 ) ) {
53 26         119 my $module = "Crypt::Perl::$alg\::Parse";
54 26         213 Module::Load::load($module);
55              
56             try {
57 26     26   2826 $obj = $module->can('private')->($der_or_pem);
58             }
59             catch {
60             try {
61 10         427 $obj = $module->can('public')->($der_or_pem);
62             }
63 26     10   3341 };
  10         314  
64              
65 26 100       731 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 2540 my ($hr) = @_;
73              
74 4 50       13 if ('HASH' ne ref $hr) {
75 0         0 die Crypt::Perl::X::create('InvalidJWK', $hr);
76             }
77              
78 4         8 my $kty = $hr->{'kty'};
79              
80 4 50       8 if ($kty) {
81 4         6 my $module;
82              
83 4 100 0     13 if ($kty eq 'RSA') {
    50          
    0          
84 2         3 $module = 'Crypt::Perl::RSA::Parse';
85              
86             }
87             elsif ($kty eq 'EC') {
88 2         2 $module = 'Crypt::Perl::ECDSA::Parse';
89             }
90             elsif ($kty eq 'OKP' && $hr->{'crv'} eq 'Ed25519') {
91 0         0 $module = 'Crypt::Perl::Ed25519::Parse';
92             }
93             else {
94 0         0 die Crypt::Perl::X::create('UnknownJTKkty', $kty);
95             }
96              
97 4         14 Module::Load::load($module);
98              
99 4         224 return $module->can('jwk')->($hr);
100             }
101              
102 0           die Crypt::Perl::X::create('InvalidJWK', %$hr);
103             }
104              
105             1;