[OpenSAML] SAML signature validation

3,637 views
Skip to first unread message

murali mca

unread,
Nov 18, 2009, 6:14:12 PM11/18/09
to mace-open...@internet2.edu
Hi,
 
I am using the below code fragment to verify the signature in SAML and getting the error. Can someone help me to find the reason for this error?
 
 Signature signatureToValidate = assertion.getSignature();
 SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
 try {
     profileValidator.validate(signatureToValidate);
 } catch (ValidationException ve) {
     ve.printStackTrace();
 }
 
Error:

18-Nov-2009 22:40:17 org.opensaml.security.SAMLSignatureProfileValidator validateTransforms
SEVERE: Signature was missing the required Enveloped signature transform
org.opensaml.xml.validation.ValidationException: Transforms did not contain the required enveloped transform
        at org.opensaml.security.SAMLSignatureProfileValidator.validateTransforms(SAMLSignatureProfileValidator.java:198
)
        at org.opensaml.security.SAMLSignatureProfileValidator.validateSignatureImpl(SAMLSignatureProfileValidator.java:
83)
        at org.opensaml.security.SAMLSignatureProfileValidator.validate(SAMLSignatureProfileValidator.java:52)
        at org.apache.jsp.service_005fprovider_jsp._jspService(service_005fprovider_jsp.java:191)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:873)
        at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java
:665)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
        at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
        at java.lang.Thread.run(Thread.java:619)

 
 
Thanks
Murali




Connect more, do more and share more with Yahoo! India Mail. Learn more.

Brent Putman

unread,
Nov 18, 2009, 6:59:34 PM11/18/09
to mace-open...@internet2.edu

murali mca wrote:

> 18-Nov-2009 22:40:17
> org.opensaml.security.SAMLSignatureProfileValidator validateTransforms
> SEVERE: Signature was missing the required Enveloped signature transform
> org.opensaml.xml.validation.ValidationException: Transforms did not
> contain the required envelope

The error's pretty self-explanatory, the Signature doesn't contain the
Enveloped transform. The SAMLSignatureProfileValidator requires that.
If someone is sending you the signature, you need to get them to fix
it. If you are generating the signature, well, you're doing something
wrong. See the wiki below for info on how to sign with OpenSAML.

However, just to check since you said you are trying "to verify the
signature in SAML" - realize that the SAMLSignatureProfileValidator does
not cryptographically verify the signature. It's purpose is just to
validate certain constraints of the SAML signature profile, before
actually doing the crypto. That's to prevent certain kinds of DoS
attacks against the verifier.

If you actually want to cryptographically verify the signature itself,
see the user's manual signature wiki page:

https://spaces.internet2.edu/display/OpenSAML/OSTwoUserManJavaDSIG

murali mca

unread,
Nov 19, 2009, 5:49:48 PM11/19/09
to mace-open...@internet2.edu
Hi
 
Thanks for the response.
Got this fixed after adding the Enveloped signature transform(<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>) to SAML asertion and now I am able to verify the signature for DoS attacks using SAMLSignatureProfileValidator.
 
However, I am getting "null pointer exception" while retrieving the Credential (signatureToValidate.getSigningCredential();) from signature.
 
 // Validating the signature cryptographically
Signature signatureToValidate = assertion.getSignature();
Credential verificationCredential = signatureToValidate.getSigningCredential();
SignatureValidator sigValidator = new SignatureValidator(verificationCredential);
try {
    sigValidator.validate(signatureToValidate);
} catch (ValidationException e) {
 
    e.printStackTrace();
}
I can see <X509Data><X509Certificate> in my signature. Please help me how to retrieve the credential/public key from X509 cert and validate the signature. Correct me if the above code is wrong.
 
