Recent

Author Topic: [Solved] OpenSSL sign PKCS7  (Read 908 times)

lainz

  • Hero Member
  • *****
  • Posts: 2957
    • Home
[Solved] OpenSSL sign PKCS7
« on: December 27, 2018, 04:29:04 pm »
Hi, I have this Node.js code that signs using both a key and a crt file.

Code: Javascript  [Select]
  1.         var privateKeyAssociatedWithCert = fs.readFileSync(__base + '/homo.key').toString();
  2.         var certOrCertPem = fs.readFileSync(__base + '/homo.crt').toString();
  3.         var p7 = forge.pkcs7.createSignedData();
  4.        
  5.         p7.content = forge.util.createBuffer(request, 'utf8');
  6.         p7.addCertificate(certOrCertPem);
  7.  
  8.         p7.addSigner({
  9.             key: privateKeyAssociatedWithCert,
  10.             certificate: certOrCertPem,
  11.             digestAlgorithm: forge.pki.oids.sha256,
  12.             authenticatedAttributes: []
  13.         });
  14.         p7.sign();

This is my code so far, I'm using webservice toolkit:

Code: Pascal  [Select]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   locService : LoginCMS;
  4.   inData: loginCms_Type;
  5.   i : Integer;
  6.   p7: pkcs7;
  7.   key, certificate: TStringList;
  8. begin
  9.   key := TStringList.Create;
  10.   key.LoadFromFile('homo.key');
  11.  
  12.   certificate := TStringList.Create;
  13.   certificate.LoadFromFile('homo.crt');
  14.  
  15.   FPC_RegisterHTTP_Transport();
  16.   locService := wst_CreateInstance_LoginCMS();
  17.   inData := loginCms_Type.Create();
  18.  
  19.   inData.in0 := ''; // signed data goes here
  20.   Memo1.Text := locService.loginCms(inData).loginCmsReturn;
  21. end;  

I need to sign the data, maybe using OpenSSL unit functions

Code: Pascal  [Select]
  1. PKCS7_sign();

Anyone knows how to use it?
« Last Edit: January 11, 2019, 08:36:32 pm by lainz »

lucamar

  • Hero Member
  • *****
  • Posts: 717
Re: OpenSSL sign PKCS7
« Reply #1 on: December 27, 2018, 04:57:49 pm »
A quick googling reveals this gems:

HTH!
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 1.8.4/FPC 3.0.4 on:
(K)Ubuntu 12..16, Windows XP SP3 (Home/Prof.) and various DOS incarnations.

lainz

  • Hero Member
  • *****
  • Posts: 2957
    • Home
Re: OpenSSL sign PKCS7
« Reply #2 on: December 27, 2018, 05:53:25 pm »
Thanks. Is possible to translate to actual code that information? I mean I think is possible in pascal, but maybe I end using openssl executable...

asdf121

  • New member
  • *
  • Posts: 24
Re: OpenSSL sign PKCS7
« Reply #3 on: December 27, 2018, 07:08:09 pm »
Sure, you can.

Not sure if Indy's OpenSSL headers do load the function for
Code: Pascal  [Select]
  1. PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags);
but if not, you can easy add them on your own or ask Remy if he could do it.

Then you just need to create the needed parameters with help of OpenSSL (see defines of Indy headers & OpenSSL docs) and call them in your pascal program.
You need to have the appropriate OpenSSL (atm v1.0.2) libs on your system and need to load them before using it.

lainz

  • Hero Member
  • *****
  • Posts: 2957
    • Home
Re: OpenSSL sign PKCS7
« Reply #4 on: December 27, 2018, 09:29:13 pm »
Thanks. Didn't know that I as well needed functions to create the parameters. That helps.

Not sure about the loading of the functions, these are included in openssl.pas, that's enough? Sorry not much usage of dll on my side.

lucamar

  • Hero Member
  • *****
  • Posts: 717
Re: OpenSSL sign PKCS7
« Reply #5 on: December 28, 2018, 10:35:20 am »
Not sure about the loading of the functions, these are included in openssl.pas, that's enough? Sorry not much usage of dll on my side.

Yes it should be enough.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 1.8.4/FPC 3.0.4 on:
(K)Ubuntu 12..16, Windows XP SP3 (Home/Prof.) and various DOS incarnations.

lainz

  • Hero Member
  • *****
  • Posts: 2957
    • Home
Re: OpenSSL sign PKCS7
« Reply #6 on: January 08, 2019, 04:54:04 pm »
Hi again, I found a code that does what I need:

