bassemAgmi / EInvoicingSigner

A command prompt application used to serialize and sign tax payers documents before sending the documents to Egyptian Tax Authority.
71 stars 57 forks source link

References array error #12

Closed whhsn closed 2 years ago

whhsn commented 2 years ago

The code is not handling array of strings properly, such as the References array: input: "references": ["1234","abcd"], proper output should be: "REFERENCES""REFERENCES""1234""REFERENCES""abcd"

suggested rough fix is adding these lines:

`

        if (request.Parent is null)

        {

            SerializeToken(request.First);
        }
        else
        {
            if (request.Type == JTokenType.Property)
            {
            :
            :
            }
            // add these lines:
            if (request.Type == JTokenType.String)
            {
                serialized += JsonConvert.ToString(request.Value<string>());
            }
            :
            :

`

I didn't properly test these and I think types other than strings should be handled also.

socertis commented 2 years ago

I have used this fix and it is working fine!

yasserabdelfadile commented 1 year ago

I have error 4043 any help please.

yasserabdelfadile commented 1 year ago

this is the code i use to create signature private async Task SignFileAsync(string inputFilePath, string outputFilePath, X509Certificate2 cert) { // Read the input file into a byte array byte[] inputBytes = System.IO.File.ReadAllBytes(inputFilePath);

        // Check that the input file exists and is not null or empty
        if (inputBytes == null || inputBytes.Length == 0)
        {
            throw new ArgumentException("Input file is null or empty.");
        }
        // Create the canonical version of the JSON as per algorithm described
        string canonicalJson = CreateCanonicalJson(inputBytes);
        string canonicalJson2 = CanonicalJson1(inputBytes);
        byte[] inputBytes1 = Encoding.UTF8.GetBytes(canonicalJson2);
        // Compute the SHA-256 hash of the canonical JSON
        byte[] hash = ComputeSha256Hash(canonicalJson2);
        // Create a new instance of the CmsSigner class with the digital certificate obtained from the USB token
        if (cert == null)
        {
            throw new ArgumentException("USB token not found or PIN code is incorrect.");
        }
        Pkcs11InteropFactories factories = new Pkcs11InteropFactories();

        using (IPkcs11Library pkcs11Library = factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, "eps2003csp11.dll", AppType.MultiThreaded))
        {
            ISlot slot = pkcs11Library.GetSlotList(SlotsType.WithTokenPresent).FirstOrDefault();

            if (slot is null)
            {
                return;
            }

            ITokenInfo tokenInfo = slot.GetTokenInfo();

            ISlotInfo slotInfo = slot.GetSlotInfo();
            using (var session = slot.OpenSession(SessionType.ReadWrite))
            {
                session.Login(CKU.CKU_USER, Encoding.UTF8.GetBytes("305310542"));

                var certificateSearchAttributes = new List<IObjectAttribute>()
            {
                session.Factories.ObjectAttributeFactory.Create(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE),
                session.Factories.ObjectAttributeFactory.Create(CKA.CKA_TOKEN, true),
                session.Factories.ObjectAttributeFactory.Create(CKA.CKA_CERTIFICATE_TYPE, CKC.CKC_X_509)
            };

                IObjectHandle certificate = session.FindAllObjects(certificateSearchAttributes).FirstOrDefault();

                if (certificate is null)
                {
                    return;
                }

                X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                store.Open(OpenFlags.MaxAllowed);

                // find cert by thumbprint
                var foundCerts = store.Certificates.Find(X509FindType.FindByIssuerName, "Egypt Trust Sealing CA", false);

                //var foundCerts = store.Certificates.Find(X509FindType.FindBySerialNumber, "2b1cdda84ace68813284519b5fb540c2", true);

                if (foundCerts.Count == 0)
                {
                    return;
                }

                var certForSigning = foundCerts[0];
                store.Close();
                byte[] Sha = this.ComputeSha256Hash1(certForSigning.RawData);
                byte[] certHash = this.ComputeSha256Hash1(certForSigning.GetRawCertData());
                X509IssuerSerial issuerSerial = new X509IssuerSerial();
                issuerSerial.IssuerName = certForSigning.IssuerName.Name;
                issuerSerial.SerialNumber = certForSigning.SerialNumber;

                 ContentInfo content = new ContentInfo(new Oid("1.2.840.113549.1.7.5"), hash);

                // Create a SignedCms object with the given hash and set the "detached" flag to true.
                SignedCms signedCms = new SignedCms(content, true);
                EssCertIDv2 bouncyCertificate = new EssCertIDv2(
                     new Org.BouncyCastle.Asn1.X509.AlgorithmIdentifier(new DerObjectIdentifier("1.2.840.113549.1.9.16.2.47")),
                     certHash
                 );

                SigningCertificateV2 signerCertificateV2 = new SigningCertificateV2(new EssCertIDv2[] { bouncyCertificate });

                CmsSigner signer = new CmsSigner(certForSigning);
                // digest algorithm
                signer.DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1");
              // signer.SignedAttributes.Add(new CryptographicAttributeObject(new Oid("1.2.840.113549.1.9.4")));
                // Set signing time for now
                signer.SignedAttributes.Add(new Pkcs9SigningTime(DateTime.UtcNow));
                signer.SignedAttributes.Add(new AsnEncodedData(new Oid("1.2.840.113549.1.9.16.2.47"), signerCertificateV2.GetEncoded()));
                 // Compute the signature using the CmsSigner object and the SignedCms object.
                signedCms.ComputeSignature(signer);

                byte[] signatureBytes = signedCms.Encode();
                AsnEncodedData signedData = new AsnEncodedData(new Oid("1.2.840.113549.1.7.2"), signatureBytes);
                string signature = Convert.ToBase64String(signedData.RawData);
                string signature1 = Convert.ToBase64String(signatureBytes);
                // Include the Base64 encoded signature in the original document JSON in a new element
                string signedJson = AddSignatureToJSON(canonicalJson, signature);

                // Write the signed JSON to the output file
                await System.IO.File.WriteAllBytesAsync(outputFilePath, System.Text.Encoding.UTF8.GetBytes(signedJson));
                // Verify the signature of the signed file
                await VerifySignatureAsync(outputFilePath, certForSigning, true);
            }
        } 
    }