Skip to content

perl-net-saml2/perl-XML-Sig

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NAME
    XML::Sig - XML::Sig - A toolkit to help sign and verify XML Digital
    Signatures

VERSION
    version 0.65

SYNOPSIS
       my $xml = '<foo ID="abc">123</foo>';
       my $signer = XML::Sig->new({
         key => 'path/to/private.key',
       });

       # create a signature
       my $signed = $signer->sign($xml);
       print "Signed XML: $signed\n";

       # verify a signature
       $signer->verify($signed)
         or die "Signature Invalid.";
       print "Signature valid.\n";

DESCRIPTION
    This perl module provides two primary capabilities: given an XML string,
    create and insert digital signatures, or if one is already present in
    the string verify it -- all in accordance with the W3C standard
    governing XML signatures.

NAME
    XML::Sig - A toolkit to help sign and verify XML Digital Signatures.

PREREQUISITES
    *   Digest::SHA

    *   XML::LibXML

    *   MIME::Base64

    *   Crypt::OpenSSL::X509

    *   Crypt::OpenSSL::Bignum

    *   Crypt::OpenSSL::RSA

    *   Crypt::OpenSSL::DSA

    *   Crypt::PK::ECC

USAGE
  SUPPORTED ALGORITHMS & TRANSFORMS
    This module supports the following signature methods:

    *   DSA

    *   RSA

    *   RSA encoded as x509

    *   ECDSA

    *   ECDSA encoded as x509

    *   HMAC

    This module supports the following canonicalization methods and
    transforms:

    *   Enveloped Signature

    *   REC-xml-c14n-20010315#

    *   REC-xml-c14n-20010315#WithComments

    *   REC-xml-c14n11-20080502

    *   REC-xml-c14n11-20080502#WithComments

    *   xml-exc-c14n#

    *   xml-exc-c14n#WithComments

  OPTIONS
    Each of the following options are also accessors on the main XML::Sig
    object. TODO Not strictly correct rewrite

    key The path to a file containing the contents of a private key. This
        option is used only when generating signatures.

    cert
        The path to a file containing a PEM-formatted X509 certificate. This
        option is used only when generating signatures with the "x509"
        option. This certificate will be embedded in the signed document,
        and should match the private key used for the signature.

    cert_text
        A string containing a PEM-formatted X509 certificate. This option is
        used only when generating signatures with the "x509" option. This
        certificate will be embedded in the signed document, and should
        match the private key used for the signature.

    x509
        Takes a true (1) or false (0) value and indicates how you want the
        signature to be encoded. When true, the X509 certificate supplied
        will be encoded in the signature. Otherwise the native encoding
        format for RSA, DSA and ECDSA will be used.

    sig_hash
        Passing sig_hash to new allows you to specify the SignatureMethod
        hashing algorithm used when signing the SignedInfo. RSA and ECDSA
        supports the hashes specified sha1, sha224, sha256, sha384 and
        sha512

        DSA supports only sha1 and sha256 (but you really should not sign
        anything with DSA anyway). This is over-ridden by the key's
        signature size which is related to the key size. 1024-bit keys
        require sha1, 2048-bit and 3072-bit keys require sha256.

    digest_hash
        Passing digest_hash to new allows you to specify the DigestMethod
        hashing algorithm used when calculating the hash of the XML being
        signed. Supported hashes can be specified sha1, sha224, sha256,
        sha384, sha512, ripemd160

    hmac_key
        Base64 encoded hmac_key

    key_name
        The name of the key that should be referenced. In the case of xmlsec
        the --keys-file (ex. t/xmlsec-keys.xml) holds keys with a KeyName
        that is referenced by this name.

    no_xml_declaration
        Some applications such as Net::SAML2 expect to sign a fragment of
        the full XML document so is this is true (1) it will not include the
        XML Declaration at the beginning of the signed XML. False (0) or
        undefined returns an XML document starting with the XML Declaration.

    The following options act similar to "xmlsec --id-attr:ID
    <node-namespace-uri>:<name>"

    ns  A HashRef to namespaces you want to define to select the correct
        attribute ID on

    id_attr
        The xpath string you want to sign your XML message on.

  METHODS
   new(...)
    Constructor; see OPTIONS above.

   sign($xml)
    When given a string of XML, it will return the same string with a
    signature generated from the key provided when the XML::Sig object was
    initialized.

    This method will sign all elements in your XML with an ID (case
    sensitive) attribute. Each element with an ID attribute will be the
    basis for a seperate signature. It will correspond to the URI attribute
    in the Reference element that will be contained by the signature. If no
    ID attribute can be found on an element, the signature will not be
    created.

    The elements are signed in reverse order currently assuming (possibly
    incorrectly) that the lower element in the tree may need to be signed
    inclusive of its Signature because it is a child of the higher element.

    Arguments: $xml: string XML string

    Returns: string Signed XML

   verify($xml)
    Returns true or false based upon whether the signature is valid or not.

    When using XML::Sig exclusively to verify a signature, no key needs to
    be specified during initialization given that the public key should be
    transmitted with the signature.

    XML::Sig checks all signature in the provided xml and will fail should
    any signature pointing to an existing ID in the XML fail to verify.

    Should there be a Signature included that does not point to an existing
    node in the XML it is ignored and other Signaures are checked. If there
    are no other Signatures it will return false.

    Arguments: $xml: string XML string

    Returns: string Signed XML

   signer_cert()
    Following a successful verify with an X509 certificate, returns the
    signer's certificate as embedded in the XML document for verification
    against a CA certificate. The certificate is returned as a
    Crypt::OpenSSL::X509 object.

    Arguments: none

    Returns: Crypt::OpenSSL::X509: Certificate used to sign the XML

