summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-ssl-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-ssl-utils.c')
-rw-r--r--epan/dissectors/packet-ssl-utils.c96
1 files changed, 65 insertions, 31 deletions
diff --git a/epan/dissectors/packet-ssl-utils.c b/epan/dissectors/packet-ssl-utils.c
index e8db3eac14..fb5bce333f 100644
--- a/epan/dissectors/packet-ssl-utils.c
+++ b/epan/dissectors/packet-ssl-utils.c
@@ -5737,15 +5737,22 @@ ssl_dissect_hnd_cert(ssl_common_dissect_t *hf, tvbuff_t *tvb, proto_tree *tree,
guint32 offset, packet_info *pinfo,
const SslSession *session, gint is_from_server)
{
- /* opaque ASN.1Cert<2^24-1>;
+ /* opaque ASN.1Cert<1..2^24-1>;
*
* struct {
- * ASN.1Cert certificate_list<1..2^24-1>;
+ * select(certificate_type) {
+ *
+ * // certificate type defined in RFC 7250
+ * case RawPublicKey:
+ * opaque ASN.1_subjectPublicKeyInfo<1..2^24-1>;
+ *
+ * // X.509 certificate defined in RFC 5246
+ * case X.509:
+ * ASN.1Cert certificate_list<0..2^24-1>;
+ * };
* } Certificate;
*/
- guint32 certificate_list_length;
- proto_item *ti;
- proto_tree *subtree;
+ enum { CERT_X509, CERT_RPK } cert_type;
asn1_ctx_t asn1_ctx;
if (!tree)
@@ -5753,40 +5760,67 @@ ssl_dissect_hnd_cert(ssl_common_dissect_t *hf, tvbuff_t *tvb, proto_tree *tree,
asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
- certificate_list_length = tvb_get_ntoh24(tvb, offset);
- proto_tree_add_uint(tree, hf->hf.hs_certificates_len,
- tvb, offset, 3, certificate_list_length);
- offset += 3; /* 24-bit length value */
-
- if (certificate_list_length > 0) {
- ti = proto_tree_add_none_format(tree,
- hf->hf.hs_certificates,
- tvb, offset, certificate_list_length,
- "Certificates (%u bytes)",
- certificate_list_length);
-
- /* make it a subtree */
- subtree = proto_item_add_subtree(ti, hf->ett.certificates);
+ if ((is_from_server && session->server_cert_type == SSL_HND_CERT_TYPE_RAW_PUBLIC_KEY) ||
+ (!is_from_server && session->client_cert_type == SSL_HND_CERT_TYPE_RAW_PUBLIC_KEY)) {
+ cert_type = CERT_RPK;
+ } else {
+ cert_type = CERT_X509;
+ }
- /* iterate through each certificate */
- while (certificate_list_length > 0) {
- /* get the length of the current certificate */
+ switch (cert_type) {
+ case CERT_RPK:
+ {
guint32 cert_length;
cert_length = tvb_get_ntoh24(tvb, offset);
- certificate_list_length -= 3 + cert_length;
- proto_tree_add_item(subtree, hf->hf.hs_certificate_len,
+ proto_tree_add_item(tree, hf->hf.hs_certificate_len,
tvb, offset, 3, ENC_BIG_ENDIAN);
offset += 3;
- if ((is_from_server && session->server_cert_type == SSL_HND_CERT_TYPE_RAW_PUBLIC_KEY) ||
- (!is_from_server && session->client_cert_type == SSL_HND_CERT_TYPE_RAW_PUBLIC_KEY)) {
- dissect_x509af_SubjectPublicKeyInfo(FALSE, tvb, offset, &asn1_ctx, subtree, hf->hf.hs_certificate);
- } else {
- dissect_x509af_Certificate(FALSE, tvb, offset, &asn1_ctx, subtree, hf->hf.hs_certificate);
- }
-
+ dissect_x509af_SubjectPublicKeyInfo(FALSE, tvb, offset, &asn1_ctx, tree, hf->hf.hs_certificate);
offset += cert_length;
+
+ break;
+ }
+ case CERT_X509:
+ {
+ guint32 certificate_list_length;
+ proto_item *ti;
+ proto_tree *subtree;
+
+ certificate_list_length = tvb_get_ntoh24(tvb, offset);
+
+ proto_tree_add_uint(tree, hf->hf.hs_certificates_len,
+ tvb, offset, 3, certificate_list_length);
+ offset += 3; /* 24-bit length value */
+
+ if (certificate_list_length > 0) {
+ ti = proto_tree_add_none_format(tree,
+ hf->hf.hs_certificates,
+ tvb, offset, certificate_list_length,
+ "Certificates (%u bytes)",
+ certificate_list_length);
+
+ /* make it a subtree */
+ subtree = proto_item_add_subtree(ti, hf->ett.certificates);
+
+ /* iterate through each certificate */
+ while (certificate_list_length > 0) {
+ /* get the length of the current certificate */
+ guint32 cert_length;
+ cert_length = tvb_get_ntoh24(tvb, offset);
+ certificate_list_length -= 3 + cert_length;
+
+ proto_tree_add_item(subtree, hf->hf.hs_certificate_len,
+ tvb, offset, 3, ENC_BIG_ENDIAN);
+ offset += 3;
+
+ dissect_x509af_Certificate(FALSE, tvb, offset, &asn1_ctx, subtree, hf->hf.hs_certificate);
+
+ offset += cert_length;
+ }
+ }
+ break;
}
}
}