# define XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE 1
# define XMLTOOLING_XERCESC_64BITSAFE 1
# define XMLTOOLING_XERCESC_INPUTSTREAM_HAS_CONTENTTYPE 1
+#else
+# define XMLTOOLING_XERCESC_HAS_XMLBYTE_RELEASE
#endif
/* Define to 1 if you have the `xsecsize_t' type. */
[AC_DEFINE([XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE], [1], [Define to 1 if Xerces DOM ID methods take extra parameter.])],
[AC_MSG_RESULT([no])])
+AC_MSG_CHECKING([whether Xerces XMLString::release(XMLByte**) exists])
+AC_TRY_COMPILE([#include <xercesc/util/XMLString.hpp>],
+ [using namespace XERCES_CPP_NAMESPACE;
+ XMLByte* buf=NULL;
+ XMLString::release(&buf);
+ ],
+ [AC_MSG_RESULT([yes])]
+ [AC_DEFINE([XMLTOOLING_XERCESC_HAS_XMLBYTE_RELEASE], [1], [Define to 1 if Xerces XMLString includes XMLByte release.])],
+ [AC_MSG_RESULT([no])])
+
# XML-Security settings
AC_ARG_WITH(xmlsec,
AC_HELP_STRING([--with-xmlsec=PATH], [where xmlsec is installed]),,
/**
* @deprecated
- * Returns the base64-encoded DER encoding of a certifiate's public key in SubjectPublicKeyInfo format.
+ * Returns the base64-encoded DER encoding of a certificate's public key in SubjectPublicKeyInfo format.
*
* @param cert the certificate's key to encode
* @param hash if true, the DER encoded data is hashed with SHA-1 before base64 encoding
* @return the base64 encoded key value
*/
static std::string getDEREncoding(const XSECCryptoX509& cert, bool hash=false, bool nowrap=true);
+
+ /**
+ * Decodes a DER-encoded public key.
+ *
+ * @param buf DER encoded data
+ * @param buflen length of data in bytes
+ * @param base64 true iff DER is base64-encoded
+ * @return the decoded public key, or nullptr
+ */
+ static XSECCryptoKey* fromDEREncoding(const char* buf, unsigned long buflen, bool base64=true);
+
+ /**
+ * Decodes a base64-encoded and DER-encoded public key.
+ *
+ * @param buf base64 and DER encoded data
+ * @return the decoded public key, or nullptr
+ */
+ static XSECCryptoKey* fromDEREncoding(const XMLCh* buf);
};
};
#include "security/BasicX509Credential.h"
#include "security/KeyInfoCredentialContext.h"
#include "security/KeyInfoResolver.h"
+#include "security/SecurityHelper.h"
#include "security/XSECCryptoX509CRL.h"
#include "signature/KeyInfo.h"
#include "signature/Signature.h"
#include <xercesc/util/XMLUniDefs.hpp>
#include <xsec/dsig/DSIGKeyInfoX509.hpp>
#include <xsec/enc/XSECKeyInfoResolverDefault.hpp>
-#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
-#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
-#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>
+#include <xsec/enc/XSECCryptoX509.hpp>
+#include <xsec/enc/XSECCryptoKeyRSA.hpp>
+#include <xsec/enc/XSECCryptoKeyDSA.hpp>
#include <xsec/enc/XSECCryptoException.hpp>
#include <xsec/framework/XSECException.hpp>
if (ret) {
ret->setId(nullptr);
ret->getRetrievalMethods().clear();
+ ret->getKeyInfoReferences().clear();
if (compact) {
ret->getKeyValues().clear();
+ ret->getDEREncodedKeyValues().clear();
ret->getSPKIDatas().clear();
ret->getPGPDatas().clear();
ret->getUnknownXMLObjects().clear();
for (VectorOf(X509Data)::size_type pos = 0; pos < x509Datas.size();) {
x509Datas[pos]->getX509Certificates().clear();
x509Datas[pos]->getX509CRLs().clear();
+ x509Datas[pos]->getOCSPResponses().clear();
x509Datas[pos]->getUnknownXMLObjects().clear();
if (x509Datas[pos]->hasChildren())
++pos;
// Check for ds:KeyValue
const vector<KeyValue*>& keyValues = keyInfo->getKeyValues();
- for (vector<KeyValue*>::const_iterator i=keyValues.begin(); i!=keyValues.end(); ++i) {
+ for (vector<KeyValue*>::const_iterator i = keyValues.begin(); i != keyValues.end(); ++i) {
try {
SchemaValidators.validate(*i); // see if it's a "valid" key
RSAKeyValue* rsakv = (*i)->getRSAKeyValue();
m_key = dsa.release();
return true;
}
+ ECKeyValue* eckv = (*i)->getECKeyValue();
+ if (eckv) {
+ log.warn("skipping ds11:ECKeyValue, not yet supported");
+ }
}
catch (ValidationException& ex) {
log.warn("skipping invalid ds:KeyValue (%s)", ex.what());
}
}
+ // Check for ds11:DEREncodedKeyValue
+ const vector<DEREncodedKeyValue*>& derValues = keyInfo->getDEREncodedKeyValues();
+ for (vector<DEREncodedKeyValue*>::const_iterator j = derValues.begin(); j != derValues.end(); ++j) {
+ log.debug("resolving ds11:DEREncodedKeyValue");
+ m_key = SecurityHelper::fromDEREncoding((*j)->getValue());
+ if (m_key)
+ return true;
+ log.warn("failed to resolve ds11:DEREncodedKeyValue");
+ }
+
+
if (followRefs) {
// Check for KeyInfoReference.
const XMLCh* fragID=NULL;
#include "util/NDC.h"
#include <fstream>
+#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
+#include <xsec/enc/XSECCryptoException.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>
+#include <xercesc/util/Base64.hpp>
using namespace xmltooling::logging;
using namespace xmltooling;
{
return getDEREncoding(cred, hash ? "SHA1" : nullptr, nowrap);
}
+
+XSECCryptoKey* SecurityHelper::fromDEREncoding(const char* buf, unsigned long buflen, bool base64)
+{
+ xsecsize_t x;
+ XMLByte* decoded=nullptr;
+ if (base64) {
+ decoded = xercesc::Base64::decode(reinterpret_cast<const XMLByte*>(buf), &x);
+ if (!decoded) {
+ Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").error("base64 decode failed");
+ return nullptr;
+ }
+ }
+
+ BIO* b = BIO_new_mem_buf((void*)(base64 ? (char*)decoded : buf), (base64 ? x : buflen));
+ EVP_PKEY* pkey = d2i_PUBKEY_bio(b, nullptr);
+ BIO_free(b);
+ if (base64) {
+#ifdef XMLTOOLING_XERCESC_HAS_XMLBYTE_RELEASE
+ XMLString::release(&decoded);
+#else
+ XMLString::release((char**)&decoded);
+#endif
+ }
+
+ if (pkey) {
+ // Now map it to an XSEC wrapper.
+ XSECCryptoKey* ret = nullptr;
+ try {
+ switch (pkey->type) {
+ case EVP_PKEY_RSA:
+ ret = new OpenSSLCryptoKeyRSA(pkey);
+ break;
+
+ case EVP_PKEY_DSA:
+ ret = new OpenSSLCryptoKeyDSA(pkey);
+ break;
+
+ default:
+ Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").error("unsupported public key type");
+ }
+ }
+ catch (XSECCryptoException& ex) {
+ Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").error(ex.getMsg());
+ }
+ EVP_PKEY_free(pkey);
+ return ret;
+ }
+
+ return nullptr;
+}
+
+XSECCryptoKey* SecurityHelper::fromDEREncoding(const XMLCh* buf)
+{
+ xsecsize_t x;
+ XMLByte* decoded = xercesc::Base64::decodeToXMLByte(buf, &x);
+ if (!decoded) {
+ Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").error("base64 decode failed");
+ return nullptr;
+ }
+ XSECCryptoKey* ret = fromDEREncoding((const char*)decoded, x, false);
+#ifdef XMLTOOLING_XERCESC_HAS_XMLBYTE_RELEASE
+ XMLString::release(&decoded);
+#else
+ XMLString::release((char**)&decoded);
+#endif
+ return ret;
+}
TSM_ASSERT_EQUALS("Wrong certificate count.", cred->getEntityCertificateChain().size(), 1);
TSM_ASSERT_EQUALS("Wrong CRL count.", cred->getCRLs().size(), 3);
}
+
+ void testDER() {
+ string path=data_path + "KeyInfo5.xml";
+ ifstream fs(path.c_str());
+ DOMDocument* doc=XMLToolingConfig::getConfig().getValidatingParser().parse(fs);
+ TS_ASSERT(doc!=nullptr);
+ const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+ TS_ASSERT(b!=nullptr);
+ auto_ptr<KeyInfo> kiObject(dynamic_cast<KeyInfo*>(b->buildFromDocument(doc)));
+ TS_ASSERT(kiObject.get()!=nullptr);
+
+ auto_ptr<X509Credential> cred(dynamic_cast<X509Credential*>(m_resolver->resolve(kiObject.get())));
+ TSM_ASSERT("Unable to resolve KeyInfo into Credential.", cred.get()!=nullptr);
+
+ TSM_ASSERT("Unable to resolve public key.", cred->getPublicKey()!=nullptr);
+ TSM_ASSERT_EQUALS("Unexpected key type.", cred->getPublicKey()->getKeyType(), XSECCryptoKey::KEY_RSA_PUBLIC);
+ TSM_ASSERT_EQUALS("Wrong certificate count.", cred->getEntityCertificateChain().size(), 0);
+ TSM_ASSERT_EQUALS("Wrong CRL count.", cred->getCRLs().size(), 0);
+ }
};
-<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ds11="http://www.w3.org/2009/xmldsig11#">\r
- <ds:KeyValue>\r
- <ds11:ECKeyValue>\r
- <ds11:NamedCurve URI="urn:oid:1.2.840.10045.3.1.7"/>\r
- <ds11:PublicKey>\r
- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER9z9tFObV/MdgFT0IDEUq6b8VZFL\r
- sj+qeNjJMVgEIrioShi5HfJfZq/aLuTvt5DZEybsFNC1Fit5cYx7+0DN3g==\r
- </ds11:PublicKey>\r
- </ds11:ECKeyValue>\r
- </ds:KeyValue>\r
-</ds:KeyInfo>\r
+<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ds11="http://www.w3.org/2009/xmldsig11#">
+ <ds:KeyValue>
+ <ds11:ECKeyValue>
+ <ds11:NamedCurve URI="urn:oid:1.2.840.10045.3.1.7"/>
+ <ds11:PublicKey>
+ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER9z9tFObV/MdgFT0IDEUq6b8VZFL
+ sj+qeNjJMVgEIrioShi5HfJfZq/aLuTvt5DZEybsFNC1Fit5cYx7+0DN3g==
+ </ds11:PublicKey>
+ </ds11:ECKeyValue>
+ </ds:KeyValue>
+</ds:KeyInfo>
--- /dev/null
+<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ds11="http://www.w3.org/2009/xmldsig11#">
+ <ds11:DEREncodedKeyValue>
+ MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQsVsByijs8ArbG2VIYc0I13Mi
+ hwO865fFKqAsru4Wis6xJiO7nZewei/s8YJ5lUc+M7MNTybFWFLfcxugAQvj+17c
+ eOk5P4eYDuoVi+FwcxVLisLDEWdEQdLAL+okLc+kwsh+OzgUiUjduIe3v74lENGb
+ SmLCaP6/AR656IiZNQIDAQAB
+ </ds11:DEREncodedKeyValue>
+</ds:KeyInfo>