| /** |
| * 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 |
| * |
| * XKMSReissueRequestImpl := Implementation for ReissueRequest Messages |
| * |
| * $Id: XKMSReissueRequestImpl.cpp 351366 2005-06-04 11:44:55Z blautenb $ |
| * |
| */ |
| |
| // XSEC Includes |
| |
| #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 "XKMSReissueRequestImpl.hpp" |
| #include "XKMSAuthenticationImpl.hpp" |
| #include "XKMSReissueKeyBindingImpl.hpp" |
| |
| #include <xsec/xkms/XKMSConstants.hpp> |
| |
| #include <xercesc/dom/DOM.hpp> |
| #include <xercesc/util/XMLUniDefs.hpp> |
| |
| XERCES_CPP_NAMESPACE_USE |
| |
| // -------------------------------------------------------------------------------- |
| // Construct/Destruct |
| // -------------------------------------------------------------------------------- |
| |
| XKMSReissueRequestImpl::XKMSReissueRequestImpl(const XSECEnv * env) : |
| m_request(env), |
| m_msg(m_request.m_msg), |
| mp_authentication(NULL), |
| mp_reissueKeyBinding(NULL), |
| mp_proofOfPossessionSignature(NULL) { |
| } |
| |
| XKMSReissueRequestImpl::XKMSReissueRequestImpl(const XSECEnv * env, DOMElement * node) : |
| m_request(env, node), |
| m_msg(m_request.m_msg), |
| mp_authentication(NULL), |
| mp_reissueKeyBinding(NULL), |
| mp_proofOfPossessionSignature(NULL) { |
| } |
| |
| XKMSReissueRequestImpl::~XKMSReissueRequestImpl() { |
| |
| if (mp_authentication != NULL) |
| delete mp_authentication; |
| if (mp_reissueKeyBinding != NULL) |
| delete mp_reissueKeyBinding; |
| // Provider will take care of the proofOfPossession signature |
| |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // Load |
| // -------------------------------------------------------------------------------- |
| |
| void XKMSReissueRequestImpl::load(void) { |
| |
| if (m_msg.mp_messageAbstractTypeElement == NULL) { |
| |
| // Attempt to load an empty element |
| throw XSECException(XSECException::XKMSError, |
| "XKMSReissueRequest::load - called on empty DOM"); |
| |
| } |
| |
| if (!strEquals(getXKMSLocalName(m_msg.mp_messageAbstractTypeElement), |
| XKMSConstants::s_tagReissueRequest)) { |
| |
| throw XSECException(XSECException::XKMSError, |
| "XKMSReissueRequest::load - called on incorrect node"); |
| |
| } |
| |
| // Load the base message |
| m_request.load(); |
| |
| // Now check for any ReissueKeyBinding elements |
| DOMElement * tmpElt = findFirstElementChild(m_msg.mp_messageAbstractTypeElement); |
| while (tmpElt != NULL && !strEquals(getXKMSLocalName(tmpElt), XKMSConstants::s_tagReissueKeyBinding)) { |
| tmpElt = findNextElementChild(tmpElt); |
| } |
| |
| if (tmpElt != NULL) { |
| |
| XSECnew(mp_reissueKeyBinding, XKMSReissueKeyBindingImpl(m_msg.mp_env, tmpElt)); |
| mp_reissueKeyBinding->load(); |
| |
| tmpElt = findNextElementChild(tmpElt); |
| |
| } |
| else { |
| |
| throw XSECException(XSECException::ExpectedXKMSChildNotFound, |
| "XKMSReissueRequest::load - Expected ReissueKeyBinding node"); |
| |
| } |
| |
| // Authentication Element |
| |
| if (tmpElt != NULL && strEquals(getXKMSLocalName(tmpElt), XKMSConstants::s_tagAuthentication)) { |
| |
| XSECnew(mp_authentication, XKMSAuthenticationImpl(m_msg.mp_env, tmpElt)); |
| mp_authentication->load(mp_reissueKeyBinding->getId()); |
| |
| tmpElt = findNextElementChild(tmpElt); |
| |
| } |
| else { |
| |
| throw XSECException(XSECException::ExpectedXKMSChildNotFound, |
| "XKMSReissueRequest::load - Expected Authentication node"); |
| |
| } |
| |
| if (tmpElt != NULL && strEquals(getXKMSLocalName(tmpElt), XKMSConstants::s_tagProofOfPossession)) { |
| |
| // Find the signature |
| |
| DOMElement * sigElt = (DOMElement *) findFirstElementChild(tmpElt); |
| |
| if (sigElt == NULL || !strEquals(getDSIGLocalName(sigElt), |
| XKMSConstants::s_tagSignature)) { |
| throw XSECException(XSECException::ExpectedXKMSChildNotFound, |
| "XKMSReissueRequest::load - Expected Signature child of ProofOfPossession"); |
| |
| } |
| |
| // The provider will take care of cleaning this up later. |
| |
| mp_proofOfPossessionSignature = m_prov.newSignatureFromDOM(m_msg.mp_env->getParentDocument(), |
| sigElt); |
| mp_proofOfPossessionSignature->load(); |
| |
| // Check the signature is across the correct input |
| |
| DSIGReferenceList * rl = |
| mp_proofOfPossessionSignature->getReferenceList(); |
| |
| if (rl->getSize() != 1) { |
| throw XSECException(XSECException::XKMSError, |
| "XKMSReissueRequestImpl::load - ProofOfPossession Signature with incorrect number of references found (should be 1)"); |
| } |
| |
| safeBuffer sb; |
| sb.sbXMLChIn(DSIGConstants::s_unicodeStrEmpty); |
| sb.sbXMLChAppendCh(chPound); |
| sb.sbXMLChCat(mp_reissueKeyBinding->getId()); |
| |
| if (!strEquals(rl->item(0)->getURI(), sb.rawXMLChBuffer())) { |
| throw XSECException(XSECException::XKMSError, |
| "XKMSReissueRequestImpl::load - ProofOfPossession Signature refers to incorrect Id (should be for ReissueKeyBinding)"); |
| } |
| |
| // We don't actually check the signature as we have no key material to do so! |
| } |
| } |
| |
| |
| // -------------------------------------------------------------------------------- |
| // Create |
| // -------------------------------------------------------------------------------- |
| |
| DOMElement * XKMSReissueRequestImpl:: |
| createBlankReissueRequest(const XMLCh * service, const XMLCh * id) { |
| |
| return m_request.createBlankRequestAbstractType( |
| XKMSConstants::s_tagReissueRequest, service, id); |
| |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // MessageType |
| // -------------------------------------------------------------------------------- |
| |
| XKMSMessageAbstractType::messageType XKMSReissueRequestImpl::getMessageType(void) { |
| |
| return XKMSMessageAbstractTypeImpl::ReissueRequest; |
| |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // Get Methods |
| // -------------------------------------------------------------------------------- |
| |
| XKMSReissueKeyBinding * XKMSReissueRequestImpl::getReissueKeyBinding(void) const { |
| |
| return mp_reissueKeyBinding; |
| |
| } |
| |
| XKMSAuthentication * XKMSReissueRequestImpl::getAuthentication (void) const { |
| |
| return mp_authentication; |
| |
| } |
| |
| DSIGSignature * XKMSReissueRequestImpl::getProofOfPossessionSignature(void) const { |
| |
| return mp_proofOfPossessionSignature; |
| |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // Set Methods |
| // -------------------------------------------------------------------------------- |
| |
| XKMSReissueKeyBinding * XKMSReissueRequestImpl::addReissueKeyBinding(XKMSStatus::StatusValue status) { |
| |
| if (mp_reissueKeyBinding != NULL) |
| return mp_reissueKeyBinding; |
| |
| |
| // OK - Nothing exists, so we need to create from scratch |
| |
| XSECnew(mp_reissueKeyBinding, XKMSReissueKeyBindingImpl(m_msg.mp_env)); |
| DOMElement * elt = mp_reissueKeyBinding->createBlankReissueKeyBinding(status); |
| |
| // Insert |
| |
| DOMElement * be = findFirstElementChild(m_msg.mp_messageAbstractTypeElement); |
| |
| while (be != NULL && |
| !strEquals(getXKMSLocalName(be), XKMSConstants::s_tagAuthentication) && |
| !strEquals(getXKMSLocalName(be), XKMSConstants::s_tagProofOfPossession)) { |
| be = findNextElementChild(be); |
| } |
| |
| if (be == NULL) { |
| m_msg.mp_env->doPrettyPrint(m_msg.mp_messageAbstractTypeElement); |
| m_msg.mp_messageAbstractTypeElement->appendChild(elt); |
| m_msg.mp_env->doPrettyPrint(m_msg.mp_messageAbstractTypeElement); |
| return mp_reissueKeyBinding; |
| } |
| |
| m_msg.mp_messageAbstractTypeElement->insertBefore(elt, be); |
| if (m_msg.mp_env->getPrettyPrintFlag() == true) { |
| m_msg.mp_messageAbstractTypeElement->insertBefore( |
| m_msg.mp_env->getParentDocument()->createTextNode(DSIGConstants::s_unicodeStrNL), |
| be); |
| } |
| |
| return mp_reissueKeyBinding; |
| |
| } |
| |
| XKMSAuthentication * XKMSReissueRequestImpl::addAuthentication(void) { |
| |
| if (mp_authentication != NULL) |
| return mp_authentication; |
| |
| if (mp_reissueKeyBinding == NULL) { |
| throw XSECException(XSECException::XKMSError, |
| "XKMSReissueRequestImpl::addAuthentication - called prior to key infos being added"); |
| } |
| |
| XSECnew(mp_authentication, XKMSAuthenticationImpl(m_msg.mp_env)); |
| DOMElement * e = |
| mp_authentication->createBlankAuthentication(mp_reissueKeyBinding->getId()); |
| |
| DOMElement * be = findFirstElementChild(m_msg.mp_messageAbstractTypeElement); |
| |
| while (be != NULL && !strEquals(getXKMSLocalName(be), XKMSConstants::s_tagProofOfPossession)) |
| be = findNextElementChild(be); |
| |
| if (be == NULL) { |
| m_msg.mp_env->doPrettyPrint(m_msg.mp_messageAbstractTypeElement); |
| m_msg.mp_messageAbstractTypeElement->appendChild(e); |
| m_msg.mp_env->doPrettyPrint(m_msg.mp_messageAbstractTypeElement); |
| return mp_authentication; |
| } |
| |
| m_msg.mp_messageAbstractTypeElement->insertBefore(e, be); |
| if (m_msg.mp_env->getPrettyPrintFlag() == true) { |
| m_msg.mp_messageAbstractTypeElement->insertBefore( |
| m_msg.mp_env->getParentDocument()->createTextNode(DSIGConstants::s_unicodeStrNL), |
| be); |
| } |
| |
| return mp_authentication; |
| |
| } |
| |
| DSIGSignature * XKMSReissueRequestImpl::addProofOfPossessionSignature( |
| const XMLCh* c14nAlgorithm, |
| const XMLCh* signatureAlgorithm, |
| const XMLCh* hashAlgorithm) { |
| |
| DSIGSignature * ret = m_prov.newSignature(); |
| DOMElement * elt = ret->createBlankSignature(m_msg.mp_env->getParentDocument(), c14nAlgorithm, signatureAlgorithm); |
| |
| /* Create the enveloping reference */ |
| safeBuffer sb; |
| sb.sbXMLChIn(DSIGConstants::s_unicodeStrEmpty); |
| sb.sbXMLChAppendCh(chPound); |
| sb.sbXMLChCat(mp_reissueKeyBinding->getId()); |
| |
| 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 = m_msg.mp_env->getParentDocument(); |
| const XMLCh * prefix = m_msg.mp_env->getXKMSNSPrefix(); |
| |
| makeQName(str, prefix, XKMSConstants::s_tagProofOfPossession); |
| |
| DOMElement * t = doc->createElementNS(XKMSConstants::s_unicodeStrURIXKMS, |
| str.rawXMLChBuffer()); |
| |
| m_msg.mp_env->doPrettyPrint(t); |
| t->appendChild(elt); |
| m_msg.mp_env->doPrettyPrint(t); |
| |
| // Now append into the ReissueRequest |
| m_msg.mp_messageAbstractTypeElement->appendChild(t); |
| m_msg.mp_env->doPrettyPrint(m_msg.mp_messageAbstractTypeElement); |
| |
| return ret; |
| } |
| |
| #endif /* XSEC_XKMS_ENABLED */ |