in reply to Re^2: Validating XML Signatures / SSL Certificate question (using Net::SAML)
in thread Validating XML Signatures / SSL Certificate question (using Net::SAML)

So I now understand that they have signed this with their *private* key, and I can do (whatever it is I need to do) by using their public key which is sent as part of the SAML assertion, and I don't need any of my own keys for this. Is that correct? :p

Yes, that is correct.

I've had problems in the past with XML::Sig failing to extract the signer's certificate correctly. You might try initialising the XML::Sig object with a local copy of that certificate just in case. eg:

my $verifier = XML::Sig->new ({ cert => '/path/to/signer/cert.pem' }) +; if ($verifier->verify ($saml_string_decoded) { # now do something with it

Also this specific version of XML::Sig has proven useful in the past, so you might try it as an alternative to see if it helps any. It does sound now like you are on the right road.

  • Comment on Re^3: Validating XML Signatures / SSL Certificate question (using Net::SAML)
  • Download Code

Replies are listed 'Best First'.
Re^4: Validating XML Signatures / SSL Certificate question (using Net::SAML)
by MattP (Novice) on Apr 05, 2017 at 19:49 UTC

    Thanks again Hippo!

    I've gone right down to basics now and made my own script without XML::Sig but nabbed some bits from it, which is working absolutely fine. This will encrypt a string with the public key and decrypt it with the private. Also sign it with the private and verify it with the public. Im using my own keys and so far so good and getting me understanding what's going on.

    One thing has amazed me however - this line - my $cert = Crypt::OpenSSL::X509->new_from_string($certificate);- I can access the public key from the certificate after this line by using $cert->pubkey. It's different to my own public key however... but still works! How and why I have no idea.. wondering if this might be a clue as to what's going wrong with the SAML.. Can there be multiple public keys??! I may try getting the public key directly from the SAML provider tomorrow, also checking what hashing they are using. Another thread I saw suggested a possible platform difference regarding big and little endian data..

    Cheers :)

    #!/usr/bin/perl use Crypt::OpenSSL::Random; use Crypt::OpenSSL::RSA; use Crypt::OpenSSL::X509; use MIME::Base64; use strict; my $debug = 0; local $/ = undef; my $public_key= "/data/pubkey.pem"; open (FILE, $public_key) or die ("Cant open public key file"); my $public_key_string = <FILE>; close(FILE); my $private_key = "/data/private.pem"; open (FILE, $private_key) or die ("Cant open private key file"); my $private_key_string = <FILE>; close(FILE); my $public_cert = "/data/x509-public.pem"; open (FILE, $public_cert) or die ("Cant open certificate file"); my $certificate = <FILE>; close(FILE); print $certificate; my $cert = Crypt::OpenSSL::X509->new_from_string($certificate); print $cert->pubkey; print $public_key_string; # they're different $public_key_string=$cert->pubkey; # it's different to the one loaded f +rom file, but still works with my existing private key in the rest of + the code - remove this line to test the old $public_key_string value print $public_key_string; my $plaintext = "Some text here"; my $rsa_pub = Crypt::OpenSSL::RSA->new_public_key($public_key_string) +; my $rsa_priv = Crypt::OpenSSL::RSA->new_private_key($private_key_strin +g); my $ciphertext = $rsa_pub->encrypt($plaintext); # encrypt with th +e public key my $plaintext_back = $rsa_priv->decrypt($ciphertext); # decrypt with +the private key print "Plain text back is " . $plaintext_back . "\n"; # Works fine if ($debug){ # debugging only print "private key is:\n", $rsa_priv->get_private_key_string() +; print "public key (in PKCS1 format) is:\n", $rsa_pub->get_public_key_string(); print "public key (in X509 format) is:\n", $rsa_pub->get_public_key_x509_string(); } $rsa_priv->use_md5_hash(); # use_sha1_hash is the default $rsa_pub->use_md5_hash(); my $signature = $rsa_priv->sign($plaintext); # sign with private key if ($rsa_pub->verify($plaintext, $signature)) { # verify with public k +ey print "Signature Verified successfully"; } else { print " *** Not verified"; }
      It's different to my own public key however

      Is it a different public key or merely a different representation of the same public key? How did you generate the contents of /data/pubkey.pem in the first place?

      Good to hear you are making solid progress regardless. My experience of working with SAML has taught me that it is essentially a war of attrition. If you persist you will eventually succeed (although you will curse both the spec designers and the platform implementers before you are through).

        Hi Hippo,

        This is still going on! Currently there seems to be a difference between what is being signed by the NSL team and what the code is expecting - the Net::SAML modules were expecting the assertion node to be signed, we are receiving a signed full XML document.

        With amended XML (a signed assertion node) we got through the part where XML::Sig was failing -  if ($rsa_pub->verify( $canonical,  $bin_signature )) { - I'm not sure if this is verifying the signature or just the certificate somehow, it's good that it passes now but there are however several steps after this where it fails. It proceeds to perform transforms on the XML before running  if ($digest eq _trim(encode_base64($digest_bin))); - we're now failing at this point with two completely different strings.

        Which one of these tests actually verifies the signature I'm not sure, nor why there are these two tests, I don't suppose you have any idea?

        Either way, getting there (very, very slowly)

        Cheers,
        Matt