Below is the SAML:
<Signature>
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#1bc6d017-f9bd-4333-a618-a73cd4ea51ac">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>0qnKCEgW2h7yX/1UfkngJXGXxPk=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>vgefKC1BZXTeNjUEqU1aGvBfn1HD2WfanLwQPbBd0ywekp7c82plARfaB+fIxrqb6m9wj9bR8MfWkj4vKBxvRA==</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIDPTCCAuegAwIBAgIJAK3Eu7cvpbf4MA0GCSqGSIb3DQEBBQUAMIGdMQswCQYD
VQQGEwJHQjEQMA4GA1UECBMHTm9yZm9sazEQMA4GA1UEBxMHTm9yd2ljaDESMBAG
A1UEChMJQXZpZA6zIc=.......</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
 
 
Thanks for your help
Murali
--- On Thu, 19/11/09, Brent Putman <put...@georgetown.edu> wrote:


The INTERNET now has a personality. YOURS! See your Yahoo! Homepage.

Brent Putman

unread,
Nov 19, 2009, 7:22:00 PM11/19/09
to mace-open...@internet2.edu


murali mca wrote:
 

 
However, I am getting "null pointer exception" while retrieving the Credential (signatureToValidate.getSigningCredential();) from signature.


That method (and also the getContentReferences()) is only used during signing to supply the signing key.  It isn't used during validation and isn't populated by the unmarshaller, hence the NPE.  I don't think any of our docs or examples on the wiki have anything like that in them, but if they do, let us know where so we can fix them.

You need to supply the validation Credential from elsewhere.  You can pull the actual Key/Credential out of the Signature/KeyInfo data, either by manual processing or using the KeyInfoCredentialResolver, and then use the SignatureValidator with resulti.  Or you can pull it from out-of-band trusted data.

For a real-world deployment, note the warning about using KeyInfo-derived Credential *only* to validate the signature. 

https://spaces.internet2.edu/display/OpenSAML/OSTwoUserManJavaDSIG#OSTwoUserManJavaDSIG-VerifyingaSignaturewithaCredential


You must somehow establish the trust of the validation key.  For that you might consider using a SignatureTrustEngine rather than the low-level SignatureValidator, as discussed in the next section on the wiki.

--Brent




murali mca

unread,
Nov 22, 2009, 3:23:10 PM11/22/09
to mace-open...@internet2.edu

Thanks for correcting me.
 
I am trying to use trusted keystore to validate the signature as below:

 
SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
profileValidator.validate( signatureToValidate );
log.info("SAML signature profile validation has been successful");
 
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
char[] password = "sspass".toCharArray();
FileInputStream fis = new FileInputStream("C:\\Program Files\\Java\\jdk1.5.0_15\\bin\\serviceKeystore1.jks");
ks.load(fis, password);
fis.close();
KeyStore.TrustedCertificateEntry tcEntry = (KeyStore.TrustedCertificateEntry) ks.getEntry("MyClientKey", null);
java.security.cert.X509Certificate samlCertificate = (java.security.cert.X509Certificate) tcEntry.getTrustedCertificate();

BasicX509Credential credentialsSign509 = new BasicX509Credential();
credentialsSign509.setEntityCertificate(samlCertificate);
credentialsSign509.setPublicKey(samlCertificate.getPublicKey());
// And create a SignatureValidator with it.
SignatureValidator signatureValidator = new SignatureValidator( credentialsSign509 );
 
try{
signatureValidator.validate( signatureToValidate );
}catch (ValidationException e) {
e.printStackTrace();
}
INFO: ObjectProviders load complete
[http-8083-1] INFO  com.aviva.tam.pmi.ValidateAssertionParams  - assertion ID is:123
[http-8083-1] INFO  com.aviva.tam.pmi.ValidateAssertionParams  - IssuerName is:http://some.issuer.here
[http-8083-1] INFO  com.aviva.tam.pmi.ValidateAssertionParams  - Issuer is: http://some.issuer.here
[http-8083-1] INFO  com.aviva.tam.pmi.ValidateAssertionParams  - 2009-10-09T18:48:07.000Z
[http-8083-1] INFO  com.aviva.tam.pmi.ValidateAssertionParams  - false
[http-8083-1] INFO  com.aviva.tam.pmi.ValidateSAML2Signature  - SAML signature profile validation has been successful
[http-8083-1] INFO  com.aviva.tam.pmi.ValidateSAML2Signature  - SAML signature profile validation has been successful