https://stackoverflow.com/questions/19193756/using-pkcs7-sign-to-sign-a-message-in-foxpro

I'm translating it from FoxPro to Pascal, but I found there's a method in some of the dll of openssl that is not defined in Pascal:

PEM_write_bio_PKCS7 There is another already defined but has 2 extra parameters...

Any ideas on how to add it to OpenSSL.pas?

Code: Pascal  [Select]
  1. var
  2.   s: TStringList;
  3.   cbuf: string;
  4.   kbuf: string;
  5.   pXml: string;
  6.   bioc, biok, biom, bios: PBIO;
  7.   fc: PX509;
  8.   fk: PEVP_PKEY;
  9.   smsg: PPKCS7;
  10.   buf: string;
  11.   nlen: cInt;
  12. begin
  13.   Result := '';
  14.  
  15.   s := TStringList.Create;
  16.   try
  17.    ...
  18.     pXml := s.Text;
  19.  
  20.     s.LoadFromFile(directorioTemp + 'homo.crt');
  21.     cbuf := s.Text;
  22.  
  23.     s.LoadFromFile(directorioTemp + 'homo.key');
  24.     kbuf := s.Text;
  25.  
  26.     bioc := BIO_new_mem_buf(@cbuf, Length(cbuf));
  27.  
  28.     fc := PEM_read_bio_X509(bioc, nil, nil, nil);
  29.  
  30.     biok := BIO_new_mem_buf(@kbuf, Length(kbuf));
  31.  
  32.     fk := PEM_read_bio_PrivateKey(biok, nil, nil, nil);
  33.  
  34.     biom := BIO_new_mem_buf(@pXml, Length(pXml));
  35.  
  36.     smsg := PKCS7_sign(fc, fk, nil, @biom, 0);
  37.  
  38.     bios := BioNew(BioSMem);
  39.  
  40.     PEM_write_bio_PKCS7(bios, smsg);
  41.  
  42.     SetLength(buf, 4096);
  43.  
  44.     nlen := BIORead(bios, buf, Length(buf));
  45.  
  46.     s.Text := Copy(buf, 0, nlen);  

Edit: I made a bug report to see if the package mantainer of OpenSSL can add it
https://bugs.freepascal.org/view.php?id=34842
« Last Edit: January 09, 2019, 03:30:44 pm by lainz »

lainz

  • Hero Member
  • *****
  • Posts: 2957
    • Home
Re: OpenSSL sign PKCS7
« Reply #7 on: January 10, 2019, 08:19:46 pm »
Hi again, now the function PEM_write_bio_PKCS7 is available in trunk of FPC. But I have another problem, calling that line gives me a "Stack Overflow" exception on this line:

Code: Pascal  [Select]
  1. PEM_write_bio_PKCS7(bios, smsg);

Any ideas?

Edit: attached a project that compiles, it requires openssl libraries installed.
« Last Edit: January 10, 2019, 08:34:31 pm by lainz »

silvioprog

  • Newbie
  • Posts: 4
Re: OpenSSL sign PKCS7
« Reply #8 on: January 10, 2019, 09:39:22 pm »
Hi @lainz,

you should use GnuTLS, its API is easier and better documented than OpenSSL one. Take a look at this:

https://www.gnutls.org/manual/html_node/PKCS-7-API.html

we are writing a Pascal binding for GnuTLS:

https://github.com/graemeg/freepascal/tree/master/packages/gnutls

Documentation in HTML, PDF and ePUB:

https://www.gnutls.org/documentation.html

cheers :)

engkin

  • Hero Member
  • *****
  • Posts: 2191
Re: OpenSSL sign PKCS7
« Reply #9 on: January 11, 2019, 05:37:29 am »
Hi again, now the function PEM_write_bio_PKCS7 is available in trunk of FPC. But I have another problem, calling that line gives me a "Stack Overflow" exception on this line:

Code: Pascal  [Select]
  1. PEM_write_bio_PKCS7(bios, smsg);

Any ideas?

Edit: attached a project that compiles, it requires openssl libraries installed.

1st: take the recent openssl file from the trunk, again. Michael corrected the SO error.

2nd: add cdecl to the end of _PKCS7_sign declaration (all these declarations should be corrected, but for your project this alone is enough):
Code: Pascal  [Select]
  1.   _PKCS7_sign : function(signcert:PX509; pkey:PEVP_PKEY; certs:Pstack_st_X509; data:PBIO; flags:longint):PPKCS7; cdecl;

