EldoS | Feel safer!

Software components for data protection, secure storage and transfer

CMS signer

Also by EldoS: CallbackDisk
Create virtual disks backed by memory or custom location, expose disk images as disks and more.
#9842
Posted: 04/28/2009 03:02:07
by delagoutte jean (Standard support level)
Joined: 04/02/2009
Posts: 34

Hi,
until now, i'm using elMessageSigner form signing files in PKCS7 but my sig file is not be compatible with a third product signer/verifier.
I just learn the third product sign format is a CMS detached.
Is there an option to use this format with elmessagesigner ? or does exists a cms signer ? i don't see this in the SBB toolbar(i'm using delphi)
Is there some exemple more than the cms manager in the sample diectory ?

Second question :
How can i determine the format for verify my sig file ? until now, i use elMessageVerifier but maybe is there a cms verifier ?
#9843
Posted: 04/28/2009 05:51:06
by Ken Ivanov (EldoS Corp.)

Thank you for contacting us.

Quote
i'm using elMessageSigner form signing files in PKCS7 but my sig file is not be compatible with a third product signer/verifier.

Can you please provide the details of incompatibility?

Quote
I just learn the third product sign format is a CMS detached.
Is there an option to use this format with elmessagesigner ?

Please try setting the Detached parameter of TElMessageSigner.Sign() method to true and check if it helps.

Quote
or does exists a cms signer ? i don't see this in the SBB toolbar(i'm using delphi)

TElMessageSigner is a high-level easy-to-use component that creates signatures compatible with the CMS specification. SBCMS unit contains a set of low-level (though still easy-to-use ;) ) CMS components that provide more flexible access to signature management. If you need just to sign some data and optionally attach a timestamp to it, use TElMessageSigner.

Quote
How can i determine the format for verify my sig file ?

Which exactly formats do you need to distinguish? If you just need to check if the signature is a valid CMS message, simply pass it for validation to TElMessageVerifier.Verify() method.
#9845
Posted: 04/28/2009 06:45:11
by delagoutte jean (Standard support level)
Joined: 04/02/2009
Posts: 34

Quote
Please try setting the Detached parameter of TElMessageSigner.Sign() method to true and check if it helps.

I think i use it, but maybe it's not good.
My code :
var
inbuf,outbuf: array of byte;//inbuf : doc to sign, outbuf : sig file
...
ElMessageSigner1.Sign(@InBuf[0], Length(InBuf), nil, Sz);
SetLength(OutBuf, Sz);
I := ElMessageSigner1.Sign(@InBuf[0], Length(InBuf), @OutBuf[0], Sz,true);
if I = 0 then
begin
...

Quote
TElMessageSigner is a high-level easy-to-use component that creates signatures compatible with the CMS specification. SBCMS unit contains a set of low-level (though still easy-to-use ;) ) CMS components that provide more flexible access to signature management. If you need just to sign some data and optionally attach a timestamp to it, use TElMessageSigner.

the third product generate CMS detached RFC 2630, i wan't sign like there.
I need sign file with TSP attributes and OCSP Attributes. for this thing it's seems to be ok
You already help me for that :
http://www.eldos.com/forum/read.php?FID=7&TID=1716
I must include the chain of certificat.

After i need to have more than only one signer. can i do this with elMessageSigner ?

Quote
Can you please provide the details of incompatibility?

* When i analyze my sig file and the sig file producted by the third product i see some différence :
in my sig file i have a attribute "MessageDigest "(OID : 1.2.840.113549.1.9.4) This attribute don't exists in the other sig file but when i verify there sig file, it is ok.the digest may be include but i don't know where ?
* In there sig file, there is the certificat signer and the chain certificate.
In my sig file there only the certificat signer. if i add the chain certificat the third product can't read my sig file(without the the chain it can read but it said me it's not valide)
* I include in my sig file a tsp attribute but the third party can't read it and said me it's not timestamped. i see one difference the hash algorythme used by TSP server. I don't find if i can specify the hash to use from the the tspclient.

Quote
Which exactly formats do you need to distinguish? If you just need to check if the signature is a valid CMS message, simply pass it for validation to TElMessageVerifier.Verify() method.

I see CMS is an evolution of PKCS7. i wan't to know if my sign file is a "simple" pkcs7 or a cms.
With Elmessage verifier i think i don't have problem, i can read the tsp response and ocsp response and certificate included but i can't read this little différence between pkcs7 and cms

Thanks for your help.
#9848
Posted: 04/28/2009 08:30:18
by Ken Ivanov (EldoS Corp.)

Quote
the third product generate CMS detached RFC 2630, i wan't sign like there.
I need sign file with TSP attributes and OCSP Attributes. for this thing it's seems to be ok

Then it would be easier for you to use low-level CMS components. Please see the CMSManager sample as a guide; it performs all the tasks you mentioned (OCSP and TSP management).

