NAME

Crypt::MagicSignatures::Envelope - MagicEnvelopes for the Salmon Protocol

SYNOPSIS

use Crypt::MagicSignatures::Envelope;

my $me = Crypt::MagicSignatures::Envelope->new({
  data => 'Some arbitrary string.'
});

$me->sign('key-01' => 'RSA.vsd...');

if ($me->verify('RSA.vsd...')) {
  print 'Signature is verified!';
};

DESCRIPTION

Crypt::MagicSignatures::Envelope implements MagicEnvelopes with MagicSignatures as described in the MagicSignatures Specification to sign messages of the Salmon Protocol. MagicSignatures is a "robust mechanism for digitally signing nearly arbitrary messages".

This module is an early release! There may be significant changes in the future.

ATTRIBUTES

alg

my $alg = $me->alg;

The algorithm used for signing the MagicEnvelope. Defaults to RSA-SHA256, which is the only supported algorithm.

data

my $data = $me->data;
$me->data('Hello world!');

The decoded data folded in the MagicEnvelope.

data_type

my $data_type = $me->data_type;
$me->data_type('text/plain');

The mime type of the data folded in the MagicEnvelope. Defaults to text/plain.

dom

my $me = Crypt::MagicSignatures::Envelope->new( data => <<'XML' );
<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns='http://www.w3.org/2005/Atom'>
  <author><uri>alice@example.com</uri></author>
</entry>
XML

$me->data_type('application/atom+xml');

# alice@example.com
print $me->dom->at('author > uri')->text;

The Mojo::DOM object of the decoded data, if the MagicEnvelope contains XML.

This attribute is experimental and may change without warning!

encoding

my $encoding = $me->encoding;

The encoding of the MagicEnvelope. Defaults to base64url, which is the only encoding supported.

signature

my $sig = $me->signature;
my $sig = $me->signature('key-01');

A signature of the MagicEnvelope. For retrieving a specific signature, pass a key id, otherwise a default signature will be returned.

If a matching signature is found, the signature is returned as a hash reference, containing base64url encoded data for value and possibly a key_id. If no matching signature is found, a false value is returned.

signature_base

my $base = $me->signature_base;

The signature base string of the MagicEnvelope as described in the MagicSignatures Specification.

signed

# With key id
if ($me->signed('key-01')) {
  print 'MagicEnvelope is signed with key-01.';
}

# Without key id
elsif ($me->signed) {
  print 'MagicEnvelope is signed.';
}

else {
  print 'MagicEnvelope is not signed.';
};

Returns a true value in case the MagicEnvelope is signed at least once. Accepts optionally a key_id and returns a true value, if the MagicEnvelope was signed with this specific key.

METHODS

new

$me = Crypt::MagicSignatures::Envelope->new(<<'MEXML');
<?xml version="1.0" encoding="UTF-8"?>
<me:env xmlns:me="http://salmon-protocol.org/ns/magic-env">
  <me:data type="text/plain">
    U29tZSBhcmJpdHJhcnkgc3RyaW5nLg==
  </me:data>
  <me:encoding>base64url</me:encoding>
  <me:alg>RSA-SHA256</me:alg>
  <me:sig key_id="my-01">
    S1VqYVlIWFpuRGVTX3l4S09CcWdjRVFDYVluZkI5Ulh4dmRFSnFhQW5XUmpB
    UEJqZUM0b0lReER4d0IwWGVQZDhzWHAxN3oybWhpTk1vNHViNGNVOVE9PQ==
  </me:sig>
</me:env>
MEXML

The constructor accepts MagicEnvelope data in various formats. It accepts MagicEnvelopes in the XML format or an XML document including a MagicEnvelope provenance element as described in the MagicSignatures Specification.

Additionally it accepts MagicEnvelopes in the JSON notation or defined by the same attributes as the JSON notation (but with the data not encoded) as described in the MagicSignatures Specification. The latter is the common way to fold new envelopes.

$me = Crypt::MagicSignatures::Envelope->new(<<'MEJSON');
{
  "data_type": "text\/plain",
  "data":"U29tZSBhcmJpdHJhcnkgc3RyaW5nLg==",
  "alg":"RSA-SHA256",
  "encoding":"base64url",
  "sigs": [
    { "key_id": "my-01",
      "value":"S1VqYVlIWFpuRGVTX3l4S09CcWdjRV..."
    }
  ]
}
MEJSON

