You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by bl...@apache.org on 2006/03/04 09:22:18 UTC

svn commit: r383073 - in /xml/security/trunk/c/src: tools/xklient/xklient.cpp xkms/XKMSRegisterResult.hpp xkms/impl/XKMSRSAKeyPairImpl.hpp xkms/impl/XKMSRegisterResultImpl.cpp xkms/impl/XKMSRegisterResultImpl.hpp

Author: blautenb
Date: Sat Mar  4 00:22:16 2006
New Revision: 383073

URL: http://svn.apache.org/viewcvs?rev=383073&view=rev
Log:
Support for PrivateKey in RegisterRequest

Modified:
    xml/security/trunk/c/src/tools/xklient/xklient.cpp
    xml/security/trunk/c/src/xkms/XKMSRegisterResult.hpp
    xml/security/trunk/c/src/xkms/impl/XKMSRSAKeyPairImpl.hpp
    xml/security/trunk/c/src/xkms/impl/XKMSRegisterResultImpl.cpp
    xml/security/trunk/c/src/xkms/impl/XKMSRegisterResultImpl.hpp

Modified: xml/security/trunk/c/src/tools/xklient/xklient.cpp
URL: http://svn.apache.org/viewcvs/xml/security/trunk/c/src/tools/xklient/xklient.cpp?rev=383073&r1=383072&r2=383073&view=diff
==============================================================================
--- xml/security/trunk/c/src/tools/xklient/xklient.cpp (original)
+++ xml/security/trunk/c/src/tools/xklient/xklient.cpp Sat Mar  4 00:22:16 2006
@@ -122,6 +122,7 @@
 
 #	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>
@@ -140,6 +141,8 @@
 
 bool g_txtOut = false;
 char * g_authPassPhrase = NULL;
+char * g_privateKeyFile = NULL;
+char * g_privateKeyPassPhrase = NULL;
 
 int doParsedMsgDump(DOMDocument * doc);
 
@@ -963,6 +966,11 @@
 	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 << "   --kek/-k <phrase>        : Key phrase to use for PrivateKey decryption\n";
+#if defined (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";
@@ -1016,6 +1024,14 @@
 			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();
@@ -1068,6 +1084,18 @@
 			pkb->appendUseKeyWithItem(MAKE_UNICODE_STRING(argv[paramCount]), MAKE_UNICODE_STRING(argv[paramCount + 1]));
 			paramCount += 2;
 		}
+#if defined (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();
@@ -1337,12 +1365,12 @@
 }
 
 // --------------------------------------------------------------------------------
-//           Create a RegisterRequest
+//           Create a RevokeRequest
 // --------------------------------------------------------------------------------
 
 void printRevokeRequestUsage(void) {
 
-	cerr << "\nUsage RegisterRequest [--help|-h] <service URI> [options]\n";
+	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";
@@ -2372,52 +2400,92 @@
 	}
 
 	// Check if there is a private key
