EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Installing P12 files into Windows Certificate Store

Also by EldoS: CallbackFilter
A component to monitor and control disk activity, track file and directory operations (create, read, write, rename etc.), alter file data, encrypt files, create virtual files.
#29252
Posted: 04/15/2014 00:01:36
by Gavin Godfrey (Standard support level)
Joined: 04/14/2014
Posts: 4

Hi,
I can quite easily import a .p12 file into my windows certificate store using
Code
Cert := TElX509Certificate.Create(self);
cert := TElX509Certificate.loadfromFileAuto(p12FileName, p12Password);
LocalWinCertStorage := TElWinCertStorage.Create(nil);
LocalWinCertStorage.SystemStores.Text := fStoreName;
LocalWinCertStorage.Add(Cert,fStoreName,true,true,false);
LocalWinCertStorage.free;



but it does not give the same results as using windows certificate import wizard, specifically, it won't install the Root Authority certificate.

Does anyone know what I must do to achieve this?

Thanks
AL
#29255
Posted: 04/15/2014 01:31:58
by Eugene Mayevski (EldoS Corp.)

With your code you load one certificate and install it to the chosen store. If you want to load multiple certificates from PKCS#12 file, use TElMemoryCertStorage.LoadFromStreamPFX method. Then add certificates from TElMemoryCertStorage to TElWinCertStorage one by one to the store of your choice.


Sincerely yours
Eugene Mayevski
#29273
Posted: 04/15/2014 16:39:43
by Gavin Godfrey (Standard support level)
Joined: 04/14/2014
Posts: 4

Hi Eugene,
Thank you very much for your quick reply. It works!
I am not sure if my code is state of the art, but here it is.
Code
  try
    memCert := TElMemoryCertStorage.Create(self);
    ts := TFileStream.create(EditHIFileName.Text,fmOpenRead);
    LocalWinCertStorage := TElWinCertStorage.Create(nil);
    nErrorHI := memCert.loadFromStreamPFX(ts,EditHIPassword.text);
    if nErrorHI = 0 then begin
      for i := 0 to memcert.count- 1 do begin
        if pos('ROOT', uppercase(memcert.Certificates[i].SubjectName.CommonName)) > 0 then begin
          LocalWinCertStorage.SystemStores.Text := 'ROOT';
          LocalWinCertStorage.Add(memCert.certificates[i],'ROOT',true,true,false);
        end
        else if pos('AUTHORITY',uppercase(memcert.Certificates[i].SubjectName.CommonName)) > 0 then begin
          LocalWinCertStorage.SystemStores.Text := 'CA';
          LocalWinCertStorage.Add(memCert.certificates[i],'CA',true,true,false);
        end
        else begin
          LocalWinCertStorage.SystemStores.Text := fStoreName;
          LocalWinCertStorage.Add(memCert.certificates[i],fStoreName,true,true,false);
        end;
      end;
    end // nErrorHI = 0;
    else begin
      if nErrorHI = 7955 then
        query('Invalid Password was specified', mtError,[mbok])
      else
        query('Error loading Certificate from disk.' + #13 +
                'Error code is ' + inttostr(nErrorHI),mtError,[mbok]);
    end;
  finally
    FreeAndNil(ts);
    FreeAndNil(memCert);
    FreeAndNil(LocalWinCertStorage);
  end;


I am wondering if there is a way for any machine on the network to read a Windows Certificate store on say, eg, the server. That way we only have to install the certificate(s) once on one machine. Is it a matter of setting AccessType?

Also comments on the above code would be appreciated, eg, is there a better way to identify Root and Authority certificates?

Thanks again. I was really stuck on this and your help is appreciated.
AL
#29276
Posted: 04/16/2014 01:11:23
by Eugene Mayevski (EldoS Corp.)

The code is fine.

Quote
AL Dwado wrote:
I am wondering if there is a way for any machine on the network to read a Windows Certificate store on say, eg, the server. That way we only have to install the certificate(s) once on one machine. Is it a matter of setting AccessType?


Potentially you can reach the server via LDAP (Active Directory and some other servers support this) and SecureBlackbox has LDAP components for this.

Also, you can try to access the remote system by setting AccessType and other properties, yet this is not a universal way (unlike LDAP) and it is provided by CryptoAPI itself. When it works, it works, when it doesn't, it's hard to diagnose.

Quote
AL Dwado wrote:
Also comments on the above code would be appreciated, eg, is there a better way to identify Root and Authority certificates?


Root certificates are self-signed. However, you should not automatically add new trusted roots from PFX. This contradicts to the concept of trusted roots. You usually get roots using some secure channel and knowing that you can trust them. When you import PFX files, you can either add those self-signed roots not to ROOT but to CA store (thus marking them as known but not trusted), or just do nothing with them.

CA certificates are CA-signed certificates with key usage and extended key usage fields set in the way to allow signing other certificates. They often have "CA" or "Authority" in the common name but this is not a requirement and not a rule.

End-entity certificates are usually the ones that are the "ends" of the certificate chain present in the file. In some cases CA certificates can be end-entity certificates just because they are end-entity certificates eg. for CA admins.

So when importing certificates, you need to identify all chains, then for each chain deal with root, then with end-entity, then with intermediate certificates.


Sincerely yours
Eugene Mayevski
#29288
Posted: 04/16/2014 20:12:13
by Gavin Godfrey (Standard support level)
Joined: 04/14/2014
Posts: 4

Hi Eugene,
Once again, thank you for the reply.
What you wrote makes a lot of sense.

Most systems will use Terminal Services and WinCertStorage defaults to Current User as access type. I am a little concerned that one user creates the store from the certificates and it won't be visible to others.
I had already added the certificate with WinCertStorage.accesstype default value of atCurrentUser.
When I then added the certificate with atLocalMachine, when I view Current User certificates using CertMgr.msc I get the certificate listed twice.
I then deleted both copies of the certificate from CurrentUser and reInstalled using atLocalMachine and the certificate is visible from CurrentUser and LocalMachine. So adding with atLocalMachine makes it visible to CurrentUser.

I can install again many times using either atCurrentUser or atLocalMachine and the listings stay the same, ie, they are not duplicated. It appears I only get a duplicate certificate if the certificate had been initially added to the store using atCurrentUser then added using atLocalMachine.
Setting allowDuplicates to false is too restrictive, eg, installing a second certificate with the same root authority.

Also adding with accessType = atLocalMachine does not give the usual warning that comes up re trusting the Root Authority certificate.

I guess what I want to know is how others make certificates available in their applications to all users on the system. Or does each user have to install the certificates. Painful when certificates expire and they need to be reinstalled.

Thanks
AL
#29289
Posted: 04/17/2014 00:34:45
by Eugene Mayevski (EldoS Corp.)

That's a question not for us. Try asking on http://serverfault.com/

BTW you must have admin rights to install anything to LocalSystem store. This can be impossible for regular users with restricted accounts.


Sincerely yours
Eugene Mayevski
#29290
Posted: 04/17/2014 00:50:58
by Gavin Godfrey (Standard support level)
Joined: 04/14/2014
Posts: 4

Thanks Eugene.
I will follow it up at that site.
Thanks again for your assistance.

AL.....
Also by EldoS: CallbackRegistry
A component to monitor and control Windows registry access and create virtual registry keys.

Reply

Statistics

Topic viewed 2962 times

Number of guests: 2, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!