0

I am using Podofo libraries and c++ code for PDf signature in Ubuntu environment.Actually I am able to do pdf signature successfully using same library and code in windows environment. But,getting "Byte range invalid" isuue in Ubuntu 32-bit environment. I am attaching "Byte range invalid "Signature certificate.please refer this and give me some inputs.

file link

 try
    {
        PdfXObject *m_pImgXObj_vs;
        PdfMemDocument document;

        document.Load(inputfile, true);
        if (!document.GetPageCount())
            PODOFO_RAISE_ERROR_INFO(ePdfError_PageNotFound, "The document has no page. Only documents with at least one page can be signed");

        PdfAcroForm* pAcroForm = document.GetAcroForm();
        if (!pAcroForm)
            PODOFO_RAISE_ERROR_INFO(ePdfError_InvalidHandle, "acroForm == NULL");

        if (!pAcroForm->GetObject()->GetDictionary().HasKey(PdfName("SigFlags")) ||
            !pAcroForm->GetObject()->GetDictionary().GetKey(PdfName("SigFlags"))->IsNumber() ||
            pAcroForm->GetObject()->GetDictionary().GetKeyAsLong(PdfName("SigFlags")) != 3)
        {
            if (pAcroForm->GetObject()->GetDictionary().HasKey(PdfName("SigFlags")))
                pAcroForm->GetObject()->GetDictionary().RemoveKey(PdfName("SigFlags"));

            pdf_int64 val = 3;
            pAcroForm->GetObject()->GetDictionary().AddKey(PdfName("SigFlags"), PdfObject(val));
        }
        if (pAcroForm->GetNeedAppearances())
        {
#if 0 /* TODO */
            update_default_appearance_streams(pAcroForm);
#endif

            pAcroForm->SetNeedAppearances(false);
        }

        PdfOutputDevice outputDevice(outputfile ? outputfile : inputfile, outputfile != NULL);
        PdfSignOutputDevice signer(&outputDevice);

        PdfString name;
        PdfObject* pExistingSigField = NULL;




        if (field_name)
        {
            name = PdfString(field_name);

            pExistingSigField = find_existing_signature_field(pAcroForm, name);
            if (pExistingSigField && !field_use_existing)
            {
                std::string err = "Signature field named '";
                err += name.GetString();
                err += "' already exists";

                PODOFO_RAISE_ERROR_INFO(ePdfError_WrongDestinationType, err.c_str());
            }
        }
        else
        {
            char fldName[96]; 
            sprintf(fldName, "PodofoSignatureField%" PDF_FORMAT_INT64, static_cast<pdf_int64>(document.GetObjects().GetObjectCount()));

            name = PdfString(fldName);
        }
        if (pExistingSigField)
        {
            if (!pExistingSigField->GetDictionary().HasKey("P"))
            {
                std::string err = "Signature field named '";
                err += name.GetString();
                err += "' doesn't have a page reference";

                PODOFO_RAISE_ERROR_INFO(ePdfError_PageNotFound, err.c_str());
            }

            PdfPage* pPage;

            pPage = document.GetPagesTree()->GetPage(pExistingSigField->GetDictionary().GetKey("P")->GetReference());
            if (!pPage)
                PODOFO_RAISE_ERROR(ePdfError_PageNotFound);

            pTemporaryAnnot = new PdfAnnotation(pExistingSigField, pPage);
            if (!pTemporaryAnnot)
                PODOFO_RAISE_ERROR_INFO(ePdfError_OutOfMemory, "Cannot allocate annotation object for existing signature field");

            pSignField = new PdfSignatureField(pTemporaryAnnot);
            if (!pSignField)
                PODOFO_RAISE_ERROR_INFO(ePdfError_OutOfMemory, "Cannot allocate existing signature field object");

            pSignField->EnsureSignatureObject();
        }
        else
        {
            PdfRect annot_rect;
            PdfPage* pPage = document.GetPage(document.GetPageCount() - 1);
            if (!pPage)
                PODOFO_RAISE_ERROR(ePdfError_PageNotFound);

            
            if (annot_position)
            {
                annot_rect = PdfRect(annot_left, pPage->GetPageSize().GetHeight() - annot_top - annot_height, annot_width, annot_height);
                annot_rect = PdfRect(annot_left, pPage->GetPageSize().GetBottom() - annot_top + 3, annot_width, annot_height);
            }

            PdfAnnotation* pAnnot = pPage->CreateAnnotation(ePdfAnnotation_Widget, annot_rect);
            if (!pAnnot)
                PODOFO_RAISE_ERROR_INFO(ePdfError_OutOfMemory, "Cannot allocate annotation object");
            pAnnot->GetTitle();
            if (annot_position && annot_print)
                pAnnot->SetFlags(ePdfAnnotationFlags_Print);
            else if (!annot_position && (!field_name || !field_use_existing))
                pAnnot->SetFlags(ePdfAnnotationFlags_Invisible | ePdfAnnotationFlags_Hidden);

            pAnnot->SetContents("ABC");
            
            PdfImage *pdfImage = NULL;
            
            PdfSigIncMemDocument m_psigMemDoc;
            PdfXObject *m_pImgXObj_vs = NULL;
            PdfXObject *m_n2XObj = NULL;
            PdfFont *m_pFont = document.CreateFont("Times-Roman", true, true);
            PdfRect objRect(0, 0, annot_rect.GetWidth(), annot_rect.GetHeight());
                        
            m_pImgXObj_vs = new PdfXObject(objRect, &document);
            PdfSigIncPainter pnt(&document, true);
            pnt.SetPageCanvas(pPage, m_pImgXObj_vs->GetContents());
            PdfXObject frmXObj(objRect, &document, "FRM", true);
            
            m_pImgXObj_vs->AddResource(PdfName("FRM"), frmXObj.GetObjectReference(), PdfName("XObject"));
            pnt.DrawXObject(0, 0, &frmXObj);
            pnt.SetFont(m_pFont);
            
            pnt.SetPageCanvas(pPage, frmXObj.GetContents());

            PdfXObject n0XObj(objRect, &document, "n0", true);
            PdfXObject n2XObj(objRect, &document, "n2", true);

            frmXObj.AddResource(PdfName("n0"), n0XObj.GetObjectReference(), PdfName("XObject"));
            frmXObj.AddResource(PdfName("n2"), n2XObj.GetObjectReference(), PdfName("XObject"));

            pnt.DrawXObject(0, 0, &n0XObj);
            pnt.DrawXObject(0, 0, &n2XObj);


            
            PdfString text = "podofo";
            
            m_pFont = document.CreateFont("Times-Roman", true, true);
            m_pFont->SetFontSize(25);
            pnt.SetFont(m_pFont);
            pnt.SetColor(0, 0, 0);
            pnt.DrawText(2, 31, "e");
            m_pFont->SetFontSize(27);
            pnt.SetColor(0.92, 0.60, 0.08);
            pnt.DrawText(10, 19, "Sign");
            n2XObj.AddResource(m_pFont->GetIdentifier(), m_pFont->GetObject()->Reference(), PdfName("Font"));


            m_pFont->SetFontSize(6.5);
            
            pnt.SetFont(m_pFont);
            pnt.SetColor(0, 0, 0);
            int width = annot_rect.GetWidth() / 2 - 15;
            pnt.DrawText(width, 40, "Digitally Signed By");
            pnt.DrawText(width, 32, "ABC");

            pnt.DrawText(width, 24, "XYZ");
            pnt.DrawText(width, 16, "Unknown");
            pnt.DrawText(width, 8, "29/10/2020");
            n2XObj.AddResource(m_pFont->GetIdentifier(), m_pFont->GetObject()->Reference(), PdfName("Font"));
            
            pnt.EndCanvas();
            pnt.FinishPage();
        
            pSignField = new PdfSignatureField(pAnnot, pAcroForm, &document);
            if (!pSignField)
                PODOFO_RAISE_ERROR_INFO(ePdfError_OutOfMemory, "Cannot allocate signature field object");

            signer.SetSignatureSize(10200);
            pSignField->SetFieldName("Signature");
            pSignField->SetSignatureReason(PdfString(reinterpret_cast<const pdf_utf8 *>(reason)));
            pSignField->SetSignatureDate(PdfDate());
            pSignField->SetSignature(*signer.GetSignatureBeacon());

            
            document.WriteUpdate(&signer, outputfile != NULL);
            if (signer.HasSignaturePosition())
            {
                signer.AdjustByteRange();
                
                signer.Seek(0);
                
                size_t len;

                unsigned char hash[SHA256_DIGEST_LENGTH];
                SHA256_CTX sha256;
                SHA256_Init(&sha256);
                const int bufSize = 65536;
                char outputBuffer[65];
                char *buffer = (char *)malloc(bufSize);
                
                unsigned int uBufferLen = 65535;
                char *pBuffer;

                while (pBuffer = reinterpret_cast<char *>(podofo_malloc(sizeof(char) * uBufferLen)), !pBuffer)
                {
                    uBufferLen = uBufferLen / 2;
                    if (!uBufferLen)
                        break;
                }
                
                int rc;
                BIO *mem = BIO_new(BIO_s_mem());
                if (!mem)
                {
                    podofo_free(pBuffer);
                    podofo_free(buffer);
                    
                }
                
                while ((len = signer.ReadForSignature(pBuffer, uBufferLen)) > 0)
                {
                    SHA256_Update(&sha256, pBuffer, len);
                    rc = BIO_write(mem, pBuffer, len);
                    

                }
                SHA256_Final(hash, &sha256);
                sha256_hash_string(hash, outputBuffer);

                
                unsigned int flags = PKCS7_DETACHED | PKCS7_BINARY;
                
                
                //Adding PKCS7 data(str_pkcs7) for Signing  
                createXPemformate(str_pkcs7, 64);
                PKCS7 *p7 = NULL;
                BIO *in = BIO_new(BIO_s_file());
                BIO *out = BIO_new(BIO_s_file());
                int der = 0; 
                int text = 0; 
                STACK_OF(X509) *certs = NULL;
                int i;

                                                             \
                    ERR_load_crypto_strings();
                OpenSSL_add_all_algorithms();

                BIO_set_fp(out, stdout, BIO_NOCLOSE);
                BIO_read_filename(in, "myfile.p7b");
                
                p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
                
                i = OBJ_obj2nid(p7->type);
                if (i == NID_pkcs7_signed) {
                    certs = p7->d.sign->cert;
                }
                else if (i == NID_pkcs7_signedAndEnveloped) {
                    certs = p7->d.signed_and_enveloped->cert;
                }
                if (PKCS7_final(p7, mem, flags) <= 0)
                {
                    PKCS7_free(p7);
                    BIO_free(mem);
                    
                }
                
                char *outBuff = NULL;
                long outLen;
                BIO *bio = BIO_new(BIO_s_mem());
                int p7_len = i2d_PKCS7_bio(bio, p7);
                outLen = BIO_get_mem_data(bio, &outBuff);
                cout << "outLen" << outLen << std::endl;
                if (outLen > 0 && outBuff)
                {
                    if (static_cast<size_t>(outLen) > signer.GetSignatureSize())
                    {
                        std::ostringstream oss;
                        oss << "Requires at least " << outLen << " bytes for the signature, but reserved is only " << signer.GetSignatureSize() << " bytes";
                        
                    }
                }
                
                PoDoFo::PdfData sigData(outBuff, outLen);
                signer.SetSignature(sigData);// Paste signature to the file
                
            }
            signer.Flush();
        }
    }
    catch (PoDoFo::PdfError & e)
    {
        std::cerr << "Error: An error " << e.what() << " occurred during the sign of the pdf file:" << std::endl;
        
    }
raj
  • 49
  • 7

1 Answers1

0

The cross reference table in your PDF is invalid:

xref
0 12
0000000000 00000 ÿ 
0000000172 00000   
0000000231 00000   
0000000328 00000   
0000000379 00000   
0000000414 00000   
0000000583 00000   
0000000706 00000   
0000000015 00000   
0000001747 00000   
0000001765 00000   
0000001932 00000    

According to the PDF specification,

The format of an in-use entry shall be:

nnnnnnnnnn ggggg n eol

[...]

The cross-reference entry for a free object has essentially the same format, except that the keyword shall be finstead of n and the interpretation of the first item is different:

nnnnnnnnnn ggggg f eol

Instead of the f and n you have 0xff (ÿ) and 0x00 (displayed above as a space).

mkl
  • 90,588
  • 15
  • 125
  • 265