1use alloc::vec::Vec;
2use nom::error::{make_error, ErrorKind};
3use nom::multi::length_data;
4use nom::number::streaming::be_u8;
5use nom::{Err, IResult};
6use nom_derive::*;
7use rusticata_macros::newtype_enum;
8
9#[derive(Clone, Copy, PartialEq, Eq, NomBE)]
15pub struct NamedGroup(pub u16);
16
17newtype_enum! {
18impl debug NamedGroup {
19 Sect163k1 = 1,
20 Sect163r1 = 2,
21 Sect163r2 = 3,
22 Sect193r1 = 4,
23 Sect193r2 = 5,
24 Sect233k1 = 6,
25 Sect233r1 = 7,
26 Sect239k1 = 8,
27 Sect283k1 = 9,
28 Sect283r1 = 10,
29 Sect409k1 = 11,
30 Sect409r1 = 12,
31 Sect571k1 = 13,
32 Sect571r1 = 14,
33 Secp160k1 = 15,
34 Secp160r1 = 16,
35 Secp160r2 = 17,
36 Secp192k1 = 18,
37 Secp192r1 = 19,
38 Secp224k1 = 20,
39 Secp224r1 = 21,
40 Secp256k1 = 22,
41 Secp256r1 = 23,
42 Secp384r1 = 24,
43 Secp521r1 = 25,
44 BrainpoolP256r1 = 26,
45 BrainpoolP384r1 = 27,
46 BrainpoolP512r1 = 28,
47 EcdhX25519 = 29,
48 EcdhX448 = 30,
49 BrainpoolP256r1tls13 = 31,
50 BrainpoolP384r1tls13 = 32,
51 BrainpoolP512r1tls13 = 33,
52 Sm2 = 41,
53 Ffdhe2048 = 0x100,
54 Ffdhe3072 = 0x101,
55 Ffdhe4096 = 0x102,
56 Ffdhe6144 = 0x103,
57 Ffdhe8192 = 0x104,
58 ArbitraryExplicitPrimeCurves = 0xFF01,
59 ArbitraryExplicitChar2Curves = 0xFF02,
60}
61}
62
63impl NamedGroup {
64 pub fn key_bits(self: NamedGroup) -> Option<u16> {
66 match self {
67 NamedGroup::Sect163k1 => Some(163),
68 NamedGroup::Sect163r1 => Some(163),
69 NamedGroup::Sect163r2 => Some(163),
70 NamedGroup::Sect193r1 => Some(193),
71 NamedGroup::Sect193r2 => Some(193),
72 NamedGroup::Sect233k1 => Some(233),
73 NamedGroup::Sect233r1 => Some(233),
74 NamedGroup::Sect239k1 => Some(239),
75 NamedGroup::Sect283k1 => Some(283),
76 NamedGroup::Sect283r1 => Some(283),
77 NamedGroup::Sect409k1 => Some(409),
78 NamedGroup::Sect409r1 => Some(409),
79 NamedGroup::Sect571k1 => Some(571),
80 NamedGroup::Sect571r1 => Some(571),
81 NamedGroup::Secp160k1 => Some(160),
82 NamedGroup::Secp160r1 => Some(160),
83 NamedGroup::Secp160r2 => Some(160),
84 NamedGroup::Secp192k1 => Some(192),
85 NamedGroup::Secp192r1 => Some(192),
86 NamedGroup::Secp224k1 => Some(224),
87 NamedGroup::Secp224r1 => Some(224),
88 NamedGroup::Secp256k1 => Some(256),
89 NamedGroup::Secp256r1 => Some(256),
90 NamedGroup::Secp384r1 => Some(384),
91 NamedGroup::Secp521r1 => Some(521),
92 NamedGroup::BrainpoolP256r1 => Some(256),
93 NamedGroup::BrainpoolP384r1 => Some(384),
94 NamedGroup::BrainpoolP512r1 => Some(521),
95 NamedGroup::EcdhX25519 => Some(253),
96 _ => None,
97 }
98 }
99}
100
101#[derive(Debug, PartialEq, NomBE)]
105pub struct ECCurve<'a> {
106 #[nom(Parse = "length_data(be_u8)")]
107 pub a: &'a [u8],
108 #[nom(Parse = "length_data(be_u8)")]
109 pub b: &'a [u8],
110}
111
112#[derive(Clone, Copy, PartialEq, Eq, NomBE)]
116pub struct ECCurveType(pub u8);
117
118newtype_enum! {
119impl display ECCurveType {
120 ExplicitPrime = 1,
121 ExplicitChar2 = 2,
122 NamedGroup = 3,
123}
124}
125
126#[derive(Clone, Debug, PartialEq, NomBE)]
128pub struct ECPoint<'a> {
129 #[nom(Parse = "length_data(be_u8)")]
130 pub point: &'a [u8],
131}
132
133#[derive(Debug, PartialEq, NomBE)]
136pub struct ExplicitPrimeContent<'a> {
137 #[nom(Parse = "length_data(be_u8)")]
138 pub prime_p: &'a [u8],
139 pub curve: ECCurve<'a>,
140 pub base: ECPoint<'a>,
141 #[nom(Parse = "length_data(be_u8)")]
142 pub order: &'a [u8],
143 #[nom(Parse = "length_data(be_u8)")]
144 pub cofactor: &'a [u8],
145}
146
147#[derive(PartialEq, Nom)]
149#[nom(Selector = "ECCurveType")]
150pub enum ECParametersContent<'a> {
151 #[nom(Selector = "ECCurveType::ExplicitPrime")]
152 ExplicitPrime(ExplicitPrimeContent<'a>),
153 #[nom(Selector = "ECCurveType::NamedGroup")]
157 NamedGroup(NamedGroup),
158}
159
160#[derive(PartialEq, NomBE)]
163pub struct ECParameters<'a> {
164 pub curve_type: ECCurveType,
166 #[nom(Parse = "{|i| ECParametersContent::parse(i, curve_type)}")]
167 pub params_content: ECParametersContent<'a>,
168}
169
170#[derive(Debug, PartialEq, NomBE)]
173pub struct ServerECDHParams<'a> {
174 pub curve_params: ECParameters<'a>,
175 pub public: ECPoint<'a>,
176}
177
178pub fn parse_named_groups(i: &[u8]) -> IResult<&[u8], Vec<NamedGroup>> {
180 let len = i.len();
181 if len == 0 {
182 return Ok((i, Vec::new()));
183 }
184 if len % 2 == 1 || len > i.len() {
185 return Err(Err::Error(make_error(i, ErrorKind::LengthValue)));
186 }
187 let v = (i[..len])
188 .chunks(2)
189 .map(|chunk| NamedGroup((chunk[0] as u16) << 8 | chunk[1] as u16))
190 .collect();
191 Ok((&i[len..], v))
192}
193
194#[inline]
195pub fn parse_ec_parameters(i: &[u8]) -> IResult<&[u8], ECParameters> {
196 ECParameters::parse(i)
197}
198
199#[inline]
200pub fn parse_ecdh_params(i: &[u8]) -> IResult<&[u8], ServerECDHParams> {
201 ServerECDHParams::parse(i)
202}