3rd: there are a few typos regarding pointers in your code, and PKCS7_NOATTR is $100:
Code: Pascal  [Select]
  1. function _FirmarLoginTicketRequest(cuit, nombre, key, cert: string): string;
  2. const
  3.   PKCS7_NOATTR =            $100;
  4. var
  5.   s: TStringList;
  6.   cn: string;
  7.   cbuf: string;
  8.   kbuf: string;
  9.   pXml: string;
  10.   bioc, biok, biom, bios: PBIO;
  11.   fc: PX509;
  12.   fk: PEVP_PKEY;
  13.   smsg: PPKCS7;
  14.   buf: string;
  15.   nlen: cInt;
  16. begin
  17.   Result := '';
  18.  
  19.   {$IFDEF AFIP_PRODUCCION}
  20.     cn := 'wsaa';
  21.   {$ELSE}
  22.     cn := 'wsaahomo';
  23.   {$ENDIF}
  24.  
  25.   s := TStringList.Create;
  26.   try
  27.     // REQUEST XML
  28.     s.Text := _GenerarLoginTicketRequest('SERIALNUMBER=CUIT ' + cuit +
  29.       ', CN=' + nombre, 'CN=' + cn + ', O=AFIP, C=AR, SERIALNUMBER=CUIT 33693450239',
  30.       '4325399', DateTimeToISO(now), DateTimeToISO(inchour(now, 12)));
  31.  
  32.     pXml := s.Text;
  33.  
  34.     s.LoadFromFile(cert);
  35.     cbuf := s.Text;
  36.  
  37.     s.LoadFromFile(key);
  38.     kbuf := s.Text;
  39.  
  40.     bioc := BIO_new_mem_buf(@cbuf[1], Length(cbuf));
  41.  
  42.     fc := PEM_read_bio_X509(bioc, nil, nil, nil);
  43.  
  44.     biok := BIO_new_mem_buf(@kbuf[1], Length(kbuf));
  45.  
  46.     fk := PEM_read_bio_PrivateKey(biok, nil, nil, nil);
  47.  
  48.     biom := BIO_new_mem_buf(@pXml[1], Length(pXml));
  49.  
  50.     smsg := PKCS7_sign(fc, fk, nil, biom, PKCS7_NOATTR);
  51.  
  52.     bios := BioNew(BioSMem);
  53.  
  54.     PEM_write_bio_PKCS7(bios, smsg);
  55.  
  56.     SetLength(buf, 4096);
  57.  
  58.     nlen := BIORead(bios, buf, Length(buf));
  59.  
  60.     s.Text := Copy(buf, 0, nlen);
  61.  
  62.     // delete BEGIN PKCS7 -- END PKCS7
  63.     s.Delete(0);
  64.     s.Delete(s.Count - 1);
  65.     Result := s.Text;
  66.   finally
  67.     s.Free;
  68.   end;
  69. end;

