EldoS | Feel safer!

Software components for data protection, secure storage and transfer

TElECDSAPublicKeyCrypto.EncodeSignature too short ASN.1

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.
#32459
Posted: 03/04/2015 04:50:09
by Tomasz Koltoniak (Basic support level)
Joined: 03/04/2015
Posts: 2

Hello Eldos,

we would like to use SecureBlackBox for verifying ECDSA-signatures.
We use the version SecBBoxVCL_D2005to2007 of SecureBlackBox for testing.

I try to encode the Signature as ASN.1 and then to verify a test-string using correspondent certificate.
But it doesn't work, because of wrong ASN.1-encoding.

This are the data i use:
- The Teststring is 1234567890abcd
- The Signature is generated with a PKCS#11-dll and a TeleSec NetKey 3.0 signaturecard.
The PKCS#11-mechanism is CKM_ECDSA_SHA1.
Return value of PKCS#11-C_Verify is for this signature ok.
- X.509-certificate from the signaturecard as a *.cert file.

This is my code:
Code
procedure TVerifySignaturBlackBox.verifySignatur;
var
  DataString: String;
  DataBuffer: PChar;

  SignatureFile: File;
  SignatureFileSize: integer;
  SignatureBuffer: array of byte;
  SignaturHex: String;

  lElECDSAPublicKeyCrypto: TElECDSAPublicKeyCrypto;

  rBuffer: PChar;
  sBuffer: PChar;
  rBufferLen: integer;
  sBufferLen: integer;

  SignatureASN1Buff: Array of byte;
  SignatureASN1BuffLen: integer;

  lElX509Certificate: TElX509CertificateEx;
  lElECKeyMaterial: TElECKeyMaterial;
  lSBPublicKeyVerificationResult: TSBPublicKeyVerificationResult;

  CertFile: File;
  CertFileSize: integer;
  CertBuffer: array of byte;

begin
  CertBuffer := nil;

  SetLicenseKey( '...');

  lElX509Certificate := TElX509CertificateEx.Create(nil);
  lElECKeyMaterial := TElECKeyMaterial.Create();
  lElECDSAPublicKeyCrypto := TElECDSAPublicKeyCrypto.Create(SB_CERT_ALGORITHM_SHA1_ECDSA);
  try

    DataString := '1234567890abcd';
    DataBuffer := PChar(DataString);

    rBufferLen := 32;
    sBufferLen := 32;
    GetMem(rBuffer, 32);
    GetMem(sBuffer, 32);

    lElECDSAPublicKeyCrypto := TElECDSAPublicKeyCrypto.Create(SB_CERT_ALGORITHM_SHA1_ECDSA);

    //read signature from file
    AssignFile(SignatureFile, 'D:/Temp/SignatureTest/SignaturTest.bin');
    Reset(SignatureFile, 1);
    SignatureFileSize := FileSize(SignatureFile);
    SetLength(SignatureBuffer, SignatureFileSize);
    BlockRead(SignatureFile, SignatureBuffer[0], Length(SignatureBuffer));

    Move(SignatureBuffer[0], rBuffer[0], 32);
    Move(SignatureBuffer[32], sBuffer[0], 32);
    SignatureASN1BuffLen := 0;

    //encoding ASN.1
    lElECDSAPublicKeyCrypto.EncodeSignature(rBuffer, rBufferLen, sBuffer, sBufferLen, SignatureASN1Buff,

SignatureASN1BuffLen);
    SetLength(SignatureASN1Buff, SignatureASN1BuffLen);
    lElECDSAPublicKeyCrypto.EncodeSignature(rBuffer, rBufferLen, sBuffer, sBufferLen, SignatureASN1Buff,

SignatureASN1BuffLen);


    //read certificate from file
    AssignFile(CertFile, 'd:/Temp/SignatureTest/TEST-PCA12.crt');
    Reset(CertFile, 1);
    CertFileSize := FileSize(CertFile);
    SetLength(CertBuffer, CertFileSize);
    BlockRead(CertFile, CertBuffer[0], Length(CertBuffer));

    //verifying
    lElX509Certificate.LoadFromBuffer(CertBuffer, CertFileSize);
    lElECDSAPublicKeyCrypto.KeyMaterial := lElX509Certificate.KeyMaterial;
    if lElECDSAPublicKeyCrypto.KeyMaterial.PublicKey then begin
      lSBPublicKeyVerificationResult :=
        lElECDSAPublicKeyCrypto.VerifyDetached( DataBuffer, Length(DataBuffer), SignatureASN1Buff,

SignatureASN1BuffLen );
    end;

  finally
    FreeMem(CertBuffer);
    FreeMem(rBuffer);
    FreeMem(sBuffer);

    lElECDSAPublicKeyCrypto.Destroy;
    lElECKeyMaterial.Destroy;
    lElX509Certificate.Destroy;
  end;

