/* * Copyright [2006] [University Corporation for Advanced Internet Development, Inc.] * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.opensaml.saml2.core; import java.security.KeyPair; import org.joda.time.DateTime; import org.opensaml.common.BaseTestCase; import org.opensaml.common.SAMLVersion; import org.opensaml.common.impl.SAMLObjectContentReference; import org.opensaml.common.impl.SecureRandomIdentifierGenerator; import org.opensaml.saml2.core.impl.AssertionBuilder; import org.opensaml.saml2.core.impl.AuthnStatementBuilder; import org.opensaml.saml2.core.impl.IssuerBuilder; import org.opensaml.xml.io.Marshaller; import org.opensaml.xml.io.MarshallingException; import org.opensaml.xml.io.UnmarshallingException; import org.opensaml.xml.security.CriteriaSet; import org.opensaml.xml.security.SecurityException; import org.opensaml.xml.security.SecurityHelper; import org.opensaml.xml.security.SecurityTestHelper; import org.opensaml.xml.security.credential.BasicCredential; import org.opensaml.xml.security.credential.StaticCredentialResolver; import org.opensaml.xml.security.criteria.EntityIDCriteria; import org.opensaml.xml.security.keyinfo.KeyInfoCredentialResolver; import org.opensaml.xml.signature.Signature; import org.opensaml.xml.signature.SignatureConstants; import org.opensaml.xml.signature.SignatureException; import org.opensaml.xml.signature.Signer; import org.opensaml.xml.signature.impl.ExplicitKeySignatureTrustEngine; import org.opensaml.xml.signature.impl.SignatureBuilder; import org.opensaml.xml.util.XMLHelper; import org.opensaml.xml.validation.ValidationException; public class SignedAssertionTest extends BaseTestCase { /** Credential used for signing. */ private BasicCredential goodCredential; /** Verification credential that should fail to verify signature. */ private BasicCredential badCredential; /** Builder of Assertions. */ private AssertionBuilder assertionBuilder; /** Builder of Issuers. */ private IssuerBuilder issuerBuilder; /** Builder of AuthnStatements. */ private AuthnStatementBuilder authnStatementBuilder; /** Builder of AuthnStatements. */ private SignatureBuilder signatureBuilder; /** Generator of element IDs. */ private SecureRandomIdentifierGenerator idGenerator; /** {@inheritDoc} */ protected void setUp() throws Exception { super.setUp(); KeyPair keyPair = SecurityTestHelper.generateKeyPair("RSA", 1024, null); goodCredential = SecurityHelper.getSimpleCredential(keyPair.getPublic(), keyPair.getPrivate()); keyPair = SecurityTestHelper.generateKeyPair("RSA", 1024, null); badCredential = SecurityHelper.getSimpleCredential(keyPair.getPublic(), null); assertionBuilder = (AssertionBuilder) builderFactory.getBuilder(Assertion.DEFAULT_ELEMENT_NAME); issuerBuilder = (IssuerBuilder) builderFactory.getBuilder(Issuer.DEFAULT_ELEMENT_NAME); authnStatementBuilder = (AuthnStatementBuilder) builderFactory.getBuilder(AuthnStatement.DEFAULT_ELEMENT_NAME); signatureBuilder = (SignatureBuilder) builderFactory.getBuilder(Signature.DEFAULT_ELEMENT_NAME); idGenerator = new SecureRandomIdentifierGenerator(); } /** * Creates a simple Assertion, signs it and then verifies the signature. * * @throws MarshallingException thrown if the Assertion can not be marshalled into a DOM * @throws ValidationException thrown if the Signature does not validate * @throws SignatureException * @throws UnmarshallingException * @throws SecurityException */ public void testAssertionSignature() throws MarshallingException, ValidationException, SignatureException, UnmarshallingException, SecurityException{ DateTime now = new DateTime(); Assertion assertion = assertionBuilder.buildObject(); assertion.setVersion(SAMLVersion.VERSION_20); assertion.setID(idGenerator.generateIdentifier()); assertion.setIssueInstant(now); Issuer issuer = issuerBuilder.buildObject(); issuer.setValue("urn:example.org:issuer"); assertion.setIssuer(issuer); AuthnStatement authnStmt = authnStatementBuilder.buildObject(); authnStmt.setAuthnInstant(now); assertion.getAuthnStatements().add(authnStmt); Signature signature = signatureBuilder.buildObject(); signature.setSigningCredential(goodCredential); signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA); assertion.setSignature(signature); Marshaller marshaller = marshallerFactory.getMarshaller(assertion); marshaller.marshall(assertion); Signer.signObject(signature); // Unmarshall new tree around DOM to avoid side effects and Apache xmlsec bug. Assertion signedAssertion = (Assertion) unmarshallerFactory.getUnmarshaller(assertion.getDOM()).unmarshall(assertion.getDOM()); StaticCredentialResolver credResolver = new StaticCredentialResolver(goodCredential); KeyInfoCredentialResolver kiResolver = SecurityTestHelper.buildBasicInlineKeyInfoResolver(); ExplicitKeySignatureTrustEngine trustEngine = new ExplicitKeySignatureTrustEngine(credResolver, kiResolver); CriteriaSet criteriaSet = new CriteriaSet( new EntityIDCriteria("urn:example.org:issuer") ); assertTrue("Assertion signature was not valid", trustEngine.validate(signedAssertion.getSignature(), criteriaSet)); } }