xsec/xkms/impl/XKMSAuthenticationImpl.cpp (131 lines of code) (raw):

/** * 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 */