-	XKMSRSAKeyPair * kp = msg->getRSAKeyPair(g_authPassPhrase);
-	if (kp != NULL) {
-		cout << endl;
-		levelSet(level);
-		cout << "RSAKeyPair found" << endl << endl;
-		level += 1;
+	if (g_authPassPhrase) {
+		XKMSRSAKeyPair * kp = msg->getRSAKeyPair(g_authPassPhrase);
+		if (kp != NULL) {
+			cout << endl;
+			levelSet(level);
+			cout << "RSAKeyPair found" << endl << endl;
+			level += 1;
 
-		char * sr = XMLString::transcode(kp->getModulus());
-		levelSet(level);
-		cout << "Modulus = " << sr << endl;
-		XSEC_RELEASE_XMLCH(sr);
-		
-		sr = XMLString::transcode(kp->getExponent());
-		levelSet(level);
-		cout << "Exponent = " << sr << endl;
-		XSEC_RELEASE_XMLCH(sr);
+			// 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());
 
-		sr = XMLString::transcode(kp->getP());
-		levelSet(level);
-		cout << "P = " << sr << endl;
-		XSEC_RELEASE_XMLCH(sr);
+#if defined (HAVE_OPENSSL)
 
-		sr = XMLString::transcode(kp->getQ());
-		levelSet(level);
-		cout << "Q = " << sr << endl;
-		XSEC_RELEASE_XMLCH(sr);
+			if (g_privateKeyFile != NULL) {
+				levelSet(level);
+				cout << "Writing private key to file " << g_privateKeyFile;
+
+				// Create the RSA key file
+				RSA * rsa = RSA_new();
+				rsa->n = OpenSSLCryptoBase64::b642BN(sModulus, strlen(sModulus));
+				rsa->e = OpenSSLCryptoBase64::b642BN(sExponent, strlen(sExponent));
+				rsa->d = OpenSSLCryptoBase64::b642BN(sD, strlen(sD));
+				rsa->p = OpenSSLCryptoBase64::b642BN(sP, strlen(sP));
+				rsa->q = OpenSSLCryptoBase64::b642BN(sQ, strlen(sQ));
+				rsa->dmp1 = OpenSSLCryptoBase64::b642BN(sDP, strlen(sDP));
+				rsa->dmq1 = OpenSSLCryptoBase64::b642BN(sDQ, strlen(sDQ));
+				rsa->iqmp = OpenSSLCryptoBase64::b642BN(sInverseQ, 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);
 
-		sr = XMLString::transcode(kp->getDP());
-		levelSet(level);
-		cout << "DP = " << sr << endl;
-		XSEC_RELEASE_XMLCH(sr);
+				cout << " done" << endl << endl;
 
-		sr = XMLString::transcode(kp->getDQ());
-		levelSet(level);
-		cout << "DQ = " << sr << endl;
-		XSEC_RELEASE_XMLCH(sr);
+			}
+#endif
+			// Now output
+			levelSet(level);
+			cout << "Modulus = " << sModulus << endl;
+			XSEC_RELEASE_XMLCH(sModulus);
+			
+			levelSet(level);
+			cout << "Exponent = " << sExponent << endl;
+			XSEC_RELEASE_XMLCH(sExponent);
 
-		sr = XMLString::transcode(kp->getInverseQ());
-		levelSet(level);
-		cout << "Inverse Q = " << sr << endl;
-		XSEC_RELEASE_XMLCH(sr);
+			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);
 
-		sr = XMLString::transcode(kp->getD());
+			levelSet(level);
+			cout << "D = " << sD << endl;
+			XSEC_RELEASE_XMLCH(sD);
+		}
+	}
+	else {
 		levelSet(level);
-		cout << "D = " << sr << endl;
-		XSEC_RELEASE_XMLCH(sr);
+		cout << "Not checking for private key as no decryption phrase set";
 	}
 
 	return 0;
@@ -3190,7 +3258,11 @@
 	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\n";
+	cerr << "                  : use <phrase> for authentication/private key in X-KRSS messages\n";
+#if defined (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";
 
 }
@@ -3222,6 +3294,17 @@
 			g_authPassPhrase = argv[paramCount];
 			paramCount++;
 		}
+#if defined (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();

Modified: xml/security/trunk/c/src/xkms/XKMSRegisterResult.hpp
URL: http://svn.apache.org/viewcvs/xml/security/trunk/c/src/xkms/XKMSRegisterResult.hpp?rev=383073&r1=383072&r2=383073&view=diff
==============================================================================
--- xml/security/trunk/c/src/xkms/XKMSRegisterResult.hpp (original)
+++ xml/security/trunk/c/src/xkms/XKMSRegisterResult.hpp Sat Mar  4 00:22:16 2006
@@ -35,6 +35,7 @@
 class XKMSKeyBinding;
 class XKMSUnverifiedKeyBinding;
 class XKMSRSAKeyPair;
