SAML in X.509 Validation
From Globus
This document is a draft describing how a relying party should process SAML assertions embedded in an X.509 certificate chain (which may include proxy certificates).
Contents |
The Certificate Chain
Assume that X.509 path validation (as defined by RFC 3280 and RFC 3820) has been accomplished and we have a valid certificate chain, which includes an end entity certificate (EEC) and zero or more proxy certificates (PCs). This document refers to the proxy certificates as PC1, PC2, ..., PCn, with PC1 (a "level 1 proxy") being the proxy certificate issued by the EEC, and PCn (a "level n proxy") being the final certificate in the chain (i.e., the certificate containing the public key associated with the private key for which possession was proven). Thus the certificate chain is of length n + 1:
EEC, PC1, PC2, ..., PCn
The entity presenting the certificate chain and proving possession of the private key associated with PCn is referred to as the Chain Presenter.
Note: While the first certificate in the chain is typically an EEC, technically, the first certificate is a non-impersonation proxy, that is, either an EEC or an independent proxy (defined below). Regardless, this document consistently refers to the first certificate in the chain as the EEC.
Proxy Policies
A proxy certificate as described in RFC 3820 has an associated proxyPolicy value, which defines the rights the proxy certificate inherits from its issuer. RFC 3820 defines two such policies:
-
id-ppl-inheritAll - This type of proxy certificate, called an impersonation proxy, inherits all rights from its issuer.
-
id-ppl-independent - This type of proxy certificate, called an independent proxy, inherits no rights from its issuer.
Additionally, the Grid Security Infrastructure, as implemented in Globus Toolkit, defines a third policy for a limited proxy, which inherits all the privileges of its issuer except for the right to launch jobs. For our purposes, a limited proxy is a type of impersonation proxy. Thus a non-impersonation proxy is either an EEC or an independent proxy.
SAML Certificate Extensions
Each certificate (PC or EEC) may contain an X.509 certificate extension containing a SAML assertion (or a reference to a SAML assertion). As discussed below, an assertion must be signed if it is not issued by the same entity that issued the containing certificate. Note that the signature on the certificate (previously verified during path validation) covers the extension. Thus an assertion issued by the same entity that issued the containing certificate (referred to as a self-issued assertion) need not be signed.
Walking the Certificate Chain
We now apply the following algorithm to the certificate chain (assuming certs[0] is PCn):
for (int i = 0; i < certs.length; i++) {
if (hasSAMLExtension(certs[i])) {
consumeSAMLExtension(certs[i]);
}
if (!isImpersonationProxy(certs[i])) {
break;
}
}
The above algorithm examines each certificate in the certificate chain (starting with PCn) and further processes those certificates containing SAML assertions. For each certificate containing an assertion, the assertion is extracted and processed as follows:
SAMLSubjectAssertion assertion = getSAMLAssertion(cert);
String issuer = assertion.getIssuer();
if (assertion.isSigned()) {
X509Certificate signingCert = getX509Certificate(issuer);
try {
assertion.verify(signingCert);
} catch (SAMLException e) { return; }
if (!isAssertionValid(assertion)) { return; }
} else {
X500Principal certIssuer = null;
if (isImpersonationProxy(cert)) {
X509Certificate eec = getEEC(subject);
certIssuer = eec.getSubjectX500Principal();
} else {
certIssuer = cert.getIssuerX500Principal();
}
if (!isSelfIssuedAssertion(issuer, certIssuer)) { return; }
}
parseSAMLAssertion(assertion);
If the assertion is signed, the signature is verified and the validity of the assertion is determined. If the assertion is not signed, it must be self-issued, that is, the assertion issuer and the issuer of the certificate must be one and the same entity.
In other words, starting with PCn, perform the following operations on the certificate chain:
- If the current certificate contains an assertion, perform the following substeps:
- If the assertion is signed and the signature can not be verified, discard the assertion.
- If the assertion has a verifiable signature but the assertion itself is not valid, discard the assertion.
- If the assertion is unsigned and its issuer does not match the issuer of the certificate in which it is contained (i.e., the assertion is not self-signed), discard the assertion.
- If the assertion passes the previous tests, process the assertion.
- If the current certificate is not an impersonation proxy, we are done processing the certificate chain. In particular, if the certificate is an EEC, we are done processing the certificate chain.
Self-issued Assertions
To process an assertion, an important distinction must be made:
An unsigned X.509-bound SAML assertion is self-issued if the assertion issuer is the certificate issuer.
Since the certificate issuer is a DN, it follows that a DN string comparison is required to determine if an assertion is self-issued. In practice, this is much more difficult than it sounds.
To first order, we require that the issuer of a certificate containing a SAML assertion set the Issuer XML attribute of the assertion to its X.509 Subject DN, formatted as an RFC 2253-conformant DN string. To determine whether or not the assertion is self-issued, a relying party reverses this process (and hopes for the best).
A SAML issuer is not usually known by a DN, however. The unique identifier of a SAML issuer (called an entityID) is very often an URI, and if SAML metadata is used, the entityID MUST be a URI. Thus if the relying party can map the SAML issuer (an URI) to an X.509 issuer (a DN), the assertion is self-issued.
Processing the SAML Assertion
To process a SAML assertion, a relying party performs the following operations:
- Parse the SAML subject and add the
<saml:NameIdentifier>element to the security context. - Parse the
<saml:AuthenticationStatement>element (if present) and add the resulting authentication context to the security context. - Parse each
<saml:AttributeStatement>element (if any) and add the resulting attributes to the security context.
In each case, the SAML issuer (defined below) accompanies any object added to the security context.
If the assertion contains one or more nested assertions (in a <saml:Advice> element), recursively process each nested assertion. In the case of nested assertions, however, the SAML issuer is a list of issuers (as discussed below).
Validating the SAML Assertion
A SAML V1.1 assertion bound to an X.509 certificate is valid if and only if all of the following statements are true:
- The assertion is valid according to section 2 of SAMLCore.
- The assertion is valid according to the Subject-based Profiles for SAML V1.1 Assertions.
- The assertion is valid according to the X.509 Binding for SAML. (This binding specification has not yet been published. See the foreign wiki topic X509BindingSAML for a preliminary list of requirements.)
Trusting the SAML Assertion
Observe the following relationship between consecutive certificates in the certificate chain:
subject(EEC) = issuer(PC1)
subject(PCi) = issuer(PCi + 1) for i = 1, …, n - 1
Thus for any PC in the chain, the issuer can be traced back to the subject of the EEC. This leads to the following definition:
For an impersonation proxy containing a SAML assertion, if the assertion is self-issued, the SAML issuer is the subject of the EEC. In all other cases, the SAML issuer is the actual assertion issuer (given by the Issuer XML attribute in the assertion).
In particular, for an EEC, the SAML issuer is always the assertion issuer.
Subsequently, the SAML assertion is discarded if the SAML issuer (as defined above) is not on a pre-configured list of trusted SAML issuers. Specifically, every assertion is associated with a SAML issuer, and by inclusion, every attribute is likewise associated with the same SAML issuer. Any given attribute is filtered if its SAML issuer is not on the list of trusted SAML issuers. More generally, an attribute is subject to attribute acceptance policy, which is a function of the trusted SAML issuer and possibly other policy constraints.
Nested SAML Assertions
A SAML assertion may contain a nested SAML assertion in a <saml:Advice> element. Policy associated with nested assertions is more complicated than top-level assertions. To accommodate nested assertions, a list of SAML issuers is maintained per attribute. A list of length 1 indicates the SAML issuer issued the attribute directly (in a top-level assertion). If the list is of length greater than 1, the attribute was asserted indirectly (in a nested assertion).
For example, suppose the SAML issuer consists of a list of two identiifers, ID0 and ID1. The latter is the identifier of the issuer that issued the attribute (in a nested assertion). ID0 is the identifier of the issuer that issued an assertion containing that nested assertion.
In general, suppose the SAML issuer is given by a list of identifiers ID0, ID1, …, IDn. The latter is the identifier of the issuer that issued the attribute (in a level n nested assertion). Issuers ID0, ID1, …, IDn - 1 are intermediary issuers, that is, proxy issuers (not to be confused with proxy certificates).
A relying party trusts the attribute issued by issuer IDn if it trusts all the issuers ID0, ID1, …, IDn. In particular, the relying party trusts the issuers ID0, ID1, …, IDn - 1 to be proxy issuers, while trusting IDn to be an actual attribute issuer. Thus there are at least two types of trusted SAML issuers of interest.

