diff options
Diffstat (limited to 'src/mscrypto/x509vfy.c')
-rw-r--r-- | src/mscrypto/x509vfy.c | 790 |
1 files changed, 223 insertions, 567 deletions
diff --git a/src/mscrypto/x509vfy.c b/src/mscrypto/x509vfy.c index cf317877..d854e7a0 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. - * - * Copyright (C) 2003 Cordys R&D BV, All rights reserved. + * + * Copyrigth (C) 2003 Cordys R&D BV, All rights reserved. * Copyright (C) 2003 Aleksey Sanin <aleksey@aleksey.com> */ #include "globals.h" @@ -33,20 +33,23 @@ #include <xmlsec/mscrypto/crypto.h> #include <xmlsec/mscrypto/x509.h> -#include "private.h" + +#if defined(__MINGW32__) +# include "xmlsec-mingw.h" +#endif /************************************************************************** * * 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; -}; +}; /**************************************************************************** * @@ -60,7 +63,7 @@ struct _xmlSecMSCryptoX509StoreCtx { sizeof(xmlSecKeyDataStoreKlass))) #define xmlSecMSCryptoX509StoreSize \ (sizeof(xmlSecKeyDataStoreKlass) + sizeof(xmlSecMSCryptoX509StoreCtx)) - + static int xmlSecMSCryptoX509StoreInitialize (xmlSecKeyDataStorePtr store); static void xmlSecMSCryptoX509StoreFinalize (xmlSecKeyDataStorePtr store); @@ -69,8 +72,8 @@ static xmlSecKeyDataStoreKlass xmlSecMSCryptoX509StoreKlass = { xmlSecMSCryptoX509StoreSize, /* data */ - xmlSecNameX509Store, /* const xmlChar* name; */ - + xmlSecNameX509Store, /* const xmlChar* name; */ + /* constructors/destructor */ xmlSecMSCryptoX509StoreInitialize, /* xmlSecKeyDataStoreInitializeMethod initialize; */ xmlSecMSCryptoX509StoreFinalize, /* xmlSecKeyDataStoreFinalizeMethod finalize; */ @@ -81,20 +84,20 @@ static xmlSecKeyDataStoreKlass xmlSecMSCryptoX509StoreKlass = { }; static PCCERT_CONTEXT xmlSecMSCryptoX509FindCert(HCERTSTORE store, - const xmlChar *subjectName, - const xmlChar *issuerName, - const xmlChar *issuerSerial, - const xmlChar *ski); + xmlChar *subjectName, + xmlChar *issuerName, + xmlChar *issuerSerial, + 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); } @@ -119,7 +122,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); @@ -140,7 +143,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; @@ -168,7 +171,7 @@ xmlSecMSCrypoVerifyCertTime(PCCERT_CONTEXT pCert, LPFILETIME pft) { if(-1 == CompareFileTime(&(pCert->pCertInfo->NotAfter), pft)) { return (FALSE); } - + return (TRUE); } @@ -179,7 +182,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, @@ -196,7 +199,7 @@ xmlSecMSCryptoCheckRevocation(HCERTSTORE hStore, PCCERT_CONTEXT pCert) { static void xmlSecMSCryptoX509StoreCertError(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cert, DWORD flags) { - xmlChar * subject = NULL; + LPSTR subject; DWORD dwSize; xmlSecAssert(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId)); @@ -204,15 +207,20 @@ xmlSecMSCryptoX509StoreCertError(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cer xmlSecAssert(flags != 0); /* get certs subject */ - subject = xmlSecMSCryptoX509GetNameString(cert, CERT_NAME_RDN_TYPE, 0, NULL); + dwSize = CertGetNameString(cert, CERT_NAME_RDN_TYPE, 0, NULL, NULL, 0); + subject = xmlMalloc(dwSize + 1); if(subject == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, - "xmlSecMSCryptoX509GetNameString", NULL, - XMLSEC_ERRORS_R_XMLSEC_FAILED, + NULL, + XMLSEC_ERRORS_R_MALLOC_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) { @@ -248,7 +256,6 @@ xmlSecMSCryptoX509StoreCertError(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cer XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, XMLSEC_ERRORS_NO_MESSAGE); } - xmlFree(subject); } @@ -258,99 +265,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); } /** @@ -361,15 +368,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; @@ -386,7 +393,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, @@ -394,7 +401,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 ) ; } @@ -405,7 +412,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, @@ -418,14 +425,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, @@ -438,7 +445,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); @@ -448,7 +455,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, @@ -461,7 +468,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); } @@ -473,13 +480,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); @@ -492,26 +499,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; @@ -526,7 +533,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) { @@ -539,10 +546,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, @@ -551,13 +558,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)) { @@ -604,8 +611,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); @@ -622,8 +629,8 @@ xmlSecMSCryptoX509StoreAdoptCert(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT pCe } -/** - * xmlSecMSCryptoX509StoreAdoptKeyStore: +/** + * xmlSecMSCryptoX509StoreAdoptKeyStore: * @store: the pointer to X509 key data store klass. * @keyStore: the pointer to keys store. * @@ -631,7 +638,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; @@ -654,8 +661,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. * @@ -686,8 +693,8 @@ xmlSecMSCryptoX509StoreAdoptTrustedStore (xmlSecKeyDataStorePtr store, HCERTSTOR return(0); } -/** - * xmlSecMSCryptoX509StoreAdoptUntrustedStore: +/** + * xmlSecMSCryptoX509StoreAdoptUntrustedStore: * @store: the pointer to X509 key data store klass. * @untrustedStore: the pointer to certs store. * @@ -718,8 +725,8 @@ xmlSecMSCryptoX509StoreAdoptUntrustedStore (xmlSecKeyDataStorePtr store, HCERTST return(0); } -/** - * xmlSecMSCryptoX509StoreEnableSystemTrustedCerts: +/** + * xmlSecMSCryptoX509StoreEnableSystemTrustedCerts: * @store: the pointer to X509 key data store klass. * @val: the enable/disable flag * @@ -728,13 +735,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; } @@ -850,7 +857,7 @@ xmlSecMSCryptoX509StoreInitialize(xmlSecKeyDataStorePtr store) { } CertCloseStore(hUntrustedMemStore, CERT_CLOSE_STORE_CHECK_FLAG); - return(0); + return(0); } static void @@ -877,357 +884,77 @@ xmlSecMSCryptoX509StoreFinalize(xmlSecKeyDataStorePtr store) { * Low-level x509 functions * *****************************************************************************/ -/** - * 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); - } - - 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 (!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); - } - } +static PCCERT_CONTEXT +xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issuerName, + xmlChar *issuerSerial, xmlChar *ski) { + PCCERT_CONTEXT pCert = NULL; + int ret; - /* 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(bdata); - } - } + xmlSecAssert2(store != 0, NULL); - /* 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); + 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); } - } - - /* 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, + cnb.pbData = cName; + cnb.cbData = cNameLen; + pCert = CertFindCertificateInStore(store, + PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &cnb, NULL); - xmlFree(bdata); - } - } - - - /* 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); - } + xmlFree(cName); } - /* 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); + 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); } - } - /* 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) { + /* 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) { xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecMSCryptoX509GetCertName", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "wcSubjectName"); - return(NULL); + NULL, + "xmlSecMSCryptoCertStrToName", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return (NULL); } - - /* 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; + cnb.pbData = cName; + cnb.cbData = cNameLen; /* get serial number */ ret = xmlSecBnInitialize(&issuerSerialBn, 0); @@ -1237,6 +964,7 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, "xmlSecBnInitialize", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(cName); return(NULL); } @@ -1248,11 +976,12 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, 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); @@ -1263,30 +992,25 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecBnFinalize(&issuerSerialBn); + xmlFree(cName); return(NULL); } - /* 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); + certInfo.Issuer.cbData = cnb.cbData ; + certInfo.Issuer.pbData = cnb.pbData ; + certInfo.SerialNumber.cbData = xmlSecBnGetSize( &issuerSerialBn ) ; + certInfo.SerialNumber.pbData = xmlSecBnGetData( &issuerSerialBn ) ; - xmlFree(wcIssuerName); + pCert = CertFindCertificateInStore( + store, + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + 0, + CERT_FIND_SUBJECT_CERT, + &certInfo, + NULL + ) ; - /* cleanup */ + xmlFree(cName); xmlSecBnFinalize(&issuerSerialBn); } @@ -1320,7 +1044,7 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, blob.pbData = binSki; blob.cbData = binSkiLen; - pCert = CertFindCertificateInStore(store, + pCert = CertFindCertificateInStore(store, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, CERT_FIND_KEY_IDENTIFIER, @@ -1329,78 +1053,10 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, 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 */ |