App-GroupSecret
view release on metacpan or search on metacpan
lib/App/GroupSecret.pm view on Meta::CPAN
sub main {
my $self = shift;
my @args = @_;
my $filepath = '';
my $help = 0;
my $man = 0;
my $version = 0;
my $private_key = '';
# Parse options using pass_through so that we can pick out the global
# options, wherever they are in the arg list, and leave the rest to be
# parsed by each individual command.
Getopt::Long::Configure('pass_through');
GetOptionsFromArray(
\@args,
'file|f=s' => \$filepath,
'help|h|?' => \$help,
'manual|man' => \$man,
'private-key|k=s' => \$private_key,
'version|v' => \$version,
) or pod2usage(2);
Getopt::Long::Configure('default');
pod2usage(-exitval => 1, -verbose => 99, -sections => [qw(SYNOPSIS OPTIONS COMMANDS)]) if $help;
pod2usage(-verbose => 2) if $man;
return print "groupsecret ${VERSION}\n" if $version;
$self->{private_key} = $private_key if $private_key;
$self->{filepath} = $filepath if $filepath;
my %commands = (
add_key => 'add_key',
add_keys => 'add_key',
change_secret => 'set_secret',
delete_key => 'delete_key',
delete_keys => 'delete_key',
list_keys => 'list_keys',
print => 'print_secret',
lib/App/GroupSecret.pm view on Meta::CPAN
shift->{filepath} ||= $ENV{GROUPSECRET_KEYFILE} || 'groupsecret.yml';
}
sub file {
my $self = shift;
return $self->{file} ||= App::GroupSecret::File->new($self->filepath);
}
sub private_key {
shift->{private_key} ||= $ENV{GROUPSECRET_PRIVATE_KEY} || "$ENV{HOME}/.ssh/id_rsa";
}
sub _action_print_secret {
my $self = shift;
my $decrypt = 1;
GetOptionsFromArray(
\@_,
'decrypt!' => \$decrypt,
) or pod2usage(2);
my $file = $self->file;
my $filepath = $file->filepath;
die "No keyfile '$filepath' exists -- use the \`add-key' command to create one.\n"
unless -e $filepath && !-d $filepath;
die "No secret in keyfile '$filepath' exists -- use the \`set-secret' command to set one.\n"
if !$file->secret;
if ($decrypt) {
my $private_key = $self->private_key;
my $secret = $file->decrypt_secret(private_key => $private_key) or die "No secret.\n";
print $secret;
}
else {
print $file->secret;
}
}
sub _action_set_secret {
my $self = shift;
lib/App/GroupSecret.pm view on Meta::CPAN
elsif ($secret_spec =~ /^file:(.*)$/i) {
$secret = $1;
}
else {
$secret = $secret_spec;
}
my $file = $self->file;
if ($keep_passphrase) {
my $private_key = $self->private_key;
$passphrase = $file->decrypt_secret_passphrase($private_key);
$file->encrypt_secret($secret, $passphrase);
}
else {
$passphrase = generate_secure_random_bytes(32);
$file->encrypt_secret($secret, $passphrase);
$file->encrypt_secret_passphrase($passphrase);
}
$file->save;
}
lib/App/GroupSecret.pm view on Meta::CPAN
for my $public_key (@_) {
my $info = read_openssh_key_fingerprint($public_key);
if ($keys->{$info->{fingerprint}} && !$update) {
my $formatted_key = $file->format_key($info);
print "SKIP\t$formatted_key\n";
next;
}
if ($file->secret && !$opts->{passphrase}) {
my $private_key = $self->private_key;
my $passphrase = $file->decrypt_secret_passphrase($private_key);
$opts->{passphrase} = $passphrase;
}
local $opts->{fingerprint_info} = $info;
my ($fingerprint, $key) = $file->add_key($public_key, $opts);
local $key->{fingerprint} = $fingerprint;
my $formatted_key = $file->format_key($key);
print "ADD\t$formatted_key\n";
}
lib/App/GroupSecret.pm view on Meta::CPAN
$filepath = $script->filepath;
Get the path to the keyfile.
=head2 file
$file = $script->file;
Get the L<App::GroupSecret::File> instance for the keyfile.
=head2 private_key
$filepath = $script->private_key;
Get the path to a private key used to decrypt the keyfile.
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
L<https://github.com/chazmcgarvey/groupsecret/issues>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
lib/App/GroupSecret/Crypt.pm view on Meta::CPAN
Read a RFC4716 (SSH2) public key from a file, converting it to PKCS8 (PEM).
=head2 read_openssh_key_fingerprint
$fingerprint = read_openssh_key_fingerprint($filepath);
Get the fingerprint of an OpenSSH private or public key.
=head2 decrypt_rsa
$plaintext = decrypt_rsa($ciphertext_filepath, $private_key_filepath);
$plaintext = decrypt_rsa(\$ciphertext, $private_key_filepath);
decrypt_rsa($ciphertext_filepath, $private_key_filepath, $plaintext_filepath);
decrypt_rsa(\$ciphertext, $private_key_filepath, $plaintext_filepath);
Do RSA decryption. Turn ciphertext into plaintext.
=head2 encrypt_rsa
$ciphertext = decrypt_rsa($plaintext_filepath, $public_key_filepath);
$ciphertext = decrypt_rsa(\$plaintext, $public_key_filepath);
decrypt_rsa($plaintext_filepath, $public_key_filepath, $ciphertext_filepath);
decrypt_rsa(\$plaintext, $public_key_filepath, $ciphertext_filepath);
lib/App/GroupSecret/File.pm view on Meta::CPAN
if ($args->{embed}) {
open(my $fh, '<', $public_key) or die "open failed: $!";
$key->{content} = do { local $/; <$fh> };
chomp $key->{content};
}
$keys->{$fingerprint} = $key;
if ($self->secret) {
my $passphrase = $args->{passphrase} || $self->decrypt_secret_passphrase($args->{private_key});
my $ciphertext = encrypt_rsa(\$passphrase, $public_key);
$key->{secret_passphrase} = $ciphertext;
}
return wantarray ? ($fingerprint => $key) : $key;
}
sub delete_key {
my $self = shift;
my $fingerprint = shift;
delete $self->keys->{$fingerprint};
}
sub decrypt_secret {
my $self = shift;
my $args = @_ == 1 ? shift : {@_};
$args->{passphrase} || $args->{private_key} or _usage(q{$file->decrypt_secret($private_key)});
my $passphrase = $args->{passphrase};
$passphrase = $self->decrypt_secret_passphrase($args->{private_key}) if !$passphrase;
my $ciphertext = $self->secret;
return decrypt_aes_256_cbc(\$ciphertext, $passphrase);
}
sub decrypt_secret_passphrase {
my $self = shift;
my $private_key = shift or _usage(q{$file->decrypt_secret_passphrase($private_key)});
die "Private key '$private_key' not found.\n" unless -e $private_key && !-d $private_key;
my $info = read_openssh_key_fingerprint($private_key);
my $fingerprint = $info->{fingerprint};
my $keys = $self->keys;
if (my $key = $keys->{$fingerprint}) {
return decrypt_rsa(\$key->{secret_passphrase}, $private_key);
}
die "Private key '$private_key' not able to decrypt the keyfile.\n";
}
sub encrypt_secret {
my $self = shift;
my $secret = shift or _usage(q{$file->encrypt_secret($secret)});
my $passphrase = shift or _usage(q{$file->encrypt_secret($secret)});
my $ciphertext = encrypt_aes_256_cbc($secret, $passphrase);
$self->info->{secret} = $ciphertext;
lib/App/GroupSecret/File.pm view on Meta::CPAN
=head2 delete_key
$file->delete_key($fingerprint);
Delete a key from the keyfile.
=head2 decrypt_secret
$secret = $file->decrypt_secret(passphrase => $passphrase);
$secret = $file->decrypt_secret(private_key => $private_key);
Get the decrypted secret.
=head2 decrypt_secret_passphrase
$passphrase = $file->decrypt_secret_passphrase($private_key);
Get the decrypted secret passphrase.
=head2 encrypt_secret
$file->encrypt_secret($secret, $passphrase);
Set the secret by encrypting it with a 256-bit passphrase.
Passphrase must be 32 bytes.
( run in 0.246 second using v1.01-cache-2.11-cpan-a5abf4f5562 )