问题
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