$me = Crypt::MagicSignatures::Envelope->new(
  data      => 'Some arbitrary string.',
  data_type => 'plain_text',
  alg       => 'RSA-SHA256',
  encoding  => 'base64url',
  sigs => [
    {
      key_id => 'my-01',
      value  => 'S1VqYVlIWFpuRGVTX3l4S09CcWdjRV...'
    }
  ]
);

Finally the constructor accepts MagicEnvelopes in the compact MagicEnvelope notation as described in the MagicSignatures Specification.

$me = Crypt::MagicSignatures::Envelope->new(<<'MECOMPACT');
  bXktMDE=.S1VqYVlIWFpuRGVTX3l4S09CcWdjRVFDYVlu
  ZkI5Ulh4dmRFSnFhQW5XUmpBUEJqZUM0b0lReER4d0IwW
  GVQZDhzWHAxN3oybWhpTk1vNHViNGNVOVE9PQ==.U29tZ
  SBhcmJpdHJhcnkgc3RyaW5nLg.dGV4dC9wbGFpbg.YmFz
  ZTY0dXJs.UlNBLVNIQTI1Ng
MECOMPACT

sign

$me->sign('key-01' => 'RSA.hgfrhvb ...')
   ->sign('RSA.hgfrhvb ...')
   ->sign('RSA.hgfrhvb ...', -data)
   ->sign('key-02' => 'RSA.hgfrhvb ...', -data);

my $mkey = Crypt::MagicSignatures::Key->new('RSA.hgfrhvb ...')
$me->sign($mkey);

Adds a signature to the MagicEnvelope.

For adding a signature, the private key with an optional prepended key id has to be given. The private key can be a Crypt::MagicSignatures::Key object, a MagicKey string as described in the MagicSignatures Specification or a hash reference containing the non-generation parameters accepted by the Crypt::MagicSignatures::Key constructor. Optionally a flag -data can be passed, that will sign the data payload instead of the signature base string as defined in the MagicSignatures Specification (this is implemented for compatibility with non-standard implementations).

On success, the method returns the MagicEnvelope, otherwise it returns a false value.

A MagicEnvelope can be signed multiple times.

This method is experimental and may change without warning!

verify

my $mkey = Crypt::MagicSignatures::Key->new( 'RSA.hgfrhvb ...' )

$me->verify(
  'RSA.vsd...',
  $mkey,
  ['key-01' => 'RSA.hgfrhvb...', -data]
);

Verifies a signed envelope against a bunch of given public MagicKeys. Returns a true value on success, otherwise false.

If one key succeeds, the envelope is verified.

An element can be a Crypt::MagicSignatures::Key object, a MagicKey string as described in the MagicSignatures Specification or a hash reference containing the non-generation parameters accepted by the Crypt::MagicSignatures::Key constructor.

For referring to a certain key, an array reference can be passed, containing the key (defined as described above) with an optional prepended key id and an optional flag appended, referring to the data to be verified. Conforming with the specification the default value is -base, referring to the base signature string of the MagicEnvelope. -data will verify against the data only, -compatible will first try to verify against the base signature string and then will verify against the data on failure (this is implemented for compatibility with non-standard implementations).

This method is experimental and may change without warning!

to_compact

my $compact_string = $me->to_compact;

Returns the MagicEnvelope in compact notation as described in the MagicSignatures Specification.

to_json

my $json_string = $me->to_json;

Returns the MagicEnvelope as a stringified json representation as described in the MagicSignatures Specification.

to_xml

my $xml_string = $me->to_xml;
my $xml_provenance_string = $me->to_xml(1);

Returns the MagicEnvelope as a stringified xml representation as described in the MagicSignatures Specification. If a true value is passed, a provenance fragment will be returned instead of a valid xml document.

DEPENDENCIES

Crypt::MagicSignatures::Key, Mojolicious.

KNOWN BUGS AND LIMITATIONS

The signing and verifification is not guaranteed to be compatible with other implementations! Implementations like StatusNet (Identi.ca), MiniMe, and examples from the reference implementation are tested.

See the test suite for further information.

AVAILABILITY

https://github.com/Akron/Crypt-MagicSignatures-Key

COPYRIGHT AND LICENSE

Copyright (C) 2011-2013, Nils Diewald.

This program is free software, you can redistribute it and/or modify it under the same terms as Perl.