File Coverage

blib/lib/Crypt/Perl/Ed25519/Parse.pm
Criterion Covered Total %
statement 39 40 97.5
branch 6 8 75.0
condition 1 3 33.3
subroutine 8 8 100.0
pod 0 3 0.0
total 54 62 87.1


line stmt bran cond sub pod time code
1             package Crypt::Perl::Ed25519::Parse;
2              
3 4     4   57091 use strict;
  4         15  
  4         118  
4 4     4   24 use warnings;
  4         10  
  4         126  
5              
6             =encoding utf-8
7              
8             =head1 NAME
9              
10             Crypt::Perl::Ed25519::Parse
11              
12             =head1 SYNOPSIS
13              
14             # These accept either DER or PEM.
15             my $prkey = Crypt::Perl::Ed25519::Parse::private($buffer);
16             my $pbkey = Crypt::Perl::Ed25519::Parse::public($buffer);
17              
18             # This accepts a structure, not raw JSON.
19             my $key = Crypt::Perl::Ed25519::Parse::jwk($jwk_hr);
20              
21             =head1 DESCRIPTION
22              
23             See L and L
24             for descriptions of the interfaces that this module returns.
25              
26             =cut
27              
28 4     4   329 use Crypt::Perl::PKCS8 ();
  4         14  
  4         74  
29 4     4   780 use Crypt::Perl::ToDER ();
  4         9  
  4         1772  
30              
31             # DER or PEM
32              
33             sub private {
34 11     11 0 96 my $pem_or_der = shift;
35              
36 11         106 Crypt::Perl::ToDER::ensure_der($pem_or_der);
37              
38 11         102 my $struct = Crypt::Perl::PKCS8::parse_private($pem_or_der);
39              
40 3         2372 require Crypt::Perl::Ed25519::PrivateKey;
41              
42 3         18 _check_oid($struct->{'privateKeyAlgorithm'}, 'Crypt::Perl::Ed25519::PrivateKey');
43              
44 2         15 substr( $struct->{'privateKey'}, 0, 2 ) = q<>;
45              
46 2         7 return Crypt::Perl::Ed25519::PrivateKey->new( $struct->{'privateKey'} );
47             }
48              
49             sub public {
50 10     10 0 883 my $pem_or_der = shift;
51              
52 10         58 Crypt::Perl::ToDER::ensure_der($pem_or_der);
53              
54 10         66 my $struct = Crypt::Perl::PKCS8::parse_public($pem_or_der);
55              
56 2         1659 require Crypt::Perl::Ed25519::PublicKey;
57              
58 2         14 _check_oid($struct->{'algorithm'}, 'Crypt::Perl::Ed25519::PublicKey');
59              
60 1         3 return Crypt::Perl::Ed25519::PublicKey->new( $struct->{'subjectPublicKey'}[0] );
61             }
62              
63             # https://tools.ietf.org/html/rfc8037
64             sub jwk {
65 2     2 0 638 my ($struct_hr) = @_;
66              
67 2         10 require MIME::Base64;
68              
69 2   33     12 my $x = $struct_hr->{'x'} && MIME::Base64::decode_base64url($struct_hr->{'x'});
70              
71 2 100       28 if ($struct_hr->{'d'}) {
72 1 50       3 my $d = MIME::Base64::decode_base64url($struct_hr->{'d'}) or do {
73 0         0 die "Neither “x” nor “d”!";
74             };
75              
76 1         14 require Crypt::Perl::Ed25519::PrivateKey;
77 1         8 return Crypt::Perl::Ed25519::PrivateKey->new( $d, $x );
78             }
79              
80 1 50       4 die "Neither “x” nor “d”!" if !$x;
81              
82 1         3 require Crypt::Perl::Ed25519::PublicKey;
83 1         39 return Crypt::Perl::Ed25519::PublicKey->new( $x );
84             }
85              
86             sub _check_oid {
87 5     5   16 my ($substruct, $class) = @_;
88              
89 5 100       57 if ( $substruct->{'algorithm'} ne $class->OID_Ed25519() ) {
90 2         18 die "OID ($substruct->{'algorithm'}) is not Ed25519!\n";
91             }
92              
93 3         8 return;
94             }
95              
96             1;