Quote
After i need to have more than only one signer. can i do this with elMessageSigner ?

Yes, it is possible.

Quote
in my sig file i have a attribute "MessageDigest "(OID : 1.2.840.113549.1.9.4) This attribute don't exists in the other sig file but when i verify there sig file, it is ok.the digest may be include but i don't know where ?

Message digest attribute can be omitted if no authenticated attributes are included to the signature.

Quote
In there sig file, there is the certificat signer and the chain certificate.
In my sig file there only the certificat signer. if i add the chain certificat the third product can't read my sig file(without the the chain it can read but it said me it's not valide)

How exactly do you add the chain? All the certificates should just be put to the same CertStorage where the signer's certificate is put (i.e., the one pointed to by the TElMessageSigner.CertStorage property).

Quote
* I include in my sig file a tsp attribute but the third party can't read it and said me it's not timestamped. i see one difference the hash algorythme used by TSP server. I don't find if i can specify the hash to use from the the tspclient.

Please use TElHTTPSClient.HashAlgorithm property (along with SB_ALGORITHM_DGST_xxx constants declared in the SBConstants unit).

Quote
I see CMS is an evolution of PKCS7. i wan't to know if my sign file is a "simple" pkcs7 or a cms.
With Elmessage verifier i think i don't have problem, i can read the tsp response and ocsp response and certificate included but i can't read this little différence between pkcs7 and cms

Not exactly. PKCS#7 is a kind of framework. CMS is a kind of skin pulled on that framework. In other words, PKCS#7 is a "class" and CMS is an "object of that class". That's why each CMS message is a valid PKCS#7 message (but not vice versa, -- for instance, PKCS#7 knows nothing about message digest attribute). SecureBlackbox always operates with CMS messages.
#9851
Posted: 04/29/2009 02:43:20
by delagoutte jean (Standard support level)
Joined: 04/02/2009
Posts: 34

Quote
Then it would be easier for you to use low-level CMS components. Please see the CMSManager sample as a guide; it performs all the tasks you mentioned (OCSP and TSP management).

I think i use it. I have some question for verify i understand.
If i want sign a file i must do :
- Create TElSignedCMSMessage
- specify the file/data to sign with TElSignedCMSMessage(CMS).Content.Init(...)
- sign or add sign to the TElSignedCMSMessage
- for this sign TElCMSSignature i add the ocsp response and the time stamp
- save TElSignedCMSMessage

Is it correct ?

Quote
How exactly do you add the chain? All the certificates should just be put to the same CertStorage where the signer's certificate is put (i.e., the one pointed to by the TElMessageSigner.CertStorage property).

Fo construct the chain i use this code :
acert = the certificat that will sign

ElMessageSigner1.CertStorage:=ElMemoryCertStorage1;
...
WinCertStorage:= TElWinCertStorage.Create(nil);
WinCertStorage.SystemStores.Add('CA');
acertTemp:=acert;
while WinCertStorage.GetIssuerCertificate(aCerttemp)<>-1 do
begin
i:= WinCertStorage.GetIssuerCertificate(aCertTemp);
acerttemp:=WinCertStorage.Certificates[i];
issuerStorage.Add(aCertTemp);
ElMemoryCertStorage1.Add(acerttemp);
end;
ElMemoryCertStorage1.Add(acert);

in ElMemoryCertStorage1 i have my cert and her issuer and issuer of issuer ...
in issuerStorage i have the same thing without aCert i use it for
OCSP
MemoryCertStorageToverify:=TElMemoryCertStorage.Create(nil);
MemoryCertStorageToverify.Options:=[csoStrictChainBuilding];
MemoryCertStorageToverify.Clear;
MemoryCertStorageToverify.Add(aCert);
HTTPOCSPClient.IssuerCertStorage:=IssuerStorage;
HTTPOCSPClient.CertStorage:=MemoryCertStorageToverify;
...
#9852
Posted: 04/29/2009 03:11:25
by Ken Ivanov (EldoS Corp.)

Quote
If i want sign a file i must do :
...<skipped>...
Is it correct ?

In general, yes. Besides, you can add timestamps and/or OCSP data to the existing signature after loading it into TElSignedCMSMessage.

Quote
Fo construct the chain i use this code :

The code seems to be correct. Which exactly problems does your partner encounter when reading the message created in such way?
#9874
Posted: 04/30/2009 03:55:23
by delagoutte jean (Standard support level)
Joined: 04/02/2009
Posts: 34

Quote
The code seems to be correct. Which exactly problems does your partner encounter when reading the message created in such way?

I had no error message but i can't load the file for verified the sign.

I don't have this problem with cms

With cms i always a no valid sign (for this third product). I think I am wrong for the différents settings. i think you can help me.

