X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=xmltooling%2Fsecurity%2Fimpl%2FInlineKeyResolver.cpp;h=9c3471c7f36eaa13ac31def00b28933c986ce399;hb=eab22660b1e5678870b4750af89a963476e38c3f;hp=acc6953c7109a7fd071bc9b902ca663004c90780;hpb=23d611f169115553c8419c0ff6556f7a62c105f0;p=shibboleth%2Fcpp-xmltooling.git diff --git a/xmltooling/security/impl/InlineKeyResolver.cpp b/xmltooling/security/impl/InlineKeyResolver.cpp index acc6953..9c3471c 100644 --- a/xmltooling/security/impl/InlineKeyResolver.cpp +++ b/xmltooling/security/impl/InlineKeyResolver.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 Internet2 + * Copyright 2001-2010 Internet2 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,9 +21,12 @@ */ #include "internal.h" +#include "logging.h" #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 "util/NDC.h" @@ -31,19 +34,19 @@ #include "util/XMLConstants.h" #include "validation/ValidatorSuite.h" -#include #include #include #include -#include -#include -#include +#include +#include +#include #include #include using namespace xmlsignature; +using namespace xmltooling::logging; using namespace xmltooling; -using namespace log4cpp; +using namespace xercesc; using namespace std; namespace xmltooling { @@ -51,27 +54,29 @@ namespace xmltooling { class XMLTOOL_DLLLOCAL InlineCredential : public BasicX509Credential { public: - InlineCredential(const KeyInfo* keyInfo=NULL) : BasicX509Credential(keyInfo!=NULL), m_credctx(new KeyInfoCredentialContext(keyInfo)) { + InlineCredential(const KeyInfo* keyInfo=nullptr) : BasicX509Credential(keyInfo!=nullptr), m_credctx(new KeyInfoCredentialContext(keyInfo)) { } InlineCredential(DSIGKeyInfoList* keyInfo) : BasicX509Credential(false), m_credctx(new KeyInfoCredentialContext(keyInfo)) { } - InlineCredential(KeyInfoCredentialContext* context) : BasicX509Credential(context->getKeyInfo()!=NULL), m_credctx(NULL) { + InlineCredential(KeyInfoCredentialContext* context) : BasicX509Credential(context->getKeyInfo()!=nullptr), m_credctx(nullptr) { } virtual ~InlineCredential() { delete m_credctx; } XSECCryptoKey* getPrivateKey() const { - return NULL; + return nullptr; } KeyInfo* getKeyInfo(bool compact=false) const { - KeyInfo* ret = m_credctx->getKeyInfo() ? m_credctx->getKeyInfo()->cloneKeyInfo() : NULL; + KeyInfo* ret = m_credctx->getKeyInfo() ? m_credctx->getKeyInfo()->cloneKeyInfo() : nullptr; if (ret) { - ret->setId(NULL); + 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(); @@ -79,6 +84,7 @@ namespace xmltooling { 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; @@ -89,12 +95,12 @@ namespace xmltooling { } if (!ret->hasChildren()) { delete ret; - ret = NULL; + ret = nullptr; } return ret; } - const CredentialContext* getCredentialContext() const { + const CredentialContext* getCredentalContext() const { return m_credctx; } @@ -102,96 +108,146 @@ namespace xmltooling { m_credctx = context; } - void resolve(const KeyInfo* keyInfo, int types=0); - void resolve(DSIGKeyInfoList* keyInfo, int types=0); + void resolve(const KeyInfo* keyInfo, int types=0, bool followRefs=false); + void resolve(DSIGKeyInfoList* keyInfo, int types=0, bool followRefs=false); private: - bool resolveCerts(const KeyInfo* keyInfo); - bool resolveKey(const KeyInfo* keyInfo); - bool resolveCRL(const KeyInfo* keyInfo); + bool resolveCerts(const KeyInfo* keyInfo, bool followRefs=false); + bool resolveKey(const KeyInfo* keyInfo, bool followRefs=false); + bool resolveCRLs(const KeyInfo* keyInfo, bool followRefs=false); KeyInfoCredentialContext* m_credctx; }; + static const XMLCh keyInfoReferences[] = UNICODE_LITERAL_17(k,e,y,I,n,f,o,R,e,f,e,r,e,n,c,e,s); + class XMLTOOL_DLLLOCAL InlineKeyResolver : public KeyInfoResolver { public: - InlineKeyResolver() {} + InlineKeyResolver(const DOMElement* e) + : m_followRefs(XMLHelper::getNodeValueAsBool(e ? e->getAttributeNodeNS(nullptr, keyInfoReferences) : nullptr, false)) { + } + virtual ~InlineKeyResolver() {} Credential* resolve(const KeyInfo* keyInfo, int types=0) const { if (!keyInfo) - return NULL; + return nullptr; if (types == 0) types = Credential::RESOLVE_KEYS|X509Credential::RESOLVE_CERTS|X509Credential::RESOLVE_CRLS; auto_ptr credential(new InlineCredential(keyInfo)); - credential->resolve(keyInfo, types); + credential->resolve(keyInfo, types, m_followRefs); return credential.release(); } Credential* resolve(DSIGKeyInfoList* keyInfo, int types=0) const { if (!keyInfo) - return NULL; + return nullptr; if (types == 0) types = Credential::RESOLVE_KEYS|X509Credential::RESOLVE_CERTS|X509Credential::RESOLVE_CRLS; auto_ptr credential(new InlineCredential(keyInfo)); - credential->resolve(keyInfo, types); + credential->resolve(keyInfo, types, m_followRefs); return credential.release(); } Credential* resolve(KeyInfoCredentialContext* context, int types=0) const { if (!context) - return NULL; + return nullptr; if (types == 0) types = Credential::RESOLVE_KEYS|X509Credential::RESOLVE_CERTS|X509Credential::RESOLVE_CRLS; auto_ptr credential(new InlineCredential(context)); if (context->getKeyInfo()) - credential->resolve(context->getKeyInfo(), types); + credential->resolve(context->getKeyInfo(), types, m_followRefs); else if (context->getNativeKeyInfo()) - credential->resolve(context->getNativeKeyInfo(), types); + credential->resolve(context->getNativeKeyInfo(), types, m_followRefs); credential->setCredentialContext(context); return credential.release(); } + + private: + bool m_followRefs; }; KeyInfoResolver* XMLTOOL_DLLLOCAL InlineKeyInfoResolverFactory(const DOMElement* const & e) { - return new InlineKeyResolver(); + return new InlineKeyResolver(e); } }; -void InlineCredential::resolve(const KeyInfo* keyInfo, int types) +void InlineCredential::resolve(const KeyInfo* keyInfo, int types, bool followRefs) { #ifdef _DEBUG NDC ndc("resolve"); #endif if (types & X509Credential::RESOLVE_CERTS) - resolveCerts(keyInfo); + resolveCerts(keyInfo, followRefs); if (types & Credential::RESOLVE_KEYS) { if (types & X509Credential::RESOLVE_CERTS) { // If we have a cert, just use it. if (!m_xseccerts.empty()) m_key = m_xseccerts.front()->clonePublicKey(); + else + resolveKey(keyInfo, followRefs); } // Otherwise try directly for a key and then go for certs if none is found. - else if (!resolveKey(keyInfo) && resolveCerts(keyInfo)) { + else if (!resolveKey(keyInfo, followRefs) && resolveCerts(keyInfo, followRefs)) { m_key = m_xseccerts.front()->clonePublicKey(); } } if (types & X509Credential::RESOLVE_CRLS) - resolveCRL(keyInfo); + resolveCRLs(keyInfo, followRefs); + + const XMLCh* n; + char* kn; + const vector& knames=keyInfo->getKeyNames(); + for (vector::const_iterator kn_i=knames.begin(); kn_i!=knames.end(); ++kn_i) { + n=(*kn_i)->getName(); + if (n && *n) { + kn=toUTF8(n); + m_keyNames.insert(kn); + delete[] kn; + } + } + const vector datas=keyInfo->getX509Datas(); + for (vector::const_iterator x_i=datas.begin(); x_i!=datas.end(); ++x_i) { + const vector snames = const_cast(*x_i)->getX509SubjectNames(); + for (vector::const_iterator sn_i = snames.begin(); sn_i!=snames.end(); ++sn_i) { + n = (*sn_i)->getName(); + if (n && *n) { + kn=toUTF8(n); + m_keyNames.insert(kn); + m_subjectName = kn; + delete[] kn; + } + } - keyInfo->extractNames(m_keyNames); + const vector inames = const_cast(*x_i)->getX509IssuerSerials(); + if (!inames.empty()) { + const X509IssuerName* iname = inames.front()->getX509IssuerName(); + if (iname) { + kn = toUTF8(iname->getName()); + if (kn) + m_issuerName = kn; + delete[] kn; + } + + const X509SerialNumber* ser = inames.front()->getX509SerialNumber(); + if (ser) { + auto_ptr_char sn(ser->getSerialNumber()); + m_serial = sn.get(); + } + } + } } -bool InlineCredential::resolveKey(const KeyInfo* keyInfo) +bool InlineCredential::resolveKey(const KeyInfo* keyInfo, bool followRefs) { - Category& log = Category::getInstance(XMLTOOLING_LOGCAT".KeyInfoResolver"); + Category& log = Category::getInstance(XMLTOOLING_LOGCAT".KeyInfoResolver."INLINE_KEYINFO_RESOLVER); // Check for ds:KeyValue const vector& keyValues = keyInfo->getKeyValues(); - for (vector::const_iterator i=keyValues.begin(); i!=keyValues.end(); ++i) { + for (vector::const_iterator i = keyValues.begin(); i != keyValues.end(); ++i) { try { SchemaValidators.validate(*i); // see if it's a "valid" key RSAKeyValue* rsakv = (*i)->getRSAKeyValue(); @@ -226,6 +282,10 @@ bool InlineCredential::resolveKey(const KeyInfo* keyInfo) 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()); @@ -239,38 +299,49 @@ bool InlineCredential::resolveKey(const KeyInfo* keyInfo) } } - // Check for RetrievalMethod. - const XMLCh* fragID=NULL; - const XMLObject* treeRoot=NULL; - const vector& methods=keyInfo->getRetrievalMethods(); - for (vector::const_iterator m=methods.begin(); m!=methods.end(); ++m) { - if (!XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_RSAKEYVALUE) && - !XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_DSAKEYVALUE)) - continue; - fragID = (*m)->getURI(); - if (!fragID || *fragID != chPound || !*(fragID+1)) { - log.warn("skipping ds:RetrievalMethod with an empty or non-local reference"); - continue; - } - if (!treeRoot) { - treeRoot = keyInfo; - while (treeRoot->getParent()) - treeRoot = treeRoot->getParent(); - } - keyInfo = dynamic_cast(XMLHelper::getXMLObjectById(*treeRoot, fragID+1)); - if (!keyInfo) { - log.warn("skipping ds:RetrievalMethod, local reference did not resolve to a ds:KeyInfo"); - continue; - } - if (resolveKey(keyInfo)) + // Check for ds11:DEREncodedKeyValue + const vector& derValues = keyInfo->getDEREncodedKeyValues(); + for (vector::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; + const XMLObject* treeRoot=NULL; + const vector& refs = keyInfo->getKeyInfoReferences(); + for (vector::const_iterator ref = refs.begin(); ref != refs.end(); ++ref) { + fragID = (*ref)->getURI(); + if (!fragID || *fragID != chPound || !*(fragID+1)) { + log.warn("skipping ds11:KeyInfoReference with an empty or non-local reference"); + continue; + } + if (!treeRoot) { + treeRoot = keyInfo; + while (treeRoot->getParent()) + treeRoot = treeRoot->getParent(); + } + keyInfo = dynamic_cast(XMLHelper::getXMLObjectById(*treeRoot, fragID+1)); + if (!keyInfo) { + log.warn("skipping ds11:KeyInfoReference, local reference did not resolve to a ds:KeyInfo"); + continue; + } + if (resolveKey(keyInfo, false)) + return true; + } } + return false; } -bool InlineCredential::resolveCerts(const KeyInfo* keyInfo) +bool InlineCredential::resolveCerts(const KeyInfo* keyInfo, bool followRefs) { - Category& log = Category::getInstance(XMLTOOLING_LOGCAT".KeyInfoResolver"); + Category& log = Category::getInstance(XMLTOOLING_LOGCAT".KeyInfoResolver."INLINE_KEYINFO_RESOLVER); // Check for ds:X509Data const vector& x509Datas=keyInfo->getX509Datas(); @@ -299,17 +370,15 @@ bool InlineCredential::resolveCerts(const KeyInfo* keyInfo) } } - if (m_xseccerts.empty()) { - // Check for RetrievalMethod. + if (followRefs && m_xseccerts.empty()) { + // Check for KeyInfoReference. const XMLCh* fragID=NULL; const XMLObject* treeRoot=NULL; - const vector methods=keyInfo->getRetrievalMethods(); - for (vector::const_iterator m=methods.begin(); m!=methods.end(); ++m) { - if (!XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_X509DATA)) - continue; - fragID = (*m)->getURI(); + const vector& refs = keyInfo->getKeyInfoReferences(); + for (vector::const_iterator ref = refs.begin(); ref != refs.end(); ++ref) { + fragID = (*ref)->getURI(); if (!fragID || *fragID != chPound || !*(fragID+1)) { - log.warn("skipping ds:RetrievalMethod with an empty or non-local reference"); + log.warn("skipping ds11:KeyInfoReference with an empty or non-local reference"); continue; } if (!treeRoot) { @@ -319,10 +388,10 @@ bool InlineCredential::resolveCerts(const KeyInfo* keyInfo) } keyInfo = dynamic_cast(XMLHelper::getXMLObjectById(*treeRoot, fragID+1)); if (!keyInfo) { - log.warn("skipping ds:RetrievalMethod, local reference did not resolve to a ds:KeyInfo"); + log.warn("skipping ds11:KeyInfoReference, local reference did not resolve to a ds:KeyInfo"); continue; } - if (resolveCerts(keyInfo)) + if (resolveCerts(keyInfo, false)) return true; } return false; @@ -332,9 +401,9 @@ bool InlineCredential::resolveCerts(const KeyInfo* keyInfo) return !m_xseccerts.empty(); } -bool InlineCredential::resolveCRL(const KeyInfo* keyInfo) +bool InlineCredential::resolveCRLs(const KeyInfo* keyInfo, bool followRefs) { - Category& log = Category::getInstance(XMLTOOLING_LOGCAT".KeyInfoResolver"); + Category& log = Category::getInstance(XMLTOOLING_LOGCAT".KeyInfoResolver."INLINE_KEYINFO_RESOLVER); // Check for ds:X509Data const vector& x509Datas=keyInfo->getX509Datas(); @@ -350,50 +419,51 @@ bool InlineCredential::resolveCRL(const KeyInfo* keyInfo) log.debug("resolving ds:X509CRL"); auto_ptr crl(XMLToolingConfig::getConfig().X509CRL()); crl->loadX509CRLBase64Bin(x.get(), strlen(x.get())); - m_crl = crl.release(); - return true; + m_crls.push_back(crl.release()); } } catch(XSECException& e) { auto_ptr_char temp(e.getMsg()); - log.error("caught XML-Security exception loading certificate: %s", temp.get()); + log.error("caught XML-Security exception loading CRL: %s", temp.get()); } catch(XSECCryptoException& e) { - log.error("caught XML-Security exception loading certificate: %s", e.getMsg()); + log.error("caught XML-Security exception loading CRL: %s", e.getMsg()); } } } - // Check for RetrievalMethod. - const XMLCh* fragID=NULL; - const XMLObject* treeRoot=NULL; - const vector methods=keyInfo->getRetrievalMethods(); - for (vector::const_iterator m=methods.begin(); m!=methods.end(); ++m) { - if (!XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_X509DATA)) - continue; - fragID = (*m)->getURI(); - if (!fragID || *fragID != chPound || !*(fragID+1)) { - log.warn("skipping ds:RetrievalMethod with an empty or non-local reference"); - continue; - } - if (!treeRoot) { - treeRoot = keyInfo; - while (treeRoot->getParent()) - treeRoot = treeRoot->getParent(); - } - keyInfo = dynamic_cast(XMLHelper::getXMLObjectById(*treeRoot, fragID+1)); - if (!keyInfo) { - log.warn("skipping ds:RetrievalMethod, local reference did not resolve to a ds:KeyInfo"); - continue; - } - if (resolveCRL(keyInfo)) - return true; + if (followRefs && m_crls.empty()) { + // Check for KeyInfoReference. + const XMLCh* fragID=NULL; + const XMLObject* treeRoot=NULL; + const vector& refs = keyInfo->getKeyInfoReferences(); + for (vector::const_iterator ref = refs.begin(); ref != refs.end(); ++ref) { + fragID = (*ref)->getURI(); + if (!fragID || *fragID != chPound || !*(fragID+1)) { + log.warn("skipping ds11:KeyInfoReference with an empty or non-local reference"); + continue; + } + if (!treeRoot) { + treeRoot = keyInfo; + while (treeRoot->getParent()) + treeRoot = treeRoot->getParent(); + } + keyInfo = dynamic_cast(XMLHelper::getXMLObjectById(*treeRoot, fragID+1)); + if (!keyInfo) { + log.warn("skipping ds11:KeyInfoReference, local reference did not resolve to a ds:KeyInfo"); + continue; + } + if (resolveCRLs(keyInfo, false)) + return true; + } + return false; } - return false; + log.debug("resolved %d CRL(s)", m_crls.size()); + return !m_crls.empty(); } -void InlineCredential::resolve(DSIGKeyInfoList* keyInfo, int types) +void InlineCredential::resolve(DSIGKeyInfoList* keyInfo, int types, bool followRefs) { #ifdef _DEBUG NDC ndc("resolve"); @@ -407,10 +477,10 @@ void InlineCredential::resolve(DSIGKeyInfoList* keyInfo, int types) } catch(XSECException& e) { auto_ptr_char temp(e.getMsg()); - Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading certificate: %s", temp.get()); + Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading certificate: %s", temp.get()); } catch(XSECCryptoException& e) { - Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading certificate: %s", e.getMsg()); + Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading certificate: %s", e.getMsg()); } } @@ -433,25 +503,83 @@ void InlineCredential::resolve(DSIGKeyInfoList* keyInfo, int types) if (types & X509Credential::RESOLVE_CRLS) { for (DSIGKeyInfoList::size_type i=0; iitem(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) { - auto_ptr_char buf(static_cast(keyInfo->item(i))->getX509CRL()); - if (buf.get()) { - try { - auto_ptr crlobj(XMLToolingConfig::getConfig().X509CRL()); - crlobj->loadX509CRLBase64Bin(buf.get(), strlen(buf.get())); - m_crl = crlobj.release(); - break; - } - catch(XSECException& e) { - auto_ptr_char temp(e.getMsg()); - Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", temp.get()); +#ifdef XMLTOOLING_XMLSEC_MULTIPLECRL + DSIGKeyInfoX509* x509 = static_cast(keyInfo->item(i)); + int count = x509->getX509CRLListSize(); + for (int j=0; jgetX509CRLItem(j)); + if (buf.get()) { + try { + auto_ptr crlobj(XMLToolingConfig::getConfig().X509CRL()); + crlobj->loadX509CRLBase64Bin(buf.get(), strlen(buf.get())); + m_crls.push_back(crlobj.release()); + } + catch(XSECException& e) { + auto_ptr_char temp(e.getMsg()); + Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading CRL: %s", temp.get()); + } + catch(XSECCryptoException& e) { + Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading CRL: %s", e.getMsg()); + } } - catch(XSECCryptoException& e) { - Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", e.getMsg()); + } +#else + // The current xmlsec API is limited to one CRL per KeyInfo. + // For now, I'm going to process the DOM directly. + DOMNode* x509Node = keyInfo->item(i)->getKeyInfoDOMNode(); + DOMElement* crlElement = x509Node ? XMLHelper::getFirstChildElement(x509Node, xmlconstants::XMLSIG_NS, X509CRL::LOCAL_NAME) : nullptr; + while (crlElement) { + if (crlElement->hasChildNodes()) { + auto_ptr_char buf(crlElement->getFirstChild()->getNodeValue()); + if (buf.get()) { + try { + auto_ptr crlobj(XMLToolingConfig::getConfig().X509CRL()); + crlobj->loadX509CRLBase64Bin(buf.get(), strlen(buf.get())); + m_crls.push_back(crlobj.release()); + } + catch(XSECException& e) { + auto_ptr_char temp(e.getMsg()); + Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading CRL: %s", temp.get()); + } + catch(XSECCryptoException& e) { + Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading CRL: %s", e.getMsg()); + } + } } + crlElement = XMLHelper::getNextSiblingElement(crlElement, xmlconstants::XMLSIG_NS, X509CRL::LOCAL_NAME); } +#endif } } } - Signature::extractNames(keyInfo, m_keyNames); + char* kn; + const XMLCh* n; + + for (size_t s=0; sgetSize(); s++) { + DSIGKeyInfo* dki = keyInfo->item(s); + n=dki->getKeyName(); + if (n && *n) { + kn=toUTF8(n); + m_keyNames.insert(kn); + if (dki->getKeyInfoType() == DSIGKeyInfo::KEYINFO_X509) + m_subjectName = kn; + delete[] kn; + } + + if (dki->getKeyInfoType() == DSIGKeyInfo::KEYINFO_X509) { + DSIGKeyInfoX509* kix = static_cast(dki); + n = kix->getX509IssuerName(); + if (n && *n) { + kn=toUTF8(n); + m_issuerName = kn; + delete[] kn; + } + n = kix->getX509IssuerSerialNumber(); + if (n && *n) { + auto_ptr_char sn(n); + m_serial = sn.get(); + } + } + } }