A huge problem - winhttpcertcfg performs only a partial match of the certificate subject name and selects the first one. RRS feed

  • Question

  • Dear ladies and sirs.

    I need a non interactive procedure to grant the IIS worker process account access to the machine certificate. For that, I am utilizing the following command line:

    <tt>winhttpcertcfg -g -a <account_name> -c LOCAL_MACHINE\My -s <certificate_name></tt>

    The problem is, that winhttpcertcfg performs only a partial match of the certificate subject name and selects the first one. It so happens, that the relevant store contains another certificate, which subject name contains the name of my certificate and it was placed there by VMWare, so I guess it is there for a reason.

    Anyway, as a result of this behavior the wrong certificate is selected, which is a huge problem for me.

    Can anyone show me the correct non interactive procedure to achieve the same goal?

    Thanks a lot in advance.

    Thursday, January 20, 2011 7:30 AM


All replies

  • Anyone?
    Monday, January 24, 2011 9:17 AM
  • Is this external page or one of Saurabh Singh's MSDN blog pages of any help? (Possibly only relevant to Windows 2008.)

    Answering policy: see profile.
    Monday, January 24, 2011 5:29 PM
  • Thanks for replying. Unfortunately, both pages are irrelevant, because the only non interactive way to grant the permissions that is mentioned there is the one I am already using - winhttpcertcfg, which suffers from the problem described in my question - it only does a partial match of the subject name.


    What would help me is either of the following (in the order of preference):

    1. Make winhttpcertcfg somehow find exactly what I need (any non documented command line switches or something)
    2. Another command line utility (VB script) to achieve the same goal.
    3. COM API to achieve the same goal, so that one can write a VB script to do the job.
    4. Unmanaged API

    Of course, the less work I have to do the better the solution (naturally :-)).


    Wednesday, January 26, 2011 10:52 AM
  • certutil -repairstore on Windows 2008 R2 has the capability to update the security descriptor of a key. I guess you are using Windows 2003. Maybe certutil -repairstore has the same functionality on Windows 2003?

    Here is the help for certutil on my system:

      CertUtil [Options] -repairstore CertificateStoreName CertIdList [PropertyInfFile | SDDLSecurityDescriptor]
      Repair key association or update certificate properties or key security descriptor


    Friday, January 28, 2011 6:17 PM
  • Hi.

    Thanks for the reply.

    Can you provide an exact command line using certutil to achieve the same thing that running the following line achieves:

    winhttpcertcfg -g -a "NETWORK SERVICE" -c LOCAL_MACHINE\My -s il-mark-lap

    The SDDL for the NETWORK SERVICE is relatively easy, but how given the exact subject name can I get the CertIdList, all in command line and non interactively?

    BTW, what if instead of NETWORK SERVICE a dedicated user is used? How can I translate its user name into the respective SDDL, again on command line non interactively?


    Thursday, February 3, 2011 9:20 AM
  • You have several questions... Before I give detailed answers to each one, let's find out if your OS even has this capability. Can you type: "certutil -repairstore" and show us what the "Usage:" text says? If it says that you can set an sddl descriptor then we are in business. Otherwise, we need to come up with a different solution.

    Brief answers to your questions:

    - CertIdList is a list of certs that you want the security descriptor to apply to. I think it will work on multiple matches but you'll need to try that out. What this means is that every cert with subject name "il-mark-lap" will have its private keys security descriptor modified. If that is not what you want, then you should specify the cert thumbprint.

    - Translating nt4 name to a sid and then to an sddl is not so obvious. You'll need to write a small tool to do this. Unless someone knows of some tool that will create SDDL given nt4 names and desired permissions.

    The command I think you want is *roughly*:

    certutil -repairstore MY <thumbprint> <sddl>



    Sunday, February 6, 2011 3:54 AM
  • Hi

    Thanks for the reply.

    certutil -repairstore accepts SDDL on Win2008/7 and does not do so for Win2003/XP. I need a procedure that works for both (or two different procedures). This is because the code belongs to the installer, which is expected to be run on all of these OS versions.


    I do want subject name il-mark-lap. The question is whether the match is exact or partial and whether all the matches are modified, because the problem with winhttpcertcfg is that the match is partial and only the first match is modified. Of course, if the match is partial, but all the matches are modified then things will work, but excessive access would be granted to irrelevant certificates.


    I can live with thumbprint. I even have a VB script that translates subject name to thumbprint using CAPICOM. I do not mind writing a utility that translates user name to SDDL, but what are the ACEs that I should specify? I mean there are million different accesses. Another question is whether SDDL is additive. Meaning, do I have to provide an SDDL listing all the accounts that need access to the certificate or just the user relevant to my scenario and it will be added?

    As I  side note, I am wondering why do I have all these problems? Am I the only one in the whole world who needs to grant access to certificate to certain user? Maybe others know a secret I don't? Or everyone is so apt in raw WIN32 security API that implement all these stuff in code? What is wrong with my approach?



    Sunday, February 6, 2011 8:15 AM
  • I don't see how you can translate an ambiguous subject name to a thumbprint. You have 2 certs with the same subject name, which one will you pick?

    You are probably having these problems because you have 2 certs with the same name in your MY store. Although, I agree with you that the tools should be better at getting around this issue.

    I see a couple of options:

    - I found the following blog post that describes how to set the key container acl in managed code: http://blogs.msdn.com/b/cagatay/archive/2009/02/08/removing-acls-from-csp-key-containers.aspx

    - Or you can go right to the native api: http://msdn.microsoft.com/en-us/library/aa380276(VS.85).aspx and call CryptSetProvParam with PP_KEYSET_SEC_DESCR. This works for CSPs. For CNG, you'll have to use http://msdn.microsoft.com/en-us/library/aa376292(VS.85).aspx NCryptSetProperty with with the NCRYPT_SECURITY_DESCR_PROPERTY property



    • Marked as answer by Markell Monday, February 14, 2011 8:38 AM
    Sunday, February 6, 2011 7:45 PM
  • Thanks abernat for your reply. However, you have missed a point. winhttpcertcfg performs a partial match ! I do not have two certificate with the same subject name that is the point! But I have two where the subject name of the first is a suffix of the second, which was added by VMWARE. So, my script works fine because it performs an exact match of the subject name, while winhttpcertcfg misfunctions.

    Thanks for the links, I will inspect them later. Still, the lack of adequate tools is scandalous.


    Monday, February 7, 2011 8:36 AM
  • I understand I think. Sadly, the tools on Win2k3 don't seem to solve your problem. I'm glad this was resolved in WIn2k8.

    But I think I found a workaround. It isn't pretty... but I think it should work for you.

    In your script, you can make the vmware cert as archived, then run the winhttpcertcfg command and then unarchive the vmware cert. I'm pretty sure the winhttpcertcfg command will not look at archived certs.

    You can use certutil to archive a cert:
    certutil -store My <thumbprint> archive.inf

    The file archive.inf would look like:
    19 = Empty ; Add archived property, OR:

    Then to unarchive the cert you would run the same certutil command using the file unarchive.inf which would look like:
    19 =       ; Remove archived property


    Friday, February 11, 2011 4:04 AM
  • Thanks. The approach you suggest is quite complex, because:

    1. I am not sure whether there are certificates with partial subject name matches. So, I will have to browse them all (using a VB script) and archive all the partial matches in order to apply the winhttpcertcfg later.
    2. The archive files must be converted to unarchive files - I did not understand the exact procedure, though.

    I am considering to write some code to achieve what I need and drop the use of winhttpcertcfg completely. This MSDN page should help.

    Sunday, February 13, 2011 11:59 AM
  • You are correct about having to deal with the ambiguous matches. You would need to achive/unarchive each one.

    In this context, there is no "archive file". There is only an archive property on a certificate which can be set or not set. To do this, we can use the certutil -repairstore command. This command takes an inf file which specifies which properties to set/unset. In the example I provided earlier I happened to call the files: archive.inf which sets the archive property and unarchive.inf which removes the archive property of a cert.

    The link you provided basically uses the api that was mentioned earlier in this thread:

    "Or you can go right to the native api: http://msdn.microsoft.com/en-us/library/aa380276(VS.85).aspx and call CryptSetProvParam with PP_KEYSET_SEC_DESCR. This works for CSPs. For CNG, you'll have to use http://msdn.microsoft.com/en-us/library/aa376292(VS.85).aspx NCryptSetProperty with with the NCRYPT_SECURITY_DESCR_PROPERTY property"

    But the example link you provided is a full example with reading the security descriptor, modifying the dacl, and setting the new security descriptor.

    Sunday, February 13, 2011 7:09 PM
  • This whole security business is a sad story of job security. This is how I feel.

    But you are right about your old post - I have marked it as the answer.

    Monday, February 14, 2011 8:39 AM