--- /dev/null
+Author: Daniel F. Dickinson <cshored@thecshore.com>
+Date: Sun Jan 27 01:04:25 2019 -0500
+
+gitolite: Eliminate the need for ssh-keygen dependency
+
+ Previously gitolite used ssh-keygen to generate fingerprints
+ from OpenSSH keys to ensure non-duplication of keys when
+ processing them to create / manage user ssh access to the
+ git repositories. This ends up depending on openssl,
+ which is large and unnecessary when we are running on an
+ embedded distro such as OpenWrt.
+
+Signed-off-by: Daniel F. Dickinson <cshored@thecshore.com>
+Index: gitolite-3.6.11/src/lib/Gitolite/Common.pm
+===================================================================
+--- gitolite-3.6.11.orig/src/lib/Gitolite/Common.pm
++++ gitolite-3.6.11/src/lib/Gitolite/Common.pm
+@@ -26,6 +26,8 @@ package Gitolite::Common;
+ use Exporter 'import';
+ use File::Path qw(mkpath);
+ use File::Temp qw(tempfile);
++use MIME::Base64 qw(decode_base64);
++use Digest::SHA qw(sha256_base64);
+ use Carp qw(carp cluck croak confess);
+
+ use strict;
+@@ -352,43 +352,82 @@ sub logger_plus_stderr {
+ }
+
+ # ----------------------------------------------------------------------
++# Decode OpenSSH key
++# If the key cannot be parsed it will be undef
++# Returns (algorithm_name, algo_data1, algo_data2, ...)
++sub ssh_decode_key($) {
++ my $key = shift;
++ my $keydata = decode_base64($key);
++ my @keyparts = ();
++ my $partlen;
++ my $algorithm;
++ my $data;
++ my $pos = 0;
++ $partlen = unpack('N', substr $keydata, $pos, 4) or return undef;
++ $algorithm = substr $keydata, $pos + 4, $partlen or return undef;
++ $pos = $pos + 4 + $partlen;
++ while ( $pos <= length($keydata) ) {
++ $partlen = unpack('N', substr $keydata, $pos, 4) or last;
++ $data = unpack('s>*', substr $keydata, $pos + 4, 4) or last;
++ $pos = $pos + 4 + $partlen;
++ push @keyparts, $data;
++ }
++ return ( $algorithm, @keyparts );
++}
++
++# ----------------------------------------------------------------------
++# Parse OpenSSH line
++# If the file cannot be parsed it will be undef
++# Returns (restrictions, algorithm, PEMkey, comment)
++sub ssh_parse_line($) {
++ my $ssh_line = shift;
++ my @ssh_parts = split / /, $ssh_line, 5;
++ if (scalar @ssh_parts < 4) {
++ @ssh_parts = ('', @ssh_parts);
++ }
++ if (scalar @ssh_parts > 4) {
++ @ssh_parts = @ssh_parts[0,3]
++ }
++ if (scalar @ssh_parts < 4) {
++ @ssh_parts = undef;
++ }
++ return ( @ssh_parts );
++}
++
++# ----------------------------------------------------------------------
++# Get the SSH fingerprint of a line of text
++# If the fingerprint cannot be parsed, it will be undef
++# In a scalar context, returns the fingerprint
++# In a list context, returns (fingerprint, output) where output
++# is the parsed input line (less algorithm)
++sub ssh_fingerprint_line($) {
++ my $ssh_line = shift;
++ my @parsed_line = ssh_parse_line($ssh_line) or return undef;
++ my @ssh_parts = ssh_decode_key($parsed_line[2]) or return undef;
++ ( $parsed_line[1] eq $ssh_parts[0] ) or die "algorithm mismatch: $parsed_line[1] vs. $ssh_parts[0]";
++ my $fp = sha256_base64(join(' ', @ssh_parts[1,-1]));
++ return wantarray ? ($fp, join(' ', @ssh_parts[1,-1])) : $fp;
++}
++
++# ----------------------------------------------------------------------
+ # Get the SSH fingerprint of a file
+ # If the fingerprint cannot be parsed, it will be undef
+ # In a scalar context, returns the fingerprint
+ # In a list context, returns (fingerprint, output) where output
+-# is the raw output of the ssh-keygen command
+-sub ssh_fingerprint_file {
++# is the raw input line
++sub ssh_fingerprint_file($) {
+ my $in = shift;
+ -f $in or die "file not found: $in\n";
+ my $fh;
+- open( $fh, "ssh-keygen -l -f $in |" ) or die "could not fork: $!\n";
++ open( $fh, $in ) or die "could not open $in: $!\n";
+ my $output = <$fh>;
+ chomp $output;
+- # dbg("fp = $fp");
+ close $fh;
+ # Return a valid fingerprint or undef
+- my $fp = undef;
+- if($output =~ /((?:MD5:)?(?:[0-9a-f]{2}:){15}[0-9a-f]{2})/i or
+- $output =~ m{((?:RIPEMD|SHA)\d+:[A-Za-z0-9+/=]+)}i) {
+- $fp = $1;
+- }
++ my $fp = ssh_fingerprint_line($output);
+ return wantarray ? ($fp, $output) : $fp;
+ }
+
+-# Get the SSH fingerprint of a line of text
+-# If the fingerprint cannot be parsed, it will be undef
+-# In a scalar context, returns the fingerprint
+-# In a list context, returns (fingerprint, output) where output
+-# is the raw output of the ssh-keygen command
+-sub ssh_fingerprint_line {
+- my ( $fh, $fn ) = tempfile();
+- print $fh shift() . "\n";
+- close $fh;
+- my ($fp,$output) = ssh_fingerprint_file($fn);
+- unlink $fn;
+- return wantarray ? ($fp,$output) : $fp;
+-}
+-
+ # ----------------------------------------------------------------------
+
+ # bare-minimum subset of 'Tsh' (see github.com/sitaramc/tsh)