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   53072 use strict;
  4         15  
  4         107  
4 4     4   20 use warnings;
  4         8  
  4         152  
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   317 use Crypt::Perl::PKCS8 ();
  4         7  
  4         56  
29 4     4   710 use Crypt::Perl::ToDER ();
  4         10  
  4         1532  
30              
31             # DER or PEM
32              
33             sub private {
34 10     10 0 95 my $pem_or_der = shift;
35              
36 10         85 Crypt::Perl::ToDER::ensure_der($pem_or_der);
37              
38 10         59 my $struct = Crypt::Perl::PKCS8::parse_private($pem_or_der);
39              
40 2         1371 require Crypt::Perl::Ed25519::PrivateKey;
41              
42 2         14 _check_oid($struct->{'privateKeyAlgorithm'}, 'Crypt::Perl::Ed25519::PrivateKey');
43              
44 2         7 substr( $struct->{'privateKey'}, 0, 2 ) = q<>;
45              
46 2         7 return Crypt::Perl::Ed25519::PrivateKey->new( $struct->{'privateKey'} );
47             }
48              
49             sub public {
50 9     9 0 698 my $pem_or_der = shift;
51              
52 9         40 Crypt::Perl::ToDER::ensure_der($pem_or_der);
53              
54 9         51 my $struct = Crypt::Perl::PKCS8::parse_public($pem_or_der);
55              
56 2         1553 require Crypt::Perl::Ed25519::PublicKey;
57              
58 2         11 _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 524 my ($struct_hr) = @_;
66              
67 2         10 require MIME::Base64;
68              
69 2   33     10 my $x = $struct_hr->{'x'} && MIME::Base64::decode_base64url($struct_hr->{'x'});
70              
71 2 100       23 if ($struct_hr->{'d'}) {
72 1 50       2 my $d = MIME::Base64::decode_base64url($struct_hr->{'d'}) or do {
73 0         0 die "Neither “x” nor “d”!";
74             };
75              
76 1         12 require Crypt::Perl::Ed25519::PrivateKey;
77 1         6 return Crypt::Perl::Ed25519::PrivateKey->new( $d, $x );
78             }
79              
80 1 50       3 die "Neither “x” nor “d”!" if !$x;
81              
82 1         3 require Crypt::Perl::Ed25519::PublicKey;
83 1         30 return Crypt::Perl::Ed25519::PublicKey->new( $x );
84             }
85              
86             sub _check_oid {
87 4     4   13 my ($substruct, $class) = @_;
88              
89 4 100       44 if ( $substruct->{'algorithm'} ne $class->OID_Ed25519() ) {
90 1         11 die "OID ($substruct->{'algorithm'}) is not Ed25519!\n";
91             }
92              
93 3         7 return;
94             }
95              
96             1;