The output on my side is:
Quote
MIIGwgYJKoZIhvcNAQcCoIIGszCCBq8CAQExDzANBglghkgBZQMEAgEFADCCAdUG
CSqGSIb3DQEHAaCCAcYEggHCPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0i
VVRGwq04Ij8+DQo8bG9naW5UaWNrZXRSZXF1ZXN0IHZlcnNpb249IjEuMCI+DQo8
aGVhZGVyPg0KICA8c291cmNlPlNFUklBTE5VTUJFUj1DVUlUIDIwMzQ5MjI0MDM5
LCBDTj1MZWFuZHJvIERpYXo8L3NvdXJjZT4NCiAgPGRlc3RpbmF0aW9uPkNOPXdz
YWEsIE89QUZJUCwgQz1BUiwgU0VSSUFMTlVNQkVSPUNVSVQgMzM2OTM0NTAyMzk8
L2Rlc3RpbmF0aW9uPg0KICA8dW5pcXVlSWQ+NDMyNTM5OTwvdW5pcXVlSWQ+DQog
IDxnZW5lcmF0aW9uVGltZT4yMDE5LTAxLTExVDA0OjI4OjI1LjY0MFo8L2dlbmVy
YXRpb25UaW1lPg0KICA8ZXhwaXJhdGlvblRpbWU+MjAxOS0wMS0xMVQxNjoyODoy
NS42NDBaPC9leHBpcmF0aW9uVGltZT4NCjwvaGVhZGVyPg0KPHNlcnZpY2U+d3Nm
ZTwvc2VydmljZT4NCjwvbG9naW5UaWNrZXRSZXF1ZXN0Pg0KoIIDSzCCA0cwggIv
oAMCAQICCCLsCZRcgrd0MA0GCSqGSIb3DQEBDQUAMDgxGjAYBgNVBAMMEUNvbXB1
dGFkb3JlcyBUZXN0MQ0wCwYDVQQKDARBRklQMQswCQYDVQQGEwJBUjAeFw0xOTAx
MDgxMzE5MDVaFw0yMTAxMDcxMzE5MDVaMC0xEDAOBgNVBAMMB0xlYW5kcm8xGTAX
BgNVBAUTEENVSVQgMjAzNDkyMjQwMzkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQDzHvhu1JGut7zM1QjggDiqWhKlr6tFfRlT6kUY8mLwVvPAJPq1fEL1
kJ/TueU2gLg32uJLNHB9nuDSBkjjBKRh5i4jYFzVsOoSrBAuNyhKCkDa+Ky0yLNo
qM6EFwEEX5kDfZwfAL0fQ9SwtxVpABT0Kal8Q+2+jColcZK2/8nx/hP3JhT9iFWq
dTw/vAbxZfNF16f6z6r69+/wnzEgI0+Ny5//XiiC4/If/2tpfpwjUodMa6rMsGyZ
DAqmBp/AGh6xzwESsdMkxgZnZ7AhTHNGW2V+4CHjqT9guGD/93loplGEiyUncgm/
zt+5dSyDUkKbkKZrnDsi1QdLPl3x5ABlAgMBAAGjYDBeMAwGA1UdEwEB/wQCMAAw
HwYDVR0jBBgwFoAUs7LT//3put7eja8RIZzWIH3yT28wHQYDVR0OBBYEFL5SmxMm
Xgm/0R0nOlAjfzbrcaOBMA4GA1UdDwEB/wQEAwIF4DANBgkqhkiG9w0BAQ0FAAOC
AQEAopVCKX+RuCDrhBTsPt0uj273r55mYU50TqZAnxGF3mFFvdj07nqpGVllmn59
Q6k7IiFxu2rlhswh12Mv0RvxyFco7uMmO44pvJ8D1bGAqSfC5m4Hgg62zCSvQAXo
mYCt0pTtYFLrt8f9wMooBThhk/0pYlWce9lK2g1L/HYSXPL3i9MhfKHO2P4HTeNv
vWvNjmeqCSD/9tMi3/UtvC2VEyhDrLJ4zQgafz6CEQVgsdOPujrB2bYeNWdpkwhL
lmPPV9rp9LmAwk9XtCAPMjFF120w0LGAu7zl6YS7qKGey7C2RrnMcLLn5cn13qMF
eEy4vt/NOKky3k3chjQbZbHbwDGCAW8wggFrAgEBMEQwODEaMBgGA1UEAwwRQ29t
cHV0YWRvcmVzIFRlc3QxDTALBgNVBAoMBEFGSVAxCzAJBgNVBAYTAkFSAggi7AmU
XIK3dDANBglghkgBZQMEAgEFADANBgkqhkiG9w0BAQEFAASCAQASl2nLYUe5O7L/
GcEwlrdX1bOrDcW4xSzBC8Z/TQxh07qzMwUXt1Ycb5hF8ehUlKP/b7YXT2Xny3QV
hOQVBFCKsw8IgmRyTiiJ3PkPJuo0hQRomzNJfh3qPNxKdO9SQqgbwyKjhzkS0m5g
UQsqHf8HdO8jNMpbNtRumWiodfr/pqiuVzeKN4tB94Kom3+il1AyIYVLhTUk5rl6
YSVWw56vKc5WsGB2Jd47x58uOdPNK9m0KUbx1OWLQDbCViFwdr2db5Q/jPDLnjpo
bsvy7uy8hkvyfF2lKO4PIqNOF+M33Cyy0PnfqXXgW2NuWHOWh2C/ellnE46fTS1K
lzSSbvxr

lainz

  • Hero Member
  • *****
  • Posts: 2957
    • Home
Re: OpenSSL sign PKCS7
« Reply #10 on: January 11, 2019, 04:06:37 pm »
Thanks I will try it today.

engkin

  • Hero Member
  • *****
  • Posts: 2191
Re: OpenSSL sign PKCS7
« Reply #11 on: January 11, 2019, 07:17:50 pm »
Don't forget to open your bug report to correct the missing cdecl.

lainz

  • Hero Member
  • *****
  • Posts: 2957
    • Home
Re: OpenSSL sign PKCS7
« Reply #12 on: January 11, 2019, 08:36:13 pm »
Don't forget to open your bug report to correct the missing cdecl.

Done. Thankyou now it works even works sending the data to the server  :)