The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Data::SSHPubkey - utility function to parse SSH public keys with

SYNOPSIS

  use Data::SSHPubkey qw(pubkeys);

  # a Mojo app might accept public keys from clients, e.g.
  #   cat /etc/ssh/*.pub | curl ... --data-urlencode pk@- http...
  # this case is supported via a scalar reference
  my $keylist = pubkeys( \$c->param('pk') );
  for my $ref ( @$keylist ) {
      my ($type, $pubkey) = @$ref;
      ...
  }

  # a key collection host could instead wrap ssh-keyscan(1) and
  # pass in a file handle
  open( my $fh, '-|', qw(ssh-keyscan --), $host ) or die ...
  binmode $fh;
  my $keylist = pubkeys($fh);

  # a string will be treated as a file to open and read
  my $keylist = pubkeys( "/etc/ssh/ssh_host_ed25519_key.pub" );

  # if you do not care about the key types, extract only the pub
  # keys with something like
  ... = map { $_->[1] } @$keylist;

DESCRIPTION

Data::SSHPubkey parses SSH public keys, or at least some of those supported by ssh-keygen(1). It may be prudent to check any uploaded data against ssh-keygen though this module should help extract said data from a web form upload or the like to get to that step.

Currently supported public key types (the possible values that $type above may contain):

  ecdsa ed25519 rsa
  PEM PKCS8 RFC4716

Neither SSH1 keys nor SSH2 DSA keys are supported.

The $pubkey data will not include any tailing comments; those are stripped. The $pubkey data will not end with a newline; that must be added by your software as necessary when writing out the public keys. POSIX mandates an ultimate newline, and the shell read command is buggy by default if that ultimate newline is missing:

  $ (echo data; echo -n loss) | while read line; do echo $line; done

Inner newlines for the multiline SSH public key types (PEM, PKCS8, and RFC4716) will be standardized to the $/ variable. This may cause problems if ssh-keygen(1) or equivalent on some platform demands a specific newline sequence that is not $/.

The types PEM, PKCS8, and RFC4716 will need conversion for use with OpenSSH; see the -i -m ... options to ssh-keygen(1).

SUBROUTINE

pubkeys filename-or-scalarref

A filename (scalar) will be opened and the public keys therein parsed; a scalar reference will be treated as an in-memory file and will likewise be opened and parsed.

This routine will croak on error as, in theory, all the errors should be due to the data passed in by the caller, or possibly the system has run out of memory, or something.

The return format is a reference to a list of [ $type, $pubkey ] sublists.

VARIABLE

The %Data::SSHPubkey::ssh_pubkey_types hash contains as its keys the SSH public key types supported by this module.

BUGS

Please report any bugs or feature requests to bug-data-sshpubkey at rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Data-SSHPubkey. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

Patches might best be applied towards:

https://github.com/thrig/Data-SSHPubkey

Known Issues

Probably not enough guards or checks against hostile input (too many lines of input, for one).

Support for the PEM and especially PKCS8 formats is a bit sloppy, and the base64 matching is done by a regex that may accept data that is not valid base64.

Support for various RFC 4253 formats is likely lacking (see below or the comments in the code).

More tests are necessary for more edge cases.

If the input uses fancy encodings (where fancy is anything not ASCII) lines longer than 72 8-bit bytes may be accepted. read_binary from File::Slurper or a traditional binmode $fh should avoid this case as the key data looked for is only a subset of ASCII (header values or comments that are ignored by this module could be UTF-8 or possibly anything else).

SEE ALSO

ssh-keygen(1), ssh-keyscan(1)

Config::OpenSSH::Authkey - older module more aimed at management of ~/.ssh/authorized_keys data and not specifically public keys. It does have support for SSH2 DSA or SSH1 keys, though.

RFC 822

Definition of white space used in various formats [ \t].

RFC 1421

PEM format details.

RFC 4253

Mentioned by RFC 4716 but it is unclear to me what the section 6.6 "Public Key Algorithms" formats exactly are.

RFC 4716

Secure Shell (SSH) public key file format.

AUTHOR

thrig - Jeremy Mates (cpan:JMATES) <jmates at cpan.org>

COPYRIGHT AND LICENSE

Copyright (C) 2019 by Jeremy Mates

This program is distributed under the (Revised) BSD License: http://www.opensource.org/licenses/BSD-3-Clause