Mojo-SAML

 view release on metacpan or  search on metacpan

lib/Mojo/SAML/Document/KeyInfo.pm  view on Meta::CPAN


use Mojo::Template;
use Mojo::XMLSig;

my $isa = sub {
  my ($obj, $class) = @_;
  Scalar::Util::blessed($obj) && $obj->isa($class);
};

has template => sub { shift->build_template(<<'XML') };
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
  % if (my $name = $self->name) {
  <KeyName><%= $name %></KeyName>
  % }
  <X509Data>
    <X509Certificate><%= $self->x509_string // '' %></X509Certificate>
  </X509Data>
</KeyInfo>
XML

has 'cert';

lib/Mojo/SAML/Document/Signature.pm  view on Meta::CPAN

package Mojo::SAML::Document::Signature;

use Mojo::Base 'Mojo::SAML::Document';

use Mojo::SAML::Document::KeyInfo;

has template => sub { shift->build_template(<<'XML') };
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:SignedInfo>
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
    % for my $ref (@{ $self->references }) {
    %= tag 'ds:Reference' => URI => "#$ref" => begin
      <ds:Transforms>
        <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      </ds:Transforms>
      <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
      <ds:DigestValue></ds:DigestValue>
    </ds:Reference>
    % end
    % }
  </ds:SignedInfo>
  <ds:SignatureValue></ds:SignatureValue>
  % if (my $info = $self->key_info) {
    <%= $info %>
  % }
</ds:Signature>

lib/Mojo/SAML/Entity.pm  view on Meta::CPAN

use Mojo::Util;
use Mojo::URL;
use Scalar::Util ();

my $isa = sub {
  my ($obj, $class) = @_;
  Scalar::Util::blessed($obj) && $obj->isa($class);
};
my %ns = (
  md => 'urn:oasis:names:tc:SAML:2.0:metadata',
  ds => 'http://www.w3.org/2000/09/xmldsig#',
);
my %uses = (
  encryption => 1,
  signing    => 1,
);

