Skip to Content.
Sympa Menu

mace-opensaml-users - RE: [OpenSAML] How to validate signing certificate of the SAML token in the relaying party?

Subject: OpenSAML user discussion

List archive

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


Chronological Thread 
  • From: "Gina Choi" <>
  • To: <>
  • Subject: RE: [OpenSAML] How to validate signing certificate of the SAML token in the relaying party?
  • Date: Thu, 28 Apr 2011 12:40:43 -0400

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:

[mailto:]
On Behalf Of Brent Putman
Sent: Thursday, April 28, 2011 11:24 AM
To:

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



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.






Archive powered by MHonArc 2.6.16.

Top of Page