/**
 * 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
 *
 * xklient := Act as a client for an XKMS service
 *
 * $Id$
 *
 */

// XSEC

#include <xsec/utils/XSECPlatformUtils.hpp>
#include <xsec/framework/XSECProvider.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/canon/XSECC14n20010315.hpp>
#include <xsec/dsig/DSIGSignature.hpp>
#include <xsec/dsig/DSIGKeyInfoX509.hpp>
#include <xsec/dsig/DSIGKeyInfoValue.hpp>
#include <xsec/dsig/DSIGKeyInfoName.hpp>
#include <xsec/framework/XSECException.hpp>
#include <xsec/enc/XSECCryptoException.hpp>
#include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>
#include <xsec/enc/XSECCryptoUtils.hpp>
#include <xsec/enc/XSECKeyInfoResolverDefault.hpp>

#include <xsec/xkms/XKMSCompoundRequest.hpp>
#include <xsec/xkms/XKMSCompoundResult.hpp>
#include <xsec/xkms/XKMSPendingRequest.hpp>
#include <xsec/xkms/XKMSMessageAbstractType.hpp>
#include <xsec/xkms/XKMSLocateRequest.hpp>
#include <xsec/xkms/XKMSLocateResult.hpp>
#include <xsec/xkms/XKMSStatusRequest.hpp>
#include <xsec/xkms/XKMSStatusResult.hpp>
#include <xsec/xkms/XKMSResult.hpp>
#include <xsec/xkms/XKMSQueryKeyBinding.hpp>
#include <xsec/xkms/XKMSKeyBinding.hpp>
#include <xsec/xkms/XKMSUseKeyWith.hpp>
#include <xsec/xkms/XKMSConstants.hpp>
#include <xsec/xkms/XKMSValidateRequest.hpp>
#include <xsec/xkms/XKMSValidateResult.hpp>
#include <xsec/xkms/XKMSRegisterRequest.hpp>
#include <xsec/xkms/XKMSRegisterResult.hpp>
#include <xsec/xkms/XKMSAuthentication.hpp>
#include <xsec/xkms/XKMSPrototypeKeyBinding.hpp>
#include <xsec/xkms/XKMSRevokeRequest.hpp>
#include <xsec/xkms/XKMSRevokeResult.hpp>
#include <xsec/xkms/XKMSRecoverRequest.hpp>
#include <xsec/xkms/XKMSRecoverResult.hpp>
#include <xsec/xkms/XKMSReissueRequest.hpp>
#include <xsec/xkms/XKMSReissueResult.hpp>
#include <xsec/xkms/XKMSRevokeKeyBinding.hpp>
#include <xsec/xkms/XKMSRecoverKeyBinding.hpp>
#include <xsec/xkms/XKMSReissueKeyBinding.hpp>
#include <xsec/xkms/XKMSRSAKeyPair.hpp>

#include <xsec/utils/XSECSOAPRequestorSimple.hpp>

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

// General

#include <memory.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>

#if !defined(_WIN32)
#   include <sys/time.h>
#   include <time.h>
#endif

#if defined (_DEBUG) && defined (_MSC_VER)
#include <crtdbg.h>
#endif


#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>

#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/StdOutFormatTarget.hpp>
#include <xercesc/util/XMLException.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include <xercesc/util/XMLUri.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/sax/ErrorHandler.hpp>
#include <xercesc/sax/SAXParseException.hpp>
#include <xercesc/sax/EntityResolver.hpp>
#include <xercesc/sax/InputSource.hpp>

XERCES_CPP_NAMESPACE_USE

using std::cerr;
using std::cout;
using std::endl;
using std::ostream;

#ifdef XSEC_HAVE_XALAN

// XALAN

#include <xalanc/XPath/XPathEvaluator.hpp>
#include <xalanc/XalanTransformer/XalanTransformer.hpp>

// If this isn't defined, we're on Xalan 1.12+ and require modern C++
#ifndef XALAN_USING_XALAN
# define XALAN_USING_XALAN(NAME) using xalanc :: NAME;
#endif

XALAN_USING_XALAN(XPathEvaluator)
XALAN_USING_XALAN(XalanTransformer)

#endif

#if defined (XSEC_HAVE_OPENSSL)
// OpenSSL

#   include <openssl/err.h>
#   include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>
#   include <xsec/enc/OpenSSL/OpenSSLCryptoBase64.hpp>
#   include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
#   include <xsec/enc/OpenSSL/OpenSSLCryptoKeyHMAC.hpp>
#   include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
#   include <xsec/enc/OpenSSL/OpenSSLSupport.hpp>

#   include <openssl/bio.h>
#   include <openssl/dsa.h>
#   include <openssl/err.h>
#   include <openssl/evp.h>
#   include <openssl/pem.h>

#endif

// --------------------------------------------------------------------------------
//           Global definitions
// --------------------------------------------------------------------------------

bool g_txtOut = false;
char * g_authPassPhrase = NULL;
char * g_privateKeyFile = NULL;
char * g_privateKeyPassPhrase = NULL;

int doParsedMsgDump(DOMDocument * doc);

// --------------------------------------------------------------------------------
//           General functions
// --------------------------------------------------------------------------------


#ifndef XSEC_HAVE_XALAN

ostream& operator<< (ostream& target, const XMLCh * s)
{
    char *p = XMLString::transcode(s);
    target << p;
    XSEC_RELEASE_XMLCH(p);
    return target;
}

#endif

class X2C {

public:

    X2C(const XMLCh * in) {
        mp_cStr = XMLString::transcode(in);
    }
    ~X2C() {
        XSEC_RELEASE_XMLCH(mp_cStr);
    }

    char * str(void) {
        return mp_cStr;
    }

private :

    char * mp_cStr;

};

ostream & operator<<(ostream& target, X2C &x) {
    target << x.str();
    return target;
}

inline
void levelSet(unsigned int level) {

    for (unsigned int i = 0; i < level; ++i)
        cout << "    ";

}

void outputDoc(DOMDocument * doc) {

    XMLCh tempStr[100];
    XMLString::transcode("Core", tempStr, 99);    
    DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tempStr);
    XMLFormatTarget *formatTarget = new StdOutFormatTarget();

    cerr << endl;

    DOMLSSerializer   *theSerializer = ((DOMImplementationLS*)impl)->createLSSerializer();

    // Get the config so we can set up pretty printing
    DOMConfiguration *dc = theSerializer->getDomConfig();
    dc->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, false);

    // Now create an output object to format to UTF-8
    DOMLSOutput *theOutput = ((DOMImplementationLS*)impl)->createLSOutput();
    Janitor<DOMLSOutput> j_theOutput(theOutput);

    theOutput->setEncoding(MAKE_UNICODE_STRING("UTF-8"));
    theOutput->setByteStream(formatTarget);

    theSerializer->write(doc, theOutput);

    cout << endl;

    cerr << endl;

    delete theSerializer;
    delete formatTarget;

}

XSECCryptoX509 * loadX509(const char * infile) {

    FILE * f = fopen(infile, "r");
    if (f == NULL)
        return NULL;

    safeBuffer sb;
    char buf[1024];

    int i = (int) fread(buf, 1, 1024, f);
    int j = 0;
    while (i != 0) {
        sb.sbMemcpyIn(j, buf, i);
        j += i;
        i = (int) fread(buf, 1, 1024, f);
    }

    fclose(f);

    sb[j] = '\0';

    XSECCryptoX509 * ret = 
        XSECPlatformUtils::g_cryptoProvider->X509();

    ret->loadX509PEM(sb.rawCharBuffer());

    return ret;

}

#if defined (XSEC_HAVE_OPENSSL)

XMLCh * BN2b64(const BIGNUM * bn) {

    int bytes = BN_num_bytes(bn);
    unsigned char * binbuf = new unsigned char[bytes + 1];
    ArrayJanitor<unsigned char> j_binbuf(binbuf);

    bytes = BN_bn2bin(bn, binbuf);


    int bufLen = bytes * 4;
    int len = bufLen;
    unsigned char * buf;
    XSECnew(buf, unsigned char[bufLen]);
    ArrayJanitor<unsigned char> j_buf(buf);

    XSCryptCryptoBase64 *b64;
    XSECnew(b64, XSCryptCryptoBase64);
    Janitor<XSCryptCryptoBase64> j_b64(b64);

    b64->encodeInit();
    bufLen = b64->encode(binbuf, bytes, buf, bufLen);
    bufLen += b64->encodeFinish(&buf[bufLen], len-bufLen);
    buf[bufLen] = '\0';

    // Now translate to a bignum
    return XMLString::transcode((char *) buf);

}

#endif

DSIGKeyInfoX509 * findX509Data(DSIGKeyInfoList * lst) {

    if (lst == NULL)
        return NULL;

    int sz = (int) lst->getSize();
    for (int i = 0; i < sz; ++i) {

        DSIGKeyInfo *ki = lst->item(i);
        if (ki->getKeyInfoType() == DSIGKeyInfo::KEYINFO_X509)
            return (DSIGKeyInfoX509*) ki;

    }

    return NULL;

}

// --------------------------------------------------------------------------------
//           ErrorHandler
// --------------------------------------------------------------------------------

class xkmsErrorHandler : public ErrorHandler {

public:
    
    xkmsErrorHandler() {}
    ~xkmsErrorHandler() {}

    // Interface
    virtual void    warning (const SAXParseException &exc);
    virtual void    error (const SAXParseException &exc);
    virtual void    fatalError (const SAXParseException &exc);
    virtual void    resetErrors ();
    
private:

    void outputError(const SAXParseException &exc);

};

void xkmsErrorHandler::outputError(const SAXParseException &exc) {

    char * systemId = XMLString::transcode(exc.getSystemId());
    char * msg = XMLString::transcode(exc.getMessage());
    if (exc.getLineNumber() > 0 || exc.getColumnNumber() > 0) {
        cerr << "File: " << systemId << " Line : " << exc.getLineNumber() << " Column : " 
            << exc.getColumnNumber() << ". " << msg << endl;
    }
    else {
        cerr << msg << endl;
    }
    XSEC_RELEASE_XMLCH(msg);
    XSEC_RELEASE_XMLCH(systemId);

}

void xkmsErrorHandler::warning(const SAXParseException &exc) {

    cerr << "Parser warning - ";
    outputError(exc);

}

void xkmsErrorHandler::error (const SAXParseException &exc) {

    cerr << "Parser error - ";
    outputError(exc);

}

void xkmsErrorHandler::fatalError (const SAXParseException &exc) {

    cerr << "Parser fatal error - ";
    outputError(exc);

}

void xkmsErrorHandler::resetErrors () {

}


// --------------------------------------------------------------------------------
//           Create a LocateRequest
// --------------------------------------------------------------------------------

void printLocateRequestUsage(void) {

    cerr << "\nUsage LocateRequest [--help|-h] <service URI> [options]\n";
    cerr << "   --help/-h                : print this screen and exit\n\n";
    cerr << "   --add-cert/-a <filename> : add cert in filename as a KeyInfo\n";
    cerr << "   --add-name/-n <name>     : Add name as a KeyInfoName\n";
    cerr << "   --add-opaque/-o <data>   : Add an opaque data string\n";
    cerr << "   --add-usage-sig/-us      : Add Signature Key Usage\n";
    cerr << "   --add-usage-exc/-ux      : Add Excange Key Usage\n";
    cerr << "   --add-usage-enc/-ue      : Add Encryption Key Usage\n";
    cerr << "   --add-responselimit/-l <limit>\n";
    cerr << "                            : Set <limit> for ResponseLimit\n";
    cerr << "   --add-usekeywith/-u <Application URI> <Identifier>\n";
    cerr << "                            : Add a UseKeyWith element\n";
    cerr << "   --add-respondwith/-r <Identifier>\n";
    cerr << "                            : Add a RespondWith element\n";
    cerr << "   --add-responsemechanism/-m <Identifier>\n";
    cerr << "                            : Add a ResponseMechanism element\n";
    cerr << "   --sign-rsa/-sr <filename> <passphrase>\n";
    cerr << "           : Sign using the RSA key in file protected by passphrase\n";
    cerr << "   --sign-dsa/-sd <filename> <passphrase>\n";
    cerr << "           : Sign using the DSA key in file protected by passphrase\n\n";

}

