2 * Routines for RFC5652 Cryptographic Message Syntax packet dissection
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include <epan/packet.h>
17 #include <epan/oids.h>
18 #include <epan/asn1.h>
19 #include <epan/proto_data.h>
20 #include <wsutil/wsgcrypt.h>
21 #include <wsutil/array.h>
23 #include "packet-ber.h"
24 #include "packet-cms.h"
25 #include "packet-x509af.h"
26 #include "packet-x509ce.h"
27 #include "packet-x509if.h"
28 #include "packet-x509sat.h"
29 #include "packet-pkcs12.h"
31 #define PNAME "Cryptographic Message Syntax"
35 void proto_register_cms(void);
36 void proto_reg_handoff_cms(void);
38 /* Initialize the protocol and registered fields */
40 static int hf_cms_ci_contentType
;
41 #include "packet-cms-hf.c"
43 /* Initialize the subtree pointers */
45 #include "packet-cms-ett.c"
47 static dissector_handle_t cms_handle
;
49 static int dissect_cms_OCTET_STRING(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index _U_
) ; /* XXX kill a compiler warning until asn2wrs stops generating these silly wrappers */
51 struct cms_private_data
{
52 const char *object_identifier_id
;
53 tvbuff_t
*content_tvb
;
56 static proto_tree
*top_tree
;
57 static proto_tree
*cap_tree
;
59 #define HASH_SHA1 "1.3.14.3.2.26"
61 #define HASH_MD5 "1.2.840.113549.2.5"
65 #define HASH_SHA224 "2.16.840.1.101.3.4.2.4"
66 #define SHA224_BUFFER_SIZE 32 /* actually 28 */
67 #define HASH_SHA256 "2.16.840.1.101.3.4.2.1"
68 #define SHA256_BUFFER_SIZE 32
70 unsigned char digest_buf
[MAX(HASH_SHA1_LENGTH
, HASH_MD5_LENGTH
)];
73 * Dissect CMS PDUs inside a PPDU.
76 dissect_cms(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, void* data _U_
)
79 proto_item
*item
=NULL
;
80 proto_tree
*tree
=NULL
;
82 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
85 item
= proto_tree_add_item(parent_tree
, proto_cms
, tvb
, 0, -1, ENC_NA
);
86 tree
= proto_item_add_subtree(item
, ett_cms
);
88 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CMS");
89 col_clear(pinfo
->cinfo
, COL_INFO
);
91 while (tvb_reported_length_remaining(tvb
, offset
) > 0){
92 offset
=dissect_cms_ContentInfo(false, tvb
, offset
, &asn1_ctx
, tree
, -1);
94 return tvb_captured_length(tvb
);
97 static struct cms_private_data
*
98 cms_get_private_data(packet_info
*pinfo
)
100 struct cms_private_data
*cms_data
= (struct cms_private_data
*)p_get_proto_data(pinfo
->pool
, pinfo
, proto_cms
, 0);
102 cms_data
= wmem_new0(pinfo
->pool
, struct cms_private_data
);
103 p_add_proto_data(pinfo
->pool
, pinfo
, proto_cms
, 0, cms_data
);
109 cms_verify_msg_digest(proto_item
*pi
, tvbuff_t
*content
, const char *alg
, tvbuff_t
*tvb
, int offset
)
111 int i
= 0, buffer_size
= 0;
113 /* we only support two algorithms at the moment - if we do add SHA2
114 we should add a registration process to use a registration process */
116 if(strcmp(alg
, HASH_SHA1
) == 0) {
117 gcry_md_hash_buffer(GCRY_MD_SHA1
, digest_buf
, tvb_get_ptr(content
, 0, tvb_captured_length(content
)), tvb_captured_length(content
));
118 buffer_size
= HASH_SHA1_LENGTH
;
120 } else if(strcmp(alg
, HASH_MD5
) == 0) {
121 gcry_md_hash_buffer(GCRY_MD_MD5
, digest_buf
, tvb_get_ptr(content
, 0, tvb_captured_length(content
)), tvb_captured_length(content
));
122 buffer_size
= HASH_MD5_LENGTH
;
126 /* compare our computed hash with what we have received */
128 if(tvb_bytes_exist(tvb
, offset
, buffer_size
) &&
129 (tvb_memeql(tvb
, offset
, digest_buf
, buffer_size
) != 0)) {
130 proto_item_append_text(pi
, " [incorrect, should be ");
131 for(i
= 0; i
< buffer_size
; i
++)
132 proto_item_append_text(pi
, "%02X", digest_buf
[i
]);
134 proto_item_append_text(pi
, "]");
137 proto_item_append_text(pi
, " [correct]");
139 proto_item_append_text(pi
, " [unable to verify]");
144 #include "packet-cms-fn.c"
146 /*--- proto_register_cms ----------------------------------------------*/
147 void proto_register_cms(void) {
150 static hf_register_info hf
[] = {
151 { &hf_cms_ci_contentType
,
152 { "contentType", "cms.contentInfo.contentType",
153 FT_OID
, BASE_NONE
, NULL
, 0,
155 #include "packet-cms-hfarr.c"
158 /* List of subtrees */
159 static int *ett
[] = {
161 #include "packet-cms-ettarr.c"
164 /* Register protocol */
165 proto_cms
= proto_register_protocol(PNAME
, PSNAME
, PFNAME
);
167 cms_handle
= register_dissector(PFNAME
, dissect_cms
, proto_cms
);
169 /* Register fields and subtrees */
170 proto_register_field_array(proto_cms
, hf
, array_length(hf
));
171 proto_register_subtree_array(ett
, array_length(ett
));
173 register_ber_syntax_dissector("ContentInfo", proto_cms
, dissect_ContentInfo_PDU
);
174 register_ber_syntax_dissector("SignedData", proto_cms
, dissect_SignedData_PDU
);
175 register_ber_oid_syntax(".p7s", NULL
, "ContentInfo");
176 register_ber_oid_syntax(".p7m", NULL
, "ContentInfo");
177 register_ber_oid_syntax(".p7c", NULL
, "ContentInfo");
183 /*--- proto_reg_handoff_cms -------------------------------------------*/
184 void proto_reg_handoff_cms(void) {
185 dissector_handle_t content_info_handle
;
186 #include "packet-cms-dis-tab.c"
188 /* RFC 3370 [CMS-ASN} section 4.3.1 */
189 register_ber_oid_dissector("1.2.840.113549.1.9.16.3.6", dissect_ber_oid_NULL_callback
, proto_cms
, "id-alg-CMS3DESwrap");
191 oid_add_from_string("id-data","1.2.840.113549.1.7.1");
192 oid_add_from_string("id-alg-des-ede3-cbc","1.2.840.113549.3.7");
193 oid_add_from_string("id-alg-des-cbc","1.3.14.3.2.7");
195 oid_add_from_string("id-ct-authEnvelopedData","1.2.840.113549.1.9.16.1.23");
196 oid_add_from_string("id-aes-CBC-CMAC-128","0.4.0.127.0.7.1.3.1.1.2");
197 oid_add_from_string("id-aes-CBC-CMAC-192","0.4.0.127.0.7.1.3.1.1.3");
198 oid_add_from_string("id-aes-CBC-CMAC-256","0.4.0.127.0.7.1.3.1.1.4");
199 oid_add_from_string("ecdsaWithSHA256","1.2.840.10045.4.3.2");
200 oid_add_from_string("ecdsaWithSHA384","1.2.840.10045.4.3.3");
201 oid_add_from_string("ecdsaWithSHA512","1.2.840.10045.4.3.4");
203 content_info_handle
= create_dissector_handle (dissect_ContentInfo_PDU
, proto_cms
);
205 dissector_add_string("media_type", "application/pkcs7-mime", content_info_handle
);
206 dissector_add_string("media_type", "application/pkcs7-signature", content_info_handle
);
208 dissector_add_string("media_type", "application/vnd.de-dke-k461-ic1+xml", content_info_handle
);
209 dissector_add_string("media_type", "application/vnd.de-dke-k461-ic1+xml; encap=cms-tr03109", content_info_handle
);
210 dissector_add_string("media_type", "application/vnd.de-dke-k461-ic1+xml; encap=cms-tr03109-zlib", content_info_handle
);
211 dissector_add_string("media_type", "application/hgp;encap=cms", content_info_handle
);