end;


-> the verification fails, lSBPublicKeyVerificationResult is pkvrInvalidSignature.

I can recognise, that SignatureASN1Buff ist too short.

The hex-string of the signature is:
EFDC124A4D62A6CCCB813085814577CAFF31D367169176657C280A5B4C6B6851
1D976F018BC92FF3C4DC067D3738ADF1C0C71178ECA8F94D790BDD8E3571190D

The hex-string of SignatureASN1Buff is;
3045
022100
EFDC124A4D62A6CCCB813085814577CAFF31D367169176657C280A5B4C6B6851
0220
1D976F018BC92FF3C4DC067D3738ADF1C0C71178ECA8F94D79

The hex-string of the signature, ASN.1-encoded in Java, is:
304502
2100
EFDC124A4D62A6CCCB813085814577CAFF31D367169176657C280A5B4C6B6851
0220
1D976F018BC92FF3C4DC067D3738ADF1C0C71178ECA8F94D790BDD8E3571190D

Have you an idea, what my failure is?

Thank you in advance,
Tomasz.
#32466
Posted: 03/04/2015 05:23:25
by Ken Ivanov (EldoS Corp.)

Hi Tomasz,

Thank you for contacting us.

What is weird here is that your ASN.1 signature seems to have been truncated *after* it was produced by the TElECDSAPublicKeyCrypto object (as the ASN.1 structure itself is correct, it's only the last 7 bytes that went missing - and SecureBlackbox ASN.1 writer just can't generate structures with errors like that due to specific of its implementation).

Could you please run the following simplified code and check if the generated ASN.1 structure is subject to the same issue:

Code
program ECDSASigFmt;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  SBTypes,
  SBUtils,
  SBStrUtils,
  SBPublicKeyCrypto;

const
  SigR : array[0..31] of byte = (
    $EF, $DC, $12, $4A, $4D, $62, $A6, $CC, $CB, $81, $30, $85, $81, $45, $77,
    $CA, $FF, $31, $D3, $67, $16, $91, $76, $65, $7C, $28, $0A, $5B, $4C, $6B,
    $68, $51
  );
  SigS : array[0..31] of byte = (
    $1D, $97, $6F, $01, $8B, $C9, $2F, $F3, $C4, $DC, $06, $7D, $37, $38, $AD,
    $F1, $C0, $C7, $11, $78, $EC, $A8, $F9, $4D, $79, $0B, $DD, $8E, $35, $71,
    $19, $0D
  );

var
  Crypto : TElECDSAPublicKeyCrypto;
  SigSize : integer;
  Sig : ByteArray;
begin
  try
    Crypto := TElECDSAPublicKeyCrypto.Create();
    try
      SigSize := 0;
      Crypto.EncodeSignature(@SigR[0], Length(SigR), @SigS[0], Length(SigS),
        nil, SigSize);
      SetLength(Sig, SigSize);
      Crypto.EncodeSignature(@SigR[0], Length(SigR), @SigS[0], Length(SigS),
        @Sig[0], SigSize);
      Writeln(BinaryToString(@Sig[0], SigSize));
    finally
      FreeAndNil(Crypto);
    end;

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.


Cheers,

Ken
#32475
Posted: 03/04/2015 06:57:52
by Tomasz Koltoniak (Basic support level)
Joined: 03/04/2015
Posts: 2

Hello Ken,

thank you, asn.1 encoding works.
I use now ByteArray for the signature buffer.

Unfortunately, the result of TElECDSAPublicKeyCrypto.VerifyDetached is still pkvrInvalidSignature.
Is my usage of TElECDSAPublicKeyCrypto not ok?
(The signature must be ok - is verified by c_verify from the PKCS#11-dll)

regards,
Tomasz
#32477
Posted: 03/04/2015 07:58:08
by Ken Ivanov (EldoS Corp.)

Tomasz,

Could you please post your certificate to the Helpdesk (I've created a ticket for you, you should receive an e-mail notification shortly) so that we could try to reproduce the issue locally?

Thanks,

Ken

Reply

Statistics

Topic viewed 680 times

Number of guests: 1, 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!