XKMSMessageAbstractType * createLocateRequest(XSECProvider &prov, DOMDocument **doc, int argc, char ** argv, int &paramCount, XKMSCompoundRequest * cr = NULL) {

    if (paramCount >= argc || 
        (_stricmp(argv[paramCount], "--help") == 0) ||
        (_stricmp(argv[paramCount], "-h") == 0)) {

        printLocateRequestUsage();
        return NULL;
    }

    /* First create the basic request */
    XKMSMessageFactory * factory = 
        prov.getXKMSMessageFactory();
    XKMSLocateRequest * lr; 
    if (cr == NULL)
        lr = factory->createLocateRequest(MAKE_UNICODE_STRING(argv[paramCount++]), doc);
    else
        lr = cr->createLocateRequest(MAKE_UNICODE_STRING(argv[paramCount++]));

    while (paramCount < argc && _stricmp(argv[paramCount], "--") != 0) {

        if (_stricmp(argv[paramCount], "--add-cert") == 0 || _stricmp(argv[paramCount], "-a") == 0) {
            if (++paramCount >= argc) {
                printLocateRequestUsage();
                delete lr;
                return NULL;
            }
            XSECCryptoX509 * x = loadX509(argv[paramCount]);
            if (x == NULL) {
                delete lr;
                (*doc)->release();
                cerr << "Error opening Certificate file : " << 
                    argv[paramCount] << endl;
                return NULL;
            }

            Janitor<XSECCryptoX509> j_x(x);

            XKMSQueryKeyBinding * qkb = lr->getQueryKeyBinding();
            if (qkb == NULL) {
                qkb = lr->addQueryKeyBinding();
            }
            // See if there is already an X.509 element
            DSIGKeyInfoX509 * kix;
            if ((kix = findX509Data(qkb->getKeyInfoList())) == NULL)
                kix = qkb->appendX509Data();
            safeBuffer sb = x->getDEREncodingSB();
            kix->appendX509Certificate(sb.sbStrToXMLCh());
            paramCount++;
        }

        else if (_stricmp(argv[paramCount], "--add-name") == 0 || _stricmp(argv[paramCount], "-n") == 0) {
            if (++paramCount >= argc) {
                printLocateRequestUsage();
                delete lr;
                return NULL;
            }
            XKMSQueryKeyBinding * qkb = lr->addQueryKeyBinding();
            qkb->appendKeyName(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-opaque") == 0 || _stricmp(argv[paramCount], "-o") == 0) {
            if (++paramCount >= argc) {
                printLocateRequestUsage();
                delete lr;
                return NULL;
            }
            lr->appendOpaqueClientDataItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-sig") == 0 || _stricmp(argv[paramCount], "-us") == 0) {
            XKMSQueryKeyBinding * qkb = lr->getQueryKeyBinding();
            if (qkb == NULL)
                qkb = lr->addQueryKeyBinding();
            qkb->setSignatureKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-exc") == 0 || _stricmp(argv[paramCount], "-ux") == 0) {
            XKMSQueryKeyBinding * qkb = lr->getQueryKeyBinding();
            if (qkb == NULL)
                qkb = lr->addQueryKeyBinding();
            qkb->setExchangeKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-enc") == 0 || _stricmp(argv[paramCount], "-ue") == 0) {
            XKMSQueryKeyBinding * qkb = lr->getQueryKeyBinding();
            if (qkb == NULL)
                qkb = lr->addQueryKeyBinding();
            qkb->setEncryptionKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-responselimit") == 0 || _stricmp(argv[paramCount], "-l") == 0) {
            if (paramCount >= argc+1) {
                printLocateRequestUsage();
                delete lr;
                return NULL;
            }
            paramCount++;
            lr->setResponseLimit(atoi(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usekeywith") == 0 || _stricmp(argv[paramCount], "-u") == 0) {
            if (++paramCount >= argc + 1) {
                printLocateRequestUsage();
                delete lr;
                return NULL;
            }
            XKMSQueryKeyBinding *qkb = lr->getQueryKeyBinding();
            if (qkb == NULL)
                qkb = lr->addQueryKeyBinding();

            qkb->appendUseKeyWithItem(MAKE_UNICODE_STRING(argv[paramCount]), MAKE_UNICODE_STRING(argv[paramCount + 1]));
            paramCount += 2;
        }
        else if (_stricmp(argv[paramCount], "--add-respondwith") == 0 || _stricmp(argv[paramCount], "-r") == 0) {
            if (++paramCount >= argc) {
                printLocateRequestUsage();
                delete lr;
                return NULL;
            }
            lr->appendRespondWithItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-responsemechanism") == 0 || _stricmp(argv[paramCount], "-m") == 0) {
            if (++paramCount >= argc) {
                printLocateRequestUsage();
                delete lr;
                return NULL;
            }
            lr->appendResponseMechanismItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
#if defined (XSEC_HAVE_OPENSSL)
        else if (_stricmp(argv[paramCount], "--sign-dsa") == 0 || _stricmp(argv[paramCount], "-sd") == 0 ||
                _stricmp(argv[paramCount], "--sign-rsa") == 0 || _stricmp(argv[paramCount], "-sr") == 0) {
            if (paramCount >= argc + 2) {
                printLocateRequestUsage();
                delete lr;
                return NULL;
            }

            // DSA or RSA OpenSSL Key
            // For now just read a particular file

            BIO * bioKey;
            if ((bioKey = BIO_new(BIO_s_file())) == NULL) {

                cerr << "Error opening private key file\n\n";
                return NULL;

            }

            if (BIO_read_filename(bioKey, argv[paramCount+1]) <= 0) {

                cerr << "Error opening private key file : " << argv[paramCount+1] << endl;
                return NULL;

            }

            EVP_PKEY * pkey;
            pkey = PEM_read_bio_PrivateKey(bioKey,NULL,NULL,argv[paramCount + 2]);

            if (pkey == NULL) {

                BIO * bio_err;
    
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
                    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
                cerr << "Error loading private key\n\n";
                ERR_print_errors(bio_err);
                return NULL;

            }
            XSECCryptoKey *key;
            DSIGSignature * sig;
            if (_stricmp(argv[paramCount], "--sign-dsa") == 0 || _stricmp(argv[paramCount], "-sd") == 0) {

                // Check type is correct

                if (EVP_PKEY_id(pkey) != EVP_PKEY_DSA) {
                    cerr << "DSA Key requested, but OpenSSL loaded something else\n";
                    return NULL;
                }

                sig = lr->addSignature(
                		DSIGConstants::s_unicodeStrURIC14N_NOC,
                		DSIGConstants::s_unicodeStrURIDSA_SHA1,
					DSIGConstants::s_unicodeStrURISHA1);
                // Create the XSEC OpenSSL interface
                key = new OpenSSLCryptoKeyDSA(pkey);

				const BIGNUM *otherP = NULL, *otherQ = NULL, *otherG = NULL;
				DSA_get0_pqg(EVP_PKEY_get0_DSA(pkey), &otherP, &otherQ, &otherG);
                XMLCh * P = BN2b64(otherP);
                XMLCh * Q = BN2b64(otherQ);
                XMLCh * G = BN2b64(otherG);
				const BIGNUM *otherPriv = NULL, *otherPub = NULL;
				DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &otherPub, &otherPriv);
                XMLCh * Y = BN2b64((BIGNUM*)otherPub);

                sig->appendDSAKeyValue(P,Q,G,Y);

                XSEC_RELEASE_XMLCH(P);
                XSEC_RELEASE_XMLCH(Q);
                XSEC_RELEASE_XMLCH(G);
                XSEC_RELEASE_XMLCH(Y);
            }
            else {
                if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
                    cerr << "RSA Key requested, but OpenSSL loaded something else\n";
                    exit (1);
                }
                sig = lr->addSignature(
                		DSIGConstants::s_unicodeStrURIC14N_NOC,
                		DSIGConstants::s_unicodeStrURIRSA_SHA1,
					DSIGConstants::s_unicodeStrURISHA1);
                key = new OpenSSLCryptoKeyRSA(pkey);

				const BIGNUM *n=NULL, *e=NULL, *d=NULL;
				RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, &e, &d);

                XMLCh * mod = BN2b64(n);
                XMLCh * exp = BN2b64(e);

                sig->appendRSAKeyValue(mod, exp);
                XSEC_RELEASE_XMLCH(mod);
                XSEC_RELEASE_XMLCH(exp);

            }

            sig->setSigningKey(key);
            sig->sign();

            EVP_PKEY_free(pkey);
            BIO_free(bioKey);

            paramCount += 3;

            
        } /* argv[1] = "dsa/rsa" */

#endif
        else {
            printLocateRequestUsage();
            delete lr;
            (*doc)->release();
            return NULL;
        }
    }

    return lr;
}

// --------------------------------------------------------------------------------
//           Create a ValidateRequest
// --------------------------------------------------------------------------------

void printValidateRequestUsage(void) {

    cerr << "\nUsage ValidateRequest [--help|-h] <service URI> [options]\n";
    cerr << "   --help/-h                : print this screen and exit\n\n";
    cerr << "   --add-cert/-a <filename> : add cert in filename as a KeyInfo\n";
    cerr << "   --add-name/-n <name>     : Add name as a KeyInfoName\n";
    cerr << "   --add-opaque/-o <data>   : Add an opaque data string\n";
    cerr << "   --add-usage-sig/-us      : Add Signature Key Usage\n";
    cerr << "   --add-usage-exc/-ux      : Add Excange Key Usage\n";
    cerr << "   --add-usage-enc/-ue      : Add Encryption Key Usage\n";
    cerr << "   --add-responselimit/-l <limit>\n";
    cerr << "                            : Set <limit> for ResponseLimit\n";
    cerr << "   --add-usekeywith/-u <Application URI> <Identifier>\n";
    cerr << "                            : Add a UseKeyWith element\n";
    cerr << "   --add-respondwith/-r <Identifier>\n";
    cerr << "                            : Add a RespondWith element\n";
    cerr << "   --add-responsemechanism/-m <Identifier>\n";
    cerr << "                            : Add a ResponseMechanism element\n";
    cerr << "   --sign-rsa/-sr <filename> <passphrase>\n";
    cerr << "           : Sign using the RSA key in file protected by passphrase\n";
    cerr << "   --sign-dsa/-sd <filename> <passphrase>\n";
    cerr << "           : Sign using the DSA key in file protected by passphrase\n";
    cerr << "   --sign-cert/-sc <filename>\n";
    cerr << "           : Add the indicated certificate to the signature KeyInfo\n\n";

}

XKMSMessageAbstractType * createValidateRequest(XSECProvider &prov, DOMDocument **doc, int argc, char ** argv, int &paramCount, XKMSCompoundRequest * cr = NULL) {

    if (paramCount >= argc || 
        (_stricmp(argv[paramCount], "--help") == 0) ||
        (_stricmp(argv[paramCount], "-h") == 0)) {

        printValidateRequestUsage();
        return NULL;
    }

    /* First create the basic request */
    XKMSMessageFactory * factory = 
        prov.getXKMSMessageFactory();
    XKMSValidateRequest * vr;

    if (cr == NULL)
        vr = factory->createValidateRequest(MAKE_UNICODE_STRING(argv[paramCount++]), doc);
    else
        vr = cr->createValidateRequest(MAKE_UNICODE_STRING(argv[paramCount++]));

    while (paramCount < argc && _stricmp(argv[paramCount], "--") != 0) {

        if (_stricmp(argv[paramCount], "--add-cert") == 0 || _stricmp(argv[paramCount], "-a") == 0) {
            if (++paramCount >= argc) {
                printValidateRequestUsage();
                delete vr;
                return NULL;
            }
            XSECCryptoX509 * x = loadX509(argv[paramCount]);
            if (x == NULL) {
                delete vr;
                (*doc)->release();
                cerr << "Error opening Certificate file : " << 
                    argv[paramCount] << endl;
                return NULL;
            }

            Janitor<XSECCryptoX509> j_x(x);

            XKMSQueryKeyBinding * qkb = vr->getQueryKeyBinding();
            if (qkb == NULL) {
                qkb = vr->addQueryKeyBinding();
            }
            // See if there is already an X.509 element
            DSIGKeyInfoX509 * kix;
            if ((kix = findX509Data(qkb->getKeyInfoList())) == NULL)
                kix = qkb->appendX509Data();
            safeBuffer sb = x->getDEREncodingSB();
            kix->appendX509Certificate(sb.sbStrToXMLCh());
            paramCount++;

        }

        else if (_stricmp(argv[paramCount], "--add-name") == 0 || _stricmp(argv[paramCount], "-n") == 0) {
            if (++paramCount >= argc) {
                printValidateRequestUsage();
                delete vr;
                return NULL;
            }
            XKMSQueryKeyBinding * qkb = vr->addQueryKeyBinding();
            qkb->appendKeyName(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-opaque") == 0 || _stricmp(argv[paramCount], "-o") == 0) {
            if (++paramCount >= argc) {
                printValidateRequestUsage();
                delete vr;
                return NULL;
            }
            vr->appendOpaqueClientDataItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-respondwith") == 0 || _stricmp(argv[paramCount], "-r") == 0) {
            if (++paramCount >= argc) {
                printValidateRequestUsage();
                delete vr;
                return NULL;
            }
            vr->appendRespondWithItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-responsemechanism") == 0 || _stricmp(argv[paramCount], "-m") == 0) {
            if (++paramCount >= argc) {
                printLocateRequestUsage();
                delete vr;
                return NULL;
            }
            vr->appendResponseMechanismItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-responselimit") == 0 || _stricmp(argv[paramCount], "-l") == 0) {
            if (paramCount >= argc+1) {
                printValidateRequestUsage();
                delete vr;
                return NULL;
            }
            paramCount++;
            vr->setResponseLimit(atoi(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-sig") == 0 || _stricmp(argv[paramCount], "-us") == 0) {
            XKMSQueryKeyBinding * qkb = vr->getQueryKeyBinding();
            if (qkb == NULL)
                qkb = vr->addQueryKeyBinding();
            qkb->setSignatureKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-exc") == 0 || _stricmp(argv[paramCount], "-ux") == 0) {
            XKMSQueryKeyBinding * qkb = vr->getQueryKeyBinding();
            if (qkb == NULL)
                qkb = vr->addQueryKeyBinding();
            qkb->setExchangeKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-enc") == 0 || _stricmp(argv[paramCount], "-ue") == 0) {
            XKMSQueryKeyBinding * qkb = vr->getQueryKeyBinding();
            if (qkb == NULL)
                qkb = vr->addQueryKeyBinding();
            qkb->setEncryptionKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usekeywith") == 0 || _stricmp(argv[paramCount], "-u") == 0) {
            if (++paramCount >= argc + 1) {
                printValidateRequestUsage();
                delete vr;
                return NULL;
            }
            XKMSQueryKeyBinding *qkb = vr->getQueryKeyBinding();
            if (qkb == NULL)
                qkb = vr->addQueryKeyBinding();

            qkb->appendUseKeyWithItem(MAKE_UNICODE_STRING(argv[paramCount]), MAKE_UNICODE_STRING(argv[paramCount + 1]));
            paramCount += 2;
        }
#if defined (XSEC_HAVE_OPENSSL)
        else if (_stricmp(argv[paramCount], "--sign-dsa") == 0 || _stricmp(argv[paramCount], "-sd") == 0 ||
                _stricmp(argv[paramCount], "--sign-rsa") == 0 || _stricmp(argv[paramCount], "-sr") == 0) {
            if (paramCount >= argc + 2) {
                printValidateRequestUsage();
                delete vr;
                return NULL;
            }

            // DSA or RSA OpenSSL Key
            // For now just read a particular file

            BIO * bioKey;
            if ((bioKey = BIO_new(BIO_s_file())) == NULL) {

                cerr << "Error opening private key file\n\n";
                return NULL;

            }

            if (BIO_read_filename(bioKey, argv[paramCount+1]) <= 0) {

                cerr << "Error opening private key file : " << argv[paramCount+1] << endl;
                return NULL;

            }

            EVP_PKEY * pkey;
            pkey = PEM_read_bio_PrivateKey(bioKey,NULL,NULL,argv[paramCount + 2]);

            if (pkey == NULL) {

                BIO * bio_err;
    
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
                    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
                cerr << "Error loading private key\n\n";
                ERR_print_errors(bio_err);
                return NULL;

            }
            XSECCryptoKey *key;
            DSIGSignature * sig;
            if (_stricmp(argv[paramCount], "--sign-dsa") == 0 || _stricmp(argv[paramCount], "-sd") == 0) {

                // Check type is correct

                if (EVP_PKEY_id(pkey) != EVP_PKEY_DSA) {
                    cerr << "DSA Key requested, but OpenSSL loaded something else\n";
                    return NULL;
                }

                sig = vr->addSignature(
                		DSIGConstants::s_unicodeStrURIC14N_NOC,
                		DSIGConstants::s_unicodeStrURIDSA_SHA1,
					DSIGConstants::s_unicodeStrURISHA1);
                // Create the XSEC OpenSSL interface
                key = new OpenSSLCryptoKeyDSA(pkey);

				const BIGNUM *otherP = NULL, *otherQ = NULL, *otherG = NULL;
				DSA_get0_pqg(EVP_PKEY_get0_DSA(pkey), &otherP, &otherQ, &otherG);
                XMLCh * P = BN2b64(otherP);
                XMLCh * Q = BN2b64(otherQ);
                XMLCh * G = BN2b64(otherG);
				const BIGNUM *otherPriv = NULL, *otherPub = NULL;
				DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &otherPub, &otherPriv);
                XMLCh * Y = BN2b64(otherPub);

                sig->appendDSAKeyValue(P,Q,G,Y);

                XSEC_RELEASE_XMLCH(P);
                XSEC_RELEASE_XMLCH(Q);
                XSEC_RELEASE_XMLCH(G);
                XSEC_RELEASE_XMLCH(Y);
            }
            else {
                if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
                    cerr << "RSA Key requested, but OpenSSL loaded something else\n";
                    exit (1);
                }
                sig = vr->addSignature(
                		DSIGConstants::s_unicodeStrURIC14N_NOC,
                		DSIGConstants::s_unicodeStrURIRSA_SHA1,
					DSIGConstants::s_unicodeStrURISHA1);
                key = new OpenSSLCryptoKeyRSA(pkey);

				const BIGNUM *n=NULL, *e=NULL, *d=NULL;
                RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, &e, &d);

                XMLCh * mod = BN2b64(n);
                XMLCh * exp = BN2b64(e);

                sig->appendRSAKeyValue(mod, exp);
                XSEC_RELEASE_XMLCH(mod);
                XSEC_RELEASE_XMLCH(exp);

            }

            sig->setSigningKey(key);
            sig->sign();

            EVP_PKEY_free(pkey);
            BIO_free(bioKey);

            paramCount += 3;

            
        } /* argv[1] = "dsa/rsa" */
        else if (_stricmp(argv[paramCount], "--sign-cert") == 0 || _stricmp(argv[paramCount], "-sc") == 0) {
            if (++paramCount >= argc) {
                printValidateRequestUsage();
                delete vr;
                return NULL;
            }
            XSECCryptoX509 * x = loadX509(argv[paramCount]);
            if (x == NULL) {
                delete vr;
                (*doc)->release();
                cerr << "Error opening Certificate file : " << 
                    argv[paramCount] << endl;
                return NULL;
            }

            Janitor<XSECCryptoX509> j_x(x);

            DSIGSignature * sig = vr->getSignature();
            if (sig == NULL) {
                cerr << "Can only add Certificates to signature after signing\n";
                return NULL;
            }

            // See if there is already an X.509 element
            DSIGKeyInfoX509 * kix;
            if ((kix = findX509Data(sig->getKeyInfoList())) == NULL)
                kix = sig->appendX509Data();
            safeBuffer sb = x->getDEREncodingSB();
            kix->appendX509Certificate(sb.sbStrToXMLCh());
            paramCount++;
        }

#endif
        else {
            printValidateRequestUsage();
            delete vr;
            (*doc)->release();
            return NULL;
        }
    }

    return vr;
}

// --------------------------------------------------------------------------------
//           Create a RegisterRequest
// --------------------------------------------------------------------------------

void printRegisterRequestUsage(void) {

    cerr << "\nUsage RegisterRequest [--help|-h] <service URI> [options]\n";
    cerr << "   --help/-h                : print this screen and exit\n\n";
    cerr << "   --add-name/-n <name>     : Add name as a KeyInfoName\n";
    cerr << "   --add-opaque/-o <data>   : Add an opaque data string\n";
    cerr << "   --add-usage-sig/-us      : Add Signature Key Usage\n";
    cerr << "   --add-usage-exc/-ux      : Add Exchange Key Usage\n";
    cerr << "   --add-usage-enc/-ue      : Add Encryption Key Usage\n";
    cerr << "   --add-usekeywith/-u <Application URI> <Identifier>\n";
    cerr << "                            : Add a UseKeyWith element\n";
    cerr << "   --add-respondwith/-r <Identifier>\n";
    cerr << "                            : Add a RespondWith element\n";
    cerr << "   --add-responsemechanism/-m <Identifier>\n";
    cerr << "                            : Add a ResponseMechanism element\n";
    cerr << "   --sign-dsa/-sd <filename> <passphrase>\n";
    cerr << "           : Sign using the DSA key in file protected by passphrase\n";
    cerr << "   --add-value-dsa/-vd <filename> <passphrase> (and do proof-of-possession sig)\n";
    cerr << "           : Add the DSA key as a keyvalue\n";
    cerr << "   --add-value-rsa/-vr <filename> <passphrase> (and do proof-of-possession sig)\n";
    cerr << "           : Add the RSA key as a keyvalue\n";
    cerr << "   --revocation/-v <phrase> : Set <phrase> as revocation code\n";
    cerr << "   --kek/-k <phrase>        : Key phrase to use for PrivateKey decryption\n";
#if defined (XSEC_HAVE_OPENSSL)
    cerr << "   --output-private-key/-p <file> <pass phrase>\n";
    cerr << "                            : Write PEM encoded private key to file\n";
#endif
    cerr << "   --authenticate/-a <phrase>\n";
    cerr << "           : Use <phrase> as the authentication key for the request\n";
    cerr << "             NOTE - This must come *after* adding of KeyInfo elements\n\n";

}

XKMSMessageAbstractType * createRegisterRequest(XSECProvider &prov, DOMDocument **doc, int argc, char ** argv, int &paramCount, XKMSCompoundRequest * cr = NULL) {

    XSECCryptoKey *proofOfPossessionKey = NULL;
    const XMLCh* proofOfPossessionSm = NULL;

    if (paramCount >= argc || 
        (_stricmp(argv[paramCount], "--help") == 0) ||
        (_stricmp(argv[paramCount], "-h") == 0)) {

        printRegisterRequestUsage();
        return NULL;
    }

    /* First create the basic request */
    XKMSMessageFactory * factory = 
        prov.getXKMSMessageFactory();
    XKMSRegisterRequest * rr;

    if (cr == NULL)
        rr = factory->createRegisterRequest(MAKE_UNICODE_STRING(argv[paramCount++]), doc);
    else
        rr = cr->createRegisterRequest(MAKE_UNICODE_STRING(argv[paramCount++]));

    while (paramCount < argc && _stricmp(argv[paramCount], "--") != 0) {

        if (_stricmp(argv[paramCount], "--add-name") == 0 || _stricmp(argv[paramCount], "-n") == 0) {
            if (++paramCount >= argc) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }

            XKMSPrototypeKeyBinding * pkb = rr->getPrototypeKeyBinding();
            if (pkb == NULL)
                pkb = rr->addPrototypeKeyBinding();
            pkb->appendKeyName(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-opaque") == 0 || _stricmp(argv[paramCount], "-o") == 0) {
            if (++paramCount >= argc) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }
            rr->appendOpaqueClientDataItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--kek") == 0 || _stricmp(argv[paramCount], "-k") == 0) {
            if (++paramCount >= argc) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }
            g_authPassPhrase = argv[paramCount++];
        }
        else if (_stricmp(argv[paramCount], "--add-respondwith") == 0 || _stricmp(argv[paramCount], "-r") == 0) {
            if (++paramCount >= argc) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }
            rr->appendRespondWithItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-responsemechanism") == 0 || _stricmp(argv[paramCount], "-m") == 0) {
            if (++paramCount >= argc) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }
            rr->appendResponseMechanismItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-sig") == 0 || _stricmp(argv[paramCount], "-us") == 0) {
            XKMSPrototypeKeyBinding * pkb = rr->getPrototypeKeyBinding();
            if (pkb == NULL)
                pkb = rr->addPrototypeKeyBinding();
            pkb->setSignatureKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-exc") == 0 || _stricmp(argv[paramCount], "-ux") == 0) {
            XKMSPrototypeKeyBinding * pkb = rr->getPrototypeKeyBinding();
            if (pkb == NULL)
                pkb = rr->addPrototypeKeyBinding();
            pkb->setExchangeKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-enc") == 0 || _stricmp(argv[paramCount], "-ue") == 0) {
            XKMSPrototypeKeyBinding * pkb = rr->getPrototypeKeyBinding();
            if (pkb == NULL)
                pkb = rr->addPrototypeKeyBinding();
            pkb->setEncryptionKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usekeywith") == 0 || _stricmp(argv[paramCount], "-u") == 0) {
            if (++paramCount >= argc + 1) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }
            XKMSPrototypeKeyBinding *pkb = rr->getPrototypeKeyBinding();
            if (pkb == NULL)
                pkb = rr->addPrototypeKeyBinding();

            pkb->appendUseKeyWithItem(MAKE_UNICODE_STRING(argv[paramCount]), MAKE_UNICODE_STRING(argv[paramCount + 1]));
            paramCount += 2;
        }
#if defined (XSEC_HAVE_OPENSSL)
        else if (_stricmp(argv[paramCount], "--output-private-key") == 0 || _stricmp(argv[paramCount], "-p") == 0) {
            if (paramCount >= argc + 2) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }
            ++paramCount;
            g_privateKeyFile = argv[paramCount++];
            g_privateKeyPassPhrase = argv[paramCount++];
        }
