WWW-LetsEncrypt

 view release on metacpan or  search on metacpan

lib/WWW/LetsEncrypt/JWK/RSA.pm  view on Meta::CPAN

package WWW::LetsEncrypt::JWK::RSA;
$WWW::LetsEncrypt::JWK::RSA::VERSION = '0.002';
use strict;
use warnings;

use Carp qw(confess);
use Digest::SHA;
use MIME::Base64 qw(encode_base64url decode_base64url);

use Crypt::OpenSSL::Bignum;
use Crypt::OpenSSL::RSA;
use JSON;
use Moose;

with qw(WWW::LetsEncrypt::JWK WWW::LetsEncrypt::JWA);

sub generate_new {
	my ($key_length) = @_;

	confess 'Invalid key length' if $key_length < 2048 || $key_length > 4096;

	my $RSA = Crypt::OpenSSL::RSA->generate_key($key_length);
	return _new_from_object($RSA);
}

sub get_privatekey_string {
	my ($self) = @_;
	return $self->_RefObj->get_private_key_string();
}

sub load_cert {
	my ($args_ref) = @_;
	my $private_key = $args_ref->{private_key};
	my $alg         = $args_ref->{alg};

	confess 'Private Key must be provided' if !$private_key;

	my $RSA = Crypt::OpenSSL::RSA->new_private_key($private_key);
	confess 'Cannot load key.' if !$RSA;

	return _new_from_object($RSA, $alg);
}

sub load_parameters {
	my ($args_ref) = @_;
	my $parameters = $args_ref->{parameters};
	my $alg        = $args_ref->{alg};

	my @required_parameters = qw{n e d p q};

	for my $param (@required_parameters) {
		confess "Required parameter '$param' not found!" if !$parameters->{$param};
	}

	my @params;
	for my $parameter (@required_parameters) {
		my $decoded_string = decode_base64url($parameters->{$parameter});
		my $param = Crypt::OpenSSL::Bignum->new_from_bin($decoded_string);
		push @params, $param;
	}

	my $RSA = Crypt::OpenSSL::RSA->new_key_from_parameters(@params);
	confess "Could not load key." if !$RSA;
	return _new_from_object($RSA, $alg);
}

sub sign {
	my ($self, $message) = @_;
	$self->_set_hash;
	return $self->_RefObj->sign($message);
}

sub thumbprint {
	my ($self) = @_;

	# RFC requires the keys to be sorted lexically.
	my $JSON = JSON->new();
	$JSON->canonical(1);

	my %pubkey = $self->_get_public_key_components();
	$pubkey{kty} = 'RSA';

	my $hash_method = Digest::SHA->can($self->_hash);
	confess "Hashing method " . $self->_hash . " is not supported!" if !$hash_method;

	my $jsonified_sorted_pk   = $JSON->encode(\%pubkey);
	my $digested_jsonified_pk = $hash_method->($jsonified_sorted_pk);
	return encode_base64url($digested_jsonified_pk);
}

sub _get_public_key_components {
	my ($self) = @_;

	my %b64_pk;

	my ($n, $e) = map { $_->to_bin() } $self->_RefObj->get_key_parameters();

	$b64_pk{n} = encode_base64url($n);



( run in 0.746 second using v1.01-cache-2.11-cpan-39bf76dae61 )