// role interface to verify the EE certificate.\r
\r
log.debug("attempting to match key information from peer with end-entity certificate");\r
- vector<XSECCryptoX509*> resolvedCerts;\r
while (keyInfoSource.hasNext()) {\r
- resolvedCerts.clear();\r
+ KeyResolver::ResolvedCertificates resolvedCerts;\r
if (0 == (keyResolver ? keyResolver : m_keyResolver)->resolveCertificates(keyInfoSource.next(),resolvedCerts)) {\r
log.debug("key information does not resolve to a certificate, skipping it");\r
continue;\r
}\r
\r
log.debug("checking if certificates contained within key information match end-entity certificate");\r
- if (resolvedCerts.front()->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {\r
+ if (resolvedCerts.v().front()->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {\r
log.error("only the OpenSSL XSEC provider is supported");\r
continue;\r
}\r
- else if (!X509_cmp(static_cast<OpenSSLCryptoX509*>(certEE)->getOpenSSLX509(),static_cast<OpenSSLCryptoX509*>(resolvedCerts.front())->getOpenSSLX509())) {\r
+ else if (!X509_cmp(static_cast<OpenSSLCryptoX509*>(certEE)->getOpenSSLX509(),static_cast<OpenSSLCryptoX509*>(resolvedCerts.v().front())->getOpenSSLX509())) {\r
log.info("end-entity certificate matches certificate from peer key information");\r
return true;\r
}\r
}\r
\r
/**\r
+ * A wrapper that handles disposal of certificates when required.\r
+ */\r
+ class XMLTOOL_API ResolvedCertificates {\r
+ MAKE_NONCOPYABLE(ResolvedCertificates);\r
+ bool m_owned;\r
+ std::vector<XSECCryptoX509*> m_certs;\r
+ public:\r
+ ResolvedCertificates() : m_owned(false) {}\r
+ ~ResolvedCertificates() {\r
+ if (m_owned) {\r
+ std::for_each(m_certs.begin(), m_certs.end(), xmltooling::cleanup<XSECCryptoX509>());\r
+ }\r
+ }\r
+ const std::vector<XSECCryptoX509*>& v() const {\r
+ return m_certs;\r
+ }\r
+ friend class XMLTOOL_API KeyResolver;\r
+ };\r
+\r
+ /**\r
* Returns a set of certificates based on the supplied KeyInfo information.\r
* The certificates must be cloned if kept beyond the lifetime of the KeyInfo source.\r
* \r
* @param keyInfo the key information\r
- * @param certs reference to vector to store certificates\r
+ * @param certs reference to object to hold certificates\r
* @return number of certificates returned\r
*/\r
virtual std::vector<XSECCryptoX509*>::size_type resolveCertificates(\r
- const KeyInfo* keyInfo, std::vector<XSECCryptoX509*>& certs\r
+ const KeyInfo* keyInfo, ResolvedCertificates& certs\r
) const;\r
\r
/**\r
* The certificates must be cloned if kept beyond the lifetime of the KeyInfo source.\r
* \r
* @param keyInfo the key information\r
- * @param certs reference to vector to store certificates\r
+ * @param certs reference to object to hold certificates\r
* @return number of certificates returned\r
*/\r
virtual std::vector<XSECCryptoX509*>::size_type resolveCertificates(\r
- DSIGKeyInfoList* keyInfo, std::vector<XSECCryptoX509*>& certs \r
+ DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs \r
) const;\r
\r
/**\r
\r
protected:\r
XSECCryptoKey* m_key;\r
+\r
+ /**\r
+ * Accessor for certificate vector from derived KeyResolver classes.\r
+ *\r
+ * @param certs certificate wrapper to access\r
+ * @return modifiable reference to vector inside wrapper\r
+ */\r
+ std::vector<XSECCryptoX509*>& accessCertificates(ResolvedCertificates& certs) const {\r
+ return certs.m_certs;\r
+ }\r
+\r
+ /**\r
+ * Accessor for certificate ownership flag from derived KeyResolver classes.\r
+ *\r
+ * @param certs certificate wrapper to access\r
+ * @return modifiable reference to ownership flag inside wrapper\r
+ */\r
+ bool& accessOwned(ResolvedCertificates& certs) const {\r
+ return certs.m_owned;\r
+ }\r
};\r
\r
/**\r
\r
XSECCryptoKey* resolveKey(const KeyInfo* keyInfo) const { return m_key ? m_key->clone() : NULL; }\r
XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const { return m_key ? m_key->clone() : NULL; }\r
- vector<XSECCryptoX509*>::size_type resolveCertificates(const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs) const {\r
- certs.assign(m_xseccerts.begin(), m_xseccerts.end());\r
- return certs.size();\r
+ vector<XSECCryptoX509*>::size_type resolveCertificates(const KeyInfo* keyInfo, ResolvedCertificates& certs) const {\r
+ accessCertificates(certs).assign(m_xseccerts.begin(), m_xseccerts.end());\r
+ accessOwned(certs) = false;\r
+ return accessCertificates(certs).size();\r
}\r
- vector<XSECCryptoX509*>::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, vector<XSECCryptoX509*>& certs) const {\r
- certs.assign(m_xseccerts.begin(), m_xseccerts.end());\r
- return certs.size();\r
+ vector<XSECCryptoX509*>::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs) const {\r
+ accessCertificates(certs).assign(m_xseccerts.begin(), m_xseccerts.end());\r
+ accessOwned(certs) = false;\r
+ return accessCertificates(certs).size();\r
}\r
\r
private:\r
\r
XSECCryptoKey* resolveKey(const KeyInfo* keyInfo) const;\r
XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const;\r
- vector<XSECCryptoX509*>::size_type resolveCertificates(const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs) const;\r
- vector<XSECCryptoX509*>::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, vector<XSECCryptoX509*>& certs) const;\r
+ vector<XSECCryptoX509*>::size_type resolveCertificates(const KeyInfo* keyInfo, ResolvedCertificates& certs) const;\r
+ vector<XSECCryptoX509*>::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs) const;\r
XSECCryptoX509CRL* resolveCRL(const KeyInfo* keyInfo) const;\r
XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const;\r
\r
}\r
\r
vector<XSECCryptoX509*>::size_type InlineKeyResolver::resolveCertificates(\r
- const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs\r
+ const KeyInfo* keyInfo, ResolvedCertificates& certs\r
) const\r
{\r
// Caching?\r
if (i != m_cache.end()) {\r
// Found in cache, so just return the results.\r
SharedLock locker(m_lock,false);\r
- certs.assign(i->second.m_certs.begin(), i->second.m_certs.end());\r
- return certs.size();\r
+ accessCertificates(certs).assign(i->second.m_certs.begin(), i->second.m_certs.end());\r
+ accessOwned(certs) = false;\r
+ return accessCertificates(certs).size();\r
}\r
else {\r
// Elevate lock.\r
i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first;\r
_resolve(i->first, i->second);\r
}\r
- certs.assign(i->second.m_certs.begin(), i->second.m_certs.end());\r
- return certs.size();\r
+ accessCertificates(certs).assign(i->second.m_certs.begin(), i->second.m_certs.end());\r
+ accessOwned(certs) = false;\r
+ return accessCertificates(certs).size();\r
}\r
}\r
- return _resolveCertificates(keyInfo, certs);\r
+ accessOwned(certs) = true;\r
+ return _resolveCertificates(keyInfo, accessCertificates(certs));\r
}\r
\r
XSECCryptoKey* InlineKeyResolver::resolveKey(DSIGKeyInfoList* keyInfo) const\r
}\r
\r
vector<XSECCryptoX509*>::size_type InlineKeyResolver::resolveCertificates(\r
- DSIGKeyInfoList* keyInfo, vector<XSECCryptoX509*>& certs\r
+ DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs\r
) const\r
{\r
- certs.clear();\r
+ accessCertificates(certs).clear();\r
+ accessOwned(certs) = false;\r
DSIGKeyInfoList::size_type sz = keyInfo->getSize();\r
- for (DSIGKeyInfoList::size_type i=0; certs.empty() && i<sz; ++i) {\r
+ for (DSIGKeyInfoList::size_type i=0; accessCertificates(certs).empty() && i<sz; ++i) {\r
if (keyInfo->item(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) {\r
DSIGKeyInfoX509* x509 = static_cast<DSIGKeyInfoX509*>(keyInfo->item(i));\r
int count = x509->getCertificateListSize();\r
for (int j=0; j<count; ++j) {\r
- certs.push_back(x509->getCertificateCryptoItem(j));\r
+ accessCertificates(certs).push_back(x509->getCertificateCryptoItem(j));\r
}\r
}\r
}\r
- return certs.size();\r
+ return accessCertificates(certs).size();\r
}\r
\r
XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(DSIGKeyInfoList* keyInfo) const\r
}
vector<XSECCryptoX509*>::size_type KeyResolver::resolveCertificates(
- const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs
+ const KeyInfo* keyInfo, ResolvedCertificates& certs
) const
{
return 0;
}
vector<XSECCryptoX509*>::size_type KeyResolver::resolveCertificates(
- DSIGKeyInfoList* keyInfo, vector<XSECCryptoX509*>& certs
+ DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs
) const
{
return 0;
auto_ptr<XSECCryptoX509CRL> crl(m_resolver->resolveCRL(kiObject.get()));\r
TSM_ASSERT("Unable to resolve CRL.", crl.get()!=NULL);\r
\r
- vector<XSECCryptoX509*> certs;\r
+ KeyResolver::ResolvedCertificates certs;\r
TSM_ASSERT_EQUALS("Wrong certificate count.", m_resolver->resolveCertificates(kiObject.get(), certs), 1);\r
}\r
};\r