VirtualBox

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

Last change on this file since 52537 was 52537, checked in by vboxsync, 10 years ago

IPRT,SUP: First part of timestamp counter signatures support.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.4 KB
Line 
1/** @file
2 * IPRT - PKCS \#7, Cryptographic Message Syntax Standard (aka CMS).
3 */
4
5/*
6 * Copyright (C) 2006-2014 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_crypto_pkcs7_h
27#define ___iprt_crypto_pkcs7_h
28
29#include <iprt/asn1.h>
30#include <iprt/crypto/x509.h>
31
32
33RT_C_DECLS_BEGIN
34
35/** @defgroup grp_rt_crpkcs7 RTCrPkcs7 - PKCS \#7, Cryptographic Message Syntax Standard (aka CMS).
36 * @ingroup grp_rt_crypto
37 * @{
38 */
39
40
41/**
42 * PKCS \#7 IssuerAndSerialNumber (IPRT representation).
43 */
44typedef struct RTCRPKCS7ISSUERANDSERIALNUMBER
45{
46 /** Sequence core. */
47 RTASN1SEQUENCECORE SeqCore;
48 /** The certificate name. */
49 RTCRX509NAME Name;
50 /** The certificate serial number. */
51 RTASN1INTEGER SerialNumber;
52} RTCRPKCS7ISSUERANDSERIALNUMBER;
53/** Pointer to the IPRT representation of a PKCS \#7 IssuerAndSerialNumber. */
54typedef RTCRPKCS7ISSUERANDSERIALNUMBER *PRTCRPKCS7ISSUERANDSERIALNUMBER;
55/** Pointer to the const IPRT representation of a PKCS \#7
56 * IssuerAndSerialNumber. */
57typedef RTCRPKCS7ISSUERANDSERIALNUMBER const *PCRTCRPKCS7ISSUERANDSERIALNUMBER;
58RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7ISSUERANDSERIALNUMBER, RTDECL, RTCrPkcs7IssuerAndSerialNumber, SeqCore.Asn1Core);
59
60
61/** Pointer to the IPRT representation of a PKCS \#7 SignerInfo. */
62typedef struct RTCRPKCS7SIGNERINFO *PRTCRPKCS7SIGNERINFO;
63/** Pointer to the const IPRT representation of a PKCS \#7 SignerInfo. */
64typedef struct RTCRPKCS7SIGNERINFO const *PCRTCRPKCS7SIGNERINFO;
65RTASN1_IMPL_GEN_SET_OF_TYPEDEFS_AND_PROTOS(RTCRPKCS7SIGNERINFOS, RTCRPKCS7SIGNERINFO, RTDECL, RTCrPkcs7SignerInfos);
66
67
68/**
69 * Attribute value type (for the union).
70 */
71typedef enum RTCRPKCS7ATTRIBUTETYPE
72{
73 /** Zero is invalid. */
74 RTCRPKCS7ATTRIBUTETYPE_INVALID = 0,
75 /** Not present, union is NULL. */
76 RTCRPKCS7ATTRIBUTETYPE_NOT_PRESENT,
77 /** Unknown values, pCores. */
78 RTCRPKCS7ATTRIBUTETYPE_UNKNOWN,
79 /** Object IDs, use pObjIds. */
80 RTCRPKCS7ATTRIBUTETYPE_OBJ_IDS,
81 /** Octet strings, use pOctetStrings. */
82 RTCRPKCS7ATTRIBUTETYPE_OCTET_STRINGS,
83 /** Counter signatures (PKCS \#9), use pCounterSignatures. */
84 RTCRPKCS7ATTRIBUTETYPE_COUNTER_SIGNATURES,
85 /** Signing time (PKCS \#9), use pSigningTime. */
86 RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME,
87 /** Blow the type up to 32-bits. */
88 RTCRPKCS7ATTRIBUTETYPE_32BIT_HACK = 0x7fffffff
89} RTCRPKCS7ATTRIBUTETYPE;
90
91/**
92 * PKCS \#7 Attribute (IPRT representation).
93 */
94typedef struct RTCRPKCS7ATTRIBUTE
95{
96 /** Sequence core. */
97 RTASN1SEQUENCECORE SeqCore;
98 /** The attribute type (object ID). */
99 RTASN1OBJID Type;
100 /** The type of data found in the values union. */
101 RTCRPKCS7ATTRIBUTETYPE enmType;
102 /** Value allocation. */
103 RTASN1ALLOCATION Allocation;
104 /** Values. */
105 union
106 {
107 /** ASN.1 cores (RTCRPKCS7ATTRIBUTETYPE_UNKNOWN). */
108 PRTASN1SETOFCORES pCores;
109 /** ASN.1 object identifiers (RTCRPKCS7ATTRIBUTETYPE_OBJ_IDS). */
110 PRTASN1SETOFOBJIDS pObjIds;
111 /** ASN.1 octet strings (RTCRPKCS7ATTRIBUTETYPE_OCTET_STRINGS). */
112 PRTASN1SETOFOCTETSTRINGS pOctetStrings;
113 /** Counter signatures RTCRPKCS7ATTRIBUTETYPE_COUNTER_SIGNATURES(). */
114 PRTCRPKCS7SIGNERINFOS pCounterSignatures;
115 /** Signing time(s) (RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME). */
116 PRTASN1SETOFTIMES pSigningTime;
117 } uValues;
118} RTCRPKCS7ATTRIBUTE;
119/** Pointer to the IPRT representation of a PKCS \#7 Attribute. */
120typedef RTCRPKCS7ATTRIBUTE *PRTCRPKCS7ATTRIBUTE;
121/** Pointer to the const IPRT representation of a PKCS \#7 Attribute. */
122typedef RTCRPKCS7ATTRIBUTE const *PCRTCRPKCS7ATTRIBUTE;
123RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7ATTRIBUTE, RTDECL, RTCrPkcs7Attribute, SeqCore.Asn1Core);
124
125RTASN1_IMPL_GEN_SET_OF_TYPEDEFS_AND_PROTOS(RTCRPKCS7ATTRIBUTES, RTCRPKCS7ATTRIBUTE, RTDECL, RTCrPkcs7Attributes);
126
127
128/**
129 * One PKCS \#7 SignerInfo (IPRT representation).
130 */
131typedef struct RTCRPKCS7SIGNERINFO
132{
133 /** Sequence core. */
134 RTASN1SEQUENCECORE SeqCore;
135 /** The structure version (RTCRPKCS7SIGNERINFO_V1). */
136 RTASN1INTEGER Version;
137 /** The issuer and serial number of the certificate used to produce the
138 * encrypted digest below. */
139 RTCRPKCS7ISSUERANDSERIALNUMBER IssuerAndSerialNumber;
140 /** The digest algorithm use to digest the signed content. */
141 RTCRX509ALGORITHMIDENTIFIER DigestAlgorithm;
142 /** Authenticated attributes, optional [0].
143 * @todo Check how other producers formats this. The microsoft one does not
144 * have explicit tags, but combines it with the SET OF. */
145 RTCRPKCS7ATTRIBUTES AuthenticatedAttributes;
146 /** The digest encryption algorithm use to encrypt the digest of the signed
147 * content. */
148 RTCRX509ALGORITHMIDENTIFIER DigestEncryptionAlgorithm;
149 /** The encrypted digest. */
150 RTASN1OCTETSTRING EncryptedDigest;
151 /** Unauthenticated attributes, optional [1].
152 * @todo Check how other producers formats this. The microsoft one does not
153 * have explicit tags, but combines it with the SET OF. */
154 RTCRPKCS7ATTRIBUTES UnauthenticatedAttributes;
155} RTCRPKCS7SIGNERINFO;
156RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7SIGNERINFO, RTDECL, RTCrPkcs7SignerInfo, SeqCore.Asn1Core);
157
158/** RTCRPKCS7SIGNERINFO::Version value. */
159#define RTCRPKCS7SIGNERINFO_V1 1
160
161/** @name PKCS \#9 Attribute IDs
162 * @{ */
163/** Content type (RFC-2630 11.1).
164 * Value: Object Identifier */
165#define RTCR_PKCS9_ID_CONTENT_TYPE_OID "1.2.840.113549.1.9.3"
166/** Message digest (RFC-2630 11.2).
167 * Value: Octet string. */
168#define RTCR_PKCS9_ID_MESSAGE_DIGEST_OID "1.2.840.113549.1.9.4"
169/** Signing time (RFC-2630 11.3).
170 * Value: Octet string. */
171#define RTCR_PKCS9_ID_SIGNING_TIME_OID "1.2.840.113549.1.9.5"
172/** Counter signature (RFC-2630 11.4).
173 * Value: SignerInfo. */
174#define RTCR_PKCS9_ID_COUNTER_SIGNATURE_OID "1.2.840.113549.1.9.6"
175/** @} */
176
177/**
178 * Get the (next) signing time attribute from the specfied SignerInfo or one of
179 * the immediate counter signatures.
180 *
181 * @returns Pointer to the signing time if found, NULL if not.
182 * @param pThis The SignerInfo to search.
183 * @param ppSignerInfo Pointer to variable keeping track of the
184 * enumeration, optional.
185 *
186 * If specified the input value is taken to the be
187 * SignerInfo of the previously returned signing
188 * time. The value pointed to is NULL, the
189 * search/enum restarts.
190 *
191 * On successful return this is set to the
192 * SignerInfo which we found the signing time in.
193 */
194RTDECL(PCRTASN1TIME) RTCrPkcs7SignerInfo_GetSigningTime(PCRTCRPKCS7SIGNERINFO pThis, PCRTCRPKCS7SIGNERINFO *ppSignerInfo);
195
196
197
198/**
199 * PKCS \#7 ContentInfo (IPRT representation).
200 */
201typedef struct RTCRPKCS7CONTENTINFO
202{
203 /** Sequence core. */
204 RTASN1SEQUENCECORE SeqCore;
205 /** Object ID identifying the content below. */
206 RTASN1OBJID ContentType;
207 /** Content, optional, explicit tag 0.
208 *
209 * Hack alert! This should've been an explict context tag 0 structure with a
210 * type selected according to ContentType. However, it's simpler to replace the
211 * explicit context with an OCTET STRING with implict tag 0. Then we can tag
212 * along on the encapsulation logic RTASN1OCTETSTRING provides for the dynamic
213 * inner type. The default decoder code will detect known structures as
214 * outlined in the union below, and decode the octet string content as an
215 * anonymous RTASN1CORE if not known.
216 *
217 * If the user want to decode the octet string content differently, it can do so
218 * by destroying and freeing the current encapsulated pointer, replacing it with
219 * it's own. (Of course following the RTASN1OCTETSTRING rules.) Just remember
220 * to also update the value in the union.
221 *
222 * @remarks What's signed and verified is Content.pEncapsulated->uData.pv.
223 */
224 RTASN1OCTETSTRING Content;
225 /** Same as Content.pEncapsulated, except a choice of known types. */
226 union
227 {
228 /** ContentType is RTCRPKCS7SIGNEDDATA_OID. */
229 struct RTCRPKCS7SIGNEDDATA *pSignedData;
230 /** ContentType is RTCRSPCINDIRECTDATACONTENT_OID. */
231 struct RTCRSPCINDIRECTDATACONTENT *pIndirectDataContent;
232 /** Generic / Unknown / User. */
233 PRTASN1CORE pCore;
234 } u;
235} RTCRPKCS7CONTENTINFO;
236/** Pointer to the IPRT representation of a PKCS \#7 ContentInfo. */
237typedef RTCRPKCS7CONTENTINFO *PRTCRPKCS7CONTENTINFO;
238/** Pointer to the const IPRT representation of a PKCS \#7 ContentInfo. */
239typedef RTCRPKCS7CONTENTINFO const *PCRTCRPKCS7CONTENTINFO;
240
241RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7CONTENTINFO, RTDECL, RTCrPkcs7ContentInfo, SeqCore.Asn1Core);
242
243RTDECL(bool) RTCrPkcs7ContentInfo_IsSignedData(PCRTCRPKCS7CONTENTINFO pThis);
244
245
246/**
247 * PKCS \#7 SignedData (IPRT representation).
248 */
249typedef struct RTCRPKCS7SIGNEDDATA
250{
251 /** Sequence core. */
252 RTASN1SEQUENCECORE SeqCore;
253 /** The structure version value (1). */
254 RTASN1INTEGER Version;
255 /** The digest algorithms that are used to signed the content (ContentInfo). */
256 RTCRX509ALGORITHMIDENTIFIERS DigestAlgorithms;
257 /** The content that's being signed. */
258 RTCRPKCS7CONTENTINFO ContentInfo;
259 /** Certificates, optional, implicit tag 0. (Required by Authenticode.) */
260 RTCRX509CERTIFICATES Certificates;
261 /** Certificate revocation lists, optional, implicit tag 1.
262 * Not used by Authenticode, so currently stubbed. */
263 RTASN1CORE Crls;
264 /** Signer infos. */
265 RTCRPKCS7SIGNERINFOS SignerInfos;
266} RTCRPKCS7SIGNEDDATA;
267/** Pointer to the IPRT representation of a PKCS \#7 SignedData. */
268typedef RTCRPKCS7SIGNEDDATA *PRTCRPKCS7SIGNEDDATA;
269/** Pointer to the const IPRT representation of a PKCS \#7 SignedData. */
270typedef RTCRPKCS7SIGNEDDATA const *PCRTCRPKCS7SIGNEDDATA;
271RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7SIGNEDDATA, RTDECL, RTCrPkcs7SignedData, SeqCore.Asn1Core);
272
273/** PKCS \#7 SignedData object ID. */
274#define RTCRPKCS7SIGNEDDATA_OID "1.2.840.113549.1.7.2"
275
276/** PKCS \#7 SignedData version number 1. */
277#define RTCRPKCS7SIGNEDDATA_V1 1
278
279
280/** @name RTCRPKCS7SIGNEDDATA_SANITY_F_XXX - Flags for RTPkcs7SignedDataCheckSantiy.
281 * @{ */
282/** Check for authenticode restrictions. */
283#define RTCRPKCS7SIGNEDDATA_SANITY_F_AUTHENTICODE RT_BIT_32(0)
284/** Check that all the hash algorithms are known to IPRT. */
285#define RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH RT_BIT_32(1)
286/** Require signing certificate to be present. */
287#define RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT RT_BIT_32(2)
288/** @} */
289
290
291/**
292 * PKCS \#7 DigestInfo (IPRT representation).
293 */
294typedef struct RTCRPKCS7DIGESTINFO
295{
296 /** Sequence core. */
297 RTASN1SEQUENCECORE SeqCore;
298 /** The digest algorithm use to digest the signed content. */
299 RTCRX509ALGORITHMIDENTIFIER DigestAlgorithm;
300 /** The digest. */
301 RTASN1OCTETSTRING Digest;
302} RTCRPKCS7DIGESTINFO;
303/** Pointer to the IPRT representation of a PKCS \#7 DigestInfo object. */
304typedef RTCRPKCS7DIGESTINFO *PRTCRPKCS7DIGESTINFO;
305/** Pointer to the const IPRT representation of a PKCS \#7 DigestInfo object. */
306typedef RTCRPKCS7DIGESTINFO const *PCRTCRPKCS7DIGESTINFO;
307RTASN1TYPE_STANDARD_PROTOTYPES(RTCRPKCS7DIGESTINFO, RTDECL, RTCrPkcs7DigestInfo, SeqCore.Asn1Core);
308
309
310/**
311 * Callback function for use with RTCrPkcs7VerifySignedData.
312 *
313 * @returns IPRT status code.
314 * @param pCert The certificate to verify.
315 * @param hCertPaths Unless the certificate is trusted directly, this
316 * is a reference to the certificate path builder
317 * and verifier instance that we used to establish
318 * at least valid trusted path to @a pCert. The
319 * callback can use this to enforce additional
320 * certificate lineage requirements, effective
321 * policy checks and whatnot.
322 * This is NIL_RTCRX509CERTPATHS if the certificate
323 * is directly trusted.
324 * @param fFlags Mix of the RTCRPKCS7VCC_F_XXX flags.
325 * @param pvUser The user argument.
326 * @param pErrInfo Optional error info buffer.
327 */
328typedef DECLCALLBACK(int) FNRTCRPKCS7VERIFYCERTCALLBACK(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths,
329 uint32_t fFlags, void *pvUser, PRTERRINFO pErrInfo);
330/** Pointer to a FNRTCRPKCS7VERIFYCERTCALLBACK callback. */
331typedef FNRTCRPKCS7VERIFYCERTCALLBACK *PFNRTCRPKCS7VERIFYCERTCALLBACK;
332
333/** @name RTCRPKCS7VCC_F_XXX - Flags for FNRTCRPKCS7VERIFYCERTCALLBACK.
334 * @{ */
335/** Normal callback for a direct signatory of the signed data. */
336#define RTCRPKCS7VCC_F_SIGNED_DATA RT_BIT_32(0)
337/** Check that the signatory can be trusted for timestamps. */
338#define RTCRPKCS7VCC_F_TIMESTAMP RT_BIT_32(1)
339/** @} */
340
341/**
342 * @callback_method_impl{RTCRPKCS7VERIFYCERTCALLBACK,
343 * Default implementation that checks for the DigitalSignature KeyUsage bit.}
344 */
345RTDECL(int) RTCrPkcs7VerifyCertCallbackDefault(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags,
346 void *pvUser, PRTERRINFO pErrInfo);
347
348/**
349 * @callback_method_impl{RTCRPKCS7VERIFYCERTCALLBACK,
350 * Standard code signing. Use this for Microsoft SPC.}
351 */
352RTDECL(int) RTCrPkcs7VerifyCertCallbackCodeSigning(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags,
353 void *pvUser, PRTERRINFO pErrInfo);
354
355/**
356 * Verifies PKCS \#7 SignedData.
357 *
358 * For compatability with alternative crypto providers, the user must work on
359 * the top level PKCS \#7 structure instead directly on the SignedData.
360 *
361 * @returns IPRT status code.
362 * @param pContentInfo PKCS \#7 content info structure.
363 * @param fFlags RTCRPKCS7VERIFY_SD_F_XXX.
364 * @param hAdditionalCerts Store containing additional certificates to
365 * supplement those mentioned in the signed data.
366 * @param hTrustedCerts Store containing trusted certificates.
367 * @param pValidationTime The time we're supposed to validate the
368 * certificates chains at. Ignored for signatures
369 * with valid signing time attributes.
370 * @param pfnVerifyCert Callback for checking that a certificate used
371 * for signing the data is suitable.
372 * @param pvUser User argument for the callback.
373 * @param pErrInfo Optional error info buffer.
374 */
375RTDECL(int) RTCrPkcs7VerifySignedData(PCRTCRPKCS7CONTENTINFO pContentInfo, uint32_t fFlags,
376 RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts,
377 PCRTTIMESPEC pValidationTime, PFNRTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, void *pvUser,
378 PRTERRINFO pErrInfo);
379
380/** @name RTCRPKCS7VERIFY_SD_F_XXX - Flags for RTCrPkcs7VerifySignedData
381 * @{ */
382/** Always use the signing time attribute if present, requiring it to be
383 * verified as valid. The default behavior is to ignore unverifiable
384 * signing time attributes and use the @a pValidationTime instead. */
385#define RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT RT_BIT_32(0)
386/** Only use signging time attributes from counter signatures. */
387#define RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY RT_BIT_32(1)
388/** Don't validate the counter signature containing the signing time, just use
389 * it unverified. This is useful if we don't necessarily have the root
390 * certificates for the timestamp server handy, but use with great care. */
391#define RTCRPKCS7VERIFY_SD_F_USE_SIGNING_TIME_UNVERIFIED RT_BIT_32(2)
392/** Indicates internally that we're validating a counter signature and should
393 * use different rules when checking out the authenticated attributes.
394 * @internal */
395#define RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE RT_BIT_32(31)
396/** @} */
397
398/** @} */
399
400RT_C_DECLS_END
401
402#endif
403
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