Trusted-certs folder not being taken into account where System folders are read
Open, NormalPublic

Description

Hi,

When using release 2.2.7, I have found that if a certificate exists in the system certificates configuration under Windows, dirmngr ignores the same certificate if it is present in trusted-certificates folder. The impact of this is when using fetch-crl of dirmngr, if the chain being imported requires a trust relationship between the certificates, it does not created this trust and is unable to import the full crl chain i.e. the trust that should be created from using the trusted-certificates folder is not set.

I notice there is a parameter in the code for --systrust however, this does not seem to be exposed for dirmngr to control it. From the code, this appears to support a mask which controls the trust relationship of system certificates, trusted-certificates and how the CRL processing handles these.

How can I access this parameter on windows?
Is there an exposed parameter on windows that allows me to say trust all read in certificates so that I can work around this issue?

Regards,

Details

Version
2.2.7
werner triaged this task as Normal priority.Jun 6 2018, 5:56 PM
werner added a subscriber: werner.

I do not fully understand your problem. Can you please explain it with an example and also state the full file names of the mentioned folders?

Hi Werner,
The issue is the following:
I have 2 certificates in the trusted-certificates folder that is searched by gpgsm (C:\ProgramData\Gnu\etc\gnupg\trusted-certs) which I want to trust. When dirmngr starts, it reads the Windows trusted certifcate store (certlm.msc for both system and user - I don't know the path / location of the windows certificates folder outside certlm) and builds the list of certificates to use. Once this list is read and if any duplicates are found in the trusted-certificate folder, it ignores them - they are already present.

From looking at the code however, there appears to be a different mask applied to the trust when it comes from the certlm list against the trusted-certificates list. When gpgsm calls dirmngr to import a CRL list, it uses the mask to know how to trust a certificate or not and reports that while the CA for my CRLs is known (read from certlm.msc) it is not trusted. This causes the flow to fail and the expected CRL to not be imported.

So for an example:

I have certificate A in my trusted-certificates folder.
This certificate has also been deployed to certlm via a group policy
From cert_cache_init (line 702, certcache.c), the following flow arises

  • Dirmngr checks for certificates, it imports certificate A with a mask saying System Certificate (CERTTRUST_CLASS_SYSTEM, line 620 - load_certs_from_w32_store, certcache.c)
  • Dirmngr then loads certificates from trusted-certs (line 716, load_certs_from_dir, certcache.c). At this point if the certificate is already present, it never adds it with the CERTTRUST_CLASS_CONFIG flag.
  • In validate.c, validate_cert_chain calls is_trusted_cert:567 which is passing in a VALIDATE_FLAG_MASK_TRUST (set as 0xf from validate.h) but server.c passes in an OR with 0. From the logic, this should work but for some reason when is_trusted_cert is called, the trustclasses do not align as expected and this appears to be caused by the difference of the certificate being set CERTTRUST_CLASS_SYSTEM against CERTTRUST_CLASS_CONFIG.

To test this issue, I have removed the at issue certificates from the certlm.msc stores of system and user but left them in the trusted-certs folder. As the only change this should introduce is the change in flow of load_certs_from_dir (line 422) this leads me to believe something is wrong with the TRUST flag that is used.

For the flow, if a certificate already exists, can the mask / flag for that certificate be updated to include that it is trusted by many sources e.g. in certcache.c, load_certs_from_dir, can the put_cert operation add / mask in the additional trust that may be present as the certificate is in multiple locations - the operation at line 348 added / also performed at 322?

If you need more information let me know.

Thank you,

Hi Werner,
I have performed some experiments on the issue I have and the following are the results:

System Store (/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem)Trusted-Cert Store (/etc/gnupg/trusted-certs)fetch-crl result?
As IsRoot CertificateIssuing CAFail - not trusted root certificate is not marked trusted
No local store usage i.e. dirmngr/certcache.c: 712 commented out - load_certs_from_system ();Root CertificateIssuing CAroot certificate is good and trusted
Local store read last ie. dirmngr/certcache.c:712 moved to 729 load_certs_from_system (); moved to after load_certs_from_file (fname, CERTTRUST_CLASS_HKPSPOOL, 1);Root CertificateIssuing CAroot certificate is good and trusted
Function Put_Cert (dirmngr/certcache.c: 266) function updated to mask in the trustclass where the certificate is a duplicate: return gpg_error (GPG_ERR_DUP_VALUE); changed to: { ci->trustclasses = ci->trustclasses | trustclass; return gpg_error (GPG_ERR_DUP_VALUE); }Root CertificateIssuing CAroot certificate is good and trusted

From the above, either of the last 3 options give me the expected operations when I look to import the CRLs so that I can then use them correctly within my applications and work flow. I have not checked in relation to the security or otherwise of my updates, I have only checked that they work for me. It is possible a different solution exists but to date I have not looked for one / looked at the masking that is performed by other flows within dirmngr code that are preventing the system from working correctly for me.

Regards and thank you,

Hi,
Can I ask if there is any update on the issue that I face?

Regards,