-1

I have a certificat (X509 .cer file) that I need to install into the current user's Trusted Publishers store so it will appear here under the certificat manager:

enter image description here

I'm able to install the certificat by double clicking on the .cer file and then clicking my way though some dialogs.

But I need to install it programmatically using the raw Windows API.

It's more or less the same question as this SO question but for C or C++ instead of C#.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • 1
    [Certificate and Certificate Store Functions](https://learn.microsoft.com/en-us/windows/desktop/SecCrypto/cryptography-functions#certificate-and-certificate-store-functions) have fun ;-p – Swordfish Sep 24 '18 at 07:05

1 Answers1

0

It's actually quite simple:

Following quick and dirty sample program adds the certificat in the cert.cer file to the current user's "Trusted Publishers" certificat store.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>

#pragma comment (lib, "crypt32.lib")

void MyHandleError(LPCTSTR psz)
{
  fprintf(stderr, TEXT("An error occurred in the program.\n"));
  fprintf(stderr, TEXT("%s\n"), psz);
  fprintf(stderr, TEXT("Error number %x.\n"), GetLastError());
  exit(1);
}

int main()
{
  HCERTSTOR hCertStore;

  if (hCertStore = CertOpenSystemStore(NULL, "TrustedPublisher"))
  {
    fprintf(stderr, "The %s store has been opened. \n", pszStoreName);
  }
  else
  {
    MyHandleError("The store was not opened.");
  }

  // Open and read certificat file
  HANDLE hfile = CreateFile("cert.cer", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

  if (hfile == INVALID_HANDLE_VALUE)
  {
    MyHandleError("File could not be opened.");
  }

  DWORD size = GetFileSize(hfile, NULL);

  if (size == INVALID_FILE_SIZE)
  {
    MyHandleError("GetFileSize failed.");
  }

  char *pFileContent = (char*)malloc(size);

  DWORD sizeread;
  ReadFile(hfile, pFileContent, size, &sizeread, NULL);
  CloseHandle(hfile);

  // pFileContent points to certificat bytes, size contains the certificat size

  if (!CertAddEncodedCertificateToStore(hCertStore, X509_ASN_ENCODING, 
                                         (const BYTE*)pFileContent, size,
                                         CERT_STORE_ADD_NEW,
                                         NULL)
     )
  {
    MyHandleError("CertAddEncodedCertificateToStore failed.");
  }

  free(pFileContent);      
  CertCloseStore(hCertStore, 0);
}
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • 1
    this handle only X.509 certificate encoded in binary form. this not handle case when it in base64 form. not handle pfx(PKCS#12) or p7b(PKCS#7 Format). also will be more simply use `CryptQueryObject` here – RbMm Sep 24 '18 at 15:22
  • @RbMm I know, but this is OK for me as I can generate my certificat in any format included X.509 binary. I just had a look at [CyrptQueryObject](https://learn.microsoft.com/en-us/windows/desktop/api/wincrypt/nf-wincrypt-cryptqueryobject), but it seems rather complicated to me. Could you just elaborate a bit and explain why it is simpler? Also the documenation says that `CryptQueryObject` is deprecated. Thanks. – Jabberwocky Sep 24 '18 at 15:26
  • use `CryptQueryObject` will be much more easy here, because you can pass file name to it and got ready certificate on exit. all what you will be need after - call `CertAddCertificateToStore` + `CertFreeCertificateContext`. not need open file yourself, query it size, read, etc – RbMm Sep 24 '18 at 15:29
  • 1
    you need call `CryptQueryObject(CERT_QUERY_OBJECT_FILE, szFileName, CERT_QUERY_CONTENT_FLAG_CERT, CERT_QUERY_FORMAT_FLAG_ALL, 0, 0, 0, 0, 0, 0, (const void**)&pCertContext)` and if no errors - `CertAddCertificateContextToStore` + `CertFreeCertificateContext` – RbMm Sep 24 '18 at 15:35
  • @RbMm the main objection to using `CryptQueryObject` is that Microsoft documents it as deprecated. – Jabberwocky Sep 24 '18 at 15:39
  • Does this function CertAddEncodedCertificateToStore work for pem, der format certificates as well? – Sheikh Arbaz Jul 29 '21 at 17:20