#endif
        else if (_stricmp(argv[paramCount], "--revocation") == 0 || _stricmp(argv[paramCount], "-v") == 0) {
            if (++paramCount >= argc) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }
            XKMSPrototypeKeyBinding *pkb = rr->getPrototypeKeyBinding();
            if (pkb == NULL)
                pkb = rr->addPrototypeKeyBinding();

            // Create the RevocationCodeIdentifier
            unsigned char rciBuf[XSEC_MAX_HASH_SIZE];
            int len = CalculateXKMSRevocationCodeIdentifierEncoding2((unsigned char *) argv[paramCount], (int) strlen(argv[paramCount]), rciBuf, XSEC_MAX_HASH_SIZE);

            if (len <= 0) {
                cerr << "Error creating revocation code!\n";
                delete rr;
                return NULL;
            }

            // Convert to base64
            XMLCh * str = EncodeToBase64XMLCh(rciBuf, len);
            pkb->setRevocationCodeIdentifier(str);
            XSEC_RELEASE_XMLCH(str);

            paramCount++;;
        }       
        else if (_stricmp(argv[paramCount], "--authenticate") == 0 || _stricmp(argv[paramCount], "-a") == 0) {
            if (++paramCount >= argc + 1) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }

            // Create the signature

            unsigned char keyBuf[XSEC_MAX_HASH_SIZE];
            int len = CalculateXKMSAuthenticationKey((unsigned char *) argv[paramCount], (int) strlen(argv[paramCount]), keyBuf, XSEC_MAX_HASH_SIZE);
            if (len <= 0) {
                cout << "Error creating key from pass phrase" << endl;
                delete rr;
                return NULL;
            }

            XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
            k->setKey(keyBuf, len);

            // Set key and validate
            XKMSAuthentication * a = rr->addAuthentication();
            DSIGSignature * sig = a->addKeyBindingAuthenticationSignature(
            			DSIGConstants::s_unicodeStrURIC14N_NOC,
					DSIGConstants::s_unicodeStrURIHMAC_SHA1,
					DSIGConstants::s_unicodeStrURISHA1);

            sig->setSigningKey(k);
            sig->sign();

            paramCount++;

        }
#if defined (XSEC_HAVE_OPENSSL)
        else if (_stricmp(argv[paramCount], "--sign-dsa") == 0 || _stricmp(argv[paramCount], "-sd") == 0 ||
                _stricmp(argv[paramCount], "--sign-rsa") == 0 || _stricmp(argv[paramCount], "-sr") == 0) {
            if (paramCount >= argc + 2) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }

            // DSA or RSA OpenSSL Key
            // For now just read a particular file

            BIO * bioKey;
            if ((bioKey = BIO_new(BIO_s_file())) == NULL) {

                cerr << "Error opening private key file\n\n";
                return NULL;

            }

            if (BIO_read_filename(bioKey, argv[paramCount+1]) <= 0) {

                cerr << "Error opening private key file : " << argv[paramCount+1] << endl;
                return NULL;

            }

            EVP_PKEY * pkey;
            pkey = PEM_read_bio_PrivateKey(bioKey,NULL,NULL,argv[paramCount + 2]);

            if (pkey == NULL) {

                BIO * bio_err;
    
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
                    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
                cerr << "Error loading private key\n\n";
                ERR_print_errors(bio_err);
                return NULL;

            }
            XSECCryptoKey *key;
            DSIGSignature * sig;
            if (_stricmp(argv[paramCount], "--sign-dsa") == 0 || _stricmp(argv[paramCount], "-sd") == 0) {

                // Check type is correct

                if (EVP_PKEY_id(pkey) != EVP_PKEY_DSA) {
                    cerr << "DSA Key requested, but OpenSSL loaded something else\n";
                    return NULL;
                }

                sig = rr->addSignature(
                		DSIGConstants::s_unicodeStrURIC14N_NOC,
                		DSIGConstants::s_unicodeStrURIDSA_SHA1,
					DSIGConstants::s_unicodeStrURISHA1);
                // Create the XSEC OpenSSL interface
                key = new OpenSSLCryptoKeyDSA(pkey);

				const BIGNUM *otherP = NULL, *otherQ = NULL, *otherG = NULL;
				DSA_get0_pqg(EVP_PKEY_get0_DSA(pkey), &otherP, &otherQ, &otherG);
                XMLCh * P = BN2b64(otherP);
                XMLCh * Q = BN2b64(otherQ);
                XMLCh * G = BN2b64(otherG);
				const BIGNUM *otherPriv = NULL, *otherPub = NULL;
				DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &otherPub, &otherPriv);
                XMLCh * Y = BN2b64(otherPub);

                sig->appendDSAKeyValue(P,Q,G,Y);

                XSEC_RELEASE_XMLCH(P);
                XSEC_RELEASE_XMLCH(Q);
                XSEC_RELEASE_XMLCH(G);
                XSEC_RELEASE_XMLCH(Y);
            }
            else {
                if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
                    cerr << "RSA Key requested, but OpenSSL loaded something else\n";
                    exit (1);
                }
                sig = rr->addSignature(
                		DSIGConstants::s_unicodeStrURIC14N_NOC,
                		DSIGConstants::s_unicodeStrURIRSA_SHA1,
					DSIGConstants::s_unicodeStrURISHA1);
                key = new OpenSSLCryptoKeyRSA(pkey);

				const BIGNUM *n=NULL, *e=NULL, *d=NULL;
				RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, &e, &d);

                XMLCh * mod = BN2b64(n);
                XMLCh * exp = BN2b64(e);

				sig->appendRSAKeyValue(mod, exp);
                XSEC_RELEASE_XMLCH(mod);
                XSEC_RELEASE_XMLCH(exp);

            }

            sig->setSigningKey(key);
            sig->sign();

            EVP_PKEY_free(pkey);
            BIO_free(bioKey);

            paramCount += 3;

            
        } /* argv[1] = "sign dsa/rsa" */
        else if (_stricmp(argv[paramCount], "--add-value-dsa") == 0 || _stricmp(argv[paramCount], "-vd") == 0 ||
                _stricmp(argv[paramCount], "--add-value-rsa") == 0 || _stricmp(argv[paramCount], "-vr") == 0) {
            if (paramCount >= argc + 2) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }

            // DSA or RSA OpenSSL Key
            // For now just read a particular file

            BIO * bioKey;
            if ((bioKey = BIO_new(BIO_s_file())) == NULL) {

                cerr << "Error opening private key file\n\n";
                return NULL;

            }

            if (BIO_read_filename(bioKey, argv[paramCount+1]) <= 0) {

                cerr << "Error opening private key file : " << argv[paramCount+1] << endl;
                return NULL;

            }

            EVP_PKEY * pkey;
            pkey = PEM_read_bio_PrivateKey(bioKey,NULL,NULL,argv[paramCount + 2]);

            if (pkey == NULL) {

                BIO * bio_err;
    
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
                    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
                cerr << "Error loading private key\n\n";
                ERR_print_errors(bio_err);
                return NULL;

            }

            XKMSPrototypeKeyBinding * pkb = rr->getPrototypeKeyBinding();
            if (pkb == NULL)
                pkb = rr->addPrototypeKeyBinding();


            if (_stricmp(argv[paramCount], "--add-value-dsa") == 0 || _stricmp(argv[paramCount], "-vd") == 0) {

                // Check type is correct

                if (EVP_PKEY_id(pkey) != EVP_PKEY_DSA) {
                    cerr << "DSA Key requested, but OpenSSL loaded something else\n";
                    return NULL;
                }

                proofOfPossessionKey = new OpenSSLCryptoKeyDSA(pkey);
                proofOfPossessionSm = DSIGConstants::s_unicodeStrURIDSA_SHA1;

				const BIGNUM *otherP = NULL, *otherQ = NULL, *otherG = NULL;
				DSA_get0_pqg(EVP_PKEY_get0_DSA(pkey), &otherP, &otherQ, &otherG);
                XMLCh * P = BN2b64(otherP);
                XMLCh * Q = BN2b64(otherQ);
                XMLCh * G = BN2b64(otherG);
				const BIGNUM *otherPriv = NULL, *otherPub = NULL;
				DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &otherPub, &otherPriv);
                XMLCh * Y = BN2b64(otherPub);

                pkb->appendDSAKeyValue(P,Q,G,Y);

                XSEC_RELEASE_XMLCH(P);
                XSEC_RELEASE_XMLCH(Q);
                XSEC_RELEASE_XMLCH(G);
                XSEC_RELEASE_XMLCH(Y);
            }
            else {
                if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
                    cerr << "RSA Key requested, but OpenSSL loaded something else\n";
                    exit (1);
                }

                proofOfPossessionKey = new OpenSSLCryptoKeyRSA(pkey);
                proofOfPossessionSm = DSIGConstants::s_unicodeStrURIRSA_SHA1;

				const BIGNUM *n=NULL, *e=NULL, *d=NULL;
				RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, &e, &d);

                XMLCh * mod = BN2b64(n);
                XMLCh * exp = BN2b64(e);

				pkb->appendRSAKeyValue(mod, exp);
                XSEC_RELEASE_XMLCH(mod);
                XSEC_RELEASE_XMLCH(exp);

            }

            EVP_PKEY_free(pkey);
            BIO_free(bioKey);

            paramCount += 3;

            
        } /* argv[1] = "value dsa/rsa" */

#endif
        else {
            printRegisterRequestUsage();
            delete rr;
            (*doc)->release();
            return NULL;
        }
    }

    if (proofOfPossessionKey != NULL) {

        // Set up the proof of possession
        DSIGSignature * s = 
            rr->addProofOfPossessionSignature(
            		DSIGConstants::s_unicodeStrURIC14N_NOC,
				proofOfPossessionSm,
				DSIGConstants::s_unicodeStrURISHA1);

        s->setSigningKey(proofOfPossessionKey);
        s->sign();

    }

    return rr;
}

// --------------------------------------------------------------------------------
//           Create a RevokeRequest
// --------------------------------------------------------------------------------

void printRevokeRequestUsage(void) {

    cerr << "\nUsage RevokeRequest [--help|-h] <service URI> [options]\n";
    cerr << "   --help/-h                : print this screen and exit\n\n";
    cerr << "   --add-name/-n <name>     : Add name as a KeyInfoName\n";
    cerr << "   --add-opaque/-o <data>   : Add an opaque data string\n";
    cerr << "   --add-usage-sig/-us      : Add Signature Key Usage\n";
    cerr << "   --add-usage-exc/-ux      : Add Exchange Key Usage\n";
    cerr << "   --add-usage-enc/-ue      : Add Encryption Key Usage\n";
    cerr << "   --add-usekeywith/-u <Application URI> <Identifier>\n";
    cerr << "                            : Add a UseKeyWith element\n";
    cerr << "   --add-respondwith/-r <Identifier>\n";
    cerr << "                            : Add a RespondWith element\n";
    cerr << "   --add-responsemechanism/-m <Identifier>\n";
    cerr << "                            : Add a ResponseMechanism element\n";
    cerr << "   --sign-dsa/-sd <filename> <passphrase>\n";
    cerr << "           : Sign using the DSA key in file protected by passphrase\n";
    cerr << "   --add-value-dsa/-vd <filename> <passphrase>\n";
    cerr << "           : Add the DSA key as a keyvalue\n";
    cerr << "   --add-value-rsa/-vr <filename> <passphrase>\n";
    cerr << "           : Add the RSA key as a keyvalue\n";
    cerr << "   --revocation/-v <phrase> : Set <phrase> as revocation code\n";
    cerr << "   --authenticate/-a <phrase>\n";
    cerr << "           : Use <phrase> as the authentication key for the request\n";
    cerr << "             NOTE - This must come *after* adding of KeyInfo elements\n\n";

}

XKMSMessageAbstractType * createRevokeRequest(XSECProvider &prov, DOMDocument **doc, int argc, char ** argv, int &paramCount, XKMSCompoundRequest * cr = NULL) {

    if (paramCount >= argc || 
        (_stricmp(argv[paramCount], "--help") == 0) ||
        (_stricmp(argv[paramCount], "-h") == 0)) {

        printRegisterRequestUsage();
        return NULL;
    }

    /* First create the basic request */
    XKMSMessageFactory * factory = 
        prov.getXKMSMessageFactory();
    XKMSRevokeRequest * rr;

    if (cr == NULL)
        rr = factory->createRevokeRequest(MAKE_UNICODE_STRING(argv[paramCount++]), doc);
    else
        rr = cr->createRevokeRequest(MAKE_UNICODE_STRING(argv[paramCount++]));

    while (paramCount < argc && _stricmp(argv[paramCount], "--") != 0) {

        if (_stricmp(argv[paramCount], "--add-name") == 0 || _stricmp(argv[paramCount], "-n") == 0) {
            if (++paramCount >= argc) {
                printRevokeRequestUsage();
                delete rr;
                return NULL;
            }

            XKMSRevokeKeyBinding * rkb = rr->getRevokeKeyBinding();
            if (rkb == NULL)
                rkb = rr->addRevokeKeyBinding(XKMSStatus::Indeterminate);
            rkb->appendKeyName(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-opaque") == 0 || _stricmp(argv[paramCount], "-o") == 0) {
            if (++paramCount >= argc) {
                printRevokeRequestUsage();
                delete rr;
                return NULL;
            }
            rr->appendOpaqueClientDataItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-respondwith") == 0 || _stricmp(argv[paramCount], "-r") == 0) {
            if (++paramCount >= argc) {
                printRevokeRequestUsage();
                delete rr;
                return NULL;
            }
            rr->appendRespondWithItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-responsemechanism") == 0 || _stricmp(argv[paramCount], "-m") == 0) {
            if (++paramCount >= argc) {
                printRevokeRequestUsage();
                delete rr;
                return NULL;
            }
            rr->appendResponseMechanismItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-sig") == 0 || _stricmp(argv[paramCount], "-us") == 0) {
            XKMSRevokeKeyBinding * rkb = rr->getRevokeKeyBinding();
            if (rkb == NULL)
                rkb = rr->addRevokeKeyBinding(XKMSStatus::Indeterminate);
            rkb->setSignatureKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-exc") == 0 || _stricmp(argv[paramCount], "-ux") == 0) {
            XKMSRevokeKeyBinding * rkb = rr->getRevokeKeyBinding();
            if (rkb == NULL)
                rkb = rr->addRevokeKeyBinding(XKMSStatus::Indeterminate);
            rkb->setExchangeKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-enc") == 0 || _stricmp(argv[paramCount], "-ue") == 0) {
            XKMSRevokeKeyBinding * rkb = rr->getRevokeKeyBinding();
            if (rkb == NULL)
                rkb = rr->addRevokeKeyBinding(XKMSStatus::Indeterminate);
            rkb->setEncryptionKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usekeywith") == 0 || _stricmp(argv[paramCount], "-u") == 0) {
            if (++paramCount >= argc + 1) {
                printRevokeRequestUsage();
                delete rr;
                return NULL;
            }
            XKMSRevokeKeyBinding *rkb = rr->getRevokeKeyBinding();
            if (rkb == NULL)
                rkb = rr->addRevokeKeyBinding(XKMSStatus::Indeterminate);

            rkb->appendUseKeyWithItem(MAKE_UNICODE_STRING(argv[paramCount]), MAKE_UNICODE_STRING(argv[paramCount + 1]));
            paramCount += 2;
        }
        else if (_stricmp(argv[paramCount], "--revocation") == 0 || _stricmp(argv[paramCount], "-v") == 0) {
            if (++paramCount >= argc) {
                printRevokeRequestUsage();
                delete rr;
                return NULL;
            }

            // Create the RevocationCode value
            unsigned char rciBuf[XSEC_MAX_HASH_SIZE];
            int len = CalculateXKMSRevocationCodeIdentifierEncoding1((unsigned char *) argv[paramCount], (int) strlen(argv[paramCount]), rciBuf, XSEC_MAX_HASH_SIZE);

            if (len <= 0) {
                cerr << "Error creating revocation code!\n";
                delete rr;
                return NULL;
            }

            // Convert to base64
            XMLCh * str = EncodeToBase64XMLCh(rciBuf, len);
            rr->addRevocationCode(str);
            XSEC_RELEASE_XMLCH(str);

            paramCount++;;
        }       else if (_stricmp(argv[paramCount], "--authenticate") == 0 || _stricmp(argv[paramCount], "-a") == 0) {
            if (++paramCount >= argc + 1) {
                printRevokeRequestUsage();
                delete rr;
                return NULL;
            }

            // Create the signature

            unsigned char keyBuf[XSEC_MAX_HASH_SIZE];
            int len = CalculateXKMSAuthenticationKey((unsigned char *) argv[paramCount], (int) strlen(argv[paramCount]), keyBuf, XSEC_MAX_HASH_SIZE);
            if (len <= 0) {
                cout << "Error creating key from pass phrase" << endl;
                delete rr;
                return NULL;
            }

            XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
            k->setKey(keyBuf, len);

            // Set key and validate
            XKMSAuthentication * a = rr->addAuthentication();
            DSIGSignature * sig = a->addKeyBindingAuthenticationSignature(
            		DSIGConstants::s_unicodeStrURIC14N_NOC,
				DSIGConstants::s_unicodeStrURIHMAC_SHA1,
				DSIGConstants::s_unicodeStrURISHA1);

            sig->setSigningKey(k);
            sig->sign();

            paramCount++;

        }
#if defined (XSEC_HAVE_OPENSSL)
        else if (_stricmp(argv[paramCount], "--sign-dsa") == 0 || _stricmp(argv[paramCount], "-sd") == 0 ||
                _stricmp(argv[paramCount], "--sign-rsa") == 0 || _stricmp(argv[paramCount], "-sr") == 0) {
            if (paramCount >= argc + 2) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }

            // DSA or RSA OpenSSL Key
            // For now just read a particular file

            BIO * bioKey;
            if ((bioKey = BIO_new(BIO_s_file())) == NULL) {

                cerr << "Error opening private key file\n\n";
                return NULL;

            }

            if (BIO_read_filename(bioKey, argv[paramCount+1]) <= 0) {

                cerr << "Error opening private key file : " << argv[paramCount+1] << endl;
                return NULL;

            }

            EVP_PKEY * pkey;
            pkey = PEM_read_bio_PrivateKey(bioKey,NULL,NULL,argv[paramCount + 2]);

            if (pkey == NULL) {

                BIO * bio_err;
    
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
                    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
                cerr << "Error loading private key\n\n";
                ERR_print_errors(bio_err);
                return NULL;

            }
            XSECCryptoKey *key;
            DSIGSignature * sig;
            if (_stricmp(argv[paramCount], "--sign-dsa") == 0 || _stricmp(argv[paramCount], "-sd") == 0) {

                // Check type is correct

                if (EVP_PKEY_id(pkey) != EVP_PKEY_DSA) {
                    cerr << "DSA Key requested, but OpenSSL loaded something else\n";
                    return NULL;
                }

                sig = rr->addSignature(
                		DSIGConstants::s_unicodeStrURIC14N_NOC,
					DSIGConstants::s_unicodeStrURIDSA_SHA1,
					DSIGConstants::s_unicodeStrURISHA1);
                // Create the XSEC OpenSSL interface
                key = new OpenSSLCryptoKeyDSA(pkey);

				const BIGNUM *otherP = NULL, *otherQ = NULL, *otherG = NULL;
				DSA_get0_pqg(EVP_PKEY_get0_DSA(pkey), &otherP, &otherQ, &otherG);
                XMLCh * P = BN2b64(otherP);
                XMLCh * Q = BN2b64(otherQ);
                XMLCh * G = BN2b64(otherG);
				const BIGNUM *otherPriv = NULL, *otherPub = NULL;
				DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &otherPub, &otherPriv);
                XMLCh * Y = BN2b64(otherPub);

                sig->appendDSAKeyValue(P,Q,G,Y);

                XSEC_RELEASE_XMLCH(P);
                XSEC_RELEASE_XMLCH(Q);
                XSEC_RELEASE_XMLCH(G);
                XSEC_RELEASE_XMLCH(Y);
            }
            else {
                if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
                    cerr << "RSA Key requested, but OpenSSL loaded something else\n";
                    exit (1);
                }
                sig = rr->addSignature(
                		DSIGConstants::s_unicodeStrURIC14N_NOC,
					DSIGConstants::s_unicodeStrURIRSA_SHA1,
					DSIGConstants::s_unicodeStrURISHA1);
                key = new OpenSSLCryptoKeyRSA(pkey);

				const BIGNUM *n=NULL, *e=NULL, *d=NULL;
				RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, &e, &d);

                XMLCh * mod = BN2b64(n);
                XMLCh * exp = BN2b64(e);

				sig->appendRSAKeyValue(mod, exp);
                XSEC_RELEASE_XMLCH(mod);
                XSEC_RELEASE_XMLCH(exp);

            }

            sig->setSigningKey(key);
            sig->sign();

            EVP_PKEY_free(pkey);
            BIO_free(bioKey);

            paramCount += 3;

            
        } /* argv[1] = "sign dsa/rsa" */
        else if (_stricmp(argv[paramCount], "--add-value-dsa") == 0 || _stricmp(argv[paramCount], "-vd") == 0 ||
                _stricmp(argv[paramCount], "--add-value-rsa") == 0 || _stricmp(argv[paramCount], "-vr") == 0) {
            if (paramCount >= argc + 2) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }

            // DSA or RSA OpenSSL Key
            // For now just read a particular file

            BIO * bioKey;
            if ((bioKey = BIO_new(BIO_s_file())) == NULL) {

                cerr << "Error opening private key file\n\n";
                return NULL;

            }

            if (BIO_read_filename(bioKey, argv[paramCount+1]) <= 0) {

                cerr << "Error opening private key file : " << argv[paramCount+1] << endl;
                return NULL;

            }

            EVP_PKEY * pkey;
            pkey = PEM_read_bio_PrivateKey(bioKey,NULL,NULL,argv[paramCount + 2]);

            if (pkey == NULL) {

                BIO * bio_err;
    
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
                    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
                cerr << "Error loading private key\n\n";
                ERR_print_errors(bio_err);
                return NULL;

            }

            XKMSRevokeKeyBinding * rkb = rr->getRevokeKeyBinding();
            if (rkb == NULL)
                rkb = rr->addRevokeKeyBinding(XKMSStatus::Indeterminate);


            if (_stricmp(argv[paramCount], "--add-value-dsa") == 0 || _stricmp(argv[paramCount], "-vd") == 0) {

                // Check type is correct

                if (EVP_PKEY_id(pkey) != EVP_PKEY_DSA) {
                    cerr << "DSA Key requested, but OpenSSL loaded something else\n";
                    return NULL;
                }

				const BIGNUM *otherP = NULL, *otherQ = NULL, *otherG = NULL;
				DSA_get0_pqg(EVP_PKEY_get0_DSA(pkey), &otherP, &otherQ, &otherG);
                XMLCh * P = BN2b64(otherP);
                XMLCh * Q = BN2b64(otherQ);
                XMLCh * G = BN2b64(otherG);
				const BIGNUM *otherPriv = NULL, *otherPub = NULL;
				DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &otherPub, &otherPriv);
                XMLCh * Y = BN2b64(otherPub);

                rkb->appendDSAKeyValue(P,Q,G,Y);

                XSEC_RELEASE_XMLCH(P);
                XSEC_RELEASE_XMLCH(Q);
                XSEC_RELEASE_XMLCH(G);
                XSEC_RELEASE_XMLCH(Y);
            }
            else {
                if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
                    cerr << "RSA Key requested, but OpenSSL loaded something else\n";
                    exit (1);
                }

				const BIGNUM *n=NULL, *e=NULL, *d=NULL;
				RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, &e, &d);

                XMLCh * mod = BN2b64(n);
                XMLCh * exp = BN2b64(e);

                rkb->appendRSAKeyValue(mod, exp);
                XSEC_RELEASE_XMLCH(mod);
                XSEC_RELEASE_XMLCH(exp);

            }

            EVP_PKEY_free(pkey);
            BIO_free(bioKey);

            paramCount += 3;

            
        } /* argv[1] = "value dsa/rsa" */

