EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Sign PDF externally, and then calculate and add PKCS#7

Also by EldoS: BizCrypto
Components for BizTalk® and SQL Server® Integration Services that let you securely store and transfer information in your business automation solutions.
#25375
Posted: 06/20/2013 08:24:08
by Ammar Gaffar Ali (Basic support level)
Joined: 06/20/2013
Posts: 6

Thanks for your quick response

Quote
You can do this in the same way as mentioned in previous messages. ( https://www.eldos.com/forum/read.php?F...ssage25337 )


Could you please show me example code snippet, I have signed data in byte array, I want to insert it in PDF.
I tried to simulate your ActiveX/Applet job by passing my ready signature array, but I encountered some issues regarding xml elements.

I would be thankful if you support me with small code for only windows app.

Thanking you in advance.
#25378
Posted: 06/20/2013 16:18:09
by Dmytro Bogatskyy (EldoS Corp.)

Here it is a sample code that will locally emulate distributed signing of a pdf document:
Code
        public void EmulateDistribSigningPDF(string fileName)
        {
            SBPDF.Unit.Initialize();
            SBPDFSecurity.Unit.Initialize();

            string TempPath = "sample-presigned.pdf";
            // preparing a temporary file copy
            File.Copy(fileName, TempPath, true);

            TElDCAsyncState state;
            TElPDFDocument doc;
            TElPDFPublicKeySecurityHandler handler;
            using (FileStream input = new FileStream(TempPath, FileMode.Open, FileAccess.ReadWrite))
            {
                doc = new TElPDFDocument();
                handler = new TElPDFPublicKeySecurityHandler();
                try
                {
                    doc.Open(input);

                    handler.SignatureType = TSBPDFPublicKeySignatureType.pstPKCS7SHA1;
                    handler.HashAlgorithm = SBConstants.__Global.SB_ALGORITHM_DGST_SHA1;
                    handler.CustomName = "Adobe.PPKMS";

                    TElPDFSignature signature = doc.get_Signatures(doc.AddSignature());
                    signature.SignatureType = SBPDF.__Global.stDocument;
                    signature.Invisible = true;
                    signature.Handler = handler;
                    signature.SigningTime = DateTime.UtcNow;

                    state = doc.InitiateAsyncOperation();
                }
                finally
                {
                    handler.Dispose();
                    doc.Dispose();
                }
            }

            // saving the obtained state to file for debug purposes
            using (FileStream output = new FileStream("state-01.xml", FileMode.Create, FileAccess.ReadWrite))
            {
                state.SaveToStream(output, SBDCXMLEnc.Unit.DCXMLEncoding());
            }

            state.Dispose();

            // processing the state by server

            SBDCServer.TElDCStandardServer Server = new SBDCServer.TElDCStandardServer();
            SBDCPKI.TElDCX509SignOperationHandler SigHandler = new SBDCPKI.TElDCX509SignOperationHandler();
            SigHandler.CertStorage = new TElMemoryCertStorage();
            using (FileStream fs = new FileStream(@"C:\Projects\SecureBlackbox\Certificates\cert.pfx", FileMode.Open, FileAccess.Read))
            {
                SigHandler.CertStorage.LoadFromStreamPFX(fs, "password", 0);
            }

            Server.AddOperarionHandler(SigHandler);
            using (FileStream input = new FileStream("state-01.xml", FileMode.Open, FileAccess.Read))
            {
                using (FileStream output = new FileStream("state-02.xml", FileMode.Create, FileAccess.ReadWrite))
                {
                    Server.Process(input, output, SBDCXMLEnc.__Global.DCXMLEncoding(), SBDCXMLEnc.__Global.DCXMLEncoding());
                }
            }

            // finalizing the signature
            state = new TElDCAsyncState();
            using (FileStream input = new FileStream("state-02.xml", FileMode.Open, FileAccess.Read))
            {
                state.LoadFromStream(input, SBDCXMLEnc.__Global.DCXMLEncoding());
            }

            doc = new TElPDFDocument();
            handler = new TElPDFPublicKeySecurityHandler();
            try
            {
                handler.SignatureType = TSBPDFPublicKeySignatureType.pstPKCS7SHA1;

                using (FileStream fs = new FileStream(TempPath, FileMode.Open, FileAccess.ReadWrite))
                {
                    doc.CompleteAsyncOperation(fs, state, handler);
                }
            }
            finally
            {
                handler.Dispose();
                doc.Dispose();
            }

            state.Dispose();
            File.Copy(TempPath, "sample-signed.pdf", true);
        }


Then to sign a digest value with own function you can either create your own sign operation handler or to process a state object directly.
To create your own sign operation handler you would need to create a descendant of the TElDCSignOperationHandler class and override a protected Sign method. For example:
Code
        class CustomSignOperationHandler : SBDCServer.TElDCSignOperationHandler
        {
            override protected byte[] Sign(byte[] Data, byte[] HashAlg, bool IncludeKeys, SBRDN.TElRelativeDistinguishedName Keys, SBRDN.TElRelativeDistinguishedName Pars)
            {
                // your code that returns a signature
                return new byte[0];
            }
        }


To process a state object directly, you would need to use a similar code:
Code
            state = new TElDCAsyncState();
            using (FileStream input = new FileStream("state-01.xml", FileMode.Open, FileAccess.Read))
            {
                state.LoadFromStream(input, SBDCXMLEnc.__Global.DCXMLEncoding());
            }

            TElDCAsyncState respState = new TElDCAsyncState();
            for (int i = 0; i < state.Messages.Count; i++)
            {
                TElDCBaseMessage msg = state.Messages.get_Messages(i);
                if (msg is TElDCOperationRequestMessage)
                {
                    TElDCOperationResponseMessage respMsg = new TElDCOperationResponseMessage();
                    respMsg.Operation = TSBDCOperation.dcRawSign;
                    byte[] digest = ((TElDCOperationRequestMessage)msg).Source;
                    byte[] hashAlgorithm = ((TElDCOperationRequestMessage)msg).HashAlgorithm;

                    // <-- SIGN the digest

                    respMsg.OperationResult = new byte[0]; // put your signature here

                    respState.Messages.Add(respMsg, false);
                }
                else if (msg is TElDCBaseMessage)
                {
                    // base messages are mirrored
                    TElDCBaseMessage msgTmp = new TElDCBaseMessage();
                    msgTmp.Assign(msg);
                    respState.Messages.Add(msgTmp, false);
                }
            }

            using (FileStream output = new FileStream("state-02.xml", FileMode.Create, FileAccess.ReadWrite))
            {
                respState.SaveToStream(output, SBDCXMLEnc.Unit.DCXMLEncoding());
            }
#25400
Posted: 06/23/2013 00:01:26
by Ammar Gaffar Ali (Basic support level)
Joined: 06/20/2013
Posts: 6

Quote
Dmytro Bogatskyy wrote:
Here it is a sample code that will locally emulate distributed signing of a pdf document:


Thanks for your code, but unfortunately it don't work with me, no signature error message appears.

Here bellow some details about the signing functions I am using from the SDK:

Sign the data with the signing keypair, the PIN is not cached
public byte[] SignData(
string szPin,
byte[] data
);
Parameters
szPin
the user PIN
data
data string to be signed
Return Value
PKCS#1 signature

Builds a PKCS7 signature from the input Data
public byte[] SignPKCS7(
string szPin,
byte[] data,
bool detached
);
Parameters
szPin
Pin value
data
input data
detached
data detached from the PKCS7 signature


I can export signature certificate but without private key.
I hope you can help.

Thanking you in advance
#25401
Posted: 06/23/2013 00:14:15
by Eugene Mayevski (EldoS Corp.)

"It doesn't work" is hard to diagnose. If you can reduce your code to the complete sample that we can run, you can post it to HelpDesk. We can replace your "SignPKCS7" function with our software-based signing for testing purposes, and in this way check if the problem happens in the code you wrote or it's originated from the hardware.


Sincerely yours
Eugene Mayevski
#25402
Posted: 06/23/2013 01:03:26
by Ammar Gaffar Ali (Basic support level)
Joined: 06/20/2013
Posts: 6

Thanks for your quick response.

Let me explain it different way, the smart card is produced by ID Authority, it has no driver so it is always Unknown Smart Card.
The only way to communicate with this card is through SDK supported by ID Authority with less documentation unfortunately.

I can only use the supported functions in the SDK to sign data & verify signatures.
Now I am using this function SignPKCS7 which is returns PKCS7 signature as byte array

What I need is to put it inside PDF file, and read it later for verification purposes.

As I said, I can export sign certificate but without private key, here bellow some details:
Signature Algorithm : sha256RSA (I tried to change your handler.HashAlgorithm to same).
Public Key: RSA (2048 Bits).

Thanking you in advance.
#25403
Posted: 06/23/2013 02:41:40
by Eugene Mayevski (EldoS Corp.)

We fully understand your task and it's possible to accomplish it. Dmytro provided you some information that should be enough for doing what you need. If that code doesn't help you, we can help you by checking your code, but we can do this only if you provide a simple test case. I don't see how else we can assist if all we have is "shows an error message" or "doesn't work".


Sincerely yours
Eugene Mayevski
#25404
Posted: 06/23/2013 02:56:05
by Ammar Gaffar Ali (Basic support level)
Joined: 06/20/2013
Posts: 6

Here bellow my code:

Code
  private void btnSign_Click(object sender, EventArgs e)
        {
                String userPIN = "pin no here"; // the user to input his card pin
                PKIFacade pkiFacade = reader.GetPKIFacade();
                byte[] file = System.IO.File.ReadAllBytes(@"D:\PDF Test.pdf");
                byte[] signature = pkiFacade.SignPKCS7(userPIN, file,true);      
                SecureBoxClass c = new SecureBoxClass();
                c.EmulateDistribSigningPDF(@"D:\PDF Test.pdf", signature)
                MessageBox.Show("Done");
        }


Your Library code is here:

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SBDC;
using SBPDF;
using SBPDFSecurity;
using System.IO;
using SBCustomCertStorage;
namespace SignWinDemo
{
    class SecureBoxClass
    {
        public void EmulateDistribSigningPDF(string fileName, byte[] sig)
        {
            SBUtils.Unit.SetLicenseKey("9BF4...2780");
            SBPDF.Unit.Initialize();
            SBPDFSecurity.Unit.Initialize();

            string TempPath = "sample-presigned.pdf";
            // preparing a temporary file copy
            File.Copy(fileName, TempPath, true);

            TElDCAsyncState state;
            TElPDFDocument doc;
            TElPDFPublicKeySecurityHandler handler;
            using (FileStream input = new FileStream(TempPath, FileMode.Open, FileAccess.ReadWrite))
            {
                doc = new TElPDFDocument();
                handler = new TElPDFPublicKeySecurityHandler();
                try
                {
                    doc.Open(input);

                    handler.SignatureType = TSBPDFPublicKeySignatureType.pstPKCS7SHA1;
                    handler.HashAlgorithm = SBConstants.__Global.SB_ALGORITHM_DGST_SHA256;
                    handler.CustomName = "Adobe.PPKMS";

                    TElPDFSignature signature = doc.get_Signatures(doc.AddSignature());
                    signature.SignatureType = SBPDF.__Global.stDocument;
                    signature.Invisible =  true;
                    signature.Handler = handler;
                    signature.SigningTime = DateTime.UtcNow;
                    state = doc.InitiateAsyncOperation();
                    handler.Dispose();
                }
                finally
                {
                    handler.Dispose();
                    doc.Dispose();
                }
            }

            // saving the obtained state to file for debug purposes
            using (FileStream output = new FileStream("state-01.xml", FileMode.Create, FileAccess.ReadWrite))
            {
                state.SaveToStream(output, SBDCXMLEnc.Unit.DCXMLEncoding());
            }

            state.Dispose();

            // processing the state by server
            processState(sig);

            // state.Dispose();
            //File.Copy(TempPath, "sample-signed.pdf", true);
        }

        //Process State
        void processState(byte[] signature)
        {
            TElDCAsyncState state = new TElDCAsyncState();
            using (FileStream input = new FileStream("state-01.xml", FileMode.Open, FileAccess.Read))
            {
                state.LoadFromStream(input, SBDCXMLEnc.__Global.DCXMLEncoding());
            }

            TElDCAsyncState respState = new TElDCAsyncState();
            for (int i = 0; i < state.Messages.Count; i++)
            {
                TElDCBaseMessage msg = state.Messages.get_Messages(i);
                if (msg is TElDCOperationRequestMessage)
                {
                    TElDCOperationResponseMessage respMsg = new TElDCOperationResponseMessage();
                    respMsg.Operation = TSBDCOperation.dcRawSign;
                    byte[] digest = ((TElDCOperationRequestMessage)msg).Source;
                    byte[] hashAlgorithm = ((TElDCOperationRequestMessage)msg).HashAlgorithm;

                    // sign

                    respMsg.OperationResult = signature; // put your signature here

                    respState.Messages.Add(respMsg, false);
                }
                else if (msg is TElDCBaseMessage)
                {
                    // base messages are mirrored
                    TElDCBaseMessage msgTmp = new TElDCBaseMessage();
                    msgTmp.Assign(msg);
                    respState.Messages.Add(msgTmp, false);
                }
            }

            using (FileStream output = new FileStream("state-02.xml", FileMode.Create, FileAccess.ReadWrite))
            {
                respState.SaveToStream(output, SBDCXMLEnc.Unit.DCXMLEncoding());
            }
            state.Dispose();
            string TempPath = "sample-presigned.pdf";
            File.Copy(TempPath, "sample-signed.pdf", true);

        }
    }
}


With above code no errors, but the signature inside PDF is invalid.

The complete sample will not work in your side, because the SDK check the smart card first before completing any functions. Now we are using sample card supported by ID Authority.

Thanking you in advance
#25405
Posted: 06/23/2013 02:59:46
by Eugene Mayevski (EldoS Corp.)

Deal Mr.Ali, we have limited possibilities to analyze user code, especially of users with Basic support level. If you want us to help you, please create a complete sample that we can compile and run, then post it to HelpDesk. It is vitally important to have a compilable sample - this is the only way to ensure that we and you are testing the same thing.


Sincerely yours
Eugene Mayevski
#25406
Posted: 06/23/2013 03:08:14
by Eugene Mayevski (EldoS Corp.)

Forgot to mention - you need to ZIP the project and also please put only the source and project files to archive (don't put obj and bin directories)


Sincerely yours
Eugene Mayevski
#25407
Posted: 06/23/2013 03:53:29
by Ammar Gaffar Ali (Basic support level)
Joined: 06/20/2013
Posts: 6

Quote
Eugene Mayevski wrote:
Deal Mr.Ali, we have limited possibilities to analyze user code, especially of users with Basic support level. If you want us to help you, please create a complete sample that we can compile and run, then post it to HelpDesk. It is vitally important to have a compilable sample - this is the only way to ensure that we and you are testing the same thing.


Thank you for your response
But the complete sample will not work for you unless you have the smart card (Specific smart card). Sign functions will work only with this card!
Also by EldoS: Rethync
The cross-platform framework that simplifies synchronizing data between mobile and desktop applications and servers and cloud storages

Reply

Statistics

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