iPXE
cms.c File Reference

Cryptographic Message Syntax (PKCS #7) More...

#include <stdint.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <ipxe/asn1.h>
#include <ipxe/x509.h>
#include <ipxe/image.h>
#include <ipxe/malloc.h>
#include <ipxe/privkey.h>
#include <ipxe/cms.h>

Go to the source code of this file.

Macros

#define EACCES_NON_SIGNING    __einfo_error ( EINFO_EACCES_NON_SIGNING )
#define EINFO_EACCES_NON_SIGNING    __einfo_uniqify ( EINFO_EACCES, 0x01, "Not a signing certificate" )
#define EACCES_NON_CODE_SIGNING    __einfo_error ( EINFO_EACCES_NON_CODE_SIGNING )
#define EINFO_EACCES_NON_CODE_SIGNING    __einfo_uniqify ( EINFO_EACCES, 0x02, "Not a code-signing certificate" )
#define EACCES_WRONG_NAME    __einfo_error ( EINFO_EACCES_WRONG_NAME )
#define EINFO_EACCES_WRONG_NAME    __einfo_uniqify ( EINFO_EACCES, 0x04, "Incorrect certificate name" )
#define EACCES_NO_SIGNATURES    __einfo_error ( EINFO_EACCES_NO_SIGNATURES )
#define EINFO_EACCES_NO_SIGNATURES    __einfo_uniqify ( EINFO_EACCES, 0x05, "No signatures present" )
#define EACCES_NO_RECIPIENTS    __einfo_error ( EINFO_EACCES_NO_RECIPIENTS )
#define EINFO_EACCES_NO_RECIPIENTS    __einfo_uniqify ( EINFO_EACCES, 0x06, "No usable recipients" )
#define EACCES_LEN    __einfo_error ( EINFO_EACCES_LEN )
#define EINFO_EACCES_LEN    __einfo_uniqify ( EINFO_EACCES, 0x07, "Bad file length" )
#define EACCES_PAD    __einfo_error ( EINFO_EACCES_PAD )
#define EINFO_EACCES_PAD    __einfo_uniqify ( EINFO_EACCES, 0x08, "Bad block padding" )
#define EACCES_MAC    __einfo_error ( EINFO_EACCES_MAC )
#define EINFO_EACCES_MAC    __einfo_uniqify ( EINFO_EACCES, 0x09, "Invalid MAC" )
#define ENOTSUP_TYPE    __einfo_error ( EINFO_ENOTSUP_TYPE )
#define EINFO_ENOTSUP_TYPE    __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unrecognised message type" )

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static int cms_parse_signed (struct cms_message *cms, const struct asn1_cursor *raw)
 Parse CMS signed data.
static int cms_parse_enveloped (struct cms_message *cms, const struct asn1_cursor *raw)
 Parse CMS enveloped data.
static int cms_parse_content_type (struct cms_message *cms, const struct asn1_cursor *raw)
 Parse CMS message content type.
static int cms_parse_certificates (struct cms_message *cms, const struct asn1_cursor *raw)
 Parse CMS message certificate list.
static int cms_parse_identifier (struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
 Parse CMS message participant identifier.
static int cms_parse_digest_algorithm (struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
 Parse CMS message digest algorithm.
static int cms_parse_pubkey_algorithm (struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
 Parse CMS message public-key algorithm.
static int cms_parse_cipher_algorithm (struct cms_message *cms, const struct asn1_cursor *raw)
 Parse CMS message cipher algorithm.
static int cms_parse_value (struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
 Parse CMS message signature or key value.
static int cms_parse_participant (struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
 Parse CMS message participant information.
static int cms_parse_participants (struct cms_message *cms, const struct asn1_cursor *raw)
 Parse CMS message participants information.
static int cms_parse_encrypted (struct cms_message *cms, const struct asn1_cursor *raw)
 Parse CMS message encrypted content information.
static int cms_parse_mac (struct cms_message *cms, const struct asn1_cursor *raw)
 Parse CMS message MAC.
static int cms_parse (struct cms_message *cms)
 Parse CMS message from ASN.1 data.
static void cms_free (struct refcnt *refcnt)
 Free CMS message.
int cms_message (struct image *image, struct cms_message **cms)
 Create CMS message.
static void cms_digest (struct cms_message *cms, struct cms_participant *part, const void *data, size_t len, void *out)
 Calculate digest of CMS-signed data.
static int cms_verify_digest (struct cms_message *cms, struct cms_participant *part, struct x509_certificate *cert, const void *data, size_t len)
 Verify digest of CMS-signed data.
static int cms_verify_signer (struct cms_message *cms, struct cms_participant *part, const void *data, size_t len, time_t time, struct x509_chain *store, struct x509_root *root)
 Verify CMS message signer.
int cms_verify (struct cms_message *cms, struct image *image, const char *name, time_t time, struct x509_chain *store, struct x509_root *root)
 Verify CMS signature.
static struct cms_participantcms_recipient (struct cms_message *cms, struct private_key *private_key)
 Identify CMS recipient corresponding to private key.
static int cms_cipher_key (struct cms_message *cms, struct cms_participant *part, struct private_key *private_key, void *ctx)
 Set CMS cipher key.
static int cms_cipher (struct cms_message *cms, struct private_key *private_key, void *ctx)
 Initialise cipher for CMS decryption.
static int cms_verify_padding (struct cms_message *cms, const void *data, size_t len)
 Check CMS padding.
int cms_decrypt (struct cms_message *cms, struct image *image, const char *name, struct private_key *private_key)
 Decrypt CMS message.

Variables

static uint8_t oid_signeddata [] = { ASN1_OID_SIGNEDDATA }
 "id-signedData" object identifier
static uint8_t oid_envelopeddata [] = { ASN1_OID_ENVELOPEDDATA }
 "id-envelopedData" object identifier
static uint8_t oid_authenvelopeddata [] = { ASN1_OID_AUTHENVELOPEDDATA }
 "id-authEnvelopedData" object identifier
static struct cms_type cms_types []
 CMS message types.

Detailed Description

Cryptographic Message Syntax (PKCS #7)

The format of CMS messages is defined in RFC 5652.

Definition in file cms.c.

Macro Definition Documentation

◆ EACCES_NON_SIGNING

#define EACCES_NON_SIGNING    __einfo_error ( EINFO_EACCES_NON_SIGNING )

Definition at line 47 of file cms.c.

47#define EACCES_NON_SIGNING \
48 __einfo_error ( EINFO_EACCES_NON_SIGNING )

Referenced by cms_verify_signer().

◆ EINFO_EACCES_NON_SIGNING

#define EINFO_EACCES_NON_SIGNING    __einfo_uniqify ( EINFO_EACCES, 0x01, "Not a signing certificate" )

Definition at line 49 of file cms.c.

49#define EINFO_EACCES_NON_SIGNING \
50 __einfo_uniqify ( EINFO_EACCES, 0x01, "Not a signing certificate" )

◆ EACCES_NON_CODE_SIGNING

#define EACCES_NON_CODE_SIGNING    __einfo_error ( EINFO_EACCES_NON_CODE_SIGNING )

Definition at line 51 of file cms.c.

51#define EACCES_NON_CODE_SIGNING \
52 __einfo_error ( EINFO_EACCES_NON_CODE_SIGNING )

Referenced by cms_verify_signer().

◆ EINFO_EACCES_NON_CODE_SIGNING

#define EINFO_EACCES_NON_CODE_SIGNING    __einfo_uniqify ( EINFO_EACCES, 0x02, "Not a code-signing certificate" )

Definition at line 53 of file cms.c.

53#define EINFO_EACCES_NON_CODE_SIGNING \
54 __einfo_uniqify ( EINFO_EACCES, 0x02, "Not a code-signing certificate" )

◆ EACCES_WRONG_NAME

#define EACCES_WRONG_NAME    __einfo_error ( EINFO_EACCES_WRONG_NAME )

Definition at line 55 of file cms.c.

55#define EACCES_WRONG_NAME \
56 __einfo_error ( EINFO_EACCES_WRONG_NAME )

Referenced by cms_verify(), and x509_check_name().

◆ EINFO_EACCES_WRONG_NAME

#define EINFO_EACCES_WRONG_NAME    __einfo_uniqify ( EINFO_EACCES, 0x04, "Incorrect certificate name" )

Definition at line 57 of file cms.c.

57#define EINFO_EACCES_WRONG_NAME \
58 __einfo_uniqify ( EINFO_EACCES, 0x04, "Incorrect certificate name" )

◆ EACCES_NO_SIGNATURES

#define EACCES_NO_SIGNATURES    __einfo_error ( EINFO_EACCES_NO_SIGNATURES )

Definition at line 59 of file cms.c.

59#define EACCES_NO_SIGNATURES \
60 __einfo_error ( EINFO_EACCES_NO_SIGNATURES )

Referenced by cms_verify().

◆ EINFO_EACCES_NO_SIGNATURES

#define EINFO_EACCES_NO_SIGNATURES    __einfo_uniqify ( EINFO_EACCES, 0x05, "No signatures present" )

Definition at line 61 of file cms.c.

61#define EINFO_EACCES_NO_SIGNATURES \
62 __einfo_uniqify ( EINFO_EACCES, 0x05, "No signatures present" )

◆ EACCES_NO_RECIPIENTS

#define EACCES_NO_RECIPIENTS    __einfo_error ( EINFO_EACCES_NO_RECIPIENTS )

Definition at line 63 of file cms.c.

63#define EACCES_NO_RECIPIENTS \
64 __einfo_error ( EINFO_EACCES_NO_RECIPIENTS )

Referenced by cms_cipher().

◆ EINFO_EACCES_NO_RECIPIENTS

#define EINFO_EACCES_NO_RECIPIENTS    __einfo_uniqify ( EINFO_EACCES, 0x06, "No usable recipients" )

Definition at line 65 of file cms.c.

65#define EINFO_EACCES_NO_RECIPIENTS \
66 __einfo_uniqify ( EINFO_EACCES, 0x06, "No usable recipients" )

◆ EACCES_LEN

#define EACCES_LEN    __einfo_error ( EINFO_EACCES_LEN )

Definition at line 67 of file cms.c.

67#define EACCES_LEN \
68 __einfo_error ( EINFO_EACCES_LEN )

Referenced by cms_decrypt().

◆ EINFO_EACCES_LEN

#define EINFO_EACCES_LEN    __einfo_uniqify ( EINFO_EACCES, 0x07, "Bad file length" )

Definition at line 69 of file cms.c.

69#define EINFO_EACCES_LEN \
70 __einfo_uniqify ( EINFO_EACCES, 0x07, "Bad file length" )

◆ EACCES_PAD

#define EACCES_PAD    __einfo_error ( EINFO_EACCES_PAD )

Definition at line 71 of file cms.c.

71#define EACCES_PAD \
72 __einfo_error ( EINFO_EACCES_PAD )

Referenced by cms_verify_padding().

◆ EINFO_EACCES_PAD

#define EINFO_EACCES_PAD    __einfo_uniqify ( EINFO_EACCES, 0x08, "Bad block padding" )

Definition at line 73 of file cms.c.

73#define EINFO_EACCES_PAD \
74 __einfo_uniqify ( EINFO_EACCES, 0x08, "Bad block padding" )

◆ EACCES_MAC

#define EACCES_MAC    __einfo_error ( EINFO_EACCES_MAC )

Definition at line 75 of file cms.c.

75#define EACCES_MAC \
76 __einfo_error ( EINFO_EACCES_MAC )

Referenced by cms_decrypt().

◆ EINFO_EACCES_MAC

#define EINFO_EACCES_MAC    __einfo_uniqify ( EINFO_EACCES, 0x09, "Invalid MAC" )

Definition at line 77 of file cms.c.

77#define EINFO_EACCES_MAC \
78 __einfo_uniqify ( EINFO_EACCES, 0x09, "Invalid MAC" )

◆ ENOTSUP_TYPE

#define ENOTSUP_TYPE    __einfo_error ( EINFO_ENOTSUP_TYPE )

Definition at line 79 of file cms.c.

79#define ENOTSUP_TYPE \
80 __einfo_error ( EINFO_ENOTSUP_TYPE )

◆ EINFO_ENOTSUP_TYPE

#define EINFO_ENOTSUP_TYPE    __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unrecognised message type" )

Definition at line 81 of file cms.c.

81#define EINFO_ENOTSUP_TYPE \
82 __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unrecognised message type" )

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ cms_parse_signed()

int cms_parse_signed ( struct cms_message * cms,
const struct asn1_cursor * raw )
static

Parse CMS signed data.

Parameters
cmsCMS message
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 530 of file cms.c.

531 {
532 struct asn1_cursor cursor;
533 int rc;
534
535 /* Allocate certificate list */
537 if ( ! cms->certificates )
538 return -ENOMEM;
539
540 /* Enter signedData */
541 memcpy ( &cursor, raw, sizeof ( cursor ) );
542 asn1_enter ( &cursor, ASN1_SEQUENCE );
543
544 /* Skip version */
545 asn1_skip ( &cursor, ASN1_INTEGER );
546
547 /* Skip digestAlgorithms */
548 asn1_skip ( &cursor, ASN1_SET );
549
550 /* Skip encapContentInfo */
551 asn1_skip ( &cursor, ASN1_SEQUENCE );
552
553 /* Parse certificates */
554 if ( ( rc = cms_parse_certificates ( cms, &cursor ) ) != 0 )
555 return rc;
556 asn1_skip_any ( &cursor );
557
558 /* Skip crls, if present */
559 asn1_skip_if_exists ( &cursor, ASN1_EXPLICIT_TAG ( 1 ) );
560
561 /* Parse signerInfos */
562 if ( ( rc = cms_parse_participants ( cms, &cursor ) ) != 0 )
563 return rc;
564
565 return 0;
566}
__be32 raw[7]
Definition CIB_PRM.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition asn1.c:290
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition asn1.c:169
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition asn1.c:231
int asn1_skip_if_exists(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object if present.
Definition asn1.c:202
#define ASN1_INTEGER
ASN.1 integer.
Definition asn1.h:63
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition asn1.h:99
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition asn1.h:90
#define ASN1_SET
ASN.1 set.
Definition asn1.h:93
static int cms_parse_participants(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS message participants information.
Definition cms.c:433
static int cms_parse_certificates(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS message certificate list.
Definition cms.c:158
#define ENOMEM
Not enough space.
Definition errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
An ASN.1 object cursor.
Definition asn1.h:21
struct x509_chain * certificates
List of all certificates (for signature messages)
Definition cms.h:64
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition x509.c:1615

References asn1_enter(), ASN1_EXPLICIT_TAG, ASN1_INTEGER, ASN1_SEQUENCE, ASN1_SET, asn1_skip(), asn1_skip_any(), asn1_skip_if_exists(), cms_message::certificates, cms_parse_certificates(), cms_parse_participants(), ENOMEM, memcpy(), raw, rc, and x509_alloc_chain().

◆ cms_parse_enveloped()

int cms_parse_enveloped ( struct cms_message * cms,
const struct asn1_cursor * raw )
static

Parse CMS enveloped data.

Parameters
cmsCMS message
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 575 of file cms.c.

576 {
577 struct asn1_cursor cursor;
578 int rc;
579
580 /* Enter envelopedData or authEnvelopedData */
581 memcpy ( &cursor, raw, sizeof ( cursor ) );
582 asn1_enter ( &cursor, ASN1_SEQUENCE );
583
584 /* Skip version */
585 asn1_skip ( &cursor, ASN1_INTEGER );
586
587 /* Skip originatorInfo, if present */
588 asn1_skip_if_exists ( &cursor, ASN1_IMPLICIT_TAG ( 0 ) );
589
590 /* Parse recipientInfos */
591 if ( ( rc = cms_parse_participants ( cms, &cursor ) ) != 0 )
592 return rc;
593 asn1_skip_any ( &cursor );
594
595 /* Parse encryptedContentInfo or authEncryptedContentInfo */
596 if ( ( rc = cms_parse_encrypted ( cms, &cursor ) ) != 0 )
597 return rc;
598 asn1_skip_any ( &cursor );
599 assert ( cms->cipher != NULL );
600
601 /* Skip unprotectedAttrs or authAttrs, if present */
602 asn1_skip_if_exists ( &cursor, ASN1_IMPLICIT_TAG ( 1 ) );
603
604 /* Parse mac, if present */
605 if ( ( cms->cipher->authsize != 0 ) &&
606 ( ( rc = cms_parse_mac ( cms, &cursor ) ) != 0 ) )
607 return rc;
608
609 return 0;
610}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define ASN1_IMPLICIT_TAG(number)
ASN.1 implicit tag.
Definition asn1.h:96
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
static int cms_parse_encrypted(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS message encrypted content information.
Definition cms.c:479
static int cms_parse_mac(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS message MAC.
Definition cms.c:505
size_t authsize
Authentication tag size.
Definition crypto.h:75
struct cipher_algorithm * cipher
Cipher algorithm.
Definition cms.h:69

References asn1_enter(), ASN1_IMPLICIT_TAG, ASN1_INTEGER, ASN1_SEQUENCE, asn1_skip(), asn1_skip_any(), asn1_skip_if_exists(), assert, cipher_algorithm::authsize, cms_message::cipher, cms_parse_encrypted(), cms_parse_mac(), cms_parse_participants(), memcpy(), NULL, raw, and rc.

◆ cms_parse_content_type()

int cms_parse_content_type ( struct cms_message * cms,
const struct asn1_cursor * raw )
static

Parse CMS message content type.

Parameters
cmsCMS message
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 124 of file cms.c.

125 {
126 struct asn1_cursor cursor;
127 struct cms_type *type;
128 unsigned int i;
129
130 /* Enter contentType */
131 memcpy ( &cursor, raw, sizeof ( cursor ) );
132 asn1_enter ( &cursor, ASN1_OID );
133
134 /* Check for a recognised OID */
135 for ( i = 0 ; i < ( sizeof ( cms_types ) /
136 sizeof ( cms_types[0] ) ) ; i++ ) {
137 type = &cms_types[i];
138 if ( asn1_compare ( &cursor, &type->oid ) == 0 ) {
139 cms->type = type;
140 DBGC ( cms, "CMS %p contains %sData\n",
141 cms, type->name );
142 return 0;
143 }
144 }
145
146 DBGC ( cms, "CMS %p is not a recognised message type:\n", cms );
147 DBGC_HDA ( cms, 0, raw->data, raw->len );
148 return -ENOTSUP_TYPE;
149}
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition asn1.c:458
#define ASN1_OID
ASN.1 object identifier.
Definition asn1.h:75
static struct cms_type cms_types[]
CMS message types.
Definition cms.c:99
uint32_t type
Operating system type.
Definition ena.h:1
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
#define ENOTSUP_TYPE
Definition stp.c:50
struct cms_type * type
Message type.
Definition cms.h:61
A CMS message type.
Definition cms.h:23

References asn1_compare(), asn1_enter(), ASN1_OID, cms_types, DBGC, DBGC_HDA, ENOTSUP_TYPE, memcpy(), raw, cms_message::type, and type.

Referenced by cms_parse().

◆ cms_parse_certificates()

int cms_parse_certificates ( struct cms_message * cms,
const struct asn1_cursor * raw )
static

Parse CMS message certificate list.

Parameters
cmsCMS message
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 158 of file cms.c.

159 {
160 struct asn1_cursor cursor;
161 struct x509_certificate *cert;
162 int rc;
163
164 /* Enter certificates */
165 memcpy ( &cursor, raw, sizeof ( cursor ) );
166 asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
167
168 /* Add each certificate */
169 while ( cursor.len ) {
170
171 /* Add certificate to chain */
172 if ( ( rc = x509_append_raw ( cms->certificates, cursor.data,
173 cursor.len ) ) != 0 ) {
174 DBGC ( cms, "CMS %p could not append certificate: %s\n",
175 cms, strerror ( rc) );
176 DBGC_HDA ( cms, 0, cursor.data, cursor.len );
177 return rc;
178 }
179 cert = x509_last ( cms->certificates );
180 DBGC ( cms, "CMS %p found certificate %s\n",
181 cms, x509_name ( cert ) );
182
183 /* Move to next certificate */
184 asn1_skip_any ( &cursor );
185 }
186
187 return 0;
188}
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
An X.509 certificate.
Definition x509.h:216
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition x509.c:147
int x509_append_raw(struct x509_chain *chain, const void *data, size_t len)
Append X.509 certificate to X.509 certificate chain.
Definition x509.c:1674
static struct x509_certificate * x509_last(struct x509_chain *chain)
Get last certificate in X.509 certificate chain.
Definition x509.h:325

References asn1_enter(), ASN1_EXPLICIT_TAG, asn1_skip_any(), cms_message::certificates, asn1_cursor::data, DBGC, DBGC_HDA, asn1_cursor::len, memcpy(), raw, rc, strerror(), x509_append_raw(), x509_last(), and x509_name().

Referenced by cms_parse_signed().

◆ cms_parse_identifier()

int cms_parse_identifier ( struct cms_message * cms,
struct cms_participant * part,
const struct asn1_cursor * raw )
static

Parse CMS message participant identifier.

Parameters
cmsCMS message
partParticipant information to fill in
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 198 of file cms.c.

200 {
201 struct asn1_cursor cursor;
202 struct asn1_cursor serial;
203 struct asn1_cursor issuer;
204 struct x509_certificate *cert;
205 int rc;
206
207 /* Enter issuerAndSerialNumber */
208 memcpy ( &cursor, raw, sizeof ( cursor ) );
209 asn1_enter ( &cursor, ASN1_SEQUENCE );
210
211 /* Identify issuer */
212 memcpy ( &issuer, &cursor, sizeof ( issuer ) );
213 if ( ( rc = asn1_shrink ( &issuer, ASN1_SEQUENCE ) ) != 0 ) {
214 DBGC ( cms, "CMS %p/%p could not locate issuer: %s\n",
215 cms, part, strerror ( rc ) );
216 DBGC_HDA ( cms, 0, raw->data, raw->len );
217 return rc;
218 }
219 DBGC ( cms, "CMS %p/%p issuer is:\n", cms, part );
220 DBGC_HDA ( cms, 0, issuer.data, issuer.len );
221 asn1_skip_any ( &cursor );
222
223 /* Identify serialNumber */
224 memcpy ( &serial, &cursor, sizeof ( serial ) );
225 if ( ( rc = asn1_shrink ( &serial, ASN1_INTEGER ) ) != 0 ) {
226 DBGC ( cms, "CMS %p/%p could not locate serialNumber: %s\n",
227 cms, part, strerror ( rc ) );
228 DBGC_HDA ( cms, 0, raw->data, raw->len );
229 return rc;
230 }
231 DBGC ( cms, "CMS %p/%p serial number is:\n", cms, part );
232 DBGC_HDA ( cms, 0, serial.data, serial.len );
233
234 /* Identify certificate */
236 if ( ! cert ) {
237 DBGC ( cms, "CMS %p/%p could not identify certificate\n",
238 cms, part );
239 return ( cms_is_signature ( cms ) ? -ENOENT : 0 );
240 }
241
242 /* Append certificate to chain */
243 if ( ( rc = x509_append ( part->chain, cert ) ) != 0 ) {
244 DBGC ( cms, "CMS %p/%p could not append certificate: %s\n",
245 cms, part, strerror ( rc ) );
246 return rc;
247 }
248
249 /* Append remaining certificates to chain */
250 if ( ( rc = x509_auto_append ( part->chain,
251 cms->certificates ) ) != 0 ) {
252 DBGC ( cms, "CMS %p/%p could not append certificates: %s\n",
253 cms, part, strerror ( rc ) );
254 return rc;
255 }
256
257 return 0;
258}
int asn1_shrink(struct asn1_cursor *cursor, unsigned int type)
Shrink ASN.1 cursor to fit object.
Definition asn1.c:254
static int cms_is_signature(struct cms_message *cms)
Check if CMS message is a signature message.
Definition cms.h:105
uint64_t serial
Serial number.
Definition edd.h:1
#define ENOENT
No such file or directory.
Definition errno.h:515
struct x509_chain * chain
Certificate chain.
Definition cms.h:43
struct x509_issuer issuer
Issuer.
Definition x509.h:241
int x509_auto_append(struct x509_chain *chain, struct x509_chain *store)
Append X.509 certificates to X.509 certificate chain.
Definition x509.c:1868
struct x509_certificate * x509_find_issuer_serial(struct x509_chain *store, const struct asn1_cursor *issuer, const struct asn1_cursor *serial)
Identify X.509 certificate by issuer and serial number.
Definition x509.c:1805
int x509_append(struct x509_chain *chain, struct x509_certificate *cert)
Append X.509 certificate to X.509 certificate chain.
Definition x509.c:1638

References asn1_enter(), ASN1_INTEGER, ASN1_SEQUENCE, asn1_shrink(), asn1_skip_any(), cms_message::certificates, cms_participant::chain, cms_is_signature(), DBGC, DBGC_HDA, ENOENT, x509_certificate::issuer, memcpy(), raw, rc, serial, strerror(), x509_append(), x509_auto_append(), and x509_find_issuer_serial().

Referenced by cms_parse_participant().

◆ cms_parse_digest_algorithm()

int cms_parse_digest_algorithm ( struct cms_message * cms,
struct cms_participant * part,
const struct asn1_cursor * raw )
static

Parse CMS message digest algorithm.

Parameters
cmsCMS message
partParticipant information to fill in
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 268 of file cms.c.

270 {
272 int rc;
273
274 /* Identify algorithm */
275 if ( ( rc = asn1_digest_algorithm ( raw, &algorithm ) ) != 0 ) {
276 DBGC ( cms, "CMS %p/%p could not identify digest algorithm: "
277 "%s\n", cms, part, strerror ( rc ) );
278 DBGC_HDA ( cms, 0, raw->data, raw->len );
279 return rc;
280 }
281
282 /* Record digest algorithm */
283 part->digest = algorithm->digest;
284 DBGC ( cms, "CMS %p/%p digest algorithm is %s\n",
285 cms, part, algorithm->name );
286
287 return 0;
288}
int asn1_digest_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified digest algorithm.
Definition asn1.c:570
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition ieee80211.h:1
An ASN.1 OID-identified algorithm.
Definition asn1.h:408
struct digest_algorithm * digest
Digest algorithm (for signature messages)
Definition cms.h:46

References algorithm, asn1_digest_algorithm(), DBGC, DBGC_HDA, cms_participant::digest, raw, rc, and strerror().

Referenced by cms_parse_participant().

◆ cms_parse_pubkey_algorithm()

int cms_parse_pubkey_algorithm ( struct cms_message * cms,
struct cms_participant * part,
const struct asn1_cursor * raw )
static

Parse CMS message public-key algorithm.

Parameters
cmsCMS message
partParticipant information to fill in
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 298 of file cms.c.

300 {
302 int rc;
303
304 /* Identify algorithm */
305 if ( ( rc = asn1_pubkey_algorithm ( raw, &algorithm ) ) != 0 ) {
306 DBGC ( cms, "CMS %p/%p could not identify public-key "
307 "algorithm: %s\n", cms, part, strerror ( rc ) );
308 DBGC_HDA ( cms, 0, raw->data, raw->len );
309 return rc;
310 }
311
312 /* Record public-key algorithm */
313 part->pubkey = algorithm->pubkey;
314 DBGC ( cms, "CMS %p/%p public-key algorithm is %s\n",
315 cms, part, algorithm->name );
316
317 return 0;
318}
int asn1_pubkey_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified public-key algorithm.
Definition asn1.c:544
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition cms.h:48

References algorithm, asn1_pubkey_algorithm(), DBGC, DBGC_HDA, cms_participant::pubkey, raw, rc, and strerror().

Referenced by cms_parse_participant().

◆ cms_parse_cipher_algorithm()

int cms_parse_cipher_algorithm ( struct cms_message * cms,
const struct asn1_cursor * raw )
static

Parse CMS message cipher algorithm.

Parameters
cmsCMS message
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 327 of file cms.c.

328 {
330 int rc;
331
332 /* Identify algorithm */
334 &cms->iv ) ) != 0 ) {
335 DBGC ( cms, "CMS %p could not identify cipher algorithm: %s\n",
336 cms, strerror ( rc ) );
337 DBGC_HDA ( cms, 0, raw->data, raw->len );
338 return rc;
339 }
340
341 /* Record cipher */
342 cms->cipher = algorithm->cipher;
343 DBGC ( cms, "CMS %p cipher algorithm is %s\n", cms, algorithm->name );
344
345 return 0;
346}
int asn1_cipher_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm, struct asn1_cursor *params)
Parse ASN.1 OID-identified cipher algorithm.
Definition asn1.c:597
struct asn1_cursor iv
Cipher initialization vector.
Definition cms.h:71

References algorithm, asn1_cipher_algorithm(), cms_message::cipher, DBGC, DBGC_HDA, cms_message::iv, raw, rc, and strerror().

Referenced by cms_parse_encrypted().

◆ cms_parse_value()

int cms_parse_value ( struct cms_message * cms,
struct cms_participant * part,
const struct asn1_cursor * raw )
static

Parse CMS message signature or key value.

Parameters
cmsCMS message
partParticipant information to fill in
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 356 of file cms.c.

358 {
359 int rc;
360
361 /* Enter signature or encryptedKey */
362 memcpy ( &part->value, raw, sizeof ( part->value ) );
363 if ( ( rc = asn1_enter ( &part->value, ASN1_OCTET_STRING ) ) != 0 ) {
364 DBGC ( cms, "CMS %p/%p could not locate value:\n",
365 cms, part );
366 DBGC_HDA ( cms, 0, raw->data, raw->len );
367 return rc;
368 }
369 DBGC ( cms, "CMS %p/%p value is:\n", cms, part );
370 DBGC_HDA ( cms, 0, part->value.data, part->value.len );
371
372 return 0;
373}
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition asn1.h:69
const void * data
Start of data.
Definition asn1.h:23
size_t len
Length of data.
Definition asn1.h:25
struct asn1_cursor value
Signature or key value.
Definition cms.h:51

References asn1_enter(), ASN1_OCTET_STRING, asn1_cursor::data, DBGC, DBGC_HDA, asn1_cursor::len, memcpy(), raw, rc, and cms_participant::value.

Referenced by cms_parse_participant().

◆ cms_parse_participant()

int cms_parse_participant ( struct cms_message * cms,
struct cms_participant * part,
const struct asn1_cursor * raw )
static

Parse CMS message participant information.

Parameters
cmsCMS message
partParticipant information to fill in
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 383 of file cms.c.

385 {
386 struct asn1_cursor cursor;
387 int rc;
388
389 /* Enter signerInfo or ktri */
390 memcpy ( &cursor, raw, sizeof ( cursor ) );
391 asn1_enter ( &cursor, ASN1_SEQUENCE );
392
393 /* Skip version */
394 asn1_skip ( &cursor, ASN1_INTEGER );
395
396 /* Parse sid or rid */
397 if ( ( rc = cms_parse_identifier ( cms, part, &cursor ) ) != 0 )
398 return rc;
399 asn1_skip_any ( &cursor );
400
401 /* Parse signature-only objects */
402 if ( cms_is_signature ( cms ) ) {
403
404 /* Parse digestAlgorithm */
405 if ( ( rc = cms_parse_digest_algorithm ( cms, part,
406 &cursor ) ) != 0 )
407 return rc;
408 asn1_skip_any ( &cursor );
409
410 /* Skip signedAttrs, if present */
411 asn1_skip_if_exists ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
412 }
413
414 /* Parse signatureAlgorithm or contentEncryptionAlgorithm */
415 if ( ( rc = cms_parse_pubkey_algorithm ( cms, part, &cursor ) ) != 0 )
416 return rc;
417 asn1_skip_any ( &cursor );
418
419 /* Parse signature or encryptedKey */
420 if ( ( rc = cms_parse_value ( cms, part, &cursor ) ) != 0 )
421 return rc;
422
423 return 0;
424}
static int cms_parse_identifier(struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
Parse CMS message participant identifier.
Definition cms.c:198
static int cms_parse_digest_algorithm(struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
Parse CMS message digest algorithm.
Definition cms.c:268
static int cms_parse_pubkey_algorithm(struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
Parse CMS message public-key algorithm.
Definition cms.c:298
static int cms_parse_value(struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
Parse CMS message signature or key value.
Definition cms.c:356

References asn1_enter(), ASN1_EXPLICIT_TAG, ASN1_INTEGER, ASN1_SEQUENCE, asn1_skip(), asn1_skip_any(), asn1_skip_if_exists(), cms_is_signature(), cms_parse_digest_algorithm(), cms_parse_identifier(), cms_parse_pubkey_algorithm(), cms_parse_value(), memcpy(), raw, and rc.

Referenced by cms_parse_participants().

◆ cms_parse_participants()

int cms_parse_participants ( struct cms_message * cms,
const struct asn1_cursor * raw )
static

Parse CMS message participants information.

Parameters
cmsCMS message
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 433 of file cms.c.

434 {
435 struct asn1_cursor cursor;
436 struct cms_participant *part;
437 int rc;
438
439 /* Enter signerInfos or recipientInfos */
440 memcpy ( &cursor, raw, sizeof ( cursor ) );
441 asn1_enter ( &cursor, ASN1_SET );
442
443 /* Add each signerInfo or recipientInfo. Errors are handled
444 * by ensuring that cms_put() will always be able to free any
445 * allocated memory.
446 */
447 while ( cursor.len ) {
448
449 /* Allocate participant information block */
450 part = zalloc ( sizeof ( *part ) );
451 if ( ! part )
452 return -ENOMEM;
453 list_add ( &part->list, &cms->participants );
454 part->digest = &digest_null;
455 part->pubkey = &pubkey_null;
456
457 /* Allocate certificate chain */
458 part->chain = x509_alloc_chain();
459 if ( ! part->chain )
460 return -ENOMEM;
461
462 /* Parse signerInfo or recipientInfo */
463 if ( ( rc = cms_parse_participant ( cms, part,
464 &cursor ) ) != 0 )
465 return rc;
466 asn1_skip_any ( &cursor );
467 }
468
469 return 0;
470}
static int cms_parse_participant(struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
Parse CMS message participant information.
Definition cms.c:383
struct pubkey_algorithm pubkey_null
struct digest_algorithm digest_null
Definition crypto_null.c:49
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
struct list_head participants
List of participant information blocks.
Definition cms.h:66
CMS participant information.
Definition cms.h:39
struct list_head list
List of participant information blocks.
Definition cms.h:41

References asn1_enter(), ASN1_SET, asn1_skip_any(), cms_participant::chain, cms_parse_participant(), cms_participant::digest, digest_null, ENOMEM, asn1_cursor::len, cms_participant::list, list_add, memcpy(), cms_message::participants, cms_participant::pubkey, pubkey_null, raw, rc, x509_alloc_chain(), and zalloc().

Referenced by cms_parse_enveloped(), and cms_parse_signed().

◆ cms_parse_encrypted()

int cms_parse_encrypted ( struct cms_message * cms,
const struct asn1_cursor * raw )
static

Parse CMS message encrypted content information.

Parameters
cmsCMS message
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 479 of file cms.c.

480 {
481 struct asn1_cursor cursor;
482 int rc;
483
484 /* Enter encryptedContentInfo */
485 memcpy ( &cursor, raw, sizeof ( cursor ) );
486 asn1_enter ( &cursor, ASN1_SEQUENCE );
487
488 /* Skip contentType */
489 asn1_skip ( &cursor, ASN1_OID );
490
491 /* Parse contentEncryptionAlgorithm */
492 if ( ( rc = cms_parse_cipher_algorithm ( cms, &cursor ) ) != 0 )
493 return rc;
494
495 return 0;
496}
static int cms_parse_cipher_algorithm(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS message cipher algorithm.
Definition cms.c:327

References asn1_enter(), ASN1_OID, ASN1_SEQUENCE, asn1_skip(), cms_parse_cipher_algorithm(), memcpy(), raw, and rc.

Referenced by cms_parse_enveloped().

◆ cms_parse_mac()

int cms_parse_mac ( struct cms_message * cms,
const struct asn1_cursor * raw )
static

Parse CMS message MAC.

Parameters
cmsCMS message
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 505 of file cms.c.

506 {
507 int rc;
508
509 /* Enter mac */
510 memcpy ( &cms->mac, raw, sizeof ( cms->mac ) );
511 if ( ( rc = asn1_enter ( &cms->mac, ASN1_OCTET_STRING ) ) != 0 ) {
512 DBGC ( cms, "CMS %p could not locate mac: %s\n",
513 cms, strerror ( rc ) );
514 DBGC_HDA ( cms, 0, raw->data, raw->len );
515 return rc;
516 }
517 DBGC ( cms, "CMS %p mac is:\n", cms );
518 DBGC_HDA ( cms, 0, cms->mac.data, cms->mac.len );
519
520 return 0;
521}
struct asn1_cursor mac
Cipher authentication tag.
Definition cms.h:73

References asn1_enter(), ASN1_OCTET_STRING, asn1_cursor::data, DBGC, DBGC_HDA, asn1_cursor::len, cms_message::mac, memcpy(), raw, rc, and strerror().

Referenced by cms_parse_enveloped().

◆ cms_parse()

int cms_parse ( struct cms_message * cms)
static

Parse CMS message from ASN.1 data.

Parameters
cmsCMS message
Return values
rcReturn status code

Definition at line 618 of file cms.c.

618 {
619 struct asn1_cursor cursor;
620 int rc;
621
622 /* Enter contentInfo */
623 memcpy ( &cursor, cms->raw, sizeof ( cursor ) );
624 asn1_enter ( &cursor, ASN1_SEQUENCE );
625
626 /* Parse contentType */
627 if ( ( rc = cms_parse_content_type ( cms, &cursor ) ) != 0 )
628 return rc;
629 asn1_skip_any ( &cursor );
630
631 /* Enter content */
632 asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
633
634 /* Parse type-specific content */
635 if ( ( rc = cms->type->parse ( cms, &cursor ) ) != 0 )
636 return rc;
637
638 return 0;
639}
static int cms_parse_content_type(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS message content type.
Definition cms.c:124
struct asn1_cursor * raw
Raw ASN.1 data.
Definition cms.h:59
int(* parse)(struct cms_message *cms, const struct asn1_cursor *raw)
Parse content.
Definition cms.h:34

References asn1_enter(), ASN1_EXPLICIT_TAG, ASN1_SEQUENCE, asn1_skip_any(), cms_parse_content_type(), memcpy(), cms_type::parse, cms_message::raw, rc, and cms_message::type.

Referenced by cms_message().

◆ cms_free()

void cms_free ( struct refcnt * refcnt)
static

Free CMS message.

Parameters
refcntReference count

Definition at line 646 of file cms.c.

646 {
647 struct cms_message *cms =
649 struct cms_participant *part;
650 struct cms_participant *tmp;
651
653 list_del ( &part->list );
654 x509_chain_put ( part->chain );
655 free ( part );
656 }
658 free ( cms->raw );
659 free ( cms );
660}
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A CMS message.
Definition cms.h:55
A reference counter.
Definition refcnt.h:27
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition x509.h:300

References cms_message::certificates, cms_participant::chain, container_of, free, cms_participant::list, list_del, list_for_each_entry_safe, cms_message::participants, cms_message::raw, tmp, and x509_chain_put().

Referenced by cms_message().

◆ cms_message()

int cms_message ( struct image * image,
struct cms_message ** cms )

Create CMS message.

Parameters
imageImage
Return values
sigCMS message
rcReturn status code

On success, the caller holds a reference to the CMS message, and is responsible for ultimately calling cms_put().

Definition at line 672 of file cms.c.

672 {
673 int next;
674 int rc;
675
676 /* Allocate and initialise message */
677 *cms = zalloc ( sizeof ( **cms ) );
678 if ( ! *cms ) {
679 rc = -ENOMEM;
680 goto err_alloc;
681 }
682 ref_init ( &(*cms)->refcnt, cms_free );
683 INIT_LIST_HEAD ( &(*cms)->participants );
684 (*cms)->cipher = &cipher_null;
685
686 /* Get raw message data */
687 next = image_asn1 ( image, 0, &(*cms)->raw );
688 if ( next < 0 ) {
689 rc = next;
690 DBGC ( *cms, "CMS %p could not get raw ASN.1 data: %s\n",
691 *cms, strerror ( rc ) );
692 goto err_asn1;
693 }
694
695 /* Use only first message in image */
696 asn1_shrink_any ( (*cms)->raw );
697
698 /* Parse message */
699 if ( ( rc = cms_parse ( *cms ) ) != 0 )
700 goto err_parse;
701
702 return 0;
703
704 err_parse:
705 err_asn1:
706 cms_put ( *cms );
707 err_alloc:
708 return rc;
709}
int image_asn1(struct image *image, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from image.
Definition asn1.c:1028
int asn1_shrink_any(struct asn1_cursor *cursor)
Shrink ASN.1 object of any type.
Definition asn1.c:300
static int cms_parse(struct cms_message *cms)
Parse CMS message from ASN.1 data.
Definition cms.c:618
static void cms_free(struct refcnt *refcnt)
Free CMS message.
Definition cms.c:646
static void cms_put(struct cms_message *cms)
Drop reference to CMS message.
Definition cms.h:94
struct cipher_algorithm cipher_null
Definition crypto_null.c:84
uint32_t next
Next descriptor address.
Definition dwmac.h:11
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
An executable image.
Definition image.h:24

References asn1_shrink_any(), cipher_null, cms_free(), cms_parse(), cms_put(), DBGC, ENOMEM, image_asn1(), INIT_LIST_HEAD, next, rc, ref_init, strerror(), and zalloc().

◆ cms_digest()

void cms_digest ( struct cms_message * cms,
struct cms_participant * part,
const void * data,
size_t len,
void * out )
static

Calculate digest of CMS-signed data.

Parameters
cmsCMS message
partParticipant information
dataSigned data
lenLength of signed data
outDigest output

Definition at line 720 of file cms.c.

722 {
723 struct digest_algorithm *digest = part->digest;
724 uint8_t ctx[ digest->ctxsize ];
725
726 /* Calculate digest */
727 digest_init ( digest, ctx );
728 digest_update ( digest, ctx, data, len );
729 digest_final ( digest, ctx, out );
730
731 DBGC ( cms, "CMS %p/%p digest value:\n", cms, part );
732 DBGC_HDA ( cms, 0, out, digest->digestsize );
733}
struct golan_eq_context ctx
Definition CIB_PRM.h:0
__be32 out[4]
Definition CIB_PRM.h:8
unsigned char uint8_t
Definition stdint.h:10
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition crypto.h:219
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition crypto.h:230
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition crypto.h:224
A message digest algorithm.
Definition crypto.h:19
size_t digestsize
Digest size.
Definition crypto.h:27
size_t ctxsize
Context size.
Definition crypto.h:23

References ctx, digest_algorithm::ctxsize, data, DBGC, DBGC_HDA, cms_participant::digest, digest_final(), digest_init(), digest_update(), digest_algorithm::digestsize, len, and out.

Referenced by cms_verify_digest().

◆ cms_verify_digest()

int cms_verify_digest ( struct cms_message * cms,
struct cms_participant * part,
struct x509_certificate * cert,
const void * data,
size_t len )
static

Verify digest of CMS-signed data.

Parameters
cmsCMS message
partParticipant information
certCorresponding certificate
dataSigned data
lenLength of signed data
Return values
rcReturn status code

Definition at line 745 of file cms.c.

748 {
749 struct digest_algorithm *digest = part->digest;
750 struct pubkey_algorithm *pubkey = part->pubkey;
751 const struct asn1_cursor *key = &cert->subject.public_key.raw;
752 const struct asn1_cursor *value = &part->value;
753 uint8_t digest_out[ digest->digestsize ];
754 int rc;
755
756 /* Generate digest */
757 cms_digest ( cms, part, data, len, digest_out );
758
759 /* Verify digest */
760 if ( ( rc = pubkey_verify ( pubkey, key, digest, digest_out,
761 value ) ) != 0 ) {
762 DBGC ( cms, "CMS %p/%p signature verification failed: %s\n",
763 cms, part, strerror ( rc ) );
764 return rc;
765 }
766
767 return 0;
768}
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
pseudo_bit_t value[0x00020]
Definition arbel.h:2
static void cms_digest(struct cms_message *cms, struct cms_participant *part, const void *data, size_t len, void *out)
Calculate digest of CMS-signed data.
Definition cms.c:720
static int pubkey_verify(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature)
Definition crypto.h:308
A public key algorithm.
Definition crypto.h:122
struct x509_subject subject
Subject.
Definition x509.h:245
struct asn1_cursor raw
Raw public key information.
Definition x509.h:52
struct x509_public_key public_key
Public key information.
Definition x509.h:66

References cms_digest(), data, DBGC, cms_participant::digest, digest_algorithm::digestsize, key, len, cms_participant::pubkey, pubkey_verify(), x509_subject::public_key, x509_public_key::raw, rc, strerror(), x509_certificate::subject, cms_participant::value, and value.

Referenced by cms_verify_signer().

◆ cms_verify_signer()

int cms_verify_signer ( struct cms_message * cms,
struct cms_participant * part,
const void * data,
size_t len,
time_t time,
struct x509_chain * store,
struct x509_root * root )
static

Verify CMS message signer.

Parameters
cmsCMS message
partParticipant information
dataSigned data
lenLength of signed data
timeTime at which to validate certificates
storeCertificate store, or NULL to use default
rootRoot certificate list, or NULL to use default
Return values
rcReturn status code

Definition at line 782 of file cms.c.

786 {
787 struct x509_certificate *cert;
788 int rc;
789
790 /* Validate certificate chain */
791 if ( ( rc = x509_validate_chain ( part->chain, time, store,
792 root ) ) != 0 ) {
793 DBGC ( cms, "CMS %p/%p could not validate chain: %s\n",
794 cms, part, strerror ( rc ) );
795 return rc;
796 }
797
798 /* Extract code-signing certificate */
799 cert = x509_first ( part->chain );
800 assert ( cert != NULL );
801
802 /* Check that certificate can create digital signatures */
803 if ( ! ( cert->extensions.usage.bits & X509_DIGITAL_SIGNATURE ) ) {
804 DBGC ( cms, "CMS %p/%p certificate cannot create signatures\n",
805 cms, part );
806 return -EACCES_NON_SIGNING;
807 }
808
809 /* Check that certificate can sign code */
810 if ( ! ( cert->extensions.ext_usage.bits & X509_CODE_SIGNING ) ) {
811 DBGC ( cms, "CMS %p/%p certificate is not code-signing\n",
812 cms, part );
814 }
815
816 /* Verify digest */
817 if ( ( rc = cms_verify_digest ( cms, part, cert, data, len ) ) != 0 )
818 return rc;
819
820 return 0;
821}
static int cms_verify_digest(struct cms_message *cms, struct cms_participant *part, struct x509_certificate *cert, const void *data, size_t len)
Verify digest of CMS-signed data.
Definition cms.c:745
#define EACCES_NON_SIGNING
Definition cms.c:47
#define EACCES_NON_CODE_SIGNING
Definition cms.c:51
struct stp_switch root
Root switch.
Definition stp.h:15
struct x509_extensions extensions
Extensions.
Definition x509.h:249
struct x509_link store
Link in certificate store.
Definition x509.h:221
unsigned int bits
Usage bits.
Definition x509.h:116
struct x509_key_usage usage
Key usage.
Definition x509.h:161
struct x509_extended_key_usage ext_usage
Extended key usage.
Definition x509.h:163
unsigned int bits
Usage bits.
Definition x509.h:97
int x509_validate_chain(struct x509_chain *chain, time_t time, struct x509_chain *store, struct x509_root *root)
Validate X.509 certificate chain.
Definition x509.c:1908
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition x509.h:311
@ X509_CODE_SIGNING
Definition x509.h:125
@ X509_DIGITAL_SIGNATURE
Definition x509.h:102

References assert, x509_extended_key_usage::bits, x509_key_usage::bits, cms_participant::chain, cms_verify_digest(), data, DBGC, EACCES_NON_CODE_SIGNING, EACCES_NON_SIGNING, x509_extensions::ext_usage, x509_certificate::extensions, len, NULL, rc, root, x509_certificate::store, strerror(), x509_extensions::usage, X509_CODE_SIGNING, X509_DIGITAL_SIGNATURE, x509_first(), and x509_validate_chain().

Referenced by cms_verify().

◆ cms_verify()

int cms_verify ( struct cms_message * cms,
struct image * image,
const char * name,
time_t time,
struct x509_chain * store,
struct x509_root * root )

Verify CMS signature.

Parameters
cmsCMS message
imageSigned image
nameRequired common name, or NULL to check all signatures
timeTime at which to validate certificates
storeCertificate store, or NULL to use default
rootRoot certificate list, or NULL to use default
Return values
rcReturn status code

Definition at line 834 of file cms.c.

836 {
837 struct cms_participant *part;
838 struct x509_certificate *cert;
839 int count = 0;
840 int rc;
841
842 /* Mark image as untrusted */
844
845 /* Sanity check */
846 if ( ! cms_is_signature ( cms ) )
847 return -ENOTTY;
848
849 /* Verify using all signers */
850 list_for_each_entry ( part, &cms->participants, list ) {
851 cert = x509_first ( part->chain );
852 if ( name && ( x509_check_name ( cert, name ) != 0 ) )
853 continue;
854 if ( ( rc = cms_verify_signer ( cms, part, image->data,
855 image->len, time, store,
856 root ) ) != 0 )
857 return rc;
858 count++;
859 }
860
861 /* Check that we have verified at least one signature */
862 if ( count == 0 ) {
863 if ( name ) {
864 DBGC ( cms, "CMS %p had no signatures matching name "
865 "%s\n", cms, name );
866 return -EACCES_WRONG_NAME;
867 } else {
868 DBGC ( cms, "CMS %p had no signatures\n", cms );
869 return -EACCES_NO_SIGNATURES;
870 }
871 }
872
873 /* Mark image as trusted */
874 image_trust ( image );
875
876 return 0;
877}
const char * name
Definition ath9k_hw.c:1986
static int cms_verify_signer(struct cms_message *cms, struct cms_participant *part, const void *data, size_t len, time_t time, struct x509_chain *store, struct x509_root *root)
Verify CMS message signer.
Definition cms.c:782
#define EACCES_WRONG_NAME
Definition cms.c:55
#define EACCES_NO_SIGNATURES
Definition cms.c:59
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
static void image_trust(struct image *image)
Set image as trusted.
Definition image.h:268
static void image_untrust(struct image *image)
Set image as untrusted.
Definition image.h:277
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
const void * data
Read-only data.
Definition image.h:51
size_t len
Length of raw file image.
Definition image.h:56
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
Definition x509.c:1564

References cms_participant::chain, cms_is_signature(), cms_verify_signer(), count, image::data, DBGC, EACCES_NO_SIGNATURES, EACCES_WRONG_NAME, ENOTTY, image_trust(), image_untrust(), image::len, list_for_each_entry, name, cms_message::participants, rc, root, x509_certificate::store, x509_check_name(), and x509_first().

Referenced by cms_verify_fail_okx(), cms_verify_okx(), and imgverify().

◆ cms_recipient()

struct cms_participant * cms_recipient ( struct cms_message * cms,
struct private_key * private_key )
static

Identify CMS recipient corresponding to private key.

Parameters
cmsCMS message
private_keyPrivate key
Return values
partParticipant information, or NULL if not found

Definition at line 887 of file cms.c.

887 {
888 struct cms_participant *part;
889 struct x509_certificate *cert;
890
891 /* Identify certificate (if any) for which we have a private key */
892 cert = x509_find_key ( NULL, private_key );
893 if ( ! cert )
894 return NULL;
895
896 /* Identify corresponding recipient, if any */
897 list_for_each_entry ( part, &cms->participants, list ) {
898 if ( cert == x509_first ( part->chain ) )
899 return part;
900 }
901
902 return NULL;
903}
A private key.
Definition privkey.h:17
struct x509_certificate * x509_find_key(struct x509_chain *store, struct private_key *key)
Identify X.509 certificate by corresponding public key.
Definition x509.c:1835

References cms_participant::chain, list_for_each_entry, NULL, cms_message::participants, x509_find_key(), and x509_first().

Referenced by cms_cipher().

◆ cms_cipher_key()

int cms_cipher_key ( struct cms_message * cms,
struct cms_participant * part,
struct private_key * private_key,
void * ctx )
static

Set CMS cipher key.

Parameters
cmsCMS message
partParticipant information
private_keyPrivate key
ctxCipher context
Return values
rcReturn status code

Definition at line 914 of file cms.c.

916 {
917 struct cipher_algorithm *cipher = cms->cipher;
918 struct pubkey_algorithm *pubkey = part->pubkey;
919 const struct asn1_cursor *key = privkey_cursor ( private_key );
920 const struct asn1_cursor *value = &part->value;
921 struct asn1_builder cipher_key = { NULL, 0 };
922 int rc;
923
924 /* Decrypt cipher key */
925 if ( ( rc = pubkey_decrypt ( pubkey, key, value,
926 &cipher_key ) ) != 0 ) {
927 DBGC ( cms, "CMS %p/%p could not decrypt cipher key: %s\n",
928 cms, part, strerror ( rc ) );
929 DBGC_HDA ( cms, 0, value->data, value->len );
930 goto err_decrypt;
931 }
932 DBGC ( cms, "CMS %p/%p cipher key:\n", cms, part );
933 DBGC_HDA ( cms, 0, cipher_key.data, cipher_key.len );
934
935 /* Set cipher key */
936 if ( ( rc = cipher_setkey ( cipher, ctx, cipher_key.data,
937 cipher_key.len ) ) != 0 ) {
938 DBGC ( cms, "CMS %p could not set cipher key: %s\n",
939 cms, strerror ( rc ) );
940 goto err_setkey;
941 }
942
943 /* Set cipher initialization vector */
944 cipher_setiv ( cipher, ctx, cms->iv.data, cms->iv.len );
945 if ( cms->iv.len ) {
946 DBGC ( cms, "CMS %p cipher IV:\n", cms );
947 DBGC_HDA ( cms, 0, cms->iv.data, cms->iv.len );
948 }
949
950 err_setkey:
951 err_decrypt:
952 free ( cipher_key.data );
953 return rc;
954}
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition crypto.h:235
static void cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv, size_t ivlen)
Definition crypto.h:241
static int pubkey_decrypt(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, const struct asn1_cursor *ciphertext, struct asn1_builder *plaintext)
Definition crypto.h:294
static struct asn1_cursor * privkey_cursor(struct private_key *key)
Get private key ASN.1 cursor.
Definition privkey.h:53
An ASN.1 object builder.
Definition asn1.h:29
void * data
Data.
Definition asn1.h:36
size_t len
Length of data.
Definition asn1.h:38
A cipher algorithm.
Definition crypto.h:51

References cms_message::cipher, cipher_setiv(), cipher_setkey(), ctx, asn1_builder::data, asn1_cursor::data, DBGC, DBGC_HDA, free, cms_message::iv, key, asn1_builder::len, asn1_cursor::len, NULL, privkey_cursor(), cms_participant::pubkey, pubkey_decrypt(), rc, strerror(), cms_participant::value, and value.

Referenced by cms_cipher().

◆ cms_cipher()

int cms_cipher ( struct cms_message * cms,
struct private_key * private_key,
void * ctx )
static

Initialise cipher for CMS decryption.

Parameters
cmsCMS message
private_keyPrivate key
ctxCipher context
Return values
rcReturn status code

Definition at line 964 of file cms.c.

965 {
966 struct cms_participant *part;
967 int rc;
968
969 /* Identify a usable recipient */
970 part = cms_recipient ( cms, private_key );
971 if ( ! part ) {
972 DBGC ( cms, "CMS %p had no usable recipients\n", cms );
973 return -EACCES_NO_RECIPIENTS;
974 }
975
976 /* Decrypt and set cipher key */
977 if ( ( rc = cms_cipher_key ( cms, part, private_key, ctx ) ) != 0 )
978 return rc;
979
980 return 0;
981}
#define EACCES_NO_RECIPIENTS
Definition cms.c:63
static struct cms_participant * cms_recipient(struct cms_message *cms, struct private_key *private_key)
Identify CMS recipient corresponding to private key.
Definition cms.c:887
static int cms_cipher_key(struct cms_message *cms, struct cms_participant *part, struct private_key *private_key, void *ctx)
Set CMS cipher key.
Definition cms.c:914

References cms_cipher_key(), cms_recipient(), ctx, DBGC, EACCES_NO_RECIPIENTS, and rc.

Referenced by cms_decrypt().

◆ cms_verify_padding()

int cms_verify_padding ( struct cms_message * cms,
const void * data,
size_t len )
static

Check CMS padding.

Parameters
cmsCMS message
dataFinal block
lenFinal block length
Return values
lenPadding length, or negative error

Definition at line 991 of file cms.c.

992 {
993 struct cipher_algorithm *cipher = cms->cipher;
994 const uint8_t *pad;
995 size_t pad_len;
996 unsigned int i;
997
998 /* Non-block ciphers do not use padding */
999 if ( ! is_block_cipher ( cipher ) )
1000 return 0;
1001
1002 /* Block padding can never produce an empty file */
1003 if ( len == 0 ) {
1004 DBGC ( cms, "CMS %p invalid empty padding\n", cms );
1005 return -EACCES_PAD;
1006 }
1007
1008 /* Sanity check */
1009 assert ( len >= cipher->blocksize );
1010
1011 /* Extract and verify padding */
1012 pad = ( data + len - 1 );
1013 pad_len = *pad;
1014 if ( ( pad_len == 0 ) || ( pad_len > len ) ) {
1015 DBGC ( cms, "CMS %p invalid padding length %zd\n",
1016 cms, pad_len );
1017 return -EACCES_PAD;
1018 }
1019 for ( i = 0 ; i < pad_len ; i++ ) {
1020 if ( *(pad--) != pad_len ) {
1021 DBGC ( cms, "CMS %p invalid padding\n", cms );
1022 DBGC_HDA ( cms, 0, ( data + len - pad_len ), pad_len );
1023 return -EACCES_PAD;
1024 }
1025 }
1026
1027 return pad_len;
1028}
u32 pad[9]
Padding.
Definition ar9003_mac.h:23
long pad_len
Definition bigint.h:31
#define EACCES_PAD
Definition cms.c:71
static int is_block_cipher(struct cipher_algorithm *cipher)
Definition crypto.h:277
size_t blocksize
Block size.
Definition crypto.h:61

References assert, cipher_algorithm::blocksize, cms_message::cipher, data, DBGC, DBGC_HDA, EACCES_PAD, is_block_cipher(), len, pad, and pad_len.

Referenced by cms_decrypt().

◆ cms_decrypt()

int cms_decrypt ( struct cms_message * cms,
struct image * image,
const char * name,
struct private_key * private_key )

Decrypt CMS message.

Parameters
cmsCMS message
imageImage to decrypt
nameDecrypted image name, or NULL to use default
private_keyPrivate key
Return values
rcReturn status code

Definition at line 1039 of file cms.c.

1040 {
1041 struct cipher_algorithm *cipher = cms->cipher;
1042 const unsigned int original_flags = image->flags;
1043 uint8_t ctx[ cipher->ctxsize ];
1044 uint8_t ctxdup[ cipher->ctxsize ];
1045 uint8_t auth[ cipher->authsize ];
1046 uint8_t final[ cipher->blocksize ];
1047 size_t final_len;
1048 size_t bulk_len;
1049 int pad_len;
1050 int rc;
1051
1052 /* Check block size */
1053 if ( ( image->len & ( cipher->blocksize - 1 ) ) != 0 ) {
1054 DBGC ( cms, "CMS %p invalid length %zd\n", cms, image->len );
1055 rc = -EACCES_LEN;
1056 goto err_blocksize;
1057 }
1058
1059 /* Initialise cipher */
1060 if ( ( rc = cms_cipher ( cms, private_key, ctx ) ) != 0 )
1061 goto err_cipher;
1062
1063 /* Duplicate cipher context for potential reencryption on error */
1064 memcpy ( ctxdup, ctx, cipher->ctxsize );
1065
1066 /* Clear trusted flag before modifying image */
1067 image_untrust ( image );
1068
1069 /* Temporarily unregister image, if applicable */
1070 if ( original_flags & IMAGE_REGISTERED ) {
1071 image_get ( image );
1073 }
1074
1075 /* Decrypt all but the final block */
1076 final_len = ( ( image->len && is_block_cipher ( cipher ) ) ?
1077 cipher->blocksize : 0 );
1078 bulk_len = ( image->len - final_len );
1079 cipher_decrypt ( cipher, ctx, image->data, image->rwdata, bulk_len );
1080
1081 /* Decrypt final block */
1082 cipher_decrypt ( cipher, ctx, ( image->data + bulk_len ), final,
1083 final_len );
1084
1085 /* Check authentication tag, if applicable */
1086 cipher_auth ( cipher, ctx, auth );
1087 if ( ( cms->mac.len != cipher->authsize ) ||
1088 ( memcmp ( cms->mac.data, auth, cipher->authsize ) != 0 ) ) {
1089 DBGC ( cms, "CMS %p invalid authentication tag\n", cms );
1090 DBGC_HDA ( cms, 0, auth, cipher->authsize );
1091 rc = -EACCES_MAC;
1092 goto err_auth;
1093 }
1094
1095 /* Check block padding, if applicable */
1096 if ( ( pad_len = cms_verify_padding ( cms, final, final_len ) ) < 0 ) {
1097 rc = pad_len;
1098 goto err_pad;
1099 }
1100
1101 /* Update image name. Do this as the last possible failure, so
1102 * that we do not have to include any error-handling code path
1103 * to restore the original image name (which may itself fail).
1104 */
1105 if ( name ) {
1106 if ( ( rc = image_set_name ( image, name ) ) != 0 )
1107 goto err_set_name;
1108 } else {
1110 }
1111
1112 /* Overwrite final fragment and strip block padding. Do this
1113 * only once no further failure paths exist, so that we do not
1114 * have to include include any error-handling code path to
1115 * reconstruct the block padding.
1116 */
1117 memcpy ( ( image->rwdata + bulk_len ), final, final_len );
1118 image->len -= pad_len;
1119
1120 /* Clear image type and re-register image, if applicable */
1121 image->type = NULL;
1122 if ( original_flags & IMAGE_REGISTERED ) {
1124 image_put ( image );
1125 }
1126
1127 return 0;
1128
1129 err_set_name:
1130 err_pad:
1131 err_auth:
1132 /* Reencrypt all overwritten portions. This can be done since
1133 * we have deliberately not overwritten the final block
1134 * containing the potentially invalid (and therefore
1135 * unreproducible) block padding.
1136 */
1137 cipher_encrypt ( cipher, ctxdup, image->data, image->rwdata, bulk_len );
1138 if ( original_flags & IMAGE_REGISTERED ) {
1139 register_image ( image ); /* Cannot fail on re-registration */
1140 image_put ( image );
1141 }
1142 image->flags = original_flags;
1143 err_cipher:
1144 err_blocksize:
1145 return rc;
1146}
static int cms_cipher(struct cms_message *cms, struct private_key *private_key, void *ctx)
Initialise cipher for CMS decryption.
Definition cms.c:964
static int cms_verify_padding(struct cms_message *cms, const void *data, size_t len)
Check CMS padding.
Definition cms.c:991
#define EACCES_LEN
Definition cms.c:67
#define EACCES_MAC
Definition cms.c:75
char * image_strip_suffix(struct image *image)
Strip dot suffix from image name, if present.
Definition image.c:206
void unregister_image(struct image *image)
Unregister executable image.
Definition image.c:358
int register_image(struct image *image)
Register executable image.
Definition image.c:315
int image_set_name(struct image *image, const char *name)
Set image name.
Definition image.c:181
static struct image * image_get(struct image *image)
Increment reference count on an image.
Definition image.h:240
#define IMAGE_REGISTERED
Image is registered.
Definition image.h:77
static void image_put(struct image *image)
Decrement reference count on an image.
Definition image.h:250
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition crypto.h:261
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition crypto.h:251
static void cipher_auth(struct cipher_algorithm *cipher, void *ctx, void *auth)
Definition crypto.h:267
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
void(* auth)(void *ctx, void *auth)
Generate authentication tag.
Definition crypto.h:118
size_t ctxsize
Context size.
Definition crypto.h:55
unsigned int flags
Flags.
Definition image.h:40
struct image_type * type
Image type, if known.
Definition image.h:59
void * rwdata
Writable data.
Definition image.h:53

References cipher_algorithm::auth, cipher_algorithm::authsize, cipher_algorithm::blocksize, cms_message::cipher, cipher_auth(), cipher_decrypt, cipher_encrypt, cms_cipher(), cms_verify_padding(), ctx, cipher_algorithm::ctxsize, asn1_cursor::data, image::data, DBGC, DBGC_HDA, EACCES_LEN, EACCES_MAC, image::flags, image_get(), image_put(), IMAGE_REGISTERED, image_set_name(), image_strip_suffix(), image_untrust(), is_block_cipher(), asn1_cursor::len, image::len, cms_message::mac, memcmp(), memcpy(), name, NULL, pad_len, rc, register_image(), image::rwdata, image::type, and unregister_image().

Referenced by cms_decrypt_okx(), and imgdecrypt().

Variable Documentation

◆ oid_signeddata

uint8_t oid_signeddata[] = { ASN1_OID_SIGNEDDATA }
static

"id-signedData" object identifier

Definition at line 90 of file cms.c.

#define ASN1_OID_SIGNEDDATA
ASN.1 OID for id-signedData (1.2.840.113549.1.7.2)
Definition asn1.h:349

◆ oid_envelopeddata

uint8_t oid_envelopeddata[] = { ASN1_OID_ENVELOPEDDATA }
static

"id-envelopedData" object identifier

Definition at line 93 of file cms.c.

#define ASN1_OID_ENVELOPEDDATA
ASN.1 OID for id-envelopedData (1.2.840.113549.1.7.3)
Definition asn1.h:355

◆ oid_authenvelopeddata

uint8_t oid_authenvelopeddata[] = { ASN1_OID_AUTHENVELOPEDDATA }
static

"id-authEnvelopedData" object identifier

Definition at line 96 of file cms.c.

#define ASN1_OID_AUTHENVELOPEDDATA
ASN.1 OID for id-authEnvelopedData (1.2.840.113549.1.9.16.1.23)
Definition asn1.h:361

◆ cms_types

struct cms_type cms_types[]
static
Initial value:
= {
{
.name = "signed",
.parse = cms_parse_signed,
},
{
.name = "enveloped",
},
{
.name = "authEnveloped",
}
}
#define ASN1_CURSOR(value)
Define an ASN.1 cursor for a static value.
Definition asn1.h:402
static uint8_t oid_authenvelopeddata[]
"id-authEnvelopedData" object identifier
Definition cms.c:96
static int cms_parse_enveloped(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS enveloped data.
Definition cms.c:575
static int cms_parse_signed(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS signed data.
Definition cms.c:530
static uint8_t oid_envelopeddata[]
"id-envelopedData" object identifier
Definition cms.c:93
static uint8_t oid_signeddata[]
"id-signedData" object identifier
Definition cms.c:90

CMS message types.

Definition at line 99 of file cms.c.

99 {
100 {
101 .name = "signed",
102 .oid = ASN1_CURSOR ( oid_signeddata ),
103 .parse = cms_parse_signed,
104 },
105 {
106 .name = "enveloped",
108 .parse = cms_parse_enveloped,
109 },
110 {
111 .name = "authEnveloped",
113 .parse = cms_parse_enveloped,
114 }
115};

Referenced by cms_parse_content_type().