summaryrefslogtreecommitdiff
path: root/src/mscrypto/x509vfy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscrypto/x509vfy.c')
-rw-r--r--src/mscrypto/x509vfy.c790
1 files changed, 567 insertions, 223 deletions
diff --git a/src/mscrypto/x509vfy.c b/src/mscrypto/x509vfy.c
index d854e7a0..cf317877 100644
--- a/src/mscrypto/x509vfy.c
+++ b/src/mscrypto/x509vfy.c
@@ -1,4 +1,4 @@
-/**
+/**
* XMLSec library
*
* X509 support
@@ -6,8 +6,8 @@
*
* This is free software; see Copyright file in the source
* distribution for preciese wording.
- *
- * Copyrigth (C) 2003 Cordys R&D BV, All rights reserved.
+ *
+ * Copyright (C) 2003 Cordys R&D BV, All rights reserved.
* Copyright (C) 2003 Aleksey Sanin <aleksey@aleksey.com>
*/
#include "globals.h"
@@ -33,23 +33,20 @@
#include <xmlsec/mscrypto/crypto.h>
#include <xmlsec/mscrypto/x509.h>
-
-#if defined(__MINGW32__)
-# include "xmlsec-mingw.h"
-#endif
+#include "private.h"
/**************************************************************************
*
* Internal MSCRYPTO X509 store CTX
*
*************************************************************************/
-typedef struct _xmlSecMSCryptoX509StoreCtx xmlSecMSCryptoX509StoreCtx,
+typedef struct _xmlSecMSCryptoX509StoreCtx xmlSecMSCryptoX509StoreCtx,
*xmlSecMSCryptoX509StoreCtxPtr;
struct _xmlSecMSCryptoX509StoreCtx {
HCERTSTORE trusted;
HCERTSTORE untrusted;
int dont_use_system_trusted_certs;
-};
+};
/****************************************************************************
*
@@ -63,7 +60,7 @@ struct _xmlSecMSCryptoX509StoreCtx {
sizeof(xmlSecKeyDataStoreKlass)))
#define xmlSecMSCryptoX509StoreSize \
(sizeof(xmlSecKeyDataStoreKlass) + sizeof(xmlSecMSCryptoX509StoreCtx))
-
+
static int xmlSecMSCryptoX509StoreInitialize (xmlSecKeyDataStorePtr store);
static void xmlSecMSCryptoX509StoreFinalize (xmlSecKeyDataStorePtr store);
@@ -72,8 +69,8 @@ static xmlSecKeyDataStoreKlass xmlSecMSCryptoX509StoreKlass = {
xmlSecMSCryptoX509StoreSize,
/* data */
- xmlSecNameX509Store, /* const xmlChar* name; */
-
+ xmlSecNameX509Store, /* const xmlChar* name; */
+
/* constructors/destructor */
xmlSecMSCryptoX509StoreInitialize, /* xmlSecKeyDataStoreInitializeMethod initialize; */
xmlSecMSCryptoX509StoreFinalize, /* xmlSecKeyDataStoreFinalizeMethod finalize; */
@@ -84,20 +81,20 @@ static xmlSecKeyDataStoreKlass xmlSecMSCryptoX509StoreKlass = {
};
static PCCERT_CONTEXT xmlSecMSCryptoX509FindCert(HCERTSTORE store,
- xmlChar *subjectName,
- xmlChar *issuerName,
- xmlChar *issuerSerial,
- xmlChar *ski);
+ const xmlChar *subjectName,
+ const xmlChar *issuerName,
+ const xmlChar *issuerSerial,
+ const xmlChar *ski);
-/**
+/**
* xmlSecMSCryptoX509StoreGetKlass:
- *
+ *
* The MSCrypto X509 certificates key data store klass.
*
* Returns: pointer to MSCrypto X509 certificates key data store klass.
*/
-xmlSecKeyDataStoreId
+xmlSecKeyDataStoreId
xmlSecMSCryptoX509StoreGetKlass(void) {
return(&xmlSecMSCryptoX509StoreKlass);
}
@@ -122,7 +119,7 @@ xmlSecMSCryptoX509StoreFindCert(xmlSecKeyDataStorePtr store, xmlChar *subjectNam
xmlChar *ski, xmlSecKeyInfoCtx* keyInfoCtx) {
xmlSecMSCryptoX509StoreCtxPtr ctx;
PCCERT_CONTEXT pCert = NULL;
-
+
xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId), NULL);
xmlSecAssert2(keyInfoCtx != NULL, NULL);
@@ -143,7 +140,7 @@ xmlSecMSCryptoX509StoreFindCert(xmlSecKeyDataStorePtr store, xmlChar *subjectNam
}
-static void
+static void
xmlSecMSCryptoUnixTimeToFileTime(time_t t, LPFILETIME pft) {
/* Note that LONGLONG is a 64-bit value */
LONGLONG ll;
@@ -171,7 +168,7 @@ xmlSecMSCrypoVerifyCertTime(PCCERT_CONTEXT pCert, LPFILETIME pft) {
if(-1 == CompareFileTime(&(pCert->pCertInfo->NotAfter), pft)) {
return (FALSE);
}
-
+
return (TRUE);
}
@@ -182,7 +179,7 @@ xmlSecMSCryptoCheckRevocation(HCERTSTORE hStore, PCCERT_CONTEXT pCert) {
xmlSecAssert2(pCert != NULL, FALSE);
xmlSecAssert2(hStore != NULL, FALSE);
-
+
while((pCrl = CertEnumCRLsInStore(hStore, pCrl)) != NULL) {
if (CertFindCertificateInCRL(pCert, pCrl, 0, NULL, &pCrlEntry) && (pCrlEntry != NULL)) {
xmlSecError(XMLSEC_ERRORS_HERE,
@@ -199,7 +196,7 @@ xmlSecMSCryptoCheckRevocation(HCERTSTORE hStore, PCCERT_CONTEXT pCert) {
static void
xmlSecMSCryptoX509StoreCertError(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cert, DWORD flags) {
- LPSTR subject;
+ xmlChar * subject = NULL;
DWORD dwSize;
xmlSecAssert(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId));
@@ -207,20 +204,15 @@ xmlSecMSCryptoX509StoreCertError(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cer
xmlSecAssert(flags != 0);
/* get certs subject */
- dwSize = CertGetNameString(cert, CERT_NAME_RDN_TYPE, 0, NULL, NULL, 0);
- subject = xmlMalloc(dwSize + 1);
+ subject = xmlSecMSCryptoX509GetNameString(cert, CERT_NAME_RDN_TYPE, 0, NULL);
if(subject == NULL) {
xmlSecError(XMLSEC_ERRORS_HERE,
+ "xmlSecMSCryptoX509GetNameString",
NULL,
- NULL,
- XMLSEC_ERRORS_R_MALLOC_FAILED,
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
XMLSEC_ERRORS_NO_MESSAGE);
return;
}
- memset(subject, 0, dwSize + 1);
- if(dwSize > 0) {
- CertGetNameString(cert, CERT_NAME_RDN_TYPE, 0, NULL, subject, dwSize);
- }
/* print error */
if (flags & CERT_STORE_SIGNATURE_FLAG) {
@@ -256,6 +248,7 @@ xmlSecMSCryptoX509StoreCertError(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cer
XMLSEC_ERRORS_R_CERT_VERIFY_FAILED,
XMLSEC_ERRORS_NO_MESSAGE);
}
+
xmlFree(subject);
}
@@ -265,99 +258,99 @@ xmlSecMSCryptoX509StoreCertError(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cer
* @pfTime: pointer to FILETIME that we are interested in
* @store_untrusted: untrusted certificates added via API
* @store_doc: untrusted certificates/CRLs extracted from a document
- *
+ *
* Builds certificates chain using Windows API.
- *
+ *
* Returns: TRUE on success or FALSE otherwise.
*/
-static BOOL
+static BOOL
xmlSecBuildChainUsingWinapi (PCCERT_CONTEXT cert, LPFILETIME pfTime,
- HCERTSTORE store_untrusted, HCERTSTORE store_doc)
+ HCERTSTORE store_untrusted, HCERTSTORE store_doc)
{
- PCCERT_CHAIN_CONTEXT pChainContext = NULL;
- CERT_CHAIN_PARA chainPara;
- BOOL rc = FALSE;
- HCERTSTORE store_add = NULL;
+ PCCERT_CHAIN_CONTEXT pChainContext = NULL;
+ CERT_CHAIN_PARA chainPara;
+ BOOL rc = FALSE;
+ HCERTSTORE store_add = NULL;
/* Initialize data structures. */
- memset(&chainPara, 0, sizeof(CERT_CHAIN_PARA));
- chainPara.cbSize = sizeof(CERT_CHAIN_PARA);
-
- /* Create additional store for CertGetCertificateChain() */
- store_add = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 0, NULL);
- if (!store_add) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- "chain additional collection store",
- "CertOpenStore",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto end;
- }
- if (!CertAddStoreToCollection(store_add, store_doc, 0, 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- "adding document store",
- "CertAddStoreToCollection",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto end;
- }
- if (!CertAddStoreToCollection(store_add, store_untrusted, 0, 0)) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- "adding untrusted store",
- "CertAddStoreToCollection",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto end;
- }
+ memset(&chainPara, 0, sizeof(CERT_CHAIN_PARA));
+ chainPara.cbSize = sizeof(CERT_CHAIN_PARA);
+
+ /* Create additional store for CertGetCertificateChain() */
+ store_add = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, 0, NULL);
+ if (!store_add) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ "chain additional collection store",
+ "CertOpenStore",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto end;
+ }
+ if (!CertAddStoreToCollection(store_add, store_doc, 0, 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ "adding document store",
+ "CertAddStoreToCollection",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto end;
+ }
+ if (!CertAddStoreToCollection(store_add, store_untrusted, 0, 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ "adding untrusted store",
+ "CertAddStoreToCollection",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto end;
+ }
/* Build a chain using CertGetCertificateChain
and the certificate retrieved. */
if(!CertGetCertificateChain(
NULL, /* use the default chain engine */
- cert,
+ cert,
pfTime,
- store_add,
- &chainPara,
- CERT_CHAIN_REVOCATION_CHECK_CHAIN,
+ store_add,
+ &chainPara,
+ CERT_CHAIN_REVOCATION_CHECK_CHAIN,
NULL,
&pChainContext))
{
xmlSecError(XMLSEC_ERRORS_HERE,
- "building certificate chain, checking root",
- "CertGetCertificateChain",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- goto end;
- }
- if (pChainContext->TrustStatus.dwErrorStatus == CERT_TRUST_REVOCATION_STATUS_UNKNOWN) {
- CertFreeCertificateChain(pChainContext); pChainContext = NULL;
- if(!CertGetCertificateChain(
- NULL, /* use the default chain engine */
- cert,
- pfTime,
- store_add,
- &chainPara,
- CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT,
+ "building certificate chain, checking root",
+ "CertGetCertificateChain",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto end;
+ }
+ if (pChainContext->TrustStatus.dwErrorStatus == CERT_TRUST_REVOCATION_STATUS_UNKNOWN) {
+ CertFreeCertificateChain(pChainContext); pChainContext = NULL;
+ if(!CertGetCertificateChain(
+ NULL, /* use the default chain engine */
+ cert,
+ pfTime,
+ store_add,
+ &chainPara,
+ CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT,
NULL,
- &pChainContext))
- {
- xmlSecError(XMLSEC_ERRORS_HERE,
- "building certificate chain, excluding root",
- "CertGetCertificateChain",
- XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ &pChainContext))
+ {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ "building certificate chain, excluding root",
+ "CertGetCertificateChain",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
XMLSEC_ERRORS_NO_MESSAGE);
- goto end;
- }
+ goto end;
+ }
}
- if (pChainContext->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
- rc = TRUE;
+ if (pChainContext->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
+ rc = TRUE;
end:
- if (pChainContext) CertFreeCertificateChain(pChainContext);
- if (store_add) CertCloseStore(store_add, 0);
- return (rc);
+ if (pChainContext) CertFreeCertificateChain(pChainContext);
+ if (store_add) CertCloseStore(store_add, 0);
+ return (rc);
}
/**
@@ -368,15 +361,15 @@ end:
* @store_untrusted: untrusted certificates added via API
* @certs: untrusted certificates/CRLs extracted from a document
* @store: pointer to store klass passed to error functions
- *
+ *
* Builds certificates chain manually.
- *
+ *
* Returns: TRUE on success or FALSE otherwise.
*/
static BOOL
xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime,
- HCERTSTORE store_trusted, HCERTSTORE store_untrusted, HCERTSTORE certs,
- xmlSecKeyDataStorePtr store) {
+ HCERTSTORE store_trusted, HCERTSTORE store_untrusted, HCERTSTORE certs,
+ xmlSecKeyDataStorePtr store) {
PCCERT_CONTEXT issuerCert = NULL;
DWORD flags;
@@ -393,7 +386,7 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime,
* Try to find the cert in the trusted cert store. We will trust
* the certificate in the trusted store.
*/
- issuerCert = CertFindCertificateInStore(store_trusted,
+ issuerCert = CertFindCertificateInStore(store_trusted,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CERT_FIND_SUBJECT_NAME,
@@ -401,7 +394,7 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime,
NULL);
if( issuerCert != NULL) {
/* We have found the trusted cert, so return true */
- /* todo: do we want to verify the trusted cert's revocation? we must, I think */
+ /* todo: do we want to verify the trusted cert's revocation? we must, I think */
CertFreeCertificateContext( issuerCert ) ;
return( TRUE ) ;
}
@@ -412,7 +405,7 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime,
}
/* try to find issuer cert in the trusted cert in the store */
- issuerCert = CertFindCertificateInStore(store_trusted,
+ issuerCert = CertFindCertificateInStore(store_trusted,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CERT_FIND_SUBJECT_NAME,
@@ -425,14 +418,14 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime,
CertFreeCertificateContext(issuerCert);
return(FALSE);
}
- /* todo: do we want to verify the trusted cert? we must check
- * revocation, I think */
+ /* todo: do we want to verify the trusted cert? we must check
+ * revocation, I think */
CertFreeCertificateContext(issuerCert);
return(TRUE);
}
/* try the untrusted certs in the chain */
- issuerCert = CertFindCertificateInStore(certs,
+ issuerCert = CertFindCertificateInStore(certs,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CERT_FIND_SUBJECT_NAME,
@@ -445,7 +438,7 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime,
CertFreeCertificateContext(issuerCert);
return(FALSE);
}
- if(!xmlSecMSCryptoBuildCertChainManually(issuerCert, pfTime, store_trusted, store_untrusted, certs, store)) {
+ if(!xmlSecMSCryptoBuildCertChainManually(issuerCert, pfTime, store_trusted, store_untrusted, certs, store)) {
xmlSecMSCryptoX509StoreCertError(store, issuerCert, flags);
CertFreeCertificateContext(issuerCert);
return(FALSE);
@@ -455,7 +448,7 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime,
}
/* try the untrusted certs in the store */
- issuerCert = CertFindCertificateInStore(store_untrusted,
+ issuerCert = CertFindCertificateInStore(store_untrusted,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CERT_FIND_SUBJECT_NAME,
@@ -468,7 +461,7 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime,
CertFreeCertificateContext(issuerCert);
return(FALSE);
}
- if(!xmlSecMSCryptoBuildCertChainManually(issuerCert, pfTime, store_trusted, store_untrusted, certs, store)) {
+ if(!xmlSecMSCryptoBuildCertChainManually(issuerCert, pfTime, store_trusted, store_untrusted, certs, store)) {
CertFreeCertificateContext(issuerCert);
return(FALSE);
}
@@ -480,13 +473,13 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime,
}
static BOOL
-xmlSecMSCryptoX509StoreConstructCertsChain(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cert, HCERTSTORE certs,
- xmlSecKeyInfoCtx* keyInfoCtx) {
+xmlSecMSCryptoX509StoreConstructCertsChain(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cert, HCERTSTORE certs,
+ xmlSecKeyInfoCtx* keyInfoCtx) {
xmlSecMSCryptoX509StoreCtxPtr ctx;
PCCERT_CONTEXT tempCert = NULL;
FILETIME fTime;
BOOL res = FALSE;
-
+
xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId), FALSE);
xmlSecAssert2(cert != NULL, FALSE);
xmlSecAssert2(cert->pCertInfo != NULL, FALSE);
@@ -499,26 +492,26 @@ xmlSecMSCryptoX509StoreConstructCertsChain(xmlSecKeyDataStorePtr store, PCCERT_C
xmlSecAssert2(ctx->untrusted != NULL, FALSE);
if(keyInfoCtx->certsVerificationTime > 0) {
- /* convert the time to FILETIME */
- xmlSecMSCryptoUnixTimeToFileTime(keyInfoCtx->certsVerificationTime, &fTime);
+ /* convert the time to FILETIME */
+ xmlSecMSCryptoUnixTimeToFileTime(keyInfoCtx->certsVerificationTime, &fTime);
} else {
- /* Defaults to current time */
- GetSystemTimeAsFileTime(&fTime);
+ /* Defaults to current time */
+ GetSystemTimeAsFileTime(&fTime);
}
/* try the certificates in the keys manager */
if(!res) {
- tempCert = CertEnumCertificatesInStore(ctx->trusted, NULL);
- if(tempCert) {
- CertFreeCertificateContext(tempCert);
+ tempCert = CertEnumCertificatesInStore(ctx->trusted, NULL);
+ if(tempCert) {
+ CertFreeCertificateContext(tempCert);
res = xmlSecMSCryptoBuildCertChainManually(cert, &fTime, ctx->trusted, ctx->untrusted, certs, store);
}
}
/* try the certificates in the system */
if(!res && !ctx->dont_use_system_trusted_certs) {
- res = xmlSecBuildChainUsingWinapi(cert, &fTime, ctx->untrusted, certs);
- }
+ res = xmlSecBuildChainUsingWinapi(cert, &fTime, ctx->untrusted, certs);
+ }
/* done */
return res;
@@ -533,7 +526,7 @@ xmlSecMSCryptoX509StoreConstructCertsChain(xmlSecKeyDataStorePtr store, PCCERT_C
* Verifies @certs list.
*
* Returns: pointer to the first verified certificate from @certs.
- */
+ */
PCCERT_CONTEXT
xmlSecMSCryptoX509StoreVerify(xmlSecKeyDataStorePtr store, HCERTSTORE certs,
xmlSecKeyInfoCtx* keyInfoCtx) {
@@ -546,10 +539,10 @@ xmlSecMSCryptoX509StoreVerify(xmlSecKeyDataStorePtr store, HCERTSTORE certs,
while((cert = CertEnumCertificatesInStore(certs, cert)) != NULL){
PCCERT_CONTEXT nextCert = NULL;
unsigned char selected = 1;
-
+
xmlSecAssert2(cert->pCertInfo != NULL, NULL);
- /* if cert is the issuer of any other cert in the list, then it is
+ /* if cert is the issuer of any other cert in the list, then it is
* to be skipped except a case of a celf-signed cert*/
do {
nextCert = CertFindCertificateInStore(certs,
@@ -558,13 +551,13 @@ xmlSecMSCryptoX509StoreVerify(xmlSecKeyDataStorePtr store, HCERTSTORE certs,
CERT_FIND_ISSUER_NAME,
&(cert->pCertInfo->Subject),
nextCert);
- if((nextCert != NULL) && !CertCompareCertificateName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ if((nextCert != NULL) && !CertCompareCertificateName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
&(nextCert->pCertInfo->Subject), &(nextCert->pCertInfo->Issuer))) {
selected = 0;
- }
+ }
} while((selected == 1) && (nextCert != NULL));
if(nextCert != NULL) {
- CertFreeCertificateContext(nextCert);
+ CertFreeCertificateContext(nextCert);
}
if((selected == 1) && xmlSecMSCryptoX509StoreConstructCertsChain(store, cert, certs, keyInfoCtx)) {
@@ -611,8 +604,8 @@ xmlSecMSCryptoX509StoreAdoptCert(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT pCe
return(-1);
}
- /* TODO: The context to be added here is not duplicated first,
- * hopefully this will not lead to errors when closing teh store
+ /* TODO: The context to be added here is not duplicated first,
+ * hopefully this will not lead to errors when closing teh store
* and freeing the mem for all the context in the store.
*/
xmlSecAssert2(certStore != NULL, -1);
@@ -629,8 +622,8 @@ xmlSecMSCryptoX509StoreAdoptCert(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT pCe
}
-/**
- * xmlSecMSCryptoX509StoreAdoptKeyStore:
+/**
+ * xmlSecMSCryptoX509StoreAdoptKeyStore:
* @store: the pointer to X509 key data store klass.
* @keyStore: the pointer to keys store.
*
@@ -638,7 +631,7 @@ xmlSecMSCryptoX509StoreAdoptCert(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT pCe
*
* Returns: 0 on success or a negative value if an error occurs.
*/
-int
+int
xmlSecMSCryptoX509StoreAdoptKeyStore (xmlSecKeyDataStorePtr store, HCERTSTORE keyStore) {
xmlSecMSCryptoX509StoreCtxPtr ctx;
@@ -661,8 +654,8 @@ xmlSecMSCryptoX509StoreAdoptKeyStore (xmlSecKeyDataStorePtr store, HCERTSTORE ke
return(0);
}
-/**
- * xmlSecMSCryptoX509StoreAdoptTrustedStore:
+/**
+ * xmlSecMSCryptoX509StoreAdoptTrustedStore:
* @store: the pointer to X509 key data store klass.
* @trustedStore: the pointer to certs store.
*
@@ -693,8 +686,8 @@ xmlSecMSCryptoX509StoreAdoptTrustedStore (xmlSecKeyDataStorePtr store, HCERTSTOR
return(0);
}
-/**
- * xmlSecMSCryptoX509StoreAdoptUntrustedStore:
+/**
+ * xmlSecMSCryptoX509StoreAdoptUntrustedStore:
* @store: the pointer to X509 key data store klass.
* @untrustedStore: the pointer to certs store.
*
@@ -725,8 +718,8 @@ xmlSecMSCryptoX509StoreAdoptUntrustedStore (xmlSecKeyDataStorePtr store, HCERTST
return(0);
}
-/**
- * xmlSecMSCryptoX509StoreEnableSystemTrustedCerts:
+/**
+ * xmlSecMSCryptoX509StoreEnableSystemTrustedCerts:
* @store: the pointer to X509 key data store klass.
* @val: the enable/disable flag
*
@@ -735,13 +728,13 @@ xmlSecMSCryptoX509StoreAdoptUntrustedStore (xmlSecKeyDataStorePtr store, HCERTST
void
xmlSecMSCryptoX509StoreEnableSystemTrustedCerts (xmlSecKeyDataStorePtr store, int val) {
xmlSecMSCryptoX509StoreCtxPtr ctx;
-
+
xmlSecAssert(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId));
-
+
ctx = xmlSecMSCryptoX509StoreGetCtx(store);
xmlSecAssert(ctx != NULL);
xmlSecAssert(ctx->untrusted != NULL);
-
+
/* it is other way around to make default value 0 mimic old behaiviour */
ctx->dont_use_system_trusted_certs = !val;
}
@@ -857,7 +850,7 @@ xmlSecMSCryptoX509StoreInitialize(xmlSecKeyDataStorePtr store) {
}
CertCloseStore(hUntrustedMemStore, CERT_CLOSE_STORE_CHECK_FLAG);
- return(0);
+ return(0);
}
static void
@@ -884,77 +877,357 @@ xmlSecMSCryptoX509StoreFinalize(xmlSecKeyDataStorePtr store) {
* Low-level x509 functions
*
*****************************************************************************/
-static PCCERT_CONTEXT
-xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issuerName,
- xmlChar *issuerSerial, xmlChar *ski) {
- PCCERT_CONTEXT pCert = NULL;
- int ret;
+/**
+ * xmlSecMSCryptoCertStrToName:
+ * @dwCertEncodingType: the encoding used.
+ * @pszX500: the string to convert.
+ * @dwStrType: the string type.
+ * @len: the result len.
+ *
+ * Converts input string to name by calling @CertStrToName function.
+ *
+ * Returns: a pointer to newly allocated string or NULL if an error occurs.
+ */
+static BYTE*
+xmlSecMSCryptoCertStrToName(DWORD dwCertEncodingType, LPTSTR pszX500, DWORD dwStrType, DWORD* len) {
+ BYTE* str = NULL;
+ LPCTSTR ppszError = NULL;
+
+ xmlSecAssert2(pszX500 != NULL, NULL);
+ xmlSecAssert2(len != NULL, NULL);
+
+ if (!CertStrToName(dwCertEncodingType, pszX500, dwStrType,
+ NULL, NULL, len, &ppszError)) {
+ /* this might not be an error, string might just not exist */
+ DWORD dw = GetLastError();
+ return(NULL);
+ }
- xmlSecAssert2(store != 0, NULL);
+ str = (BYTE *)xmlMalloc(sizeof(TCHAR) * ((*len) + 1));
+ if(str == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "len=%ld", (*len));
+ return(NULL);
+ }
+ memset(str, 0, (*len) + 1);
- if((pCert == NULL) && (NULL != subjectName)) {
- CERT_NAME_BLOB cnb;
- BYTE *cName;
- DWORD cNameLen;
-
- cName = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- subjectName,
- CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
- &cNameLen);
- if(cName == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlSecMSCryptoCertStrToName",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return (NULL);
+ if (!CertStrToName(dwCertEncodingType, pszX500, dwStrType,
+ NULL, str, len, NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "CertStrToName",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(str);
+ return(NULL);
+ }
+
+ return(str);
+}
+
+
+/**
+ * xmlSecMSCryptoX509FindCertBySubject:
+ * @store: the pointer to certs store
+ * @wcSubject: the cert subject (Unicode)
+ * @dwCertEncodingType: the cert encoding type
+ *
+ * Searches for a cert with given @subject in the @store
+ *
+ * Returns: cert handle on success or NULL otherwise
+ */
+PCCERT_CONTEXT
+xmlSecMSCryptoX509FindCertBySubject(HCERTSTORE store, const LPTSTR wcSubject, DWORD dwCertEncodingType) {
+ PCCERT_CONTEXT res = NULL;
+ CERT_NAME_BLOB cnb;
+ BYTE* bdata;
+ DWORD len;
+
+ xmlSecAssert2(store != NULL, NULL);
+ xmlSecAssert2(wcSubject != NULL, NULL);
+
+ /* CASE 1: UTF8, DN */
+ if (NULL == res) {
+ bdata = xmlSecMSCryptoCertStrToName(dwCertEncodingType,
+ wcSubject,
+ CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG | CERT_OID_NAME_STR,
+ &len);
+ if(bdata != NULL) {
+ cnb.cbData = len;
+ cnb.pbData = bdata;
+
+ res = CertFindCertificateInStore(store,
+ dwCertEncodingType,
+ 0,
+ CERT_FIND_SUBJECT_NAME,
+ &cnb,
+ NULL);
+ xmlFree(bdata);
}
- cnb.pbData = cName;
- cnb.cbData = cNameLen;
- pCert = CertFindCertificateInStore(store,
- PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
+ }
+
+ /* CASE 2: UTF8, REVERSE DN */
+ if (NULL == res) {
+ bdata = xmlSecMSCryptoCertStrToName(dwCertEncodingType,
+ wcSubject,
+ CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG | CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
+ &len);
+ if(bdata != NULL) {
+ cnb.cbData = len;
+ cnb.pbData = bdata;
+
+ res = CertFindCertificateInStore(store,
+ dwCertEncodingType,
0,
CERT_FIND_SUBJECT_NAME,
&cnb,
NULL);
- xmlFree(cName);
+ xmlFree(bdata);
+ }
}
- if((pCert == NULL) && (NULL != issuerName) && (NULL != issuerSerial)) {
- xmlSecBn issuerSerialBn;
- xmlChar * p;
- CERT_INFO certInfo;
- CERT_NAME_BLOB cnb;
- BYTE *cName = NULL;
- DWORD cNameLen = 0;
-
- /* aleksey: for some unknown to me reasons, mscrypto wants Email
- * instead of emailAddress. This code is not bullet proof and may
- * produce incorrect results if someone has "emailAddress=" string
- * in one of the fields, but it is best I can suggest to fix this problem.
- * Also see xmlSecMSCryptoX509NameWrite function.
- */
- while( (p = (xmlChar*)xmlStrstr(issuerName, BAD_CAST "emailAddress=")) != NULL) {
- memcpy(p, " Email=", 13);
+ /* CASE 3: UNICODE, DN */
+ if (NULL == res) {
+ bdata = xmlSecMSCryptoCertStrToName(dwCertEncodingType,
+ wcSubject,
+ CERT_OID_NAME_STR,
+ &len);
+ if(bdata != NULL) {
+ cnb.cbData = len;
+ cnb.pbData = bdata;
+
+ res = CertFindCertificateInStore(store,
+ dwCertEncodingType,
+ 0,
+ CERT_FIND_SUBJECT_NAME,
+ &cnb,
+ NULL);
+ xmlFree(bdata);
}
+ }
+ /* CASE 4: UNICODE, REVERSE DN */
+ if (NULL == res) {
+ bdata = xmlSecMSCryptoCertStrToName(dwCertEncodingType,
+ wcSubject,
+ CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
+ &len);
+ if(bdata != NULL) {
+ cnb.cbData = len;
+ cnb.pbData = bdata;
+
+ res = CertFindCertificateInStore(store,
+ dwCertEncodingType,
+ 0,
+ CERT_FIND_SUBJECT_NAME,
+ &cnb,
+ NULL);
+ xmlFree(bdata);
+ }
+ }
- /* get issuer name */
- cName = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- issuerName,
- CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG | CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
- &cNameLen);
- if(cName == NULL) {
+ /* done */
+ return (res);
+}
+
+/**
+ * xmlSecMSCryptoX509FindCertByIssuer:
+ * @store: the pointer to certs store
+ * @wcIssuer: the cert issuer (Unicode)
+ * @issuerSerialBn: the cert issuer serial
+ * @dwCertEncodingType: the cert encoding type
+ *
+ * Searches for a cert with given @subject in the @store
+ *
+ * Returns: cert handle on success or NULL otherwise
+ */
+static PCCERT_CONTEXT
+xmlSecMSCryptoX509FindCertByIssuer(HCERTSTORE store, const LPTSTR wcIssuer,
+ xmlSecBnPtr issuerSerialBn, DWORD dwCertEncodingType) {
+
+ PCCERT_CONTEXT res = NULL;
+ CERT_INFO certInfo;
+ BYTE* bdata;
+ DWORD len;
+
+
+ xmlSecAssert2(store != NULL, NULL);
+ xmlSecAssert2(wcIssuer != NULL, NULL);
+ xmlSecAssert2(issuerSerialBn != NULL, NULL);
+
+ certInfo.SerialNumber.cbData = xmlSecBnGetSize(issuerSerialBn);
+ certInfo.SerialNumber.pbData = xmlSecBnGetData(issuerSerialBn);
+
+
+ /* CASE 1: UTF8, DN */
+ if (NULL == res) {
+ bdata = xmlSecMSCryptoCertStrToName(dwCertEncodingType,
+ wcIssuer,
+ CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG | CERT_OID_NAME_STR,
+ &len);
+ if(bdata != NULL) {
+ certInfo.Issuer.cbData = len;
+ certInfo.Issuer.pbData = bdata;
+
+ res = CertFindCertificateInStore(store,
+ dwCertEncodingType,
+ 0,
+ CERT_FIND_SUBJECT_CERT,
+ &certInfo,
+ NULL);
+ xmlFree(bdata);
+ }
+ }
+
+ /* CASE 2: UTF8, REVERSE DN */
+ if (NULL == res) {
+ bdata = xmlSecMSCryptoCertStrToName(dwCertEncodingType,
+ wcIssuer,
+ CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG | CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
+ &len);
+ if(bdata != NULL) {
+ certInfo.Issuer.cbData = len;
+ certInfo.Issuer.pbData = bdata;
+
+ res = CertFindCertificateInStore(store,
+ dwCertEncodingType,
+ 0,
+ CERT_FIND_SUBJECT_CERT,
+ &certInfo,
+ NULL);
+ xmlFree(bdata);
+ }
+ }
+
+ /* CASE 3: UNICODE, DN */
+ if (NULL == res) {
+ bdata = xmlSecMSCryptoCertStrToName(dwCertEncodingType,
+ wcIssuer,
+ CERT_OID_NAME_STR,
+ &len);
+ if(bdata != NULL) {
+ certInfo.Issuer.cbData = len;
+ certInfo.Issuer.pbData = bdata;
+
+ res = CertFindCertificateInStore(store,
+ dwCertEncodingType,
+ 0,
+ CERT_FIND_SUBJECT_CERT,
+ &certInfo,
+ NULL);
+ xmlFree(bdata);
+ }
+ }
+
+ /* CASE 4: UNICODE, REVERSE DN */
+ if (NULL == res) {
+ bdata = xmlSecMSCryptoCertStrToName(dwCertEncodingType,
+ wcIssuer,
+ CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
+ &len);
+ if(bdata != NULL) {
+ certInfo.Issuer.cbData = len;
+ certInfo.Issuer.pbData = bdata;
+
+ res = CertFindCertificateInStore(store,
+ dwCertEncodingType,
+ 0,
+ CERT_FIND_SUBJECT_CERT,
+ &certInfo,
+ NULL);
+ xmlFree(bdata);
+ }
+ }
+
+
+ /* done */
+ return (res);
+}
+
+static LPTSTR
+xmlSecMSCryptoX509GetCertName(const xmlChar * name) {
+ xmlChar *name2 = NULL;
+ xmlChar *p = NULL;
+ LPTSTR res = NULL;
+
+ xmlSecAssert2(name != 0, NULL);
+
+ /* MSCrypto doesn't support "emailAddress" attribute (see NSS as well).
+ * This code is not bullet proof and may produce incorrect results if someone has
+ * "emailAddress=" string in one of the fields, but it is best I can suggest to fix
+ * this problem.
+ */
+ name2 = xmlStrdup(name);
+ if(name2 == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "xmlStrlen(name)=%d",
+ xmlStrlen(name));
+ return(NULL);
+ }
+ while( (p = (xmlChar*)xmlStrstr(name2, BAD_CAST "emailAddress=")) != NULL) {
+ memcpy(p, " E=", 13);
+ }
+
+ /* get name */
+ res = xmlSecMSCryptoConvertUtf8ToTstr(name2);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecMSCryptoConvertUtf8ToTstr",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ /* done */
+ return(res);
+}
+
+static PCCERT_CONTEXT
+xmlSecMSCryptoX509FindCert(HCERTSTORE store,
+ const xmlChar *subjectName,
+ const xmlChar *issuerName,
+ const xmlChar *issuerSerial,
+ const xmlChar *ski) {
+ PCCERT_CONTEXT pCert = NULL;
+ int ret;
+
+ xmlSecAssert2(store != 0, NULL);
+
+ if((pCert == NULL) && (NULL != subjectName)) {
+ LPTSTR wcSubjectName = NULL;
+
+ /* get unicode subject name */
+ wcSubjectName = xmlSecMSCryptoX509GetCertName(subjectName);
+ if(wcSubjectName == NULL) {
xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlSecMSCryptoCertStrToName",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return (NULL);
+ NULL,
+ "xmlSecMSCryptoX509GetCertName",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "wcSubjectName");
+ return(NULL);
}
- cnb.pbData = cName;
- cnb.cbData = cNameLen;
+
+ /* search */
+ pCert = xmlSecMSCryptoX509FindCertBySubject(store,
+ wcSubjectName,
+ PKCS_7_ASN_ENCODING | X509_ASN_ENCODING);
+
+
+ /* cleanup */
+ xmlFree(wcSubjectName);
+ }
+
+ if((pCert == NULL) && (NULL != issuerName) && (NULL != issuerSerial)) {
+ xmlSecBn issuerSerialBn;
+ LPTSTR wcIssuerName = NULL;
/* get serial number */
ret = xmlSecBnInitialize(&issuerSerialBn, 0);
@@ -964,7 +1237,6 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
"xmlSecBnInitialize",
XMLSEC_ERRORS_R_XMLSEC_FAILED,
XMLSEC_ERRORS_NO_MESSAGE);
- xmlFree(cName);
return(NULL);
}
@@ -976,12 +1248,11 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
XMLSEC_ERRORS_R_XMLSEC_FAILED,
XMLSEC_ERRORS_NO_MESSAGE);
xmlSecBnFinalize(&issuerSerialBn);
- xmlFree(cName);
return(NULL);
}
- /* I have no clue why at a sudden a swap is needed to
- * convert from lsb... This code is purely based upon
+ /* I have no clue why at a sudden a swap is needed to
+ * convert from lsb... This code is purely based upon
* trial and error :( WK
*/
ret = xmlSecBnReverse(&issuerSerialBn);
@@ -992,25 +1263,30 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
XMLSEC_ERRORS_R_XMLSEC_FAILED,
XMLSEC_ERRORS_NO_MESSAGE);
xmlSecBnFinalize(&issuerSerialBn);
- xmlFree(cName);
return(NULL);
}
- certInfo.Issuer.cbData = cnb.cbData ;
- certInfo.Issuer.pbData = cnb.pbData ;
- certInfo.SerialNumber.cbData = xmlSecBnGetSize( &issuerSerialBn ) ;
- certInfo.SerialNumber.pbData = xmlSecBnGetData( &issuerSerialBn ) ;
+ /* get issuer name */
+ wcIssuerName = xmlSecMSCryptoX509GetCertName(issuerName);
+ if(wcIssuerName == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecMSCryptoX509GetCertName",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "wcIssuerName");
+ xmlSecBnFinalize(&issuerSerialBn);
+ return(NULL);
+ }
+
+ /* search */
+ pCert = xmlSecMSCryptoX509FindCertByIssuer(store,
+ wcIssuerName,
+ &issuerSerialBn,
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING);
- pCert = CertFindCertificateInStore(
- store,
- X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- 0,
- CERT_FIND_SUBJECT_CERT,
- &certInfo,
- NULL
- ) ;
+ xmlFree(wcIssuerName);
- xmlFree(cName);
+ /* cleanup */
xmlSecBnFinalize(&issuerSerialBn);
}
@@ -1044,7 +1320,7 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
blob.pbData = binSki;
blob.cbData = binSkiLen;
- pCert = CertFindCertificateInStore(store,
+ pCert = CertFindCertificateInStore(store,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
0,
CERT_FIND_KEY_IDENTIFIER,
@@ -1053,10 +1329,78 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
xmlFree(binSki);
}
- return(pCert);
+ return(pCert);
}
+/**
+ * xmlSecMSCryptoX509GetNameString:
+ * @pCertContext: the pointer to cert
+ * @dwType: the type (see CertGetNameString description in MSDN)
+ * @dwFlags: the flags (see CertGetNameString description in MSDN)
+ * @pvTypePara: the type parameter (see CertGetNameString description in MSDN)
+ *
+ * Gets the name string for certificate (see CertGetNameString description in MSDN).
+ *
+ * Returns: name string (should be freed with xmlFree) or NULL if failed.
+ */
+xmlChar *
+xmlSecMSCryptoX509GetNameString(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void *pvTypePara) {
+ LPTSTR name = NULL;
+ xmlChar * res = NULL;
+ DWORD dwSize;
+
+ xmlSecAssert2(pCertContext != NULL, NULL);
+
+ /* get size first */
+ dwSize = CertGetNameString(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
+ if(dwSize <= 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ "CertGetNameString",
+ NULL,
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return (NULL);
+ }
+
+ /* allocate buffer */
+ name = (LPTSTR)xmlMalloc(sizeof(TCHAR) * (dwSize + 1));
+ if(name == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return (NULL);
+ }
+
+ /* actually get the name */
+ dwSize = CertGetNameString(pCertContext, dwType, dwFlags, pvTypePara, name, dwSize);
+ if(dwSize <= 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ "CertGetNameString",
+ NULL,
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(name);
+ return (NULL);
+ }
+
+ res = xmlSecMSCryptoConvertTstrToUtf8(name);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ "xmlSecMSCryptoConvertTstrToUtf8",
+ NULL,
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(name);
+ return (NULL);
+ }
+ /* done */
+ xmlFree(name);
+ return (res);
+}
+
#endif /* XMLSEC_NO_X509 */