blob: d90c0f1dace6864ccdb2f5a4775db68a89393d41 [file] [log] [blame]
/**
* 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
*
* XKMSKeyBindingAbstractTypeImpl := Implementation of base for KeyBinding elements
*
* $Id$
*
*/
#include <xsec/dsig/DSIGKeyInfoList.hpp>
#include <xsec/framework/XSECDefs.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/framework/XSECEnv.hpp>
XERCES_CPP_NAMESPACE_USE
#ifdef XSEC_XKMS_ENABLED
#include "../../utils/XSECDOMUtils.hpp"
#include "XKMSKeyBindingAbstractTypeImpl.hpp"
#include "XKMSUseKeyWithImpl.hpp"
#include <xsec/xkms/XKMSConstants.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
// --------------------------------------------------------------------------------
// Constructor/Destructor
// --------------------------------------------------------------------------------
XKMSKeyBindingAbstractTypeImpl::XKMSKeyBindingAbstractTypeImpl(
const XSECEnv * env) :
mp_keyBindingAbstractTypeElement(NULL),
mp_env(env),
mp_idAttr(NULL),
mp_keyUsageSignatureElement(NULL),
mp_keyUsageEncryptionElement(NULL),
mp_keyUsageExchangeElement(NULL),
mp_keyInfoElement(NULL) {
XSECnew(mp_keyInfoList, DSIGKeyInfoList(mp_env));
}
XKMSKeyBindingAbstractTypeImpl::XKMSKeyBindingAbstractTypeImpl(
const XSECEnv * env,
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * node) :
mp_keyBindingAbstractTypeElement(node),
mp_env(env),
mp_idAttr(NULL),
mp_keyUsageSignatureElement(NULL),
mp_keyUsageEncryptionElement(NULL),
mp_keyUsageExchangeElement(NULL),
mp_keyInfoElement(NULL) {
XSECnew(mp_keyInfoList, DSIGKeyInfoList(mp_env));
}
XKMSKeyBindingAbstractTypeImpl::~XKMSKeyBindingAbstractTypeImpl() {
if (mp_keyInfoList != NULL)
delete mp_keyInfoList;
UseKeyWithVectorType::iterator i;
for (i = m_useKeyWithList.begin(); i != m_useKeyWithList.end(); ++i)
delete (*i);
}
// --------------------------------------------------------------------------------
// Load from DOM
// --------------------------------------------------------------------------------
void XKMSKeyBindingAbstractTypeImpl::load(void) {
if (mp_keyBindingAbstractTypeElement == NULL) {
throw XSECException(XSECException::ExpectedXKMSChildNotFound,
"XKMSKeyBindingAbstractTypeImpl::load - called on empty DOM");
}
// Id
mp_idAttr =
mp_keyBindingAbstractTypeElement->getAttributeNodeNS(NULL, XKMSConstants::s_tagId);
DOMElement * tmpElt = findFirstElementChild(mp_keyBindingAbstractTypeElement);
if (tmpElt != NULL && strEquals(getDSIGLocalName(tmpElt), XKMSConstants::s_tagKeyInfo)) {
if (mp_keyInfoList != NULL)
delete mp_keyInfoList;
XSECnew(mp_keyInfoList, DSIGKeyInfoList(mp_env));
mp_keyInfoList->loadListFromXML(tmpElt);
mp_keyInfoElement = tmpElt;
tmpElt = findNextElementChild(tmpElt);
}
while (tmpElt != NULL && strEquals(getXKMSLocalName(tmpElt), XKMSConstants::s_tagKeyUsage)) {
DOMNode * txt = findFirstChildOfType(tmpElt, DOMNode::TEXT_NODE);
if (txt == NULL) {
throw XSECException(XSECException::ExpectedXKMSChildNotFound,
"XKMSKeyBindingAbstractTypeImpl::load - Require text node beneath <KeyUsage>");
}
const XMLCh * usageStr = txt->getNodeValue();
int index = XMLString::indexOf(usageStr, chPound);
if (index == -1 || XMLString::compareNString(usageStr, XKMSConstants::s_unicodeStrURIXKMS, index)) {
throw XSECException(XSECException::XKMSError,
"XKMSResultType::load - KeyUsage not in XKMS Name Space");
}
usageStr = &usageStr[index+1];
if (strEquals(usageStr, XKMSConstants::s_tagEncryption)) {
mp_keyUsageEncryptionElement = tmpElt;
} else if (strEquals(usageStr, XKMSConstants::s_tagExchange)) {
mp_keyUsageExchangeElement = tmpElt;
} else if (strEquals(usageStr, XKMSConstants::s_tagSignature)) {
mp_keyUsageSignatureElement = tmpElt;
} else {
throw XSECException(XSECException::ExpectedXKMSChildNotFound,
"XKMSKeyBindingAbstractTypeImpl::load - require Encryption, Exchange or Signature text node beneath <KeyUsage>");
}
tmpElt = findNextElementChild(tmpElt);
}
while (tmpElt != NULL && strEquals(getXKMSLocalName(tmpElt), XKMSConstants::s_tagUseKeyWith)) {
XKMSUseKeyWithImpl *ukw;
XSECnew(ukw, XKMSUseKeyWithImpl(mp_env, tmpElt));
m_useKeyWithList.push_back(ukw);
ukw->load();
tmpElt = findNextElementChild(tmpElt);
}
}
// --------------------------------------------------------------------------------
// Create Blank
// --------------------------------------------------------------------------------
DOMElement * XKMSKeyBindingAbstractTypeImpl::createBlankKeyBindingAbstractType(const XMLCh * tag) {
// Get some setup values
safeBuffer str;
DOMDocument *doc = mp_env->getParentDocument();
const XMLCh * prefix = mp_env->getXKMSNSPrefix();
makeQName(str, prefix, tag);
mp_keyBindingAbstractTypeElement = doc->createElementNS(XKMSConstants::s_unicodeStrURIXKMS,
str.rawXMLChBuffer());
mp_env->doPrettyPrint(mp_keyBindingAbstractTypeElement);
return mp_keyBindingAbstractTypeElement;
}
// --------------------------------------------------------------------------------
// Getter methods
// --------------------------------------------------------------------------------
DOMElement * XKMSKeyBindingAbstractTypeImpl::getElement(void) const {
return mp_keyBindingAbstractTypeElement;
}
const XMLCh * XKMSKeyBindingAbstractTypeImpl::getId(void) const {
return (mp_idAttr != NULL ? mp_idAttr->getNodeValue() : NULL);
}
DSIGKeyInfoList * XKMSKeyBindingAbstractTypeImpl::getKeyInfoList(void) const {
return mp_keyInfoList;
}
bool XKMSKeyBindingAbstractTypeImpl::getEncryptionKeyUsage(void) const {
return (mp_keyUsageEncryptionElement != NULL ||
(mp_keyUsageExchangeElement == NULL && mp_keyUsageSignatureElement == NULL));
}
bool XKMSKeyBindingAbstractTypeImpl::getSignatureKeyUsage(void) const {
return (mp_keyUsageSignatureElement != NULL ||
(mp_keyUsageExchangeElement == NULL && mp_keyUsageEncryptionElement == NULL));
}
bool XKMSKeyBindingAbstractTypeImpl::getExchangeKeyUsage(void) const {
return (mp_keyUsageExchangeElement != NULL ||
(mp_keyUsageEncryptionElement == NULL && mp_keyUsageSignatureElement == NULL));
}
// --------------------------------------------------------------------------------
// KeyInfo elements
// --------------------------------------------------------------------------------
DSIGKeyInfoList * XKMSKeyBindingAbstractTypeImpl::getKeyInfoList() {
return mp_keyInfoList;
}
void XKMSKeyBindingAbstractTypeImpl::clearKeyInfo(void) {
if (mp_keyInfoElement == NULL)
return;
if (mp_keyBindingAbstractTypeElement->removeChild(mp_keyInfoElement) != mp_keyInfoElement) {
throw XSECException(XSECException::ExpectedDSIGChildNotFound,
"Attempted to remove KeyInfo node but it is no longer a child of <KeyBindingAbstractType>");
}
mp_keyInfoElement->release(); // No longer required
mp_keyInfoElement = NULL;
// Clear out the list
mp_keyInfoList->empty();
}
void XKMSKeyBindingAbstractTypeImpl::createKeyInfoElement(void) {
if (mp_keyInfoElement != NULL)
return;
safeBuffer str;
const XMLCh * prefixNS = mp_env->getDSIGNSPrefix();
makeQName(str, prefixNS, "KeyInfo");
mp_keyInfoElement = mp_keyInfoList->createKeyInfo();
// Needs to be first element
DOMNode * insertBefore = mp_keyBindingAbstractTypeElement->getFirstChild();
if (insertBefore != NULL) {
if (mp_env->getPrettyPrintFlag() == true)
mp_keyBindingAbstractTypeElement->insertBefore(mp_env->getParentDocument()->createTextNode(DSIGConstants::s_unicodeStrNL), insertBefore);
mp_keyBindingAbstractTypeElement->insertBefore(mp_keyInfoElement, insertBefore);
}
else {
mp_keyBindingAbstractTypeElement->appendChild(mp_keyInfoElement);
mp_env->doPrettyPrint(mp_keyBindingAbstractTypeElement);
}
// 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);
}
DSIGKeyInfoName * XKMSKeyBindingAbstractTypeImpl::appendKeyName(const XMLCh * name, bool isDName) {
createKeyInfoElement();
return mp_keyInfoList->appendKeyName(name, isDName);
}
DSIGKeyInfoValue * XKMSKeyBindingAbstractTypeImpl::appendDSAKeyValue(const XMLCh * P,
const XMLCh * Q,
const XMLCh * G,
const XMLCh * Y) {
createKeyInfoElement();
return mp_keyInfoList->appendDSAKeyValue(P, Q, G, Y);
}
DSIGKeyInfoValue * XKMSKeyBindingAbstractTypeImpl::appendRSAKeyValue(const XMLCh * modulus,
const XMLCh * exponent) {
createKeyInfoElement();
return mp_keyInfoList->appendRSAKeyValue(modulus, exponent);
}
DSIGKeyInfoX509 * XKMSKeyBindingAbstractTypeImpl::appendX509Data(void) {
createKeyInfoElement();
return mp_keyInfoList->appendX509Data();
}
DSIGKeyInfoPGPData * XKMSKeyBindingAbstractTypeImpl::appendPGPData(const XMLCh * id, const XMLCh * packet) {
createKeyInfoElement();
return mp_keyInfoList->appendPGPData(id, packet);
}
DSIGKeyInfoSPKIData * XKMSKeyBindingAbstractTypeImpl::appendSPKIData(const XMLCh * sexp) {
createKeyInfoElement();
return mp_keyInfoList->appendSPKIData(sexp);
}
DSIGKeyInfoMgmtData * XKMSKeyBindingAbstractTypeImpl::appendMgmtData(const XMLCh * data) {
createKeyInfoElement();
return mp_keyInfoList->appendMgmtData(data);
}
// --------------------------------------------------------------------------------
// Setter methods
// --------------------------------------------------------------------------------
void XKMSKeyBindingAbstractTypeImpl::setId(const XMLCh * id) {
// Setup the id
XMLCh * myId;
if (id == NULL)
myId = generateId();
mp_keyBindingAbstractTypeElement->setAttributeNS(NULL, XKMSConstants::s_tagId, id ? id : myId);
if (id == NULL)
XSEC_RELEASE_XMLCH(myId);
mp_keyBindingAbstractTypeElement->setIdAttributeNS(NULL, XKMSConstants::s_tagId, true);
mp_idAttr =
mp_keyBindingAbstractTypeElement->getAttributeNodeNS(NULL, XKMSConstants::s_tagId);
}
DOMElement * XKMSKeyBindingAbstractTypeImpl::setKeyUsage(const XMLCh * usage) {
/* Create the element and string*/
safeBuffer str;
DOMDocument *doc = mp_env->getParentDocument();
const XMLCh * prefix = mp_env->getXKMSNSPrefix();
makeQName(str, prefix, XKMSConstants::s_tagKeyUsage);
/* Create the element */
DOMElement * e = doc->createElementNS(XKMSConstants::s_unicodeStrURIXKMS,
str.rawXMLChBuffer());
str.sbXMLChIn(XKMSConstants::s_unicodeStrURIXKMS);
str.sbXMLChCat(usage);
e->appendChild(doc->createTextNode(str.rawXMLChBuffer()));
/* Now find where it goes */
DOMElement * t = findFirstElementChild(mp_keyBindingAbstractTypeElement);
while (t != NULL) {
if (!strEquals(getDSIGLocalName(t), XKMSConstants::s_tagKeyInfo) &&
!strEquals(getXKMSLocalName(t), XKMSConstants::s_tagKeyUsage))
break;
t = findNextElementChild(t);
}
// Append the element
if (t == NULL) {
mp_keyBindingAbstractTypeElement->appendChild(e);
mp_env->doPrettyPrint(mp_keyBindingAbstractTypeElement);
}
else {
mp_keyBindingAbstractTypeElement->insertBefore(e, t);
if (mp_env->getPrettyPrintFlag()) {
mp_keyBindingAbstractTypeElement->insertBefore(
mp_env->getParentDocument()->createTextNode(DSIGConstants::s_unicodeStrNL),
t);
}
}
return e;
}
void XKMSKeyBindingAbstractTypeImpl::setEncryptionKeyUsage(void) {
if (mp_keyUsageEncryptionElement != NULL)
return;
mp_keyUsageEncryptionElement = setKeyUsage(XKMSConstants::s_tagEncryption);
}
void XKMSKeyBindingAbstractTypeImpl::setSignatureKeyUsage(void) {
if (mp_keyUsageSignatureElement != NULL)
return;
mp_keyUsageSignatureElement = setKeyUsage(XKMSConstants::s_tagSignature);
}
void XKMSKeyBindingAbstractTypeImpl::setExchangeKeyUsage(void) {
if (mp_keyUsageExchangeElement != NULL)
return;
mp_keyUsageExchangeElement = setKeyUsage(XKMSConstants::s_tagExchange);
}
// --------------------------------------------------------------------------------
// UseKeyWith handling
// --------------------------------------------------------------------------------
int XKMSKeyBindingAbstractTypeImpl::getUseKeyWithSize(void) const {
return (int) m_useKeyWithList.size();
}
XKMSUseKeyWith * XKMSKeyBindingAbstractTypeImpl::getUseKeyWithItem(int item) const {
if (item < 0 || item >= (int) m_useKeyWithList.size()) {
throw XSECException(XSECException::XKMSError,
"XKMSKeyBindingAbstractType::getUseKeyWithItem - item out of range");
}
return m_useKeyWithList[item];
}
XKMSUseKeyWith * XKMSKeyBindingAbstractTypeImpl::appendUseKeyWithItem(
const XMLCh * application,
const XMLCh * identifier) {
XKMSUseKeyWithImpl * u;
XSECnew(u, XKMSUseKeyWithImpl(mp_env));
m_useKeyWithList.push_back(u);
DOMElement * e = u->createBlankUseKeyWith(application, identifier);
// Find where to append the element
DOMElement * t = findFirstElementChild(mp_keyBindingAbstractTypeElement);
while (t != NULL) {
if (!strEquals(getDSIGLocalName(t), XKMSConstants::s_tagKeyInfo) &&
!strEquals(getXKMSLocalName(t), XKMSConstants::s_tagKeyUsage) &&
!strEquals(getXKMSLocalName(t), XKMSConstants::s_tagUseKeyWith))
break;
t = findNextElementChild(t);
}
// Append the element
if (t == NULL) {
mp_keyBindingAbstractTypeElement->appendChild(e);
mp_env->doPrettyPrint(mp_keyBindingAbstractTypeElement);
}
else {
mp_keyBindingAbstractTypeElement->insertBefore(e, t);
if (mp_env->getPrettyPrintFlag()) {
mp_keyBindingAbstractTypeElement->insertBefore(
mp_env->getParentDocument()->createTextNode(DSIGConstants::s_unicodeStrNL),
t);
}
}
return u;
}
#endif /* XSEC_XKMS_ENABLED */