All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.litsec.opensaml.xmlsec.SAMLObjectDecrypter Maven / Gradle / Ivy

There is a newer version: 1.4.5
Show newest version
/*
 * Copyright 2016-2018 Litsec AB
 *
 * 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 se.litsec.opensaml.xmlsec;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.opensaml.core.xml.XMLObject;
import org.opensaml.saml.saml2.core.EncryptedElementType;
import org.opensaml.security.credential.Credential;
import org.opensaml.xmlsec.DecryptionConfiguration;
import org.opensaml.xmlsec.DecryptionParameters;
import org.opensaml.xmlsec.encryption.EncryptedData;
import org.opensaml.xmlsec.encryption.support.Decrypter;
import org.opensaml.xmlsec.encryption.support.DecryptionException;

import net.shibboleth.utilities.java.support.logic.Constraint;
import se.swedenconnect.opensaml.xmlsec.encryption.support.DecryptionUtils;
import se.swedenconnect.opensaml.xmlsec.encryption.support.Pkcs11Decrypter;

/**
 * A support bean for easy decryption.
 * 

* For some reason, OpenSAML offers two ways to represent decryption parameters, the {@link DecryptionParameters} and * the {@link DecryptionConfiguration}. This bean supports being initialized by either of these two, but also, and * perhaps easier to use; it supports initialization with just the encryption credentials and assigns the defaults from * {@link DecryptionUtils#createDecryptionParameters(Credential...)}. *

* * @author Martin Lindström ([email protected]) */ public class SAMLObjectDecrypter { /** The decrypter. */ private Decrypter decrypter; /** Decryption parameters. */ private DecryptionParameters parameters; /** * If using a HSM it is likely that the SunPKCS11 crypto provider is used. This provider does not have support for * OAEP padding. This is used commonly for XML encryption since * {@code http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p} is the default algorithm to use for key encryption. This * class has a workaround for this limitation that is enabled by setting the {@code pkcs11Workaround} flag. */ private boolean pkcs11Workaround = false; /** For testing the workaround without the use of a HSM. */ private boolean pkcs11testMode = false; /** * Constructor given the credential to use to decrypt the messages (certificate or key pair). * * @param decryptionCredential * decryption credential */ public SAMLObjectDecrypter(Credential decryptionCredential) { this(Collections.singletonList(decryptionCredential)); } /** * Constructor accepting several credentials (certificates or key pairs) to be used when decrypting. This may be * useful after a key rollover. * * @param decryptionCredentials * decryption credentials */ public SAMLObjectDecrypter(List decryptionCredentials) { Constraint.isNotEmpty(decryptionCredentials, "At least one credential must be supplied to SAMLObjectDecrypter"); this.parameters = DecryptionUtils.createDecryptionParameters( decryptionCredentials.stream().toArray(Credential[]::new)); // Should be assigned explicitly this.parameters.setBlacklistedAlgorithms(Collections.emptyList()); this.parameters.setWhitelistedAlgorithms(Collections.emptyList()); } /** * Initializes the decrypter using {@link DecryptionParameters}. * * @param decryptionParameters * parameters */ public SAMLObjectDecrypter(DecryptionParameters decryptionParameters) { this.parameters = new DecryptionParameters(); this.parameters.setDataKeyInfoCredentialResolver(decryptionParameters.getDataKeyInfoCredentialResolver()); this.parameters.setKEKKeyInfoCredentialResolver(decryptionParameters.getKEKKeyInfoCredentialResolver()); this.parameters.setEncryptedKeyResolver(decryptionParameters.getEncryptedKeyResolver()); this.parameters.setBlacklistedAlgorithms(decryptionParameters.getBlacklistedAlgorithms()); this.parameters.setWhitelistedAlgorithms(decryptionParameters.getWhitelistedAlgorithms()); } /** * Initializes the decrypter using {@link DecryptionConfiguration}. * * @param decryptionConfiguration * parameters */ public SAMLObjectDecrypter(DecryptionConfiguration decryptionConfiguration) { this.parameters = new DecryptionParameters(); this.parameters.setDataKeyInfoCredentialResolver(decryptionConfiguration.getDataKeyInfoCredentialResolver()); this.parameters.setKEKKeyInfoCredentialResolver(decryptionConfiguration.getKEKKeyInfoCredentialResolver()); this.parameters.setEncryptedKeyResolver(decryptionConfiguration.getEncryptedKeyResolver()); this.parameters.setBlacklistedAlgorithms(decryptionConfiguration.getBlacklistedAlgorithms()); this.parameters.setWhitelistedAlgorithms(decryptionConfiguration.getWhitelistedAlgorithms()); } /** * Decrypts the supplied encrypted object into an object of the given type. * * @param encryptedObject * the encrypted object * @param destinationClass * the class of the destination object * @param * the type of the destination object * @param * the type of the encrypted object * @return the decrypted element of object T * @throws DecryptionException * for decryption errors */ public T decrypt(E encryptedObject, Class destinationClass) throws DecryptionException { if (encryptedObject.getEncryptedData() == null) { throw new DecryptionException("Object contains no encrypted data"); } return this.decrypt(encryptedObject.getEncryptedData(), destinationClass); } /** * Decrypts the supplied encrypted object into an object of the given type. * * @param encryptedData * the encrypted data * @param destinationClass * the class of the destination object * @param * the type of the destination object * @return the decrypted element of object T * @throws DecryptionException * for decryption errors */ public T decrypt(EncryptedData encryptedData, Class destinationClass) throws DecryptionException { XMLObject object = this.getDecrypter().decryptData(encryptedData); if (!destinationClass.isInstance(object)) { throw new DecryptionException(String.format("Decrypted object can not be cast to %s - is %s", destinationClass.getSimpleName(), object.getClass().getSimpleName())); } return destinationClass.cast(object); } /** * Returns the decrypter to use. * * @return the decrypter */ private synchronized Decrypter getDecrypter() { if (this.decrypter == null) { if (this.pkcs11Workaround) { Pkcs11Decrypter p11Decrypter = new Pkcs11Decrypter(this.parameters); p11Decrypter.setTestMode(this.pkcs11testMode); this.decrypter = p11Decrypter; } else { this.decrypter = new Decrypter(this.parameters); } this.decrypter.setRootInNewDocument(true); } return this.decrypter; } /** * Assigns a list of black listed algorithms * * @param blacklistedAlgorithms * non allowed algorithms */ public void setBlacklistedAlgorithms(Collection blacklistedAlgorithms) { if (this.decrypter != null) { throw new IllegalStateException("Object has already been initialized"); } this.parameters.setBlacklistedAlgorithms(blacklistedAlgorithms); } /** * Assigns a list of white listed algorithms * * @param whitelistedAlgorithms * white listed algorithms */ public void setWhitelistedAlgorithms(Collection whitelistedAlgorithms) { if (this.decrypter != null) { throw new IllegalStateException("Object has already been initialized"); } this.parameters.setWhitelistedAlgorithms(whitelistedAlgorithms); } /** * If using a HSM it is likely that the SunPKCS11 crypto provider is used. This provider does not have support for * OAEP padding. This is used commonly for XML encryption since * {@code http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p} is the default algorithm to use for key encryption. This * class has a workaround for this limitation that is enabled by setting the {@code pkcs11Workaround} flag. * * @param pkcs11Workaround * whether to run in PKCS11 workaround mode */ public void setPkcs11Workaround(boolean pkcs11Workaround) { this.pkcs11Workaround = pkcs11Workaround; } /** * For internal testing only. * * @param pkcs11testMode * test flag */ public void setPkcs11testMode(boolean pkcs11testMode) { this.pkcs11testMode = pkcs11testMode; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy