/**
 * 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
 *
 * DSIGKeyX509 := A "Super" key that defines a certificate with a sub-key that defines
 *                the signing key
 *
 * $Id$
 *
 */

#include <xsec/dsig/DSIGKeyInfoX509.hpp>
#include <xsec/dsig/DSIGSignature.hpp>
#include <xsec/framework/XSECEnv.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/utils/XSECPlatformUtils.hpp>

#include "../utils/XSECAutoPtr.hpp"
#include "../utils/XSECDOMUtils.hpp"

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//           Constructors and Destructors
// --------------------------------------------------------------------------------


DSIGKeyInfoX509::DSIGKeyInfoX509(const XSECEnv * env, DOMNode *X509Data) :
DSIGKeyInfo(env),
mp_X509IssuerName(NULL),
mp_X509SerialNumber(NULL),
mp_X509SubjectName(NULL),
mp_X509SKI(NULL),
mp_rawRetrievalURI(NULL),
mp_X509SubjectNameTextNode(0),
mp_X509IssuerNameTextNode(0),
mp_X509SerialNumberTextNode(0),
mp_X509SKITextNode(0),
mp_X509DigestTextNode(0) {

	mp_keyInfoDOMNode = X509Data;
	m_X509List.clear();
	m_X509CRLList.clear();
}

DSIGKeyInfoX509::DSIGKeyInfoX509(const XSECEnv * env) :
DSIGKeyInfo(env),
mp_X509IssuerName(NULL),
mp_X509SerialNumber(NULL),
mp_X509SubjectName(NULL),
mp_X509SKI(NULL),
mp_rawRetrievalURI(NULL),
mp_X509SubjectNameTextNode(0),
mp_X509IssuerNameTextNode(0),
mp_X509SerialNumberTextNode(0),
mp_X509SKITextNode(0),
mp_X509DigestTextNode(0){

	mp_keyInfoDOMNode = 0;
	m_X509List.clear();
    m_X509CRLList.clear();
}


DSIGKeyInfoX509::~DSIGKeyInfoX509() {

	// SubjectName and IssuerName are local (decoded) copies of the
	// encoded DName held in the DOM

	if (mp_X509IssuerName != NULL)
		XSEC_RELEASE_XMLCH(mp_X509IssuerName);

	if (mp_X509SubjectName != NULL)
		XSEC_RELEASE_XMLCH(mp_X509SubjectName);

	X509ListType::iterator i;

	for (i = m_X509List.begin(); i != m_X509List.end(); ++i) {

		if ((*i)->mp_cryptoX509 != NULL)
			delete ((*i)->mp_cryptoX509);
		delete (*i);

	}

	m_X509List.clear();
    m_X509CRLList.clear();

	if (mp_rawRetrievalURI != NULL)
		XSEC_RELEASE_XMLCH(mp_rawRetrievalURI);

	
};

// --------------------------------------------------------------------------------
//           Load and Get
// --------------------------------------------------------------------------------


// Methods unique to DSIGKeyInfoX509

void DSIGKeyInfoX509::load(void) {

	// Assuming we have a valid DOM_Node to start with, load the signing key so that it can
	// be used later on

	if (mp_keyInfoDOMNode == NULL) {

		// Attempt to load an empty signature element
		throw XSECException(XSECException::LoadEmptyX509);

	}

	if (!strEquals(getDSIGLocalName(mp_keyInfoDOMNode), "X509Data")) {

		throw XSECException(XSECException::LoadNonX509);

	}

	// Now check for an X509 Data Element we understand

	DOMNode *tmpElt = mp_keyInfoDOMNode->getFirstChild();
	DOMNode *child;	// Worker

	while (tmpElt != 0) {

		if (tmpElt->getNodeType() == DOMNode::ELEMENT_NODE) {

			// See if it's a known element type
			if (strEquals(getDSIGLocalName(tmpElt), "X509Certificate")) {

			    // Loop over Text nodes until we successfully load a certificate.
			    // If we run out, throw out the last exception raised.

				X509Holder * h;
                XSECCryptoX509* cryptoX509 = XSECPlatformUtils::g_cryptoProvider->X509();
				DOMNode *certElt = findFirstChildOfType(tmpElt, DOMNode::TEXT_NODE);
				while (certElt) {
                    XSECAutoPtrChar charX509(certElt->getNodeValue());
				    try {
                        cryptoX509->loadX509Base64Bin(charX509.get(), (int) strlen(charX509.get()));

	                    // Add to the list
                        XSECnew(h, X509Holder);
	                    m_X509List.push_back(h);
	                    h->mp_encodedX509 = certElt->getNodeValue();
	                    h->mp_cryptoX509 = cryptoX509;
	                    break;
				    }
			catch (const XSECCryptoException&) {
	                    certElt = findNextChildOfType(certElt, DOMNode::TEXT_NODE);
	                    if (!certElt) {
	                        delete cryptoX509;
	                        throw;
	                    }
				    }
				}
			}

			else if (strEquals(getDSIGLocalName(tmpElt), "X509SubjectName")) {

				child = findFirstChildOfType(tmpElt, DOMNode::TEXT_NODE);

				if (child == NULL) {

					throw XSECException(XSECException::ExpectedDSIGChildNotFound,
						"Expected TEXT_NODE child of <X509SubjectName>");

				}

				mp_X509SubjectName = decodeDName(child->getNodeValue());

			}

			else if (strEquals(getDSIGLocalName(tmpElt), "X509IssuerSerial")) {

				child = tmpElt->getFirstChild();
				while (child != 0 && child->getNodeType() != DOMNode::ELEMENT_NODE &&
					!strEquals(getDSIGLocalName(child), "X509IssuerName"))
					child = child->getNextSibling();

				if (child == NULL) {

					throw XSECException(XSECException::ExpectedDSIGChildNotFound,
						"Expected <X509IssuerName> child of <X509IssuerSerial>");

				}

				child = child->getFirstChild();
				while (child != 0 && child->getNodeType() != DOMNode::TEXT_NODE)
					child = child->getNextSibling();

				if (child == NULL) {

					throw XSECException(XSECException::ExpectedDSIGChildNotFound,
						"Expected TEXT_NODE child of <X509IssuerSerial>");

				}

				mp_X509IssuerName = decodeDName(child->getNodeValue());

				// Now find the serial number
				child = tmpElt->getFirstChild();
				while (child != 0 && (child->getNodeType() != DOMNode::ELEMENT_NODE ||
					!strEquals(getDSIGLocalName(child), "X509SerialNumber")))
					child = child->getNextSibling();

				if (child == NULL) {

					throw XSECException(XSECException::ExpectedDSIGChildNotFound,
						"Expected <X509SerialNumber> child of <X509IssuerSerial>");

				}

				child = child->getFirstChild();
				while (child != 0 && child->getNodeType() != DOMNode::TEXT_NODE)
					child = child->getNextSibling();

				if (child == NULL) {

					throw XSECException(XSECException::ExpectedDSIGChildNotFound,
						"Expected TEXT_NODE child of <X509IssuerSerial>");

				}

				mp_X509SerialNumber = child->getNodeValue();

			}

			else if (strEquals(getDSIGLocalName(tmpElt), "X509CRL")) {

                DOMNode *crlElt = findFirstChildOfType(tmpElt, DOMNode::TEXT_NODE);

                if (crlElt != 0) {

                    // Add to the list
                    m_X509CRLList.push_back(crlElt->getNodeValue());

                }

			}
			else if (strEquals(getDSIGLocalName(tmpElt), "X509SKI")) {

				child = findFirstChildOfType(tmpElt, DOMNode::TEXT_NODE);

				if (child == NULL) {

					throw XSECException(XSECException::ExpectedDSIGChildNotFound,
						"Expected TEXT_NODE child of <X509SKI>");

				}

				mp_X509SKITextNode = child;
				mp_X509SKI = child->getNodeValue();

			}
            else if (strEquals(getDSIG11LocalName(tmpElt), "X509Digest")) {

                child = findFirstChildOfType(tmpElt, DOMNode::TEXT_NODE);

                if (child == NULL) {

                    throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                        "Expected TEXT_NODE child of <X509Digest>");

                }

                mp_X509DigestTextNode = child;

            }
		}

		// Go to next data element to load if we understand

		tmpElt = tmpElt->getNextSibling();

	}

}

const XMLCh * DSIGKeyInfoX509::getKeyName(void) const {

	return mp_X509SubjectName;

	// Should return DN

}

const XMLCh * DSIGKeyInfoX509::getX509SubjectName(void) const {


	return mp_X509SubjectName;

}

const XMLCh * DSIGKeyInfoX509::getX509DigestAlgorithm(void) const {

    return mp_X509DigestTextNode ?
        static_cast<DOMElement*>(mp_X509DigestTextNode->getParentNode())->getAttributeNS(NULL, DSIGConstants::s_unicodeStrAlgorithm) :
            NULL;

}

const XMLCh * DSIGKeyInfoX509::getX509DigestValue(void) const {

    return mp_X509DigestTextNode ? mp_X509DigestTextNode->getNodeValue() : NULL;

}

const XMLCh * DSIGKeyInfoX509::getX509IssuerName(void) const {

	return mp_X509IssuerName;

}

const XMLCh * DSIGKeyInfoX509::getX509IssuerSerialNumber(void) const {

    return mp_X509SerialNumber;

}

const XMLCh * DSIGKeyInfoX509::getX509CRL(void) const {

	return m_X509CRLList.empty() ? NULL : m_X509CRLList.front();

}

int DSIGKeyInfoX509::getX509CRLListSize(void) const {

    return (int) m_X509CRLList.size();

}


const XMLCh * DSIGKeyInfoX509::getX509CRLItem(int item) const {

    if (item >=0 && (unsigned int) item < m_X509CRLList.size())
        return m_X509CRLList[item];

    return 0;

}

const XMLCh * DSIGKeyInfoX509::getX509SKI(void) const {

	return mp_X509SKI;

}

int DSIGKeyInfoX509::getCertificateListSize(void) const {

	return (int) m_X509List.size();

}

const XMLCh * DSIGKeyInfoX509::getCertificateItem(int item) const {

	if (item >=0 && (unsigned int) item < m_X509List.size())
		return m_X509List[item]->mp_encodedX509;

	return 0;

}

XSECCryptoX509 * DSIGKeyInfoX509::getCertificateCryptoItem(int item) {

    if (item >=0 && (unsigned int) item < m_X509List.size())
        return m_X509List[item]->mp_cryptoX509;

    return 0;
}

const XSECCryptoX509 * DSIGKeyInfoX509::getCertificateCryptoItem(int item) const {

	if (item >=0 && (unsigned int) item < m_X509List.size())
		return m_X509List[item]->mp_cryptoX509;

	return 0;
}

const XMLCh * DSIGKeyInfoX509::getRawRetrievalURI(void) const {

	return mp_rawRetrievalURI;

}

// --------------------------------------------------------------------------------
//           Create and Set
// --------------------------------------------------------------------------------

DOMElement * DSIGKeyInfoX509::createBlankX509Data(void) {

	// Create the DOM Structure

	safeBuffer str;
	DOMDocument *doc = mp_env->getParentDocument();
	const XMLCh * prefix = mp_env->getDSIGNSPrefix();

	makeQName(str, prefix, "X509Data");

	DOMElement *ret = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
	mp_keyInfoDOMNode = ret;
	mp_env->doPrettyPrint(ret);

	return ret;

}

void DSIGKeyInfoX509::setX509CRL(const XMLCh * crl) {
    appendX509CRL(crl);
}

void DSIGKeyInfoX509::appendX509CRL(const XMLCh * crl) {

    safeBuffer str;
    DOMDocument *doc = mp_env->getParentDocument();
    const XMLCh * prefix = mp_env->getDSIGNSPrefix();

    makeQName(str, prefix, "X509CRL");

    DOMElement * s = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
    DOMNode * b64Txt = doc->createTextNode(crl);
    s->appendChild(b64Txt);

    mp_keyInfoDOMNode->appendChild(s);
    mp_env->doPrettyPrint(mp_keyInfoDOMNode);

    // Add to the list

    m_X509CRLList.push_back(b64Txt->getNodeValue());
}

void DSIGKeyInfoX509::setX509SKI(const XMLCh * ski) {

	if (mp_X509SKITextNode == 0) {

		safeBuffer str;
		DOMDocument *doc = mp_env->getParentDocument();
		const XMLCh * prefix = mp_env->getDSIGNSPrefix();

		makeQName(str, prefix, "X509SKI");

		DOMElement * s = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
		mp_X509SKITextNode = doc->createTextNode(ski);
		s->appendChild(mp_X509SKITextNode);

		// Add to the over-arching node
		mp_keyInfoDOMNode->appendChild(s);
		mp_env->doPrettyPrint(mp_keyInfoDOMNode);

	}

	else {

		mp_X509SKITextNode->setNodeValue(ski);

	}

	mp_X509SKI = mp_X509SKITextNode->getNodeValue();

}

void DSIGKeyInfoX509::setX509SubjectName(const XMLCh * name) {

	if (mp_X509SubjectName != NULL)
		XSEC_RELEASE_XMLCH(mp_X509SubjectName);

	mp_X509SubjectName = XMLString::replicate(name);
	
	XMLCh * encodedName = encodeDName(name);

	if (mp_X509SubjectNameTextNode == 0) {

		// Does not yet exist in the DOM

		safeBuffer str;
		DOMDocument *doc = mp_env->getParentDocument();
		const XMLCh * prefix = mp_env->getDSIGNSPrefix();

		makeQName(str, prefix, "X509SubjectName");

		DOMElement * s = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
		mp_X509SubjectNameTextNode = doc->createTextNode(encodedName);
		s->appendChild(mp_X509SubjectNameTextNode);

		// Add to the over-arching node
		mp_keyInfoDOMNode->appendChild(s);
		mp_env->doPrettyPrint(mp_keyInfoDOMNode);

	}

	else {

		mp_X509SubjectNameTextNode->setNodeValue(encodedName);

	}
	XSEC_RELEASE_XMLCH(encodedName);
}

