# Is it safe to include the public certificate in xml digital signatures?

### My understanding of XML Digital Signatures:

Let's use a SAML token as an example.

Note - for the sake of simplicity I'm omitting some details like CanonicalizationMethod, base64 encoding, etc.

In order for me to sign the <saml:Assertion> node I use a private/public key pair:

1. Create a hash of the <saml:Assertion> block and store it in a <ds:Reference> inside the <ds:SignedInfo> node.
2. Use the private key to encrypt the <ds:SignedInfo> node and store it in the <ds:SignatureValue> node.
3. Pass the public certificate in the <ds:KeyInfo> block.

To verify the signature I then:

1. decrypt the <ds:SignatureValue> node using the public certificate found in <ds:KeyInfo> and ensure that it is equal to the <ds:SignedInfo> block
2. ensure that the hash of the <saml:Assertion> node is equal to the digest stored in the <ds:Reference> node.

### My question:

What I don't understand is that in my opinion this doesn't verify the sender, it simply verifies that the private key component of the public certificate sent in the <ds:KeyInfo> node was used to sign the token. An attacker could create his own certificate pair and sign the token with that.

This risk is probably resolved by ensuring that the certificate is either signed by a certificate authority, but if the sender uses self-signed certificates the verifying party should NOT use the public certificate sent in the <ds:KeyInfo>, but rather obtain the public certificate from another trusted source.

Could someone please verify or point out how I'm misunderstanding XML Digital Signatures?

• "Use the private key to encrypt" and "decrypt .. using the public (key in the) certificate" are (barely) related to RSA Digital Signature generation and verification; but make no sense for many other Digital Signature schemes, including the common DSA and ECDSA. We have all too many questions and answers dealing with this. See e.g. this. On the rest of the question, if it is about the fact that being along a signature (or even in the signed messages) is no sign of authenticity of a certificate, and would allow forgery: indeed! – fgrieu Oct 9 '17 at 15:15

The problem that you are having is how trust in the ownership of a public key can be created. That is a problem in all public key settings and independent of the format used (like XML signatures).

As you state correctly, the pure signature verification can only check, if some public key matches the private key used to sign a mesage. After that step, you need to check if you trust the ownership relation between the public key and the (claimed) signer.

There are quite a few trust models used in practice:

1. Certification Authorities An authority that you trust in advance (usually via a list installed in your operating system or software) signed a certificate containing the signers name and the public key
2. Trust on first use Whenever you communicate with a new entity for the first time, you trust the sender' public key and store that relationship
3. Web of trust Similar to 1. You trust a certificate, because someone else that you already trust does so.
4. Manual validation You have manually checked the ownership of a keypair by the sender previously via some out-of-band mechanism (like comparing the key's fingerprint on the phone)

What I don't understand is that in my opinion this doesn't verify the sender, it simply verifies that the private key component of the public certificate sent in the node was used to sign the token.

You are right. The KeyInfo doesn't enforce integrity itself.

However - the certificate passed along the SAMLResponse should be only used to validate, that the sender (entityId) has the same certificate. The attached certificate may not be used to validate the signature directly!

Some SAML implementation have configured only a fingerprint of the certificate (e.g. simpleSAMLphp has this option) for a participant IdP or SP. The framework then validates the certificate (if it's having the configured fingerprint or the same certificate) and only then the certificate can be used to validate the signature.

An attacker could create his own certificate pair and sign the token with that.

And exactly that's why a validating party (Service Provider) must first validate if the certificate belongs to the configured IdP.

Just a note from my experience - with SAML what I've see the most common issues:

• Service Provider doesn't validate the signature or timestamp at all
• vulnerability for XML Signature Wrapping attack

So - take care :)