Skip to main content

Signature verification for InCommon SAML metadata using xmlsec1 fails [Resolved]

InCommon Federation provides IdP and SP metadata. Their refresh policy recommends frequent checking of the metadata aggregate to use the most recent version. They strongly recommend InCommon SPs refresh and verify metadata at least daily.

Following instruction provided on Metadata Consumption page, I download an aggregate and obtain an authentic copy of the Metadata Signing Certificate.

Then, I'm to "Verify the XML signature on downloaded metadata." This is where I'm having issues. I'm able to verify the downloaded metadata with the embedded x509 certificate, but cannot verify using the separately downloaded Metadata Signing Certificate.

I have the two files downloaded from InCommon:

  • xml: InCommon-metadata-idp-only.xml
  • private signing key: inc-md-cert.pem

I thought I should be able to run the command:

# xmlsec1 --verify \
     --id-attr:ID urn:oasis:names:tc:SAML:2.0:metadata:EntitiesDescriptor \
     --privkey-pem ./inc-md-cert.pem \

That fails saying "Failed to load private key from ./inc-md-cert.pem". I can verify it contains a valid key using openssl x509 -text -in ./inc-md-cert.pem. ( and it's readable, and that's the correct path.) Fails the same way if I reference it with --privkey-pem or --pubkey-pem.

Now, if I use --pubkey-cert-pem ./inc-md-cert.pem instead, it runs without error, indicating OK SignedInfo References (ok/all): 1/1.

But no, it's clearly ignoring my private signing key, and simply doing verification based on the key embedded in the metadata.xml file. (I can remove the --pubkey-cert-pem argument completely, and the verify still works, using the embedded x509 certificate.


Given that the provided signature file is self-signed (by the organization) I tried adding itself as a trusted certificate. For example if you try basic verify with openssl, compare:

# openssl verify ./inc-md-cert.pem
error 18 at 9 depth lookup:self signed certificate
# openssl verify -CAfile ./inc-md-cert.pem ./inc-md-cert.pem
./inc-md-cert.pem: OK

So what if that's the problem? So I try adding the --trusted-pem option

# xmlsec1 --verify \
     --id-attr:ID urn:oasis:names:tc:SAML:2.0:metadata:EntitiesDescriptor \
     --privkey-pem ./inc-md-cert.pem \
     --trusted-pem ./inc-md-cert.pem \
   obj=unknown:subj=PEM_read_bio_PrivateKey and PEM_read_bio_PUBKEY:
   error=4:crypto library function failed: 
   error=1:xmlsec library function failed:
   error=1:xmlsec library function failed:uri=./inc-md-cert.pem
Error: failed to load public key from "./inc-md-cert.pem".
Error: keys manager creation failed

Fundamental error on my part, I assume, as this can't be so difficult: How do I use an external key (provided by InCommon) to verify the signature of the metadata file (provided by InCommon)?

Question Credit: pbuck
Question Reference
Asked December 5, 2018
Tags: openssl, saml
Posted Under: Network
1 Answers

One solution, though it feels a bit unsatisfying:

a) Verify the InCommon metadata file using the embedded certificate.

# xmlsec1  --verify --id-attr:ID \ 
        urn:oasis:names:tc:SAML:2.0:metadata:EntitiesDescriptor  \
SignedInfo References (ok/all): 1/1
Manifests References (ok/all): 0/0

b) Then, simply compare the embedded certificate with the separately downloaded certificate -- they should match, modulo white space. Note that one or the other certificates may be chained, which you should ignore for comparison purposes.

credit: pbuck
Answered December 5, 2018
Your Answer