has entity_id => sub {
  my $dom = shift->metadata;
  my $desc = $dom->find('md|EntityDescriptor[entityID]', %ns);
  Carp::croak 'Multiple EntityDescriptor elements found' if $desc->size > 1;

lib/Mojo/XMLSig.pm  view on Meta::CPAN

use Carp ();
use Digest::SHA;
use Mojo::DOM;
use Mojo::Util;
use XML::CanonicalizeXML;

my $isa = sub {
  my ($obj, $class) = @_;
  Scalar::Util::blessed($obj) && $obj->isa($class);
};
my %ns = (ds => 'http://www.w3.org/2000/09/xmldsig#');

my %actions = (
  # xml
  'http://www.w3.org/2000/09/xmldsig#enveloped-signature' => \&_enveloped_signature,

  # canonical
  'http://www.w3.org/TR/2001/REC-xml-c14n-20010315' => _mk_canon(0,0),
  'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments' => _mk_canon(0,1),
  'http://www.w3.org/2006/12/xml-c14n11' => _mk_canon(2,0),
  'http://www.w3.org/2006/12/xml-c14n11#WithComments' => _mk_canon(2,1),
  'http://www.w3.org/2001/10/xml-exc-c14n#' => _mk_canon(1,0),
  'http://www.w3.org/2001/10/xml-exc-c14n#WithComments' => _mk_canon(1,1),

  # encoding
  'http://www.w3.org/2000/09/xmldsig#base64' => sub { Mojo::Util::b64_encode(shift, '') },

  # digest
  'http://www.w3.org/2000/09/xmldsig#sha1'  => sub { _get_digest(sha1 => @_) },
  'http://www.w3.org/2001/04/xmlenc#sha256' => sub { _get_digest(sha256 => @_) },
  'http://www.w3.org/2001/04/xmldsig-more#sha224' => sub { _get_digest(sha224 => @_) },
  'http://www.w3.org/2001/04/xmldsig-more#sha384' => sub { _get_digest(sha384 => @_) },
  'http://www.w3.org/2001/04/xmlenc#sha512' => sub { _get_digest(sha512 => @_) },

  # sign
  'http://www.w3.org/2000/09/xmldsig#rsa-sha1' => sub { _rsa(sha1 => @_) },
  'http://www.w3.org/2001/04/xmldsig-more#rsa-sha224' => sub { _rsa(sha224 => @_) },
  'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' => sub { _rsa(sha256 => @_) },
  'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384' => sub { _rsa(sha384 => @_) },
  'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512' => sub { _rsa(sha512 => @_) },
);

sub digest { _digest(0, @_) }

sub format_cert {
  my $cert = shift;
  $cert =~ s/\n//g;
  $cert = Mojo::Util::trim $cert;
  $cert = Mojo::Util::b64_encode(Mojo::Util::b64_decode($cert), "\n");
  $cert = Mojo::Util::trim $cert;

lib/Mojo/XMLSig.pm  view on Meta::CPAN


  # verify using an embedded certificate
  my $verified = Mojo::XMLSig::verify($signed);

  # verify using a known public certificate
  my $pub = Crypt::OpenSSL::RSA->new_public_key(...);
  my $verified = Mojo::XMLSig::verify($signed, $pub);

=head1 DESCRIPTION

L<Mojo::XMLSig> is an implementation of the L<XML Signature Syntax and Processing Version 1.1|https://www.w3.org/TR/xmldsig-core1/> spec.
It allows a user to sign and verify documents in XML format.
This is a requirement for many SAML documents and recommended in nearly all others.

It is important to note that module does not create any tags.
Rather it relies on you passing in a document with the relevant sections included.
It will then fill out the computed sections given the parameters and algorithms specified.
In this way signing and verifying are actually quite similar.

An example document to be signed could be as follows.

  <Thing ID="abc123">
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
        <ds:Reference URI="#abc123">
          <ds:Transforms>
            <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
          </ds:Transforms>
          <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          <ds:DigestValue></ds:DigestValue>
        </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue></ds:SignatureValue>
      <ds:KeyInfo>
        <ds:X509Data>
          <ds:X509Certificate>$cert</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </ds:Signature>

lib/Mojolicious/Plugin/SAML.pm  view on Meta::CPAN

      assertion_consumer_service_index => 0,
      is_passive => $passive,
      nameid_policy => NameIDPolicy->new(format => 'unspecified'),
      destination => "$url",
    );

    if ($binding eq 'HTTP-Redirect') {
      $url->query(SAMLRequest => $req->to_string_deflate);

      if ($sign) {
        $url->query({SigAlg => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'});
        $key->use_sha256_hash;
        my $val = $url->query->to_string;
        my $sig = $key->sign($val);
        $url->query({Signature => Mojo::Util::b64_encode($sig, '')});
      }

      $c->redirect_to($url);
    } else {
      Carp::croak "Binding '$binding' is not implemented by saml.authn_request helper";
    }

t/keycloak_saml_response.xml  view on Meta::CPAN

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Destination="https://demo.jberger.pl/saml" ID="ID_ede25624-e6c6-48ab-8a6d-9825e1b8077b" InResponseTo="MOJOSAML_78BA184C-52E5-11E8-9B...

t/xmlsig.t  view on Meta::CPAN


subtest 'create document, sign, and verify' => sub {
  my $cert = path('t/test.cer')->slurp;
  my $x509 = Crypt::OpenSSL::X509->new_from_string($cert);
  my $pub  = Crypt::OpenSSL::RSA->new_public_key($x509->pubkey);
  my $key  = Crypt::OpenSSL::RSA->new_private_key(path('t/test.key')->slurp);

  $cert = Mojo::XMLSig::trim_cert($cert);

  my $xml = <<"XML";
<Thing ID="abc123"><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:SignedInfo>
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
    <ds:Reference URI="#abc123">
      <ds:Transforms>
        <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      </ds:Transforms>
      <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
      <ds:DigestValue></ds:DigestValue>
    </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue></ds:SignatureValue>
    <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
  <X509Data>
    <X509Certificate>$cert</X509Certificate>
  </X509Data>
</KeyInfo>

</ds:Signature>

  <Important>Cool Stuff</Important>
</Thing>
XML



( run in 1.828 second using v1.01-cache-2.11-cpan-71847e10f99 )