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

Thank you Hippo for your response.

As you have probably worked out, I'm pretty new to this sort of thing, it turns out I sent them my key in order that they can check my signatures from my SAML requests - just haven't got to that bit yet.

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

I have noticed that the XML::Sig module supplied with Net::SAML2 is wildly different from the standalone, thanks. I have been debugging with this, printing out all the bits as I go.

I can see that it's calling my $rsa_pub = Crypt::OpenSSL::RSA->new_public_key($cert->pubkey) - and the public key in $cert->pubkey looks like a perfectly good public key to me - starting with the text -----BEGIN RSA PUBLIC KEY----, ending with the END - etc.

Then it calls if ($rsa_pub->verify( $canonical,  $bin_signature )) {

$bin_signature is a base 64 decoded version of the signature node. $canonical appears to be the value of the "digestValue" node. This is also base64 encoded and I am told it is actually a binary value, but the module doesn't b64 decode this - I don't know if it should or not.

Either way, trying b64 decoded and the regular $canonical value, the response from this verify command is consistently false.

Does any of this mean anything to you?!

Thanks,
Matt

Replies are listed 'Best First'.
Re^3: Validating XML Signatures / SSL Certificate question (using Net::SAML)
by hippo (Archbishop) on Apr 05, 2017 at 16:03 UTC
    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.

      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).