ABOUT DIGITAL SIGNATURES
    Just as one might want to send an email message that is
    cryptographically signed in order to give the recipient the means to
    independently verify who sent the email, one might also want to sign an
    XML document. This is especially true in the scenario where an XML
    document is received in an otherwise unauthenticated context, e.g. SAML.

    However XML provides a challenge that email does not. In XML, two
    documents can be byte-wise inequivalent, and semanticaly equivalent at
    the same time. For example:

        <?xml version="1.0"?>
        <foo>
          <bar />
        </foo>

        And:

        <?xml version="1.0"?>
        <foo>
          <bar></bar>
        </foo>

    Each of these document express the same thing, or in other words they
    "mean" the same thing. However if you were to strictly sign the raw text
    of these documents, they would each produce different signatures.

    XML Signatures on the other hand will produce the same signature for
    each of the documents above. Therefore an XML document can be written
    and rewritten by different parties and still be able to have someone at
    the end of the line verify a signature the document may contain.

    There is a specially subscribed methodology for how this process should
    be executed and involves transforming the XML into its canonical form so
    a signature can be reliably inserted or extracted for verification. This
    module implements that process.

  EXAMPLE SIGNATURE
    Below is a sample XML signature to give you some sense of what they look
    like. First let's look at the original XML document, prior to being
    signed:

      <?xml version="1.0"?>
      <foo ID="abc">
        <bar>123</bar>
      </foo>

    Now, let's insert a signature:

      <?xml version="1.0"?>
      <foo ID="abc">
        <bar>123</bar>
        <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
          <SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
            <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" />
            <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
            <Reference URI="#abc">
              <Transforms>
                <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
              </Transforms>
              <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
              <DigestValue>9kpmrvv3peVJpNSTRycrV+jeHVY=</DigestValue>
            </Reference>
          </SignedInfo>
          <SignatureValue>
            HXUBnMgPJf//j4ihaWnaylNwAR5AzDFY83HljFIlLmTqX1w1C72ZTuRObvYve8TNEbVsQlTQkj4R
            hiY0pgIMQUb75GLYFtc+f0YmBZf5rCWY3NWzo432D3ogAvpEzYXEQPmicWe2QozQhybaz9/wrYki
            XiXY+57fqCkf7aT8Bb6G+fn7Aj8gnZFLkmKxwCdyGsIZOIZdQ8MWpeQrifxBR0d8W1Zm6ix21WNv
            ONt575h7VxLKw8BDhNPS0p8CS3hOnSk29stpiDMCHFPxAwrbKVL1kGDLaLZn1q8nNRmH8oFxG15l
            UmS3JXDZAss8gZhU7g9T4XllCqjrAvzPLOFdeQ==
          </SignatureValue>
          <KeyInfo>
            <KeyValue>
              <RSAKeyValue>
                <Modulus>
                  1b+m37u3Xyawh2ArV8txLei251p03CXbkVuWaJu9C8eHy1pu87bcthi+T5WdlCPKD7KGtkKn9vq
                  i4BJBZcG/Y10e8KWVlXDLg9gibN5hb0Agae3i1cCJTqqnQ0Ka8w1XABtbxTimS1B0aO1zYW6d+U
                  Yl0xIeAOPsGMfWeu1NgLChZQton1/NrJsKwzMaQy1VI8m4gUleit9Z8mbz9bNMshdgYEZ9oC4bH
                  n/SnA4FvQl1fjWyTpzL/aWF/bEzS6Qd8IBk7yhcWRJAGdXTWtwiX4mXb4h/2sdrSNvyOsd/shCf
                  OSMsf0TX+OdlbH079AsxOwoUjlzjuKdCiFPdU6yAJw==
                </Modulus>
                <Exponent>Iw==</Exponent>
              </RSAKeyValue>
            </KeyValue>
          </KeyInfo>
        </Signature>
      </foo>

SEE ALSO
    <http://www.w3.org/TR/xmldsig-core/>

VERSION CONTROL
    <https://github.com/perl-net-saml2/perl-XML-Sig>

AUTHORS and CREDITS
    Author: Byrne Reese <byrne@majordojo.com>

    Thanks to Manni Heumann who wrote Google::SAML::Response from which this
    module borrows heavily in order to create digital signatures.

    Net::SAML2 embedded version amended by Chris Andrews <chris@nodnol.org>.

    Maintainer: Timothy Legge <timlegge@cpan.org>

AUTHORS
    *   Byrne Reese <byrne@cpan.org>

    *   Timothy Legge <timlegge@cpan.org>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2023 by Byrne Reese, Chris Andrews and
    Others; in detail:

      Copyright 2009       Byrne, Michael Hendricks
                2010       Chris Andrews
                2011       Chris Andrews, Oskari Okko Ojala
                2012       Chris Andrews, Peter Marschall
                2015       Mike Wisener
                2016       Jeff Fearn
                2017       Mike Wisener, xmikew
                2019-2021  Timothy Legge
                2022-2023  Timothy Legge, Wesley Schwengle

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.