| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| */ |
| |
| /* |
| * XSEC |
| * |
| * XENCEncryptedTypeImpl := Implementation of the EncryptedType interface |
| * element |
| * |
| * $Id$ |
| * |
| */ |
| |
| |
| #include <xsec/dsig/DSIGReference.hpp> |
| #include <xsec/framework/XSECDefs.hpp> |
| #include <xsec/framework/XSECEnv.hpp> |
| #include <xsec/framework/XSECError.hpp> |
| #include <xsec/transformers/TXFMBase64.hpp> |
| #include <xsec/transformers/TXFMChain.hpp> |
| #include <xsec/transformers/TXFMSB.hpp> |
| #include <xsec/transformers/TXFMC14n.hpp> |
| #include <xsec/xenc/XENCEncryptedKey.hpp> |
| |
| #include "XENCCipherImpl.hpp" |
| #include "XENCCipherDataImpl.hpp" |
| #include "XENCEncryptedTypeImpl.hpp" |
| #include "XENCEncryptionMethodImpl.hpp" |
| #include "../../utils/XSECAutoPtr.hpp" |
| #include "../../utils/XSECDOMUtils.hpp" |
| |
| #include <xercesc/util/XMLUniDefs.hpp> |
| #include <xercesc/util/Janitor.hpp> |
| |
| XERCES_CPP_NAMESPACE_USE |
| |
| // -------------------------------------------------------------------------------- |
| // UNICODE Strings |
| // -------------------------------------------------------------------------------- |
| |
| static XMLCh s_EncryptionMethod[] = { |
| |
| chLatin_E, |
| chLatin_n, |
| chLatin_c, |
| chLatin_r, |
| chLatin_y, |
| chLatin_p, |
| chLatin_t, |
| chLatin_i, |
| chLatin_o, |
| chLatin_n, |
| chLatin_M, |
| chLatin_e, |
| chLatin_t, |
| chLatin_h, |
| chLatin_o, |
| chLatin_d, |
| chNull, |
| }; |
| |
| static XMLCh s_KeyInfo[] = { |
| |
| chLatin_K, |
| chLatin_e, |
| chLatin_y, |
| chLatin_I, |
| chLatin_n, |
| chLatin_f, |
| chLatin_o, |
| chNull, |
| }; |
| |
| static XMLCh s_CipherData[] = { |
| |
| chLatin_C, |
| chLatin_i, |
| chLatin_p, |
| chLatin_h, |
| chLatin_e, |
| chLatin_r, |
| chLatin_D, |
| chLatin_a, |
| chLatin_t, |
| chLatin_a, |
| chNull, |
| }; |
| |
| static XMLCh s_Type[] = { |
| |
| chLatin_T, |
| chLatin_y, |
| chLatin_p, |
| chLatin_e, |
| chNull |
| }; |
| |
| static XMLCh s_MimeType[] = { |
| |
| chLatin_M, |
| chLatin_i, |
| chLatin_m, |
| chLatin_e, |
| chLatin_T, |
| chLatin_y, |
| chLatin_p, |
| chLatin_e, |
| chNull |
| }; |
| |
| |
| static XMLCh s_Encoding[] = { |
| |
| chLatin_E, |
| chLatin_n, |
| chLatin_c, |
| chLatin_o, |
| chLatin_d, |
| chLatin_i, |
| chLatin_n, |
| chLatin_g, |
| chNull |
| }; |
| |
| // -------------------------------------------------------------------------------- |
| // Constructors and Destructors |
| // -------------------------------------------------------------------------------- |
| |
| XENCEncryptedTypeImpl::XENCEncryptedTypeImpl(const XSECEnv * env) : |
| mp_env(env), |
| mp_encryptedTypeElement(NULL), |
| mp_keyInfoElement(NULL), |
| mp_cipherDataElement(NULL), |
| mp_cipherData(NULL), |
| mp_encryptionMethod(NULL), |
| m_keyInfoList(env), |
| mp_typeAttr(NULL), |
| mp_mimeTypeAttr(NULL), |
| mp_encodingAttr(NULL) { |
| |
| } |
| |
| |
| XENCEncryptedTypeImpl::XENCEncryptedTypeImpl(const XSECEnv * env, DOMElement * node) : |
| mp_env(env), |
| mp_encryptedTypeElement(node), |
| mp_keyInfoElement(NULL), |
| mp_cipherDataElement(NULL), |
| mp_cipherData(NULL), |
| mp_encryptionMethod(NULL), |
| m_keyInfoList(env), |
| mp_typeAttr(NULL), |
| mp_mimeTypeAttr(NULL), |
| mp_encodingAttr(NULL) { |
| |
| } |
| |
| XENCEncryptedTypeImpl::~XENCEncryptedTypeImpl() { |
| |
| if (mp_cipherData != NULL) |
| delete mp_cipherData; |
| |
| if (mp_encryptionMethod != NULL) |
| delete mp_encryptionMethod; |
| |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // Load DOM Structures |
| // -------------------------------------------------------------------------------- |
| |
| void XENCEncryptedTypeImpl::load() { |
| |
| if (mp_encryptedTypeElement == NULL) { |
| |
| // Attempt to load an empty encryptedType element |
| throw XSECException(XSECException::EncryptedTypeError, |
| "XENCEncryptedType::load - called on empty DOM"); |
| |
| } |
| |
| // Type |
| mp_typeAttr = mp_encryptedTypeElement->getAttributeNodeNS(NULL, s_Type); |
| // MimeType |
| mp_mimeTypeAttr = mp_encryptedTypeElement->getAttributeNodeNS(NULL, s_MimeType); |
| // Encoding |
| mp_encodingAttr = mp_encryptedTypeElement->getAttributeNodeNS(NULL, s_Encoding); |
| |
| // Don't know what the node name should be (held by super class), |
| // so go straight to the children |
| |
| DOMElement *tmpElt = (DOMElement *) findFirstChildOfType(mp_encryptedTypeElement, DOMNode::ELEMENT_NODE); |
| |
| if (tmpElt != NULL && strEquals(getXENCLocalName(tmpElt), s_EncryptionMethod)) { |
| |
| XSECnew(mp_encryptionMethod, XENCEncryptionMethodImpl(mp_env, tmpElt)); |
| mp_encryptionMethod->load(); |
| |
| tmpElt = findNextElementChild(tmpElt); |
| |
| } |
| |
| if (tmpElt != NULL && strEquals(getDSIGLocalName(tmpElt), s_KeyInfo)) { |
| |
| // Load |
| mp_keyInfoElement = tmpElt; |
| m_keyInfoList.loadListFromXML(tmpElt); |
| |
| // Find the next node |
| |
| tmpElt = findNextElementChild(tmpElt); |
| |
| } |
| |
| if (tmpElt != NULL && strEquals(getXENCLocalName(tmpElt), s_CipherData)) { |
| |
| mp_cipherDataElement = tmpElt; |
| |
| XSECnew(mp_cipherData, XENCCipherDataImpl(mp_env, tmpElt)); |
| mp_cipherData->load(); |
| tmpElt = findNextElementChild(tmpElt); |
| |
| } |
| |
| else { |
| |
| throw XSECException(XSECException::ExpectedXENCChildNotFound, |
| "Expected <CipherData> child of <EncryptedType>"); |
| |
| } |
| |
| // Should check for EncryptionProperties |
| |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // Create a blank structure |
| // -------------------------------------------------------------------------------- |
| |
| DOMElement * XENCEncryptedTypeImpl::createBlankEncryptedType( |
| XMLCh * localName, |
| XENCCipherData::XENCCipherDataType type, |
| const XMLCh * algorithm, |
| const XMLCh * value) { |
| |
| // Reset |
| mp_cipherData = NULL; |
| mp_encryptionMethod = NULL; |
| |
| // Get some setup values |
| safeBuffer str; |
| DOMDocument *doc = mp_env->getParentDocument(); |
| const XMLCh * prefix = mp_env->getXENCNSPrefix(); |
| |
| makeQName(str, prefix, localName); |
| |
| mp_encryptedTypeElement = doc->createElementNS(DSIGConstants::s_unicodeStrURIXENC, str.rawXMLChBuffer()); |
| |
| // Set namespace |
| if (prefix[0] == XERCES_CPP_NAMESPACE_QUALIFIER chNull) { |
| str.sbTranscodeIn("xmlns"); |
| } |
| else { |
| str.sbTranscodeIn("xmlns:"); |
| str.sbXMLChCat(prefix); |
| } |
| |
| mp_encryptedTypeElement->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, |
| str.rawXMLChBuffer(), |
| DSIGConstants::s_unicodeStrURIXENC); |
| |
| mp_env->doPrettyPrint(mp_encryptedTypeElement); |
| |
| // Create the EncryptionMethod |
| if (algorithm != NULL) { |
| |
| XSECnew(mp_encryptionMethod, XENCEncryptionMethodImpl(mp_env)); |
| DOMNode * encryptionMethodNode = |
| mp_encryptionMethod->createBlankEncryptionMethod(algorithm); |
| |
| mp_encryptedTypeElement->appendChild(encryptionMethodNode); |
| |
| mp_env->doPrettyPrint(mp_encryptedTypeElement); |
| |
| } |
| |
| // Create the cipher Data |
| XSECnew(mp_cipherData, XENCCipherDataImpl(mp_env)); |
| mp_cipherDataElement = mp_cipherData->createBlankCipherData(type, value); |
| |
| // Add to EncryptedType |
| mp_encryptedTypeElement->appendChild(mp_cipherDataElement); |
| |
| mp_env->doPrettyPrint(mp_encryptedTypeElement); |
| |
| return mp_encryptedTypeElement; |
| |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // Create a txfm chain for this transform list |
| // -------------------------------------------------------------------------------- |
| |
| TXFMChain * XENCEncryptedTypeImpl::createCipherTXFMChain(void) { |
| |
| if (mp_cipherData->getCipherDataType() == XENCCipherData::VALUE_TYPE) { |
| |
| TXFMChain * chain; |
| |
| // Given we already have this in memory, we transcode to |
| // local code page and then transform |
| |
| XSECAutoPtrChar b64(mp_cipherData->getCipherValue()->getCipherString()); |
| |
| try { |
| TXFMSB *sb; |
| XSECnew(sb, TXFMSB(mp_env->getParentDocument())); |
| |
| safeBuffer temp(b64.get()); |
| sb->setInput(temp); |
| |
| // Create a chain |
| XSECnew(chain, TXFMChain(sb)); |
| |
| // Create a base64 decoder |
| TXFMBase64 * tb64; |
| XSECnew(tb64, TXFMBase64(mp_env->getParentDocument())); |
| |
| chain->appendTxfm(tb64); |
| |
| return chain; |
| } |
| catch (...) { |
| throw; |
| } |
| } |
| |
| else if (mp_cipherData->getCipherDataType() == XENCCipherData::REFERENCE_TYPE) { |
| |
| TXFMChain * chain; |
| TXFMBase * b = DSIGReference::getURIBaseTXFM(mp_env->getParentDocument(), mp_cipherData->getCipherReference()->getURI(), mp_env); |
| |
| chain = DSIGReference::createTXFMChainFromList(b, mp_cipherData->getCipherReference()->getTransforms()); |
| Janitor<TXFMChain> j_chain(chain); |
| |
| if (chain->getLastTxfm()->getOutputType() == TXFMBase::DOM_NODES) { |
| |
| TXFMC14n * c14n; |
| XSECnew(c14n, TXFMC14n(mp_env->getParentDocument())); |
| chain->appendTxfm(c14n); |
| |
| } |
| |
| j_chain.release(); |
| return chain; |
| |
| } |
| |
| else { |
| |
| throw XSECException(XSECException::EncryptedTypeError, |
| "XENCEncryptedType::createDecryptionTXFMChain - Unknown type of CipherData"); |
| |
| } |
| |
| |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // Get Methods |
| // -------------------------------------------------------------------------------- |
| |
| XENCCipherData * XENCEncryptedTypeImpl::getCipherData() const { |
| |
| return mp_cipherData; |
| |
| } |
| |
| XENCEncryptionMethod * XENCEncryptedTypeImpl::getEncryptionMethod() const { |
| |
| return mp_encryptionMethod; |
| |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // KeyInfo elements |
| // -------------------------------------------------------------------------------- |
| |
| const DSIGKeyInfoList * XENCEncryptedTypeImpl::getKeyInfoList() const { |
| return &m_keyInfoList; |
| } |
| |
| DSIGKeyInfoList * XENCEncryptedTypeImpl::getKeyInfoList() { |
| return &m_keyInfoList; |
| } |
| |
| void XENCEncryptedTypeImpl::clearKeyInfo() { |
| |
| if (mp_keyInfoElement == NULL) |
| return; |
| |
| if (mp_encryptedTypeElement->removeChild(mp_keyInfoElement) != mp_keyInfoElement) { |
| |
| throw XSECException(XSECException::ExpectedDSIGChildNotFound, |
| "Attempted to remove KeyInfo node but it is no longer a child of <EncryptedType>"); |
| |
| } |
| |
| mp_keyInfoElement->release(); // No longer required |
| |
| mp_keyInfoElement = NULL; |
| |
| // Clear out the list |
| m_keyInfoList.empty(); |
| |
| } |
| |
| void XENCEncryptedTypeImpl::createKeyInfoElement() { |
| |
| if (mp_keyInfoElement != NULL) |
| return; |
| |
| safeBuffer str; |
| |
| const XMLCh * prefixNS = mp_env->getDSIGNSPrefix(); |
| makeQName(str, prefixNS, "KeyInfo"); |
| |
| mp_keyInfoElement = m_keyInfoList.createKeyInfo(); |
| |
| // Place the node before the CipherData node |
| if (mp_cipherDataElement == NULL) { |
| |
| throw XSECException(XSECException::EncryptedTypeError, |
| "XENCEncryptedTypeImpl::createKeyInfoElement - unable to find CipherData node"); |
| |
| } |
| |
| mp_encryptedTypeElement->insertBefore(mp_keyInfoElement, mp_cipherDataElement); |
| |
| if (mp_env->getPrettyPrintFlag() == true) |
| mp_encryptedTypeElement->insertBefore(mp_env->getParentDocument()->createTextNode(DSIGConstants::s_unicodeStrNL), mp_cipherDataElement); |
| |
| // Need to add the DS namespace |
| |
| if (prefixNS[0] == '\0') { |
| str.sbTranscodeIn("xmlns"); |
| } |
| else { |
| str.sbTranscodeIn("xmlns:"); |
| str.sbXMLChCat(prefixNS); |
| } |
| |
| mp_keyInfoElement->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, |
| str.rawXMLChBuffer(), |
| DSIGConstants::s_unicodeStrURIDSIG); |
| |
| } |
| |
| DSIGKeyInfoValue * XENCEncryptedTypeImpl::appendDSAKeyValue(const XMLCh * P, |
| const XMLCh * Q, |
| const XMLCh * G, |
| const XMLCh * Y) { |
| |
| createKeyInfoElement(); |
| return m_keyInfoList.appendDSAKeyValue(P, Q, G, Y); |
| |
| } |
| |
| DSIGKeyInfoValue * XENCEncryptedTypeImpl::appendRSAKeyValue(const XMLCh * modulus, |
| const XMLCh * exponent) { |
| |
| createKeyInfoElement(); |
| return m_keyInfoList.appendRSAKeyValue(modulus, exponent); |
| |
| } |
| |
| |
| DSIGKeyInfoX509 * XENCEncryptedTypeImpl::appendX509Data() { |
| |
| createKeyInfoElement(); |
| return m_keyInfoList.appendX509Data(); |
| |
| } |
| |
| DSIGKeyInfoName * XENCEncryptedTypeImpl::appendKeyName(const XMLCh * name, bool isDName) { |
| |
| createKeyInfoElement(); |
| return m_keyInfoList.appendKeyName(name, isDName); |
| |
| } |
| |
| DSIGKeyInfoPGPData * XENCEncryptedTypeImpl::appendPGPData(const XMLCh * id, const XMLCh * packet) { |
| |
| createKeyInfoElement(); |
| return m_keyInfoList.appendPGPData(id, packet); |
| |
| } |
| |
| DSIGKeyInfoSPKIData * XENCEncryptedTypeImpl::appendSPKIData(const XMLCh * sexp) { |
| |
| createKeyInfoElement(); |
| return m_keyInfoList.appendSPKIData(sexp); |
| |
| } |
| |
| DSIGKeyInfoMgmtData * XENCEncryptedTypeImpl::appendMgmtData(const XMLCh * data) { |
| |
| createKeyInfoElement(); |
| return m_keyInfoList.appendMgmtData(data); |
| |
| } |
| |
| void XENCEncryptedTypeImpl::appendEncryptedKey(XENCEncryptedKey * encryptedKey) { |
| |
| createKeyInfoElement(); |
| m_keyInfoList.addAndInsertKeyInfo(encryptedKey); |
| |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // Type URI handling |
| // -------------------------------------------------------------------------------- |
| |
| const XMLCh * XENCEncryptedTypeImpl::getType() const { |
| |
| if (mp_typeAttr != NULL) |
| return mp_typeAttr->getNodeValue(); |
| |
| return NULL; |
| |
| } |
| |
| void XENCEncryptedTypeImpl::setType(const XMLCh * uri) { |
| |
| if (mp_typeAttr != NULL) { |
| mp_typeAttr->setNodeValue(uri); |
| } |
| else { |
| |
| // Need to create the node |
| mp_encryptedTypeElement->setAttributeNS(NULL, s_Type, uri); |
| mp_typeAttr = mp_encryptedTypeElement->getAttributeNodeNS(NULL, s_Type); |
| |
| if (mp_typeAttr == NULL) { |
| |
| throw XSECException(XSECException::InternalError, |
| "XENCEncryptedTypeImpl::setTypeURI - Cannot find the attribute I just added"); |
| |
| } |
| |
| } |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // MimeType handling |
| // -------------------------------------------------------------------------------- |
| |
| const XMLCh * XENCEncryptedTypeImpl::getMimeType() const { |
| |
| if (mp_mimeTypeAttr != NULL) |
| return mp_mimeTypeAttr->getNodeValue(); |
| |
| return NULL; |
| |
| } |
| |
| void XENCEncryptedTypeImpl::setMimeType(const XMLCh * mimeType) { |
| |
| if (mp_mimeTypeAttr != NULL) { |
| mp_mimeTypeAttr->setNodeValue(mimeType); |
| } |
| else { |
| |
| // Need to create the node |
| mp_encryptedTypeElement->setAttributeNS(NULL, s_MimeType, mimeType); |
| mp_mimeTypeAttr = mp_encryptedTypeElement->getAttributeNodeNS(NULL, s_MimeType); |
| if (mp_mimeTypeAttr == NULL) { |
| |
| throw XSECException(XSECException::InternalError, |
| "XENCEncryptedTypeImpl::setMimeType - Cannot find the attribute I just added"); |
| |
| } |
| |
| } |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // Encoding handling |
| // -------------------------------------------------------------------------------- |
| |
| const XMLCh * XENCEncryptedTypeImpl::getEncoding() const { |
| |
| if (mp_encodingAttr != NULL) |
| return mp_encodingAttr->getNodeValue(); |
| |
| return NULL; |
| |
| } |
| |
| void XENCEncryptedTypeImpl::setEncoding(const XMLCh * uri) { |
| |
| if (mp_encodingAttr != NULL) { |
| mp_encodingAttr->setNodeValue(uri); |
| } |
| else { |
| |
| // Need to create the node |
| mp_encryptedTypeElement->setAttributeNS(NULL, s_Encoding, uri); |
| mp_encodingAttr = mp_encryptedTypeElement->getAttributeNodeNS(NULL, s_Encoding); |
| |
| if (mp_encodingAttr == NULL) { |
| |
| throw XSECException(XSECException::InternalError, |
| "XENCEncryptedTypeImpl::setEncodingURI - Cannot find the attribute I just added"); |
| |
| } |
| |
| } |
| } |