#endif
        else {
            printRevokeRequestUsage();
            delete rr;
            (*doc)->release();
            return NULL;
        }
    }

    return rr;
}

// --------------------------------------------------------------------------------
//           Create a ReissueRequest
// --------------------------------------------------------------------------------

void printReissueRequestUsage(void) {

    cerr << "\nUsage ReissueRequest [--help|-h] <service URI> [options]\n";
    cerr << "   --help/-h                : print this screen and exit\n\n";
    cerr << "   --add-name/-n <name>     : Add name as a KeyInfoName\n";
    cerr << "   --add-opaque/-o <data>   : Add an opaque data string\n";
    cerr << "   --add-usage-sig/-us      : Add Signature Key Usage\n";
    cerr << "   --add-usage-exc/-ux      : Add Exchange Key Usage\n";
    cerr << "   --add-usage-enc/-ue      : Add Encryption Key Usage\n";
    cerr << "   --add-usekeywith/-u <Application URI> <Identifier>\n";
    cerr << "                            : Add a UseKeyWith element\n";
    cerr << "   --add-respondwith/-r <Identifier>\n";
    cerr << "                            : Add a RespondWith element\n";
    cerr << "   --add-responsemechanism/-m <Identifier>\n";
    cerr << "                            : Add a ResponseMechanism element\n";
    cerr << "   --sign-dsa/-sd <filename> <passphrase>\n";
    cerr << "           : Sign using the DSA key in file protected by passphrase\n";
    cerr << "   --add-value-dsa/-vd <filename> <passphrase>\n";
    cerr << "           : Add the DSA key as a keyvalue (and do proof-of-possession sig)\n";
    cerr << "   --add-value-rsa/-vr <filename> <passphrase>\n";
    cerr << "           : Add the RSA key as a keyvalue (and do proof-of-possession sig)\n";
    cerr << "   --authenticate/-a <phrase>\n";
    cerr << "           : Use <phrase> as the authentication key for the request\n";
    cerr << "             NOTE - This must come *after* adding of KeyInfo elements\n\n";

}

XKMSMessageAbstractType * createReissueRequest(XSECProvider &prov, DOMDocument **doc, int argc, char ** argv, int &paramCount, XKMSCompoundRequest * cr = NULL) {

    XSECCryptoKey *proofOfPossessionKey = NULL;
    const XMLCh* proofOfPossessionSm = NULL;

    if (paramCount >= argc || 
        (_stricmp(argv[paramCount], "--help") == 0) ||
        (_stricmp(argv[paramCount], "-h") == 0)) {

        printReissueRequestUsage();
        return NULL;
    }

    /* First create the basic request */
    XKMSMessageFactory * factory = 
        prov.getXKMSMessageFactory();
    XKMSReissueRequest * rr;

    if (cr == NULL)
        rr = factory->createReissueRequest(MAKE_UNICODE_STRING(argv[paramCount++]), doc);
    else
        rr = cr->createReissueRequest(MAKE_UNICODE_STRING(argv[paramCount++]));

    while (paramCount < argc && _stricmp(argv[paramCount], "--") != 0) {

        if (_stricmp(argv[paramCount], "--add-name") == 0 || _stricmp(argv[paramCount], "-n") == 0) {
            if (++paramCount >= argc) {
                printReissueRequestUsage();
                delete rr;
                return NULL;
            }

            XKMSReissueKeyBinding * pkb = rr->getReissueKeyBinding();
            if (pkb == NULL)
                pkb = rr->addReissueKeyBinding(XKMSStatus::Indeterminate);
            pkb->appendKeyName(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-opaque") == 0 || _stricmp(argv[paramCount], "-o") == 0) {
            if (++paramCount >= argc) {
                printReissueRequestUsage();
                delete rr;
                return NULL;
            }
            rr->appendOpaqueClientDataItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-respondwith") == 0 || _stricmp(argv[paramCount], "-r") == 0) {
            if (++paramCount >= argc) {
                printReissueRequestUsage();
                delete rr;
                return NULL;
            }
            rr->appendRespondWithItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-responsemechanism") == 0 || _stricmp(argv[paramCount], "-m") == 0) {
            if (++paramCount >= argc) {
                printReissueRequestUsage();
                delete rr;
                return NULL;
            }
            rr->appendResponseMechanismItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-sig") == 0 || _stricmp(argv[paramCount], "-us") == 0) {
            XKMSReissueKeyBinding * pkb = rr->getReissueKeyBinding();
            if (pkb == NULL)
                pkb = rr->addReissueKeyBinding(XKMSStatus::Indeterminate);
            pkb->setSignatureKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-exc") == 0 || _stricmp(argv[paramCount], "-ux") == 0) {
            XKMSReissueKeyBinding * pkb = rr->getReissueKeyBinding();
            if (pkb == NULL)
                pkb = rr->addReissueKeyBinding(XKMSStatus::Indeterminate);
            pkb->setExchangeKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-enc") == 0 || _stricmp(argv[paramCount], "-ue") == 0) {
            XKMSReissueKeyBinding * pkb = rr->getReissueKeyBinding();
            if (pkb == NULL)
                pkb = rr->addReissueKeyBinding(XKMSStatus::Indeterminate);
            pkb->setEncryptionKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usekeywith") == 0 || _stricmp(argv[paramCount], "-u") == 0) {
            if (++paramCount >= argc + 1) {
                printReissueRequestUsage();
                delete rr;
                return NULL;
            }
            XKMSReissueKeyBinding *pkb = rr->getReissueKeyBinding();
            if (pkb == NULL)
                pkb = rr->addReissueKeyBinding(XKMSStatus::Indeterminate);

            pkb->appendUseKeyWithItem(MAKE_UNICODE_STRING(argv[paramCount]), MAKE_UNICODE_STRING(argv[paramCount + 1]));
            paramCount += 2;
        }
        else if (_stricmp(argv[paramCount], "--authenticate") == 0 || _stricmp(argv[paramCount], "-a") == 0) {
            if (++paramCount >= argc + 1) {
                printReissueRequestUsage();
                delete rr;
                return NULL;
            }

            // Create the signature

            unsigned char keyBuf[XSEC_MAX_HASH_SIZE];
            int len = CalculateXKMSAuthenticationKey((unsigned char *) argv[paramCount], (int) strlen(argv[paramCount]), keyBuf, XSEC_MAX_HASH_SIZE);
            if (len <= 0) {
                cout << "Error creating key from pass phrase" << endl;
                delete rr;
                return NULL;
            }

            XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
            k->setKey(keyBuf, len);

            // Set key and validate
            XKMSAuthentication * a = rr->addAuthentication();
            DSIGSignature * sig = a->addKeyBindingAuthenticationSignature(
            		DSIGConstants::s_unicodeStrURIC14N_NOC,
				DSIGConstants::s_unicodeStrURIHMAC_SHA1,
				DSIGConstants::s_unicodeStrURISHA1);

            sig->setSigningKey(k);
            sig->sign();

            paramCount++;

        }
#if defined (XSEC_HAVE_OPENSSL)
        else if (_stricmp(argv[paramCount], "--sign-dsa") == 0 || _stricmp(argv[paramCount], "-sd") == 0 ||
                _stricmp(argv[paramCount], "--sign-rsa") == 0 || _stricmp(argv[paramCount], "-sr") == 0) {
            if (paramCount >= argc + 2) {
                printReissueRequestUsage();
                delete rr;
                return NULL;
            }

            // DSA or RSA OpenSSL Key
            // For now just read a particular file

            BIO * bioKey;
            if ((bioKey = BIO_new(BIO_s_file())) == NULL) {

                cerr << "Error opening private key file\n\n";
                return NULL;

            }

            if (BIO_read_filename(bioKey, argv[paramCount+1]) <= 0) {

                cerr << "Error opening private key file : " << argv[paramCount+1] << endl;
                return NULL;

            }

            EVP_PKEY * pkey;
            pkey = PEM_read_bio_PrivateKey(bioKey,NULL,NULL,argv[paramCount + 2]);

            if (pkey == NULL) {

                BIO * bio_err;
    
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
                    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
                cerr << "Error loading private key\n\n";
                ERR_print_errors(bio_err);
                return NULL;

            }
            XSECCryptoKey *key;
            DSIGSignature * sig;
            if (_stricmp(argv[paramCount], "--sign-dsa") == 0 || _stricmp(argv[paramCount], "-sd") == 0) {

                // Check type is correct

                if (EVP_PKEY_id(pkey) != EVP_PKEY_DSA) {
                    cerr << "DSA Key requested, but OpenSSL loaded something else\n";
                    return NULL;
                }

                sig = rr->addSignature(
                		DSIGConstants::s_unicodeStrURIC14N_NOC,
					DSIGConstants::s_unicodeStrURIDSA_SHA1,
					DSIGConstants::s_unicodeStrURISHA1);
                // Create the XSEC OpenSSL interface
                key = new OpenSSLCryptoKeyDSA(pkey);

				const BIGNUM *otherP = NULL, *otherQ = NULL, *otherG = NULL;
				DSA_get0_pqg(EVP_PKEY_get0_DSA(pkey), &otherP, &otherQ, &otherG);
                XMLCh * P = BN2b64(otherP);
                XMLCh * Q = BN2b64(otherQ);
                XMLCh * G = BN2b64(otherG);
				const BIGNUM *otherPriv = NULL, *otherPub = NULL;
				DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &otherPub, &otherPriv);
                XMLCh * Y = BN2b64(otherPub);

                sig->appendDSAKeyValue(P,Q,G,Y);

                XSEC_RELEASE_XMLCH(P);
                XSEC_RELEASE_XMLCH(Q);
                XSEC_RELEASE_XMLCH(G);
                XSEC_RELEASE_XMLCH(Y);
            }
            else {
                if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
                    cerr << "RSA Key requested, but OpenSSL loaded something else\n";
                    exit (1);
                }
                sig = rr->addSignature(
                		DSIGConstants::s_unicodeStrURIC14N_NOC,
					DSIGConstants::s_unicodeStrURIRSA_SHA1,
					DSIGConstants::s_unicodeStrURISHA1);
                key = new OpenSSLCryptoKeyRSA(pkey);

				const BIGNUM *n=NULL, *e=NULL, *d=NULL;
				RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, &e, &d);

                XMLCh * mod = BN2b64(n);
                XMLCh * exp = BN2b64(e);

				sig->appendRSAKeyValue(mod, exp);
                XSEC_RELEASE_XMLCH(mod);
                XSEC_RELEASE_XMLCH(exp);

            }

            sig->setSigningKey(key);
            sig->sign();

            EVP_PKEY_free(pkey);
            BIO_free(bioKey);

            paramCount += 3;

            
        } /* argv[1] = "sign dsa/rsa" */
        else if (_stricmp(argv[paramCount], "--add-value-dsa") == 0 || _stricmp(argv[paramCount], "-vd") == 0 ||
                _stricmp(argv[paramCount], "--add-value-rsa") == 0 || _stricmp(argv[paramCount], "-vr") == 0) {
            if (paramCount >= argc + 2) {
                printReissueRequestUsage();
                delete rr;
                return NULL;
            }

            // DSA or RSA OpenSSL Key
            // For now just read a particular file

            BIO * bioKey;
            if ((bioKey = BIO_new(BIO_s_file())) == NULL) {

                cerr << "Error opening private key file\n\n";
                return NULL;

            }

            if (BIO_read_filename(bioKey, argv[paramCount+1]) <= 0) {

                cerr << "Error opening private key file : " << argv[paramCount+1] << endl;
                return NULL;

            }

            EVP_PKEY * pkey;
            pkey = PEM_read_bio_PrivateKey(bioKey,NULL,NULL,argv[paramCount + 2]);

            if (pkey == NULL) {

                BIO * bio_err;
    
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
                    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
                cerr << "Error loading private key\n\n";
                ERR_print_errors(bio_err);
                return NULL;

            }

            XKMSReissueKeyBinding * pkb = rr->getReissueKeyBinding();
            if (pkb == NULL)
                pkb = rr->addReissueKeyBinding(XKMSStatus::Indeterminate);


            if (_stricmp(argv[paramCount], "--add-value-dsa") == 0 || _stricmp(argv[paramCount], "-vd") == 0) {

                // Check type is correct

                if (EVP_PKEY_id(pkey) != EVP_PKEY_DSA) {
                    cerr << "DSA Key requested, but OpenSSL loaded something else\n";
                    return NULL;
                }

                proofOfPossessionKey = new OpenSSLCryptoKeyDSA(pkey);
                proofOfPossessionSm = DSIGConstants::s_unicodeStrURIDSA_SHA1;

				const BIGNUM *otherP = NULL, *otherQ = NULL, *otherG = NULL;
				DSA_get0_pqg(EVP_PKEY_get0_DSA(pkey), &otherP, &otherQ, &otherG);
                XMLCh * P = BN2b64(otherP);
                XMLCh * Q = BN2b64(otherQ);
                XMLCh * G = BN2b64(otherG);
				const BIGNUM *otherPriv = NULL, *otherPub = NULL;
				DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &otherPub, &otherPriv);
                XMLCh * Y = BN2b64(otherPub);

                pkb->appendDSAKeyValue(P,Q,G,Y);

                XSEC_RELEASE_XMLCH(P);
                XSEC_RELEASE_XMLCH(Q);
                XSEC_RELEASE_XMLCH(G);
                XSEC_RELEASE_XMLCH(Y);
            }
            else {
                if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
                    cerr << "RSA Key requested, but OpenSSL loaded something else\n";
                    exit (1);
                }

                proofOfPossessionKey = new OpenSSLCryptoKeyRSA(pkey);
                proofOfPossessionSm = DSIGConstants::s_unicodeStrURIRSA_SHA1;

				const BIGNUM *n=NULL, *e=NULL, *d=NULL;
				RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, &e, &d);

                XMLCh * mod = BN2b64(n);
                XMLCh * exp = BN2b64(e);

				pkb->appendRSAKeyValue(mod, exp);
                XSEC_RELEASE_XMLCH(mod);
                XSEC_RELEASE_XMLCH(exp);

            }

            EVP_PKEY_free(pkey);
            BIO_free(bioKey);

            paramCount += 3;

            
        } /* argv[1] = "value dsa/rsa" */

