diff options
author | Tor Lillqvist <tml@collabora.com> | 2015-02-18 15:20:10 +0200 |
---|---|---|
committer | Tor Lillqvist <tml@collabora.com> | 2015-02-18 15:30:44 +0200 |
commit | 4f69b6de069b7ed70a4aa0095ad9bf981eed53ae (patch) | |
tree | b41860810e87457ff612595c72bdaabf8d639c22 | |
parent | 0a8bcd8256f2618b30c9767d5eaddb51ec3d9a8e (diff) |
tdf#84881: Intermediate commit: Construct RFC3161 TimeStampReq
It took a while to figure out how to use the NSS API to construct ASN.1
DER-encoded data using the SEC_ASN1_Template data structs. But I am getting
closer. Now the SEC_ASN1EncodeItem() doesn't crash at least.
Change-Id: I863542bbeed47d48d05a67b851648f87ba9ccf31
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 160 |
1 files changed, 159 insertions, 1 deletions
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index ec373aaaf911..20a24413eaa1 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -6020,6 +6020,9 @@ bool PDFWriterImpl::emitSignature() #if !defined(ANDROID) && !defined(IOS) && !defined(_WIN32) namespace { +#if 0 +} +#endif char *PDFSigningPKCS7PasswordCallback(PK11SlotInfo * /*slot*/, PRBool /*retry*/, void *arg) { @@ -6035,7 +6038,123 @@ public: HASHContext *get() { return mpPtr; } }; -} +/* +MessageImprint ::= SEQUENCE { + hashAlgorithm AlgorithmIdentifier, + hashedMessage OCTET STRING } +*/ + +typedef struct { + SECAlgorithmID hashAlgorithm; + SECItem hashedMessage; +} MessageImprint; + +/* +Extension ::= SEQUENCE { + extnID OBJECT IDENTIFIER, + critical BOOLEAN DEFAULT FALSE, + extnValue OCTET STRING } +*/ + +typedef struct { + SECItem extnID; + bool critical; + SECItem extnValue; +} Extension; + +/* +Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension +*/ + +/* +Accuracy ::= SEQUENCE { + seconds INTEGER OPTIONAL, + millis [0] INTEGER (1..999) OPTIONAL, + micros [1] INTEGER (1..999) OPTIONAL } +*/ + +typedef struct { + SECItem seconds; + SECItem millis; + SECItem micros; +} Accuracy; + +/* +TimeStampReq ::= SEQUENCE { + version INTEGER { v1(1) }, + messageImprint MessageImprint, + --a hash algorithm OID and the hash value of the data to be + --time-stamped + reqPolicy TSAPolicyId OPTIONAL, + nonce INTEGER OPTIONAL, + certReq BOOLEAN DEFAULT FALSE, + extensions [0] IMPLICIT Extensions OPTIONAL } +*/ +typedef struct { + SECItem version; + MessageImprint messageImprint; + SECItem reqPolicy; + SECItem nonce; + SECItem certReq; + SECItem extensions; +} TimeStampReq; + +SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) +SEC_ASN1_MKSUB(MessageImprint_Template) +SEC_ASN1_MKSUB(Extensions_Template) + +const SEC_ASN1Template MessageImprint_Template[] = +{ + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(MessageImprint) }, + { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(MessageImprint, hashAlgorithm), SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate), 0 }, + { SEC_ASN1_OCTET_STRING, offsetof(MessageImprint, hashedMessage), 0, 0 }, + { 0, 0, 0, 0 } +}; + +const SEC_ASN1Template Extension_Template[] = +{ + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(Extension) }, + { SEC_ASN1_OBJECT_ID, offsetof(Extension, extnID), 0, 0 }, + { SEC_ASN1_BOOLEAN, offsetof(Extension, critical), 0, 0 }, + { SEC_ASN1_OCTET_STRING, offsetof(Extension, extnValue), 0, 0 }, + { 0, 0, 0, 0 } +}; + +const SEC_ASN1Template Extensions_Template[] = +{ + { SEC_ASN1_SEQUENCE_OF, 0, Extension_Template, 0 } +}; + +const SEC_ASN1Template Integer_Template[] = +{ + { SEC_ASN1_INTEGER, 0, NULL, sizeof(SECItem) } +}; + +const SEC_ASN1Template Accuracy_Template[] = +{ + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(Accuracy) }, + { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof(Accuracy, seconds), 0, 0 }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(Accuracy, millis), Integer_Template, 0 }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1, offsetof(Accuracy, micros), Integer_Template, 0 }, + { 0, 0, 0, 0 } +}; + +const SEC_ASN1Template TimeStampReq_Template[] = +{ + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(TimeStampReq) }, + { SEC_ASN1_INTEGER, offsetof(TimeStampReq, version), 0, 0 }, + { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(TimeStampReq, messageImprint), SEC_ASN1_SUB(MessageImprint_Template), 0 }, + { SEC_ASN1_OBJECT_ID, offsetof(TimeStampReq, reqPolicy), 0, 0 }, + { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof(TimeStampReq, nonce), 0, 0 }, + { SEC_ASN1_BOOLEAN, offsetof(TimeStampReq, certReq), 0, 0 }, + { SEC_ASN1_XTRN | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(TimeStampReq, extensions), SEC_ASN1_SUB(Extensions_Template), 0 }, + { 0, 0, 0, 0 } +}; + +#if 0 +{ +#endif +} // anonymous namespace #endif @@ -6150,6 +6269,45 @@ bool PDFWriterImpl::finalizeSignature() HASH_End(hc.get(), digest.data, &digest.len, SHA1_LENGTH); hc.clear(); + SECItem dest; + TimeStampReq src; + + unsigned char cOne = 1; + src.version.type = siUnsignedInteger; + src.version.data = &cOne; + src.version.len = sizeof(cOne); + + // FIXME, use proper contents + src.messageImprint.hashAlgorithm.algorithm.type = siBuffer; + src.messageImprint.hashAlgorithm.algorithm.data = NULL; + src.messageImprint.hashAlgorithm.algorithm.len = 0; + src.messageImprint.hashAlgorithm.parameters.type = siBuffer; + src.messageImprint.hashAlgorithm.parameters.data = NULL; + src.messageImprint.hashAlgorithm.parameters.len = 0; + src.messageImprint.hashedMessage = digest; + + src.reqPolicy.type = siBuffer; + src.reqPolicy.data = NULL; + src.reqPolicy.len = 0; + + // FIXME, need a proper nonce + src.nonce.type = siBuffer; + src.nonce.data = NULL; + src.nonce.len = 0; + + unsigned char cFalse = false; + src.certReq.type = siUnsignedInteger; + src.certReq.data = &cFalse; + src.certReq.len = sizeof(cFalse); + + src.extensions.type = siBuffer; + src.extensions.data = NULL; + src.extensions.len = 0; + + SECItem* item = SEC_ASN1EncodeItem(NULL, &dest, &src, TimeStampReq_Template); + // SAL_ DEBUG("====> item=" << item << " data=" << (item ? (void*)item->data : nullptr) << " len=" << (item ? item->len : -1)); + // SECITEM_FreeItem(item, PR_TRUE); // crashes for some reason + NSSCMSMessage *cms_msg = NSS_CMSMessage_Create(NULL); if (!cms_msg) { |