09-Oct-2009 19:53:11 org.apache.xml.security.signature.Reference verify
WARNING: Verification failed for URI "#123"
org.opensaml.xml.validation.ValidationException: Signature did not validate against the credential's key
        at org.opensaml.xml.signature.SignatureValidator.validate(SignatureValidator.java:78)
        at com.aviva.tam.pmi.ValidateSAML2Signature.signatureValidator(ValidateSAML2Signature.java:168)
        at org.apache.jsp.service_005fprovider_jsp._jspService(service_005fprovider_jsp.java:241)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:384)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:196)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:228)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:216)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:634)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)
        at java.lang.Thread.run(Unknown Source)
I am sure I am using correct key for validation.
I have no clue about this error, can  some one help me ?
Enabled the "debug" level in logg4j.properties file, but could not see the
debug statements of the SAML API classes in the output. Any idea how can I see the debug messages?
 
Many Thanks

--- On Fri, 20/11/09, Brent Putman <put...@georgetown.edu> wrote:

From: Brent Putman <put...@georgetown.edu>
Subject: Re: [OpenSAML] SAML signature validation
To: mace-open...@internet2.edu
Date: Friday, 20 November, 2009, 5:52 AM

That method (and also the getContentReferences()) is only used during signing to supply the signing key.  It isn't used during validation and isn't populated by the unmarshaller, hence the NPE.  I don't think any of our docs or examples on the wiki have anything like that in them, but if they do, let us know where so we can fix them.

You need to supply the validation Credential from elsewhere.  You can pull the actual Key/Credential out of the Signature/KeyInfo data, either by manual processing or using the KeyInfoCredentialResolver, and then use the SignatureValidator with resulti.  Or you can pull it from out-of-band trusted data.

For a real-world deployment, note the warning about using KeyInfo-derived Credential *only* to validate the signature. 

https://spaces.internet2.edu/display/OpenSAML/OSTwoUserManJavaDSIG#OSTwoUserManJavaDSIG-VerifyingaSignaturewithaCredential


You must somehow establish the trust of the validation key.  For that you might consider using a SignatureTrustEngine rather than the low-level SignatureValidator, as discussed in the next section on the wiki.

--Brent

Brent Putman

unread,
Nov 23, 2009, 4:32:30 PM11/23/09
to mace-open...@internet2.edu

murali mca wrote:

>
> 09-Oct-2009 19:53:11 org.apache.xml.security.signature.Reference verify
> WARNING: Verification failed for URI "#123"
> org.opensaml.xml.validation.ValidationException: Signature did not
> validate against the credential's key
>
>
>

> I am sure I am using correct key for validation.
>


Well, if you're really, really sure you are using the right validation
key, then...

> I have no clue about this error, can some one help me ?
>

The mostly likely possibility is that the signature really is invalid,
due to the signed document being modified sometime after it was signed.
Any change to the document, even whitespace addition (e.g. pretty print
formatting, etc) will render the signature invalid. This could be
happening on either signer's end, or the verifier's end. If you're
doing both, you should check both sides.

It's also possible there could be a bug or incompatibility somewhere
(esp. if you're using different libraries are being used for the signing
and verification), but you should rule out the invalid signature
possibility first. If you're using OpenSAML for both the signing and
validation, and with the same version of Java, then this is almost
certainly not the case.


> Enabled the "debug" level in logg4j.properties file, but could not see the
> debug statements of the SAML API classes in the output. Any idea how
> can I see the debug messages?
>


OpenSAML doesn't use log4j, at least natively. It uses a logging facade
called slf4j. See here for further info.

