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   69340 use strict;
  4         20  
  4         114  
4 4     4   21 use warnings;
  4         9  
  4         129  
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   404 use Crypt::Perl::PKCS8 ();
  4         8  
  4         67  
29 4     4   750 use Crypt::Perl::ToDER ();
  4         8  
  4         1634  
30              
31             # DER or PEM
32              
33             sub private {
34 11     11 0 106 my $pem_or_der = shift;
35              
36 11         90 Crypt::Perl::ToDER::ensure_der($pem_or_der);
37              
38 11         84 my $struct = Crypt::Perl::PKCS8::parse_private($pem_or_der);
39              
40 3         2291 require Crypt::Perl::Ed25519::PrivateKey;
41              
42 3         19 _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 10     10 0 960 my $pem_or_der = shift;
51              
52 10         38 Crypt::Perl::ToDER::ensure_der($pem_or_der);
53              
54 10         53 my $struct = Crypt::Perl::PKCS8::parse_public($pem_or_der);
55              
56 2         1691 require Crypt::Perl::Ed25519::PublicKey;
57              
58 2         13 _check_oid($struct->{'algorithm'}, 'Crypt::Perl::Ed25519::PublicKey');
59              
60 1         4 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 831 my ($struct_hr) = @_;
66              
67 2         12 require MIME::Base64;
68              
69 2   33     13 my $x = $struct_hr->{'x'} && MIME::Base64::decode_base64url($struct_hr->{'x'});
70              
71 2 100       32 if ($struct_hr->{'d'}) {
72 1 50       5 my $d = MIME::Base64::decode_base64url($struct_hr->{'d'}) or do {
73 0         0 die "Neither “x” nor “d”!";
74             };
75              
76 1         17 require Crypt::Perl::Ed25519::PrivateKey;
77 1         9 return Crypt::Perl::Ed25519::PrivateKey->new( $d, $x );
78             }
79              
80 1 50       54 die "Neither “x” nor “d”!" if !$x;
81              
82 1         6 require Crypt::Perl::Ed25519::PublicKey;
83 1         5 return Crypt::Perl::Ed25519::PublicKey->new( $x );
84             }
85              
86             sub _check_oid {
87 5     5   19 my ($substruct, $class) = @_;
88              
89 5 100       58 if ( $substruct->{'algorithm'} ne $class->OID_Ed25519() ) {
90 2         15 die "OID ($substruct->{'algorithm'}) is not Ed25519!\n";
91             }
92              
93 3         9 return;
94             }
95              
96             1;