diff options
author | dakkar <dakkar@thenautilus.net> | 2011-03-25 21:43:42 +0000 |
---|---|---|
committer | dakkar <dakkar@thenautilus.net> | 2011-03-25 21:43:42 +0000 |
commit | 75aa29074f273164a8029d2fd8c963f8de5aea49 (patch) | |
tree | 7dca22b15aa45172a36c3bf83035bb610e9ff109 /lib/DeWeave/Crypto.pm | |
parent | broken first stab (diff) | |
download | DeWeave-75aa29074f273164a8029d2fd8c963f8de5aea49.tar.gz DeWeave-75aa29074f273164a8029d2fd8c963f8de5aea49.tar.bz2 DeWeave-75aa29074f273164a8029d2fd8c963f8de5aea49.zip |
it might even complie
Diffstat (limited to 'lib/DeWeave/Crypto.pm')
-rw-r--r-- | lib/DeWeave/Crypto.pm | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/lib/DeWeave/Crypto.pm b/lib/DeWeave/Crypto.pm new file mode 100644 index 0000000..618e095 --- /dev/null +++ b/lib/DeWeave/Crypto.pm @@ -0,0 +1,126 @@ +package DeWeave::Crypto; +use Moose; +use namespace::autoclean; +use MooseX::Types::Moose qw(HashRef Str); +use MooseX::Types::Structured qw(Tuple); +use JSON::Any; +use Try::Tiny; +use Digest::SHA (); +use MIME::Base32 'RFC'; +use Crypt::CBC; + +has storage => ( + isa => 'DeWeave::Storage', + required => 1, + is => 'ro', +); + +has sync_key => ( + isa => Str, + required => 1, + is => 'ro', +); + +sub _byte_sync_key { + my ($self) = @_; + + my $key = $self->sync_key; + $key =~ y{89}{lo}; + return MIME::Base32::decode($key); +} + +has _hmac_input => ( + isa => Str, + default => 'Sync-AES_256_CBC-HMAC256', + is => 'ro', +); + +has _encryption_key => ( + isa => Str, + lazy_build => 1, + is => 'ro', +); + +sub _build__encryption_key { + my ($self) = @_; + + my $secret = $self->_hmac_input + . $self->storage->username . "\x01"; + return Digest::SHA::hmac_sha256($secret, $self->_byte_sync_key); +} + +has _hmac_key => ( + isa => Str, + lazy_build => 1, + is => 'ro', +); + +sub _build__hmac_key { + my ($self) = @_; + + my $secret = $self->_encryption_key . $self->_hmac_input + . $self->storage->username . "\x02"; + return Digest::SHA::hmac_sha256($secret, $self->_byte_sync_key); +} + +has _keys => ( + isa => HashRef[Tuple[Str,Str]], + init_arg => undef, + lazy_build => 1, + is => 'ro', + traits => ['Hash'], + handles => { + _has_collection_keys => 'exists', + _get_collection_keys => 'get', + }, +); + +sub _build__keys { + my ($self) = @_; + + my $j = JSON::Any->new; + + my $keys_payload = $self->storage->get_item('crypto/keys'); + my $struct = $j->decode($keys_payload); + + my $keys = { + default => $struct->{default}, + %{$struct->{collections}}, + }; + + return $keys; +} + +sub keys_for_collection { + my ($self,$collection) = @_; + + if ($self->_has_collection_keys($collection)) { + return $self->_get_collection_keys($collection); + } + else { + return $self->_get_collection_keys('default'); + } +} + +sub decrypt { + my ($self,$args) = @_; + + my $iv = $args->{IV}; + my $hmac = $args->{hmac}; + my $ct = $args->{ciphertext}; + + my $cipher = Crypt::CBC->new( + -key => $self->_encryption_key, + -cipher => 'Crypt::OpenSSL::AES', + -iv => $iv, + -header => 'none', + -padding => 'null', + -literal_key => 1, + ); + + my $pt = $cipher->decrypt($ct); + # TODO verify + return $pt; +} + +1; |