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 &lt;saml:Assertion&gt; node I use a private/public key pair:


Create a hash of the &lt;saml:Assertion&gt; block and store it in a &lt;ds:Reference&gt; inside the &lt;ds:SignedInfo&gt; node.
Use the private key to encrypt the &lt;ds:SignedInfo&gt; node and store it in the &lt;ds:SignatureValue&gt; node.
Pass the public certificate in the &lt;ds:KeyInfo&gt; block.


To verify the signature I then:


decrypt the &lt;ds:SignatureValue&gt; node using the public certificate found in &lt;ds:KeyInfo&gt; and ensure that it is equal to the &lt;ds:SignedInfo&gt; block
ensure that the hash of the &lt;saml:Assertion&gt; node is equal to the digest stored in the &lt;ds:Reference&gt; 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 &lt;ds:KeyInfo&gt; 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 &lt;ds:KeyInfo&gt;, but rather obtain the public certificate from another trusted source.

Could someone please verify or point out how I'm misunderstanding XML Digital Signatures?
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:


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
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
Web of trust Similar to 1. You trust a certificate, because someone else that you already trust does so.
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)