#endif
        else {
            printReissueRequestUsage();
            delete rr;
            (*doc)->release();
            return NULL;
        }
    }

    if (proofOfPossessionKey != NULL) {

        // Set up the proof of possession
        DSIGSignature * s = 
            rr->addProofOfPossessionSignature(
            			DSIGConstants::s_unicodeStrURIC14N_NOC,
            			proofOfPossessionSm,
					DSIGConstants::s_unicodeStrURISHA1);

        s->setSigningKey(proofOfPossessionKey);
        s->sign();

    }

    return rr;
}

// --------------------------------------------------------------------------------
//           Create a RecoverRequest
// --------------------------------------------------------------------------------

void printRecoverRequestUsage(void) {

    cerr << "\nUsage RecoverRequest [--help|-h] <service URI> [options]\n";
    cerr << "   --help/-h                : print this screen and exit\n\n";
    cerr << "   --add-name/-n <name>     : Add name as a KeyInfoName\n";
    cerr << "   --add-opaque/-o <data>   : Add an opaque data string\n";
    cerr << "   --add-usage-sig/-us      : Add Signature Key Usage\n";
    cerr << "   --add-usage-exc/-ux      : Add Exchange Key Usage\n";
    cerr << "   --add-usage-enc/-ue      : Add Encryption Key Usage\n";
    cerr << "   --add-usekeywith/-u <Application URI> <Identifier>\n";
    cerr << "                            : Add a UseKeyWith element\n";
    cerr << "   --add-respondwith/-r <Identifier>\n";
    cerr << "                            : Add a RespondWith element\n";
    cerr << "   --add-responsemechanism/-m <Identifier>\n";
    cerr << "                            : Add a ResponseMechanism element\n";
    cerr << "   --sign-dsa/-sd <filename> <passphrase>\n";
    cerr << "           : Sign using the DSA key in file protected by passphrase\n";
    cerr << "   --add-value-dsa/-vd <filename> <passphrase>\n";
    cerr << "           : Add the DSA key as a keyvalue\n";
    cerr << "   --add-value-rsa/-vr <filename> <passphrase>\n";
    cerr << "           : Add the RSA key as a keyvalue\n";
    cerr << "   --kek/-k <phrase>        : Key phrase to use for PrivateKey decryption\n";
#if defined (XSEC_HAVE_OPENSSL)
    cerr << "   --output-private-key/-p <file> <pass phrase>\n";
    cerr << "                            : Write PEM encoded private key to file\n";
#endif  
    cerr << "   --authenticate/-a <phrase>\n";
    cerr << "           : Use <phrase> as the authentication key for the request\n";
    cerr << "             NOTE - This must come *after* adding of KeyInfo elements\n\n";

}

XKMSMessageAbstractType * createRecoverRequest(XSECProvider &prov, DOMDocument **doc, int argc, char ** argv, int &paramCount, XKMSCompoundRequest * cr = NULL) {

    if (paramCount >= argc || 
        (_stricmp(argv[paramCount], "--help") == 0) ||
        (_stricmp(argv[paramCount], "-h") == 0)) {

        printRegisterRequestUsage();
        return NULL;
    }

    /* First create the basic request */
    XKMSMessageFactory * factory = 
        prov.getXKMSMessageFactory();
    XKMSRecoverRequest * rr;

    if (cr == NULL)
        rr = factory->createRecoverRequest(MAKE_UNICODE_STRING(argv[paramCount++]), doc);
    else
        rr = cr->createRecoverRequest(MAKE_UNICODE_STRING(argv[paramCount++]));

    while (paramCount < argc && _stricmp(argv[paramCount], "--") != 0) {

        if (_stricmp(argv[paramCount], "--add-name") == 0 || _stricmp(argv[paramCount], "-n") == 0) {
            if (++paramCount >= argc) {
                printRecoverRequestUsage();
                delete rr;
                return NULL;
            }

            XKMSRecoverKeyBinding * rkb = rr->getRecoverKeyBinding();
            if (rkb == NULL)
                rkb = rr->addRecoverKeyBinding(XKMSStatus::Indeterminate);
            rkb->appendKeyName(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-opaque") == 0 || _stricmp(argv[paramCount], "-o") == 0) {
            if (++paramCount >= argc) {
                printRecoverRequestUsage();
                delete rr;
                return NULL;
            }
            rr->appendOpaqueClientDataItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-respondwith") == 0 || _stricmp(argv[paramCount], "-r") == 0) {
            if (++paramCount >= argc) {
                printRecoverRequestUsage();
                delete rr;
                return NULL;
            }
            rr->appendRespondWithItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-responsemechanism") == 0 || _stricmp(argv[paramCount], "-m") == 0) {
            if (++paramCount >= argc) {
                printRecoverRequestUsage();
                delete rr;
                return NULL;
            }
            rr->appendResponseMechanismItem(MAKE_UNICODE_STRING(argv[paramCount]));
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-sig") == 0 || _stricmp(argv[paramCount], "-us") == 0) {
            XKMSRecoverKeyBinding * rkb = rr->getRecoverKeyBinding();
            if (rkb == NULL)
                rkb = rr->addRecoverKeyBinding(XKMSStatus::Indeterminate);
            rkb->setSignatureKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-exc") == 0 || _stricmp(argv[paramCount], "-ux") == 0) {
            XKMSRecoverKeyBinding * rkb = rr->getRecoverKeyBinding();
            if (rkb == NULL)
                rkb = rr->addRecoverKeyBinding(XKMSStatus::Indeterminate);
            rkb->setExchangeKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usage-enc") == 0 || _stricmp(argv[paramCount], "-ue") == 0) {
            XKMSRecoverKeyBinding * rkb = rr->getRecoverKeyBinding();
            if (rkb == NULL)
                rkb = rr->addRecoverKeyBinding(XKMSStatus::Indeterminate);
            rkb->setEncryptionKeyUsage();
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "--add-usekeywith") == 0 || _stricmp(argv[paramCount], "-u") == 0) {
            if (++paramCount >= argc + 1) {
                printRecoverRequestUsage();
                delete rr;
                return NULL;
            }
            XKMSRecoverKeyBinding *rkb = rr->getRecoverKeyBinding();
            if (rkb == NULL)
                rkb = rr->addRecoverKeyBinding(XKMSStatus::Indeterminate);

            rkb->appendUseKeyWithItem(MAKE_UNICODE_STRING(argv[paramCount]), MAKE_UNICODE_STRING(argv[paramCount + 1]));
            paramCount += 2;
        }
        else if (_stricmp(argv[paramCount], "--kek") == 0 || _stricmp(argv[paramCount], "-k") == 0) {
            if (++paramCount >= argc) {
                printRecoverRequestUsage();
                delete rr;
                return NULL;
            }
            g_authPassPhrase = argv[paramCount++];
        }
#if defined (XSEC_HAVE_OPENSSL)
        else if (_stricmp(argv[paramCount], "--output-private-key") == 0 || _stricmp(argv[paramCount], "-p") == 0) {
            if (paramCount >= argc + 2) {
                printRecoverRequestUsage();
                delete rr;
                return NULL;
            }
            ++paramCount;
            g_privateKeyFile = argv[paramCount++];
            g_privateKeyPassPhrase = argv[paramCount++];
        }
#endif      
        else if (_stricmp(argv[paramCount], "--authenticate") == 0 || _stricmp(argv[paramCount], "-a") == 0) {
            if (++paramCount >= argc + 1) {
                printRecoverRequestUsage();
                delete rr;
                return NULL;
            }

            // Create the signature

            unsigned char keyBuf[XSEC_MAX_HASH_SIZE];
            int len = CalculateXKMSAuthenticationKey((unsigned char *) argv[paramCount], (int) strlen(argv[paramCount]), keyBuf, XSEC_MAX_HASH_SIZE);
            if (len <= 0) {
                cout << "Error creating key from pass phrase" << endl;
                delete rr;
                return NULL;
            }

            XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
            k->setKey(keyBuf, len);

            // Set key and validate
            XKMSAuthentication * a = rr->addAuthentication();
            DSIGSignature * sig = a->addKeyBindingAuthenticationSignature(
            		DSIGConstants::s_unicodeStrURIC14N_NOC,
            		DSIGConstants::s_unicodeStrURIHMAC_SHA1,
				DSIGConstants::s_unicodeStrURISHA1);

            sig->setSigningKey(k);
            sig->sign();

            paramCount++;

        }
#if defined (XSEC_HAVE_OPENSSL)
        else if (_stricmp(argv[paramCount], "--sign-dsa") == 0 || _stricmp(argv[paramCount], "-sd") == 0 ||
                _stricmp(argv[paramCount], "--sign-rsa") == 0 || _stricmp(argv[paramCount], "-sr") == 0) {
            if (paramCount >= argc + 2) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }

            // DSA or RSA OpenSSL Key
            // For now just read a particular file

            BIO * bioKey;
            if ((bioKey = BIO_new(BIO_s_file())) == NULL) {

                cerr << "Error opening private key file\n\n";
                return NULL;

            }

            if (BIO_read_filename(bioKey, argv[paramCount+1]) <= 0) {

                cerr << "Error opening private key file : " << argv[paramCount+1] << endl;
                return NULL;

            }

            EVP_PKEY * pkey;
            pkey = PEM_read_bio_PrivateKey(bioKey,NULL,NULL,argv[paramCount + 2]);

            if (pkey == NULL) {

                BIO * bio_err;
    
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
                    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
                cerr << "Error loading private key\n\n";
                ERR_print_errors(bio_err);
                return NULL;

            }
            XSECCryptoKey *key;
            DSIGSignature * sig;
            if (_stricmp(argv[paramCount], "--sign-dsa") == 0 || _stricmp(argv[paramCount], "-sd") == 0) {

                // Check type is correct

                if (EVP_PKEY_id(pkey) != EVP_PKEY_DSA) {
                    cerr << "DSA Key requested, but OpenSSL loaded something else\n";
                    return NULL;
                }

                sig = rr->addSignature(
                				DSIGConstants::s_unicodeStrURIC14N_NOC,
							DSIGConstants::s_unicodeStrURIDSA_SHA1,
							DSIGConstants::s_unicodeStrURISHA1);
                // Create the XSEC OpenSSL interface
                key = new OpenSSLCryptoKeyDSA(pkey);

				const BIGNUM *otherP = NULL, *otherQ = NULL, *otherG = NULL;
				DSA_get0_pqg(EVP_PKEY_get0_DSA(pkey), &otherP, &otherQ, &otherG);
                XMLCh * P = BN2b64(otherP);
                XMLCh * Q = BN2b64(otherQ);
                XMLCh * G = BN2b64(otherG);
				const BIGNUM *otherPriv = NULL, *otherPub = NULL;
				DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &otherPub, &otherPriv);
                XMLCh * Y = BN2b64(otherPub);

                sig->appendDSAKeyValue(P,Q,G,Y);

                XSEC_RELEASE_XMLCH(P);
                XSEC_RELEASE_XMLCH(Q);
                XSEC_RELEASE_XMLCH(G);
                XSEC_RELEASE_XMLCH(Y);
            }
            else {
                if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
                    cerr << "RSA Key requested, but OpenSSL loaded something else\n";
                    exit (1);
                }
                sig = rr->addSignature(
                			DSIGConstants::s_unicodeStrURIC14N_NOC,
						DSIGConstants::s_unicodeStrURIRSA_SHA1,
						DSIGConstants::s_unicodeStrURISHA1);
                key = new OpenSSLCryptoKeyRSA(pkey);

				const BIGNUM *n=NULL, *e=NULL, *d=NULL;
				RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, &e, &d);

                XMLCh * mod = BN2b64(n);
                XMLCh * exp = BN2b64(e);

                sig->appendRSAKeyValue(mod, exp);
                XSEC_RELEASE_XMLCH(mod);
                XSEC_RELEASE_XMLCH(exp);

            }

            sig->setSigningKey(key);
            sig->sign();

            EVP_PKEY_free(pkey);
            BIO_free(bioKey);

            paramCount += 3;

            
        } /* argv[1] = "sign dsa/rsa" */
        else if (_stricmp(argv[paramCount], "--add-value-dsa") == 0 || _stricmp(argv[paramCount], "-vd") == 0 ||
                _stricmp(argv[paramCount], "--add-value-rsa") == 0 || _stricmp(argv[paramCount], "-vr") == 0) {
            if (paramCount >= argc + 2) {
                printRegisterRequestUsage();
                delete rr;
                return NULL;
            }

            // DSA or RSA OpenSSL Key
            // For now just read a particular file

            BIO * bioKey;
            if ((bioKey = BIO_new(BIO_s_file())) == NULL) {

                cerr << "Error opening private key file\n\n";
                return NULL;

            }

            if (BIO_read_filename(bioKey, argv[paramCount+1]) <= 0) {

                cerr << "Error opening private key file : " << argv[paramCount+1] << endl;
                return NULL;

            }

            EVP_PKEY * pkey;
            pkey = PEM_read_bio_PrivateKey(bioKey,NULL,NULL,argv[paramCount + 2]);

            if (pkey == NULL) {

                BIO * bio_err;
    
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
                    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
                cerr << "Error loading private key\n\n";
                ERR_print_errors(bio_err);
                return NULL;

            }

            XKMSRecoverKeyBinding * rkb = rr->getRecoverKeyBinding();
            if (rkb == NULL)
                rkb = rr->addRecoverKeyBinding(XKMSStatus::Indeterminate);


            if (_stricmp(argv[paramCount], "--add-value-dsa") == 0 || _stricmp(argv[paramCount], "-vd") == 0) {

                // Check type is correct

                if (EVP_PKEY_id(pkey) != EVP_PKEY_DSA) {
                    cerr << "DSA Key requested, but OpenSSL loaded something else\n";
                    return NULL;
                }

				const BIGNUM *otherP = NULL, *otherQ = NULL, *otherG = NULL;
				DSA_get0_pqg(EVP_PKEY_get0_DSA(pkey), &otherP, &otherQ, &otherG);
                XMLCh * P = BN2b64(otherP);
                XMLCh * Q = BN2b64(otherQ);
                XMLCh * G = BN2b64(otherG);
				const BIGNUM *otherPriv = NULL, *otherPub = NULL;
				DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &otherPub, &otherPriv);
                XMLCh * Y = BN2b64(otherPub);

                rkb->appendDSAKeyValue(P,Q,G,Y);

                XSEC_RELEASE_XMLCH(P);
                XSEC_RELEASE_XMLCH(Q);
                XSEC_RELEASE_XMLCH(G);
                XSEC_RELEASE_XMLCH(Y);
            }
            else {
                if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
                    cerr << "RSA Key requested, but OpenSSL loaded something else\n";
                    exit (1);
                }

				const BIGNUM *n=NULL, *e=NULL, *d=NULL;
				RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, &e, &d);

                XMLCh * mod = BN2b64(n);
                XMLCh * exp = BN2b64(e);

				rkb->appendRSAKeyValue(mod, exp);
                XSEC_RELEASE_XMLCH(mod);
                XSEC_RELEASE_XMLCH(exp);

            }

            EVP_PKEY_free(pkey);
            BIO_free(bioKey);

            paramCount += 3;

            
        } /* argv[1] = "value dsa/rsa" */

#endif
        else {
            printRecoverRequestUsage();
            delete rr;
            (*doc)->release();
            return NULL;
        }
    }

    return rr;
}

// --------------------------------------------------------------------------------
//           Create a PendingRequest
// --------------------------------------------------------------------------------

void printPendingRequestUsage(void) {

    cerr << "\nUsage PendingRequest [--help|-h] <service URI> [options]\n";
    cerr << "   --help/-h                : print this screen and exit\n";
    cerr << "   --original-request-id/-o <id>\n";
    cerr << "                            : Set original request ID\n";
    cerr << "   --response-id/-r <id>\n";
    cerr << "                            : Set Response ID\n\n";

}

XKMSMessageAbstractType * createPendingRequest(XSECProvider &prov, DOMDocument **doc, int argc, char ** argv, int paramCount) {

    if (paramCount  >= argc || 
        (_stricmp(argv[paramCount], "--help") == 0) ||
        (_stricmp(argv[paramCount], "-h") == 0)) {

        printPendingRequestUsage();
        return NULL;
    }

    /* First create the basic request */
    XKMSMessageFactory * factory = 
        prov.getXKMSMessageFactory();
    XKMSPendingRequest * pr = 
        factory->createPendingRequest(MAKE_UNICODE_STRING(argv[paramCount++]), doc);

    while (paramCount < argc && _stricmp(argv[paramCount], "--") != 0) {

        if (_stricmp(argv[paramCount], "--original-request-id") == 0 || _stricmp(argv[paramCount], "-o") == 0) {
            if (++paramCount >= argc) {
                printPendingRequestUsage();
                delete pr;
                return NULL;
            }

            pr->setOriginalRequestId(MAKE_UNICODE_STRING(argv[paramCount++]));
        }
        else if (_stricmp(argv[paramCount], "--response-id") == 0 || _stricmp(argv[paramCount], "-r") == 0) {
            if (++paramCount >= argc) {
                printPendingRequestUsage();
                delete pr;
                return NULL;
            }
            pr->setResponseId(MAKE_UNICODE_STRING(argv[paramCount++]));
        }
        else {
            printPendingRequestUsage();
            delete pr;
            return NULL;
        }
    }

    return pr;
}

// --------------------------------------------------------------------------------
//           Create a StatusRequest
// --------------------------------------------------------------------------------

void printStatusRequestUsage(void) {

    cerr << "\nUsage StatusRequest [--help|-h] <service URI> [options]\n";
    cerr << "   --help/-h                : print this screen and exit\n";
    cerr << "   --original-request-id/-o <id>\n";
    cerr << "                            : Set original request ID\n";
    cerr << "   --response-id/-r <id>\n";
    cerr << "                            : Set Response ID\n\n";

}

XKMSMessageAbstractType * createStatusRequest(XSECProvider &prov, DOMDocument **doc, int argc, char ** argv, int paramCount) {

    if (paramCount  >= argc || 
        (_stricmp(argv[paramCount], "--help") == 0) ||
        (_stricmp(argv[paramCount], "-h") == 0)) {

        printStatusRequestUsage();
        return NULL;
    }

    /* First create the basic request */
    XKMSMessageFactory * factory = 
        prov.getXKMSMessageFactory();
    XKMSStatusRequest * sr = 
        factory->createStatusRequest(MAKE_UNICODE_STRING(argv[paramCount++]), doc);

    while (paramCount < argc && _stricmp(argv[paramCount], "--") != 0) {

        if (_stricmp(argv[paramCount], "--original-request-id") == 0 || _stricmp(argv[paramCount], "-o") == 0) {
            if (++paramCount >= argc) {
                printStatusRequestUsage();
                delete sr;
                return NULL;
            }

            sr->setOriginalRequestId(MAKE_UNICODE_STRING(argv[paramCount++]));
        }
        else if (_stricmp(argv[paramCount], "--response-id") == 0 || _stricmp(argv[paramCount], "-r") == 0) {
            if (++paramCount >= argc) {
                printStatusRequestUsage();
                delete sr;
                return NULL;
            }
            sr->setResponseId(MAKE_UNICODE_STRING(argv[paramCount++]));
        }
        else {
            printStatusRequestUsage();
            delete sr;
            return NULL;
        }
    }

    return sr;
}