+class XENCCipherData;
 
 /**
  * @ingroup xkms
@@ -146,6 +147,48 @@
 	 */
 
 	virtual XKMSRSAKeyPair * getRSAKeyPair(const char * passPhrase) = 0;
+
+	/**
+	 * \brief Add the RSAKeyPair in an encrypted PrivateKey
+	 *
+	 * This call requires the passphrase to encrypt the private key.
+	 * The implementation encrypts the RSAKeyPair and adds the result
+	 * to the resulting RSAKey Pair.  It returns the CipherData element
+	 * to the caller (not a structure for the PrivateKey)
+	 *
+	 * @note The encryption is performed *inside* the RegisterResult, so
+	 * this actually modified the contents of the XML.  It should never
+	 * be called twice!
+	 *
+	 * @param passPhrase The local code page version of the pass phrase
+	 * @param Modulus Base64 encoded string with the modulus
+	 * @param Exponent Base64 encoded string with the exponent
+	 * @param P Base64 encoded string with p
+	 * @param Q Base64 encoded string with q
+	 * @param DP Base64 encoded string with dp
+	 * @param DQ Base64 encoded string with dq
+	 * @param InverseQ Base64 encoded string with inverseq
+	 * @param D Base64 encoded string with d
+	 * @param em The encryptionMethod to use for this encryption.  Use
+	 * ENCRYPT_NONE if a user defined type is required.
+	 * @param algorithmURI If ENCRYPT_NONE is passed in, this will be
+	 * used to set the algorithm URI.  If this is also NULL - no
+	 * EncryptionMethod will be set.  <b>NULL Value Unsupported if em not
+	 * set!  It's use could cause problems!</b>
+	 * @returns The encrypted result of adding the info
+	 */
+
+	virtual XENCEncryptedData * setRSAKeyPair(const char * passPhrase,
+		XMLCh * Modulus,
+		XMLCh * Exponent,
+		XMLCh * P,
+		XMLCh * Q,
+		XMLCh * DP,
+		XMLCh * DQ,
+		XMLCh * InverseQ,
+		XMLCh * D,
+		encryptionMethod em,
+		const XMLCh * algorithmURI = NULL) = 0;
 
 	//@}
 

Modified: xml/security/trunk/c/src/xkms/impl/XKMSRSAKeyPairImpl.hpp
URL: http://svn.apache.org/viewcvs/xml/security/trunk/c/src/xkms/impl/XKMSRSAKeyPairImpl.hpp?rev=383073&r1=383072&r2=383073&view=diff
==============================================================================
--- xml/security/trunk/c/src/xkms/impl/XKMSRSAKeyPairImpl.hpp (original)
+++ xml/security/trunk/c/src/xkms/impl/XKMSRSAKeyPairImpl.hpp Sat Mar  4 00:22:16 2006
@@ -56,14 +56,14 @@
 	// Create from scratch - tag is the element name to create
 	XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * 
 		createBlankXKMSRSAKeyPairImpl(
-			const XMLCh * modulus, 
-			const XMLCh * exponent, 
-			const XMLCh * p, 
-			const XMLCh * q, 
-			const XMLCh * dp, 
-			const XMLCh * dq, 
-			const XMLCh * invq, 
-			const XMLCh * d);
+			const XMLCh * Modulus, 
+			const XMLCh * Exponent, 
+			const XMLCh * P, 
+			const XMLCh * Q, 
+			const XMLCh * DO, 
+			const XMLCh * DQ, 
+			const XMLCh * InverseQ, 
+			const XMLCh * D);
 
 	// Interface methods
 

