[OpenSAML] How to validate signing certificate of the SAML token in the relaying party?

6,877 views
Skip to first unread message

Gina Choi

unread,
Apr 28, 2011, 10:35:28 AM4/28/11
to mace-open...@internet2.edu
I extracted singing certificate from Identity Provider and installed it in the
relying party. I used the following code to validate the signature. Does
signatureValidator.validate(signature) also validate the expiration date of
the certificate or I have to write my own code to check if the certificate is
expired?

File certificateFile = new
File("C:\\ginashare\\adfs_token_trust.cer");
FileInputStream certInputStream =
new FileInputStream(certificateFile);
CertificateFactory certificateFactory =
CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)
certificateFactory
.generateCertificate(certInputStream);

// pull out the public key part of the certificate into a
// KeySpec
publicKeySpec = new
X509EncodedKeySpec(certificate.getPublicKey().getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// generate public key to validate signatures
PublicKey publicKey =
keyFactory.generatePublic(publicKeySpec);

// create credentials
BasicX509Credential publicCredential = new
BasicX509Credential();

// add public key value
publicCredential.setPublicKey(publicKey);
// create SignatureValidator
signatureValidator = new
SignatureValidator(publicCredential);

signatureValidator.validate(signature);

Thanks.

Gina

Paul Hethmon

unread,
Apr 28, 2011, 10:45:06 AM4/28/11
to OpenSAML List
Pretty sure you'll have to validate the certificate separately for
expiration date. You definitely will if you want to check the certificate
chain since that's out of scope of SAML.

Cantor, Scott E.

unread,
Apr 28, 2011, 10:46:16 AM4/28/11
to mace-open...@internet2.edu
> I extracted singing certificate from Identity Provider and installed it in the
> relying party. I used the following code to validate the signature. Does
> signatureValidator.validate(signature) also validate the expiration date of
> the certificate or I have to write my own code to check if the certificate is
> expired?

The goal of the validator is to verify the signature. Trust management (doing anything with the certificate) is separate. There is an extensive body of code for that, and we suggest you abandon any notions of certificate evaluation in favor of using SAML metadata for key comparison.

-- Scott

Gina Choi

unread,
Apr 28, 2011, 11:06:50 AM4/28/11
to mace-open...@internet2.edu
Thanks Paul and Scott for your response. I thought that
signatureValidator.validate(signature) handles everything. By the way, do you
have any recommendation on dealing with trust management? For example, what
kind of items do I need to check except expiration date?

Gina

Paul Hethmon

unread,
Apr 28, 2011, 11:13:05 AM4/28/11
to OpenSAML List
It depends on your business requirements. I take Scott's approach and
highly recommend it. If my IdP or SP has a certificate in a metadata file,
then I implicitly trust it.

Think of it this way. You are going to acquire that metadata file (and
certificate) via some out of band process. There will be some sort of
business arrangement between you and the other party. All set up and
handled outside of the technical arena. You don't need that certificate to
be signed and trusted by a commercial CA. You have an arrangement with the
partner and having established that arrangement, you already implicitly
trust them. Why pay a commercial CA? You do not gain anything by doing so.

Paul

Cantor, Scott E.

unread,
Apr 28, 2011, 11:12:34 AM4/28/11
to mace-open...@internet2.edu
> Thanks Paul and Scott for your response. I thought that
> signatureValidator.validate(signature) handles everything. By the way, do
> you have any recommendation on dealing with trust management? For example,
> whatkind of items do I need to check except expiration date?

This is an extremely complex problem, there are no simple "just check this" answers. If you wanted to use PKIX, then you *need* to do PKIX. That's far more than just checking a date. You have to do path validation, possibly check various extensions, implement a revocation strategy, etc. You also need a mechanism to bind certificate DNs to SAML issuers.

Or you can implement solutions based on SAML metadata to exchange key material. There is a standard for this, implemented at some level of the code base, possibly only in Shibboleth.

http://wiki.oasis-open.org/security/SAML2MetadataIOP

See also:
https://wiki.shibboleth.net/confluence/display/SHIB2/TrustManagement

-- Scott

Brent Putman

unread,
Apr 28, 2011, 11:23:41 AM4/28/11
to mace-open...@internet2.edu

On 4/28/11 11:06 AM, Gina Choi wrote:
> Thanks Paul and Scott for your response. I thought that
> signatureValidator.validate(signature) handles everything.


No, it just does the simple cryptographic validation of the signature
against the supplied key.


> By the way, do you
> have any recommendation on dealing with trust management? For example, what
> kind of items do I need to check except expiration date?
>


There's a pretty decent example in the wiki page on XML Signature,
illustrating the use of SAML metadata and the explicit key
metadata-based trust engine. The TrustEngine is the abstraction in
OpenSAML that both cryptographically validates a token as well as
performs trust evaluation. (The signature ones for example internally
make use of the SignatureValidator).

https://wiki.shibboleth.net/confluence/display/OpenSAML/OSTwoUserManJavaDSIG

It's the very last example on that page.

In the SAML metadata trust model that Scott refers to, you don't care
about any data in the certificate other than the public key. The
validity (and expiration, etc) of the binding of the key to the SAML
entity is expressed by the metadata itself. X.509/PKIX-style PKI
concepts therefore don't apply there. That's the model that we use and
advocate predominantly in Shibboleth. If you absolutely, positively
have to do X.509/PKIX style trust evaluation, we have code for that too.

Gina Choi

unread,
Apr 28, 2011, 12:40:43 PM4/28/11
to mace-open...@internet2.edu
Thanks for all your responses. I am a Service Provider. The application that
we provide to our clients is not sensitive, so I am not planning to make a
complex validation. My identity provider is Microsoft ADFS2.0 and my
application is receiving SAML2.0 tokens from ADFS and I don't use any other
third party product. I exported token signing certificate from ADFS and
placed it in my application(SP). The singing certificate has an expiration
date of one year. My worry is after one year what happens? I will keep work
as normal or something will break?

The following is my initial code(definitely I will refactor it later) to
decode the string(I don't know if it is a ADFS specific, the SAML token was
encoded with Base64) and validating signature(I probably try explicit key
signature trust engine later as your suggestion). Before I go deep into wrong
direction, someone could check it for me. I got some part of the code from
Internet. By the way, response.getSignature() returns a null, so I had to get
assertion object out of response object to get a Singature. I did
assertion.getSignature() to get a Signature object. I don't know if it is
caused by ADFS implementation.

// args[0].itemAt(0).getStringValue() returns Base64 encode SAML
token string
byte[] decoded =
Base64.decodeBase64(args[0].itemAt(0).getStringValue());
String decodedSamlToken = new String(decoded);
Response response = null;
Assertion assertion = null;
// FileUtils.writeStringToFile(responseFile, decodedString);
try {
// Initializes the OpenSAML library, loading default
configurations.
DefaultBootstrap.bootstrap();

// Gets a schema that can validate SAML 1.1, 2.0, and
all registered
// extensions.
Schema schema = SAMLSchemaBuilder.getSAML11Schema();

// get parser pool manager
BasicParserPool parserPoolManager = new
BasicParserPool();
parserPoolManager.setNamespaceAware(true);

parserPoolManager.setIgnoreElementContentWhitespace(true);
parserPoolManager.setSchema(schema);

InputStream in = new
ByteArrayInputStream(decodedSamlToken.getBytes("UTF-8"));

// parse input stream
Document document = parserPoolManager.parse(in);

Element metadataRoot = document.getDocumentElement();

javax.xml.namespace.QName qName = new
javax.xml.namespace.QName(
metadataRoot.getNamespaceURI(),
metadataRoot.getLocalName(),
metadataRoot.getPrefix());

// get an unmarshaller
Unmarshaller unmarshaller =
Configuration.getUnmarshallerFactory().getUnmarshaller(qName);

// unmarshall using the document root element
response = (Response)
unmarshaller.unmarshall(metadataRoot);

} catch (ConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XMLParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnmarshallingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

List<Assertion> assList = response.getAssertions();
// Assertion assertion = (Assertion)
response.getAssertions();
System.out.println("assertion length:" + assList.size());
assertion = assList.get(0);
Signature signature = assertion.getSignature();

File certificateFile = new
File("C:\\ginashare\\adfs_token_trust.cer");

// get the certificate from the file

CertificateFactory certificateFactory;
SignatureValidator signatureValidator = null;
X509EncodedKeySpec publicKeySpec = null;
InputStream certInputStream = null;
try {
certInputStream = new
FileInputStream(certificateFile);


certificateFactory =
CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)
certificateFactory

.generateCertificate(certInputStream);

// pull out the public key part of the certificate
into a
// KeySpec
publicKeySpec = new
X509EncodedKeySpec(certificate.getPublicKey()
.getEncoded());

// get KeyFactory object that creates key objects,
specifying
// RSA

} catch (CertificateException e1) {
// TODO Auto-generated catch block
System.out.println("CertificateException thrown");
e1.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

KeyFactory keyFactory;
try {


keyFactory = KeyFactory.getInstance("RSA");

System.out.println("Security Provider: "
+
keyFactory.getProvider().toString());


// generate public key to validate signatures
PublicKey publicKey =
keyFactory.generatePublic(publicKeySpec);

// we have the public key
System.out.println("Public Key created");

// create credentials
BasicX509Credential publicCredential = new
BasicX509Credential();

// add public key value
publicCredential.setPublicKey(publicKey);
// create SignatureValidator
signatureValidator = new
SignatureValidator(publicCredential);

System.out.println("Algorithm:" +
publicKey.getAlgorithm());
System.out.println("Format:" +
publicKey.getFormat());

// no validation exception was thrown
System.out.println("Signature is valid.");

} catch (NoSuchAlgorithmException e) {
e.getClass().getSimpleName();
// TODO Auto-generated catch block
System.out.println("NoSuchAlgorithmException
thrown");
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

try {
System.out.println("Validating signature....");
signatureValidator.validate(signature);
System.out.println("Finished Validating signature");
} catch (Exception ve) {
System.out.println("Signature is NOT valid.");
System.out.println(ve.getStackTrace());


}
-----Original Message-----
From: mace-opensaml...@internet2.edu
[mailto:mace-opensaml...@internet2.edu] On Behalf Of Brent Putman
Sent: Thursday, April 28, 2011 11:24 AM
To: mace-open...@internet2.edu
Subject: Re: [OpenSAML] How to validate signing certificate of the SAML token
in the relaying party?

Cantor, Scott E.

unread,
Apr 28, 2011, 12:44:08 PM4/28/11
to mace-open...@internet2.edu
> Thanks for all your responses. I am a Service Provider. The application that
> we provide to our clients is not sensitive, so I am not planning to make a
> complex validation.

Until they change the app or your code gets copied around as an example or approach for some other app.



> My identity provider is Microsoft ADFS2.0 and my
> application is receiving SAML2.0 tokens from ADFS and I don't use any other
> third party product. I exported token signing certificate from ADFS and
> placed it in my application(SP). The singing certificate has an expiration
> date of one year. My worry is after one year what happens? I will keep work
> as normal or something will break?

That's up to you. And what happens if and when they change it?

You need to read what I provided as background. It's not optional if you're implementing SAML (or anything else involving keys for trust management).

-- Scott

Gina Choi

unread,
Apr 28, 2011, 3:45:57 PM4/28/11
to mace-open...@internet2.edu
Hi Scott,

The link that you previously sent me was very helpful. I got some idea about
how to handle expiration date of the certificate.


Thanks.

Gina

-----Original Message-----
From: mace-opensaml...@internet2.edu
[mailto:mace-opensaml...@internet2.edu] On Behalf Of Cantor, Scott
E.
Sent: Thursday, April 28, 2011 12:44 PM
To: mace-open...@internet2.edu
Subject: RE: [OpenSAML] How to validate signing certificate of the SAML token
in the relaying party?

Michael Kjorling

unread,
Apr 29, 2011, 6:20:34 AM4/29/11
to mace-open...@internet2.edu
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Apr 28 2011 12:40 -0400, from gc...@sdl.com (Gina Choi):


> The following is my initial code(definitely I will refactor it later) to
> decode the string(I don't know if it is a ADFS specific, the SAML token was
> encoded with Base64)

You may want to look over the parts of the standard that are relevant
to your use case. For one, "Bindings", section 3.5 (HTTP POST Binding)
clearly states "The HTTP POST binding defines a mechanism by which
SAML protocol messages may be transmitted within _the base64-encoded
content_ of an HTML form control.".

http://saml.xml.org/saml-specifications

- --
Michael Kjörling .. mic...@kjorling.se .. http://michael.kjorling.se
* ..... No bird soars too high if he soars with his own wings ..... *
* ENCRYPTED email preferred -- OpenPGP keys: 0x32D6B8C6, 0xBDE9ADA6 *
* ASCII Ribbon Campaign: Against HTML mail, proprietary attachments *

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iD8DBQFNupDydY+HSb3praYRAsIFAJ9orx3CFd+XMFXz6biDgO/JH8HFDQCgiKBO
CGWjzfouvS5t12fmlVQUfYQ=
=FSJU
-----END PGP SIGNATURE-----

Gina Choi

unread,
May 2, 2011, 12:33:25 PM5/2/11
to mace-open...@internet2.edu
The following is part of assertion token. NotOnOrAfter is in both
<SubjectConfirmation> and <Conditions> tags. The NotOnOrAfter timestamp in
the SubjectConfirmation tag is around two hours ahead and the one in the
Conditions tag is 5 min ahead then current time. I looked at document for
Assertion protocols and it seems that NotOnOrAfter in the SubjectConfirmation
is to restrict Subject data while the one in the Conditions tag is to
restrict the Assertion token, but I wonder why do we need NotOnOrAfter in
both places? Isn't one in the either place enough?


<Subject>
<NameID>gchoi</NameID>
<SubjectConfirmation Method =
"urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData NotOnOrAfter =
"2011-04-12T18:37:00.243Z" Recipient
="https://wkensv0303.global.sdl.corp:8443/servletTestApp/testServlet"/>
</SubjectConfirmation>
</Subject>
<Conditions NotBefore = "2011-04-12T18:32:00.237Z" NotOnOrAfter =
"2011-04-12T19:32:00.237Z">
<AudienceRestriction>

<Audience>https://wkensv0303.global.sdl.corp:8443/servletTestApp</Audience>
</AudienceRestriction>
</Conditions>
<AttributeStatement>

Thanks.

Gina

Cantor, Scott E.

unread,
May 2, 2011, 12:36:33 PM5/2/11
to mace-open...@internet2.edu
On 5/2/11 12:33 PM, "Gina Choi" <gc...@sdl.com> wrote:
>The following is part of assertion token. NotOnOrAfter is in both
><SubjectConfirmation> and <Conditions> tags. The NotOnOrAfter timestamp in
>the SubjectConfirmation tag is around two hours ahead and the one in the
>Conditions tag is 5 min ahead then current time.

That's backwards from accepted norms for bearer assertions, but a
condition is going to be an upper bound on subject confirmation anyway.

>I looked at document for
>Assertion protocols and it seems that NotOnOrAfter in the
>SubjectConfirmation
>is to restrict Subject data while the one in the Conditions tag is to
>restrict the Assertion token, but I wonder why do we need NotOnOrAfter in
>both places? Isn't one in the either place enough?

No, since they serve completely different functions.

-- Scott

Gina Choi

unread,
May 2, 2011, 1:00:04 PM5/2/11
to mace-open...@internet2.edu
Thanks for your response. Sorry, NotOnOrAfter timestamp in the Conditions is
one hour ahead instead of two hours. By the way where are the 5 min and 1
hour coming from? Is this implementation specific? Timeframe of NotOnOrAfter
in SubjectConfirmationData(5min) is much shorter than the one in the
Conditions(60min). Because of time off between identity server and relying
party server can happen, I am thinking that verifying NotONOrAfter in the
Conditions tag is realistic than the one in the SubjectConfirmation. Your
advise would be appreciated.

Gina Choi

-----Original Message-----
From: mace-opensaml...@internet2.edu
[mailto:mace-opensaml...@internet2.edu] On Behalf Of Cantor, Scott
E.

Sent: Monday, May 02, 2011 12:37 PM
To: mace-open...@internet2.edu

Cantor, Scott E.

unread,
May 2, 2011, 1:05:06 PM5/2/11
to mace-open...@internet2.edu
On 5/2/11 1:00 PM, "Gina Choi" <gc...@sdl.com> wrote:
>Thanks for your response. Sorry, NotOnOrAfter timestamp in the Conditions
>is
>one hour ahead instead of two hours.

I thought you said the confirmation window was the one that was ahead of
the other. That means it's as expected.

> By the way where are the 5 min and 1
>hour coming from? Is this implementation specific?

It's policy and profile specific (or should be).

> Timeframe of NotOnOrAfter
>in SubjectConfirmationData(5min) is much shorter than the one in the
>Conditions(60min).

It should be.

> Because of time off between identity server and relying
>party server can happen, I am thinking that verifying NotONOrAfter in the
>Conditions tag is realistic than the one in the SubjectConfirmation. Your
>advise would be appreciated.

Clock synchronication is a requirement in SAML and most security
protocols. Doing what you propose is wrong, and would be insecure.

-- Scott

Gina Choi

unread,
May 2, 2011, 1:44:46 PM5/2/11
to mace-open...@internet2.edu
>It's policy and profile specific
I am using Web Browser SSO profile, SP initialed Redirect->POST binding.


>Clock synchronication is a requirement in SAML and most security
>protocols. Doing what you propose is wrong, and would be insecure.

1. How do I force clock synchronizations between two servers?
2. Could you recommend correct way of verifying NotOnOrAftr timestamp?

Thank you.

Gina Choi

-----Original Message-----
From: mace-opensaml...@internet2.edu
[mailto:mace-opensaml...@internet2.edu] On Behalf Of Cantor, Scott
E.
Sent: Monday, May 02, 2011 1:05 PM
To: mace-open...@internet2.edu
Subject: Re: [OpenSAML] Difference NotOnOrAfter in <SubjectConfirmationData>
and <Conditions>

Cantor, Scott E.

unread,
May 2, 2011, 1:50:13 PM5/2/11
to mace-open...@internet2.edu
On 5/2/11 1:44 PM, "Gina Choi" <gc...@sdl.com> wrote:

>1. How do I force clock synchronizations between two servers?

By configuring all servers with a good time source. This is basic server
admin 101.

>2. Could you recommend correct way of verifying NotOnOrAftr timestamp?

Allow a configurable amount of clock skew of 3-5 minutes or so and then
apply that to the value you're comparing to in the conservative direction.

-- Scott

Gina Choi

unread,
May 2, 2011, 2:37:38 PM5/2/11
to mace-open...@internet2.edu
Hi Scott,

Thank you so much for your advice. I need to verify two more things before I
start on(hopefully doesn't bother you more on same question).

1. Do you recommend me verifying NotBefore timestamp in both
SubjectConfirmation and Conditions? I should, correct? Even one is enclosed
by the other(time range wise), but they have different meanings as you said.
2. Where can I get technical description about 5 min and 1 hour? I just want
to have a supportive document when later asked by others.

Thanks again. When you have a chance to come to Boston, please let me know. I
should take you out for lunch.:)

Gina Choi

-----Original Message-----
From: mace-opensaml...@internet2.edu
[mailto:mace-opensaml...@internet2.edu] On Behalf Of Cantor, Scott
E.
Sent: Monday, May 02, 2011 1:50 PM
To: mace-open...@internet2.edu
Subject: Re: [OpenSAML] Difference NotOnOrAfter in <SubjectConfirmationData>
and <Conditions>

Cantor, Scott E.

unread,
May 2, 2011, 3:20:22 PM5/2/11
to mace-open...@internet2.edu
>1. Do you recommend me verifying NotBefore timestamp in both
>SubjectConfirmation and Conditions? I should, correct? Even one is
>enclosed
>by the other(time range wise), but they have different meanings as you
>said.

You're obligated to. The validity of an assertion depends on both
generic/invariant processing rules and rules specific to profiles and the
context of use, such as when subject confirmation is involved because an
assertion is used for authentication.

>2. Where can I get technical description about 5 min and 1 hour? I just
>want
>to have a supportive document when later asked by others.

They're policy, nothing is going to absolutely dictate what the values
should be, particularly the assertion lifetime. But the profile neglects
to explicitly say the confirmation window should be short. That's either a
bug, or more likely a result of "everything is policy and risk management"
attitudes during drafting.

The Security Considerations document mentions it, but it's old text that
just mentions NotBefore and NonOnOrAfter and neglects to note which set
it's talking about. It's out of date.

I may propose an errata, probably to the definition of the "bearer"
confirmation method to catch a wider net.

>Thanks again. When you have a chance to come to Boston, please let me
>know. I
>should take you out for lunch.:)

I haven't been in awhile actually.

-- Scott

Reply all
Reply to author
Forward
0 new messages