// --------------------------------------------------------------------------------
//           Create a CompoundRequest
// --------------------------------------------------------------------------------

void printCompoundRequestUsage(void) {

    cerr << "\nUsage CompoundRequest [--help|-h] <service URI> <LocateRequest|ValidateRequest> .... [-- LocateRequest|ValidateRequest|PendingRequest]*\n";
    cerr << "   --help/-h                : print this screen and exit\n\n";

}

XKMSMessageAbstractType * createCompoundRequest(XSECProvider &prov, DOMDocument **doc, int argc, char ** argv, int paramCount) {

    if (paramCount >= argc || 
        (_stricmp(argv[paramCount], "--help") == 0) ||
        (_stricmp(argv[paramCount], "-h") == 0)) {

        printCompoundRequestUsage();
        return NULL;
    }

    /* First create the basic request */
    XKMSMessageFactory * factory = 
        prov.getXKMSMessageFactory();
    XKMSCompoundRequest * cr = 
        factory->createCompoundRequest(MAKE_UNICODE_STRING(argv[paramCount++]), doc);

    while (paramCount < argc) {

        if ((_stricmp(argv[paramCount], "LocateRequest") == 0) ||
            (_stricmp(argv[paramCount], "lr") == 0)) {

            paramCount++;
            XKMSLocateRequest * r = 
                (XKMSLocateRequest *) (createLocateRequest(prov, NULL, argc, argv, paramCount, cr));

            if (r == NULL) {
                delete cr;
                return NULL;
            }

        }
        else if ((_stricmp(argv[paramCount], "ValidateRequest") == 0) ||
            (_stricmp(argv[paramCount], "vr") == 0)) {

            paramCount++;
            XKMSValidateRequest * r = 
                (XKMSValidateRequest *) (createValidateRequest(prov, NULL, argc, argv, paramCount, cr));

            if (r == NULL) {
                delete cr;
                return NULL;
            }
        }

        else {
            printCompoundRequestUsage();
            delete cr;
            (*doc)->release();
            return NULL;
        }

        if (paramCount < argc && _stricmp(argv[paramCount], "--") == 0)
            paramCount++;
    }

    return cr;
}

// --------------------------------------------------------------------------------
//           MsgDump
// --------------------------------------------------------------------------------

void doMessageAbstractTypeDump(XKMSMessageAbstractType *msg, unsigned int level) {

    cout << endl;
    levelSet(level);
    cout << "Base message information : " << endl << endl;

    char * s = XMLString::transcode(msg->getId());
    levelSet(level);
    cout << "Id = " << s << endl;
    XSEC_RELEASE_XMLCH(s);

    s = XMLString::transcode(msg->getService());
    levelSet(level);
    cout << "Service URI = " << s << endl;
    XSEC_RELEASE_XMLCH(s);

    s = XMLString::transcode(msg->getNonce());
    levelSet(level);
    if (s != NULL) {
        cout << "Nonce = " << s << endl;
        XSEC_RELEASE_XMLCH(s);
    }
    else
        cout << "Nonce = <NONE SET>" << endl;

    /* Check for OpaqueClientData */
    if (msg->getOpaqueClientDataSize() > 0) {
        levelSet(level);
        cout << "Opaque Client Data found : " << endl;
        for (int i = 0; i < msg->getOpaqueClientDataSize(); ++i) {
            s = XMLString::transcode(msg->getOpaqueClientDataItemStr(i));
            if (s != NULL) {
                levelSet(level + 1);
                cout << i << " : " << s << endl;
                XSEC_RELEASE_XMLCH(s);
            }
        }
    }
}

void doRequestAbstractTypeDump(XKMSRequestAbstractType *msg, unsigned int level) {

    levelSet(level);
    int i = msg->getRespondWithSize();

    cout << "Request message has " << i << " RespondWith elements" << endl << endl;

    for (int j = 0; j < i; ++j) {
        levelSet(level +1);
        char * s = XMLString::transcode(msg->getRespondWithItemStr(j));
        cout << "Item " << j+1 << " : " << s << endl;
        XSEC_RELEASE_XMLCH(s);
    }
    
}

void doResultTypeDump(XKMSResultType *msg, unsigned int level) {

    const XMLCh * rid = msg->getRequestId();
    char * s;

    if (rid != NULL) {
        levelSet(level);
        cout << "Result is in response to MsgID : ";
        s = XMLString::transcode(rid);
        cout << s << endl;
        XSEC_RELEASE_XMLCH(s);
    }

    levelSet(level);
    cout << "Result Major code = ";
    s = XMLString::transcode(XKMSConstants::s_tagResultMajorCodes[msg->getResultMajor()]);
    cout << s << endl;
    XSEC_RELEASE_XMLCH(s);

    XKMSResultType::ResultMinor rm = msg->getResultMinor();
    if (rm != XKMSResultType::NoneMinor) {
        levelSet(level);
        cout << "Result Minor code = ";
        char * s = XMLString::transcode(XKMSConstants::s_tagResultMinorCodes[rm]);
        cout << s << endl;
        XSEC_RELEASE_XMLCH(s);
    }

    rid = msg->getRequestSignatureValue();
    if (rid != NULL) {
        levelSet(level);
        cout << "RequestSignatureValue = ";
        s = XMLString::transcode(rid);
        cout << s << endl;
        XSEC_RELEASE_XMLCH(s);
    }
}

void doKeyInfoDump(DSIGKeyInfoList * l, unsigned int level) {


    int size = (int) l->getSize();

    for (int i = 0 ; i < size ; ++ i) {

        DSIGKeyInfoValue * kiv;
        DSIGKeyInfoName * kn;
        char * b;

        DSIGKeyInfo * ki = l->item(i);

        switch (ki->getKeyInfoType()) {

        case DSIGKeyInfo::KEYINFO_VALUE_RSA :

            kiv = (DSIGKeyInfoValue *) ki;
            levelSet(level);
            cout << "RSA Key Value" << endl;

            levelSet(level+1);
            b = XMLString::transcode(kiv->getRSAExponent());
            cout << "Base64 encoded exponent = " << b << endl;
            delete[] b;

            levelSet(level+1);
            b = XMLString::transcode(kiv->getRSAModulus());
            cout << "Base64 encoded modulus  = " << b << endl;
            delete[] b;

            break;

        case DSIGKeyInfo::KEYINFO_VALUE_DSA :

            kiv = (DSIGKeyInfoValue *) ki;
            levelSet(level);
            cout << "DSA Key Value" << endl;

            levelSet(level+1);
            b = XMLString::transcode(kiv->getDSAG());
            cout << "G = " << b << endl;
            delete[] b;

            levelSet(level+1);
            b = XMLString::transcode(kiv->getDSAP());
            cout << "P = " << b << endl;
            delete[] b;

            levelSet(level+1);
            b = XMLString::transcode(kiv->getDSAQ());
            cout << "Q = " << b << endl;
            delete[] b;

            levelSet(level+1);
            b = XMLString::transcode(kiv->getDSAY());
            cout << "Y = " << b << endl;
            delete[] b;

            break;

        case DSIGKeyInfo::KEYINFO_NAME :

            kn = (DSIGKeyInfoName *) ki;
            levelSet(level);
            cout << "Key Name" << endl;

            levelSet(level+1);
            b = XMLString::transcode(kn->getKeyName());
            cout << "Name = " << b << endl;
            delete[] b;

            break;

        default:

            levelSet(level);
            cout << "Unknown KeyInfo type" << endl;

        }

    }
}


void doKeyBindingAbstractDump(XKMSKeyBindingAbstractType * msg, unsigned int level) {

    levelSet(level);
    cout << "Key Binding found." << endl;

    levelSet(level+1);
    cout << "KeyUsage Encryption : ";
    if (msg->getEncryptionKeyUsage())
        cout << "yes" << endl;
    else
        cout << "no" << endl;

    levelSet(level+1);
    cout << "KeyUsage Exchange   : ";
    if (msg->getExchangeKeyUsage())
        cout << "yes" << endl;
    else
        cout << "no" << endl;

    levelSet(level+1);
    cout << "KeyUsage Signature  : ";
    if (msg->getSignatureKeyUsage())
        cout << "yes" << endl;
    else
        cout << "no" << endl;

    int n = msg->getUseKeyWithSize();
    levelSet(level+1);
    if (n == 0) {
        cout << "No UseKeyWith items found" << endl;
    }
    else {
        cout << "UseKeyWith items : \n";
    }

    for (int i = 0; i < msg->getUseKeyWithSize() ; ++i) {

        XKMSUseKeyWith * ukw = msg->getUseKeyWithItem(i);
        levelSet(level+2);
        char * a = XMLString::transcode(ukw->getApplication());
        char * id = XMLString::transcode(ukw->getIdentifier());
        cout << "Application : \"" << a << "\"\n";
        levelSet(level+2);
        cout << "Identifier  : \"" << id << "\"" << endl;
        XSEC_RELEASE_XMLCH(a);
        XSEC_RELEASE_XMLCH(id);

    }

    // Now dump any KeyInfo
    levelSet(level+1);
    cout << "KeyInfo information:" << endl << endl;

    doKeyInfoDump(msg->getKeyInfoList(), level + 2);

}

void doUnverifiedKeyBindingDump(XKMSUnverifiedKeyBinding * ukb, unsigned int level) {

    doKeyBindingAbstractDump((XKMSKeyBindingAbstractType *) ukb, level);

}

void doStatusReasonDump(XKMSStatus::StatusValue v, XKMSStatus *s, int level) {

    char * sr = XMLString::transcode(XKMSConstants::s_tagStatusValueCodes[v]);
    for (XKMSStatus::StatusReason i = XKMSStatus::Signature; i > XKMSStatus::ReasonUndefined; i = (XKMSStatus::StatusReason) (i-1)) {

        if (s->getStatusReason(v, i)) {
            levelSet(level);
            char * rc = XMLString::transcode(XKMSConstants::s_tagStatusReasonCodes[i]);
            cout << sr << "Reason = " << rc << endl;
            XSEC_RELEASE_XMLCH(rc);
        }
    }
    XSEC_RELEASE_XMLCH(sr);

}

void doKeyBindingDump(XKMSKeyBinding * kb, unsigned int level) {

    /* Dump the status */

    XKMSStatus * s = kb->getStatus();
    if (s == NULL)
        return;

    char * sr = XMLString::transcode(XKMSConstants::s_tagStatusValueCodes[s->getStatusValue()]);
    levelSet(level);
    cout << "Status = " << sr << endl;
    XSEC_RELEASE_XMLCH(sr);

    /* Dump the status reasons */
    doStatusReasonDump(XKMSStatus::Valid, s, level+1);
    doStatusReasonDump(XKMSStatus::Invalid, s, level+1);
    doStatusReasonDump(XKMSStatus::Indeterminate, s, level+1);

    /* Now the actual key */
    doKeyBindingAbstractDump((XKMSKeyBindingAbstractType *) kb, level);

}

void doRevokeKeyBindingDump(XKMSRevokeKeyBinding * kb, unsigned int level) {

    /* Dump the status */

    XKMSStatus * s = kb->getStatus();
    if (s == NULL)
        return;

    char * sr = XMLString::transcode(XKMSConstants::s_tagStatusValueCodes[s->getStatusValue()]);
    levelSet(level);
    cout << "Status = " << sr << endl;
    XSEC_RELEASE_XMLCH(sr);

    /* Dump the status reasons */
    doStatusReasonDump(XKMSStatus::Valid, s, level+1);
    doStatusReasonDump(XKMSStatus::Invalid, s, level+1);
    doStatusReasonDump(XKMSStatus::Indeterminate, s, level+1);

    /* Now the actual key */
    doKeyBindingAbstractDump((XKMSKeyBindingAbstractType *) kb, level);

}

void doRecoverKeyBindingDump(XKMSRecoverKeyBinding * kb, unsigned int level) {

    /* Dump the status */

    XKMSStatus * s = kb->getStatus();
    if (s == NULL)
        return;

    char * sr = XMLString::transcode(XKMSConstants::s_tagStatusValueCodes[s->getStatusValue()]);
    levelSet(level);
    cout << "Status = " << sr << endl;
    XSEC_RELEASE_XMLCH(sr);

    /* Dump the status reasons */
    doStatusReasonDump(XKMSStatus::Valid, s, level+1);
    doStatusReasonDump(XKMSStatus::Invalid, s, level+1);
    doStatusReasonDump(XKMSStatus::Indeterminate, s, level+1);

    /* Now the actual key */
    doKeyBindingAbstractDump((XKMSKeyBindingAbstractType *) kb, level);

}

void doReissueKeyBindingDump(XKMSReissueKeyBinding * kb, unsigned int level) {

    /* Dump the status */

    XKMSStatus * s = kb->getStatus();
    if (s == NULL)
        return;

    char * sr = XMLString::transcode(XKMSConstants::s_tagStatusValueCodes[s->getStatusValue()]);
    levelSet(level);
    cout << "Status = " << sr << endl;
    XSEC_RELEASE_XMLCH(sr);

    /* Dump the status reasons */
    doStatusReasonDump(XKMSStatus::Valid, s, level+1);
    doStatusReasonDump(XKMSStatus::Invalid, s, level+1);
    doStatusReasonDump(XKMSStatus::Indeterminate, s, level+1);

    /* Now the actual key */
    doKeyBindingAbstractDump((XKMSKeyBindingAbstractType *) kb, level);

}

void doAuthenticationDump(XKMSAuthentication *a, unsigned int level) {


    if (a == NULL)
        return;

    DSIGSignature * sig = a->getKeyBindingAuthenticationSignature();
    if (sig != NULL) {

        levelSet(level);
        cout << "KeyBindingAuthentication Signature found.  ";
        if (g_authPassPhrase == NULL) {
            cout << "Cannot check - no pass phrase set" << endl;
            return;
        }
        
        cout << "Checking.... ";

        // Create the key
        unsigned char keyBuf[XSEC_MAX_HASH_SIZE];
        int len = CalculateXKMSAuthenticationKey((unsigned char *) g_authPassPhrase, (int) strlen(g_authPassPhrase), keyBuf, XSEC_MAX_HASH_SIZE);
        if (len <= 0) {
            cout << "Error creating key from pass phrase" << endl;
            return;
        }

        XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
        k->setKey(keyBuf, len);
        //k->setKey((unsigned char *) g_authPassPhrase, strlen(g_authPassPhrase));

        // Set key and validate
        sig->setSigningKey(k);
        if (sig->verify())
            cout << "OK!" << endl;
        else 
            cout << "Signature BAD!" << endl;

    }

    return;

}

int doLocateRequestDump(XKMSLocateRequest *msg) {

    cout << endl << "This is a LocateRequest Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doRequestAbstractTypeDump(msg, level);

    XKMSQueryKeyBinding *qkb = msg->getQueryKeyBinding();
    if (qkb != NULL)
        doKeyBindingAbstractDump(qkb, level);

    return 0;
}

int doStatusRequestDump(XKMSStatusRequest *msg) {

    cout << endl << "This is a StatusRequest Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doRequestAbstractTypeDump(msg, level);

    return 0;
}

int doValidateRequestDump(XKMSValidateRequest *msg) {

    cout << endl << "This is a ValidateRequest Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doRequestAbstractTypeDump(msg, level);

    XKMSQueryKeyBinding *qkb = msg->getQueryKeyBinding();
    if (qkb != NULL)
        doKeyBindingAbstractDump(qkb, level);

    return 0;
}

int doLocateResultDump(XKMSLocateResult *msg) {

    cout << endl << "This is a LocateResult Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doResultTypeDump(msg, level);

    int j;

    if ((j = msg->getUnverifiedKeyBindingSize()) > 0) {

        cout << endl;
        levelSet(level);
        cout << "Unverified Key Bindings" << endl << endl;

        for (int i = 0; i < j ; ++i) {

            doUnverifiedKeyBindingDump(msg->getUnverifiedKeyBindingItem(i), level + 1);

        }

    }

    return 0;
}

int doValidateResultDump(XKMSValidateResult *msg) {

    cout << endl << "This is a ValidateResult Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doResultTypeDump(msg, level);

    int j;

    if ((j = msg->getKeyBindingSize()) > 0) {

        cout << endl;
        levelSet(level);
        cout << "Key Bindings" << endl << endl;

        for (int i = 0; i < j ; ++i) {

            doKeyBindingDump(msg->getKeyBindingItem(i), level + 1);

        }

    }

    return 0;
}

int doRegisterResultDump(XKMSRegisterResult *msg) {

    cout << endl << "This is a RegisterResult Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doResultTypeDump(msg, level);

    int j;

    if ((j = msg->getKeyBindingSize()) > 0) {

        cout << endl;
        levelSet(level);
        cout << "Key Bindings" << endl << endl;

        for (int i = 0; i < j ; ++i) {

            doKeyBindingDump(msg->getKeyBindingItem(i), level + 1);

        }

    }

    // Check if there is a private key
    if (g_authPassPhrase) {
        XKMSRSAKeyPair * kp = msg->getRSAKeyPair(g_authPassPhrase);
        if (kp != NULL) {
            cout << endl;
            levelSet(level);
            cout << "RSAKeyPair found" << endl << endl;
            level += 1;

            // Translate the parameters to char strings
            char * sModulus = XMLString::transcode(kp->getModulus());
            char * sExponent = XMLString::transcode(kp->getExponent());
            char * sP = XMLString::transcode(kp->getP());
            char * sQ = XMLString::transcode(kp->getQ());
            char * sDP = XMLString::transcode(kp->getDP());
            char * sDQ = XMLString::transcode(kp->getDQ());
            char * sInverseQ = XMLString::transcode(kp->getInverseQ());
            char * sD = XMLString::transcode(kp->getD());

#if defined (XSEC_HAVE_OPENSSL)

            if (g_privateKeyFile != NULL) {
                levelSet(level);
                cout << "Writing private key to file " << g_privateKeyFile;

                // Create the RSA key file
                RSA * rsa = RSA_new();

                RSA_set0_key(rsa, 
                             OpenSSLCryptoBase64::b642BN(sModulus, (unsigned int) strlen(sModulus)),
                             OpenSSLCryptoBase64::b642BN(sExponent, (unsigned int) strlen(sExponent)),
                             OpenSSLCryptoBase64::b642BN(sD, (unsigned int) strlen(sD)));
                RSA_set0_factors(rsa,
                                 OpenSSLCryptoBase64::b642BN(sP, (unsigned int) strlen(sP)),
                                 OpenSSLCryptoBase64::b642BN(sQ, (unsigned int) strlen(sQ)));

                RSA_set0_crt_params(rsa,
                                    OpenSSLCryptoBase64::b642BN(sDP, (unsigned int) strlen(sDP)), 
                                    OpenSSLCryptoBase64::b642BN(sDQ, (unsigned int) strlen(sDQ)), 
                                    OpenSSLCryptoBase64::b642BN(sInverseQ, (unsigned int) strlen(sInverseQ)));

                // Write it to disk
                BIO *out;
                out = BIO_new_file(g_privateKeyFile, "w");
                if(!out) cout << "Error occurred in opening file!" << endl << endl;
                if (!PEM_write_bio_RSAPrivateKey(out, rsa, EVP_des_ede3_cbc(), NULL, 0, 0, g_privateKeyPassPhrase)) {
                    cout << "Error creating PEM output" << endl << endl;
                }
                BIO_free(out);
                RSA_free(rsa);

                cout << " done" << endl << endl;

            }
#endif
            // Now output
            levelSet(level);
            cout << "Modulus = " << sModulus << endl;
            XSEC_RELEASE_XMLCH(sModulus);
            
            levelSet(level);
            cout << "Exponent = " << sExponent << endl;
            XSEC_RELEASE_XMLCH(sExponent);

            levelSet(level);
            cout << "P = " << sP << endl;
            XSEC_RELEASE_XMLCH(sP);

            levelSet(level);
            cout << "Q = " << sQ << endl;
            XSEC_RELEASE_XMLCH(sQ);

            levelSet(level);
            cout << "DP = " << sDP << endl;
            XSEC_RELEASE_XMLCH(sDP);

            levelSet(level);
            cout << "DQ = " << sDQ << endl;
            XSEC_RELEASE_XMLCH(sDQ);

            levelSet(level);
            cout << "Inverse Q = " << sInverseQ << endl;
            XSEC_RELEASE_XMLCH(sInverseQ);

            levelSet(level);
            cout << "D = " << sD << endl;
            XSEC_RELEASE_XMLCH(sD);
        }
    }
    else {
        levelSet(level);
        cout << "Not checking for private key as no decryption phrase set";
    }

    return 0;
}

