From af3656ea5614b701de65713a1abcaea787b2adb8 Mon Sep 17 00:00:00 2001 From: Aleksey Sanin Date: Thu, 18 Jul 2024 09:05:05 -0400 Subject: [PATCH 1/5] (xmlsec-mscng) Improve cert verification --- src/mscng/x509vfy.c | 99 +++++++++++++++++++++++++++++++++------------ win32/mycfg.bat | 2 +- 2 files changed, 74 insertions(+), 27 deletions(-) diff --git a/src/mscng/x509vfy.c b/src/mscng/x509vfy.c index 288e164ef..9d441df86 100644 --- a/src/mscng/x509vfy.c +++ b/src/mscng/x509vfy.c @@ -397,6 +397,42 @@ xmlSecMSCngCheckRevocation(HCERTSTORE store, PCCERT_CONTEXT cert) { return(0); } +/* this function does NOT check for time validity (see xmlSecMSCngVerifyCertTime) +* returns <0 if there is an error; 0 if verification failed and >0 if verification succeeded */ +static int +xmlSecMSCngX509StoreVerifySubject(PCCERT_CONTEXT cert, PCCERT_CONTEXT issuerCert) { + DWORD flags; + BOOL ret; + + xmlSecAssert2(cert != NULL, -1); + xmlSecAssert2(issuerCert != NULL, -1); + + flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG; + ret = CertVerifySubjectCertificateContext(cert, issuerCert, &flags); + if (!ret) { + xmlSecMSCngLastError("CertVerifySubjectCertificateContext", NULL); + return(-1); + } + + /* parse returned flags: https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms883939(v=msdn.10) */ + if ((flags & CERT_STORE_SIGNATURE_FLAG) != 0) { + xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, + NULL, + "CertVerifySubjectCertificateContext: CERT_STORE_SIGNATURE_FLAG"); + return(0); + } else if (((flags & CERT_STORE_REVOCATION_FLAG) != 0) && ((flags & CERT_STORE_NO_CRL_FLAG) == 0)) { + /* If CERT_STORE_REVOCATION_FLAG is enabled and the issuer does not have a CRL in the store, + then CERT_STORE_NO_CRL_FLAG is set in addition to CERT_STORE_REVOCATION_FLAG. */ + xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, + NULL, + "CertVerifySubjectCertificateContext: CERT_STORE_REVOCATION_FLAG"); + return(0); + } + + /* success */ + return(1); +} + /** * xmlSecMSCngX509StoreContainsCert: * @store: the certificate store @@ -413,7 +449,6 @@ xmlSecMSCngX509StoreContainsCert(HCERTSTORE store, CERT_NAME_BLOB* name, PCCERT_CONTEXT cert) { PCCERT_CONTEXT issuerCert = NULL; - DWORD flags; int ret; xmlSecAssert2(store != NULL, -1); @@ -426,23 +461,26 @@ xmlSecMSCngX509StoreContainsCert(HCERTSTORE store, CERT_NAME_BLOB* name, CERT_FIND_SUBJECT_NAME, name, NULL); - if(issuerCert != NULL) { - flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG; - ret = CertVerifySubjectCertificateContext(cert, - issuerCert, - &flags); - if(ret == 0) { - xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, - NULL, - "CertVerifySubjectCertificateContext"); - CertFreeCertificateContext(issuerCert); - return(-1); - } + if (issuerCert == NULL) { + return (0); + } + + ret = xmlSecMSCngX509StoreVerifySubject(cert, issuerCert); + if (ret < 0) { + xmlSecInternalError("xmlSecMSCngX509StoreVerifySubject", NULL); CertFreeCertificateContext(issuerCert); - return(1); + return(-1); + } else if (ret == 0) { + xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, + NULL, + "xmlSecMSCngX509StoreVerifySubject"); + CertFreeCertificateContext(issuerCert); + return(-1); } - return(0); + /* success */ + CertFreeCertificateContext(issuerCert); + return(1); } static int @@ -485,7 +523,6 @@ xmlSecMSCngX509StoreVerifyCertificateOwn(PCCERT_CONTEXT cert, FILETIME* time, HCERTSTORE trustedStore, HCERTSTORE untrustedStore, HCERTSTORE certStore ) { PCCERT_CONTEXT issuerCert = NULL; - DWORD flags; int ret; xmlSecAssert2(cert != NULL, -1); @@ -543,11 +580,16 @@ xmlSecMSCngX509StoreVerifyCertificateOwn(PCCERT_CONTEXT cert, FILETIME* time, &cert->pCertInfo->Issuer, NULL); if(issuerCert != NULL) { - flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG; - ret = CertVerifySubjectCertificateContext(cert, issuerCert, &flags); - if(ret == 0) { - xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, NULL, - "CertVerifySubjectCertificateContext"); + ret = xmlSecMSCngX509StoreVerifySubject(cert, issuerCert); + if (ret < 0) { + xmlSecInternalError("xmlSecMSCngX509StoreVerifySubject", NULL); + CertFreeCertificateContext(issuerCert); + return(-1); + } + else if (ret == 0) { + xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, + NULL, + "xmlSecMSCngX509StoreVerifySubject"); CertFreeCertificateContext(issuerCert); return(-1); } @@ -574,11 +616,16 @@ xmlSecMSCngX509StoreVerifyCertificateOwn(PCCERT_CONTEXT cert, FILETIME* time, &cert->pCertInfo->Issuer, NULL); if(issuerCert != NULL) { - flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG; - ret = CertVerifySubjectCertificateContext(cert, issuerCert, &flags); - if(ret == 0) { - xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, NULL, - "CertVerifySubjectCertificateContext"); + ret = xmlSecMSCngX509StoreVerifySubject(cert, issuerCert); + if (ret < 0) { + xmlSecInternalError("xmlSecMSCngX509StoreVerifySubject", NULL); + CertFreeCertificateContext(issuerCert); + return(-1); + } + else if (ret == 0) { + xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, + NULL, + "xmlSecMSCngX509StoreVerifySubject"); CertFreeCertificateContext(issuerCert); return(-1); } diff --git a/win32/mycfg.bat b/win32/mycfg.bat index 5385c714c..6bfd5050a 100644 --- a/win32/mycfg.bat +++ b/win32/mycfg.bat @@ -8,7 +8,7 @@ REM REM Aleksey Sanin REM -SET XMLSEC_CRYPTO=mscng,mscrypto +SET XMLSEC_CRYPTO=mscng SET PREFIX=C:\local\distro SET LIBXML2_PREFIX=%PREFIX%\libxml2 From f448516a29d5e3f583dff966ead164c7f0669aa1 Mon Sep 17 00:00:00 2001 From: Aleksey Sanin Date: Thu, 18 Jul 2024 09:34:39 -0400 Subject: [PATCH 2/5] (xmlsec-mscrypto) Improve cert verification --- src/mscrypto/x509vfy.c | 174 +++++++++++++++++++++-------------------- win32/mycfg.bat | 2 +- 2 files changed, 90 insertions(+), 86 deletions(-) diff --git a/src/mscrypto/x509vfy.c b/src/mscrypto/x509vfy.c index 450ba1932..c1dd95ac2 100644 --- a/src/mscrypto/x509vfy.c +++ b/src/mscrypto/x509vfy.c @@ -234,53 +234,6 @@ xmlSecMSCryptoCheckRevocation(HCERTSTORE hStore, PCCERT_CONTEXT pCert) { return(TRUE); } -static void -xmlSecMSCryptoX509StoreCertError(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cert, DWORD flags) { - xmlChar * subject = NULL; - - xmlSecAssert(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId)); - xmlSecAssert(cert != NULL); - xmlSecAssert(flags != 0); - - /* get certs subject */ - subject = xmlSecMSCryptoX509GetNameString(cert, CERT_NAME_RDN_TYPE, 0, NULL); - if(subject == NULL) { - xmlSecInternalError("xmlSecMSCryptoX509GetNameString", NULL); - return; - } - - /* print error */ - if (flags & CERT_STORE_SIGNATURE_FLAG) { - xmlSecOtherError2(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, - xmlSecKeyDataStoreGetName(store), - "signature failed, subject=%s", - xmlSecErrorsSafeString(subject)); - } else if (flags & CERT_STORE_TIME_VALIDITY_FLAG) { - xmlSecOtherError2(XMLSEC_ERRORS_R_CERT_HAS_EXPIRED, - xmlSecKeyDataStoreGetName(store), - "subject=%s", - xmlSecErrorsSafeString(subject)); - } else if (flags & CERT_STORE_REVOCATION_FLAG) { - if (flags & CERT_STORE_NO_CRL_FLAG) { - xmlSecOtherError2(XMLSEC_ERRORS_R_CERT_REVOKED, - xmlSecKeyDataStoreGetName(store), - "no crl, subject=%s", - xmlSecErrorsSafeString(subject)); - } else { - xmlSecOtherError2(XMLSEC_ERRORS_R_CERT_REVOKED, - xmlSecKeyDataStoreGetName(store), - "subject=%s", - xmlSecErrorsSafeString(subject)); - } - } else { - xmlSecOtherError2(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, - xmlSecKeyDataStoreGetName(store), - "subject=%s", - xmlSecErrorsSafeString(subject)); - } - - xmlFree(subject); -} /** * xmlSecBuildChainUsingWinapi: @@ -359,6 +312,46 @@ xmlSecBuildChainUsingWinapi (PCCERT_CONTEXT cert, LPFILETIME pfTime, return (rc); } + + +/* this function does NOT check for time validity (see xmlSecMSCngVerifyCertTime) +* returns <0 if there is an error; 0 if verification failed and >0 if verification succeeded */ +static int +xmlSecMSCryptoX509StoreVerifySubject(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT cert, PCCERT_CONTEXT issuerCert) { + DWORD flags; + BOOL ret; + + xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecMSCryptoX509StoreId), -1); + xmlSecAssert2(cert != NULL, -1); + xmlSecAssert2(issuerCert != NULL, -1); + + flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG; + ret = CertVerifySubjectCertificateContext(cert, issuerCert, &flags); + if (!ret) { + xmlSecMSCryptoError("CertVerifySubjectCertificateContext", NULL); + return(-1); + } + + /* parse returned flags: https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms883939(v=msdn.10) */ + if ((flags & CERT_STORE_SIGNATURE_FLAG) != 0) { + xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, + xmlSecKeyDataStoreGetName(store), + "CertVerifySubjectCertificateContext: CERT_STORE_SIGNATURE_FLAG"); + return(0); + } + else if (((flags & CERT_STORE_REVOCATION_FLAG) != 0) && ((flags & CERT_STORE_NO_CRL_FLAG) == 0)) { + /* If CERT_STORE_REVOCATION_FLAG is enabled and the issuer does not have a CRL in the store, + then CERT_STORE_NO_CRL_FLAG is set in addition to CERT_STORE_REVOCATION_FLAG. */ + xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, + xmlSecKeyDataStoreGetName(store), + "CertVerifySubjectCertificateContext: CERT_STORE_REVOCATION_FLAG"); + return(0); + } + + /* success */ + return(1); +} + /** * xmlSecMSCryptoBuildCertChainManually: * @cert: the certificate we check @@ -377,36 +370,19 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime, HCERTSTORE store_trusted, HCERTSTORE store_untrusted, HCERTSTORE certs, xmlSecKeyDataStorePtr store) { PCCERT_CONTEXT issuerCert = NULL; - DWORD flags; + int ret; if (!xmlSecMSCryptoVerifyCertTime(cert, pfTime)) { - xmlSecMSCryptoX509StoreCertError(store, cert, CERT_STORE_TIME_VALIDITY_FLAG); + xmlSecOtherError(XMLSEC_ERRORS_R_CERT_HAS_EXPIRED, + xmlSecKeyDataStoreGetName(store), + "certificate expired"); return(FALSE); } if (!xmlSecMSCryptoCheckRevocation(certs, cert)) { - return(FALSE); - } - - /* - * Try to find the cert in the trusted cert store. We will trust - * the certificate in the trusted store. - */ - issuerCert = CertFindCertificateInStore(store_trusted, - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - 0, - CERT_FIND_SUBJECT_NAME, - &(cert->pCertInfo->Subject), - 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 */ - CertFreeCertificateContext( issuerCert ) ; - return( TRUE ) ; - } - - /* Check whether the certificate is self signed certificate */ - if(CertCompareCertificateName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &(cert->pCertInfo->Subject), &(cert->pCertInfo->Issuer))) { + xmlSecOtherError(XMLSEC_ERRORS_R_CRL_VERIFY_FAILED, + xmlSecKeyDataStoreGetName(store), + "certificate revoked");; return(FALSE); } @@ -418,14 +394,21 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime, &(cert->pCertInfo->Issuer), NULL); if(issuerCert != NULL) { - flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG; - if(!CertVerifySubjectCertificateContext(cert, issuerCert, &flags)) { - xmlSecMSCryptoX509StoreCertError(store, issuerCert, flags); + ret = xmlSecMSCryptoX509StoreVerifySubject(store, cert, issuerCert); + if (ret < 0) { + xmlSecInternalError("xmlSecMSCryptoX509StoreVerifySubject", NULL); + CertFreeCertificateContext(issuerCert); + return(FALSE); + } + else if (ret == 0) { + xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, + NULL, + "xmlSecMSCryptoX509StoreVerifySubject"); CertFreeCertificateContext(issuerCert); return(FALSE); } - /* todo: do we want to verify the trusted cert? we must check - * revocation, I think */ + + /* success */ CertFreeCertificateContext(issuerCert); return(TRUE); } @@ -438,17 +421,27 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime, &(cert->pCertInfo->Issuer), NULL); if(issuerCert != NULL) { - flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG; - if(!CertVerifySubjectCertificateContext(cert, issuerCert, &flags)) { - xmlSecMSCryptoX509StoreCertError(store, issuerCert, flags); + ret = xmlSecMSCryptoX509StoreVerifySubject(store, cert, issuerCert); + if (ret < 0) { + xmlSecInternalError("xmlSecMSCryptoX509StoreVerifySubject", NULL); CertFreeCertificateContext(issuerCert); return(FALSE); } - if(!xmlSecMSCryptoBuildCertChainManually(issuerCert, pfTime, store_trusted, store_untrusted, certs, store)) { - xmlSecMSCryptoX509StoreCertError(store, issuerCert, flags); + else if (ret == 0) { + xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, + NULL, + "xmlSecMSCryptoX509StoreVerifySubject"); CertFreeCertificateContext(issuerCert); return(FALSE); } + + if (!xmlSecMSCryptoBuildCertChainManually(issuerCert, pfTime, store_trusted, store_untrusted, certs, store)) { + xmlSecInternalError("xmlSecMSCryptoBuildCertChainManually", NULL); + CertFreeCertificateContext(issuerCert); + return(FALSE); + } + + /* success */ CertFreeCertificateContext(issuerCert); return(TRUE); } @@ -461,16 +454,27 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime, &(cert->pCertInfo->Issuer), NULL); if(issuerCert != NULL) { - flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG; - if(!CertVerifySubjectCertificateContext(cert, issuerCert, &flags)) { - xmlSecMSCryptoX509StoreCertError(store, issuerCert, flags); + ret = xmlSecMSCryptoX509StoreVerifySubject(store, cert, issuerCert); + if (ret < 0) { + xmlSecInternalError("xmlSecMSCryptoX509StoreVerifySubject", NULL); + CertFreeCertificateContext(issuerCert); + return(FALSE); + } + else if (ret == 0) { + xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, + NULL, + "xmlSecMSCryptoX509StoreVerifySubject"); CertFreeCertificateContext(issuerCert); return(FALSE); } - if(!xmlSecMSCryptoBuildCertChainManually(issuerCert, pfTime, store_trusted, store_untrusted, certs, store)) { + + if (!xmlSecMSCryptoBuildCertChainManually(issuerCert, pfTime, store_trusted, store_untrusted, certs, store)) { + xmlSecInternalError("xmlSecMSCryptoBuildCertChainManually", NULL); CertFreeCertificateContext(issuerCert); return(FALSE); } + + /* success */ CertFreeCertificateContext(issuerCert); return(TRUE); } diff --git a/win32/mycfg.bat b/win32/mycfg.bat index 6bfd5050a..f38d88aef 100644 --- a/win32/mycfg.bat +++ b/win32/mycfg.bat @@ -8,7 +8,7 @@ REM REM Aleksey Sanin REM -SET XMLSEC_CRYPTO=mscng +SET XMLSEC_CRYPTO=mscrypto SET PREFIX=C:\local\distro SET LIBXML2_PREFIX=%PREFIX%\libxml2 From 732cdc1a3093d45d87f48878d10a7f094de72197 Mon Sep 17 00:00:00 2001 From: Aleksey Sanin Date: Thu, 18 Jul 2024 11:02:58 -0400 Subject: [PATCH 3/5] Added test, added docs, cleanup code a bit more --- docs/index.html | 4 +- src/mscng/certkeys.c | 2 +- src/mscng/x509vfy.c | 34 +++---- src/mscrypto/x509vfy.c | 90 +++++++++++++----- src/nss/x509.c | 4 +- .../enveloped-x509-same-subj-cert.tmpl | 31 ++++++ .../enveloped-x509-same-subj-cert.xml | 58 +++++++++++ tests/keys/README.md | 14 +++ tests/keys/same-subj-cert1.der | Bin 0 -> 1011 bytes tests/keys/same-subj-cert1.pem | 24 +++++ tests/keys/same-subj-cert2.der | Bin 0 -> 1011 bytes tests/keys/same-subj-cert2.pem | 24 +++++ tests/keys/same-subj-key1.der | Bin 0 -> 1218 bytes tests/keys/same-subj-key1.pem | 28 ++++++ tests/keys/same-subj-key2.der | Bin 0 -> 1217 bytes tests/keys/same-subj-key2.pem | 28 ++++++ tests/testDSig.sh | 35 ++++++- win32/mycfg.bat | 2 +- 18 files changed, 332 insertions(+), 46 deletions(-) create mode 100644 tests/aleksey-xmldsig-01/enveloped-x509-same-subj-cert.tmpl create mode 100755 tests/aleksey-xmldsig-01/enveloped-x509-same-subj-cert.xml create mode 100644 tests/keys/same-subj-cert1.der create mode 100644 tests/keys/same-subj-cert1.pem create mode 100644 tests/keys/same-subj-cert2.der create mode 100644 tests/keys/same-subj-cert2.pem create mode 100644 tests/keys/same-subj-key1.der create mode 100644 tests/keys/same-subj-key1.pem create mode 100644 tests/keys/same-subj-key2.der create mode 100644 tests/keys/same-subj-key2.pem diff --git a/docs/index.html b/docs/index.html index d77ef40a3..0c76d2e40 100644 --- a/docs/index.html +++ b/docs/index.html @@ -72,8 +72,8 @@

XML Security Library



    -
  • - (xmlsec-core) Fix deprecated functions in LibXML2 2.13.1 including disabling HTTP support +
  • (xmlsec-mscng,xmlsec-mscrypto) Improved certificates verification.
  • +
  • (xmlsec-core) Fix deprecated functions in LibXML2 2.13.1 including disabling HTTP support by default (use ''--enable-http' option to re-enable it).
  • Several other small fixes (see more details).
diff --git a/src/mscng/certkeys.c b/src/mscng/certkeys.c index 9ec83e5e2..dc3138a68 100644 --- a/src/mscng/certkeys.c +++ b/src/mscng/certkeys.c @@ -52,7 +52,7 @@ xmlSecMSCngKeyDataCertGetPubkey(PCCERT_CONTEXT cert, BCRYPT_KEY_HANDLE* key) { xmlSecAssert2(key != NULL, -1); if(!CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING, - &cert->pCertInfo->SubjectPublicKeyInfo, + &(cert->pCertInfo->SubjectPublicKeyInfo), 0, NULL, key)) { diff --git a/src/mscng/x509vfy.c b/src/mscng/x509vfy.c index 9d441df86..52a6d7738 100644 --- a/src/mscng/x509vfy.c +++ b/src/mscng/x509vfy.c @@ -448,38 +448,38 @@ static int xmlSecMSCngX509StoreContainsCert(HCERTSTORE store, CERT_NAME_BLOB* name, PCCERT_CONTEXT cert) { - PCCERT_CONTEXT issuerCert = NULL; + PCCERT_CONTEXT storeCert = NULL; int ret; xmlSecAssert2(store != NULL, -1); xmlSecAssert2(name != NULL, -1); xmlSecAssert2(cert != NULL, -1); - issuerCert = CertFindCertificateInStore(store, + storeCert = CertFindCertificateInStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, name, NULL); - if (issuerCert == NULL) { + if (storeCert == NULL) { return (0); } - ret = xmlSecMSCngX509StoreVerifySubject(cert, issuerCert); + ret = xmlSecMSCngX509StoreVerifySubject(cert, storeCert); if (ret < 0) { xmlSecInternalError("xmlSecMSCngX509StoreVerifySubject", NULL); - CertFreeCertificateContext(issuerCert); + CertFreeCertificateContext(storeCert); return(-1); } else if (ret == 0) { xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, NULL, "xmlSecMSCngX509StoreVerifySubject"); - CertFreeCertificateContext(issuerCert); + CertFreeCertificateContext(storeCert); return(-1); } /* success */ - CertFreeCertificateContext(issuerCert); + CertFreeCertificateContext(storeCert); return(1); } @@ -489,14 +489,14 @@ xmlSecMSCngVerifyCertTime(PCCERT_CONTEXT cert, LPFILETIME time) { xmlSecAssert2(cert->pCertInfo != NULL, -1); xmlSecAssert2(time != NULL, -1); - if(CompareFileTime(&cert->pCertInfo->NotBefore, time) == 1) { + if(CompareFileTime(&(cert->pCertInfo->NotBefore), time) == 1) { xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, NULL, "CompareFileTime"); return(-1); } - if(CompareFileTime(&cert->pCertInfo->NotAfter, time) == -1) { + if(CompareFileTime(&(cert->pCertInfo->NotAfter), time) == -1) { xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, NULL, "CompareFileTime"); @@ -529,6 +529,7 @@ xmlSecMSCngX509StoreVerifyCertificateOwn(PCCERT_CONTEXT cert, FILETIME* time, xmlSecAssert2(trustedStore != NULL, -1); xmlSecAssert2(certStore != NULL, -1); + /* check certificate validity and revokation */ ret = xmlSecMSCngVerifyCertTime(cert, time); if(ret < 0) { xmlSecInternalError("xmlSecMSCngVerifyCertTime", NULL); @@ -543,19 +544,18 @@ xmlSecMSCngX509StoreVerifyCertificateOwn(PCCERT_CONTEXT cert, FILETIME* time, /* does trustedStore contain cert directly? */ ret = xmlSecMSCngX509StoreContainsCert(trustedStore, - &cert->pCertInfo->Subject, cert); + &(cert->pCertInfo->Subject), cert); if(ret < 0) { xmlSecInternalError("xmlSecMSCngX509StoreContainsCert", NULL); return(-1); - } - if(ret == 1) { + } else if(ret == 1) { /* success */ return(1); } /* does trustedStore contain the issuer cert? */ ret = xmlSecMSCngX509StoreContainsCert(trustedStore, - &cert->pCertInfo->Issuer, cert); + &(cert->pCertInfo->Issuer), cert); if(ret < 0) { xmlSecInternalError("xmlSecMSCngX509StoreContainsCert", NULL); return(-1); @@ -566,8 +566,8 @@ xmlSecMSCngX509StoreVerifyCertificateOwn(PCCERT_CONTEXT cert, FILETIME* time, /* is cert self-signed? no recursion in that case */ if(CertCompareCertificateName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - &cert->pCertInfo->Subject, - &cert->pCertInfo->Issuer)) { + &(cert->pCertInfo->Subject), + &(cert->pCertInfo->Issuer))) { /* not verified */ return(0); } @@ -577,7 +577,7 @@ xmlSecMSCngX509StoreVerifyCertificateOwn(PCCERT_CONTEXT cert, FILETIME* time, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, - &cert->pCertInfo->Issuer, + &(cert->pCertInfo->Issuer), NULL); if(issuerCert != NULL) { ret = xmlSecMSCngX509StoreVerifySubject(cert, issuerCert); @@ -613,7 +613,7 @@ xmlSecMSCngX509StoreVerifyCertificateOwn(PCCERT_CONTEXT cert, FILETIME* time, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, - &cert->pCertInfo->Issuer, + &(cert->pCertInfo->Issuer), NULL); if(issuerCert != NULL) { ret = xmlSecMSCngX509StoreVerifySubject(cert, issuerCert); diff --git a/src/mscrypto/x509vfy.c b/src/mscrypto/x509vfy.c index c1dd95ac2..47cec4f45 100644 --- a/src/mscrypto/x509vfy.c +++ b/src/mscrypto/x509vfy.c @@ -352,6 +352,47 @@ xmlSecMSCryptoX509StoreVerifySubject(xmlSecKeyDataStorePtr store, PCCERT_CONTEXT return(1); } +static int +xmlSecMSCryptoX509StoreContainsCert(HCERTSTORE store, CERT_NAME_BLOB* name, + PCCERT_CONTEXT cert, xmlSecKeyDataStorePtr keyDataStore) +{ + PCCERT_CONTEXT storeCert = NULL; + int ret; + + xmlSecAssert2(store != NULL, -1); + xmlSecAssert2(name != NULL, -1); + xmlSecAssert2(cert != NULL, -1); + xmlSecAssert2(keyDataStore != NULL, -1); + + storeCert = CertFindCertificateInStore(store, + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + 0, + CERT_FIND_SUBJECT_NAME, + name, + NULL); + if (storeCert == NULL) { + return (0); + } + + ret = xmlSecMSCryptoX509StoreVerifySubject(keyDataStore, cert, storeCert); + if (ret < 0) { + xmlSecInternalError("xmlSecMSCryptoX509StoreVerifySubject", NULL); + CertFreeCertificateContext(storeCert); + return(-1); + } else if (ret == 0) { + xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, + NULL, + "xmlSecMSCryptoX509StoreVerifySubject"); + CertFreeCertificateContext(storeCert); + return(-1); + } + + /* success */ + CertFreeCertificateContext(storeCert); + return(1); +} + + /** * xmlSecMSCryptoBuildCertChainManually: * @cert: the certificate we check @@ -372,6 +413,7 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime, PCCERT_CONTEXT issuerCert = NULL; int ret; + /* check certificate validity and revokation */ if (!xmlSecMSCryptoVerifyCertTime(cert, pfTime)) { xmlSecOtherError(XMLSEC_ERRORS_R_CERT_HAS_EXPIRED, xmlSecKeyDataStoreGetName(store), @@ -386,33 +428,36 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime, return(FALSE); } - /* try to find issuer cert in the trusted cert in the store */ - issuerCert = CertFindCertificateInStore(store_trusted, - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - 0, - CERT_FIND_SUBJECT_NAME, - &(cert->pCertInfo->Issuer), - NULL); - if(issuerCert != NULL) { - ret = xmlSecMSCryptoX509StoreVerifySubject(store, cert, issuerCert); - if (ret < 0) { - xmlSecInternalError("xmlSecMSCryptoX509StoreVerifySubject", NULL); - CertFreeCertificateContext(issuerCert); - return(FALSE); - } - else if (ret == 0) { - xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, - NULL, - "xmlSecMSCryptoX509StoreVerifySubject"); - CertFreeCertificateContext(issuerCert); - return(FALSE); - } + /* does trustedStore contain cert directly? */ + ret = xmlSecMSCryptoX509StoreContainsCert(store_trusted, + &(cert->pCertInfo->Subject), cert, store); + if (ret < 0) { + xmlSecInternalError("xmlSecMSCryptoX509StoreContainsCert", NULL); + return(FALSE); + } else if (ret == 1) { + /* success */ + return(TRUE); + } + /* does trustedStore contain the issuer cert? */ + ret = xmlSecMSCryptoX509StoreContainsCert(store_trusted, + &(cert->pCertInfo->Issuer), cert, store); + if (ret < 0) { + xmlSecInternalError("xmlSecMSCryptoX509StoreContainsCert", NULL); + return(FALSE); + } else if (ret == 1) { /* success */ - CertFreeCertificateContext(issuerCert); return(TRUE); } + /* is cert self-signed? no recursion in that case */ + if (CertCompareCertificateName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + &(cert->pCertInfo->Subject), + &(cert->pCertInfo->Issuer))) { + /* not verified */ + return(FALSE); + } + /* try the untrusted certs in the chain */ issuerCert = CertFindCertificateInStore(certs, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, @@ -479,6 +524,7 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime, return(TRUE); } + /* no luck */ return(FALSE); } diff --git a/src/nss/x509.c b/src/nss/x509.c index ca01a484d..86d175f64 100644 --- a/src/nss/x509.c +++ b/src/nss/x509.c @@ -1396,7 +1396,7 @@ xmlSecNssX509CertDebugDump(CERTCertificate* cert, FILE* output) { fprintf(output, "==== Subject Name: %s\n", cert->subjectName); fprintf(output, "==== Issuer Name: %s\n", cert->issuerName); - sn = &cert->serialNumber; + sn = &(cert->serialNumber); for (i = 0; i < sn->len; i++) { if (i != sn->len - 1) { @@ -1426,7 +1426,7 @@ xmlSecNssX509CertDebugXmlDump(CERTCertificate* cert, FILE* output) { fprintf(output, "\n"); fprintf(output, ""); - sn = &cert->serialNumber; + sn = &(cert->serialNumber); for (i = 0; i < sn->len; i++) { if (i != sn->len - 1) { fprintf(output, "%02x:", sn->data[i]); diff --git a/tests/aleksey-xmldsig-01/enveloped-x509-same-subj-cert.tmpl b/tests/aleksey-xmldsig-01/enveloped-x509-same-subj-cert.tmpl new file mode 100644 index 000000000..915dd55c0 --- /dev/null +++ b/tests/aleksey-xmldsig-01/enveloped-x509-same-subj-cert.tmpl @@ -0,0 +1,31 @@ + + + + + Hello, World! + + + + + + + + + + not(ancestor-or-self::dsig:Signature) + + + + + + + + + + + + + + diff --git a/tests/aleksey-xmldsig-01/enveloped-x509-same-subj-cert.xml b/tests/aleksey-xmldsig-01/enveloped-x509-same-subj-cert.xml new file mode 100755 index 000000000..af56f9c52 --- /dev/null +++ b/tests/aleksey-xmldsig-01/enveloped-x509-same-subj-cert.xml @@ -0,0 +1,58 @@ + + + + + Hello, World! + + + + + + + + + + not(ancestor-or-self::dsig:Signature) + + + + SsyGDfQDqAg9cuEzSIJDsrp8cSWGzoRqH8E3atXJ4Dw= + + + C0FMZHYPwPzrnHDgjFTXp/ngsD+7/nunjwRRdStP8a39l6S3lJT74fDsRHbtDTrl +nmKFVvl1qt3EPr3mybxJ7ie65z2rb2DCPne4tqPAnrd1qORsWulgG1bG5QK7gxgL +Ma1ugm/W7eks0VVIYYvccz3XHnHMMui5PjjWuCmb+TP5ITKlX6BBJ5oUQH0BAkp0 +cJjiIB3QxQF6vSNWXdzIIcvjXa1VBdOjGf929DNJ/rLK8wyiUvNaWKUVFLnhkSLL +Nfqh34e5LO4OuiOqgtRHRG1jgOf17z7/yyUQiOhSmj7T3CN+QhCIO4txLisxtEoV +XSuveMZOIKZcENPRr56d/w== + + + MIID7zCCAtegAwIBAgIUIgqmR9n7YZ00FWk0uikgAPUdS8swDQYJKoZIhvcNAQEL +BQAwgYYxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcM +CENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFu +eVNlY3Rpb25OYW1lMR0wGwYDVQQDDBRDb21tb25OYW1lT3JIb3N0bmFtZTAeFw0y +NDA3MTgxNDI1NTdaFw0zNDA3MTYxNDI1NTdaMIGGMQswCQYDVQQGEwJYWDESMBAG +A1UECAwJU3RhdGVOYW1lMREwDwYDVQQHDAhDaXR5TmFtZTEUMBIGA1UECgwLQ29t +cGFueU5hbWUxGzAZBgNVBAsMEkNvbXBhbnlTZWN0aW9uTmFtZTEdMBsGA1UEAwwU +Q29tbW9uTmFtZU9ySG9zdG5hbWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDgszZxDsl1xmzYQb0kclEQ3NIRnnPhoBQJ69ibbpWrpAK+RBakCWkImPNe +1LBtZK9KvlCDrLd1u3paVBDXxqk5ewgD8khtpcek0C4V+G3ZnaMRXuOGcNdX/cTH +AW2gIScYGKFVtLaBQ+CSOvTQyBRWYRM/ydSr61yNhTINC6E3mV5ylee+yxkQzX++ +Iw+2rvnS12d3fkmiBSwNO2ROsYybYX1ba/xxSRbRJ7g4GTfCSGzaEltXZrv71CQO +5YWO9cg4D4E+levH4UgDv8Ag6oQ0fn1iNoHDCZJSv14tfUchfyP8TLOaWW2pRHMr +M8+t24OPLwHQLvp2OkAzvddfbtRjAgMBAAGjUzBRMB0GA1UdDgQWBBSw742X8NJq +E4AZliU1fqjJjIodKzAfBgNVHSMEGDAWgBSw742X8NJqE4AZliU1fqjJjIodKzAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQC8cU/fujwtbvPXUis3 ++8LU1HgP4g0fK9jcQtwik2rp5FkXzVf1isH10Htpl27l3DRA1Q2LgSYqFy1h6x7a +nOFe/bYfPGIvcDl/EcIP2uhZBmix/PGhk3DP8E4/aPfcRJ2jctSyoCmX2A++EWsn +d5wJv/VfiDOqIDI5dZYw6HxziKY6CR9ULAUqjCRWv38V5ZVWe+v4EbLDEN1R+hx7 ++0Qnp42ejCPvIgmT+l6rsvqVR/grQfg0nG/IwDqt8SBbgIJQqstJcG+OrH+shcKw +wtkkc4KFfSPyAwaV/1z43xgwLeYxgopUD5q9uAjQB6xWG5m/DSI0O6NbEtosw8af +N2Qf + + + + + diff --git a/tests/keys/README.md b/tests/keys/README.md index ac195ac51..47408beba 100644 --- a/tests/keys/README.md +++ b/tests/keys/README.md @@ -223,6 +223,20 @@ openssl verify -CAfile cacert.pem -untrusted ca2cert.pem dh1024-first-pubkey.crt rm dh1024-first-req.pem ``` + +### Generate two certs and keys with the same certificate +``` +openssl req -x509 -newkey rsa:2048 -keyout same-subj-key1.pem -out same-subj-cert1.pem -sha256 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=CommonNameOrHostname" +openssl req -x509 -newkey rsa:2048 -keyout same-subj-key2.pem -out same-subj-cert2.pem -sha256 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=CommonNameOrHostname" + +openssl x509 -in same-subj-cert1.pem -out same-subj-cert1.der --outform DER +openssl x509 -in same-subj-cert2.pem -out same-subj-cert2.der --outform DER + +openssl rsa -in same-subj-key1.pem -out same-subj-key1.der --outform DER +openssl rsa -in same-subj-key2.pem -out same-subj-key2.der --outform DER +``` + + ### Generate and sign GOST2001 and GOST2012 keys with second level CA To enable GOST support, modify openssl.conf file: - uncomment the `# gost = gost_section` line' diff --git a/tests/keys/same-subj-cert1.der b/tests/keys/same-subj-cert1.der new file mode 100644 index 0000000000000000000000000000000000000000..6af3c44f33ce2ccac6151946d9d79af6323e8d26 GIT binary patch literal 1011 zcmXqLVt#MX#B_ZDGZP~dlZX=6GWVOm6X%+UW}58MRABfj>wVgQmyJ`a&7!e(NRpXH1Spvc5%e$e$S*F* z16pDrC(dhRVqk7)VQ6AxYHA)O&T9YZ;V>ve*_o@^H3f#FQIIsBO0uj#FH)iKeUA=^9pNrTM&Pv2HqCawP&Rr}R_qeU#didWX#~E`MD5^_H zEDYVUtte6_d@fTaYa*~?>j9iaJGJ*GXJ)9KQCQR zFR$}l#Hzzk!3Kc_vcUM3YjQ?3!4VZxxa#8khb~nLsza; z@IT^}*S>Mb>5kImtd~zB#m|O+?K=4NLUrc!yr*|e9Iozog>n6UIyEW%w+}~~T zHc9#gmi2;%_;0<4WXst2=i|c31?NBb*=Kye<1%+~(UnaLG^gL--zS)@UOtC&|JV2q z<5dbqmZj4SUepwKEVJU257A-O>QM>XUoZM}YFPE_AA*|>3)~I-B~$&|MSXeiydLHE zN}Q8_#jW1-YpVMXZO0!bbMj9duv+_3A-bU{VAW~Qg8aTU^=n!WZ8&sOrMRiJR{0Y% v+tmLtKkiEy=sq)S>I&hXwRZ={1@<*z(lht-Dw$X>juyJ5bNJYN^Avdi!Bcn0 literal 0 HcmV?d00001 diff --git a/tests/keys/same-subj-cert1.pem b/tests/keys/same-subj-cert1.pem new file mode 100644 index 000000000..dfd173a65 --- /dev/null +++ b/tests/keys/same-subj-cert1.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIUIgqmR9n7YZ00FWk0uikgAPUdS8swDQYJKoZIhvcNAQEL +BQAwgYYxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcM +CENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFu +eVNlY3Rpb25OYW1lMR0wGwYDVQQDDBRDb21tb25OYW1lT3JIb3N0bmFtZTAeFw0y +NDA3MTgxNDI1NTdaFw0zNDA3MTYxNDI1NTdaMIGGMQswCQYDVQQGEwJYWDESMBAG +A1UECAwJU3RhdGVOYW1lMREwDwYDVQQHDAhDaXR5TmFtZTEUMBIGA1UECgwLQ29t +cGFueU5hbWUxGzAZBgNVBAsMEkNvbXBhbnlTZWN0aW9uTmFtZTEdMBsGA1UEAwwU +Q29tbW9uTmFtZU9ySG9zdG5hbWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDgszZxDsl1xmzYQb0kclEQ3NIRnnPhoBQJ69ibbpWrpAK+RBakCWkImPNe +1LBtZK9KvlCDrLd1u3paVBDXxqk5ewgD8khtpcek0C4V+G3ZnaMRXuOGcNdX/cTH +AW2gIScYGKFVtLaBQ+CSOvTQyBRWYRM/ydSr61yNhTINC6E3mV5ylee+yxkQzX++ +Iw+2rvnS12d3fkmiBSwNO2ROsYybYX1ba/xxSRbRJ7g4GTfCSGzaEltXZrv71CQO +5YWO9cg4D4E+levH4UgDv8Ag6oQ0fn1iNoHDCZJSv14tfUchfyP8TLOaWW2pRHMr +M8+t24OPLwHQLvp2OkAzvddfbtRjAgMBAAGjUzBRMB0GA1UdDgQWBBSw742X8NJq +E4AZliU1fqjJjIodKzAfBgNVHSMEGDAWgBSw742X8NJqE4AZliU1fqjJjIodKzAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQC8cU/fujwtbvPXUis3 ++8LU1HgP4g0fK9jcQtwik2rp5FkXzVf1isH10Htpl27l3DRA1Q2LgSYqFy1h6x7a +nOFe/bYfPGIvcDl/EcIP2uhZBmix/PGhk3DP8E4/aPfcRJ2jctSyoCmX2A++EWsn +d5wJv/VfiDOqIDI5dZYw6HxziKY6CR9ULAUqjCRWv38V5ZVWe+v4EbLDEN1R+hx7 ++0Qnp42ejCPvIgmT+l6rsvqVR/grQfg0nG/IwDqt8SBbgIJQqstJcG+OrH+shcKw +wtkkc4KFfSPyAwaV/1z43xgwLeYxgopUD5q9uAjQB6xWG5m/DSI0O6NbEtosw8af +N2Qf +-----END CERTIFICATE----- diff --git a/tests/keys/same-subj-cert2.der b/tests/keys/same-subj-cert2.der new file mode 100644 index 0000000000000000000000000000000000000000..fc226e25029f8d3025606b00be34169b166970c5 GIT binary patch literal 1011 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 REM -SET XMLSEC_CRYPTO=mscrypto +SET XMLSEC_CRYPTO=mscng SET PREFIX=C:\local\distro SET LIBXML2_PREFIX=%PREFIX%\libxml2 From ebe2f7ebe65d1d29eb2db7bd7f4eb8021a2c2a9a Mon Sep 17 00:00:00 2001 From: Aleksey Sanin Date: Thu, 18 Jul 2024 12:33:52 -0400 Subject: [PATCH 4/5] Remove additional test for now --- tests/testDSig.sh | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/testDSig.sh b/tests/testDSig.sh index 00b8cd5c0..6b39f4ea7 100755 --- a/tests/testDSig.sh +++ b/tests/testDSig.sh @@ -1204,16 +1204,6 @@ execDSigTest $res_success \ "x509" \ "--untrusted-$cert_format $topfolder/keys/ca2cert.$cert_format --trusted-$cert_format $topfolder/keys/cacert.$cert_format --enabled-key-data x509" -# this should succeeed with intermidiate cert as trusted -extra_message="Cert chain is good: intermidiate cert as trusted" -execDSigTest $res_success \ - "" \ - "aleksey-xmldsig-01/enveloped-x509-missing-cert" \ - "sha256 rsa-sha256" \ - "x509" \ - "--trusted-$cert_format $topfolder/keys/ca2cert.$cert_format --enabled-key-data x509" - - # this should succeeed too because we bypass all cert checks with --insecure mode extra_message="Cert chain is missing but there is --insecure bypass" execDSigTest $res_success \ From cfab4d6a06a547de03e8c92f10c3d3b43788ef5c Mon Sep 17 00:00:00 2001 From: Aleksey Sanin Date: Thu, 18 Jul 2024 13:14:29 -0400 Subject: [PATCH 5/5] (xmlsec-mscng,xmlsec-mscrypto) Improved certificates verification. --- .github/workflows/make-check.yml | 4 ++-- config.h.in | 0 docs/index.html | 1 + src/gnutls/private.h | 1 + src/gnutls/x509utils.c | 11 +++++++++++ src/gnutls/x509vfy.c | 27 ++++++++++++++++++--------- 6 files changed, 33 insertions(+), 11 deletions(-) mode change 100755 => 100644 config.h.in diff --git a/.github/workflows/make-check.yml b/.github/workflows/make-check.yml index 01aa7ad9b..97699b89d 100755 --- a/.github/workflows/make-check.yml +++ b/.github/workflows/make-check.yml @@ -11,7 +11,7 @@ on: - xmlsec-1_2_x jobs: - check-ubuntu-openssl300: + check-ubuntu: runs-on: ubuntu-22.04 strategy: fail-fast: false @@ -48,7 +48,7 @@ jobs: run: | make install - check-ubuntu-openssl111: + check-ubuntu-openssl-111: runs-on: ubuntu-20.04 strategy: fail-fast: false diff --git a/config.h.in b/config.h.in old mode 100755 new mode 100644 diff --git a/docs/index.html b/docs/index.html index 0c76d2e40..ec225c025 100644 --- a/docs/index.html +++ b/docs/index.html @@ -73,6 +73,7 @@

XML Security Library


  • (xmlsec-mscng,xmlsec-mscrypto) Improved certificates verification.
  • +
  • (xmlsec-gnutls) Added support for self-signed certificates.
  • (xmlsec-core) Fix deprecated functions in LibXML2 2.13.1 including disabling HTTP support by default (use ''--enable-http' option to re-enable it).
  • Several other small fixes (see more details).
  • diff --git a/src/gnutls/private.h b/src/gnutls/private.h index 1b7e95598..26c106cf4 100644 --- a/src/gnutls/private.h +++ b/src/gnutls/private.h @@ -66,6 +66,7 @@ xmlSecPtrListPtr xmlSecGnuTLSKeyDataX509GetCrls (xmlSecKeyDataPt * ************************************************************************/ gnutls_x509_crt_t xmlSecGnuTLSX509CertDup (gnutls_x509_crt_t src); +int xmlSecGnuTLSX509CertIsSelfSigned (gnutls_x509_crt_t cert); xmlChar * xmlSecGnuTLSX509CertGetSubjectDN (gnutls_x509_crt_t cert); xmlChar * xmlSecGnuTLSX509CertGetIssuerDN (gnutls_x509_crt_t cert); xmlChar * xmlSecGnuTLSX509CertGetIssuerSerial (gnutls_x509_crt_t cert); diff --git a/src/gnutls/x509utils.c b/src/gnutls/x509utils.c index 3e770fa7d..d590472d1 100644 --- a/src/gnutls/x509utils.c +++ b/src/gnutls/x509utils.c @@ -197,6 +197,17 @@ xmlSecGnuTLSX509CertDup(gnutls_x509_crt_t src) { return (res); } + +/* returns 1 if self signed; 0 - if not; <0 on error*/ +int +xmlSecGnuTLSX509CertIsSelfSigned(gnutls_x509_crt_t cert) { + unsigned ret; + + xmlSecAssert2(cert != NULL, -1); + ret = gnutls_x509_crt_check_issuer(cert, cert); + return ((ret != 0) ? 1 : 0); +} + xmlChar * xmlSecGnuTLSX509CertGetSubjectDN(gnutls_x509_crt_t cert) { char* buf = NULL; diff --git a/src/gnutls/x509vfy.c b/src/gnutls/x509vfy.c index 7bfd63853..171795fc2 100644 --- a/src/gnutls/x509vfy.c +++ b/src/gnutls/x509vfy.c @@ -655,18 +655,27 @@ xmlSecGnuTLSX509StoreVerify(xmlSecKeyDataStorePtr store, goto done; } - /* check if we are the "leaf" node in the certs chain */ - if(xmlSecGnuTLSX509FindSignedCert(certs, cert) != NULL) { + if(xmlSecGnuTLSX509CertIsSelfSigned(cert) != 1) { + /* check if we are the "leaf" node in the certs chain */ + if(xmlSecGnuTLSX509FindSignedCert(certs, cert) != NULL) { + continue; + } + + /* build the chain */ + ret = xmlSecGnuTLSX509StoreGetCertsChain(ctx, cert, certs, certs_chain, certs_chain_size, &certs_chain_cur_size); + if(ret < 0) { + xmlSecInternalError("xmlSecPtrListGetItem(certs)", xmlSecKeyDataStoreGetName(store)); + goto done; + } + } else if (certs_size == 1) { + /* only do self signed cert when it is the only cert */ + /* chain for self signed cert is easy */ + certs_chain[0] = cert; + certs_chain_cur_size = 1; + } else { continue; } - /* build the chain */ - ret = xmlSecGnuTLSX509StoreGetCertsChain(ctx, cert, certs, certs_chain, certs_chain_size, &certs_chain_cur_size); - if(ret < 0) { - xmlSecInternalError("xmlSecPtrListGetItem(certs)", xmlSecKeyDataStoreGetName(store)); - goto done; - } - /* try to verify */ ret = xmlSecGnuTLSX509StoreVerifyCert(ctx, certs_chain, certs_chain_cur_size,