https://spaces.internet2.edu/display/OpenSAML/OSTwoUsrManJavaBB

You must have installed and bound some logging framework to slf4j,
otherwise I believe you'd be getting runtime errors. Whatever logging
implementation you bind to slf4j, that's what you should configure.

murali mca

unread,
Nov 26, 2009, 6:40:45 PM11/26/09
to mace-open...@internet2.edu
Thanks for clear explanation.
 
I was using Prettyprint in my code. I removed that and gave another try to validate the signature. This time I encountered below error:
java.lang.RuntimeException: org.apache.xml.security.signature.XMLSignatureException: object not initialized for signature or verification
Original Exception was java.security.SignatureException: object not initialized for signature or verification
	org.apache.xml.security.utils.SignerOutputStream.write(Unknown Source)
	org.apache.xml.security.utils.UnsyncBufferedOutputStream.flushBuffer(Unknown Source)
	org.apache.xml.security.utils.UnsyncBufferedOutputStream.flush(Unknown Source)
	org.apache.xml.security.utils.UnsyncBufferedOutputStream.close(Unknown Source)
	org.apache.xml.security.c14n.implementations.CanonicalizerBase.engineCanonicalizeSubTree(Unknown Source)
	org.apache.xml.security.c14n.implementations.Canonicalizer20010315Excl.engineCanonicalizeSubTree(Unknown Source)
	org.apache.xml.security.c14n.implementations.Canonicalizer20010315Excl.engineCanonicalizeSubTree(Unknown Source)
	org.apache.xml.security.c14n.Canonicalizer.canonicalizeSubtree(Unknown Source)
	org.apache.xml.security.signature.SignedInfo.signInOctectStream(Unknown Source)
	org.apache.xml.security.signature.XMLSignature.checkSignatureValue(Unknown Source)
	org.opensaml.xml.signature.SignatureValidator.validate(SignatureValidator.java:68)
	com.aviva.tam.pmi.ValidateSAML2Signature.signatureValidator(ValidateSAML2Signature.java:171)
	org.apache.jsp.service_005fprovider_jsp._jspService(service_005fprovider_jsp.java:241)
	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:384)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:196)
Please suggest.
Many Thanks,
Murali
 
 

Brent Putman

unread,
Nov 30, 2009, 11:48:19 AM11/30/09
to mace-open...@internet2.edu

murali mca wrote:
>
> Thanks for clear explanation.
>
> I was using Prettyprint in my code. I removed that and gave
> another try to validate the signature. This time I
> encountered below error:
>
> java.lang.RuntimeException: org.apache.xml.security.signature.XMLSignatureException: object not initialized for signature or verification
> Original Exception was java.security.SignatureException: object not initialized for signature or verification
>
>


IIRC, I'm pretty sure this error occurs from trying to use the same
Apache XMLSignature object to both sign and then verify a document in
the same thread. It's a known issue with Apache xmlsec. If you're
trying to test the validation in your code immediately after signing,
you should serialize the signed document and then deserialize the DOM
and unmarshall a new XMLObject tree around it, which will also create a
new Apache XMLSignature object, and then verify that new XMLObject.
That should avoid this problem.


murali mca

unread,
Dec 15, 2009, 10:58:31 AM12/15/09
to mace-open...@internet2.edu
Hi
 
I am trying to validate the SAML signature received from the IdentityProvider.The signature validation is always getting failed.So I want to print the digest value and compare it with actual digest value.
 
I have enabled the "DEBUG" level for logging(using slf4j), but could not see any thing related digestvalue in the logs.
Can some one suggest me how to accomplish this?
 
 
Thanks,
Regards,
Murali
 
 
--- On Fri, 27/11/09, murali mca <murali...@yahoo.co.in> wrote:

From: murali mca <murali...@yahoo.co.in>
Subject: Re: [OpenSAML] SAML signature validation
To: mace-open...@internet2.edu
Reply all
Reply to author
Forward
0 new messages