/* * Copyright 2014 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, and Graz University of Technology. * * Licensed under the EUPL, Version 1.1 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: * http://www.osor.eu/eupl/ * * 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.egovernment.moa.id.protocols.pvp2x.verification.metadata; import java.io.IOException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactoryConfigurationError; import org.opensaml.saml2.metadata.EntitiesDescriptor; import org.opensaml.saml2.metadata.EntityDescriptor; import org.opensaml.saml2.metadata.provider.FilterException; import org.opensaml.saml2.metadata.provider.MetadataFilter; import org.opensaml.xml.XMLObject; import at.gv.egovernment.moa.id.auth.builder.SignatureVerificationUtils; import at.gv.egovernment.moa.id.commons.api.data.IVerifiyXMLSignatureResponse; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.DOMUtils; import at.gv.egovernment.moa.util.MiscUtil; /** * @author tlenz * */ public class MOASPMetadataSignatureFilter implements MetadataFilter { private String trustProfileID = null; /** * */ public MOASPMetadataSignatureFilter(String trustProfileID) { this.trustProfileID = trustProfileID; } /* (non-Javadoc) * @see org.opensaml.saml2.metadata.provider.MetadataFilter#doFilter(org.opensaml.xml.XMLObject) */ @Override public void doFilter(XMLObject metadata) throws FilterException { if (metadata instanceof EntityDescriptor) { checkSignature(metadata, ((EntityDescriptor)metadata).getEntityID()); } else if (metadata instanceof EntitiesDescriptor) { EntitiesDescriptor entitiesDesc = (EntitiesDescriptor) metadata; if (entitiesDesc.getEntityDescriptors() != null && entitiesDesc.getEntityDescriptors().size() > 1) { String nameForLogging = entitiesDesc.getName(); if (MiscUtil.isEmpty(nameForLogging)) nameForLogging = entitiesDesc.getID(); checkSignature(metadata, nameForLogging); } else { Logger.warn("Metadata root-element is of type 'EntitiesDescriptor' but only include one 'EntityDescriptor'"); throw new FilterException("Metadata root-element is not of type 'EntitiesDescriptor' but only include one 'EntityDescriptor"); } } else { Logger.warn("Metadata root-element is not of type 'EntityDescriptor' or 'EntitiesDescriptor'"); throw new FilterException("Metadata root-element is not of type 'EntityDescriptor' or 'EntitiesDescriptor'"); } } private void checkSignature(XMLObject metadata, String nameForLogging) throws FilterException { if (((EntityDescriptor) metadata).isSigned()) { //check signature; try { byte[] serialized = DOMUtils.serializeNode(metadata.getDOM(), "UTF-8"); SignatureVerificationUtils sigVerify = new SignatureVerificationUtils(); IVerifiyXMLSignatureResponse result = sigVerify.verify( serialized, trustProfileID); //check signature-verification result if (result.getSignatureCheckCode() != 0) { Logger.warn("Metadata signature-verification FAILED!" + " Metadata: " + nameForLogging + " StatusCode:" + result.getSignatureCheckCode()); } if (result.getCertificateCheckCode() != 0) { Logger.warn("Metadata certificate-verification FAILED!" + " Metadata: " + nameForLogging + " StatusCode:" + result.getCertificateCheckCode()); throw new FilterException("Metadata certificate-verification FAILED!" + " Metadata: " + nameForLogging + " StatusCode:" + result.getCertificateCheckCode()); } Logger.debug("SAML metadata for entityID:" + nameForLogging + " is valid"); } catch (MOAIDException | TransformerFactoryConfigurationError | TransformerException | IOException e) { Logger.error("Metadata verification for Entity:" + nameForLogging + " has an interal error.", e); throw new FilterException("Metadata verification has an interal error." + " Message:" + e.getMessage()); } } else { Logger.warn("Metadata root-element MUST be signed."); throw new FilterException("Metadata root-element MUST be signed.'"); } } }