I have many specifications about the sig format of the third party.
1- the sign file is CMS detached accordance RFC2630
For this i use
Code
CMSMessage := TElSignedCMSMessage.Create(nil);
CMSMessage.Detached:=True;

after i verify if a sign file already exists :
if not exsits : (afile : string = file to sign)
Code
DataStream := TFileStream.Create(aFile, fmOpenRead);
CMSMessage.CreateNew(@afile[1], Length(afile));
CMSMessage.Content.Init(DataStream, 0, DataStream.Size);

if exists :(FileSigName : string is the name of sign file)
Code
CMSStream := TFileStream.Create(FileSigName, fmOpenRead);
CMSMessage.Open(CMSStream, nil);


2- algorithme for sign must be RSA with digest SHA1
Code
var Sig : TElCMSSignature
...
sig.DigestAlgorithm :=SB_ALGORITHM_DGST_SHA1;
Sig.Sign(Cert, Chain);

I think i forgot something how can i specify RSA ?

3- Token timestamp accordance RFC3161 sign with key RSA 2048 bits that contains the digest SHA1 of document.attrtype must be "id-smime-aa-timeStampToken" and OID 1.2.840.113549.1.9.16.2.14 :

Code
TSPCli.HTTPClient := HTTPCli;
TSPCli.URL := fTSPURL;
TSPCli.HashAlgorithm:=  SB_ALGORITHM_DGST_SHA1;
if pos('https://',TSPCli.URL)>0 then
  HTTPCli.SSLEnabled:=true
else
  HTTPCli.SSLEnabled:=false;
Sig.AddTimestamp(TSPCli);

like for point 2, i think i'm wrong

4- contain a Basic OCSP Response accordance RFC 2560 with attrType "Basic OCSP Response" and OID : 1.3.6.1.5.5.7.48.1.1
Code
HTTPOCSPClient:= TElHTTPOCSPClient.Create(nil);
HTTPOCSPClient.URL:=fOCSPUrl;
HTTPSClient2:= TElHTTPSClient.Create(nil);
HTTPSClient2.UseCompression:=false;
HTTPOCSPClient.HTTPClient:=HTTPSClient2;
if pos('https://',HTTPOCSPClient.URL)>0 then
  HTTPSClient2.SSLEnabled:=true
else
  HTTPSClient2.SSLEnabled:=false;
  HTTPOCSPClient.CertStorage:=MemoryCertStorageToverify;
  HTTPOCSPClient.IssuerCertStorage:=IssuerStorage;
resocsp := HTTPOCSPClient.PerformRequest(ServeroCSPResult,ReplyOcsp);

It's only the code for having the OCSP Response, idon't already work for adding this response to the signature.

5 - The sig file was encoded in base64:
Code
try
  //Saving CMS Message to file
  CMSStream := TFileStream.Create(FileSigName, fmCreate);
  try
    CMSMessage.Save(CMSStream);
  finally
    FreeAndNil(CMSStream);
  end;
  //Load Sig file not encoded
  AssignFile(F, FileSigName);
  Reset(F, 1);
  SetLength(OutBuf, FileSize(F));
  BlockRead(F, OutBuf[0], Length(OutBuf));
  CloseFile(F);

  //Encoded in Base64
  PEMProc:= TelPEMProcessor.Create(nil);
  PEMProc.Header:='PKCS7';
  PEMProc.PEMEncode(byteArray(OutBuf),ByteArray(FBase64),false);
  //save encoded file base64
  AssignFile(F, FileSigName);
  Rewrite(F, 1);
  BlockWrite(F, FBase64[0],length(FBase64));
  CloseFile(F);
finally
  freeandNil(PEMPROC);
end;

I think it's not the more easy solution but it's seems working.

Could you say me where i'm wrong and what i have forget ?
#9880
Posted: 04/30/2009 14:27:41
by Ken Ivanov (EldoS Corp.)

1) You are loading the message correctly,
2) You do not have to specify RSA explicitly. Signing public key algorithm is chosen automatically basing on private key algorithm.
3) You are adding the timestamp correctly,
4) OCSP retrieval seems to be correct. Please use the sample as a guide of adding OCSP information,
5) Encoding in Base64 also seems to be correct.
#9917
Posted: 05/05/2009 10:21:14
by delagoutte jean (Standard support level)
Joined: 04/02/2009
Posts: 34

Code
procedure TSignCMS.AddOCSP(Sig : TElCMSSignature; Cert : TElX509Certificate);
var
  OCSPCli : TElHTTPOCSPClient;
  HTTPCli : TElHTTPSClient;
  Chain,CertToVerif : TElMemoryCertStorage;
  ServerOCSPResult: TElOCSPServerError;
  ReplyOCsp : ByteArray;
  resocsp: Integer;
  OCSP : TList;
  CrlStorage : TElMemoryCRLStorage;
