DataFlex
DataFlex
CADES-BES Signature using ePass2003 Token
See more Egypt ITIDA Examples
Demonstrates using a certificate and private key located on an ePass2003 USB token to create a CADES-BES signature.(Demonstrates how to create a .p7s signature that fits Egypt's ITIDA requirements where Chilkat automatically does the ITIDA JSON canonicalization.)
Chilkat DataFlex Downloads
Use ChilkatAx-win32.pkg
Procedure Test
Boolean iSuccess
Handle hoScmd
String sReaderName
Integer iRetval
String sCertPart
String sPartValue
Variant vCert
Handle hoCert
Handle hoCrypt
Handle hoCmsOptions
SigningAttrs Handle hoJsonSigningAttrs
Handle hoJson
String sSigBase64
String sTemp1
Boolean bTemp1
Move False To iSuccess
// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
Get Create (RefClass(cComChilkatScMinidriver)) To hoScmd
If (Not(IsComObjectCreated(hoScmd))) Begin
Send CreateComObject of hoScmd
End
// Reader names (smart card readers or USB tokens) can be discovered
// via List Readers or Find Smart Cards
Move "FS USB Token 0" To sReaderName
Get ComAcquireContext Of hoScmd sReaderName To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoScmd To sTemp1
Showln sTemp1
Procedure_Return
End
// If successful, the name of the currently inserted smart card is available:
Get ComCardName Of hoScmd To sTemp1
Showln "Card name: " sTemp1
// If desired, perform regular PIN authentication with the smartcard.
// For more details about smart card PIN authentication, see the Smart Card PIN Authentication Example
Get ComPinAuthenticate Of hoScmd "user" "12345678" To iRetval
If (iRetval <> 0) Begin
Showln "PIN Authentication failed."
End
// You can find a cerficate using any of the following certificate parts:
// "subjectDN" -- The full distinguished name of the cert.
// "subjectDN_withTags" -- Same as above, but in a format that includes the subject part tags, such as the "CN=" in "CN=something"
// "subjectCN" -- The common name part (CN) of the certificate's subject.
// "serial" -- The certificate serial number.
// "serial:issuerCN" -- The certificate serial number + the issuer's common name, delimited with a colon char.
// These are the same certificate parts that can be retrieved by listing certificates on the smart card (or USB token).
// See List Certificates on Smart Card Example
Move "subjectCN" To sCertPart
Move "Matt" To sPartValue
// If the certificate is found, it is loaded into the cert object.
// Note: We imported this certificate from a .p12/.pfx using code such as this Example to Import a .pfx/.p12 onto a Smart Card
Get Create (RefClass(cComChilkatCert)) To hoCert
If (Not(IsComObjectCreated(hoCert))) Begin
Send CreateComObject of hoCert
End
Get pvComObject of hoCert to vCert
Get ComFindCert Of hoScmd sCertPart sPartValue vCert To iSuccess
If (iSuccess = False) Begin
Showln "Failed to find the certificate."
Get ComDeleteContext Of hoScmd To iSuccess
Procedure_Return
End
Showln "Successfully loaded the cert object from the smart card / USB token."
// Note: When successful, the cert object is internally linked to the ScMinidriver object's authenticated session.
// The cert object can now be used to sign or do other cryptographic operations that occur on the smart card / USB token.
// If your application calls PinDeauthenticate or DeleteContext, the cert will no longer be able to sign on the smart card
// because the smart card ScMinidriver session will no longer be authenticated or deleted.
// ------------------------------------------------------------------------------------------------------------
// Here we have to code to create the CADES-BES signature using Chilkat Crypt2..
Get Create (RefClass(cComChilkatCrypt2)) To hoCrypt
If (Not(IsComObjectCreated(hoCrypt))) Begin
Send CreateComObject of hoCrypt
End
// Tell the crypt class to use the cert on the ePass2003 token.
Get pvComObject of hoCert to vCert
Get ComSetSigningCert Of hoCrypt vCert To iSuccess
If (iSuccess <> True) Begin
Get ComLastErrorText Of hoCrypt To sTemp1
Showln sTemp1
Procedure_Return
End
Get Create (RefClass(cComChilkatJsonObject)) To hoCmsOptions
If (Not(IsComObjectCreated(hoCmsOptions))) Begin
Send CreateComObject of hoCmsOptions
End
// Setting "DigestData" causes OID 1.2.840.113549.1.7.5 (digestData) to be used.
Get ComUpdateBool Of hoCmsOptions "DigestData" True To iSuccess
Get ComUpdateBool Of hoCmsOptions "OmitAlgorithmIdNull" True To iSuccess
// Indicate that we are passing normal JSON and we want Chilkat do automatically
// do the ITIDA JSON canonicalization:
Get ComUpdateBool Of hoCmsOptions "CanonicalizeITIDA" True To iSuccess
Get ComEmit Of hoCmsOptions To sTemp1
Set ComCmsOptions Of hoCrypt To sTemp1
// The CadesEnabled property applies to all methods that create CMS/PKCS7 signatures.
// To create a CAdES-BES signature, set this property equal to true.
Set ComCadesEnabled Of hoCrypt To True
Set ComHashAlgorithm Of hoCrypt To "sha256"
Get Create (RefClass(cComChilkatJsonObject)) To hoJsonSigningAttrs
If (Not(IsComObjectCreated(hoJsonSigningAttrs))) Begin
Send CreateComObject of hoJsonSigningAttrs
End
Get ComUpdateInt Of hoJsonSigningAttrs "contentType" 1 To iSuccess
Get ComUpdateInt Of hoJsonSigningAttrs "signingTime" 1 To iSuccess
Get ComUpdateInt Of hoJsonSigningAttrs "messageDigest" 1 To iSuccess
Get ComUpdateInt Of hoJsonSigningAttrs "signingCertificateV2" 1 To iSuccess
Get ComEmit Of hoJsonSigningAttrs To sTemp1
Set ComSigningAttributes Of hoCrypt To sTemp1
// By default, all the certs in the chain of authentication are included in the signature.
// If desired, we can choose to only include the signing certificate:
Set ComIncludeCertChain Of hoCrypt To False
// Pass a JSON document such as the following. Chilkat will do the ITIDA canonicalization.
// (It is the canonicalized JSON that gets signed.)
// {
// "issuer":{
// "address":{
// "branchID":"0",
// "country":"EG",
// "regionCity":"Cairo",
// "postalCode":"",
// "buildingNumber":"0",
// "street":"123rd Street",
// "governate":"GOVERNATE"
// },
// "type":"B",
// "id":"209999899",
// "name":"Xyz SAE"
// },
// "receiver":{
// "address":{
// "country":"EG",
// "regionCity":"CAIRO",
// "postalCode":"11435",
// "buildingNumber":"0",
// "street":"Autostrad Road Abc",
// "governate":"GOVERNATE"
// },
// "type":"B",
// "id":"999999999",
// "name":"XYZ EGYPT FOR TRADE"
// },
// "documentType":"I",
// "documentTypeVersion":"1.0",
// "dateTimeIssued":"2020-11-15T11:04:53Z",
// "taxpayerActivityCode":"1073",
// "internalID":"ZZZZ999",
// "purchaseOrderReference":"2009199918",
// "salesOrderReference":"",
// "payment":{
// "bankName":"",
// "bankAddress":"",
// "bankAccountNo":"",
// "bankAccountIBAN":"",
// "swiftCode":"",
// "terms":""
// },
// "delivery":{
// "approach":"",
// "packaging":"",
// "dateValidity":"",
// "exportPort":"",
// "countryOfOrigin":"EG",
// "grossWeight":0,
// "netWeight":0,
// "terms":""
// },
// "invoiceLines":[
// {
// "description":"CDM Widget 48GX99X12BA",
// "itemType":"GS1",
// "itemCode":"7622213335056",
// "unitType":"CS",
// "quantity":1.00,
// "unitValue":{
// "currencySold":"EGP",
// "amountEGP":588.67,
// "amountSold":0,
// "currencyExchangeRate":0
// },
// "salesTotal":588.67,
// "total":603.97,
// "valueDifference":0,
// "totalTaxableFees":0,
// "netTotal":529.8,
// "itemsDiscount":0,
// "discount":{
// "rate":10.00,
// "amount":58.87
// },
// "taxableItems":[
// {
// "taxType":"T1",
// "amount":74.17,
// "subType":"No sub",
// "rate":14.00
// }
// ],
// "internalCode":"9099994"
// }
// ],
// "totalSales":588.67,
// "totalSalesAmount":588.67,
// "totalDiscountAmount":58.87,
// "netAmount":529.80,
// "taxTotals":[
// {
// "taxType":"T1",
// "amount":74.17
// }
// ],
// "extraDiscountAmount":0,
// "totalItemsDiscountAmount":0,
// "totalAmount":603.97,
// }
//
Get Create (RefClass(cComChilkatJsonObject)) To hoJson
If (Not(IsComObjectCreated(hoJson))) Begin
Send CreateComObject of hoJson
End
Get ComLoadFile Of hoJson "qa_data/itida/sdk.invoicing.eta.gov.eg/files/one-doc.json" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoJson To sTemp1
Showln sTemp1
Procedure_Return
End
Set ComEmitCompact Of hoJson To False
// Create the CAdES-BES signature.
Set ComEncodingMode Of hoCrypt To "base64"
// Make sure we sign the utf-8 byte representation of the JSON string
Set ComCharset Of hoCrypt To "utf-8"
Get ComEmit Of hoJson To sTemp1
Get ComSignStringENC Of hoCrypt sTemp1 To sSigBase64
Get ComLastMethodSuccess Of hoCrypt To bTemp1
If (bTemp1 = False) Begin
Get ComLastErrorText Of hoCrypt To sTemp1
Showln sTemp1
Procedure_Return
End
Showln "Base64 signature:"
Showln sSigBase64
// Add the signature to the JSON.
Get ComUpdateString Of hoJson "signatures[0].signatureType" "I" To iSuccess
Get ComUpdateString Of hoJson "signatures[0].value" sSigBase64 To iSuccess
Showln "JSON with signature added:"
Get ComEmit Of hoJson To sTemp1
Showln sTemp1
// ------------------------------------------------------------------------------------------------------------
// Cleanup our ScMinidriver session...
// When finished with operations that required authentication, you may if you wish, deauthenticate the session.
Get ComPinDeauthenticate Of hoScmd "user" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoScmd To sTemp1
Showln sTemp1
End
// Delete the context when finished with the card.
Get ComDeleteContext Of hoScmd To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoScmd To sTemp1
Showln sTemp1
End
End_Procedure