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   75200 use strict;
  4         27  
  4         128  
4 4     4   20 use warnings;
  4         14  
  4         137  
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   472 use Crypt::Perl::PKCS8 ();
  4         10  
  4         83  
29 4     4   1050 use Crypt::Perl::ToDER ();
  4         9  
  4         1988  
30              
31             # DER or PEM
32              
33             sub private {
34 12     12 0 128 my $pem_or_der = shift;
35              
36 12         127 Crypt::Perl::ToDER::ensure_der($pem_or_der);
37              
38 12         84 my $struct = Crypt::Perl::PKCS8::parse_private($pem_or_der);
39              
40 3         2751 require Crypt::Perl::Ed25519::PrivateKey;
41              
42 3         22 _check_oid($struct->{'privateKeyAlgorithm'}, 'Crypt::Perl::Ed25519::PrivateKey');
43              
44 2         7 substr( $struct->{'privateKey'}, 0, 2 ) = q<>;
45              
46 2         6 return Crypt::Perl::Ed25519::PrivateKey->new( $struct->{'privateKey'} );
47             }
48              
49             sub public {
50 11     11 0 1026 my $pem_or_der = shift;
51              
52 11         52 Crypt::Perl::ToDER::ensure_der($pem_or_der);
53              
54 11         58 my $struct = Crypt::Perl::PKCS8::parse_public($pem_or_der);
55              
56 2         1387 require Crypt::Perl::Ed25519::PublicKey;
57              
58 2         12 _check_oid($struct->{'algorithm'}, 'Crypt::Perl::Ed25519::PublicKey');
59              
60 1         5 return Crypt::Perl::Ed25519::PublicKey->new( $struct->{'subjectPublicKey'}[0] );
61             }
62              
63             # https://tools.ietf.org/html/rfc8037
64             sub jwk {
65 3     3 0 811 my ($struct_hr) = @_;
66              
67 3         18 require MIME::Base64;
68              
69 3   33     26 my $x = $struct_hr->{'x'} && MIME::Base64::decode_base64url($struct_hr->{'x'});
70              
71 3 100       53 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         13 require Crypt::Perl::Ed25519::PrivateKey;
77 1         14 return Crypt::Perl::Ed25519::PrivateKey->new( $d, $x );
78             }
79              
80 2 50       9 die "Neither “x” nor “d”!" if !$x;
81              
82 2         455 require Crypt::Perl::Ed25519::PublicKey;
83 2         11 return Crypt::Perl::Ed25519::PublicKey->new( $x );
84             }
85              
86             sub _check_oid {
87 5     5   21 my ($substruct, $class) = @_;
88              
89 5 100       80 if ( $substruct->{'algorithm'} ne $class->OID_Ed25519() ) {
90 2         19 die "OID ($substruct->{'algorithm'}) is not Ed25519!\n";
91             }
92              
93 3         9 return;
94             }
95              
96             1;