fix #67 (better handling of PEM decoding failures)
Karel Miko
3 years ago
226 | 226 | } |
227 | 227 | elsif (ref $param eq 'SCALAR') { |
228 | 228 | my $data = $$param; |
229 | $data = pem_to_der($data) if $data =~ /-----BEGIN DH PARAMETERS-----\s*(.+)\s*-----END DH PARAMETERS-----/s; | |
229 | if ($data =~ /-----BEGIN DH PARAMETERS-----\s*(.+)\s*-----END DH PARAMETERS-----/s) { | |
230 | $data = pem_to_der($data) or croak "FATAL: PEM/params decode failed"; | |
231 | } | |
230 | 232 | return $self->_generate_key_dhparam($data); |
231 | 233 | } |
232 | 234 | elsif (ref $param eq 'HASH') { |
35 | 35 | } |
36 | 36 | elsif (@_ == 1 && ref $_[0] eq 'SCALAR') { |
37 | 37 | my $data = ${$_[0]}; |
38 | $data = pem_to_der($data) if $data =~ /-----BEGIN DSA PARAMETERS-----\s*(.+)\s*-----END DSA PARAMETERS-----/s; | |
38 | if ($data =~ /-----BEGIN DSA PARAMETERS-----\s*(.+)\s*-----END DSA PARAMETERS-----/s) { | |
39 | $data = pem_to_der($data) or croak "FATAL: PEM/params decode failed"; | |
40 | } | |
39 | 41 | return $self->_generate_key_dsaparam($data); |
40 | 42 | } |
41 | 43 | croak "FATAL: DSA generate_key - invalid args"; |
75 | 77 | croak "FATAL: invalid key data" unless $data; |
76 | 78 | |
77 | 79 | if ($data =~ /-----BEGIN (DSA PRIVATE|DSA PUBLIC|PRIVATE|PUBLIC) KEY-----(.*?)-----END/sg) { |
78 | $data = pem_to_der($data, $password); | |
80 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
79 | 81 | return $self->_import($data); |
80 | 82 | } |
81 | 83 | elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) { |
82 | $data = pem_to_der($data); | |
84 | $data = pem_to_der($data) or croak "FATAL: PEM/key decode failed"; | |
83 | 85 | my ($typ, $p, $q, $g, $y) = Crypt::PK::_ssh_parse($data); |
84 | 86 | return $self->_import_hex(unpack('H*',$p), unpack('H*',$q), unpack('H*',$g), undef, unpack('H*',$y)) if $typ && $p && $q && $g && $y && $typ eq 'ssh-dss'; |
85 | 87 | } |
218 | 218 | croak "FATAL: invalid key data" unless $data; |
219 | 219 | |
220 | 220 | if ($data =~ /-----BEGIN (EC PRIVATE|EC PUBLIC|PUBLIC) KEY-----(.*?)-----END/sg) { |
221 | $data = pem_to_der($data, $password); | |
221 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
222 | 222 | my $rv = eval { $self->_import($data) } || eval { $self->_import_old($data) }; |
223 | 223 | return $rv if $rv; |
224 | 224 | } |
225 | 225 | elsif ($data =~ /-----BEGIN PRIVATE KEY-----(.*?)-----END/sg) { |
226 | $data = pem_to_der($data, $password); | |
226 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
227 | 227 | return $self->_import_pkcs8($data, $password); |
228 | 228 | } |
229 | 229 | elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) { |
230 | $data = pem_to_der($data, $password); | |
230 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
231 | 231 | return $self->_import_pkcs8($data, $password); |
232 | 232 | } |
233 | 233 | elsif ($data =~ /^\s*(\{.*?\})\s*$/s) { |
243 | 243 | } |
244 | 244 | } |
245 | 245 | elsif ($data =~ /-----BEGIN CERTIFICATE-----(.*?)-----END CERTIFICATE-----/sg) { |
246 | $data = pem_to_der($data); | |
246 | $data = pem_to_der($data) or croak "FATAL: PEM/cert decode failed"; | |
247 | 247 | return $self->_import_x509($data); |
248 | 248 | } |
249 | 249 | elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) { |
250 | $data = pem_to_der($data); | |
250 | $data = pem_to_der($data) or croak "FATAL: PEM/key decode failed"; | |
251 | 251 | my ($typ, $skip, $pubkey) = Crypt::PK::_ssh_parse($data); |
252 | 252 | return $self->import_key_raw($pubkey, "$2") if $pubkey && $typ =~ /^ecdsa-(.+?)-(.*)$/; |
253 | 253 | } |
63 | 63 | croak "FATAL: invalid key data" unless $data; |
64 | 64 | |
65 | 65 | if ($data =~ /-----BEGIN PUBLIC KEY-----(.*?)-----END/sg) { |
66 | $data = pem_to_der($data, $password); | |
66 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
67 | 67 | return $self->_import($data); |
68 | 68 | } |
69 | 69 | elsif ($data =~ /-----BEGIN PRIVATE KEY-----(.*?)-----END/sg) { |
70 | $data = pem_to_der($data, $password); | |
70 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
71 | 71 | return $self->_import_pkcs8($data, $password); |
72 | 72 | } |
73 | 73 | elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) { |
74 | $data = pem_to_der($data, $password); | |
74 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
75 | 75 | return $self->_import_pkcs8($data, $password); |
76 | 76 | } |
77 | 77 | elsif ($data =~ /-----BEGIN ED25519 PRIVATE KEY-----(.*?)-----END/sg) { |
78 | $data = pem_to_der($data, $password); | |
78 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
79 | 79 | return $self->_import_pkcs8($data, $password); |
80 | 80 | } |
81 | 81 | elsif ($data =~ /^\s*(\{.*?\})\s*$/s) { # JSON |
86 | 86 | } |
87 | 87 | } |
88 | 88 | elsif ($data =~ /-----BEGIN CERTIFICATE-----(.*?)-----END CERTIFICATE-----/sg) { |
89 | $data = pem_to_der($data); | |
89 | $data = pem_to_der($data) or croak "FATAL: PEM/cert decode failed"; | |
90 | 90 | return $self->_import_x509($data); |
91 | 91 | } |
92 | 92 | elsif ($data =~ /-----BEGIN OPENSSH PRIVATE KEY-----(.*?)-----END/sg) { |
96 | 96 | croak "FATAL: OPENSSH PRIVATE KEY not supported"; |
97 | 97 | } |
98 | 98 | elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) { |
99 | $data = pem_to_der($data); | |
99 | $data = pem_to_der($data) or croak "FATAL: PEM/key decode failed"; | |
100 | 100 | my ($typ, $pubkey) = Crypt::PK::_ssh_parse($data); |
101 | 101 | return $self->_import_raw($pubkey, 0) if $typ eq 'ssh-ed25519' && length($pubkey) == 32; |
102 | 102 | } |
121 | 121 | # PKCS#1 RSAPublicKey (PEM header: BEGIN RSA PUBLIC KEY) |
122 | 122 | # PKCS#1 RSAPrivateKey (PEM header: BEGIN RSA PRIVATE KEY) |
123 | 123 | # X.509 SubjectPublicKeyInfo (PEM header: BEGIN PUBLIC KEY) |
124 | $data = pem_to_der($data, $password); | |
124 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
125 | 125 | return $self->_import($data) if $data; |
126 | 126 | } |
127 | 127 | elsif ($data =~ /-----BEGIN PRIVATE KEY-----(.*?)-----END/sg) { |
128 | 128 | # PKCS#8 PrivateKeyInfo (PEM header: BEGIN PRIVATE KEY) |
129 | $data = pem_to_der($data, $password); | |
129 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
130 | 130 | return $self->_import_pkcs8($data, $password); |
131 | 131 | } |
132 | 132 | elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) { |
133 | 133 | # PKCS#8 PrivateKeyInfo (PEM header: BEGIN ENCRYPTED PRIVATE KEY) |
134 | $data = pem_to_der($data, $password); | |
134 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
135 | 135 | return $self->_import_pkcs8($data, $password); |
136 | 136 | } |
137 | 137 | elsif ($data =~ /^\s*(\{.*?\})\s*$/s) { |
146 | 146 | } |
147 | 147 | } |
148 | 148 | elsif ($data =~ /-----BEGIN CERTIFICATE-----(.*?)-----END CERTIFICATE-----/sg) { |
149 | $data = pem_to_der($data); | |
149 | $data = pem_to_der($data) or croak "FATAL: PEM/cert decode failed"; | |
150 | 150 | return $self->_import_x509($data); |
151 | 151 | } |
152 | 152 | elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) { |
153 | $data = pem_to_der($data); | |
153 | $data = pem_to_der($data) or croak "FATAL: PEM/key decode failed"; | |
154 | 154 | my ($typ, $N, $e) = Crypt::PK::_ssh_parse($data); |
155 | 155 | return $self->_import_hex(unpack("H*", $e), unpack("H*", $N)) if $typ && $e && $N && $typ eq 'ssh-rsa'; |
156 | 156 | } |
63 | 63 | croak "FATAL: invalid key data" unless $data; |
64 | 64 | |
65 | 65 | if ($data =~ /-----BEGIN PUBLIC KEY-----(.*?)-----END/sg) { |
66 | $data = pem_to_der($data, $password); | |
66 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
67 | 67 | return $self->_import($data); |
68 | 68 | } |
69 | 69 | elsif ($data =~ /-----BEGIN PRIVATE KEY-----(.*?)-----END/sg) { |
70 | $data = pem_to_der($data, $password); | |
70 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
71 | 71 | return $self->_import_pkcs8($data, $password); |
72 | 72 | } |
73 | 73 | elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) { |
74 | $data = pem_to_der($data, $password); | |
74 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
75 | 75 | return $self->_import_pkcs8($data, $password); |
76 | 76 | } |
77 | 77 | elsif ($data =~ /-----BEGIN X25519 PRIVATE KEY-----(.*?)-----END/sg) { |
78 | $data = pem_to_der($data, $password); | |
78 | $data = pem_to_der($data, $password) or croak "FATAL: PEM/key decode failed"; | |
79 | 79 | return $self->_import_pkcs8($data, $password); |
80 | 80 | } |
81 | 81 | elsif ($data =~ /^\s*(\{.*?\})\s*$/s) { # JSON |