1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
use puffin::algebra::Matcher;
use serde::{Deserialize, Serialize};

use crate::tls::rustls::msgs::enums::HandshakeType;

/// [TlsQueryMatcher] contains TLS-related typing information, this is to be distinguished from the
/// *.typ fields It uses [rustls::msgs::enums::{ContentType,HandshakeType}].
#[derive(Debug, Deserialize, Serialize, Clone, Copy, Hash, Eq, PartialEq)]
pub enum TlsQueryMatcher {
    ChangeCipherSpec,
    Alert,
    Handshake(Option<HandshakeType>),
    ApplicationData,
    Heartbeat,
}

impl Matcher for TlsQueryMatcher {
    fn matches(&self, matcher: &TlsQueryMatcher) -> bool {
        match matcher {
            TlsQueryMatcher::Handshake(query_handshake_type) => match self {
                TlsQueryMatcher::Handshake(handshake_type) => {
                    handshake_type.matches(query_handshake_type)
                }
                _ => false,
            },
            TlsQueryMatcher::ChangeCipherSpec => matches!(self, TlsQueryMatcher::ChangeCipherSpec),
            TlsQueryMatcher::Alert => matches!(self, TlsQueryMatcher::Alert),
            TlsQueryMatcher::Heartbeat => matches!(self, TlsQueryMatcher::Heartbeat),
            TlsQueryMatcher::ApplicationData => matches!(self, TlsQueryMatcher::ApplicationData),
        }
    }

    fn specificity(&self) -> u32 {
        match self {
            TlsQueryMatcher::Handshake(handshake_type) => {
                1 + match handshake_type {
                    None => 0,
                    Some(handshake_type) => handshake_type.specificity(),
                }
            }
            _ => 0,
        }
    }
}