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   216885 use strict;
  4         23  
  4         121  
4 4     4   25 use warnings;
  4         8  
  4         120  
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   422 use Try::Tiny;
  4         1980  
  4         155  
38              
39 4     4   805 use Module::Load ();
  4         1869  
  4         56  
40              
41 4     4   620 use Crypt::Perl::X ();
  4         5  
  4         1332  
42              
43             sub parse_key {
44 20     20 0 294696 my ($der_or_pem) = @_;
45              
46 20 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 20         50 my $obj;
51              
52 20         101 for my $alg ( qw( RSA Ed25519 ECDSA ) ) {
53 39         124 my $module = "Crypt::Perl::$alg\::Parse";
54 39         243 Module::Load::load($module);
55              
56             try {
57 39     39   3530 $obj = $module->can('private')->($der_or_pem);
58             }
59             catch {
60             try {
61 21         926 $obj = $module->can('public')->($der_or_pem);
62             }
63 39     21   3839 };
  21         490  
64              
65 39 100       1094 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 2983 my ($hr) = @_;
73              
74 4 50       15 if ('HASH' ne ref $hr) {
75 0         0 die Crypt::Perl::X::create('InvalidJWK', $hr);
76             }
77              
78 4         7 my $kty = $hr->{'kty'};
79              
80 4 50       7 if ($kty) {
81 4         7 my $module;
82              
83 4 100       16 if ($kty eq 'RSA') {
    50          
    50          
84 2         3 $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         3 $module = 'Crypt::Perl::ECDSA::Parse';
96             }
97             else {
98 0         0 die Crypt::Perl::X::create('UnknownJTKkty', $kty);
99             }
100              
101 4         11 Module::Load::load($module);
102              
103 4         225 return $module->can('jwk')->($hr);
104             }
105              
106 0           die Crypt::Perl::X::create('InvalidJWK', %$hr);
107             }
108              
109             1;