int doRecoverResultDump(XKMSRecoverResult *msg) {

    cout << endl << "This is a RecoverResult Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doResultTypeDump(msg, level);

    int j;

    if ((j = msg->getKeyBindingSize()) > 0) {

        cout << endl;
        levelSet(level);
        cout << "Key Bindings" << endl << endl;

        for (int i = 0; i < j ; ++i) {

            doKeyBindingDump(msg->getKeyBindingItem(i), level + 1);

        }

    }

    // Check if there is a private key
    if (g_authPassPhrase) {
        XKMSRSAKeyPair * kp = msg->getRSAKeyPair(g_authPassPhrase);
        if (kp != NULL) {
            cout << endl;
            levelSet(level);
            cout << "RSAKeyPair found" << endl << endl;
            level += 1;

            // Translate the parameters to char strings
            char * sModulus = XMLString::transcode(kp->getModulus());
            char * sExponent = XMLString::transcode(kp->getExponent());
            char * sP = XMLString::transcode(kp->getP());
            char * sQ = XMLString::transcode(kp->getQ());
            char * sDP = XMLString::transcode(kp->getDP());
            char * sDQ = XMLString::transcode(kp->getDQ());
            char * sInverseQ = XMLString::transcode(kp->getInverseQ());
            char * sD = XMLString::transcode(kp->getD());

#if defined (XSEC_HAVE_OPENSSL)

            if (g_privateKeyFile != NULL) {
                levelSet(level);
                cout << "Writing private key to file " << g_privateKeyFile;

                // Create the RSA key file
                RSA * rsa = RSA_new();

                RSA_set0_key(rsa, 
                             OpenSSLCryptoBase64::b642BN(sModulus, (unsigned int) strlen(sModulus)),
                             OpenSSLCryptoBase64::b642BN(sExponent, (unsigned int) strlen(sExponent)),
                             OpenSSLCryptoBase64::b642BN(sD, (unsigned int) strlen(sD)));

                RSA_set0_factors(rsa,
                                 OpenSSLCryptoBase64::b642BN(sP, (unsigned int) strlen(sP)),
                                 OpenSSLCryptoBase64::b642BN(sQ, (unsigned int) strlen(sQ)));

                RSA_set0_crt_params(rsa,
                                    OpenSSLCryptoBase64::b642BN(sDP, (unsigned int) strlen(sDP)), 
                                    OpenSSLCryptoBase64::b642BN(sDQ, (unsigned int) strlen(sDQ)), 
                                    OpenSSLCryptoBase64::b642BN(sInverseQ, (unsigned int) strlen(sInverseQ)));

                // Write it to disk
                BIO *out;
                out = BIO_new_file(g_privateKeyFile, "w");
                if(!out) cout << "Error occurred in opening file!" << endl << endl;
                if (!PEM_write_bio_RSAPrivateKey(out, rsa, EVP_des_ede3_cbc(), NULL, 0, 0, g_privateKeyPassPhrase)) {
                    cout << "Error creating PEM output" << endl << endl;
                }
                BIO_free(out);
                RSA_free(rsa);

                cout << " done" << endl << endl;

            }
#endif
            // Now output
            levelSet(level);
            cout << "Modulus = " << sModulus << endl;
            XSEC_RELEASE_XMLCH(sModulus);
            
            levelSet(level);
            cout << "Exponent = " << sExponent << endl;
            XSEC_RELEASE_XMLCH(sExponent);

            levelSet(level);
            cout << "P = " << sP << endl;
            XSEC_RELEASE_XMLCH(sP);

            levelSet(level);
            cout << "Q = " << sQ << endl;
            XSEC_RELEASE_XMLCH(sQ);

            levelSet(level);
            cout << "DP = " << sDP << endl;
            XSEC_RELEASE_XMLCH(sDP);

            levelSet(level);
            cout << "DQ = " << sDQ << endl;
            XSEC_RELEASE_XMLCH(sDQ);

            levelSet(level);
            cout << "Inverse Q = " << sInverseQ << endl;
            XSEC_RELEASE_XMLCH(sInverseQ);

            levelSet(level);
            cout << "D = " << sD << endl;
            XSEC_RELEASE_XMLCH(sD);
        }
    }
    else {
        levelSet(level);
        cout << "Not checking for private key as no decryption phrase set";
    }

    return 0;
}

int doRevokeResultDump(XKMSRevokeResult *msg) {

    cout << endl << "This is a RevokeResult Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doResultTypeDump(msg, level);

    int j;

    if ((j = msg->getKeyBindingSize()) > 0) {

        cout << endl;
        levelSet(level);
        cout << "Key Bindings" << endl << endl;

        for (int i = 0; i < j ; ++i) {

            doKeyBindingDump(msg->getKeyBindingItem(i), level + 1);

        }

    }

    return 0;
}

int doReissueResultDump(XKMSReissueResult *msg) {

    cout << endl << "This is a ReissueResult Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doResultTypeDump(msg, level);

    int j;

    if ((j = msg->getKeyBindingSize()) > 0) {

        cout << endl;
        levelSet(level);
        cout << "Key Bindings" << endl << endl;

        for (int i = 0; i < j ; ++i) {

            doKeyBindingDump(msg->getKeyBindingItem(i), level + 1);

        }

    }

    return 0;
}

int doStatusResultDump(XKMSStatusResult *msg) {

    cout << endl << "This is a StatusResult Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doResultTypeDump(msg, level);

    return 0;
}

int doResultDump(XKMSResult *msg) {

    cout << endl << "This is a Result Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doResultTypeDump(msg, level);

    return 0;
}

int doRegisterRequestDump(XKMSRegisterRequest *msg) {

    cout << endl << "This is a RegisterRequest Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doRequestAbstractTypeDump(msg, level);

    XKMSPrototypeKeyBinding *pkb = msg->getPrototypeKeyBinding();
    if (pkb != NULL) {
        const XMLCh * rci = pkb->getRevocationCodeIdentifier();
        if (rci != NULL) {
            levelSet(1);
            char * sr = XMLString::transcode(rci);
            cout << "Revocation Code found = " << sr << endl;
            XSEC_RELEASE_XMLCH(sr);
        }

        doKeyBindingAbstractDump(pkb, level);
    }

    // Check authentication
    doAuthenticationDump(msg->getAuthentication(), level);

    // Check ProofOfPossession
    levelSet(1);
    DSIGSignature * sig = msg->getProofOfPossessionSignature();
    if (sig != NULL) {

        cout << "Proof of PossessionSignature signature found. Checking.... ";

        // Try to find the key
        XSECKeyInfoResolverDefault kir;
        XSECCryptoKey * k = kir.resolveKey(pkb->getKeyInfoList());

        if (k != NULL) {

            sig->setSigningKey(k);
            if (sig->verify())
                cout << "OK!" << endl;
            else 
                cout << "Signature Bad!" << endl;
        }
        else
            cout << "Cannot obtain key from PrototypeKeyBinding" << endl;

    }
    else {

        cout << "No ProofOfPossession Signature found" << endl;

    }

    return 0;

}

int doRevokeRequestDump(XKMSRevokeRequest *msg) {

    cout << endl << "This is a RevokeRequest Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doRequestAbstractTypeDump(msg, level);

    XKMSRevokeKeyBinding *rkb = msg->getRevokeKeyBinding();
    if (rkb != NULL) {
        doRevokeKeyBindingDump(rkb, level);
    }

    // Check authentication
    if (msg->getAuthentication())
        doAuthenticationDump(msg->getAuthentication(), level);

    if (msg->getRevocationCode()) {

        levelSet(1);
        cout << "RevocationCode found = ";
        char * sr = XMLString::transcode(msg->getRevocationCode());
        cout << sr << endl;
        XSEC_RELEASE_XMLCH(sr);
    }

    return 0;

}

int doRecoverRequestDump(XKMSRecoverRequest *msg) {

    cout << endl << "This is a RecoverRequest Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doRequestAbstractTypeDump(msg, level);

    XKMSRecoverKeyBinding *rkb = msg->getRecoverKeyBinding();
    if (rkb != NULL) {
        doRecoverKeyBindingDump(rkb, level);
    }

    // Check authentication
    if (msg->getAuthentication())
        doAuthenticationDump(msg->getAuthentication(), level);

    return 0;

}

int doReissueRequestDump(XKMSReissueRequest *msg) {

    cout << endl << "This is a ReiussueRequest Message" << endl;
    unsigned int level = 1;
    
    doMessageAbstractTypeDump(msg, level);
    doRequestAbstractTypeDump(msg, level);

    XKMSReissueKeyBinding *rkb = msg->getReissueKeyBinding();
    if (rkb != NULL) {
        doReissueKeyBindingDump(rkb, level);
    }

    // Check authentication
    doAuthenticationDump(msg->getAuthentication(), level);

    // Check ProofOfPossession
    levelSet(1);
    DSIGSignature * sig = msg->getProofOfPossessionSignature();
    if (sig != NULL) {

        cout << "Proof of PossessionSignature signature found. Checking.... ";

        // Try to find the key
        XSECKeyInfoResolverDefault kir;
        XSECCryptoKey * k = kir.resolveKey(rkb->getKeyInfoList());

        if (k != NULL) {

            sig->setSigningKey(k);
            if (sig->verify())
                cout << "OK!" << endl;
            else 
                cout << "Signature Bad!" << endl;
        }
        else
            cout << "Cannot obtain key from PrototypeKeyBinding" << endl;

    }
    else {

        cout << "No ProofOfPossession Signature found" << endl;

    }

    return 0;

}

int doMsgDump(XKMSMessageAbstractType * msg) {

    if (msg->isSigned()) {

        cout << "Message is signed.  Checking signature ... ";
        try {

            XSECKeyInfoResolverDefault theKeyInfoResolver;
            DSIGSignature * sig = msg->getSignature();

            // The only way we can verify is using keys read directly from the KeyInfo list,
            // so we add a KeyInfoResolverDefault to the Signature.

            sig->setKeyInfoResolver(&theKeyInfoResolver);

            if (sig->verify())
                cout << "OK!" << endl;
            else
                cout << "Bad!" << endl;

        }
    
        catch (const XSECException &e) {
            cout << "Bad!.  Caught exception : " << endl;
            char * msg = XMLString::transcode(e.getMsg());
            cout << msg << endl;
            XSEC_RELEASE_XMLCH(msg);
        }
    }

    int i;

    switch (msg->getMessageType()) {

    case XKMSMessageAbstractType::CompoundRequest :

        cout << "Compound Request\n\n";

        for (i = 0 ; i < ((XKMSCompoundRequest *) (msg))->getRequestListSize(); ++i) {

            cout << "Message " << i << endl;
            doMsgDump(((XKMSCompoundRequest *) msg)->getRequestListItem(i));

        }
        break;
    
    case XKMSMessageAbstractType::CompoundResult :

        cout << "Compound Result\n\n";

        for (i = 0 ; i < ((XKMSCompoundResult *)(msg))->getResultListSize(); ++i) {

            cout << "Message " << i << endl;
            doMsgDump(((XKMSCompoundResult *) msg)->getResultListItem(i));

        }
        break;
    
    case XKMSMessageAbstractType::LocateRequest :

        doLocateRequestDump((XKMSLocateRequest *) msg);
        break;

    case XKMSMessageAbstractType::LocateResult :

        doLocateResultDump((XKMSLocateResult *) msg);
        break;

    case XKMSMessageAbstractType::StatusRequest :

        doStatusRequestDump((XKMSStatusRequest *) msg);
        break;

    case XKMSMessageAbstractType::StatusResult :

        doStatusResultDump((XKMSStatusResult *) msg);
        break;

    case XKMSMessageAbstractType::Result :

        doResultDump((XKMSResult *) msg);
        break;

    case XKMSMessageAbstractType::ValidateRequest :

        doValidateRequestDump((XKMSValidateRequest *) msg);
        break;

    case XKMSMessageAbstractType::ValidateResult :

        doValidateResultDump((XKMSValidateResult *) msg);
        break;

    case XKMSMessageAbstractType::RegisterRequest :

        doRegisterRequestDump((XKMSRegisterRequest *) msg);
        break;

    case XKMSMessageAbstractType::RegisterResult :

        doRegisterResultDump((XKMSRegisterResult *) msg);
        break;

    case XKMSMessageAbstractType::RevokeRequest :

        doRevokeRequestDump((XKMSRevokeRequest *) msg);
        break;

    case XKMSMessageAbstractType::RevokeResult :

        doRevokeResultDump((XKMSRevokeResult *) msg);
        break;

    case XKMSMessageAbstractType::RecoverRequest :

        doRecoverRequestDump((XKMSRecoverRequest *) msg);
        break;

    case XKMSMessageAbstractType::RecoverResult :

        doRecoverResultDump((XKMSRecoverResult *) msg);
        break;

    case XKMSMessageAbstractType::ReissueRequest :

        doReissueRequestDump((XKMSReissueRequest *) msg);
        break;

    case XKMSMessageAbstractType::ReissueResult :

        doReissueResultDump((XKMSReissueResult *) msg);
        break;

    default :

        cout << "Unknown message type!" << endl;

    }

    return 0;
}

int doParsedMsgDump(DOMDocument * doc) {

    // Get an XKMS Message Factory
    XSECProvider prov;
    XKMSMessageFactory * factory = prov.getXKMSMessageFactory();

    try {

        XKMSMessageAbstractType * msg =
            factory->newMessageFromDOM(doc->getDocumentElement());

        if (msg == NULL) {
            cerr << "Unable to create XKMS msg from parsed DOM\n" << endl;
            return 2;
        }

        Janitor <XKMSMessageAbstractType> j_msg(msg);

        return doMsgDump(msg);

    }

    catch (const XSECException &e) {
        char * msg = XMLString::transcode(e.getMsg());
        cerr << "An error occurred during message loading\n   Message: "
        << msg << endl;
        XSEC_RELEASE_XMLCH(msg);
        return 2;
    }
    catch (const XSECCryptoException &e) {
        cerr << "An error occurred during encryption/signature processing\n   Message: "
        << e.getMsg() << endl;

#if defined (XSEC_HAVE_OPENSSL)
        ERR_load_crypto_strings();
        BIO * bio_err;
        if ((bio_err=BIO_new(BIO_s_file())) != NULL)
            BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

        ERR_print_errors(bio_err);
#endif

        return 2;
    }
    catch (...) {

        cerr << "Unknown Exception type occurred.  Cleaning up and exitting\n" << endl;
        return 2;

    }

    // Clean up

    return 0;
}

// --------------------------------------------------------------------------------
//           Base MessageCreate module
// --------------------------------------------------------------------------------

void printMsgCreateUsage(void) {

    cerr << "\nUsage messagecreate [options] {LocateRequest} [msg specific options]\n";
    cerr << "   --help/-h    : print this screen and exit\n\n";

}

int doMsgCreate(int argc, char ** argv, int paramCount) {

    XSECProvider prov;
    DOMDocument * doc;
    XKMSMessageAbstractType *msg;

    if (paramCount >= argc || 
        (_stricmp(argv[paramCount], "--help") == 0) ||
        (_stricmp(argv[paramCount], "-h") == 0)) {
        printMsgCreateUsage();
        return -1;
    }

    if ((_stricmp(argv[paramCount], "LocateRequest") == 0) ||
        (_stricmp(argv[paramCount], "lr") == 0)) {

        paramCount++;
        msg = createLocateRequest(prov, &doc, argc, argv, paramCount);
        if (msg == NULL) {
            return -1;
        }

    }
    else {

        printMsgCreateUsage();
        return -1;

    }

    outputDoc(doc);
    
    // Cleanup message stuff
    delete msg;
    doc->release();

    return 0;

}


// --------------------------------------------------------------------------------
//           Base request module
// --------------------------------------------------------------------------------

void printDoRequestUsage(void) {

    cerr << "\nUsage request [options] {RequestType} [msg specific options]\n";
    cerr << "   --help/-h       : Print this screen and exit\n";
    cerr << "   --two-phase/-t  : Indicate Two-Phase support in the request message\n";
    cerr << "   --nonce/-n [nonce]\n";
    cerr << "                   : Set two phase nonce value\n";
    cerr << "   --original-requestid/-o [id]\n";
    cerr << "                   : set OriginalRequestId attribute in request\n";
    cerr << "   --envelope-type/-e [NONE|SOAP11|SOAP12]\n";
    cerr << "                   : Set envelope wrapper for request\n";
    cerr << "                         NONE   = No wrapper - straight HTTP request\n";
    cerr << "                         SOAP11 = Use a SOAP 1.1 envelope\n";
    cerr << "                         SOAP12 = Use a SOAP 1.2 envelope\n\n";
    cerr << "                     Where RequestType = one of :\n";
    cerr << "                         CompoundRequest (cr)\n";
    cerr << "                         LocateRequest   (lr)\n";
    cerr << "                         ValidateRequest (vr)\n";
    cerr << "                         PendingRequest  (pr)\n";
    cerr << "                         RegisterRequest (rr)\n";
    cerr << "                         ReissueRequest  (ir)\n";
    cerr << "                         RecoverRequest  (or)\n";
    cerr << "                         RevokeRequest   (er)\n\n";

}

