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 d77ef40a3..ec225c025 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -72,8 +72,9 @@
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-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,
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 288e164ef..52a6d7738 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
@@ -412,37 +448,39 @@ static int
xmlSecMSCngX509StoreContainsCert(HCERTSTORE store, CERT_NAME_BLOB* name,
PCCERT_CONTEXT cert)
{
- PCCERT_CONTEXT issuerCert = NULL;
- DWORD flags;
+ 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) {
- 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);
- }
- CertFreeCertificateContext(issuerCert);
- return(1);
+ if (storeCert == NULL) {
+ return (0);
}
- return(0);
+ ret = xmlSecMSCngX509StoreVerifySubject(cert, storeCert);
+ if (ret < 0) {
+ xmlSecInternalError("xmlSecMSCngX509StoreVerifySubject", NULL);
+ CertFreeCertificateContext(storeCert);
+ return(-1);
+ } else if (ret == 0) {
+ xmlSecOtherError(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED,
+ NULL,
+ "xmlSecMSCngX509StoreVerifySubject");
+ CertFreeCertificateContext(storeCert);
+ return(-1);
+ }
+
+ /* success */
+ CertFreeCertificateContext(storeCert);
+ return(1);
}
static int
@@ -451,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");
@@ -485,13 +523,13 @@ xmlSecMSCngX509StoreVerifyCertificateOwn(PCCERT_CONTEXT cert, FILETIME* time,
HCERTSTORE trustedStore, HCERTSTORE untrustedStore, HCERTSTORE certStore
) {
PCCERT_CONTEXT issuerCert = NULL;
- DWORD flags;
int ret;
xmlSecAssert2(cert != NULL, -1);
xmlSecAssert2(trustedStore != NULL, -1);
xmlSecAssert2(certStore != NULL, -1);
+ /* check certificate validity and revokation */
ret = xmlSecMSCngVerifyCertTime(cert, time);
if(ret < 0) {
xmlSecInternalError("xmlSecMSCngVerifyCertTime", NULL);
@@ -506,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);
@@ -529,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);
}
@@ -540,14 +577,19 @@ 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) {
- 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);
}
@@ -571,14 +613,19 @@ 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) {
- 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/src/mscrypto/x509vfy.c b/src/mscrypto/x509vfy.c
index 450ba1932..47cec4f45 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,87 @@ 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);
+}
+
+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
@@ -377,57 +411,51 @@ xmlSecMSCryptoBuildCertChainManually (PCCERT_CONTEXT cert, LPFILETIME pfTime,
HCERTSTORE store_trusted, HCERTSTORE store_untrusted, HCERTSTORE certs,
xmlSecKeyDataStorePtr store) {
PCCERT_CONTEXT issuerCert = NULL;
- DWORD flags;
+ int ret;
+ /* check certificate validity and revokation */
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)) {
+ xmlSecOtherError(XMLSEC_ERRORS_R_CRL_VERIFY_FAILED,
+ xmlSecKeyDataStoreGetName(store),
+ "certificate revoked");;
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 ) ;
+ /* 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);
}
- /* Check whether the certificate is self signed certificate */
- if(CertCompareCertificateName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &(cert->pCertInfo->Subject), &(cert->pCertInfo->Issuer))) {
+ /* 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 */
+ return(TRUE);
}
- /* 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) {
- flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG;
- if(!CertVerifySubjectCertificateContext(cert, issuerCert, &flags)) {
- xmlSecMSCryptoX509StoreCertError(store, issuerCert, flags);
- CertFreeCertificateContext(issuerCert);
- return(FALSE);
- }
- /* todo: do we want to verify the trusted cert? we must check
- * revocation, I think */
- 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 */
@@ -438,17 +466,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)) {
- xmlSecMSCryptoX509StoreCertError(store, issuerCert, flags);
+
+ if (!xmlSecMSCryptoBuildCertChainManually(issuerCert, pfTime, store_trusted, store_untrusted, certs, store)) {
+ xmlSecInternalError("xmlSecMSCryptoBuildCertChainManually", NULL);
CertFreeCertificateContext(issuerCert);
return(FALSE);
}
+
+ /* success */
CertFreeCertificateContext(issuerCert);
return(TRUE);
}
@@ -461,20 +499,32 @@ 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)) {
+ 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);
}
+ /* 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 000000000..6af3c44f3
Binary files /dev/null and b/tests/keys/same-subj-cert1.der differ
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 000000000..fc226e250
Binary files /dev/null and b/tests/keys/same-subj-cert2.der differ
diff --git a/tests/keys/same-subj-cert2.pem b/tests/keys/same-subj-cert2.pem
new file mode 100644
index 000000000..83508649d
--- /dev/null
+++ b/tests/keys/same-subj-cert2.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID7zCCAtegAwIBAgIUEeFP1v2WpPij1E1749hqonA6zJQwDQYJKoZIhvcNAQEL
+BQAwgYYxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcM
+CENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFu
+eVNlY3Rpb25OYW1lMR0wGwYDVQQDDBRDb21tb25OYW1lT3JIb3N0bmFtZTAeFw0y
+NDA3MTgxNDI2MDFaFw0zNDA3MTYxNDI2MDFaMIGGMQswCQYDVQQGEwJYWDESMBAG
+A1UECAwJU3RhdGVOYW1lMREwDwYDVQQHDAhDaXR5TmFtZTEUMBIGA1UECgwLQ29t
+cGFueU5hbWUxGzAZBgNVBAsMEkNvbXBhbnlTZWN0aW9uTmFtZTEdMBsGA1UEAwwU
+Q29tbW9uTmFtZU9ySG9zdG5hbWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQCzDd5kS6vukx2HaTumA4fW+1ZSM0MJtqk8BNWcmc58+XPIXasUEYm5txwQ
++ZK0DYLPgCp7arumIpUqfbl8/60BKhaKeRQfQj0IQ8w64s8rfIk23EW6iYkO70jN
+WJTRMQ25x6ty+XnTYWuqipNkuiwneto60E8gOUPR6cieV96uoVYU04a99aWGIRTR
+jh0nRsOmF8VMNws/wlnYbxxHDlW71hKCNaJE4DCctOu7UOD3t1cR3nLB1O3ZuzpG
+Dw4NvRE0T8VHMUm3CpU6KYKMGTQ9WIzK5Pk+VQfAbznBwdeTO2l+NPnJ7W5hcLaT
+GwU+tJXHxeKlQ/9CczuAc9D3TzdxAgMBAAGjUzBRMB0GA1UdDgQWBBTpuTGsFM+z
+TQcOUOQycJk+M44NvTAfBgNVHSMEGDAWgBTpuTGsFM+zTQcOUOQycJk+M44NvTAP
+BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCxINay68oUjhE+bEt6
+igVijvSWxzw+XlRhBmEZ3Si2lHL/jg3zVJddYTXTps4o95b7gEEGKxhZ6QFGBaY8
+qWYHKHTs/izKxj2CMrpB7lE9lcG/gMxECWlFeu55R2d+lMnFjDT9I8sAvK/eaNHH
+3niDcxueyy6Cak1biXesHSwSYoBxdHcToizwnMfGviA2SfjygO4ObHjmoMT0VynB
+dkv+QvzArnydiF5sMuELHg8RsARJlnOYZVOe7lZ5hyt8YAhV3tCKf6txcSWAdP8l
+Y1ltG8YI+IriNm8mEUv/Q+fCuM8VuhNuPezrsI6NkTEVKhFeuXS+8oX6Qn6EVWbS
+rTzp
+-----END CERTIFICATE-----
diff --git a/tests/keys/same-subj-key1.der b/tests/keys/same-subj-key1.der
new file mode 100644
index 000000000..690628382
Binary files /dev/null and b/tests/keys/same-subj-key1.der differ
diff --git a/tests/keys/same-subj-key1.pem b/tests/keys/same-subj-key1.pem
new file mode 100644
index 000000000..ba6bbda71
--- /dev/null
+++ b/tests/keys/same-subj-key1.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDgszZxDsl1xmzY
+Qb0kclEQ3NIRnnPhoBQJ69ibbpWrpAK+RBakCWkImPNe1LBtZK9KvlCDrLd1u3pa
+VBDXxqk5ewgD8khtpcek0C4V+G3ZnaMRXuOGcNdX/cTHAW2gIScYGKFVtLaBQ+CS
+OvTQyBRWYRM/ydSr61yNhTINC6E3mV5ylee+yxkQzX++Iw+2rvnS12d3fkmiBSwN
+O2ROsYybYX1ba/xxSRbRJ7g4GTfCSGzaEltXZrv71CQO5YWO9cg4D4E+levH4UgD
+v8Ag6oQ0fn1iNoHDCZJSv14tfUchfyP8TLOaWW2pRHMrM8+t24OPLwHQLvp2OkAz
+vddfbtRjAgMBAAECggEAInAfwkN46Z29ZYZAczXjah6Il6izAVE5IQLOPOw9m4PU
+jnf9sasQ4lTGyrGgT0kk0I4gkD3IFGQ6brOprS3Ga90zr58ng0lAMuixLNmEGdve
+IosU0LBkthivsFcYsnfCTSAhQfMjcZEHTyzNWV5WN52Yh1NApA9mLPkitaXNp1Pc
+U1TLXRTkXCb9CgO1U8i5ypm9cgnvwXC9sN43ACzwVJ8TPpcMzpfa2oG417rirGyn
+O11gcH/2rC6KZEKXfTMfcE9Hu+alxM+NiPDACKMcFpJZUayfX4mPzw44do+tsGDy
+ZsQ/tJuwI33agsewgQ3aPl6gGNmKBqsoQG9fstUZ2QKBgQD2w5Xu6cziHnbYbPyV
+7GlSmFdep/2tBe2wTrZT+pKri8skr0zhiP+tXw/FzpLH6P1vn2j7543rCECrWnR+
+g2Vgs1Uf/QYxmt9rq86H+x6VA99S4HKSJe4HN1+ybsu/OZlrOsu0km1Wfn/c+XLh
+FVz2caQp7BcRkErhtqkddORyrQKBgQDpHDeXqWUt7FCOq8WDs1UZxpsMqivSXFg1
+YnI07S4dsE53ysIENSFVvlYEECy0MEWRt0toPdbzhm9tP9A6Vr5gCi07U6obMXNn
+r3dDwFifAebDB3AOmhFbVBtnSKsETnU17gwO6+bn9eZJ+Ngz8aFb4JkHFt1CQkLk
+XYDsdcxVTwKBgQDnZOqg2Y7tbuHE+xY0RDdTY1Vyhpcje46yqGzi/PIyeOkqYlP2
+nbAb1CuHMrmDSqD03gflR/JVtixmQnFA/VfAQQoO8Aax12ewoLAP5VR9Kd9t6Nim
+4Xh+Pde4C5t1mr6Zxc2lazWqSP7/qM6n8I927YOiaCgNqT/+vnmBDM74FQKBgQDB
+9nOfYxjITGB/RhgTzK0bxHCQ6iuKXsIasW578Xo0w9WWwYQMQjUZhkVGHjtENwI8
+C/rXotTvTsX6bmWRlUnU2cLnIWdiNxRiitK+8hYLQGbFkrO/wpx8lJA0sXdzHuFS
+XV91Lv6ztZzHoiIrnnt32nsaNgEmt8G3CMJUfnPl6wKBgGp+qG/jRqKXVNn016F0
+wx/5Zz4YfEKh3g2tONejqW5OJjp0SghzqqMhk2kswbKrQEmrFzMfeUYxImnlOUOM
+16ypcxzYcCnTJYRb012/I+Np91bvw/Hk2AVj3i6l90eKqElwEGSur3lLDhiIPQKC
+YL51LWk536Mf+LsfQ52kkF41
+-----END PRIVATE KEY-----
diff --git a/tests/keys/same-subj-key2.der b/tests/keys/same-subj-key2.der
new file mode 100644
index 000000000..7e8710893
Binary files /dev/null and b/tests/keys/same-subj-key2.der differ
diff --git a/tests/keys/same-subj-key2.pem b/tests/keys/same-subj-key2.pem
new file mode 100644
index 000000000..120a8fb4c
--- /dev/null
+++ b/tests/keys/same-subj-key2.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzDd5kS6vukx2H
+aTumA4fW+1ZSM0MJtqk8BNWcmc58+XPIXasUEYm5txwQ+ZK0DYLPgCp7arumIpUq
+fbl8/60BKhaKeRQfQj0IQ8w64s8rfIk23EW6iYkO70jNWJTRMQ25x6ty+XnTYWuq
+ipNkuiwneto60E8gOUPR6cieV96uoVYU04a99aWGIRTRjh0nRsOmF8VMNws/wlnY
+bxxHDlW71hKCNaJE4DCctOu7UOD3t1cR3nLB1O3ZuzpGDw4NvRE0T8VHMUm3CpU6
+KYKMGTQ9WIzK5Pk+VQfAbznBwdeTO2l+NPnJ7W5hcLaTGwU+tJXHxeKlQ/9CczuA
+c9D3TzdxAgMBAAECggEABz+l28tU8uf1g3J7CdPdg1JiOpps6bchd4auE6SF35kV
+KvzAxOOXXuN28Uh7PAsKe0ZB4gRug5GlloZntJPgr/oBVtqDOic7M4sUGOOu9aCZ
+aPVGpOA1wlslSDvgbW4WE0nuKs3G9OveGRW6VRL03+XJMSWW+HPdByHW33Mo9oqL
+2JqPM3II5MAMH/NELFfIB743u9Ssr5EvL0g5lFyOqt3ROX+n93ibaotmtl3mGHSh
+PSbWC/fMPxE4IVPgZFbUZcHGMbaqt9j4oNMkaD2AyLrLAJCJe/zrU4Wn1b4HVEVE
+qcjfOpNuF760MXlpI7hgQpFFMzAcYn9aaQGXOLLAwQKBgQDrn8xNdg7MJizHCosP
+GmbNIusC8cJxIVWaZH41iBP5ABfWOOq7BkVSwjiGEM4zzVwXU+E9vwqDe/c8cjPN
+qA1DwqoGiSis7Fqa88TthUy6jFW/OWVwLYsMEHciX18sUDSK8qXdM9vltrUL+NG1
+z51W3xSM9S4cuGGJbu6P+WRhYQKBgQDCibwEP0FWCVkix34qCK6Sgp7Gw1lUd0fN
+2F8njghEHJWXpNZAEDjqgM3Vgh5g89FewrjQDZONZKG7ByDPy/TwWlcx5Gn0DbGJ
+LyxLRXQZqVUihHTIvAgnFuO1ploGt6+WpJhDzWb4tgrCC2xDzmvhpQ/3MSWkV1EJ
+wVZWeBzAEQKBgAQYU+GowpsTssWGzmHl0JGSIMl9UCbNMIKtanAdvFMgiEmF1baI
+Zl4I2BikZCEMWaRiJdD/5/vfBK39Qh8543khAfl5GsbemLiGsg56uZmoZLkdE0E+
+2WLNSnTDeZD4l+EuVGmixBia80yQ93wUbqSa3e2ROUrwfWl5DxZbfD4hAoGAZ1jE
+iX0ROKO+trtESxBRrYO21eDxk+3KN5C6/Eh4G7cTwXvQVjhIBExpDQQTH25ny++m
+PuD3giXzxWgEBmBTv1w+9kJiB0U/C6ID5fj/tKJAmBXF9N3vdtSyI848BVWP8nd+
+bIayLW6ISI3I9jyzEyydTrTNSoEYjBYpx8YHgAECgYEAoZ3GaF91LkEkY77OTS6B
+qphuPGrQMq0QPr6cUUySHa0EcxMaWsyuaJjHJClPwJt5SgicH3YOIejRJbJPpcwG
+7ZMxMDrGJ0yecs/2udGAo76V+dRf2plJXd4nzYLuDFFFx748WGHwX/4mvN1w5Qwl
+qxQHcdcuuwrltU0MtUGOug8=
+-----END PRIVATE KEY-----
diff --git a/tests/testDSig.sh b/tests/testDSig.sh
index f76fe0983..6b39f4ea7 100755
--- a/tests/testDSig.sh
+++ b/tests/testDSig.sh
@@ -1168,12 +1168,35 @@ execDSigTest $res_success \
"rsa x509" \
"--enabled-key-data x509 --insecure"
+
+
+# Test was created using the following command:
+# xmlsec.exe sign --crypto openssl --lax-key-search --privkey-pem tests/keys/same-subj-key1.pem,tests/keys/same-subj-cert1.pem tests/aleksey-xmldsig-01/enveloped-x509-same-subj-cert.tmpl
+# this should succeeed with both intermidiate and trusted certs provided
+extra_message="Cert chaing is good"
+execDSigTest $res_success \
+ "" \
+ "aleksey-xmldsig-01/enveloped-x509-same-subj-cert" \
+ "sha256 rsa-sha256" \
+ "x509" \
+ "--trusted-$cert_format $topfolder/keys/same-subj-cert1.$cert_format --enabled-key-data x509"
+
+# this should fail: missing intermidiate cert (ca2cert)
+extra_message="Negative test: Same subject but wrong cert"
+execDSigTest $res_fail \
+ "" \
+ "aleksey-xmldsig-01/enveloped-x509-same-subj-cert" \
+ "sha256 rsa-sha256" \
+ "x509" \
+ "--trusted-$cert_format $topfolder/keys/same-subj-cert2.$cert_format --enabled-key-data x509"
+
+
# Test was created using the following command:
# xmlsec1 sign --lax-key-search --privkey-pem tests/keys/rsakey.pem,tests/keys/rsacert.pem tests/aleksey-xmldsig-01/enveloped-x509-missing-cert.tmpl
#
# this should succeeed with both intermidiate and trusted certs provided
-extra_message="Cert chaing is good"
+extra_message="Cert chain is good: both intermidiate and trusted certs provided"
execDSigTest $res_success \
"" \
"aleksey-xmldsig-01/enveloped-x509-missing-cert" \
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