Recent

Author Topic: Load Cert+Key into Ararat Synapse OpenSSL from string?  (Read 5350 times)

PizzaProgram

  • Jr. Member
  • **
  • Posts: 62
  • ...developing Delphi apps since 25 years.
Load Cert+Key into Ararat Synapse OpenSSL from string?
« on: May 08, 2022, 04:13:19 pm »
Hi,
 What if I have the Private Key and Public Certificate as "string" (and not as File) ?
How do I load it?
For example:
Code: Pascal  [Select][+][-]
  1. uses httpsend, ssl_openssl;
  2. const
  3. c_CER: AnsiString = '-----BEGIN CERTIFICATE-----'#10+
  4. 'MIIG4DC ... '
  5. ...
  6. var
  7.     HTTP: THTTPSend;
  8. begin
  9.     HTTP := THTTPSend.Create;
  10.     HTTP.Sock.SSL.Certificate := c_CER;
  11.     HTTP.Sock.SSL.PrivateKey  := c_priv_key;
  12.     HTTP.Sock.SSl.VerifyCert  := True;
  13.  

This is not working. Http error code 500 .
I guess I have to "digest" the Base64 code into raw bytes.
But How ?
« Last Edit: May 08, 2022, 05:19:20 pm by PizzaProgram »
x86_64-win64 --Win7 PRO 64bit HUN

PizzaProgram

  • Jr. Member
  • **
  • Posts: 62
  • ...developing Delphi apps since 25 years.
Re: Load Cert+Key into Ararat Synapse OpenSSL from string?
« Reply #1 on: May 08, 2022, 05:21:48 pm »
With this technique:
Code: Pascal  [Select][+][-]
  1. TSSLOpenSSL(HTTP.Sock.SSL).LastErrorDesc

I am able to get a proper error msg:
Code: [Select]
error:068000A8:asn1 encoding routines::wrong tag
x86_64-win64 --Win7 PRO 64bit HUN

zeljko

  • Hero Member
  • *****
  • Posts: 1998
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: Load Cert+Key into Ararat Synapse OpenSSL from string?
« Reply #2 on: May 08, 2022, 06:58:41 pm »
Hi,
 What if I have the Private Key and Public Certificate as "string" (and not as File) ?
How do I load it?
For example:
Code: Pascal  [Select][+][-]
  1. uses httpsend, ssl_openssl;
  2. const
  3. c_CER: AnsiString = '-----BEGIN CERTIFICATE-----'#10+
  4. 'MIIG4DC ... '
  5. ...
  6. var
  7.     HTTP: THTTPSend;
  8. begin
  9.     HTTP := THTTPSend.Create;
  10.     HTTP.Sock.SSL.Certificate := c_CER;
  11.     HTTP.Sock.SSL.PrivateKey  := c_priv_key;
  12.     HTTP.Sock.SSl.VerifyCert  := True;
  13.  

This is not working. Http error code 500 .
I guess I have to "digest" the Base64 code into raw bytes.
But How ?

Probably it expects filename instead of certificate data ?

PierceNg

  • Sr. Member
  • ****
  • Posts: 443
    • SamadhiWeb
Re: Load Cert+Key into Ararat Synapse OpenSSL from string?
« Reply #3 on: May 09, 2022, 05:08:40 am »
Hi,
 What if I have the Private Key and Public Certificate as "string" (and not as File) ?

Why not just save the data you have as files?

An X.509 public key certificate has an expiry date. When one expires, you may get a replacement certificate for the same private key, or you may get a certificate for a new private key. If you embed key and cert in your source code, then you'll have to rebuild your program when the time comes. If the data is kept in files outside your executable program, you just replace the files. Remember to secure the private key using operating system file permissions at least.

PizzaProgram

  • Jr. Member
  • **
  • Posts: 62
  • ...developing Delphi apps since 25 years.
Re: Load Cert+Key into Ararat Synapse OpenSSL from string?
« Reply #4 on: May 09, 2022, 07:34:41 pm »
Why not just save the data you have as files?

