XMLToolingConfig.h
encinclude_HEADERS = \
+ encryption/Decrypter.h \
encryption/Encrypter.h \
encryption/Encryption.h
siginclude_HEADERS = \
signature/ContentReference.h \
signature/KeyInfo.h \
+ signature/KeyResolver.h \
signature/Signature.h \
signature/SignatureValidator.h
if BUILD_XMLSEC
xmlsec_sources = \
+ encryption/impl/Decrypter.cpp \
encryption/impl/Encrypter.cpp \
signature/impl/SignatureValidator.cpp \
signature/impl/XMLSecSignatureImpl.cpp
--- /dev/null
+/*
+ * Copyright 2001-2006 Internet2
+ *
+ * Licensed 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.
+ */
+
+/**
+ * @file Encrypter.h
+ *
+ * Methods for encrypting XMLObjects and other data.
+ */
+
+#if !defined(__xmltooling_decrypter_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_decrypter_h__
+
+#include <xmltooling/encryption/Encryption.h>
+#include <xmltooling/signature/KeyResolver.h>
+
+#include <xsec/enc/XSECCryptoKey.hpp>
+#include <xsec/xenc/XENCCipher.hpp>
+
+namespace xmlencryption {
+
+ /**
+ * Wrapper API for XML Decryption functionality.
+ */
+ class XMLTOOL_API Decrypter
+ {
+ public:
+ /**
+ * Constructor.
+ * Resolvers will be deleted when Decrypter is.
+ *
+ * @param KEKresolver resolves key decryption key based on KeyInfo information
+ * @param resolver resolves data decryption key based on KeyInfo information
+ */
+ Decrypter(xmlsignature::KeyResolver* KEKresolver=NULL, xmlsignature::KeyResolver* resolver=NULL)
+ : m_cipher(NULL), m_resolver(resolver), m_KEKresolver(KEKresolver) {
+ }
+
+ ~Decrypter();
+
+ /**
+ * Replace the current KeyResolver interface, if any, with a new one.
+ *
+ * @param resolver the KeyResolver to attach
+ */
+ void setKeyResolver(xmlsignature::KeyResolver* resolver) {
+ delete m_resolver;
+ m_resolver=resolver;
+ }
+
+ /**
+ * Replace the current key encryption KeyResolver interface, if any, with a new one.
+ *
+ * @param resolver the KeyResolver to attach
+ */
+ void setKEKResolver(xmlsignature::KeyResolver* resolver) {
+ delete m_KEKresolver;
+ m_KEKresolver=resolver;
+ }
+
+ /**
+ * Decrypts the supplied information and returns the resulting as a DOM
+ * fragment owned by the document associated with the marshalled EncryptedData
+ * object.
+ *
+ * Note that the DOM nodes will be invalidated once that document
+ * is released. The caller should therefore process the DOM fragment as
+ * required and drop all references to it before that happens. The usual
+ * approach should be to unmarshall the DOM and then release it, or the
+ * DOM can also be imported into a separately owned document.
+ *
+ * @param encryptedData the encrypted data to decrypt
+ * @return the decrypted DOM fragment
+ */
+ DOMDocumentFragment* decryptData(EncryptedData* encryptedData);
+
+ /**
+ * Decrypts the supplied information and returns the resulting key.
+ * The caller is responsible for deleting the key. The algorithm of the
+ * key must be supplied by the caller based on knowledge of the associated
+ * EncryptedData information.
+ *
+ * @param encryptedKey the encrypted/wrapped key to decrypt
+ * @param algorithm the algorithm associated with the decrypted key
+ * @return the decrypted key
+ */
+ XSECCryptoKey* decryptKey(EncryptedKey* encryptedKey, const XMLCh* algorithm);
+
+ private:
+ XENCCipher* m_cipher;
+ xmlsignature::KeyResolver* m_resolver;
+ xmlsignature::KeyResolver* m_KEKresolver;
+ };
+
+ DECL_XMLTOOLING_EXCEPTION(DecryptionException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmlencryption,xmltooling::XMLToolingException,Exceptions in decryption processing);
+
+};
+
+#endif /* __xmltooling_decrypter_h__ */
/**
* Encrypts the supplied element and returns the resulting object.
- * The returned object will be unmarshalled around a DOM tree created
- * using the encrypted element's owning document.
*
* If an encryption algorithm is set, but no key, a random key will be
- * generated iff keParams is non-NULL and the algorithm is known.
+ * generated iff kencParams is non-NULL and the algorithm is known.
*
* If key encryption parameters are supplied, then the encryption key
* is wrapped and the result placed into an EncryptedKey object in the
* KeyInfo of the returned EncryptedData.
*
- * @param element the DOM element to encrypt
- * @param keParams key encryption settings, or NULL
+ * @param element the DOM element to encrypt
+ * @param encParams primary encryption settings
+ * @param kencParams key encryption settings, or NULL
*/
EncryptedData* encryptElement(DOMElement* element, EncryptionParams& encParams, KeyEncryptionParams* kencParams=NULL);
/**
* Encrypts the supplied element's children and returns the resulting object.
- * The returned object will be unmarshalled around a DOM tree created
- * using the encrypted content's owning document.
*
* If an encryption algorithm is set, but no key, a random key will be
- * generated iff keParams is non-NULL and the algorithm is known.
+ * generated iff kencParams is non-NULL and the algorithm is known.
* If key encryption parameters are supplied, then the encryption key
* is wrapped and the result placed into an EncryptedKey object in the
* KeyInfo of the returned EncryptedData.
*
- * @param element parent element of children to encrypt
- * @param keParams key encryption settings, or NULL
+ * @param element parent element of children to encrypt
+ * @param encParams primary encryption settings
+ * @param kencParams key encryption settings, or NULL
*/
EncryptedData* encryptElementContent(DOMElement* element, EncryptionParams& encParams, KeyEncryptionParams* kencParams=NULL);
/**
* Encrypts the supplied input stream and returns the resulting object.
- * The returned object will be unmarshalled around a DOM tree created
- * using the encrypted element's owning document.
*
* If an encryption algorithm is set, but no key, a random key will be
- * generated iff keParams is non-NULL and the algorithm is known.
+ * generated iff kencParams is non-NULL and the algorithm is known.
* If key encryption parameters are supplied, then the encryption key
* is wrapped and the result placed into an EncryptedKey object in the
* KeyInfo of the returned EncryptedData.
*
- * @param input the stream to encrypt
- * @param keParams key encryption settings, or NULL
+ * @param input the stream to encrypt
+ * @param encParams primary encryption settings
+ * @param kencParams key encryption settings, or NULL
*/
EncryptedData* encryptStream(std::istream& input, EncryptionParams& encParams, KeyEncryptionParams* kencParams=NULL);
+ /**
+ * Encrypts the supplied key and returns the resulting object.
+ *
+ * @param keyBuffer raw key material to encrypt
+ * @param keyBufferSize size in bytes of raw key material
+ * @param kencParams key encryption settings
+ */
+ EncryptedKey* encryptKey(const unsigned char* keyBuffer, unsigned int keyBufferSize, KeyEncryptionParams& kencParams);
+
private:
void checkParams(EncryptionParams& encParams, KeyEncryptionParams* kencParams);
EncryptedData* decorateAndUnmarshall(EncryptionParams& encParams, KeyEncryptionParams* kencParams);
--- /dev/null
+/*
+ * Copyright 2001-2006 Internet2
+ *
+ * Licensed 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.
+ */
+
+/**
+ * Encrypter.cpp
+ *
+ * Methods for encrypting XMLObjects and other data.
+ */
+
+#include "internal.h"
+#include "encryption/Decrypter.h"
+
+#include <log4cpp/Category.hh>
+#include <xsec/enc/XSECCryptoException.hpp>
+#include <xsec/framework/XSECException.hpp>
+#include <xsec/framework/XSECAlgorithmMapper.hpp>
+#include <xsec/framework/XSECAlgorithmHandler.hpp>
+#include <xsec/xenc/XENCEncryptedData.hpp>
+#include <xsec/xenc/XENCEncryptedKey.hpp>
+
+using namespace xmlencryption;
+using namespace xmlsignature;
+using namespace xmltooling;
+using namespace std;
+
+Decrypter::~Decrypter()
+{
+ XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher);
+ delete m_resolver;
+ delete m_KEKresolver;
+}
+
+DOMDocumentFragment* Decrypter::decryptData(EncryptedData* encryptedData)
+{
+ if (encryptedData->getDOM()==NULL)
+ throw DecryptionException("The object must be marshalled before decryption.");
+
+ // We can reuse the cipher object if the document hasn't changed.
+
+ if (m_cipher && m_cipher->getDocument()!=encryptedData->getDOM()->getOwnerDocument()) {
+ XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher);
+ m_cipher=NULL;
+ }
+
+ if (!m_cipher)
+ m_cipher=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newCipher(encryptedData->getDOM()->getOwnerDocument());
+
+ try {
+ // Resolve decryption key.
+ XSECCryptoKey* key=NULL;
+ if (m_resolver)
+ key=m_resolver->resolveKey(encryptedData->getKeyInfo());
+ if (!key) {
+ // See if there's an encrypted key present. We'll need the algorithm...
+ const XMLCh* algorithm=
+ encryptedData->getEncryptionMethod() ? encryptedData->getEncryptionMethod()->getAlgorithm() : NULL;
+ if (!algorithm)
+ throw DecryptionException("No EncryptionMethod/@Algorithm set, key decryption cannot proceed.");
+
+ if (encryptedData->getKeyInfo()) {
+ const vector<XMLObject*>& others=const_cast<const KeyInfo*>(encryptedData->getKeyInfo())->getOthers();
+ for (vector<XMLObject*>::const_iterator i=others.begin(); i!=others.end(); i++) {
+ EncryptedKey* encKey=dynamic_cast<EncryptedKey*>(*i);
+ if (encKey) {
+ try {
+ key=decryptKey(encKey, algorithm);
+ }
+ catch (DecryptionException& e) {
+ log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".Decrypter").warn(e.what());
+ }
+ }
+ }
+ }
+
+ if (!key)
+ throw DecryptionException("Unable to resolve a decryption key.");
+ }
+
+ m_cipher->setKey(key);
+ DOMNode* ret=m_cipher->decryptElementDetached(encryptedData->getDOM());
+ if (ret->getNodeType()!=DOMNode::DOCUMENT_FRAGMENT_NODE) {
+ ret->release();
+ throw DecryptionException("Decryption operation did not result in DocumentFragment.");
+ }
+ return static_cast<DOMDocumentFragment*>(ret);
+ }
+ catch(XSECException& e) {
+ auto_ptr_char temp(e.getMsg());
+ throw DecryptionException(string("XMLSecurity exception while decrypting: ") + temp.get());
+ }
+ catch(XSECCryptoException& e) {
+ throw DecryptionException(string("XMLSecurity exception while decrypting: ") + e.getMsg());
+ }
+}
+
+XSECCryptoKey* Decrypter::decryptKey(EncryptedKey* encryptedKey, const XMLCh* algorithm)
+{
+ if (encryptedKey->getDOM()==NULL)
+ throw DecryptionException("The object must be marshalled before decryption.");
+
+ // We can reuse the cipher object if the document hasn't changed.
+
+ if (m_cipher && m_cipher->getDocument()!=encryptedKey->getDOM()->getOwnerDocument()) {
+ XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher);
+ m_cipher=NULL;
+ }
+
+ if (!m_cipher)
+ m_cipher=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newCipher(encryptedKey->getDOM()->getOwnerDocument());
+
+ try {
+ // Resolve key decryption key.
+ XSECCryptoKey* key=NULL;
+ if (m_KEKresolver)
+ key=m_KEKresolver->resolveKey(encryptedKey->getKeyInfo());
+ if (!key)
+ throw DecryptionException("Unable to resolve a key decryption key.");
+ m_cipher->setKEK(key);
+
+ XMLByte buffer[1024];
+ int keySize = m_cipher->decryptKey(encryptedKey->getDOM(), buffer, 1024);
+ if (keySize > 0) {
+ // Try to map the key.
+ XSECAlgorithmHandler* handler = XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(algorithm);
+ if (handler != NULL)
+ return handler->createKeyForURI(algorithm, buffer, keySize);
+ throw DecryptionException("Unrecognized algorithm, could not build object around decrypted key.");
+ }
+ throw DecryptionException("Unable to decrypt key.");
+ }
+ catch(XSECException& e) {
+ auto_ptr_char temp(e.getMsg());
+ throw DecryptionException(string("XMLSecurity exception while decrypting: ") + temp.get());
+ }
+ catch(XSECCryptoException& e) {
+ throw DecryptionException(string("XMLSecurity exception while decrypting: ") + e.getMsg());
+ }
+}
#include "internal.h"
#include "encryption/Encrypter.h"
-#include <xsec/enc/openssl/OpenSSLCryptoSymmetricKey.hpp>
#include <xsec/enc/XSECCryptoException.hpp>
#include <xsec/framework/XSECException.hpp>
+#include <xsec/framework/XSECAlgorithmMapper.hpp>
+#include <xsec/framework/XSECAlgorithmHandler.hpp>
#include <xsec/xenc/XENCEncryptedData.hpp>
#include <xsec/xenc/XENCEncryptedKey.hpp>
if (!encParams.m_key) {
// We have to have a raw key now, so we need to build a wrapper around it.
- if (XMLString::equals(encParams.m_algorithm,DSIGConstants::s_unicodeStrURI3DES_CBC)) {
- encParams.m_key=new OpenSSLCryptoSymmetricKey(XSECCryptoSymmetricKey::KEY_3DES_192);
- }
- else if (XMLString::equals(encParams.m_algorithm,DSIGConstants::s_unicodeStrURIAES128_CBC)) {
- encParams.m_key=new OpenSSLCryptoSymmetricKey(XSECCryptoSymmetricKey::KEY_AES_128);
- }
- else if (XMLString::equals(encParams.m_algorithm,DSIGConstants::s_unicodeStrURIAES192_CBC)) {
- encParams.m_key=new OpenSSLCryptoSymmetricKey(XSECCryptoSymmetricKey::KEY_AES_192);
- }
- else if (XMLString::equals(encParams.m_algorithm,DSIGConstants::s_unicodeStrURIAES256_CBC)) {
- encParams.m_key=new OpenSSLCryptoSymmetricKey(XSECCryptoSymmetricKey::KEY_AES_256);
- }
- else {
- throw EncryptionException("Unrecognized encryption algorithm, unable to build key wrapper.");
- }
- static_cast<OpenSSLCryptoSymmetricKey*>(encParams.m_key)->setKey(encParams.m_keyBuffer, encParams.m_keyBufferSize);
+ XSECAlgorithmHandler* handler =XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(encParams.m_algorithm);
+ if (handler != NULL)
+ encParams.m_key = handler->createKeyForURI(
+ encParams.m_algorithm,const_cast<unsigned char*>(encParams.m_keyBuffer),encParams.m_keyBufferSize
+ );
+
+ if (!encParams.m_key)
+ throw EncryptionException("Unable to build wrapper for key, unknown algorithm?");
}
// Set the encryption key.
xmlObject.release();
return xmlEncData;
}
+
+EncryptedKey* Encrypter::encryptKey(const unsigned char* keyBuffer, unsigned int keyBufferSize, KeyEncryptionParams& kencParams)
+{
+ // Get a fresh cipher object and document.
+
+ if (m_cipher) {
+ XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher);
+ m_cipher=NULL;
+ }
+
+ DOMDocument* doc=NULL;
+ try {
+ doc=XMLToolingConfig::getConfig().getParser().newDocument();
+ m_cipher=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newCipher(doc);
+ m_cipher->setKEK(kencParams.m_key->clone());
+ auto_ptr<XENCEncryptedKey> encKey(m_cipher->encryptKey(keyBuffer, keyBufferSize, ENCRYPT_NONE, kencParams.m_algorithm));
+
+ EncryptedKey* xmlEncKey=NULL;
+ auto_ptr<XMLObject> xmlObjectKey(XMLObjectBuilder::buildOneFromElement(encKey->getElement()));
+ if (!(xmlObjectKey.get()) || !(xmlEncKey=dynamic_cast<EncryptedKey*>(xmlObjectKey.get())))
+ throw EncryptionException("Unable to unmarshall into EncryptedKey object.");
+
+ xmlEncKey->releaseThisAndChildrenDOM();
+
+ // KeyInfo?
+ if (kencParams.m_keyInfo) {
+ xmlEncKey->setKeyInfo(kencParams.m_keyInfo);
+ kencParams.m_keyInfo=NULL; // transfer ownership
+ }
+
+ doc->release();
+ xmlObjectKey.release();
+ return xmlEncKey;
+ }
+ catch(XSECException& e) {
+ doc->release();
+ auto_ptr_char temp(e.getMsg());
+ throw EncryptionException(string("XMLSecurity exception while encrypting: ") + temp.get());
+ }
+ catch(XSECCryptoException& e) {
+ doc->release();
+ throw EncryptionException(string("XMLSecurity exception while encrypting: ") + e.getMsg());
+ }
+ catch (...) {
+ doc->release();
+ throw;
+ }
+}
--- /dev/null
+/*\r
+ * Copyright 2001-2006 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * @file KeyResolver.h\r
+ * \r
+ * Resolves keys based on KeyInfo information or other external factors. \r
+ */\r
+\r
+#if !defined(__xmltooling_keyres_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
+#define __xmltooling_keyres_h__\r
+\r
+#include <xmltooling/signature/KeyInfo.h>\r
+\r
+#include <xsec/dsig/DSIGKeyInfoList.hpp>\r
+#include <xsec/enc/XSECCryptoKey.hpp>\r
+\r
+namespace xmlsignature {\r
+\r
+ /**\r
+ * An API for resolving decryption keys.\r
+ * Can be used during both data and key decryption.\r
+ */\r
+ class XMLTOOL_API KeyResolver {\r
+ public:\r
+ /**\r
+ * Constructor based on a single externally supplied decryption key.\r
+ * The key will be destroyed when the resolver is. \r
+ * \r
+ * @param key external decryption key\r
+ */\r
+ KeyResolver(XSECCryptoKey* key=NULL) : m_key(key) {}\r
+ \r
+ virtual ~KeyResolver() {\r
+ delete m_key;\r
+ }\r
+ \r
+ /**\r
+ * Returns a key based on the supplied KeyInfo information.\r
+ * The caller must delete the key when done with it.\r
+ * \r
+ * @param keyInfo the key information\r
+ * @return the resolved key\r
+ */\r
+ virtual XSECCryptoKey* resolveKey(KeyInfo* keyInfo) {\r
+ return m_key ? m_key->clone() : NULL;\r
+ }\r
+\r
+ /**\r
+ * Returns a key based on the supplied KeyInfo information.\r
+ * The caller must delete the key when done with it.\r
+ * \r
+ * @param keyInfo the key information\r
+ * @return the resolved key\r
+ */\r
+ virtual XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo=NULL) {\r
+ return m_key ? m_key->clone() : NULL;\r
+ }\r
+ \r
+ /**\r
+ * Creates a copy of the resolver.\r
+ * \r
+ * @return the cloned resolver\r
+ */\r
+ virtual KeyResolver* clone() const {\r
+ return new KeyResolver(m_key ? m_key->clone() : NULL);\r
+ }\r
+ \r
+ protected:\r
+ XSECCryptoKey* m_key;\r
+ };\r
+\r
+};\r
+\r
+#endif /* __xmltooling_keyres_h__ */\r
#if !defined(__xmltooling_sigval_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
#define __xmltooling_sigval_h__\r
\r
+#include <xmltooling/signature/KeyResolver.h>\r
#include <xmltooling/signature/Signature.h>\r
#include <xmltooling/validation/Validator.h>\r
\r
namespace xmlsignature {\r
\r
/**\r
- * Validator for signatures based on an externally-supplied key.\r
+ * Validator for signatures based on a KeyResolver\r
*/\r
class XMLTOOL_API SignatureValidator : public virtual xmltooling::Validator\r
{\r
/**\r
* Constructor\r
* \r
- * @param key the verification key to use, will be freed by Validator\r
+ * @param resolver the key resolver to use, will be freed by Validator\r
*/\r
- SignatureValidator(XSECCryptoKey* key) : m_key(key) {\r
- if (!key)\r
- throw xmltooling::ValidationException("Verification key cannot be NULL.");\r
+ SignatureValidator(KeyResolver* resolver) : m_resolver(resolver) {\r
}\r
\r
virtual ~SignatureValidator() {\r
- delete m_key;\r
+ delete m_resolver;\r
}\r
\r
void validate(const xmltooling::XMLObject* xmlObject) const;\r
SignatureValidator* clone() const {\r
return new SignatureValidator(*this);\r
}\r
+\r
+ /**\r
+ * Replace the current KeyResolver, if any, with a new one.\r
+ * \r
+ * @param resolver the KeyResolver to attach \r
+ */\r
+ void setKeyResolver(KeyResolver* resolver) {\r
+ delete m_resolver;\r
+ m_resolver=resolver;\r
+ }\r
\r
protected:\r
SignatureValidator(const SignatureValidator& src) {\r
- m_key=src.m_key->clone();\r
+ m_resolver=src.m_resolver ? src.m_resolver->clone() : NULL;\r
}\r
\r
- private:\r
- XSECCryptoKey* m_key;\r
+ KeyResolver* m_resolver;\r
};\r
\r
};\r
DSIGSignature* sig=sigObj->getXMLSignature();\r
if (!sig)\r
throw ValidationException("Signature does not exist yet.");\r
+ else if (!m_resolver)\r
+ throw ValidationException("No KeyResolver set on Validator.");\r
\r
try {\r
- sig->setSigningKey(m_key->clone());\r
+ XSECCryptoKey* key=m_resolver->resolveKey(sig->getKeyInfoList());\r
+ if (!key)\r
+ throw ValidationException("Unable to resolve signing key.");\r
+ sig->setSigningKey(key);\r
if (!sig->verify())\r
throw ValidationException("Digital signature does not validate with the given key.");\r
}\r
Name="impl"\r
>\r
<File\r
+ RelativePath=".\encryption\impl\Decrypter.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\encryption\impl\Encrypter.cpp"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath=".\signature\KeyResolver.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\signature\Signature.h"\r
>\r
</File>\r
Name="encryption"\r
>\r
<File\r
+ RelativePath=".\encryption\Decrypter.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\encryption\Encrypter.h"\r
>\r
</File>\r
--- /dev/null
+/*\r
+ * Copyright 2001-2005 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "XMLObjectBaseTestCase.h"\r
+\r
+#include <xmltooling/encryption/Decrypter.h>\r
+#include <xmltooling/encryption/Encrypter.h>\r
+\r
+#include <fstream>\r
+#include <openssl/pem.h>\r
+#include <xercesc/util/XMLUniDefs.hpp>\r
+#include <xsec/dsig/DSIGReference.hpp>\r
+#include <xsec/enc/XSECKeyInfoResolverDefault.hpp>\r
+#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>\r
+#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>\r
+#include <xsec/enc/XSECCryptoException.hpp>\r
+#include <xsec/framework/XSECException.hpp>\r
+\r
+using namespace xmlencryption;\r
+\r
+class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {\r
+public:\r
+ void operator()(X509Data* bag, XSECCryptoX509* cert) const {\r
+ safeBuffer& buf=cert->getDEREncodingSB();\r
+ X509Certificate* x=X509CertificateBuilder::buildX509Certificate();\r
+ x->setValue(buf.sbStrToXMLCh());\r
+ bag->getX509Certificates().push_back(x);\r
+ }\r
+};\r
+\r
+class EncryptionTest : public CxxTest::TestSuite {\r
+ XSECCryptoKey* m_key;\r
+ vector<XSECCryptoX509*> m_certs;\r
+public:\r
+ void setUp() {\r
+ string keypath=data_path + "key.pem";\r
+ BIO* in=BIO_new(BIO_s_file_internal());\r
+ if (in && BIO_read_filename(in,keypath.c_str())>0) {\r
+ EVP_PKEY* pkey=PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);\r
+ if (pkey) {\r
+ m_key=new OpenSSLCryptoKeyRSA(pkey);\r
+ EVP_PKEY_free(pkey);\r
+ }\r
+ }\r
+ if (in) BIO_free(in);\r
+ TS_ASSERT(m_key!=NULL);\r
+\r
+ string certpath=data_path + "cert.pem";\r
+ in=BIO_new(BIO_s_file_internal());\r
+ if (in && BIO_read_filename(in,certpath.c_str())>0) {\r
+ X509* x=NULL;\r
+ while (x=PEM_read_bio_X509(in,NULL,NULL,NULL)) {\r
+ m_certs.push_back(new OpenSSLCryptoX509(x));\r
+ X509_free(x);\r
+ }\r
+ }\r
+ if (in) BIO_free(in);\r
+ TS_ASSERT(m_certs.size()>0);\r
+ \r
+ }\r
+\r
+ void tearDown() {\r
+ delete m_key;\r
+ for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());\r
+ }\r
+\r
+ void testBasic() {\r
+ TS_TRACE("testBasic");\r
+\r
+ string path=data_path + "ComplexXMLObject.xml";\r
+ ifstream fs(path.c_str());\r
+ DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
+ TS_ASSERT(doc!=NULL);\r
+\r
+ try {\r
+ Encrypter encrypter;\r
+ Encrypter::EncryptionParams ep;\r
+ Encrypter::KeyEncryptionParams kep(DSIGConstants::s_unicodeStrURIRSA_1_5,m_key->clone());\r
+ auto_ptr<EncryptedData> encData(encrypter.encryptElement(doc->getDocumentElement(),ep,&kep));\r
+\r
+ string buf;\r
+ XMLHelper::serialize(encData->marshall(), buf);\r
+ istringstream is(buf);\r
+ DOMDocument* doc2=XMLToolingConfig::getConfig().getValidatingParser().parse(is);\r
+ auto_ptr<EncryptedData> encData2(\r
+ dynamic_cast<EncryptedData*>(XMLObjectBuilder::buildOneFromElement(doc2->getDocumentElement(),true))\r
+ );\r
+\r
+ Decrypter decrypter(new KeyResolver(m_key->clone()));\r
+ DOMDocumentFragment* frag = decrypter.decryptData(encData2.get());\r
+ XMLHelper::serialize(static_cast<DOMElement*>(frag->getFirstChild()), buf);\r
+ TS_TRACE(buf.c_str());\r
+ TS_ASSERT(doc->getDocumentElement()->isEqualNode(frag->getFirstChild()));\r
+ frag->release();\r
+ doc->release();\r
+ }\r
+ catch (XMLToolingException& e) {\r
+ TS_TRACE(e.what());\r
+ doc->release();\r
+ throw;\r
+ }\r
+ }\r
+\r
+};\r
if BUILD_XMLSEC
xmlsec_sources = \
+ EncryptionTest.h \
SignatureTest.h
else
xmlsec_sources =
}\r
\r
public:\r
- TestValidator(const XMLCh* uri, XSECCryptoKey* key) : SignatureValidator(key) {\r
+ TestValidator(const XMLCh* uri, XSECCryptoKey* key) : SignatureValidator(new KeyResolver(key)) {\r
m_uri=XMLString::replicate(uri);\r
}\r
\r
<?xml version="1.0" encoding="UTF-8"?>
<products>
- <product id="1144"
- xmlns="http://example.com/product-info"
- xmlns:html="http://www.w3.org/1999/xhtml"
- >
+ <product id="1144" xmlns="http://example.com/product-info">
<name xml:lang="en">Python Perfect IDE</name>
<description>
Uses mind-reading technology to anticipate and accommodate
all user needs in Python development. Implements all
- <html:code>from __future__ import</html:code> features though
+ <html:code xmlns:html="http://www.w3.org/1999/xhtml">from __future__ import</html:code> features though
the year 3000. Works well with <code>1166</code>.
</description>
</product>
<p:product id="1166" xmlns:p="http://example.com/product-info">
<p:name>XSLT Perfect IDE</p:name>
- <p:description
- xmlns:html="http://www.w3.org/1999/xhtml"
- xmlns:xl="http://www.w3.org/1999/xlink"
- >
+ <p:description>
<p:code>red</p:code>
- <html:code>blue</html:code>
- <html:div>
- <ref xl:type="simple" xl:href="index.xml">A link</ref>
+ <html:code xmlns:html="http://www.w3.org/1999/xhtml">blue</html:code>
+ <html:div xmlns:html="http://www.w3.org/1999/xhtml">
+ <ref xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="index.xml">A link</ref>
</html:div>
</p:description>
</p:product>
>\r
</File>\r
<File\r
+ RelativePath=".\EncryptionTest.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\ExceptionTest.cpp"\r
>\r
</File>\r
</FileConfiguration>\r
</File>\r
<File\r
+ RelativePath=".\EncryptionTest.h"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ CommandLine="\perl\bin\perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o "$(InputName)".cpp "$(InputPath)""\r
+ Outputs=""$(InputName)".cpp"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ CommandLine="\perl\bin\perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o "$(InputName)".cpp "$(InputPath)""\r
+ Outputs=""$(InputName)".cpp"\r
+ />\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
RelativePath=".\ExceptionTest.h"\r
>\r
<FileConfiguration\r