void DSIGKeyInfoX509::setX509IssuerSerial(const XMLCh * name, const XMLCh * serial) {

	if (mp_X509IssuerName != NULL)
		XSEC_RELEASE_XMLCH(mp_X509IssuerName);

	mp_X509IssuerName = XMLString::replicate(name);
	
	XMLCh * encodedName = encodeDName(name);

	if (mp_X509IssuerNameTextNode == 0) {

		// Does not yet exist in the DOM

		safeBuffer str;
		DOMDocument *doc = mp_env->getParentDocument();
		const XMLCh * prefix = mp_env->getDSIGNSPrefix();

		makeQName(str, prefix, "X509IssuerSerial");

		DOMElement * s = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
		mp_env->doPrettyPrint(s);

		// Create the text nodes with the contents

		mp_X509IssuerNameTextNode = doc->createTextNode(encodedName);
		mp_X509SerialNumberTextNode = doc->createTextNode(serial);
	
		// Create the sub elements

		makeQName(str, prefix, "X509IssuerName");
		DOMElement * t = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
		t->appendChild(mp_X509IssuerNameTextNode);
		
		s->appendChild(t);
		mp_env->doPrettyPrint(s);
		
		makeQName(str, prefix, "X509SerialNumber");
		t = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
		t->appendChild(mp_X509SerialNumberTextNode);
		
		s->appendChild(t);
		mp_env->doPrettyPrint(s);

		// Add to the over-arching X509Data

		mp_keyInfoDOMNode->appendChild(s);
		mp_env->doPrettyPrint(mp_keyInfoDOMNode);

	}

	else {

		mp_X509IssuerNameTextNode->setNodeValue(encodedName);
		mp_X509SerialNumberTextNode->setNodeValue(serial);

	}

	XSEC_RELEASE_XMLCH(encodedName);
}

void DSIGKeyInfoX509::setX509Digest(const XMLCh * algorithm, const XMLCh * value) {

    if (mp_X509DigestTextNode == 0) {

        // Does not yet exist in the DOM

        safeBuffer str;
        DOMDocument *doc = mp_env->getParentDocument();
        const XMLCh * prefix = mp_env->getDSIG11NSPrefix();

        makeQName(str, prefix, "X509Digest");

        DOMElement * s = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG11, str.rawXMLChBuffer());
        s->setAttributeNS(NULL, DSIGConstants::s_unicodeStrAlgorithm, algorithm);

        // Create the text node with the contents

        mp_X509DigestTextNode = doc->createTextNode(value);
        s->appendChild(mp_X509DigestTextNode);

        mp_env->doPrettyPrint(s);

        // Add to the over-arching X509Data

        mp_keyInfoDOMNode->appendChild(s);
        mp_env->doPrettyPrint(mp_keyInfoDOMNode);

    }

    else {

        mp_X509DigestTextNode->setNodeValue(value);
        static_cast<DOMElement*>(mp_X509DigestTextNode->getParentNode())->setAttributeNS(NULL, DSIGConstants::s_unicodeStrAlgorithm, algorithm);

    }

}

void DSIGKeyInfoX509::setRawRetrievalURI(const XMLCh * uri) {

	if (mp_rawRetrievalURI != NULL)
		XSEC_RELEASE_XMLCH(mp_rawRetrievalURI);

	mp_rawRetrievalURI = XMLString::replicate(uri);

}

void DSIGKeyInfoX509::appendX509Certificate(const XMLCh * base64Certificate) {

	safeBuffer str;
	DOMDocument *doc = mp_env->getParentDocument();
	const XMLCh * prefix = mp_env->getDSIGNSPrefix();

	makeQName(str, prefix, "X509Certificate");

	DOMElement * s = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
	DOMNode * b64Txt = doc->createTextNode(base64Certificate);
	s->appendChild(b64Txt);

	mp_keyInfoDOMNode->appendChild(s);
	mp_env->doPrettyPrint(mp_keyInfoDOMNode);

	// Add to the list

	X509Holder * h;
	XSECnew(h, X509Holder);
	m_X509List.push_back(h);
	h->mp_encodedX509 = b64Txt->getNodeValue();
	h->mp_cryptoX509 = XSECPlatformUtils::g_cryptoProvider->X509();
	XSECAutoPtrChar charX509(h->mp_encodedX509);
	h->mp_cryptoX509->loadX509Base64Bin(charX509.get(), (unsigned int) strlen(charX509.get()));
	
}