Modified: xml/security/trunk/c/src/xkms/impl/XKMSRegisterResultImpl.cpp
URL: http://svn.apache.org/viewcvs/xml/security/trunk/c/src/xkms/impl/XKMSRegisterResultImpl.cpp?rev=383073&r1=383072&r2=383073&view=diff
==============================================================================
--- xml/security/trunk/c/src/xkms/impl/XKMSRegisterResultImpl.cpp (original)
+++ xml/security/trunk/c/src/xkms/impl/XKMSRegisterResultImpl.cpp Sat Mar  4 00:22:16 2006
@@ -193,9 +193,25 @@
 	DOMElement * e = u->createBlankKeyBinding(status);
 
 	// Append the element
+	DOMElement * c = findFirstElementChild(m_msg.mp_messageAbstractTypeElement);
+	while (c != NULL) {
 
-	m_msg.mp_messageAbstractTypeElement->appendChild(e);
-	m_msg.mp_env->doPrettyPrint(m_msg.mp_messageAbstractTypeElement);
+		if (strEquals(getXKMSLocalName(c), XKMSConstants::s_tagPrivateKey))
+			break;
+
+	}
+
+	if (c != NULL) {
+		m_msg.mp_messageAbstractTypeElement->insertBefore(e, c);
+		if (m_msg.mp_env->getPrettyPrintFlag()) {
+			m_msg.mp_messageAbstractTypeElement->insertBefore(
+				m_msg.mp_env->getParentDocument()->createTextNode(DSIGConstants::s_unicodeStrNL), c);
+		}
+	}
+	else {
+		m_msg.mp_messageAbstractTypeElement->appendChild(e);
+		m_msg.mp_env->doPrettyPrint(m_msg.mp_messageAbstractTypeElement);
+	}
 
 	return u;
 
@@ -255,6 +271,8 @@
 					(XMLByte *) kbuf,
 					XSEC_MAX_HASH_SIZE);
 
+	memset(kbuf, 0, XSEC_MAX_HASH_SIZE);
+
 	cipher->setKey(sk);
 	cipher->decryptElement();
 
@@ -272,4 +290,89 @@
 
 	return mp_RSAKeyPair;
 }
+
+XENCEncryptedData * XKMSRegisterResultImpl::setRSAKeyPair(const char * passPhrase,
+		XMLCh * Modulus,
+		XMLCh * Exponent,
+		XMLCh * P,
+		XMLCh * Q,
+		XMLCh * DP,
+		XMLCh * DQ,
+		XMLCh * InverseQ,
+		XMLCh * D,
+		encryptionMethod em,
+		const XMLCh * algorithmURI) {
+
+	// Try to set up the key first - if this fails, don't want to have added the
+	// XML
+
+	const XMLCh * uri;
+	safeBuffer algorithmSB;
+
+	if (em != ENCRYPT_NONE) {
+		if (encryptionMethod2URI(algorithmSB, em) != true) {
+			throw XSECException(XSECException::XKMSError, 
+				"XKMSRegisterResult::setRSAKeyPair - Unknown encryption method");
+		}
+		uri = algorithmSB.sbStrToXMLCh();
+	}		
+	// Find if we can get an algorithm for this URI
+	XSECAlgorithmHandler *handler;
+
+	handler = 
+		XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(
+			uri);
+
+	if (handler == NULL) {
+		throw XSECException(XSECException::XKMSError,
+			"XKMSRegisterResult::setRSAKeyPair - unable to handle algorithm");
+	}
+
+	unsigned char kbuf[XSEC_MAX_HASH_SIZE];
+	unsigned int len = CalculateXKMSKEK((unsigned char *) passPhrase, strlen(passPhrase), kbuf, XSEC_MAX_HASH_SIZE);
+
+	XSECCryptoKey * sk = handler->createKeyForURI(
+					uri,
+					(XMLByte *) kbuf,
+					XSEC_MAX_HASH_SIZE);
+
+	memset(kbuf, 0, XSEC_MAX_HASH_SIZE);
+
+	// Get some setup values
+	safeBuffer str;
+	DOMDocument *doc = m_msg.mp_env->getParentDocument();
+	const XMLCh * prefix = m_msg.mp_env->getXKMSNSPrefix();
+
+	makeQName(str, prefix, XKMSConstants::s_tagPrivateKey);
+
+	// Create a PrivateKey to add this to
+	DOMElement * pk = doc->createElementNS(XKMSConstants::s_unicodeStrURIXKMS, 
+												str.rawXMLChBuffer());
+
+	m_msg.mp_env->doPrettyPrint(pk);
+
+	// Add it to the request doc
+	m_msg.mp_messageAbstractTypeElement->appendChild(pk);
+	m_msg.mp_env->doPrettyPrint(m_msg.mp_messageAbstractTypeElement);
+
+	// Now create the RSA structure
+	XKMSRSAKeyPairImpl * rsa;
+	XSECnew(rsa, XKMSRSAKeyPairImpl(m_msg.mp_env));
+
+	DOMElement * e = 
+		rsa->createBlankXKMSRSAKeyPairImpl(Modulus, Exponent, P, Q, DP, DQ, InverseQ, D);
+
+	// Add it to the PrivateKey
+	pk->appendChild(e);
+	m_msg.mp_env->doPrettyPrint(pk);
+
+	// Encrypt all of this for future use
+	XENCCipher * cipher = m_prov.newCipher(m_msg.mp_env->getParentDocument());
+	cipher->setKey(sk);
+	cipher->encryptElementContent(pk, ENCRYPT_NONE, uri);
+
+	// Now load the encrypted data back in
+	return cipher->loadEncryptedData(findFirstElementChild(pk));
+
+}	
 

