Source

p5-rdf-crypt / lib / RDF / Crypt / Role / WithPublicKeys.pm

Full commit
package RDF::Crypt::Role::WithPublicKeys;

use 5.010;
use Any::Moose 'Role';

use Crypt::OpenSSL::RSA qw[];
use File::Slurp qw[slurp];
use RDF::TrineX::Functions -shortcuts;
use Web::ID;

use namespace::clean;

BEGIN {
	$RDF::Crypt::Role::WithPublicKeys::AUTHORITY = 'cpan:TOBYINK';
	$RDF::Crypt::Role::WithPublicKeys::VERSION   = '0.002';
}

has public_keys => (
	is         => 'ro',
	isa        => 'ArrayRef[Crypt::OpenSSL::RSA]',
	lazy_build => 1,
);

has webid => (
	is         => 'ro',
	isa        => 'Str',
	required   => 0,
);

has webid_san => (
	is         => 'ro',
	isa        => 'Web::ID::SAN::URI | Undef',
	lazy_build => 1,
	handles    => {
		webid_model  => 'model',
	},
);

sub new_from_file
{
	my ($class, $key_file) = @_;
	return $class->new_from_string( scalar slurp($key_file) );
}

sub new_from_string
{
	my ($class, $key_string) = @_;
	my $key = Crypt::OpenSSL::RSA->new_public_key($key_string);
	$class->new_from_pubkey($key);
}

sub new_from_pubkey
{
	my ($class, $key) = @_;
	$key->use_pkcs1_padding;
	# OpenSSL command-line tool defaults to this...
	$key->use_md5_hash;
	$class->new( public_keys => [$key] );
}

sub new_from_webid
{
	my ($class, $uri) = @_;
	$class->new(
		webid => "$uri",
	);
}

sub _build_webid_san
{
	my ($self) = @_;
	Web::ID::SAN::URI->new(value => $self->webid)
}

sub _build_public_keys
{
	my ($self) = @_;
	return unless $self->webid_san;
	
	[
		map {
			Crypt::OpenSSL::RSA->new_key_from_parameters(
				Crypt::OpenSSL::Bignum->new_from_decimal($_->modulus->bstr),   # n
				Crypt::OpenSSL::Bignum->new_from_decimal($_->exponent->bstr),  # e
			)
		}
		$self->webid_san->associated_keys
	]
}

1;