VirtualBox

source: vbox/trunk/include/iprt/crypto/pkcs7.h@ 100275

Last change on this file since 100275 was 98103, checked in by vboxsync, 2 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 34.7 KB
Line 
1/** @file
2 * IPRT - PKCS \#7, Cryptographic Message Syntax Standard (aka CMS).
3 */
4
5/*
6 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef IPRT_INCLUDED_crypto_pkcs7_h
37#define IPRT_INCLUDED_crypto_pkcs7_h
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <iprt/asn1.h>
43#include <iprt/crypto/x509.h>
44
45
46RT_C_DECLS_BEGIN
47
48struct RTCRPKCS7CONTENTINFO;
49
50
51/** @defgroup grp_rt_crpkcs7 RTCrPkcs7 - PKCS \#7, Cryptographic Message Syntax Standard (aka CMS).
52 * @ingroup grp_rt_crypto
53 * @{
54 */
55
56/** PKCS \#7 data object ID.*/
57#define RTCR_PKCS7_DATA_OID "1.2.840.113549.1.7.1"
58/** PKCS \#7 signedData object ID. */
59#define RTCR_PKCS7_SIGNED_DATA_OID "1.2.840.113549.1.7.2"
60/** PKCS \#7 envelopedData object ID. */
61#define RTCR_PKCS7_ENVELOPED_DATA_OID "1.2.840.113549.1.7.3"
62/** PKCS \#7 signedAndEnvelopedData object ID. */
63#define RTCR_PKCS7_SIGNED_AND_ENVELOPED_DATA_OID "1.2.840.113549.1.7.4"
64/** PKCS \#7 digestedData object ID. */
65#define RTCR_PKCS7_DIGESTED_DATA_OID "1.2.840.113549.1.7.5"
66/** PKCS \#7 encryptedData object ID. */
67#define RTCR_PKCS7_ENCRYPTED_DATA_OID "1.2.840.113549.1.7.6"
68
69
70/**
71 * PKCS \#7 IssuerAndSerialNumber (IPRT representation).
72 */
73typedef struct RTCRPKCS7ISSUERANDSERIALNUMBER
74{
75 /** Sequence core. */
76 RTASN1SEQUENCECORE SeqCore;
77 /** The certificate name. */
78 RTCRX509NAME Name;
79 /** The certificate serial number. */
80 RTASN1INTEGER SerialNumber;
81} RTCRPKCS7ISSUERANDSERIALNUMBER;
82/** Pointer to the IPRT representation of a PKCS \#7 IssuerAndSerialNumber. */
83typedef RTCRPKCS7ISSUERANDSERIALNUMBER *PRTCRPKCS7ISSUERANDSERIALNUMBER;
84/** Pointer to the const IPRT representation of a PKCS \#7
85 * IssuerAndSerialNumber. */
86typedef RTCRPKCS7ISSUERANDSERIALNUMBER const *PCRTCRPKCS7ISSUERANDSERIALNUMBER;
87RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7ISSUERANDSERIALNUMBER, RTDECL, RTCrPkcs7IssuerAndSerialNumber, SeqCore.Asn1Core);
88
89
90/** Pointer to the IPRT representation of a PKCS \#7 SignerInfo. */
91typedef struct RTCRPKCS7SIGNERINFO *PRTCRPKCS7SIGNERINFO;
92/** Pointer to the const IPRT representation of a PKCS \#7 SignerInfo. */
93typedef struct RTCRPKCS7SIGNERINFO const *PCRTCRPKCS7SIGNERINFO;
94RTASN1_IMPL_GEN_SET_OF_TYPEDEFS_AND_PROTOS(RTCRPKCS7SIGNERINFOS, RTCRPKCS7SIGNERINFO, RTDECL, RTCrPkcs7SignerInfos);
95
96
97/**
98 * Attribute value type (for the union).
99 */
100typedef enum RTCRPKCS7ATTRIBUTETYPE
101{
102 /** Zero is invalid. */
103 RTCRPKCS7ATTRIBUTETYPE_INVALID = 0,
104 /** Not present, union is NULL. */
105 RTCRPKCS7ATTRIBUTETYPE_NOT_PRESENT,
106 /** Unknown values, pCores. */
107 RTCRPKCS7ATTRIBUTETYPE_UNKNOWN,
108 /** Object IDs, use pObjIds. */
109 RTCRPKCS7ATTRIBUTETYPE_OBJ_IDS,
110 /** Octet strings, use pOctetStrings. */
111 RTCRPKCS7ATTRIBUTETYPE_OCTET_STRINGS,
112 /** Counter signatures (PKCS \#9), use pCounterSignatures.
113 * RTCR_PKCS9_ID_COUNTER_SIGNATURE_OID - 1.2.840.113549.1.9.6. */
114 RTCRPKCS7ATTRIBUTETYPE_COUNTER_SIGNATURES,
115 /** Signing time (PKCS \#9), use pSigningTime.
116 * RTCR_PKCS9_ID_SIGNING_TIME_OID - 1.2.840.113549.1.9.5. */
117 RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME,
118 /** Microsoft timestamp info (RFC-3161) signed data, use pContentInfo.
119 * RTCR_PKCS9_ID_MS_TIMESTAMP - 1.3.6.1.4.1.311.3.3.1. */
120 RTCRPKCS7ATTRIBUTETYPE_MS_TIMESTAMP,
121 /** Microsoft nested PKCS\#7 signature (signtool /as).
122 * RTCR_PKCS9_ID_MS_NESTED_SIGNATURE - 1.3.6.1.4.1.311.2.4.1. */
123 RTCRPKCS7ATTRIBUTETYPE_MS_NESTED_SIGNATURE,
124 /** Microsoft statement type, use pObjIdSeqs.
125 * RTCR_PKCS9_ID_MS_STATEMENT_TYPE - 1.3.6.1.4.1.311.2.1.11. */
126 RTCRPKCS7ATTRIBUTETYPE_MS_STATEMENT_TYPE,
127 /** Apple plist with the all code directory digests, use pOctetStrings.
128 * RTCR_PKCS9_ID_APPLE_MULTI_CD_PLIST - 1.2.840.113635.100.9.1. */
129 RTCRPKCS7ATTRIBUTETYPE_APPLE_MULTI_CD_PLIST,
130 /** Blow the type up to 32-bits. */
131 RTCRPKCS7ATTRIBUTETYPE_32BIT_HACK = 0x7fffffff
132} RTCRPKCS7ATTRIBUTETYPE;
133
134/**
135 * PKCS \#7 Attribute (IPRT representation).
136 */
137typedef struct RTCRPKCS7ATTRIBUTE
138{
139 /** Sequence core. */
140 RTASN1SEQUENCECORE SeqCore;
141 /** The attribute type (object ID). */
142 RTASN1OBJID Type;
143 /** The type of data found in the values union. */
144 RTCRPKCS7ATTRIBUTETYPE enmType;
145 /** Value allocation. */
146 RTASN1ALLOCATION Allocation;
147 /** Values. */
148 union
149 {
150 /** ASN.1 cores (RTCRPKCS7ATTRIBUTETYPE_UNKNOWN). */
151 PRTASN1SETOFCORES pCores;
152 /** ASN.1 object identifiers (RTCRPKCS7ATTRIBUTETYPE_OBJ_IDS). */
153 PRTASN1SETOFOBJIDS pObjIds;
154 /** Sequence of ASN.1 object identifiers (RTCRPKCS7ATTRIBUTETYPE_MS_STATEMENT_TYPE). */
155 PRTASN1SETOFOBJIDSEQS pObjIdSeqs;
156 /** ASN.1 octet strings (RTCRPKCS7ATTRIBUTETYPE_OCTET_STRINGS). */
157 PRTASN1SETOFOCTETSTRINGS pOctetStrings;
158 /** Counter signatures RTCRPKCS7ATTRIBUTETYPE_COUNTER_SIGNATURES(). */
159 PRTCRPKCS7SIGNERINFOS pCounterSignatures;
160 /** Signing time(s) (RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME). */
161 PRTASN1SETOFTIMES pSigningTime;
162 /** Microsoft timestamp (RFC-3161 signed data, RTCRPKCS7ATTRIBUTETYPE_MS_TIMESTAMP),
163 * Microsoft nested signature (RTCRPKCS7ATTRIBUTETYPE_MS_NESTED_SIGNATURE). */
164 struct RTCRPKCS7SETOFCONTENTINFOS *pContentInfos;
165 } uValues;
166} RTCRPKCS7ATTRIBUTE;
167/** Pointer to the IPRT representation of a PKCS \#7 Attribute. */
168typedef RTCRPKCS7ATTRIBUTE *PRTCRPKCS7ATTRIBUTE;
169/** Pointer to the const IPRT representation of a PKCS \#7 Attribute. */
170typedef RTCRPKCS7ATTRIBUTE const *PCRTCRPKCS7ATTRIBUTE;
171RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7ATTRIBUTE, RTDECL, RTCrPkcs7Attribute, SeqCore.Asn1Core);
172
173RTDECL(int) RTCrPkcs7Attribute_SetAppleMultiCdPlist(PRTCRPKCS7ATTRIBUTE pThis, PCRTASN1SETOFOCTETSTRINGS pToClone,
174 PCRTASN1ALLOCATORVTABLE pAllocator);
175RTDECL(int) RTCrPkcs7Attribute_SetContentType(PRTCRPKCS7ATTRIBUTE pThis, PCRTASN1SETOFOBJIDS pToClone,
176 PCRTASN1ALLOCATORVTABLE pAllocator);
177RTDECL(int) RTCrPkcs7Attribute_SetCounterSignatures(PRTCRPKCS7ATTRIBUTE pThis, PCRTCRPKCS7SIGNERINFOS pToClone,
178 PCRTASN1ALLOCATORVTABLE pAllocator);
179RTDECL(int) RTCrPkcs7Attribute_SetMessageDigest(PRTCRPKCS7ATTRIBUTE pThis, PCRTASN1SETOFOCTETSTRINGS pToClone,
180 PCRTASN1ALLOCATORVTABLE pAllocator);
181RTDECL(int) RTCrPkcs7Attribute_SetMsStatementType(PRTCRPKCS7ATTRIBUTE pThis, PCRTASN1SETOFOBJIDSEQS pToClone,
182 PCRTASN1ALLOCATORVTABLE pAllocator);
183RTDECL(int) RTCrPkcs7Attribute_SetMsNestedSignature(PRTCRPKCS7ATTRIBUTE pThis, struct RTCRPKCS7SETOFCONTENTINFOS const *pToClone,
184 PCRTASN1ALLOCATORVTABLE pAllocator);
185RTDECL(int) RTCrPkcs7Attribute_SetMsTimestamp(PRTCRPKCS7ATTRIBUTE pThis, struct RTCRPKCS7SETOFCONTENTINFOS const *pToClone,
186 PCRTASN1ALLOCATORVTABLE pAllocator);
187RTDECL(int) RTCrPkcs7Attribute_SetSigningTime(PRTCRPKCS7ATTRIBUTE pThis, PCRTASN1SETOFTIMES pToClone,
188 PCRTASN1ALLOCATORVTABLE pAllocator);
189
190RTASN1_IMPL_GEN_SET_OF_TYPEDEFS_AND_PROTOS(RTCRPKCS7ATTRIBUTES, RTCRPKCS7ATTRIBUTE, RTDECL, RTCrPkcs7Attributes);
191
192RTDECL(int) RTCrPkcs7Attributes_HashAttributes(PRTCRPKCS7ATTRIBUTES pAttributes, RTCRDIGEST hDigest, PRTERRINFO pErrInfo);
193
194
195/**
196 * One PKCS \#7 SignerInfo (IPRT representation).
197 */
198typedef struct RTCRPKCS7SIGNERINFO
199{
200 /** Sequence core. */
201 RTASN1SEQUENCECORE SeqCore;
202 /** The structure version (RTCRPKCS7SIGNERINFO_V1). */
203 RTASN1INTEGER Version;
204 /** The issuer and serial number of the certificate used to produce the
205 * encrypted digest below. */
206 RTCRPKCS7ISSUERANDSERIALNUMBER IssuerAndSerialNumber;
207 /** The digest algorithm use to digest the signed content. */
208 RTCRX509ALGORITHMIDENTIFIER DigestAlgorithm;
209 /** Authenticated attributes, optional [0].
210 * @todo Check how other producers formats this. The microsoft one does not
211 * have explicit tags, but combines it with the SET OF. */
212 RTCRPKCS7ATTRIBUTES AuthenticatedAttributes;
213 /** The digest encryption algorithm use to encrypt the digest of the signed
214 * content. */
215 RTCRX509ALGORITHMIDENTIFIER DigestEncryptionAlgorithm;
216 /** The encrypted digest. */
217 RTASN1OCTETSTRING EncryptedDigest;
218 /** Unauthenticated attributes, optional [1].
219 * @todo Check how other producers formats this. The microsoft one does not
220 * have explicit tags, but combines it with the SET OF. */
221 RTCRPKCS7ATTRIBUTES UnauthenticatedAttributes;
222} RTCRPKCS7SIGNERINFO;
223RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7SIGNERINFO, RTDECL, RTCrPkcs7SignerInfo, SeqCore.Asn1Core);
224
225RTDECL(int) RTCrPkcs7SignerInfo_SetAuthenticatedAttributes(PRTCRPKCS7SIGNERINFO pThis, PCRTCRPKCS7ATTRIBUTES pAttributes,
226 PCRTASN1ALLOCATORVTABLE pAllocator);
227RTDECL(int) RTCrPkcs7SignerInfo_SetUnauthenticatedAttributes(PRTCRPKCS7SIGNERINFO pThis, PCRTCRPKCS7ATTRIBUTES pAttributes,
228 PCRTASN1ALLOCATORVTABLE pAllocator);
229
230/** RTCRPKCS7SIGNERINFO::Version value. */
231#define RTCRPKCS7SIGNERINFO_V1 1
232
233/** @name PKCS \#9 Attribute IDs
234 * @{ */
235/** Content type (RFC-2630 11.1).
236 * Value: Object Identifier */
237#define RTCR_PKCS9_ID_CONTENT_TYPE_OID "1.2.840.113549.1.9.3"
238/** Message digest (RFC-2630 11.2).
239 * Value: Octet string. */
240#define RTCR_PKCS9_ID_MESSAGE_DIGEST_OID "1.2.840.113549.1.9.4"
241/** Signing time (RFC-2630 11.3).
242 * Value: Octet string. */
243#define RTCR_PKCS9_ID_SIGNING_TIME_OID "1.2.840.113549.1.9.5"
244/** Counter signature (RFC-2630 11.4).
245 * Value: SignerInfo. */
246#define RTCR_PKCS9_ID_COUNTER_SIGNATURE_OID "1.2.840.113549.1.9.6"
247/** Microsoft timestamp (RTF-3161) counter signature (SignedData).
248 * @remarks This isn't defined by PKCS \#9, but lumped in here for convenience. It's actually listed as SPC by MS. */
249#define RTCR_PKCS9_ID_MS_TIMESTAMP "1.3.6.1.4.1.311.3.3.1"
250/** Microsoft nested PKCS\#7 signature.
251 * @remarks This isn't defined by PKCS \#9, but lumped in here for convenience. */
252#define RTCR_PKCS9_ID_MS_NESTED_SIGNATURE "1.3.6.1.4.1.311.2.4.1"
253/** Microsoft statement type.
254 * @remarks This isn't defined by PKCS \#9, but lumped in here for convenience. It's actually listed as SPC by MS. */
255#define RTCR_PKCS9_ID_MS_STATEMENT_TYPE "1.3.6.1.4.1.311.2.1.11"
256/** Microsoft opus info.
257 * @remarks This isn't defined by PKCS \#9, but lumped in here for convenience. It's actually listed as SPC by MS. */
258#define RTCR_PKCS9_ID_MS_SP_OPUS_INFO "1.3.6.1.4.1.311.2.1.12"
259/** Apple code signing multi-code-directory plist.
260 * @remarks This isn't defined by PKCS \#9, but lumped in here for convenience. */
261#define RTCR_PKCS9_ID_APPLE_MULTI_CD_PLIST "1.2.840.113635.100.9.1"
262/** @} */
263
264
265/**
266 * Get the (next) signing time attribute from the specfied SignerInfo or one of
267 * the immediate counter signatures.
268 *
269 * @returns Pointer to the signing time if found, NULL if not.
270 * @param pThis The SignerInfo to search.
271 * @param ppSignerInfo Pointer to variable keeping track of the
272 * enumeration, optional.
273 *
274 * If specified the input value is taken to the be
275 * SignerInfo of the previously returned signing
276 * time. The value pointed to is NULL, the
277 * search/enum restarts.
278 *
279 * On successful return this is set to the
280 * SignerInfo which we found the signing time in.
281 */
282RTDECL(PCRTASN1TIME) RTCrPkcs7SignerInfo_GetSigningTime(PCRTCRPKCS7SIGNERINFO pThis, PCRTCRPKCS7SIGNERINFO *ppSignerInfo);
283
284
285/**
286 * Get the (first) timestamp from within a Microsoft timestamp server counter
287 * signature.
288 *
289 * @returns Pointer to the signing time if found, NULL if not.
290 * @param pThis The SignerInfo to search.
291 * @param ppContentInfoRet Where to return the pointer to the counter
292 * signature, optional.
293 */
294RTDECL(PCRTASN1TIME) RTCrPkcs7SignerInfo_GetMsTimestamp(PCRTCRPKCS7SIGNERINFO pThis,
295 struct RTCRPKCS7CONTENTINFO const **ppContentInfoRet);
296
297
298
299/**
300 * PKCS \#7 ContentInfo (IPRT representation).
301 */
302typedef struct RTCRPKCS7CONTENTINFO
303{
304 /** Sequence core. */
305 RTASN1SEQUENCECORE SeqCore;
306 /** Object ID identifying the content below. */
307 RTASN1OBJID ContentType;
308 /** Content, optional, explicit tag 0.
309 *
310 * Hack alert! This should've been an explict context tag 0 structure with a
311 * type selected according to ContentType. However, it's simpler to replace the
312 * explicit context with an OCTET STRING with implict tag 0. Then we can tag
313 * along on the encapsulation logic RTASN1OCTETSTRING provides for the dynamic
314 * inner type. The default decoder code will detect known structures as
315 * outlined in the union below, and decode the octet string content as an
316 * anonymous RTASN1CORE if not known.
317 *
318 * If the user want to decode the octet string content differently, it can do so
319 * by destroying and freeing the current encapsulated pointer, replacing it with
320 * it's own. (Of course following the RTASN1OCTETSTRING rules.) Just remember
321 * to also update the value in the union.
322 *
323 * @remarks What's signed and verified is Content.pEncapsulated->uData.pv.
324 */
325 RTASN1OCTETSTRING Content;
326 /** Pointer to the CMS octet string that's inside the Content, NULL if PKCS \#7.
327 *
328 * Hack alert! When transitioning from PKCS \#7 to CMS, the designers decided to
329 * change things and add another wrapper. This time we're talking about a real
330 * octet string, not like the one above which is really an explicit content tag.
331 * When constructing or decoding CMS content, this will be the same pointer as
332 * Content.pEncapsulated, while the union below will be holding the same pointer
333 * as pCmsContent->pEncapsulated.
334 */
335 PRTASN1OCTETSTRING pCmsContent;
336 /** Same as Content.pEncapsulated, except a choice of known types. */
337 union
338 {
339 /** ContentType is RTCRPKCS7SIGNEDDATA_OID. */
340 struct RTCRPKCS7SIGNEDDATA *pSignedData;
341 /** ContentType is RTCRSPCINDIRECTDATACONTENT_OID. */
342 struct RTCRSPCINDIRECTDATACONTENT *pIndirectDataContent;
343 /** ContentType is RTCRTSPTSTINFO_OID. */
344 struct RTCRTSPTSTINFO *pTstInfo;
345 /** Generic / Unknown / User. */
346 PRTASN1CORE pCore;
347 } u;
348} RTCRPKCS7CONTENTINFO;
349/** Pointer to the IPRT representation of a PKCS \#7 ContentInfo. */
350typedef RTCRPKCS7CONTENTINFO *PRTCRPKCS7CONTENTINFO;
351/** Pointer to the const IPRT representation of a PKCS \#7 ContentInfo. */
352typedef RTCRPKCS7CONTENTINFO const *PCRTCRPKCS7CONTENTINFO;
353RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7CONTENTINFO, RTDECL, RTCrPkcs7ContentInfo, SeqCore.Asn1Core);
354RTASN1_IMPL_GEN_SET_OF_TYPEDEFS_AND_PROTOS(RTCRPKCS7SETOFCONTENTINFOS, RTCRPKCS7CONTENTINFO, RTDECL, RTCrPkcs7SetOfContentInfos);
355
356RTDECL(bool) RTCrPkcs7ContentInfo_IsSignedData(PCRTCRPKCS7CONTENTINFO pThis);
357
358
359/**
360 * PKCS \#7 Certificate choice.
361 */
362typedef enum RTCRPKCS7CERTCHOICE
363{
364 RTCRPKCS7CERTCHOICE_INVALID = 0,
365 RTCRPKCS7CERTCHOICE_X509,
366 RTCRPKCS7CERTCHOICE_EXTENDED_PKCS6,
367 RTCRPKCS7CERTCHOICE_AC_V1,
368 RTCRPKCS7CERTCHOICE_AC_V2,
369 RTCRPKCS7CERTCHOICE_OTHER,
370 RTCRPKCS7CERTCHOICE_END,
371 RTCRPKCS7CERTCHOICE_32BIT_HACK = 0x7fffffff
372} RTCRPKCS7CERTCHOICE;
373
374
375/**
376 * Common representation for PKCS \#7 ExtendedCertificateOrCertificate and the
377 * CMS CertificateChoices types.
378 */
379typedef struct RTCRPKCS7CERT
380{
381 /** Dummy ASN.1 record, not encoded. */
382 RTASN1DUMMY Dummy;
383 /** The value allocation. */
384 RTASN1ALLOCATION Allocation;
385 /** The choice of value. */
386 RTCRPKCS7CERTCHOICE enmChoice;
387 /** The value union. */
388 union
389 {
390 /** Standard X.509 certificate (RTCRCMSCERTIFICATECHOICE_X509). */
391 PRTCRX509CERTIFICATE pX509Cert;
392 /** Extended PKCS \#6 certificate (RTCRCMSCERTIFICATECHOICE_EXTENDED_PKCS6). */
393 PRTASN1CORE pExtendedCert;
394 /** Attribute certificate version 1 (RTCRCMSCERTIFICATECHOICE_AC_V1). */
395 PRTASN1CORE pAcV1;
396 /** Attribute certificate version 2 (RTCRCMSCERTIFICATECHOICE_AC_V2). */
397 PRTASN1CORE pAcV2;
398 /** Other certificate (RTCRCMSCERTIFICATECHOICE_OTHER). */
399 PRTASN1CORE pOtherCert;
400 } u;
401} RTCRPKCS7CERT;
402/** Pointer to the IPRT representation of PKCS \#7 or CMS certificate. */
403typedef RTCRPKCS7CERT *PRTCRPKCS7CERT;
404/** Pointer to the const IPRT representation of PKCS \#7 or CMS certificate. */
405typedef RTCRPKCS7CERT const *PCRTCRPKCS7CERT;
406RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7CERT, RTDECL, RTCrPkcs7Cert, Dummy.Asn1Core);
407RTASN1_IMPL_GEN_SET_OF_TYPEDEFS_AND_PROTOS(RTCRPKCS7SETOFCERTS, RTCRPKCS7CERT, RTDECL, RTCrPkcs7SetOfCerts);
408
409RTDECL(int) RTCrPkcs7Cert_SetX509Cert(PRTCRPKCS7CERT pThis, PCRTCRX509CERTIFICATE pToClone, PCRTASN1ALLOCATORVTABLE pAllocator);
410RTDECL(int) RTCrPkcs7Cert_SetExtendedCert(PRTCRPKCS7CERT pThis, PCRTASN1CORE pToClone, PCRTASN1ALLOCATORVTABLE pAllocator);
411RTDECL(int) RTCrPkcs7Cert_SetAcV1(PRTCRPKCS7CERT pThis, PCRTASN1CORE pToClone, PCRTASN1ALLOCATORVTABLE pAllocator);
412RTDECL(int) RTCrPkcs7Cert_SetAcV2(PRTCRPKCS7CERT pThis, PCRTASN1CORE pToClone, PCRTASN1ALLOCATORVTABLE pAllocator);
413RTDECL(int) RTCrPkcs7Cert_SetOtherCert(PRTCRPKCS7CERT pThis, PCRTASN1CORE pToClone, PCRTASN1ALLOCATORVTABLE pAllocator);
414
415RTDECL(PCRTCRX509CERTIFICATE) RTCrPkcs7SetOfCerts_FindX509ByIssuerAndSerialNumber(PCRTCRPKCS7SETOFCERTS pCertificates,
416 PCRTCRX509NAME pIssuer,
417 PCRTASN1INTEGER pSerialNumber);
418
419
420/**
421 * PKCS \#7 SignedData (IPRT representation).
422 */
423typedef struct RTCRPKCS7SIGNEDDATA
424{
425 /** Sequence core. */
426 RTASN1SEQUENCECORE SeqCore;
427 /** The structure version value (1). */
428 RTASN1INTEGER Version;
429 /** The digest algorithms that are used to signed the content (ContentInfo). */
430 RTCRX509ALGORITHMIDENTIFIERS DigestAlgorithms;
431 /** The content that's being signed. */
432 RTCRPKCS7CONTENTINFO ContentInfo;
433 /** Certificates, optional, implicit tag 0. (Required by Authenticode.) */
434 RTCRPKCS7SETOFCERTS Certificates;
435 /** Certificate revocation lists, optional, implicit tag 1.
436 * Not used by Authenticode, so currently stubbed. */
437 RTASN1CORE Crls;
438 /** Signer infos. */
439 RTCRPKCS7SIGNERINFOS SignerInfos;
440} RTCRPKCS7SIGNEDDATA;
441/** Pointer to the IPRT representation of a PKCS \#7 SignedData. */
442typedef RTCRPKCS7SIGNEDDATA *PRTCRPKCS7SIGNEDDATA;
443/** Pointer to the const IPRT representation of a PKCS \#7 SignedData. */
444typedef RTCRPKCS7SIGNEDDATA const *PCRTCRPKCS7SIGNEDDATA;
445RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7SIGNEDDATA, RTDECL, RTCrPkcs7SignedData, SeqCore.Asn1Core);
446RTASN1_IMPL_GEN_SET_OF_TYPEDEFS_AND_PROTOS(RTCRPKCS7SETOFSIGNEDDATA, RTCRPKCS7SIGNEDDATA, RTDECL, RTCrPkcs7SetOfSignedData);
447
448/** PKCS \#7 SignedData object ID. */
449#define RTCRPKCS7SIGNEDDATA_OID RTCR_PKCS7_SIGNED_DATA_OID
450
451/** PKCS \#7 SignedData version number 1. */
452#define RTCRPKCS7SIGNEDDATA_V1 1
453/* No version 2 seems to exist. */
454/** CMS SignedData version number 3.
455 * This should only be used if there are version 1 attribute certificates
456 * present, or if there are version 3 SignerInfo items present, or if
457 * enmcCountInfo is not id-data (RFC-5652, section 5.1). */
458#define RTCRPKCS7SIGNEDDATA_V3 3
459/** CMS SignedData version number 4.
460 * This should only be used if there are version 2 attribute certificates
461 * present (RFC-5652, section 5.1). */
462#define RTCRPKCS7SIGNEDDATA_V4 4
463/** CMS SignedData version number 5.
464 * This should only be used if there are certificates or/and CRLs of the
465 * OTHER type present (RFC-5652, section 5.1). */
466#define RTCRPKCS7SIGNEDDATA_V5 5
467
468RTDECL(int) RTCrPkcs7SignedData_SetCertificates(PRTCRPKCS7SIGNEDDATA pThis, PCRTCRPKCS7SETOFCERTS pCerts, PCRTASN1ALLOCATORVTABLE pAllocator);
469RTDECL(int) RTCrPkcs7SignedData_SetCrls(PRTCRPKCS7SIGNEDDATA pThis, PCRTASN1CORE pCerts, PCRTASN1ALLOCATORVTABLE pAllocator);
470
471/** @name RTCRPKCS7SIGNEDDATA_SANITY_F_XXX - Flags for RTPkcs7SignedDataCheckSantiy.
472 * @{ */
473/** Check for authenticode restrictions. */
474#define RTCRPKCS7SIGNEDDATA_SANITY_F_AUTHENTICODE RT_BIT_32(0)
475/** Check that all the hash algorithms are known to IPRT. */
476#define RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH RT_BIT_32(1)
477/** Require signing certificate to be present. */
478#define RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT RT_BIT_32(2)
479/** @} */
480
481/** PKCS\#7/CMS (content info) markers. */
482extern RTDATADECL(RTCRPEMMARKER const) g_aRTCrPkcs7Markers[];
483/** Number of entries in g_aRTCrPkcs7Markers. */
484extern RTDATADECL(uint32_t const) g_cRTCrPkcs7Markers;
485
486/** @name Flags for RTCrPkcs7ContentInfo_ReadFromBuffer
487 * @{ */
488/** Only allow PEM certificates, not binary ones.
489 * @sa RTCRPEMREADFILE_F_ONLY_PEM */
490#define RTCRPKCS7_READ_F_PEM_ONLY RT_BIT(1)
491/** @} */
492
493RTDECL(int) RTCrPkcs7_ReadFromBuffer(PRTCRPKCS7CONTENTINFO pContentInfo, const void *pvBuf, size_t cbBuf,
494 uint32_t fFlags, PCRTASN1ALLOCATORVTABLE pAllocator,
495 bool *pfCmsLabeled, PRTERRINFO pErrInfo, const char *pszErrorTag);
496
497
498/**
499 * PKCS \#7 DigestInfo (IPRT representation).
500 */
501typedef struct RTCRPKCS7DIGESTINFO
502{
503 /** Sequence core. */
504 RTASN1SEQUENCECORE SeqCore;
505 /** The digest algorithm use to digest the signed content. */
506 RTCRX509ALGORITHMIDENTIFIER DigestAlgorithm;
507 /** The digest. */
508 RTASN1OCTETSTRING Digest;
509} RTCRPKCS7DIGESTINFO;
510/** Pointer to the IPRT representation of a PKCS \#7 DigestInfo object. */
511typedef RTCRPKCS7DIGESTINFO *PRTCRPKCS7DIGESTINFO;
512/** Pointer to the const IPRT representation of a PKCS \#7 DigestInfo object. */
513typedef RTCRPKCS7DIGESTINFO const *PCRTCRPKCS7DIGESTINFO;
514RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7DIGESTINFO, RTDECL, RTCrPkcs7DigestInfo, SeqCore.Asn1Core);
515
516
517/**
518 * Callback function for use with RTCrPkcs7VerifySignedData.
519 *
520 * @returns IPRT status code.
521 * @param pCert The certificate to verify.
522 * @param hCertPaths Unless the certificate is trusted directly, this
523 * is a reference to the certificate path builder
524 * and verifier instance that we used to establish
525 * at least valid trusted path to @a pCert. The
526 * callback can use this to enforce additional
527 * certificate lineage requirements, effective
528 * policy checks and whatnot.
529 * This is NIL_RTCRX509CERTPATHS if the certificate
530 * is directly trusted.
531 * @param fFlags Mix of the RTCRPKCS7VCC_F_XXX flags.
532 * @param pvUser The user argument.
533 * @param pErrInfo Optional error info buffer.
534 */
535typedef DECLCALLBACKTYPE(int, FNRTCRPKCS7VERIFYCERTCALLBACK,(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths,
536 uint32_t fFlags, void *pvUser, PRTERRINFO pErrInfo));
537/** Pointer to a FNRTCRPKCS7VERIFYCERTCALLBACK callback. */
538typedef FNRTCRPKCS7VERIFYCERTCALLBACK *PFNRTCRPKCS7VERIFYCERTCALLBACK;
539
540/** @name RTCRPKCS7VCC_F_XXX - Flags for FNRTCRPKCS7VERIFYCERTCALLBACK.
541 * @{ */
542/** Normal callback for a direct signatory of the signed data. */
543#define RTCRPKCS7VCC_F_SIGNED_DATA RT_BIT_32(0)
544/** Check that the signatory can be trusted for timestamps. */
545#define RTCRPKCS7VCC_F_TIMESTAMP RT_BIT_32(1)
546/** @} */
547
548/**
549 * @callback_method_impl{FNRTCRPKCS7VERIFYCERTCALLBACK,
550 * Default implementation that checks for the DigitalSignature KeyUsage bit.}
551 */
552RTDECL(int) RTCrPkcs7VerifyCertCallbackDefault(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags,
553 void *pvUser, PRTERRINFO pErrInfo);
554
555/**
556 * @callback_method_impl{FNRTCRPKCS7VERIFYCERTCALLBACK,
557 * Standard code signing. Use this for Microsoft SPC.}
558 */
559RTDECL(int) RTCrPkcs7VerifyCertCallbackCodeSigning(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags,
560 void *pvUser, PRTERRINFO pErrInfo);
561
562/**
563 * Verifies PKCS \#7 SignedData.
564 *
565 * For compatability with alternative crypto providers, the user must work on
566 * the top level PKCS \#7 structure instead directly on the SignedData.
567 *
568 * @returns IPRT status code.
569 * @param pContentInfo PKCS \#7 content info structure.
570 * @param fFlags RTCRPKCS7VERIFY_SD_F_XXX.
571 * @param hAdditionalCerts Store containing additional certificates to
572 * supplement those mentioned in the signed data.
573 * @param hTrustedCerts Store containing trusted certificates.
574 * @param pValidationTime The time we're supposed to validate the
575 * certificates chains at. Ignored for signatures
576 * with valid signing time attributes.
577 * When RTCRPKCS7VERIFY_SD_F_UPDATE_VALIDATION_TIME
578 * is set, this is updated to the actual validation
579 * time used.
580 * @param pfnVerifyCert Callback for checking that a certificate used
581 * for signing the data is suitable.
582 * @param pvUser User argument for the callback.
583 * @param pErrInfo Optional error info buffer.
584 * @sa RTCrPkcs7VerifySignedDataWithExternalData
585 */
586RTDECL(int) RTCrPkcs7VerifySignedData(PCRTCRPKCS7CONTENTINFO pContentInfo, uint32_t fFlags,
587 RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts,
588 PCRTTIMESPEC pValidationTime, PFNRTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, void *pvUser,
589 PRTERRINFO pErrInfo);
590
591
592/**
593 * Verifies PKCS \#7 SignedData with external data.
594 *
595 * For compatability with alternative crypto providers, the user must work on
596 * the top level PKCS \#7 structure instead directly on the SignedData.
597 *
598 * @returns IPRT status code.
599 * @param pContentInfo PKCS \#7 content info structure.
600 * @param fFlags RTCRPKCS7VERIFY_SD_F_XXX.
601 * @param hAdditionalCerts Store containing additional certificates to
602 * supplement those mentioned in the signed data.
603 * @param hTrustedCerts Store containing trusted certificates.
604 * @param pValidationTime The time we're supposed to validate the
605 * certificates chains at. Ignored for signatures
606 * with valid signing time attributes.
607 * When RTCRPKCS7VERIFY_SD_F_UPDATE_VALIDATION_TIME
608 * is set, this is updated to the actual validation
609 * time used.
610 * @param pfnVerifyCert Callback for checking that a certificate used
611 * for signing the data is suitable.
612 * @param pvUser User argument for the callback.
613 * @param pvData The signed external data.
614 * @param cbData The size of the signed external data.
615 * @param pErrInfo Optional error info buffer.
616 * @sa RTCrPkcs7VerifySignedData
617 */
618RTDECL(int) RTCrPkcs7VerifySignedDataWithExternalData(PCRTCRPKCS7CONTENTINFO pContentInfo, uint32_t fFlags,
619 RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts,
620 PCRTTIMESPEC pValidationTime,
621 PFNRTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, void *pvUser,
622 void const *pvData, size_t cbData, PRTERRINFO pErrInfo);
623
624/** @name RTCRPKCS7VERIFY_SD_F_XXX - Flags for RTCrPkcs7VerifySignedData and
625 * RTCrPkcs7VerifySignedDataWithExternalData
626 * @{ */
627/** Always use the signing time attribute if present, requiring it to be
628 * verified as valid. The default behavior is to ignore unverifiable
629 * signing time attributes and use the @a pValidationTime instead. */
630#define RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT RT_BIT_32(0)
631/** Same as RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT for the MS
632 * timestamp counter signatures. */
633#define RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT RT_BIT_32(1)
634/** Only use signing time attributes from counter signatures. */
635#define RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY RT_BIT_32(2)
636/** Don't validate the counter signature containing the signing time, just use
637 * it unverified. This is useful if we don't necessarily have the root
638 * certificates for the timestamp server handy, but use with great care.
639 * @sa RTCRPKCS7VERIFY_SD_F_USE_MS_TIMESTAMP_UNVERIFIED */
640#define RTCRPKCS7VERIFY_SD_F_USE_SIGNING_TIME_UNVERIFIED RT_BIT_32(3)
641/** Don't validate the MS counter signature containing the signing timestamp.
642 * @sa RTCRPKCS7VERIFY_SD_F_USE_SIGNING_TIME_UNVERIFIED */
643#define RTCRPKCS7VERIFY_SD_F_USE_MS_TIMESTAMP_UNVERIFIED RT_BIT_32(4)
644/** Do not consider timestamps in microsoft counter signatures. */
645#define RTCRPKCS7VERIFY_SD_F_IGNORE_MS_TIMESTAMP RT_BIT_32(5)
646/** The signed data requires certificates to have the timestamp extended
647 * usage bit present. This is used for recursivly verifying MS timestamp
648 * signatures. */
649#define RTCRPKCS7VERIFY_SD_F_USAGE_TIMESTAMPING RT_BIT_32(6)
650/** Skip the verification of the certificate trust paths, taking all
651 * certificates to be trustworthy. */
652#define RTCRPKCS7VERIFY_SD_F_TRUST_ALL_CERTS RT_BIT_32(7)
653/** Update @a pValidationTime with the actual validation time used.
654 * This requires RTCRPKCS7VERIFY_SD_F_HAS_SIGNER_INDEX to get a consistent
655 * result. And yeah, it unconst the parameter, which is patently ugly. */
656#define RTCRPKCS7VERIFY_SD_F_UPDATE_VALIDATION_TIME RT_BIT_32(8)
657/** Check trust anchors (@sa RTCrX509CertPathsSetTrustAnchorChecks). */
658#define RTCRPKCS7VERIFY_SD_F_CHECK_TRUST_ANCHORS RT_BIT_32(9)
659
660/** This can be used to only verify one given signer info.
661 * Max index value is 15. */
662#define RTCRPKCS7VERIFY_SD_F_SIGNER_INDEX(a_idxSignerInfo) \
663 ( RTCRPKCS7VERIFY_SD_F_HAS_SIGNER_INDEX \
664 | (((a_idxSignerInfo) & RTCRPKCS7VERIFY_SD_F_SIGNER_INDEX_MAX) << RTCRPKCS7VERIFY_SD_F_SIGNER_INDEX_SHIFT) )
665/** Has a valid value in RTCRPKCS7VERIFY_SD_F_SIGNER_INDEX_MASK. */
666#define RTCRPKCS7VERIFY_SD_F_HAS_SIGNER_INDEX RT_BIT_32(23)
667/** Signer index shift value. */
668#define RTCRPKCS7VERIFY_SD_F_SIGNER_INDEX_SHIFT 24
669/** Signer index mask. */
670#define RTCRPKCS7VERIFY_SD_F_SIGNER_INDEX_MASK UINT32_C(0x0f000000)
671/** Max signer index value (inclusive). */
672#define RTCRPKCS7VERIFY_SD_F_SIGNER_INDEX_MAX \
673 (RTCRPKCS7VERIFY_SD_F_SIGNER_INDEX_MASK >> RTCRPKCS7VERIFY_SD_F_SIGNER_INDEX_SHIFT)
674
675/** Indicates internally that we're validating a counter signature and should
676 * use different rules when checking out the authenticated attributes.
677 * @internal */
678#define RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE RT_BIT_32(31)
679/** @} */
680
681
682RTDECL(int) RTCrPkcs7SimpleSignSignedData(uint32_t fFlags, PCRTCRX509CERTIFICATE pSigner, RTCRKEY hPrivateKey,
683 void const *pvData, size_t cbData, RTDIGESTTYPE enmDigestType,
684 RTCRSTORE hAdditionalCerts, PCRTCRPKCS7ATTRIBUTES pAdditionalAuthenticatedAttribs,
685 void *pvResult, size_t *pcbResult, PRTERRINFO pErrInfo);
686
687/** @name RTCRPKCS7SIGN_SD_F_XXX - Flags for RTCrPkcs7SimpleSign.
688 * @{ */
689/** Detached data. */
690#define RTCRPKCS7SIGN_SD_F_DEATCHED RT_BIT_32(0)
691/** No SMIME capabilities attribute. */
692#define RTCRPKCS7SIGN_SD_F_NO_SMIME_CAP RT_BIT_32(1)
693/** Produce version 1 output (PKCS\#7), rather than version 3 (CMS). */
694#define RTCRPKCS7SIGN_SD_F_USE_V1 RT_BIT_32(2)
695/** Avoid extra OCTET STRING encapsulation around the data blob.
696 * This is needed for Authenticode signatures. This requires that the
697 * content type is supplied via the additional authenticated attributes.
698 * @note Currently only works with RTCRPKCS7SIGN_SD_F_USE_V1. */
699#define RTCRPKCS7SIGN_SD_F_NO_DATA_ENCAP RT_BIT_32(3)
700/** Valid flag mask. */
701#define RTCRPKCS7SIGN_SD_F_VALID_MASK UINT32_C(0x0000000f)
702/** @} */
703
704/** @} */
705
706RT_C_DECLS_END
707
708#endif /* !IPRT_INCLUDED_crypto_pkcs7_h */
709
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette