In WS-Security, how does a wsse:BinarySecurityToken carry an X.509 certificate, and how does a signature identify the certificate it used?
answer
- binary bytes, Base64 inside XML
- ValueType names the format
- single cert, path, or PKCS#7 set
- SecurityTokenReference inside KeyInfo
- by ID, key identifier or issuer-serial
basics
~20 sA wsse:BinarySecurityToken carries the Base64-encoded certificate, its ValueType naming the format (#X509v3, #X509PKIPathv1, #PKCS7). The signature's ds:KeyInfo holds a wsse:SecurityTokenReference pointing to that token by ID, or to the certificate by subject key identifier or issuer and serial number.
solid answer
~50 sThe **X.509 Certificate Token Profile 1.1.1** puts the certificate in `<wsse:BinarySecurityToken>`, whose `EncodingType` defaults to `#Base64Binary` and whose `ValueType` says what the bytes are: `#X509v3` for one certificate, `#X509PKIPathv1` for an ordered path, or `#PKCS7` for a set with optional CRLs (PKIPath is RECOMMENDED for paths, because PKCS#7 order is not significant). Every reference to an X.509 token from a signature or encryption SHALL use `<wsse:SecurityTokenReference>`, placed in `ds:KeyInfo`, by one of three means: a `wsse:Reference` whose URI points at the token's `wsu:Id`, a `wsse:KeyIdentifier` of ValueType `#X509SubjectKeyIdentifier`, or `ds:X509Data/ds:X509IssuerSerial`. The last two let the certificate stay out of the message when the receiver already holds it. The token SHOULD precede the signature that uses it, and the producer should sign the token too, so nobody can later claim a different certificate over the same key was meant.
go deeper
Recall that the certificate travels Base64-encoded in a BinarySecurityToken and that a SecurityTokenReference tells the receiver which key signed.
Explain the three ValueTypes, the three reference forms, and when each lets the certificate stay out of the message.
Show how you would debug a partner's signature that fails to resolve or is rejected as untrusted, and why the token itself should be signed.
Weigh embedding certificates against pre-exchanged identifiers across many partners, including what each choice costs at certificate rotation time.
## Why a binary token An X.509 certificate is a binary structure, not XML, so it cannot simply be dropped into a SOAP header. **WSS: SOAP Message Security 1.1.1** defines a general wrapper for such tokens, `<wsse:BinarySecurityToken>`, with two attributes that tell a receiver how to read it: - `EncodingType` says how the bytes are written into XML. The pre-defined value is `#Base64Binary`, which is also the default. - `ValueType` says what the decoded bytes *are*, for example an X.509 certificate or a Kerberos ticket. Its use is RECOMMENDED, and each token profile defines its own values. - `wsu:Id` gives the token a label other elements can point at. The core specification leaves the rules for each binary format to separate profiles; the **X.509 Certificate Token Profile 1.1.1** is the one for certificates. ## The three X.509 token types | `ValueType` | What it carries | Note from the profile | |---|---|---| | `#X509v3` | one X.509 v3 certificate | capable of signature verification at a minimum | | `#X509PKIPathv1` | an **ordered** list of certificates in a PKIPath | MAY represent a certificate path | | `#PKCS7` | certificates and, optionally, CRLs in a PKCS#7 wrapper | order is not significant; PKIPath is RECOMMENDED for paths instead | Which kind of end entity a certificate authenticates is, in the profile's words, a matter of policy outside its scope. ## Pointing at the key: SecurityTokenReference A signature or an encrypted key has to say which key was used. XML Signature puts that in `ds:KeyInfo`; the X.509 profile says that every reference to an X.509 token from a signature or encryption element **SHALL** use a `<wsse:SecurityTokenReference>` there, so all token types are referenced the same way. It allows three forms: | Form inside the reference | Points at | Needs the certificate in the message? | |---|---|---| | `wsse:Reference URI="#Cert-1"` | a `BinarySecurityToken` by its `wsu:Id`, or a remote source | yes, for a local reference | | `wsse:KeyIdentifier ValueType="...#X509SubjectKeyIdentifier"` | the certificate's X.509v3 SubjectKeyIdentifier extension value | no | | `ds:X509Data/ds:X509IssuerSerial` | the certificate's issuer name and serial number | no | A subject key identifier may only reference an X.509v3 certificate. WS-Security 1.1 also defines a SHA-1 **thumbprint** key identifier, `#ThumbprintSHA1`, which the X.509 profile's examples use to name a decryption certificate that is not in the message. When a receiver cannot resolve a reference, the matching fault code is `wsse:SecurityTokenUnavailable`. ```xml <wsse:Security xmlns:wsse="..." xmlns:wsu="..." xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <wsse:BinarySecurityToken wsu:Id="Cert-1" EncodingType="...#Base64Binary" ValueType="...#X509v3">MIIEZzCCA9Cg...</wsse:BinarySecurityToken> <ds:Signature> <ds:SignedInfo>...</ds:SignedInfo> <ds:SignatureValue>...</ds:SignatureValue> <ds:KeyInfo> <wsse:SecurityTokenReference> <wsse:Reference URI="#Cert-1"/> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> </wsse:Security> ``` ## Order inside the header The core specification asks for the key-bearing element to come **before** the element that uses it, so a receiver reading top down already has the certificate when it meets the signature. For processing efficiency it RECOMMENDS adding the signature first and then prepending the token, which produces exactly that order. ## Reading a failure When an exchange with a certificate token fails, the X.509 profile says the error codes of the core specification MUST be used, and each points at a different step. If the receiver chooses to return a fault: - `wsse:UnsupportedSecurityToken`: it does not support the token type it was sent. - `wsse:InvalidSecurityToken`: the token provided is invalid, for example malformed. - `wsse:SecurityTokenUnavailable`: a reference could not be resolved, for example an unknown subject key identifier. - `wsse:FailedCheck`: the signature (or a decryption) did not verify. - `wsse:FailedAuthentication`: the token could not be authenticated or authorised; reporting an untrusted certificate this way is a natural fit, though the mapping is the implementation's choice. ## Trust is still the receiver's decision A certificate in the message is a *claim*. Validating the signature against it proves only that whoever signed held the matching private key. The core specification says signature validation **MUST** fail when the application's own policy rejects the message, for example because the key is not trusted; certificate path and revocation checks are the receiver's policy, outside WS-Security. Two threats the specification calls out: 1. **Token substitution.** The same key pair can appear in several certificates with different attributes or limits. If the certificate is not under the producer's signature, the producer could later claim a different certificate was meant. The counter is to sign the token, or its identifying data, along with the message. 2. **Response-key substitution.** When a request supplies a public key for encrypting the response, an attacker in the middle could swap it. The specification suggests using the same key pair that signed the request, or putting that public key under the request's signature. The X.509 profile adds that TLS MAY be used as an alternative to, or alongside, message-level protection; it introduces no threats beyond those of the core specification.
- When would a sender reference its certificate by subject key identifier instead of embedding it?When the receiver already holds the certificate, for example exchanged when the partnership was set up. A `wsse:KeyIdentifier` with ValueType `#X509SubjectKeyIdentifier` (X.509v3 certificates only) or a `ds:X509IssuerSerial` names it without sending the bytes, keeping messages smaller. If the receiver cannot find a matching certificate, `wsse:SecurityTokenUnavailable` is the matching fault code.
- If the signature verifies against the certificate in the message, should the receiver accept the sender?Not on that alone. Cryptographic validation proves the signer held the private key for that certificate; it says nothing about whether the certificate is trusted. WS-Security says signature validation MUST fail when the application's own policy rejects the key, and leaves path building, revocation and the choice of trusted issuers to that policy.
saying these in an interview costs you the question
- The certificate must always travel inside the SOAP message.
- #PKCS7 preserves certificate order, so it is the preferred path format.
- A signature that verifies means the signer's certificate is trusted.
- BinarySecurityToken exists only for X.509 certificates.
- The signature should come before the token it uses in the header.