#1 2024-02-29 07:54:53

itSDS
Member
From: Germany
Registered: 2014-04-24
Posts: 506

Feature request or question concerning Certificate in Windows Storage

Hi Arnaud,

im Using WEBSOCKET_DEFAULT_MODE in some of my new services.
Before i used useHttpApiRegisteringURI
now i have to switch some services also using https from http to Socket mode. There was a Certificate attached to the service by fingerprint from Windows certificate storage.

I read your Blog with detailed information on how to setup the tls:
https://blog.synopse.info/?post/2022/07 … WebSockets

Is it possible to use the Certificate from Windows Storage as TLS Parameter ?
Or is there a way to export it to give tls the cert files ?

Last edited by itSDS (2024-02-29 07:55:20)


Rad Studio 12.1 Santorini

Offline

#2 2024-02-29 09:12:07

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,237
Website

Re: Feature request or question concerning Certificate in Windows Storage

You need to use the TNetTlsContext fields.
My guess is that you need client TLS authentication using a certificate with a private key stored within the local windows storage?

But it depends on the TLS engine used.
For OpenSSL you can specify CertificateFile or other fields if needed.
For SSPI (default on Windows), you can't specify a client certificate (yet).

You can try to modify TSChannelNetTls in mormot.net.sock.windows.inc to add the ability to specify a client Certificate in TNetTlsContext.
Either as a file name or a file fingerprint using CertFindCertificateInStore(CERT_FIND_HASH).
If you need it for SSPI, I could try to implement it, and you may validate/test it.

Offline

#3 2024-02-29 09:38:26

itSDS
Member
From: Germany
Registered: 2014-04-24
Posts: 506

Re: Feature request or question concerning Certificate in Windows Storage

Hi i have the p7b File of the Certificate can i use this ?


Rad Studio 12.1 Santorini

Offline

#4 2024-02-29 09:52:11

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,237
Website

Re: Feature request or question concerning Certificate in Windows Storage

Not with SSPI, only with OpenSSL.

Offline

#5 2024-02-29 10:16:29

Chaa
Member
Registered: 2011-03-26
Posts: 245

Re: Feature request or question concerning Certificate in Windows Storage

You can use certmgr.msc to import .p7b file and then export as .pfx.

Offline

#6 2024-03-01 08:08:12

itSDS
Member
From: Germany
Registered: 2014-04-24
Posts: 506

Re: Feature request or question concerning Certificate in Windows Storage

Chaa wrote:

You can use certmgr.msc to import .p7b file and then export as .pfx.

i tried it, but the file does not include the private key - Export is grey for this


Rad Studio 12.1 Santorini

Offline

#7 2024-03-01 10:25:04

itSDS
Member
From: Germany
Registered: 2014-04-24
Posts: 506

Re: Feature request or question concerning Certificate in Windows Storage

ab wrote:

You need to use the TNetTlsContext fields.
My guess is that you need client TLS authentication using a certificate with a private key stored within the local windows storage?

But it depends on the TLS engine used.
For OpenSSL you can specify CertificateFile or other fields if needed.
For SSPI (default on Windows), you can't specify a client certificate (yet).

You can try to modify TSChannelNetTls in mormot.net.sock.windows.inc to add the ability to specify a client Certificate in TNetTlsContext.
Either as a file name or a file fingerprint using CertFindCertificateInStore(CERT_FIND_HASH).
If you need it for SSPI, I could try to implement it, and you may validate/test it.

Hi Arnaud, my certificate is stored in local Machine storage. so i tried to add it to SChannel Afterbind, but get error on start i can not explain to me:

procedure TSChannelNetTls.AfterBind(var Context: TNetTlsContext);
var
  certblob: RawByteString;
  blob: TCryptDataBlob;
  pass: SynUnicode;
  flags: integer;
begin
  if Context.CertificateFile = '' then begin
    // Load certificate and private key from Windows certificate store
//     fAcceptCertStore := CertOpenSystemStoreW(nil, 'MY')
    var LProvider : WideChar := WideChar(CERT_STORE_PROV_SYSTEM);
    var LMy := 'MY';
    fAcceptCertStore := mormot.lib.sspi.CertOpenStoreW(@LProvider, 0, nil, CERT_SYSTEM_STORE_LOCAL_MACHINE, @LMy);
  end else
  begin
    certblob := StringFromFile(TFileName(Context.CertificateFile));

At Programm start a message pops up CertOpenStoreW not found in dll (my exe name) in source is it declared as extern crypt32.dll

any idea ?


Rad Studio 12.1 Santorini

Offline

#8 2024-03-01 11:25:59

Chaa
Member
Registered: 2011-03-26
Posts: 245

Re: Feature request or question concerning Certificate in Windows Storage