Because of 2 reasons:
 - the cert + key strings are stored in a database, distributing it to every client PC
 - revealing it by saving it to a file on every PC is very unsecure! Anybody could simply copy them to a PenDrive.

It would be better, if it would work, as it should and I could feed the string directly.
I'm starting to think, it's a bug?
x86_64-win64 --Win7 PRO 64bit HUN

Thausand

  • Hero Member
  • *****
  • Posts: 600
Re: Load Cert+Key into Ararat Synapse OpenSSL from string?
« Reply #5 on: May 09, 2022, 08:09:19 pm »
Certificate is not file but string (http://synapse.ararat.cz/doc/help/blcksock.TCustomSSL.html#Certificate)
Quote
Used for loading certificate from binary string. See to plugin documentation if this method is supported and how!
For file there is special certificatefile property.

I not know how string is expect to be encoded.

Here (http://synapse.ararat.cz/doc/help/ssl_openssl.html) it write:
Quote
TCustomSSL.Certificate for ASN1 DER format only.

String must be binary string, maybe remove begin/end certificate text ?
A docile goblin always follow HERMES.md

rvk

  • Hero Member
  • *****
  • Posts: 7064
Re: Load Cert+Key into Ararat Synapse OpenSSL from string?
« Reply #6 on: May 09, 2022, 08:28:15 pm »
Yes the string needs to be ASN1 DER.
The file can be both PEM and ASN1 DER.
See ssl_openssl.pas
Quote
For handling keys and certificates you can use this properties:
@link(TCustomSSL.CertificateFile) for PEM or ASN1 DER (cer) format. @br
@link(TCustomSSL.Certificate) for ASN1 DER format only. @br
@link(TCustomSSL.PrivateKeyFile) for PEM or ASN1 DER (key) format. @br
@link(TCustomSSL.PrivateKey) for ASN1 DER format only. @br
@link(TCustomSSL.CertCAFile) for PEM CA certificate bundle. @br
@link(TCustomSSL.PFXFile) for PFX format. @br
@link(TCustomSSL.PFX) for PFX format from binary string. @br

You can probably look in the source how to convert it in code.

For testing you can also do it manually and take the result from file.
openssl x509 -inform PEM -outform DER -in server.pem -out server.der

PizzaProgram

  • Jr. Member
  • **
  • Posts: 62
  • ...developing Delphi apps since 25 years.
Re: Load Cert+Key into Ararat Synapse OpenSSL from string?
« Reply #7 on: May 12, 2022, 09:16:03 pm »
This is a Test-code only (made by someone else).
 It's very ugly, but:

IT WORKS :-)

Code: Pascal  [Select][+][-]
  1. const CRLF = #13+#10;
  2. var List : TStringList;
  3.  
  4. List := TStringList.Create();
  5.  
  6. List.LoadFromFile(cerfile);
  7. List.Text := AnsiReplaceStr(List.Text, CRLF, '');
  8. List.Text := AnsiReplaceStr(List.Text, '-----BEGIN CERTIFICATE-----', '');
  9. List.Text := AnsiReplaceStr(List.Text, '-----END CERTIFICATE-----', '');
  10. HTTP.Sock.SSL.Certificate := DecodeStringBase64(List.Text);
  11. HTTP.Headers.Add('x-certificate: ' + List.Text);
  12.  
  13. List.LoadFromFile(keyfile);
  14. List.Text := AnsiReplaceStr(List.Text, CRLF, '');
  15. List.Text := AnsiReplaceStr(List.Text, '-----BEGIN PRIVATE KEY-----', '');
  16. List.Text := AnsiReplaceStr(List.Text, '-----END PRIVATE KEY-----', '');
  17. HTTP.Sock.SSL.PrivateKey := DecodeStringBase64(List.Text);
  18. HTTP.Headers.Add('x-jws-signature: ' + List.Text);
  19.  
  20. List.Free;     
  21.  
x86_64-win64 --Win7 PRO 64bit HUN

zamronypj

  • Full Member
  • ***
  • Posts: 140
    • Fano Framework, Free Pascal web application framework
Re: Load Cert+Key into Ararat Synapse OpenSSL from string?
« Reply #8 on: May 12, 2022, 09:58:28 pm »
This is a Test-code only (made by someone else).
 It's very ugly, but:

IT WORKS :-)