int doRequest(int argc, char ** argv, int paramCount) {

    XSECProvider prov;
    DOMDocument * doc;
    XKMSMessageAbstractType *msg = NULL;
    XSECSOAPRequestorSimple::envelopeType et = XSECSOAPRequestorSimple::ENVELOPE_SOAP11;

    bool twoPhase = false;
    bool parmsDone = false;

    char * nonce = NULL;
    char * originalRequestId = NULL;

    if (paramCount >= argc || 
        (_stricmp(argv[paramCount], "--help") == 0) ||
        (_stricmp(argv[paramCount], "-h") == 0)) {
        printDoRequestUsage();
        return -1;
    }

    while (!parmsDone) {
        if ((_stricmp(argv[paramCount], "--two-phase") == 0) ||
            (_stricmp(argv[paramCount], "-t") == 0)) {

            twoPhase = true;
            paramCount++;

        }
        else if ((_stricmp(argv[paramCount], "--nonce") == 0) ||
            (_stricmp(argv[paramCount], "-n") == 0)) {

            paramCount++;
            if (paramCount == argc) {
                printDoRequestUsage();
                return -1;
            }

            nonce=argv[paramCount++];
        }
        else if ((_stricmp(argv[paramCount], "--original-requestid") == 0) ||
            (_stricmp(argv[paramCount], "-o") == 0)) {

            paramCount++;
            if (paramCount == argc) {
                printDoRequestUsage();
                return -1;
            }

            originalRequestId=argv[paramCount++];
        }       
        else if ((_stricmp(argv[paramCount], "--envelope") == 0) ||
            (_stricmp(argv[paramCount], "-e") == 0)) {

            // Set the wrapper envelope type

            paramCount++;
            if (paramCount == argc) {
                printDoRequestUsage();
                return -1;
            }

            if (_stricmp(argv[paramCount], "NONE") == 0) {
                et = XSECSOAPRequestorSimple::ENVELOPE_NONE;
            }
            else if (_stricmp(argv[paramCount], "SOAP11") == 0) {
                et = XSECSOAPRequestorSimple::ENVELOPE_SOAP11;
            }
            else if (_stricmp(argv[paramCount], "SOAP12") == 0) {
                et = XSECSOAPRequestorSimple::ENVELOPE_SOAP12;
            }
            else {
                printDoRequestUsage();
                return -1;
            }
            paramCount++;
        }
        else if ((_stricmp(argv[paramCount], "LocateRequest") == 0) ||
            (_stricmp(argv[paramCount], "lr") == 0)) {

            paramCount++;
            XKMSLocateRequest * r = 
                (XKMSLocateRequest *) (createLocateRequest(prov, &doc, argc, argv, paramCount));

            if (r == NULL) {
                return -1;
            }

            if (twoPhase)
                r->appendResponseMechanismItem(XKMSConstants::s_tagRepresent);

            msg = r;
            parmsDone = true;

        }
        else if ((_stricmp(argv[paramCount], "ValidateRequest") == 0) ||
            (_stricmp(argv[paramCount], "vr") == 0)) {

            paramCount++;
            XKMSValidateRequest * r = 
                (XKMSValidateRequest *) (createValidateRequest(prov, &doc, argc, argv, paramCount));

            if (r == NULL) {
                return -1;
            }
            if (twoPhase)
                r->appendResponseMechanismItem(XKMSConstants::s_tagRepresent);

            msg = r;
            parmsDone = true;

        }
        else if ((_stricmp(argv[paramCount], "RegisterRequest") == 0) ||
            (_stricmp(argv[paramCount], "rr") == 0)) {

            paramCount++;
            XKMSRegisterRequest * r = 
                (XKMSRegisterRequest *) (createRegisterRequest(prov, &doc, argc, argv, paramCount));

            if (r == NULL) {
                return -1;
            }
            if (twoPhase)
                r->appendResponseMechanismItem(XKMSConstants::s_tagRepresent);

            msg = r;
            parmsDone = true;

        }
        else if ((_stricmp(argv[paramCount], "RevokeRequest") == 0) ||
            (_stricmp(argv[paramCount], "er") == 0)) {

            paramCount++;
            XKMSRevokeRequest * r = 
                (XKMSRevokeRequest *) (createRevokeRequest(prov, &doc, argc, argv, paramCount));

            if (r == NULL) {
                return -1;
            }
            if (twoPhase)
                r->appendResponseMechanismItem(XKMSConstants::s_tagRepresent);

            msg = r;
            parmsDone = true;

        }       
        else if ((_stricmp(argv[paramCount], "RecoverRequest") == 0) ||
            (_stricmp(argv[paramCount], "or") == 0)) {

            paramCount++;
            XKMSRecoverRequest * r = 
                (XKMSRecoverRequest *) (createRecoverRequest(prov, &doc, argc, argv, paramCount));

            if (r == NULL) {
                return -1;
            }
            if (twoPhase)
                r->appendResponseMechanismItem(XKMSConstants::s_tagRepresent);

            msg = r;
            parmsDone = true;

        }
        else if ((_stricmp(argv[paramCount], "ReissueRequest") == 0) ||
            (_stricmp(argv[paramCount], "ir") == 0)) {

            paramCount++;
            XKMSReissueRequest * r = 
                (XKMSReissueRequest *) (createReissueRequest(prov, &doc, argc, argv, paramCount));

            if (r == NULL) {
                return -1;
            }
            if (twoPhase)
                r->appendResponseMechanismItem(XKMSConstants::s_tagRepresent);

            msg = r;
            parmsDone = true;

        }
        else if ((_stricmp(argv[paramCount], "PendingRequest") == 0) ||
            (_stricmp(argv[paramCount], "pr") == 0)) {

            paramCount++;
            XKMSPendingRequest * r = 
                (XKMSPendingRequest *) (createPendingRequest(prov, &doc, argc, argv, paramCount));

            if (r == NULL) {
                return -1;
            }
            if (twoPhase)
                r->appendResponseMechanismItem(XKMSConstants::s_tagRepresent);

            msg = r;
            parmsDone = true;

        }
        else if ((_stricmp(argv[paramCount], "StatusRequest") == 0) ||
            (_stricmp(argv[paramCount], "sr") == 0)) {

            paramCount++;
            XKMSStatusRequest * r = 
                (XKMSStatusRequest *) (createStatusRequest(prov, &doc, argc, argv, paramCount));

            if (r == NULL) {
                return -1;
            }
            if (twoPhase)
                r->appendResponseMechanismItem(XKMSConstants::s_tagRepresent);

            msg = r;
            parmsDone = true;

        }
        else if ((_stricmp(argv[paramCount], "CompoundRequest") == 0) ||
            (_stricmp(argv[paramCount], "cr") == 0)) {

            XKMSCompoundRequest * r = 
                (XKMSCompoundRequest *) (createCompoundRequest(prov, &doc, argc, argv, paramCount + 1));

            if (r == NULL) {
                return -1;
            }
            if (twoPhase)
                r->appendResponseMechanismItem(XKMSConstants::s_tagRepresent);

            msg = r;
            parmsDone = true;

        }
        else {

            printDoRequestUsage();
            return -1;

        }
    }

    XKMSMessageFactory * f = prov.getXKMSMessageFactory();
    XKMSRequestAbstractType * request = f->toRequestAbstractType(msg);

    if (nonce != NULL)
        request->setNonce(MAKE_UNICODE_STRING(nonce));
    if (originalRequestId != NULL)
        request->setOriginalRequestId(MAKE_UNICODE_STRING(originalRequestId));

    try {
        if (g_txtOut) {
            outputDoc(doc);
        }
    }
    catch (...) {
        delete msg;
        doc->release();
        throw;
    }

    DOMDocument * responseDoc;

    try {
        XSECSOAPRequestorSimple req(msg->getService());
#if !defined(_WIN32)
        struct timeval tv1, tv2;
        gettimeofday(&tv1, NULL);
#endif
        req.setEnvelopeType(et);

        responseDoc = req.doRequest(doc);
#if !defined(_WIN32)
        gettimeofday(&tv2, NULL);
        long seconds = tv2.tv_sec - tv1.tv_sec;
        long useconds;
        if (seconds != 0) {
            useconds = 1000000 - tv1.tv_usec + tv2.tv_usec;
            seconds--;
        }
        else {
            useconds = tv2.tv_usec - tv1.tv_usec;
        }
        if (useconds >= 1000000) {
            useconds -= 1000000;
            seconds++;
        }

        cout << "Time taken for request = " << seconds << " seconds, " << useconds << " useconds" << endl;
#endif
        /* If two-phase - re-do the request */
        if (twoPhase) {

            XKMSResultType * r = f->toResultType(f->newMessageFromDOM(responseDoc->getDocumentElement()));
            if (r->getResultMajor() == XKMSResultType::Represent) {

                cerr << "Intermediate response of a two phase sequence received\n\n";

                if (g_txtOut) {
                    outputDoc(responseDoc);
                }
                doParsedMsgDump(responseDoc);

                //XKMSRequestAbstractType * request = f->toRequestAbstractType(msg);
                for (int k = 0; k < request->getResponseMechanismSize(); ++k) {
                    if (strEquals(request->getResponseMechanismItemStr(k),
                                  XKMSConstants::s_tagRepresent)) {
                        request->removeResponseMechanismItem(k);
                        break;
                    }
                }

                request->setNonce(r->getNonce());
                request->setOriginalRequestId(request->getId());
                XMLCh * myId = generateId();

                request->setId(myId);
                XSEC_RELEASE_XMLCH(myId);

                responseDoc->release();
                responseDoc = req.doRequest(doc);

            }
            delete r;
        }

    }
    catch (const XSECException &e) {

        char * m = XMLString::transcode(e.getMsg());
        cerr << "Error sending request: " << m << endl;
        XSEC_RELEASE_XMLCH(m);

        delete msg;
        doc->release();

        return -1;

    }
    catch (...) {
        delete msg;
        doc->release();

        throw;

    }

    // Cleanup request stuff
    delete msg;
    doc->release();

    // Now lets process the result

    int ret;
    
    try {
        if (g_txtOut) {
            outputDoc(responseDoc);
        }
        ret = doParsedMsgDump(responseDoc);
    }
    catch (...) {
        responseDoc->release();
        throw;
    }
    
    responseDoc->release();
    return ret;

}


// --------------------------------------------------------------------------------
//           Base msgdump module
// --------------------------------------------------------------------------------


#if 0
class XMLSchemaDTDResolver : public EntityResolver { 

public: 

    XMLSchemaDTDResolver() {}
    ~XMLSchemaDTDResolver() {}
    
    InputSource * resolveEntity (const XMLCh* const publicId, const XMLCh* const systemId);
    
};

InputSource * XMLSchemaDTDResolver::resolveEntity (const XMLCh* const publicId, 
                                                   const XMLCh* const systemId) { 
    

    
    if (strEquals(systemId, "http://www.w3.org/2001/XMLSchema")) {  
        return new LocalFileInputSource(MAKE_UNICODE_STRING("C:\\prog\\SRC\\xml-security\\c\\Build\\Win32\\VC6\\Debug\\XMLSchema.dtd")); 
    } 
    else { 
        return NULL; 
    }

}
#endif
void printMsgDumpUsage(void) {

    cerr << "\nUsage msgdump [options] <filename>\n";
    cerr << "   --help/-h      : print this screen and exit\n";
    cerr << "   --validate/-v  : validate the input messages\n";
    cerr << "   --auth-phrase/-a <phrase>\n";
    cerr << "                  : use <phrase> for authentication/private key in X-KRSS messages\n";
#if defined (XSEC_HAVE_OPENSSL)
    cerr << "   --output-private-key/-p <filename> <passphrase>\n";
    cerr << "                  : Write private keys from Register or Recover requests to the file\n\n";
#endif
    cerr << "   filename = name of file containing XKMS msg to dump\n\n";

}

int doMsgDump(int argc, char ** argv, int paramCount) {

    char * inputFile = NULL;
    bool doValidate = false;

    if (paramCount >= argc || 
        (_stricmp(argv[paramCount], "--help") == 0) ||
        (_stricmp(argv[paramCount], "-h") == 0)) {
        printMsgDumpUsage();
        return -1;
    }

    while (paramCount < argc-1) {
        if ((_stricmp(argv[paramCount], "--validate") == 0) ||
            (_stricmp(argv[paramCount], "-v") == 0)) {

            doValidate = true;
            paramCount++;

        }
        else if ((_stricmp(argv[paramCount], "--auth-phrase") == 0) ||
            (_stricmp(argv[paramCount], "-a") == 0)) {

            paramCount++;
            g_authPassPhrase = argv[paramCount];
            paramCount++;
        }
#if defined (XSEC_HAVE_OPENSSL)
        else if (_stricmp(argv[paramCount], "--output-private-key") == 0 || _stricmp(argv[paramCount], "-p") == 0) {
            if (paramCount >= argc + 2) {
                printMsgDumpUsage();
                return -1;
            }
            ++paramCount;
            g_privateKeyFile = argv[paramCount++];
            g_privateKeyPassPhrase = argv[paramCount++];
        }
#endif
        else {

            printMsgDumpUsage();
            return -1;
        }
    }

    if (paramCount >= argc) {
        printMsgDumpUsage();
        return -1;
    }

    inputFile = argv[paramCount];

    // Dump the details of an XKMS message to the console
    cout << "Decoding XKMS Message contained in " << inputFile << endl;
    
    // Create and set up the parser

    XercesDOMParser * parser = new XercesDOMParser;
    Janitor<XercesDOMParser> j_parser(parser);

    parser->setDoNamespaces(true);
    parser->setCreateEntityReferenceNodes(true);

    // Error handling
    xkmsErrorHandler xeh;
    parser->setErrorHandler(&xeh);

#if 0
    // Local load of XMLSchema.dtd
    XMLSchemaDTDResolver sdr;
    parser->setEntityResolver(&sdr);
#endif

    // Schema handling
    if (doValidate) {
        parser->setDoSchema(true);
        parser->setExternalSchemaLocation("http://www.w3.org/2002/03/xkms# http://www.w3.org/TR/xkms2/Schemas/xkms.xsd");
    }

    bool errorsOccured = false;
    XMLSize_t errorCount = 0;
    try
    {
        parser->parse(inputFile);
        errorCount = parser->getErrorCount();
    }

    catch (const XMLException& e)
    {
        char * msg = XMLString::transcode(e.getMessage());
        cerr << "An error occurred during parsing\n   Message: "
             << msg << endl;
        XSEC_RELEASE_XMLCH(msg);
        errorsOccured = true;
    }


    catch (const DOMException& e)
    {
       cerr << "A DOM error occurred during parsing\n   DOMException code: "
             << e.code << endl;
        errorsOccured = true;
    }

    if (errorCount > 0 || errorsOccured) {

        cout << "Errors during parse" << endl;
        return (2);

    }

    /*

        Now that we have the parsed file, get the DOM document and start looking at it

    */
    
    DOMDocument *doc = parser->getDocument();

    return doParsedMsgDump(doc);
}


// --------------------------------------------------------------------------------
//           Startup and main
// --------------------------------------------------------------------------------

void printUsage(void) {

    cerr << "\nUsage: xklient [base options] {msgdump|msgcreate|dorequest} [command specific options]\n\n";
    cerr << "     msgdump   : Read an XKMS message and print details\n";
    cerr << "     msgcreate : Create a message of type :\n";
    cerr << "                 LocateRequest\n";
    cerr << "                 ValidateRequest\n";
    cerr << "                 PendingRequest\n";
    cerr << "                 RegisterRequest\n";
    cerr << "                 RecoverRequest\n";
    cerr << "                 ReissueRequest\n";
    cerr << "                 RevokeRequest\n";
    cerr << "                 PendingRequest\n";
    cerr << "                 send to service URI and output result\n\n";
    cerr << "     Where options are :\n\n";
    cerr << "     --text/-t\n";
    cerr << "         Print any created XML to screen\n";

}

int evaluate(int argc, char ** argv) {
    
    if (argc < 2) {

        printUsage();
        return 2;
    }

    int paramCount = 1;

    // Run through parameters

    while (paramCount < argc) {

        if (_stricmp(argv[paramCount], "--text") == 0 || _stricmp(argv[paramCount], "-t") == 0) {
            g_txtOut = true;
            paramCount++;
        }
        else if (_stricmp(argv[paramCount], "MsgDump") == 0 || _stricmp(argv[paramCount], "md") == 0) {
            
            // Perform a MsgDump operation
            return doMsgDump(argc, argv, paramCount +1);

        }
        else if (_stricmp(argv[paramCount], "MsgCreate") == 0 || _stricmp(argv[paramCount], "mc") == 0) {
            
            // Perform a MsgDump operation
            return doMsgCreate(argc, argv, paramCount +1);

        }
        else if (_stricmp(argv[paramCount], "Request") == 0 || _stricmp(argv[paramCount], "req") == 0) {
            
            // Perform a MsgDump operation
            return doRequest(argc, argv, paramCount +1);

        }
        else {
            printUsage();
            return 2;
        }
    }

    return 1;

}
    


int main(int argc, char **argv) {

    int retResult;

    /* We output a version number to overcome a "feature" in Microsoft's memory
       leak detection */

    cout << "XKMS Client (Using Apache XML-Security-C Library v" << XSEC_VERSION_MAJOR <<
        "." << XSEC_VERSION_MEDIUM << "." << XSEC_VERSION_MINOR << ")\n";

#if defined (_DEBUG) && defined (_MSC_VER)

    // Do some memory debugging under Visual C++

    _CrtMemState s1, s2, s3;

    // At this point we are about to start really using XSEC, so
    // Take a "before" checkpoing

    _CrtMemCheckpoint( &s1 );

#endif

    // Initialise the XML system

    try {

        XMLPlatformUtils::Initialize();
#ifdef XSEC_HAVE_XALAN
        XPathEvaluator::initialize();
        XalanTransformer::initialize();
#endif
        XSECPlatformUtils::Initialise();

    }
    catch (const XMLException &e) {

        cerr << "Error during initialisation of Xerces" << endl;
        cerr << "Error Message = : "
             << e.getMessage() << endl;

    }

    retResult = evaluate(argc, argv);

    XSECPlatformUtils::Terminate();
#ifdef XSEC_HAVE_XALAN
    XalanTransformer::terminate();
    XPathEvaluator::terminate();
#endif
    XMLPlatformUtils::Terminate();

#if defined (_DEBUG) && defined (_MSC_VER)

    _CrtMemCheckpoint( &s2 );

    if ( _CrtMemDifference( &s3, &s1, &s2 ) && s3.lCounts[1] > 1) {

        std::cerr << "Total count = " << (unsigned int) s3.lTotalCount << endl;

        // Send all reports to STDOUT
        _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
        _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
        _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
        _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
        _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
        _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );

        // Dumpy memory stats

        _CrtMemDumpAllObjectsSince( &s3 );
        _CrtMemDumpStatistics( &s3 );
    }

    // Now turn off memory leak checking and end as there are some 
    // Globals that are allocated that get seen as leaks (Xalan?)

    int dbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
    dbgFlag &= ~(_CRTDBG_LEAK_CHECK_DF);
    _CrtSetDbgFlag( dbgFlag );

#endif

    return retResult;
}