It's a bug in mormot.lib.sspi.pas.

CertOpenStore does not have CertOpenStoreA and CertOpenStoreW variants.

Ansi or Unicode usage depends on first parameter, for example CERT_STORE_PROV_SYSTEM_A or CERT_STORE_PROV_SYSTEM_W.

P.S.

And first parameter is PAnsiChar, so:

var LProvider: AnsiChar := #10; // CERT_STORE_PROV_SYSTEM_W
var LMy: UnicodeString := 'MY';

Last edited by Chaa (2024-03-01 11:31:41)

Offline

#9 2024-03-01 13:41:30

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,237
Website

Re: Feature request or question concerning Certificate in Windows Storage

Offline

#10 2024-03-01 13:57:57

itSDS
Member
From: Germany
Registered: 2014-04-24
Posts: 506

Re: Feature request or question concerning Certificate in Windows Storage

ty ab-

I'm a few steps further, Moving my Certiicate to MY private storage and looking for ThumbPrint now works:

  LsThumbPrint := '12097c0d0db94e85b83b415bc8b6aa324dcd9dc1';

  flags := Length(LsThumbPrint) div 2;
  SetLength(certblob, flags);
  HexToBinFast(PAnsiChar(LsThumbPrint), PByte(certblob), flags);
  blob.cbData := flags;
  blob.pbData := pointer(certblob);
  fAcceptCert := mormot.lib.sspi.CertFindCertificateInStore(fAcceptCertStore, X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, 0, $10000, @blob, nil);
  if fAcceptCert = nil then
    raise ESChannel.Create('AfterBind: no Certificate available');

But if i use my request to local machine (See above) and then look for thmubprint does not work - may something wrong with selecting right storage


Rad Studio 12.1 Santorini

Offline

#11 2024-03-01 14:05:25

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,237
Website

Re: Feature request or question concerning Certificate in Windows Storage

The AfterBind() method is for the server side, so you want to download a server certificate, right?

Are you sure the certificate is at the expected location:
https://learn.microsoft.com/en-us/windo … al_machine

Offline

#12 2024-03-01 14:14:19

itSDS
Member
From: Germany
Registered: 2014-04-24
Posts: 506

Re: Feature request or question concerning Certificate in Windows Storage

Yes certificate is in HKLM/Software/Microsoft/SystemCertificates/MY/Certificates

But CertOpenStore returns nil ...

May Be Something wrong with Parameters:

  CERT_STORE_PROV_SYSTEM = 10;
  CERT_STORE_MAXIMUM_ALLOWED_FLAG = $00001000;
  CERT_SYSTEM_STORE_CURRENT_USER =  $00010000;
  CERT_SYSTEM_STORE_LOCAL_MACHINE = $00020000;


    var LProvider : AnsiChar := #10; // CERT_STORE_PROV_SYSTEM  or CERT_STORE_MAXIMUM_ALLOWED_FLAG
    var LMy := 'MY';
    fAcceptCertStore := mormot.lib.sspi.CertOpenStore(@LProvider, 0, nil, CERT_SYSTEM_STORE_LOCAL_MACHINE, @LMy);

tried also with Admin rights / Ask for User also does not work.

Last edited by itSDS (2024-03-01 14:14:56)


Rad Studio 12.1 Santorini

Offline

#13 2024-03-01 14:56:45

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,237
Website

Re: Feature request or question concerning Certificate in Windows Storage

You are making a lot of confusion about pointers and types.
@LMy returns the address of the LMy pointer in the stack.

Edit:
And also LProvide seems wrong. It is a PAnsiChar() of a numerical constant.

So define
  const LMy: PWideChar = 'My';
           CERT_STORE_PROV_SYSTEM_W = pointer(10);

Just try CertOpenStore(CERT_STORE_PROV_SYSTEM_W, ..., LMy);

Offline

#14 2024-03-01 19:24:53

itSDS
Member
From: Germany
Registered: 2014-04-24
Posts: 506

Re: Feature request or question concerning Certificate in Windows Storage

ty i tried my best but was a little confused converting from c to delphi. But now it works and certificate is found.

Now after getting the Handle the next error comes in AfterAccept:

Erste Gelegenheit für Exception bei $76CCDD80. Exception-Klasse ESChannel mit Meldung '<>: AcquireCredentialsHandleW returned 8009030E [2148074254], System Error 1312 [Eine angegebene Anmeldesitzung ist nicht vorhanden. Sie wurde gegebenenfalls bereits beendet]'.

Something about missing Credentials


Rad Studio 12.1 Santorini

Offline

#15 2024-03-02 08:07:02

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,237
Website

Re: Feature request or question concerning Certificate in Windows Storage

I guess you need to use both a private key and a certificate for the server to work.

Offline

Board footer

Powered by FluxBB