Refactor extraction of certificate details.
Add X509SubjectName/X509IssuerSerial to KeyInfo handling.
// Resolve a decryption key directly.
vector<const Credential*> creds;
- int types =
- CredentialCriteria::KEYINFO_EXTRACTION_KEY |
- CredentialCriteria::KEYINFO_EXTRACTION_KEYNAMES |
- CredentialCriteria::KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES;
+ int types = CredentialCriteria::KEYINFO_EXTRACTION_KEY | CredentialCriteria::KEYINFO_EXTRACTION_KEYNAMES;
if (m_criteria) {
m_criteria->setUsage(Credential::ENCRYPTION_CREDENTIAL);
m_criteria->setKeyInfo(encryptedData.getKeyInfo(), types);
// Resolve a decryption key directly.
vector<const Credential*> creds;
- int types =
- CredentialCriteria::KEYINFO_EXTRACTION_KEY |
- CredentialCriteria::KEYINFO_EXTRACTION_KEYNAMES |
- CredentialCriteria::KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES;
+ int types = CredentialCriteria::KEYINFO_EXTRACTION_KEY | CredentialCriteria::KEYINFO_EXTRACTION_KEYNAMES;
if (m_criteria) {
m_criteria->setUsage(Credential::ENCRYPTION_CREDENTIAL);
m_criteria->setKeyInfo(encryptedData.getKeyInfo(), types);
m_cipher=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newCipher(encryptedKey.getDOM()->getOwnerDocument());
// Resolve key decryption keys.
- int types =
- CredentialCriteria::KEYINFO_EXTRACTION_KEY |
- CredentialCriteria::KEYINFO_EXTRACTION_KEYNAMES |
- CredentialCriteria::KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES;
+ int types = CredentialCriteria::KEYINFO_EXTRACTION_KEY | CredentialCriteria::KEYINFO_EXTRACTION_KEYNAMES;
vector<const Credential*> creds;
if (m_criteria) {
m_criteria->setUsage(Credential::ENCRYPTION_CREDENTIAL);
*
* @param ownCerts true iff any certificates subsequently stored should be freed by destructor
*/
- BasicX509Credential(bool ownCerts) : m_key(NULL), m_ownCerts(ownCerts), m_crl(NULL), m_keyInfo(NULL), m_compactKeyInfo(NULL) {
+ BasicX509Credential(bool ownCerts) : m_key(NULL), m_serial(-1), m_ownCerts(ownCerts), m_crl(NULL), m_keyInfo(NULL), m_compactKeyInfo(NULL) {
}
/**
* @param crl optional CRL
*/
BasicX509Credential(XSECCryptoKey* key, const std::vector<XSECCryptoX509*>& certs, XSECCryptoX509CRL* crl=NULL)
- : m_key(key), m_xseccerts(certs), m_ownCerts(true), m_crl(crl), m_keyInfo(NULL), m_compactKeyInfo(NULL) {
+ : m_key(key), m_serial(-1), m_xseccerts(certs), m_ownCerts(true), m_crl(crl), m_keyInfo(NULL), m_compactKeyInfo(NULL) {
}
/** The private/secret key/keypair. */
/** Key names (derived from credential, KeyInfo, or both). */
std::set<std::string> m_keyNames;
+ /** Subject DN. */
+ std::string m_subjectName;
+
+ /** Issuer DN. */
+ std::string m_issuerName;
+
+ /** Serial number. */
+ int m_serial;
+
/** The X.509 certificate chain. */
std::vector<XSECCryptoX509*> m_xseccerts;
* Initializes (or reinitializes) a ds:KeyInfo to represent the Credential.
*/
void initKeyInfo();
-
+
public:
virtual ~BasicX509Credential();
XSECCryptoX509CRL* getCRL() const {
return m_crl;
}
+
+ const char* getSubjectName() const {
+ return m_subjectName.c_str();
+ }
+
+ const char* getIssuerName() const {
+ return m_issuerName.c_str();
+ }
+
+ int getSerialNumber() const {
+ return m_serial;
+ }
+
+ void extract();
};
};
*/
enum keyinfo_extraction_t {
KEYINFO_EXTRACTION_KEY = 1,
- KEYINFO_EXTRACTION_KEYNAMES = 2,
- KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES = 4
+ KEYINFO_EXTRACTION_KEYNAMES = 2
};
/**
return;
int types = (extraction & KEYINFO_EXTRACTION_KEY) ? Credential::RESOLVE_KEYS : 0;
- types |= (extraction & KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES) ? X509Credential::RESOLVE_CERTS : 0;
+ types |= (extraction & KEYINFO_EXTRACTION_KEYNAMES) ? X509Credential::RESOLVE_CERTS : 0;
m_credential = XMLToolingConfig::getConfig().getKeyInfoResolver()->resolve(keyInfo,types);
if (extraction & KEYINFO_EXTRACTION_KEY)
setPublicKey(m_credential->getPublicKey());
- if (extraction & KEYINFO_EXTRACTION_KEYNAMES)
+ if (extraction & KEYINFO_EXTRACTION_KEYNAMES) {
+ X509Credential* xcred = dynamic_cast<X509Credential*>(m_credential);
+ if (xcred)
+ xcred->extract();
m_keyNames.insert(m_credential->getKeyNames().begin(), m_credential->getKeyNames().end());
- if (extraction & KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES) {
- const X509Credential* xcred = dynamic_cast<const X509Credential*>(m_credential);
- if (xcred && !xcred->getEntityCertificateChain().empty())
- X509Credential::extractNames(xcred->getEntityCertificateChain().front(), m_keyNames);
}
}
return;
int types = (extraction & KEYINFO_EXTRACTION_KEY) ? Credential::RESOLVE_KEYS : 0;
- types |= (extraction & KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES) ? X509Credential::RESOLVE_CERTS : 0;
+ types |= (extraction & KEYINFO_EXTRACTION_KEYNAMES) ? X509Credential::RESOLVE_CERTS : 0;
m_credential = XMLToolingConfig::getConfig().getKeyInfoResolver()->resolve(keyInfo,types);
if (extraction & KEYINFO_EXTRACTION_KEY)
setPublicKey(m_credential->getPublicKey());
- if (extraction & KEYINFO_EXTRACTION_KEYNAMES)
+ if (extraction & KEYINFO_EXTRACTION_KEYNAMES) {
+ X509Credential* xcred = dynamic_cast<X509Credential*>(m_credential);
+ if (xcred)
+ xcred->extract();
m_keyNames.insert(m_credential->getKeyNames().begin(), m_credential->getKeyNames().end());
- if (extraction & KEYINFO_EXTRACTION_IMPLICIT_KEYNAMES) {
- const X509Credential* xcred = dynamic_cast<const X509Credential*>(m_credential);
- if (xcred && !xcred->getEntityCertificateChain().empty())
- X509Credential::extractNames(xcred->getEntityCertificateChain().front(), m_keyNames);
}
}
setXMLAlgorithm(sig.getSignatureAlgorithm());
xmlsignature::KeyInfo* k = sig.getKeyInfo();
if (k)
- return setKeyInfo(k,extraction);
+ return setKeyInfo(k, extraction);
DSIGSignature* dsig = sig.getXMLSignature();
if (dsig)
- setNativeKeyInfo(dsig->getKeyInfoList(),extraction);
+ setNativeKeyInfo(dsig->getKeyInfoList(), extraction);
}
private:
virtual XSECCryptoX509CRL* getCRL() const=0;
/**
- * Extracts Subject CN and DNS/URI subjectAltNames from a certificate.
+ * Gets the subject name of the first certificate in the chain.
*
- * @param x509 certificate to extract
- * @param names a set to insert names into
+ * @return the Subject DN
*/
- static void extractNames(XSECCryptoX509* x509, std::set<std::string>& names);
+ virtual const char* getSubjectName() const=0;
+
+ /**
+ * Gets the issuer name of the first certificate in the chain.
+ *
+ * @return the Issuer DN
+ */
+ virtual const char* getIssuerName() const=0;
+
+ /**
+ * Gets the serial number of the first certificate in the chain.
+ *
+ * @return the serial number
+ */
+ virtual int getSerialNumber() const=0;
+
+ /**
+ * Extracts properties like issuer and subject from the first certificate in the chain.
+ */
+ virtual void extract()=0;
};
};
m_compactKeyInfo = KeyInfoBuilder::buildKeyInfo();
VectorOf(KeyName) knames = m_compactKeyInfo->getKeyNames();
for (set<string>::const_iterator n = names.begin(); n!=names.end(); ++n) {
+ if (*n == m_subjectName)
+ continue;
auto_ptr_XMLCh wide(n->c_str());
KeyName* kname = KeyNameBuilder::buildKeyName();
kname->setName(wide.get());
knames.push_back(kname);
}
}
+
+ if (!m_subjectName.empty() || (!m_issuerName.empty() && m_serial >= 0)) {
+ if (!m_compactKeyInfo)
+ m_compactKeyInfo = KeyInfoBuilder::buildKeyInfo();
+ X509Data* x509Data=X509DataBuilder::buildX509Data();
+ m_compactKeyInfo->getX509Datas().push_back(x509Data);
+ if (!m_subjectName.empty()) {
+ X509SubjectName* sn = X509SubjectNameBuilder::buildX509SubjectName();
+ auto_ptr_XMLCh wide(m_subjectName.c_str());
+ sn->setName(wide.get());
+ x509Data->getX509SubjectNames().push_back(sn);
+ }
+
+ if (!m_issuerName.empty() && m_serial >= 0) {
+ X509IssuerSerial* is = X509IssuerSerialBuilder::buildX509IssuerSerial();
+ X509IssuerName* in = X509IssuerNameBuilder::buildX509IssuerName();
+ auto_ptr_XMLCh wide(m_issuerName.c_str());
+ in->setName(wide.get());
+ is->setX509IssuerName(in);
+ X509SerialNumber* ser = X509SerialNumberBuilder::buildX509SerialNumber();
+ char buf[64];
+ sprintf(buf,"%d",m_serial);
+ auto_ptr_XMLCh wide2(buf);
+ ser->setSerialNumber(wide2.get());
+ is->setX509SerialNumber(ser);
+ x509Data->getX509IssuerSerials().push_back(is);
+ }
+ }
if (!m_xseccerts.empty()) {
m_keyInfo = m_compactKeyInfo ? m_compactKeyInfo->cloneKeyInfo() : KeyInfoBuilder::buildKeyInfo();
- X509Data* x509Data=X509DataBuilder::buildX509Data();
- m_keyInfo->getX509Datas().push_back(x509Data);
+ if (m_keyInfo->getX509Datas().empty())
+ m_keyInfo->getX509Datas().push_back(X509DataBuilder::buildX509Data());
for (vector<XSECCryptoX509*>::const_iterator x = m_xseccerts.begin(); x!=m_xseccerts.end(); ++x) {
safeBuffer& buf=(*x)->getDEREncodingSB();
X509Certificate* x509=X509CertificateBuilder::buildX509Certificate();
x509->setValue(buf.sbStrToXMLCh());
- x509Data->getX509Certificates().push_back(x509);
+ m_keyInfo->getX509Datas().front()->getX509Certificates().push_back(x509);
}
}
}
-void X509Credential::extractNames(XSECCryptoX509* x509, set<string>& names)
+void BasicX509Credential::extract()
{
+ XSECCryptoX509* x509 = m_xseccerts.empty() ? NULL : m_xseccerts.front();
if (!x509 || x509->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL)
return;
-
X509* cert = static_cast<OpenSSLCryptoX509*>(x509)->getOpenSSLX509();
if (!cert)
return;
-
+
+ BIO* b;
+ int len;
+ char buf[256];
+
+ X509_NAME* issuer=X509_get_issuer_name(cert);
+ if (issuer) {
+ memset(buf,0,sizeof(buf));
+ b = BIO_new(BIO_s_mem());
+ BIO_set_mem_eof_return(b, 0);
+ len=X509_NAME_print_ex(b,issuer,0,XN_FLAG_RFC2253);
+ BIO_flush(b);
+ m_issuerName.erase();
+ while ((len = BIO_read(b, buf, 255)) > 0) {
+ buf[len] = '\0';
+ m_issuerName+=buf;
+ }
+ BIO_free(b);
+ }
+
+ ASN1_INTEGER* serialASN = X509_get_serialNumber(cert);
+ BIGNUM* serialBN = ASN1_INTEGER_to_BN(serialASN, NULL);
+ if (serialBN) {
+ char* serial = BN_bn2dec(serialBN);
+ if (serial) {
+ m_serial = atoi(serial);
+ free(serial);
+ }
+ BN_free(serialBN);
+ }
+
X509_NAME* subject=X509_get_subject_name(cert);
if (subject) {
- char buf[256];
+ memset(buf,0,sizeof(buf));
+ b = BIO_new(BIO_s_mem());
+ BIO_set_mem_eof_return(b, 0);
+ len=X509_NAME_print_ex(b,subject,0,XN_FLAG_RFC2253);
+ BIO_flush(b);
+ m_subjectName.erase();
+ while ((len = BIO_read(b, buf, 255)) > 0) {
+ buf[len] = '\0';
+ m_subjectName+=buf;
+ }
+ m_keyNames.insert(m_subjectName);
+ BIO_free(b);
+
memset(buf,0,sizeof(buf));
if (X509_NAME_get_text_by_NID(subject,NID_commonName,buf,255)>0)
- names.insert(buf);
+ m_keyNames.insert(buf);
STACK_OF(GENERAL_NAME)* altnames=(STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
if (altnames) {
if (altlen>0) {
alt.erase();
alt.append(altptr,altlen);
- names.insert(alt);
+ m_keyNames.insert(alt);
}
}
}
FilesystemCredential(
FilesystemCredentialResolver* resolver, XSECCryptoKey* key, const std::vector<XSECCryptoX509*>& xseccerts, XSECCryptoX509CRL* crl=NULL
) : BasicX509Credential(key, xseccerts, crl), m_resolver(resolver), m_usage(UNSPECIFIED_CREDENTIAL) {
- if (!m_xseccerts.empty())
- extractNames(m_xseccerts.front(), m_keyNames);
+ extract();
initKeyInfo();
}
virtual ~FilesystemCredential() {
if (types & X509Credential::RESOLVE_CRLS)
resolveCRL(keyInfo);
- keyInfo->extractNames(m_keyNames);
+ const XMLCh* n;
+ char* kn;
+ const vector<KeyName*>& knames=keyInfo->getKeyNames();
+ for (vector<KeyName*>::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<X509Data*> datas=keyInfo->getX509Datas();
+ for (vector<X509Data*>::const_iterator x_i=datas.begin(); x_i!=datas.end(); ++x_i) {
+ const vector<X509SubjectName*> snames = const_cast<const X509Data*>(*x_i)->getX509SubjectNames();
+ for (vector<X509SubjectName*>::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;
+ }
+ }
+
+ const vector<X509IssuerSerial*> inames = const_cast<const X509Data*>(*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)
+ m_serial = XMLString::parseInt(ser->getSerialNumber());
+ }
+ }
}
bool InlineCredential::resolveKey(const KeyInfo* keyInfo)
}
}
- Signature::extractNames(keyInfo, m_keyNames);
+ char* kn;
+ const XMLCh* n;
+
+ for (size_t s=0; s<keyInfo->getSize(); 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<DSIGKeyInfoX509*>(dki);
+ n = kix->getX509IssuerName();
+ if (n && *n) {
+ kn=toUTF8(n);
+ m_issuerName = kn;
+ delete[] kn;
+ }
+ n = kix->getX509IssuerSerialNumber();
+ if (n && *n)
+ m_serial = XMLString::parseInt(n);
+ }
+ }
}
DECL_TYPED_CHILDREN(SPKIData);
/** KeyInfoType local name */
static const XMLCh TYPE_NAME[];
-
- /**
- * Populates a set of key names using the information found in this KeyInfo object.
- *
- * @param names a set of names to populate
- */
- virtual void extractNames(std::set<std::string>& names) const=0;
END_XMLOBJECT;
DECL_XMLSIGOBJECTBUILDER(PGPData);
unsigned int in_len
);
- /**
- * Populates a set of key names using the information found in a native KeyInfo object.
- *
- * @param keyInfo a native KeyInfo object
- * @param names a set of names to populate
- */
- static void extractNames(DSIGKeyInfoList* keyInfo, std::set<std::string>& names);
-
protected:
Signature() {}
};
IMPL_TYPED_CHILDREN(PGPData,m_children.end());
IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end());
- void extractNames(set<string>& names) const {
- const XMLCh* n;
- char* kn;
- const vector<KeyName*>& knames=getKeyNames();
- for (vector<KeyName*>::const_iterator kn_i=knames.begin(); kn_i!=knames.end(); ++kn_i) {
- n=(*kn_i)->getName();
- if (n && *n) {
- kn=toUTF8(n);
- names.insert(kn);
- delete[] kn;
- }
- }
- const vector<X509Data*> datas=getX509Datas();
- for (vector<X509Data*>::const_iterator x_i=datas.begin(); x_i!=datas.end(); ++x_i) {
- const vector<X509SubjectName*> snames = const_cast<const X509Data*>(*x_i)->getX509SubjectNames();
- for (vector<X509SubjectName*>::const_iterator sn_i = snames.begin(); sn_i!=snames.end(); ++sn_i) {
- n = (*sn_i)->getName();
- if (n && *n) {
- kn=toUTF8(n);
- names.insert(kn);
- delete[] kn;
- }
- }
- const vector<X509SKI*> skis = const_cast<const X509Data*>(*x_i)->getX509SKIs();
- for (vector<X509SKI*>::const_iterator sk_i = skis.begin(); sk_i!=skis.end(); ++sk_i) {
- n = (*sk_i)->getValue();
- if (n && *n) {
- kn=toUTF8(n);
- names.insert(kn);
- delete[] kn;
- }
- }
- }
- }
-
protected:
void marshallAttributes(DOMElement* domElement) const {
MARSHALL_ID_ATTRIB(Id,ID,NULL);
throw SignatureException(string("Caught an XMLSecurity exception while verifying raw signature: ") + e.getMsg());
}
}
-
-void Signature::extractNames(DSIGKeyInfoList* keyInfo, set<string>& names)
-{
- char* kn;
- const XMLCh* n;
-
- for (size_t s=0; s<keyInfo->getSize(); s++) {
- n=keyInfo->item(s)->getKeyName();
- if (n && *n) {
- kn=toUTF8(n);
- names.insert(kn);
- delete[] kn;
- }
- }
-}