How do you encode the Certificate Revocation List (CRL) stream bytes in PDF?

末鹿安然 提交于 2020-03-25 18:39:15

问题


I sign a PDF and I add update version in which I write the DSS with its CRLs, Certs, VRI.

19 0 obj
    [15 0 R 16 0 R]
endobj
20 0 obj
    [13 0 R 14 0 R]
endobj
11 0 obj
    [15 0 R 16 0 R]
endobj
12 0 obj 
    [13 0 R 14 0 R]
endobj
17 0 obj
<<
    /CRL 11 0 R
    /Cert 12 0 R
>>
endobj
18 0 obj
<<
    /5F44CF6F351DFD45FB62F3D0ED046408BC892797 17 0 R
>>
endobj
21 0 obj
<<
    /VRI 18 0 R
    /CRLs 19 0 R
    /Certs 20 0 R
>>

I am confused about how should I write the Certificate and CRL streams.

15 0 obj
<<
    /Length 1454
    /Filter /FlateDecode
>>
stream
xÚ3hb0hb{ÅÄÈhÀÉƪÍÇÌ$ÅÊ`àcÈä2‡²°    3…Šˆ€8\¼®y%E¥Å%:žyÉz†ªÊ
ZbXd{0%KW÷ýY¯’ó‚-ØÂÛ„OÏó½z•î    ‰`®•®   K-›2}tÖ§^_8;xÉì¥Ó®~›.g9A'Õüê½—
ZbXd{0%KW÷ýY¯’ó‚-ØÂÛ„OÏó½z•î    ‰`®•®   K-›2}tÖ§^_8;xÉì¥Ó®~›.g9A'Õüê½— 
endstream
endobj

16 0 obj
<<
    /Length 1477
    /Filter /FlateDecode
>>
stream
„kâR7Å41*!‡#8Íñ3 Ź˜@‰o=«‡çƒ#yë:X]r\~}¼)/Ñmç×£¦³äsËê]ÓÕ_+µ¥$Ô¿}¾ÜÏiÁÝT!¹ôi–Í9üÀ}Š¸|
ìŒH¿GÓø^ú¿ÔVÜK–qõ†µ®“¸»Ý*Žh¾JzåU7c~÷•ÔêýK*îú®¹¸DcÁ­³·NtV~Vóåíé5\‚&½|¶NäïŽ[K­
î›NRZbXd{0%KW÷ýY¯’ó‚-ØÂÛ„OÏó½z•î    ‰`®•®   K-›2}tÖ§^_8;xÉì¥Ó®~›.g9A'Õüê½—›oÇ:ç-¶?
endstream
endobj

13 0 obj
<<
    /Length 1240
    /Filter /FlateDecode
>>
stream
%ŸwC[í2×¾Iej©úkŽ-:ݳÔ<¼a£ƒô/5›‡~zÒ•7ü9uãcfk?ËÅ`ßÃ:Èb—’‚Ÿõ{ÏÅ—¢{]HçQ”9w(ÂB#í×g¥ìþè
^–F«š/r§š¿ì=#,^pëO€{äú=}RÎêð¦ÉŠ7or¼±Ëtë–x·˜§LÌŒŒ‹› Cd0€eùÿ³°03±>0P ñUY$
endstream
endobj

14 0 obj
<<
    /Length 1159
    /Filter /FlateDecode
>>
stream
4!>T‚êPpÎI,.V0Ò™@ûœºƒ=LÍš•ãˆ‘•¹‰‘Ÿ(ÎÅÔÄÈÈplŽ÷A¯¹7k/[‡O\}
öe™¨îö£œ¶ä'¶ÌpžªweÞª[¡$¼ØÍþþtó[½xÉO4ÞZ¥ØŸ^g ø,mu„_Rz™_PÏê.||º¶*þîÝxv½"»êôó»ø%Ü%ý
endstream
endobj

Please ignore the lengths and content of the streams above. I truncated them so the lengths don't correspond anymore. The streams are bigger than that.

The issue is that my PDF is not LTV enabled and I tested some scenarios from which I concluded that my stream are not being written the right way.

I use the following structure from WinCrypt.h:

typedef struct _CERT_CONTEXT {
    DWORD                   dwCertEncodingType;
    BYTE                    *pbCertEncoded;
    DWORD                   cbCertEncoded;
    PCERT_INFO              pCertInfo;
    HCERTSTORE              hCertStore;
} CERT_CONTEXT, *PCERT_CONTEXT;
typedef const CERT_CONTEXT *PCCERT_CONTEXT;

I go through them and get the bytes this way:

PCCERT_CONTEXT  cngContext = (PCCERT_CONTEXT)(*itChain);
ByteArray certBytes(cngContext->pbCertEncoded, (size_t)cngContext->cbCertEncoded);

Then I just apply FlateDecode on the obtained bytes and write them into the PDF like a stream as you can see in the second block of code.

Am I missing any step? Like a conversion or something? I saw that the stream should be BER-Encoded. So should I transform the bytes into BER-Encoded and then apply FlateDecode?

Edit:

You can find My File here


回答1:


SOLUTION

The problem was the stream of CRLs that I was writing in the PDF file.

Having the CRL_CONTEXT structures from each Certificate, I just took the pbCrlEncoded variable and write it directly in the stream of the CRL.

It seemed correct but I noticed I didn't have any CRL_ENTRY in the CRL_INFO of this structure so the encoded BYTEs didn't contain any list of revoked certificates. Therefore, found that the certificates have a URL from where you can download the updated CRL. You can do that by opening Manage Computer Certificates in Windows -> find your Certificate and Open the Certificate -> Details -> CRL Distribution Points -> URL = "..". By accessing this url, the browser automatically downloads the CRL Info. You can access it and see some informations like Next Update which is the last day that this list is valid. After that, I'm assuming that you need to download it again for getting an updated version. Also you can see the list itself of revoked certificates.

This is the list I needed to put into the CRLs streams in PDF. So I found a method to do that download process by code. This is a snippet of code used:

PCERT_CHAIN_ELEMENT chainElement; // this is the certification in the chain
pExtension = CertFindExtension(szOID_CRL_DIST_POINTS, chainElement->pCertContext->pCertInfo->cExtension, chainElement->pCertContext->pCertInfo->rgExtension);
if (!pExtension)
    return ByteArray();

if (!CryptDecodeObject(X509_ASN_ENCODING, szOID_CRL_DIST_POINTS, pExtension->Value.pbData, pExtension->Value.cbData, 0, 0, &cbStructInfo))
    return ByteArray();

if (!(pvStructInfo = LocalAlloc(LMEM_FIXED, cbStructInfo)))
    return ByteArray();

CryptDecodeObject(X509_ASN_ENCODING, szOID_CRL_DIST_POINTS, pExtension->Value.pbData, pExtension->Value.cbData, 0, pvStructInfo, &cbStructInfo);

pInfo = (CRL_DIST_POINTS_INFO*)pvStructInfo;

Net::HttpRequest req;
Net::HttpRequestOptions ops;
ops.verb = Net::GET;
crllist = req.send(pInfo->rgDistPoint->DistPointName.FullName.rgAltEntry->pwszURL);

This way I obtained the Bytes that I could paste in PDF after applying FlateDecode on them. Now the PDF is LTV Enabled.



来源:https://stackoverflow.com/questions/60432684/how-do-you-encode-the-certificate-revocation-list-crl-stream-bytes-in-pdf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!