File Coverage

blib/lib/Crypt/Format.pm
Criterion Covered Total %
statement 32 32 100.0
branch 6 8 75.0
condition n/a
subroutine 9 9 100.0
pod 0 4 0.0
total 47 53 88.6


line stmt bran cond sub pod time code
1             package Crypt::Format;
2              
3 5     5   300756 use strict;
  5         41  
  5         120  
4 5     5   20 use warnings;
  5         9  
  5         2477  
5              
6             our $VERSION = '0.12';
7              
8             our $BASE64_MODULE = 'MIME::Base64';
9              
10             =encoding utf-8
11              
12             =head1 NAME
13              
14             Crypt::Format - Conversion utilities for encryption applications
15              
16             =head1 SYNOPSIS
17              
18             use Crypt::Format;
19              
20             my $der = Crypt::Format::pem2der($pem);
21             my $pem = Crypt::Format::der2pem($der, 'CERTIFICATE REQUEST');
22              
23             my $good_pem = Crypt::Format::normalize_pem($weird_pem);
24              
25             # Split PEM chains such as application/pem-certificate-chain …
26             my @pems = Crypt::Format::split_pem_chain($pem_chain);
27              
28             {
29             #If, for whatever reason, you don’t like MIME::Base64,
30             #then customize this. The module must have encode() and/or decode()
31             #functions, depending on which of this module’s functions you use.
32             #
33             local $Crypt::Format::BASE64_MODULE = '..';
34              
35             Crypt::Format::...
36             }
37              
38             =head1 DESCRIPTION
39              
40             Not much more to say! This module is for simple conversions that I got
41             tired of writing out.
42              
43             =cut
44              
45             my $_LINE_SEP = "\n";
46              
47             sub der2pem {
48 4     4 0 1271 my ($der_r, $whatsit) = (\$_[0], $_[1]);
49              
50 4 100       22 die "Missing object type!" if !$whatsit;
51              
52 3         10 my $pem = _do_base64('encode', $$der_r, q<>);
53 3         42 $pem = join( $_LINE_SEP, $pem =~ m<(.{1,64})>g, q<> );
54              
55 3         20 substr( $pem, 0, 0, "-----BEGIN $whatsit-----$_LINE_SEP" );
56 3         11 substr( $pem, length($pem), 0, "-----END $whatsit-----" );
57              
58 3         11 return $pem;
59             }
60              
61             sub pem2der {
62 9     9 0 2463 my ($pem) = @_;
63              
64             # Strip the first line:
65 9         64 $pem =~ s<.+?[\x0d\x0a]+><>s;
66              
67             # Strip the last line and any trailing CRs and LFs:
68 9         411 $pem =~ s<[\x0d\x0a]+ [^\x0d\x0a]+? [\x0d\x0a]*\z><>sx;
69              
70 9         24 return _do_base64('decode', $pem);
71             }
72              
73             sub split_pem_chain {
74 5     5 0 2645 return split m[(?<=-)[\x0d\x0a]+(?=-)], shift();
75             }
76              
77             sub _do_base64 {
78 12     12   22 my $path = "$BASE64_MODULE.pm";
79 12         31 $path =~ s<::>g;
80              
81 12 100       46 _load_module($BASE64_MODULE) if !$INC{$path};
82              
83 12         65 my $cr = $BASE64_MODULE->can(shift);
84 12         128 return $cr->(@_);
85             }
86              
87             sub _load_module {
88 2     2   3 local $@;
89 2 50   2   123 eval "use $_[0]; 1" or die;
  2         800  
  2         2257  
  2         76  
90 2         5 return $_[0];
91             }
92              
93             sub normalize_pem {
94 1     1 0 785 my ($pem) = @_;
95              
96 1 50       7 $pem =~ m or die "Invalid PEM: “$pem”";
97              
98 1         4 return der2pem( pem2der( $pem ), $1 );
99             }
100              
101             =pod
102              
103             =head1 AUTHOR
104              
105             Felipe Gasper (FELIPE)
106              
107             =head1 REPOSITORY
108              
109             https://github.com/FGasper/p5-Crypt-Format
110              
111             =head1 COPYRIGHT
112              
113             This program is free software; you can redistribute
114             it and/or modify it under the same terms as Perl itself.
115              
116             The full text of the license can be found in the
117             LICENSE file included with this module.
118              
119             =cut
120              
121             1;