use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.
the class XMLEncryptionUtil method decryptElementInDocument.
/**
* Decrypt an encrypted element inside a document
*
* @param documentWithEncryptedElement
* @param privateKey key need to unwrap the encryption key
*
* @return the document with the encrypted element replaced by the data element
*/
public static Element decryptElementInDocument(Document documentWithEncryptedElement, PrivateKey privateKey) throws ProcessingException {
if (documentWithEncryptedElement == null)
throw logger.nullArgumentError("Input document is null");
// Look for encrypted data element
Element documentRoot = documentWithEncryptedElement.getDocumentElement();
Element encDataElement = getNextElementNode(documentRoot.getFirstChild());
if (encDataElement == null)
throw logger.domMissingElementError("No element representing the encrypted data found");
// Look at siblings for the key
Element encKeyElement = getNextElementNode(encDataElement.getNextSibling());
if (encKeyElement == null) {
// Search the enc data element for enc key
NodeList nodeList = encDataElement.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_ENCRYPTEDKEY);
if (nodeList == null || nodeList.getLength() == 0)
throw logger.nullValueError("Encrypted Key not found in the enc data");
encKeyElement = (Element) nodeList.item(0);
}
XMLCipher cipher;
EncryptedData encryptedData;
EncryptedKey encryptedKey;
try {
cipher = XMLCipher.getInstance();
cipher.init(XMLCipher.DECRYPT_MODE, null);
encryptedData = cipher.loadEncryptedData(documentWithEncryptedElement, encDataElement);
encryptedKey = cipher.loadEncryptedKey(documentWithEncryptedElement, encKeyElement);
} catch (XMLEncryptionException e1) {
throw logger.processingError(e1);
}
Document decryptedDoc = null;
if (encryptedData != null && encryptedKey != null) {
try {
String encAlgoURL = encryptedData.getEncryptionMethod().getAlgorithm();
XMLCipher keyCipher = XMLCipher.getInstance();
keyCipher.init(XMLCipher.UNWRAP_MODE, privateKey);
Key encryptionKey = keyCipher.decryptKey(encryptedKey, encAlgoURL);
cipher = XMLCipher.getInstance();
cipher.init(XMLCipher.DECRYPT_MODE, encryptionKey);
decryptedDoc = cipher.doFinal(documentWithEncryptedElement, encDataElement);
} catch (Exception e) {
throw logger.processingError(e);
}
}
if (decryptedDoc == null) {
throw logger.nullValueError("decryptedDoc");
}
Element decryptedRoot = decryptedDoc.getDocumentElement();
Element dataElement = getNextElementNode(decryptedRoot.getFirstChild());
if (dataElement == null)
throw logger.nullValueError("Data Element after encryption is null");
decryptedRoot.removeChild(dataElement);
decryptedDoc.replaceChild(dataElement, decryptedRoot);
return decryptedDoc.getDocumentElement();
}
use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.
the class XMLEncryptionUtil method encryptElement.
/**
* Given an element in a Document, encrypt the element and replace the element in the document with the encrypted
* data
*
* @param elementQName QName of the element that we like to encrypt
* @param document
* @param publicKey
* @param secretKey
* @param keySize
* @param wrappingElementQName A QName of an element that will wrap the encrypted element
* @param addEncryptedKeyInKeyInfo Need for the EncryptedKey to be placed in ds:KeyInfo
*
* @throws ProcessingException
*/
public static void encryptElement(QName elementQName, Document document, PublicKey publicKey, SecretKey secretKey, int keySize, QName wrappingElementQName, boolean addEncryptedKeyInKeyInfo) throws ProcessingException {
if (elementQName == null)
throw logger.nullArgumentError("elementQName");
if (document == null)
throw logger.nullArgumentError("document");
String wrappingElementPrefix = wrappingElementQName.getPrefix();
if (wrappingElementPrefix == null || "".equals(wrappingElementPrefix))
throw logger.wrongTypeError("Wrapping element prefix invalid");
Element documentElement = DocumentUtil.getElement(document, elementQName);
if (documentElement == null)
throw logger.domMissingDocElementError(elementQName.toString());
XMLCipher cipher = null;
EncryptedKey encryptedKey = encryptKey(document, secretKey, publicKey, keySize);
String encryptionAlgorithm = getXMLEncryptionURL(secretKey.getAlgorithm(), keySize);
// Encrypt the Document
try {
cipher = XMLCipher.getInstance(encryptionAlgorithm);
cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
} catch (XMLEncryptionException e1) {
throw logger.processingError(e1);
}
Document encryptedDoc;
try {
encryptedDoc = cipher.doFinal(document, documentElement);
} catch (Exception e) {
throw logger.processingError(e);
}
// The EncryptedKey element is added
Element encryptedKeyElement = cipher.martial(document, encryptedKey);
final String wrappingElementName;
if (StringUtil.isNullOrEmpty(wrappingElementPrefix)) {
wrappingElementName = wrappingElementQName.getLocalPart();
} else {
wrappingElementName = wrappingElementPrefix + ":" + wrappingElementQName.getLocalPart();
}
// Create the wrapping element and set its attribute NS
Element wrappingElement = encryptedDoc.createElementNS(wrappingElementQName.getNamespaceURI(), wrappingElementName);
if (!StringUtil.isNullOrEmpty(wrappingElementPrefix)) {
wrappingElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + wrappingElementPrefix, wrappingElementQName.getNamespaceURI());
}
// Get Hold of the Cipher Data
NodeList cipherElements = encryptedDoc.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_ENCRYPTEDDATA);
if (cipherElements == null || cipherElements.getLength() == 0)
throw logger.domMissingElementError("xenc:EncryptedData");
Element encryptedDataElement = (Element) cipherElements.item(0);
Node parentOfEncNode = encryptedDataElement.getParentNode();
parentOfEncNode.replaceChild(wrappingElement, encryptedDataElement);
wrappingElement.appendChild(encryptedDataElement);
if (addEncryptedKeyInKeyInfo) {
// Outer ds:KeyInfo Element to hold the EncryptionKey
Element sigElement = encryptedDoc.createElementNS(XMLSignature.XMLNS, DS_KEY_INFO);
sigElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:ds", XMLSignature.XMLNS);
sigElement.appendChild(encryptedKeyElement);
// Insert the Encrypted key before the CipherData element
NodeList nodeList = encryptedDoc.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_CIPHERDATA);
if (nodeList == null || nodeList.getLength() == 0)
throw logger.domMissingElementError("xenc:CipherData");
Element cipherDataElement = (Element) nodeList.item(0);
Node cipherParent = cipherDataElement.getParentNode();
cipherParent.insertBefore(sigElement, cipherDataElement);
} else {
// Add the encrypted key as a child of the wrapping element
wrappingElement.appendChild(encryptedKeyElement);
}
}
use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.
the class StaxWriterUtil method writeKeyInfo.
/**
* Write the {@link org.keycloak.dom.xmlsec.w3.xmldsig.KeyInfoType}
*
* @param writer
* @param keyInfo
*
* @throws org.keycloak.saml.common.exceptions.ProcessingException
*/
public static void writeKeyInfo(XMLStreamWriter writer, KeyInfoType keyInfo) throws ProcessingException {
if (keyInfo.getContent() == null || keyInfo.getContent().size() == 0)
throw logger.writerInvalidKeyInfoNullContentError();
StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.KEYINFO, WSTrustConstants.XMLDSig.DSIG_NS);
StaxUtil.writeNameSpace(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.DSIG_NS);
// write the keyInfo content.
Object content = keyInfo.getContent().get(0);
if (content instanceof Element) {
Element element = (Element) keyInfo.getContent().get(0);
StaxUtil.writeDOMNode(writer, element);
} else if (content instanceof X509DataType) {
X509DataType type = (X509DataType) content;
if (type.getDataObjects().size() == 0)
throw logger.writerNullValueError("X509Data");
StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.X509DATA, WSTrustConstants.XMLDSig.DSIG_NS);
Object obj = type.getDataObjects().get(0);
if (obj instanceof Element) {
Element element = (Element) obj;
StaxUtil.writeDOMElement(writer, element);
} else if (obj instanceof X509CertificateType) {
X509CertificateType cert = (X509CertificateType) obj;
StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.X509CERT, WSTrustConstants.XMLDSig.DSIG_NS);
StaxUtil.writeCharacters(writer, new String(cert.getEncodedCertificate(), GeneralConstants.SAML_CHARSET));
StaxUtil.writeEndElement(writer);
}
StaxUtil.writeEndElement(writer);
} else if (content instanceof KeyValueType) {
KeyValueType keyvalueType = (KeyValueType) content;
StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.KEYVALUE, WSTrustConstants.XMLDSig.DSIG_NS);
if (keyvalueType instanceof DSAKeyValueType) {
writeDSAKeyValueType(writer, (DSAKeyValueType) keyvalueType);
}
if (keyvalueType instanceof RSAKeyValueType) {
writeRSAKeyValueType(writer, (RSAKeyValueType) keyvalueType);
}
StaxUtil.writeEndElement(writer);
} else
throw new ProcessingException(ErrorCodes.UNSUPPORTED_TYPE + content);
StaxUtil.writeEndElement(writer);
}
use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.
the class AssertionUtil method decryptAssertion.
/**
* This method modifies the given responseType, and replaces the encrypted assertion with a decrypted version.
* @param responseType a response containg an encrypted assertion
* @return the assertion element as it was decrypted. This can be used in signature verification.
*/
public static Element decryptAssertion(SAMLDocumentHolder holder, ResponseType responseType, PrivateKey privateKey) throws ParsingException, ProcessingException, ConfigurationException {
Document doc = holder.getSamlDocument();
Element enc = DocumentUtil.getElement(doc, new QName(JBossSAMLConstants.ENCRYPTED_ASSERTION.get()));
if (enc == null) {
throw new ProcessingException("No encrypted assertion found.");
}
String oldID = enc.getAttribute(JBossSAMLConstants.ID.get());
Document newDoc = DocumentUtil.createDocument();
Node importedNode = newDoc.importNode(enc, true);
newDoc.appendChild(importedNode);
Element decryptedDocumentElement = XMLEncryptionUtil.decryptElementInDocument(newDoc, privateKey);
SAMLParser parser = SAMLParser.getInstance();
JAXPValidationUtil.checkSchemaValidation(decryptedDocumentElement);
AssertionType assertion = (AssertionType) parser.parse(parser.createEventReader(DocumentUtil.getNodeAsStream(decryptedDocumentElement)));
responseType.replaceAssertion(oldID, new ResponseType.RTChoiceType(assertion));
return decryptedDocumentElement;
}
use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.
the class AssertionUtil method asDocument.
/**
* Given {@code AssertionType}, convert it into a DOM Document.
*
* @param assertion
*
* @return
*
* @throws ProcessingException
*/
public static Document asDocument(AssertionType assertion) throws ProcessingException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SAMLAssertionWriter writer = new SAMLAssertionWriter(StaxUtil.getXMLStreamWriter(baos));
writer.write(assertion);
try {
return DocumentUtil.getDocument(new ByteArrayInputStream(baos.toByteArray()));
} catch (Exception e) {
throw logger.processingError(e);
}
}
Aggregations