blob: 1da4b6eb365306c64073806debcc6c8838e085dd [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
*
* XKMSAuthenticationImpl := Implementation of Authentication elements
*
* $Id$
*
*/
#include <xsec/dsig/DSIGReference.hpp>
#include <xsec/framework/XSECDefs.hpp>
#include <xsec/framework/XSECEnv.hpp>
#include <xsec/framework/XSECError.hpp>
#ifdef XSEC_XKMS_ENABLED
#include "../../utils/XSECDOMUtils.hpp"
#include "XKMSAuthenticationImpl.hpp"
#include "XKMSNotBoundAuthenticationImpl.hpp"
#include <xsec/xkms/XKMSConstants.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
XERCES_CPP_NAMESPACE_USE
// --------------------------------------------------------------------------------
// Constructor/Destructor
// --------------------------------------------------------------------------------
XKMSAuthenticationImpl::XKMSAuthenticationImpl(const XSECEnv * env) :
mp_env(env),
mp_authenticationElement(NULL),
mp_keyBindingAuthenticationSignatureElement(NULL),
mp_keyBindingAuthenticationSignature(NULL),
mp_notBoundAuthentication(NULL)
{
}
XKMSAuthenticationImpl::XKMSAuthenticationImpl(const XSECEnv * env, DOMElement * node) :
mp_env(env),
mp_authenticationElement(node),
mp_keyBindingAuthenticationSignatureElement(NULL),
mp_keyBindingAuthenticationSignature(NULL),
mp_notBoundAuthentication(NULL)
{
}
XKMSAuthenticationImpl::~XKMSAuthenticationImpl() {
if (mp_notBoundAuthentication != NULL)
delete mp_notBoundAuthentication;
}
// --------------------------------------------------------------------------------
// Load
// --------------------------------------------------------------------------------
void XKMSAuthenticationImpl::load(const XMLCh * id) {
if (mp_authenticationElement == NULL) {
throw XSECException(XSECException::ExpectedXKMSChildNotFound,
"XKMSAuthenticationImpl::load - called on empty DOM");
}
// Store for later use
mp_keyBindingId = id;
DOMElement * tmpElt = findFirstElementChild(mp_authenticationElement);
if (tmpElt != NULL && strEquals(getXKMSLocalName(tmpElt),
XKMSConstants::s_tagKeyBindingAuthentication)) {
// Find the signature
mp_keyBindingAuthenticationSignatureElement =
(DOMElement *) findFirstElementChild(tmpElt);
while (mp_keyBindingAuthenticationSignatureElement != NULL &&
!strEquals(getDSIGLocalName(mp_keyBindingAuthenticationSignatureElement),
XKMSConstants::s_tagSignature)) {
mp_keyBindingAuthenticationSignatureElement=
findNextElementChild(mp_keyBindingAuthenticationSignatureElement);
}
// The provider will take care of cleaning this up later.
if (mp_keyBindingAuthenticationSignatureElement != NULL) {
mp_keyBindingAuthenticationSignature = m_prov.newSignatureFromDOM(
mp_keyBindingAuthenticationSignatureElement->getOwnerDocument(),
mp_keyBindingAuthenticationSignatureElement);
mp_keyBindingAuthenticationSignature->load();
// Check the signature is across the correct input
DSIGReferenceList * rl =
mp_keyBindingAuthenticationSignature->getReferenceList();
if (rl->getSize() != 1) {
throw XSECException(XSECException::XKMSError,
"XKMSAuthenticationImpl::load - KeyBindingAuthentication Signature with incorrect number of references found (should be 1)");
}
safeBuffer sb;
sb.sbXMLChIn(DSIGConstants::s_unicodeStrEmpty);
sb.sbXMLChAppendCh(chPound);
sb.sbXMLChCat(mp_keyBindingId);
if (!strEquals(rl->item(0)->getURI(), sb.rawXMLChBuffer())) {
throw XSECException(XSECException::XKMSError,
"XKMSAuthenticationImpl::load - KeyBindingAuthentication Signature refers to incorrect Id (should be for KeyBinding)");
}
// We don't actually check the signature as we have no key material to do so!
}
tmpElt = findNextElementChild(tmpElt);
}
if (tmpElt != NULL && strEquals(getXKMSLocalName(tmpElt),
XKMSConstants::s_tagNotBoundAuthentication)) {
XSECnew(mp_notBoundAuthentication, XKMSNotBoundAuthenticationImpl(mp_env, tmpElt));
mp_notBoundAuthentication->load();
}
}
// --------------------------------------------------------------------------------
// Create
// --------------------------------------------------------------------------------
DOMElement * XKMSAuthenticationImpl::createBlankAuthentication(const XMLCh * id) {
// Get some setup values
safeBuffer str;
DOMDocument *doc = mp_env->getParentDocument();
const XMLCh * prefix = mp_env->getXKMSNSPrefix();
makeQName(str, prefix, XKMSConstants::s_tagAuthentication);
mp_authenticationElement = doc->createElementNS(XKMSConstants::s_unicodeStrURIXKMS,
str.rawXMLChBuffer());
mp_env->doPrettyPrint(mp_authenticationElement);
// This isn't used immediately - it is simply held for when we create a signature
mp_keyBindingId = id;
return mp_authenticationElement;
}
// --------------------------------------------------------------------------------
// Interfacet - Get
// --------------------------------------------------------------------------------
DSIGSignature * XKMSAuthenticationImpl::getKeyBindingAuthenticationSignature(void) const {
return mp_keyBindingAuthenticationSignature;
}
XKMSNotBoundAuthentication * XKMSAuthenticationImpl::getNotBoundAuthentication(void) const {
return mp_notBoundAuthentication;
}
// --------------------------------------------------------------------------------
// Interface - Set
// --------------------------------------------------------------------------------
DSIGSignature * XKMSAuthenticationImpl::addKeyBindingAuthenticationSignature(
const XMLCh* c14nAlgorithm,
const XMLCh* signatureAlgorithm,
const XMLCh* hashAlgorithm) {
if (mp_keyBindingId == NULL) {
throw XSECException(XSECException::XKMSError,
"XKMSAuthenticationImpl::addKeyBindingAuthenticationSignature - called prior to key infos being added");
}
DSIGSignature * ret = m_prov.newSignature();
DOMElement * elt = ret->createBlankSignature(mp_env->getParentDocument(), c14nAlgorithm, signatureAlgorithm);
/* Create the enveloping reference */
safeBuffer sb;
sb.sbXMLChIn(DSIGConstants::s_unicodeStrEmpty);
sb.sbXMLChAppendCh(chPound);
sb.sbXMLChCat(mp_keyBindingId);
DSIGReference *ref = ret->createReference(sb.rawXMLChBuffer(), hashAlgorithm);
ref->appendCanonicalizationTransform(DSIGConstants::s_unicodeStrURIEXC_C14N_COM);
/* Embed the signature in the document inside a KeyBindingAuthentication element */
safeBuffer str;
DOMDocument *doc = mp_env->getParentDocument();
const XMLCh * prefix = mp_env->getXKMSNSPrefix();
makeQName(str, prefix, XKMSConstants::s_tagKeyBindingAuthentication);
DOMElement * t = doc->createElementNS(XKMSConstants::s_unicodeStrURIXKMS,
str.rawXMLChBuffer());
mp_env->doPrettyPrint(t);
t->appendChild(elt);
mp_env->doPrettyPrint(t);
mp_authenticationElement->appendChild(t);
mp_env->doPrettyPrint(mp_authenticationElement);
return ret;
}
void XKMSAuthenticationImpl::setNotBoundAuthentication(
const XMLCh * uri,
const XMLCh * value) {
XSECnew(mp_notBoundAuthentication, XKMSNotBoundAuthenticationImpl(mp_env));
mp_authenticationElement->appendChild(mp_notBoundAuthentication->createBlankNotBoundAuthentication(uri, value));
mp_env->doPrettyPrint(mp_authenticationElement);
}
#endif /* XSEC_XKMS_ENABLED */