in xsec/tools/checksig/InteropResolver.cpp [300:427]
bool InteropResolver::checkMatch(const DSIGKeyInfoList * lst, X509 * x) const {
// Check if the parameters in x match the required certificate
int sz = (int) lst->getSize();
const DSIGKeyInfo* k;
for (int i = 0; i < sz; ++i) {
k = lst->item(i);
if (k->getKeyInfoType() == DSIGKeyInfo::KEYINFO_X509) {
const DSIGKeyInfoX509 * kx = static_cast<const DSIGKeyInfoX509 *>(k);
const XMLCh * serial = kx->getX509IssuerSerialNumber();
if (serial != NULL) {
char * cserial = XMLString::transcode(serial);
char * xserial;
BIGNUM * bnserial = ASN1_INTEGER_to_BN(X509_get_serialNumber(x), NULL);
xserial = BN_bn2dec(bnserial);
BN_free(bnserial);
if (strcmp(xserial, cserial) == 0) {
OPENSSL_free(xserial);
XSEC_RELEASE_XMLCH(cserial);
return true;
}
//delete[] xserial;
XSEC_RELEASE_XMLCH(cserial);
OPENSSL_free(xserial);
}
/*
* Either it's not a serial number, or we didn't pass, so lets
* look at the next option.
*/
const XMLCh * ski = kx->getX509SKI();
if (ski != NULL) {
char * cski = XMLString::transcode(ski);
int clen = (int) strlen(cski);
unsigned char * xski = new unsigned char[clen];
ArrayJanitor <unsigned char> j_xski(xski);
// Decode
OpenSSLCryptoBase64 b64;
b64.decodeInit();
int xlen = b64.decode((unsigned char *) cski, clen, xski, clen);
xlen += b64.decodeFinish(&xski[xlen], clen - xlen);
XSEC_RELEASE_XMLCH(cski);
if (xlen != 0) {
// Have a buffer with a number in it
const STACK_OF(X509_EXTENSION) *exts;
exts = X509_get0_extensions(x);
if (exts != NULL) {
// Find the Subject Key Identifier OID
X509_EXTENSION * ext;
ASN1_OBJECT * objski = OBJ_nid2obj(NID_subject_key_identifier);
int extn = X509v3_get_ext_by_OBJ(exts, objski, -1);
if (extn != -1) {
// Dummy up an OCTET_STRING from the xski
unsigned char * octxski = new unsigned char[xlen + 2];
ArrayJanitor<unsigned char> j_octxski(octxski);
octxski[0] = 4;
octxski[1] = xlen;
memcpy(&octxski[2], xski, xlen);
ext = sk_X509_EXTENSION_value(exts,extn);
ASN1_OCTET_STRING *skid = X509_EXTENSION_get_data(ext);
ASN1_OCTET_STRING * xskid = ASN1_OCTET_STRING_new();
ASN1_STRING_set(xskid, octxski, xlen+2);
if (ASN1_OCTET_STRING_cmp(xskid, skid) == 0) {
ASN1_OCTET_STRING_free(xskid);
return true;
}
}
}
}
}
/* Not a subject key identifier */
const XMLCh *sn = kx->getX509SubjectName();
if (sn != NULL) {
char * csn = XMLString::transcode(sn);
X509_NAME * x509name = X509_get_subject_name(x);
X509_NAME * snname = X509_NAME_create_from_txt(csn);
XSEC_RELEASE_XMLCH(csn);
if (snname != NULL) {
if (!X509_NAME_cmp(x509name, snname)) {
X509_NAME_free(snname);
return true;
}
X509_NAME_free(snname);
}
}
}
}
return false;
}