+
+void FilesystemCredentialResolver::attach(SSL_CTX* ctx) const
+{
+#ifdef _DEBUG
+ NDC ndc("attach");
+#endif
+
+ // Attach key.
+ SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
+ SSL_CTX_set_default_passwd_cb_userdata(ctx, const_cast<char*>(m_keypass.c_str()));
+
+ int ret=0;
+ switch (m_keyformat) {
+ case PEM:
+ ret=SSL_CTX_use_PrivateKey_file(ctx, m_keypath.c_str(), m_keyformat);
+ break;
+
+ case DER:
+ ret=SSL_CTX_use_RSAPrivateKey_file(ctx, m_keypath.c_str(), m_keyformat);
+ break;
+
+ default: {
+ BIO* in=BIO_new(BIO_s_file_internal());
+ if (in && BIO_read_filename(in,m_keypath.c_str())>0) {
+ EVP_PKEY* pkey=NULL;
+ PKCS12* p12 = d2i_PKCS12_bio(in, NULL);
+ if (p12) {
+ PKCS12_parse(p12, const_cast<char*>(m_keypass.c_str()), &pkey, NULL, NULL);
+ PKCS12_free(p12);
+ if (pkey) {
+ ret=SSL_CTX_use_PrivateKey(ctx, pkey);
+ EVP_PKEY_free(pkey);
+ }
+ }
+ }
+ if (in)
+ BIO_free(in);
+ }
+ }
+
+ if (ret!=1) {
+ log_openssl();
+ throw XMLSecurityException("Unable to attach private key to SSL context.");
+ }
+
+ // Attach certs.
+ for (vector<X509*>::const_iterator i=m_certs.begin(); i!=m_certs.end(); i++) {
+ if (i==m_certs.begin()) {
+ if (SSL_CTX_use_certificate(ctx, *i) != 1) {
+ log_openssl();
+ throw XMLSecurityException("Unable to attach client certificate to SSL context.");
+ }
+ }
+ else {
+ // When we add certs, they don't get ref counted, so we need to duplicate them.
+ X509* dup = X509_dup(*i);
+ if (SSL_CTX_add_extra_chain_cert(ctx, dup) != 1) {
+ X509_free(dup);
+ log_openssl();
+ throw XMLSecurityException("Unable to attach CA certificate to SSL context.");
+ }
+ }
+ }
+}
+
+void FilesystemCredential::addKeyNames(const DOMElement* e)
+{
+ e = XMLHelper::getFirstChildElement(e, Name);
+ while (e) {
+ if (e->hasChildNodes()) {
+ auto_ptr_char n(e->getFirstChild()->getNodeValue());
+ if (n.get() && *n.get())
+ m_keyNames.insert(n.get());
+ }
+ e = XMLHelper::getNextSiblingElement(e, Name);
+ }
+}
+
+void FilesystemCredential::attach(SSL_CTX* ctx) const
+{
+ return m_resolver->attach(ctx);
+}