Code: Pascal  [Select][+][-]
  1. const CRLF = #13+#10;
  2. var List : TStringList;
  3.  
  4. List := TStringList.Create();
  5.  
  6. List.LoadFromFile(cerfile);
  7. List.Text := AnsiReplaceStr(List.Text, CRLF, '');
  8. List.Text := AnsiReplaceStr(List.Text, '-----BEGIN CERTIFICATE-----', '');
  9. List.Text := AnsiReplaceStr(List.Text, '-----END CERTIFICATE-----', '');
  10. HTTP.Sock.SSL.Certificate := DecodeStringBase64(List.Text);
  11. HTTP.Headers.Add('x-certificate: ' + List.Text);
  12.  
  13. List.LoadFromFile(keyfile);
  14. List.Text := AnsiReplaceStr(List.Text, CRLF, '');
  15. List.Text := AnsiReplaceStr(List.Text, '-----BEGIN PRIVATE KEY-----', '');
  16. List.Text := AnsiReplaceStr(List.Text, '-----END PRIVATE KEY-----', '');
  17. HTTP.Sock.SSL.PrivateKey := DecodeStringBase64(List.Text);
  18. HTTP.Headers.Add('x-jws-signature: ' + List.Text);
  19.  
  20. List.Free;     
  21.  

What you are doing is very dangerous as you expose your private key in HTTP header. Private key need to be kept secret
Fano Framework, Free Pascal web application framework https://fanoframework.github.io
Apache module executes Pascal program like scripting language https://zamronypj.github.io/mod_pascal/
Github https://github.com/zamronypj

PizzaProgram

  • Jr. Member
  • **
  • Posts: 62
  • ...developing Delphi apps since 25 years.
Re: Load Cert+Key into Ararat Synapse OpenSSL from string?
« Reply #9 on: May 13, 2022, 10:01:05 am »
This is a MUST, demanded by our government:  :o
Code: Pascal  [Select][+][-]
  1. HTTP.Headers.Add('x-certificate: ' + List.Text);

But you are right about the 2th one:
Code: Pascal  [Select][+][-]
  1. List.LoadFromFile(keyfile);
  2. ...
  3. HTTP.Headers.Add('x-jws-signature: ' + List.Text);
That is a BIG mistake! Mixing JOSE JWS signature with Private key and revealing it...  %)
I will tell the guy to delete it.

There is also a finished function that is doing all this in one line:
Code: Pascal  [Select][+][-]
  1. uses pfpem, basenenc, ...
  2.  
  3.  ... := basenenc.Base64URL.Decode(fppem.PemToDER( private_Key_string , _BEGIN_PRIVATE_KEY, _END_PRIVATE_KEY ));

But that is generating TByte value and I don't know how to convert TByte back to String...
x86_64-win64 --Win7 PRO 64bit HUN

PizzaProgram

  • Jr. Member
  • **
  • Posts: 62
  • ...developing Delphi apps since 25 years.
[Solved] Load Cert+Key into Ararat Synapse OpenSSL from string?
« Reply #10 on: May 13, 2022, 12:18:58 pm »
OK, here is the final, tested, short solution:  :P

Code: Pascal  [Select][+][-]
  1. uses basenenc, fppem, ...
  2.  
  3.   HTTP.Sock.SSL.PrivateKey  := basenenc.GetRawStringFromBytes(fppem.PemToDER( priv_key_string , _BEGIN_PRIVATE_KEY, _END_PRIVATE_KEY ));
  4.   HTTP.Sock.SSL.Certificate := basenenc.GetRawStringFromBytes(fppem.PemToDER( cert_string     , _BEGIN_PRIVATE_KEY, _END_PRIVATE_KEY ));
x86_64-win64 --Win7 PRO 64bit HUN

 

TinyPortal © 2005-2018