Modified: xml/security/trunk/c/src/xkms/impl/XKMSRegisterResultImpl.hpp
URL: http://svn.apache.org/viewcvs/xml/security/trunk/c/src/xkms/impl/XKMSRegisterResultImpl.hpp?rev=383073&r1=383072&r2=383073&view=diff
==============================================================================
--- xml/security/trunk/c/src/xkms/impl/XKMSRegisterResultImpl.hpp (original)
+++ xml/security/trunk/c/src/xkms/impl/XKMSRegisterResultImpl.hpp Sat Mar  4 00:22:16 2006
@@ -30,6 +30,7 @@
 
 #include <xsec/framework/XSECDefs.hpp>
 #include <xsec/xkms/XKMSRegisterResult.hpp>
+#include <xsec/framework/XSECProvider.hpp>
 
 #include "XKMSResultTypeImpl.hpp"
 
@@ -37,6 +38,7 @@
 
 class XKMSKeyBindingImpl;
 class XKMSRSAKeyPairImpl;
+class XENCCipherImpl;
 
 class XKMSRegisterResultImpl : public XKMSRegisterResult {
 
@@ -72,6 +74,18 @@
 	virtual XKMSKeyBinding * getKeyBindingItem(int item) const;
 	virtual XKMSKeyBinding * appendKeyBindingItem(XKMSStatus::StatusValue status);
 	virtual XKMSRSAKeyPair * getRSAKeyPair(const char * passPhrase);
+	virtual XENCEncryptedData * setRSAKeyPair(const char * passPhrase,
+		XMLCh * Modulus,
+		XMLCh * Exponent,
+		XMLCh * P,
+		XMLCh * Q,
+		XMLCh * DP,
+		XMLCh * DQ,
+		XMLCh * InverseQ,
+		XMLCh * D,		
+		encryptionMethod em,
+		const XMLCh * algorithmURI = NULL);
+
 
 
 	/* Implemented from MessageAbstractType */
@@ -96,6 +110,10 @@
 
 	XERCES_CPP_NAMESPACE_QUALIFIER  DOMElement
 						* mp_privateKeyElement;
+
+	// To handle the cipher
+	XSECProvider	m_prov;
+
 	// Unimplemented
 	XKMSRegisterResultImpl(void);
 	XKMSRegisterResultImpl(const XKMSRegisterResultImpl &);