Initial commit
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
128
src/extensions/extension_data/key_share.rs
Normal file
128
src/extensions/extension_data/key_share.rs
Normal file
@@ -0,0 +1,128 @@
|
||||
use heapless::Vec;
|
||||
|
||||
use crate::buffer::CryptoBuffer;
|
||||
use crate::extensions::extension_data::supported_groups::NamedGroup;
|
||||
|
||||
use crate::ProtocolError;
|
||||
use crate::parse_buffer::{ParseBuffer, ParseError};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct KeyShareServerHello<'a>(pub KeyShareEntry<'a>);
|
||||
|
||||
impl<'a> KeyShareServerHello<'a> {
|
||||
pub fn parse(buf: &mut ParseBuffer<'a>) -> Result<Self, ParseError> {
|
||||
Ok(KeyShareServerHello(KeyShareEntry::parse(buf)?))
|
||||
}
|
||||
|
||||
pub fn encode(&self, buf: &mut CryptoBuffer) -> Result<(), ProtocolError> {
|
||||
self.0.encode(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct KeyShareClientHello<'a, const N: usize> {
|
||||
pub client_shares: Vec<KeyShareEntry<'a>, N>,
|
||||
}
|
||||
|
||||
impl<'a, const N: usize> KeyShareClientHello<'a, N> {
|
||||
pub fn parse(buf: &mut ParseBuffer<'a>) -> Result<Self, ParseError> {
|
||||
let len = buf.read_u16()? as usize;
|
||||
Ok(KeyShareClientHello {
|
||||
client_shares: buf.read_list(len, KeyShareEntry::parse)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn encode(&self, buf: &mut CryptoBuffer) -> Result<(), ProtocolError> {
|
||||
buf.with_u16_length(|buf| {
|
||||
for client_share in &self.client_shares {
|
||||
client_share.encode(buf)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct KeyShareHelloRetryRequest {
|
||||
pub selected_group: NamedGroup,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl KeyShareHelloRetryRequest {
|
||||
pub fn parse(buf: &mut ParseBuffer) -> Result<Self, ParseError> {
|
||||
Ok(Self {
|
||||
selected_group: NamedGroup::parse(buf)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn encode(&self, buf: &mut CryptoBuffer) -> Result<(), ProtocolError> {
|
||||
self.selected_group.encode(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct KeyShareEntry<'a> {
|
||||
pub(crate) group: NamedGroup,
|
||||
pub(crate) opaque: &'a [u8],
|
||||
}
|
||||
|
||||
impl<'a> KeyShareEntry<'a> {
|
||||
pub fn parse(buf: &mut ParseBuffer<'a>) -> Result<Self, ParseError> {
|
||||
let group = NamedGroup::parse(buf)?;
|
||||
|
||||
let opaque_len = buf.read_u16()?;
|
||||
let opaque = buf.slice(opaque_len as usize)?;
|
||||
|
||||
Ok(Self {
|
||||
group,
|
||||
opaque: opaque.as_slice(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn encode(&self, buf: &mut CryptoBuffer) -> Result<(), ProtocolError> {
|
||||
self.group.encode(buf)?;
|
||||
|
||||
buf.with_u16_length(|buf| buf.extend_from_slice(self.opaque))
|
||||
.map_err(|_| ProtocolError::EncodeError)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use std::sync::Once;
|
||||
|
||||
static INIT: Once = Once::new();
|
||||
|
||||
fn setup() {
|
||||
INIT.call_once(|| {
|
||||
env_logger::init();
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_empty() {
|
||||
setup();
|
||||
let buffer = [0x00, 0x17, 0x00, 0x00];
|
||||
let result = KeyShareEntry::parse(&mut ParseBuffer::new(&buffer)).unwrap();
|
||||
|
||||
assert_eq!(NamedGroup::Secp256r1, result.group);
|
||||
assert_eq!(0, result.opaque.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
setup();
|
||||
let buffer = [0x00, 0x17, 0x00, 0x02, 0xAA, 0xBB];
|
||||
let result = KeyShareEntry::parse(&mut ParseBuffer::new(&buffer)).unwrap();
|
||||
|
||||
assert_eq!(NamedGroup::Secp256r1, result.group);
|
||||
assert_eq!(2, result.opaque.len());
|
||||
assert_eq!([0xAA, 0xBB], result.opaque);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user