/******************************************************************************* * Copyright 2017 Graz University of Technology * EAAF-Core Components has been developed in a cooperation between EGIZ, * A-SIT Plus, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. *******************************************************************************/ /******************************************************************************* *******************************************************************************/ /******************************************************************************* *******************************************************************************/ package at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder; import java.util.ArrayList; import java.util.List; import org.joda.time.DateTime; import org.opensaml.Configuration; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.EncryptedAssertion; import org.opensaml.saml2.core.Issuer; import org.opensaml.saml2.core.NameID; import org.opensaml.saml2.core.RequestAbstractType; import org.opensaml.saml2.core.Response; import org.opensaml.saml2.encryption.Encrypter; import org.opensaml.saml2.encryption.Encrypter.KeyPlacement; import org.opensaml.saml2.metadata.SPSSODescriptor; import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.security.MetadataCredentialResolver; import org.opensaml.security.MetadataCriteria; import org.opensaml.xml.encryption.EncryptionException; import org.opensaml.xml.encryption.EncryptionParameters; import org.opensaml.xml.encryption.KeyEncryptionParameters; import org.opensaml.xml.security.CriteriaSet; import org.opensaml.xml.security.SecurityException; import org.opensaml.xml.security.credential.UsageType; import org.opensaml.xml.security.criteria.EntityIDCriteria; import org.opensaml.xml.security.criteria.UsageCriteria; import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorFactory; import org.opensaml.xml.security.x509.X509Credential; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import at.gv.egiz.eaaf.modules.pvp2.PVPConstants; import at.gv.egiz.eaaf.modules.pvp2.idp.exception.InvalidAssertionEncryptionException; import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils; /** * @author tlenz * */ public class AuthResponseBuilder { private static final Logger log = LoggerFactory.getLogger(AuthResponseBuilder.class); public static Response buildResponse(MetadataProvider metadataProvider, String issuerEntityID, RequestAbstractType req, DateTime date, Assertion assertion, boolean enableEncryption) throws InvalidAssertionEncryptionException { Response authResponse = SAML2Utils.createSAMLObject(Response.class); Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class); nissuer.setValue(issuerEntityID); nissuer.setFormat(NameID.ENTITY); authResponse.setIssuer(nissuer); authResponse.setInResponseTo(req.getID()); //set responseID String remoteSessionID = SAML2Utils.getSecureIdentifier(); authResponse.setID(remoteSessionID); //SAML2 response required IssueInstant authResponse.setIssueInstant(date); authResponse.setStatus(SAML2Utils.getSuccessStatus()); //check, if metadata includes an encryption key MetadataCredentialResolver mdCredResolver = new MetadataCredentialResolver(metadataProvider); CriteriaSet criteriaSet = new CriteriaSet(); criteriaSet.add( new EntityIDCriteria(req.getIssuer().getValue()) ); criteriaSet.add( new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS) ); criteriaSet.add( new UsageCriteria(UsageType.ENCRYPTION) ); X509Credential encryptionCredentials = null; try { encryptionCredentials = (X509Credential) mdCredResolver.resolveSingle(criteriaSet); } catch (SecurityException e2) { log.warn("Can not extract the Assertion Encryption-Key from metadata", e2); throw new InvalidAssertionEncryptionException(); } if (encryptionCredentials != null && enableEncryption) { //encrypt SAML2 assertion try { EncryptionParameters dataEncParams = new EncryptionParameters(); dataEncParams.setAlgorithm(PVPConstants.DEFAULT_SYM_ENCRYPTION_METHODE); List keyEncParamList = new ArrayList(); KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters(); keyEncParam.setEncryptionCredential(encryptionCredentials); keyEncParam.setAlgorithm(PVPConstants.DEFAULT_ASYM_ENCRYPTION_METHODE); KeyInfoGeneratorFactory kigf = Configuration.getGlobalSecurityConfiguration() .getKeyInfoGeneratorManager().getDefaultManager() .getFactory(encryptionCredentials); keyEncParam.setKeyInfoGenerator(kigf.newInstance()); keyEncParamList.add(keyEncParam); Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList); //samlEncrypter.setKeyPlacement(KeyPlacement.INLINE); samlEncrypter.setKeyPlacement(KeyPlacement.PEER); EncryptedAssertion encryptAssertion = null; encryptAssertion = samlEncrypter.encrypt(assertion); authResponse.getEncryptedAssertions().add(encryptAssertion); } catch (EncryptionException e1) { log.warn("Can not encrypt the PVP2 assertion", e1); throw new InvalidAssertionEncryptionException(); } } else { authResponse.getAssertions().add(assertion); } return authResponse; } }