Pdofo Extract签名字段

时间:2015-04-14 09:11:44

标签: c++ digital-signature podofo

我使用PoDoFo从签名字段中提取一些签名数据。 我搜索了很多指南,我找到了这段代码(不能记住这篇文章,或者我会将它链接起来)。

int getNumberOfSignatures(const PdfMemDocument &doc)
{
    /// Find the document catalog dictionary
    const PdfObject *const trailer = doc.GetTrailer();
    if (!trailer->IsDictionary())
        throw std::invalid_argument("Document invalid, non-dictionary trailer!");

    const PdfObject *const catalogRef = trailer->GetDictionary().GetKey(PdfName("Root"));
    if (catalogRef == 0 || !catalogRef->IsReference())
        throw std::invalid_argument("Invalid /Root entry");

    const PdfObject *const catalog = doc.GetObjects().GetObject(catalogRef->GetReference());
    if (catalog == 0 || !catalog->IsDictionary())
        throw std::invalid_argument("Invalid or non-dictionary referenced by / Root entry");

    /// Find the Fields array in catalog dictionary
    const PdfObject *acroFormValue = catalog->GetDictionary().GetKey(PdfName("AcroForm"));
    if (acroFormValue == 0) return 0;
    if (acroFormValue->IsReference())
        acroFormValue = doc.GetObjects().GetObject(acroFormValue->GetReference());
    if (!acroFormValue->IsDictionary()) return 0;

    const PdfObject *fieldsValue =
        acroFormValue->GetDictionary().GetKey(PdfName("Fields"));
    if (fieldsValue == 0) return 0;
    if (fieldsValue->IsReference())
        fieldsValue = doc.GetObjects().GetObject(acroFormValue->GetReference());
    if (!fieldsValue->IsArray()) return 0;

    /// Verify if each object of the array is a signature field
    int n = 0;
    const PdfArray &array = fieldsValue->GetArray();
    for (unsigned int i = 0; i < array.size(); i++) {
        const PdfObject *const obj = doc.GetObjects().GetObject(array[i].GetReference());
        if (isCustomSignatureField(doc, obj)) {
            n++;                
        }
    }

检查签名字段的功能是这个

bool isSignatureField(const PdfMemDocument &doc, const PdfObject *const pObj)
{
    if (pObj == 0) return false;
    if (!pObj->IsDictionary()) return false;

    const PdfObject *const keyFTValue = pObj->GetDictionary().GetKey(PdfName("FT"));
    if (keyFTValue == 0) return false;

    string value;
    keyFTValue->ToString(value);
    if (value != "/Sig") return false;

    const PdfObject *const keyVValue = pObj->GetDictionary().GetKey(PdfName("V"));
    if (keyVValue == 0) return false;

    const PdfObject *const signature = doc.GetObjects().GetObject(keyVValue->GetReference());
    if (signature->IsDictionary()) return true;
    else return false;
}

此代码正常工作,但我必须改进它。  当我签名时,我会在签名词典(/ Sig dic)中添加一个自定义词典(我将调用ilt Custom_Dic ),现在我必须检索它。我能怎么做?我想我错过了一些逻辑。

bool isCustomSignatureField(const PdfMemDocument &doc, const PdfObject *const pObj)
{
    if (pObj == 0) return false;
    if (!pObj->IsDictionary()) return false;

    const PdfObject *const keyFTValue = pObj->GetDictionary().GetKey(PdfName("FT"));
    if (keyFTValue == 0) return false;

    string value;
    keyFTValue->ToString(value);
    if (value != "/Sig") return false;

    const PdfObject *const keyVValue = pObj->GetDictionary().GetKey(PdfName("V"));
    if (keyVValue == 0) return false;

    const PdfObject *const signature = doc.GetObjects().GetObject(keyVValue->GetReference());
    if (!signature->IsDictionary()) return false;

    const PdfObject *const keyAaValue = signature->GetDictionary().GetKey(PdfName("Custom_Dic"));
    if (keyAValue == 0) return false;

    cout << keyAValue;

    const PdfObject *const signatureMetadata = doc.GetObjects().GetObject(keyAValue->GetReference());
    if (signatureMetadata->IsDictionary()) return true;

    else return false;
}

这个函数给我一个例外:

TestLayer.exe中0x75154598处的未处理异常:Microsoft C ++异常:内存位置0x008BDCD4处的PoDoFo :: PdfError。

这行代码打印出一个值,所以我认为不是空的

cout << keyValue;

感谢您的建议。

0 个答案:

没有答案