/** * Constructor. * * @param newResolver resolver for data encryption keys. * @param newKEKResolver resolver for key encryption keys. * @param newEncKeyResolver resolver for EncryptedKey elements */ public Decrypter(KeyInfoCredentialResolver newResolver, KeyInfoCredentialResolver newKEKResolver, EncryptedKeyResolver newEncKeyResolver) { resolver = newResolver; kekResolver = newKEKResolver; encKeyResolver = newEncKeyResolver; resolverCriteria = null; kekResolverCriteria = null; // Note: Use of this internal JAXP ParserPool is hopefully only temporary, // to be replaced when Xerces implements DOM 3 LSParser.parseWithContext(...). parserPool = buildParserPool(); unmarshallerFactory = Configuration.getUnmarshallerFactory(); defaultRootInNewDocument = false; }
/** * This is a convenience method for calling {@link #decryptData(EncryptedData, boolean)}, * with the <code>rootInNewDocument</code> parameter value supplied by {@link #isRootInNewDocument()}. * * @param encryptedData encrypted data element containing the data to be decrypted * @return the decrypted XMLObject * @throws DecryptionException exception indicating a decryption error, possibly because the decrypted data * contained more than one top-level Element, or some non-Element Node type. */ public XMLObject decryptData(EncryptedData encryptedData) throws DecryptionException { return decryptData(encryptedData, isRootInNewDocument()); }
/** * Attempt to decrypt by resolving the decryption key by first resolving EncryptedKeys, and using the KEK credential * resolver to resolve the key decryption for each. * * @param encryptedData the encrypted data to decrypt * @param algorithm the algorithm of the key to be decrypted * @return the decrypted document fragment, or null if decryption key could not be resolved or decryption failed */ private DocumentFragment decryptUsingResolvedEncryptedKey(EncryptedData encryptedData, String algorithm) { if (encKeyResolver != null) { for (EncryptedKey encryptedKey : encKeyResolver.resolve(encryptedData)) { try { Key decryptedKey = decryptKey(encryptedKey, algorithm); return decryptDataToDOM(encryptedData, decryptedKey); } catch (DecryptionException e) { String msg = "Attempt to decrypt EncryptedData using key extracted from EncryptedKey failed: "; log.debug(msg, e); continue; } } } return null; }
/** * This is a convenience method for calling {@link #decryptDataToList(EncryptedData, boolean)}, * with the <code>rootInNewDocument</code> parameter value supplied by {@link #isRootInNewDocument()}. * * @param encryptedData encrypted data element containing the data to be decrypted * @return the list decrypted top-level XMLObjects * @throws DecryptionException exception indicating a decryption error, possibly because the decrypted data * contained DOM nodes other than type of Element */ public List<XMLObject> decryptDataToList(EncryptedData encryptedData) throws DecryptionException { return decryptDataToList(encryptedData, isRootInNewDocument()); }
checkAndMarshall(encryptedData); } catch (DecryptionException e) { log.error("Error marshalling EncryptedData for decryption", e); if (getJCAProviderName() != null) { xmlCipher = XMLCipher.getProviderInstance(getJCAProviderName()); } else { xmlCipher = XMLCipher.getInstance(); DocumentFragment docFragment = parseInputStream(input, encryptedData.getDOM().getOwnerDocument()); return docFragment;
checkAndMarshall(encryptedKey); } catch (DecryptionException e) { log.error("Error marshalling EncryptedKey for decryption", e); preProcessEncryptedKey(encryptedKey, algorithm, kek); if (getJCAProviderName() != null) { xmlCipher = XMLCipher.getProviderInstance(getJCAProviderName()); } else { xmlCipher = XMLCipher.getInstance();
/** * Attempt to decrypt by resolving the decryption key using the standard credential resolver. * * @param encryptedData the encrypted data to decrypt * @return the decrypted document fragment, or null if decryption key could not be resolved or decryption failed */ private DocumentFragment decryptUsingResolvedKey(EncryptedData encryptedData) { if (resolver != null) { CriteriaSet criteriaSet = buildCredentialCriteria(encryptedData, resolverCriteria); try { for (Credential cred : resolver.resolve(criteriaSet)) { try { return decryptDataToDOM(encryptedData, SecurityHelper.extractDecryptionKey(cred)); } catch (DecryptionException e) { String msg = "Decryption attempt using credential from standard KeyInfo resolver failed: "; log.debug(msg, e); continue; } } } catch (SecurityException e) { log.error("Error resolving credentials from EncryptedData KeyInfo", e); } } return null; }
CriteriaSet criteriaSet = buildCredentialCriteria(encryptedKey, kekResolverCriteria); try { for (Credential cred : kekResolver.resolve(criteriaSet)) { try { return decryptKey(encryptedKey, algorithm, SecurityHelper.extractDecryptionKey(cred)); } catch (DecryptionException e) { String msg = "Attempt to decrypt EncryptedKey using credential from KEK KeyInfo resolver failed: ";
KeyAlgorithmCriteria algoCrit = buildKeyAlgorithmCriteria(encAlgorithmURI); if (algoCrit != null) { critSet.add(algoCrit); KeyLengthCriteria lengthCrit = buildKeyLengthCriteria(encAlgorithmURI); if (lengthCrit != null) { critSet.add(lengthCrit);
/** * Decrypts the supplied EncryptedData and returns the resulting XMLObject. * * This will only succeed if the decrypted EncryptedData contains exactly one DOM Node of type Element. * * @param encryptedData encrypted data element containing the data to be decrypted * @param rootInNewDocument if true, root the underlying Element of the returned XMLObject in a new Document as * described in {@link Decrypter} * @return the decrypted XMLObject * @throws DecryptionException exception indicating a decryption error, possibly because the decrypted data * contained more than one top-level Element, or some non-Element Node type. */ public XMLObject decryptData(EncryptedData encryptedData, boolean rootInNewDocument) throws DecryptionException { List<XMLObject> xmlObjects = decryptDataToList(encryptedData, rootInNewDocument); if (xmlObjects.size() != 1) { log.error("The decrypted data contained more than one top-level XMLObject child"); throw new DecryptionException("The decrypted data contained more than one XMLObject child"); } return xmlObjects.get(0); }
/** * Utility method to build a new set of credential criteria based on the KeyInfo of an EncryptedData or * EncryptedKey, and any additional static criteria which might have been supplied to the decrypter. * * @param encryptedType an EncryptedData or EncryptedKey for which to resolve decryption credentials * @param staticCriteria static set of credential criteria to add to the new criteria set * @return the new credential criteria set */ private CriteriaSet buildCredentialCriteria(EncryptedType encryptedType, CriteriaSet staticCriteria) { CriteriaSet newCriteriaSet = new CriteriaSet(); // This is the main criteria based on the encrypted type's KeyInfo newCriteriaSet.add(new KeyInfoCriteria(encryptedType.getKeyInfo())); // Also attemtpt to dynamically construct key criteria based on information // in the encrypted object Set<Criteria> keyCriteria = buildKeyCriteria(encryptedType); if (keyCriteria != null && !keyCriteria.isEmpty()) { newCriteriaSet.addAll(keyCriteria); } // Add any static criteria which may have been supplied to the decrypter if (staticCriteria != null && !staticCriteria.isEmpty()) { newCriteriaSet.addAll(staticCriteria); } // If don't have a usage criteria yet from static criteria, add encryption usage if (!newCriteriaSet.contains(UsageCriteria.class)) { newCriteriaSet.add(new UsageCriteria(UsageType.ENCRYPTION)); } return newCriteriaSet; }
List<XMLObject> xmlObjects = new LinkedList<XMLObject>(); DocumentFragment docFragment = decryptDataToDOM(encryptedData);
checkAndMarshall(encryptedData); } catch (DecryptionException e) { log.error("Error marshalling EncryptedData for decryption", e); if (getJCAProviderName() != null) { xmlCipher = XMLCipher.getProviderInstance(getJCAProviderName()); } else { xmlCipher = XMLCipher.getInstance(); DocumentFragment docFragment = parseInputStream(input, encryptedData.getDOM().getOwnerDocument()); return docFragment;
checkAndMarshall(encryptedKey); } catch (DecryptionException e) { log.error("Error marshalling EncryptedKey for decryption", e); preProcessEncryptedKey(encryptedKey, algorithm, kek); if (getJCAProviderName() != null) { xmlCipher = XMLCipher.getProviderInstance(getJCAProviderName()); } else { xmlCipher = XMLCipher.getInstance();
/** * This is a convenience method for calling {@link #decryptDataToList(EncryptedData, boolean)}, * with the <code>rootInNewDocument</code> parameter value supplied by {@link #isRootInNewDocument()}. * * @param encryptedData encrypted data element containing the data to be decrypted * @return the list decrypted top-level XMLObjects * @throws DecryptionException exception indicating a decryption error, possibly because the decrypted data * contained DOM nodes other than type of Element */ public List<XMLObject> decryptDataToList(EncryptedData encryptedData) throws DecryptionException { return decryptDataToList(encryptedData, isRootInNewDocument()); }
/** * Attempt to decrypt by resolving the decryption key using the standard credential resolver. * * @param encryptedData the encrypted data to decrypt * @return the decrypted document fragment, or null if decryption key could not be resolved or decryption failed */ private DocumentFragment decryptUsingResolvedKey(EncryptedData encryptedData) { if (resolver != null) { CriteriaSet criteriaSet = buildCredentialCriteria(encryptedData, resolverCriteria); try { for (Credential cred : resolver.resolve(criteriaSet)) { try { return decryptDataToDOM(encryptedData, SecurityHelper.extractDecryptionKey(cred)); } catch (DecryptionException e) { String msg = "Decryption attempt using credential from standard KeyInfo resolver failed: "; log.debug(msg, e); continue; } } } catch (SecurityException e) { log.error("Error resolving credentials from EncryptedData KeyInfo", e); } } return null; }
CriteriaSet criteriaSet = buildCredentialCriteria(encryptedKey, kekResolverCriteria); try { for (Credential cred : kekResolver.resolve(criteriaSet)) { try { return decryptKey(encryptedKey, algorithm, SecurityHelper.extractDecryptionKey(cred)); } catch (DecryptionException e) { String msg = "Attempt to decrypt EncryptedKey using credential from KEK KeyInfo resolver failed: ";
KeyAlgorithmCriteria algoCrit = buildKeyAlgorithmCriteria(encAlgorithmURI); if (algoCrit != null) { critSet.add(algoCrit); KeyLengthCriteria lengthCrit = buildKeyLengthCriteria(encAlgorithmURI); if (lengthCrit != null) { critSet.add(lengthCrit);
/** * Decrypts the supplied EncryptedData and returns the resulting XMLObject. * * This will only succeed if the decrypted EncryptedData contains exactly one DOM Node of type Element. * * @param encryptedData encrypted data element containing the data to be decrypted * @param rootInNewDocument if true, root the underlying Element of the returned XMLObject in a new Document as * described in {@link Decrypter} * @return the decrypted XMLObject * @throws DecryptionException exception indicating a decryption error, possibly because the decrypted data * contained more than one top-level Element, or some non-Element Node type. */ public XMLObject decryptData(EncryptedData encryptedData, boolean rootInNewDocument) throws DecryptionException { List<XMLObject> xmlObjects = decryptDataToList(encryptedData, rootInNewDocument); if (xmlObjects.size() != 1) { log.error("The decrypted data contained more than one top-level XMLObject child"); throw new DecryptionException("The decrypted data contained more than one XMLObject child"); } return xmlObjects.get(0); }
/** * Utility method to build a new set of credential criteria based on the KeyInfo of an EncryptedData or * EncryptedKey, and any additional static criteria which might have been supplied to the decrypter. * * @param encryptedType an EncryptedData or EncryptedKey for which to resolve decryption credentials * @param staticCriteria static set of credential criteria to add to the new criteria set * @return the new credential criteria set */ private CriteriaSet buildCredentialCriteria(EncryptedType encryptedType, CriteriaSet staticCriteria) { CriteriaSet newCriteriaSet = new CriteriaSet(); // This is the main criteria based on the encrypted type's KeyInfo newCriteriaSet.add(new KeyInfoCriteria(encryptedType.getKeyInfo())); // Also attemtpt to dynamically construct key criteria based on information // in the encrypted object Set<Criteria> keyCriteria = buildKeyCriteria(encryptedType); if (keyCriteria != null && !keyCriteria.isEmpty()) { newCriteriaSet.addAll(keyCriteria); } // Add any static criteria which may have been supplied to the decrypter if (staticCriteria != null && !staticCriteria.isEmpty()) { newCriteriaSet.addAll(staticCriteria); } // If don't have a usage criteria yet from static criteria, add encryption usage if (!newCriteriaSet.contains(UsageCriteria.class)) { newCriteriaSet.add(new UsageCriteria(UsageType.ENCRYPTION)); } return newCriteriaSet; }