begin
  try

    CrlStorage := TElMemoryCRLStorage.Create(nil);
    OCSP := TList.Create;
    Chain := TElMemoryCertStorage.Create(nil);
    CertToVerif:= TElMemoryCertStorage.Create(nil);
    CertToVerif.Add(Cert);
    ConstructeChain(Cert,false,chain);
    OCSPCli := TElHTTPOCSPClient.Create(nil);
    OCSPCli.URL:=fOCSPURL;
    HTTPCli:= TElHTTPSClient.Create(nil);
    HTTPCli.UseCompression:=false;
    if pos('https://',OCSPCli.URL)>0 then
      HTTPCli.SSLEnabled:=true
    else
      HTTPCli.SSLEnabled:=false;
    OCSPCli.HTTPClient:=HTTPCli;
    OCSPCli.CertStorage:=CertToVerif;
    OCSPCli.IssuerCertStorage:=chain;
    resocsp := OCSPCli.PerformRequest(ServeroCSPResult,ReplyOcsp);
    OCSP.Add(OCSPCli.Response);
    Sig.AddCompleteValidationData(chain, CrlStorage, OCSP, false);
  finally
    freeandnil(OCSPCli);
    if Chain <> nil then
        FreeAndNil(Chain);
    if CertToVerif <> nil then
      FreeAndNil(CertToVerif);
    FreeAndNil(OCSP);
     FreeAndNil(CrlStorage);
  end;
end;



I'm not sure i must use AddCompleteValidationData for adding my ocsp response But i don't know the fonction for do it.
I must have an error because i can't read the OCSP attribute with my elmessageverifier.

I use this for reading the ocsp :
Code
Function GetOcsp(Attr : TElMessageVerifier):String;
  var i,J : integer;
      OCSPResp : TElOCSPResponse;
      OCSPRespData : String;
      V : TSBCMSSignatureValidity;
  begin
    result:='---------------OCSP-----------------'+#13#10+
            '--SERVEUR DE VALIDITE DE CERTIFICAT-'+#13#10 ;
    for i :=0 to attr.Attributes.Count-1 do
    begin
     if attr.Attributes.Attributes[i]=SB_OCSP_OID_BASIC_RESPONSE then
     begin
       try
        OCSPRespData:= Attr.Attributes.Values[i][0];
        OCSPResp := TElOCSPResponse.create;
        OCSPResp.Load(@OcspRespData[1],length(OcspRespData));
        v:=Ocspresp.Validate;
        case V of
          csvValid : result:=result+'Le format OCSP est Valide'+#13#10;
          csvInvalid : result:=result+ 'Le format OCSP est Invalide'+#13#10;
          csvSignerNotFound : result:=result+ 'Le signataire de la r&#233;ponse OCSP est introuvable'+#13#10;
          csvGeneralFailure : result:=result+ 'Erreur de lecture de la r&#233;ponse OCSP'+#13#10;
        end;
        for J := 0 to Ocspresp.ResponseCount - 1 do
        begin
          case Ocspresp.Responses[J].CertStatus of
          csGood : result:=result+ 'Le certificat &#233;tait bon au moment de la signature'+#13#10;
          csRevoked : result:=result+ 'Le certificat &#233;tait r&#233;voqu&#233; au moment de la signature'+#13#10;
          csUnknown : result:=result+ 'La validit&#233; du certificat au moment de la signature n''a pu &#234;tre d&#233;termin&#233;'+#13#10;
          end;
        end;
        result:=result+WriteCertificateInfo(OCSPResp.Certificates);


       finally
         OCSPResp.Free;

       end;
     end;
  //   result:=oidtostr(attr.Attributes.Values[i].Text);
    // result:='trouv&#233;';
    end;
    if result='' then
      result:='Pas de r&#233;ponse OCSP incluse dans la signature';
    result:=result+#13#10;
  end;


Can you say me if it's correct code for adding ocsp to my cms message?
#9920
Posted: 05/05/2009 12:18:36
by Ken Ivanov (EldoS Corp.)

OCSP responses that are added to the signature via the AddCompleteValidationData() call are saved as a set of special attributes defined in CAdES specification, in particular RevocationRefs and RevocationValues. Besides OCSP responses, those attributes also contain revocation information of other kinds, such as CRLs. Thus, those attributes are not compatible with basic OCSP response attribute you expect to get (due to separate attribute OIDs first of all).

It is important to clarify, which exactly OCSP format is understood by the software you need to communicate with. If it's the format you are trying to read in your code (basic OCSP response stored under SB_OCSP_OID_BASIC_RESPONSE attribute), then please add the response to the signature using CustomSignedAttributes or CustomUnsignedAttributes properties.
Also by EldoS: CallbackDisk
Create virtual disks backed by memory or custom location, expose disk images as disks and more.

Reply

Statistics

Topic viewed 7987 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!