xsec/tools/xklient/xklient.cpp (3,450 lines of code) (raw):

/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * XSEC * * 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; }