internet/ietf/tls1_0/encoding/
change_cipher_spec.rs1use crate::{
11 Buf,
12 BufError::{self},
13 BufMut, BufResult, Codec, Cursor,
14};
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
20#[repr(u8)]
21pub enum ChangeCipherSpecType {
22 ChangeCipherSpec = 1,
24}
25
26impl Codec for ChangeCipherSpecType {
27 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
28 (*self as u8).encode(writer, ())
29 }
30
31 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
32 match u8::decode(reader, ())? {
33 x if x == (Self::ChangeCipherSpec as u8) => Ok(Self::ChangeCipherSpec),
34 _ => Err(BufError::UnexpectedValue),
35 }
36 }
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
43pub struct ChangeCipherSpec {
44 pub type_: ChangeCipherSpecType,
46}
47
48impl Codec for ChangeCipherSpec {
49 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
50 self.type_.encode(writer, ())
51 }
52
53 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
54 Ok(Self {
55 type_: ChangeCipherSpecType::decode(reader, ())?,
56 })
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use core::fmt::Debug;
63
64 use super::{ChangeCipherSpec, ChangeCipherSpecType};
65 use crate::{Codec, Cursor};
66
67 fn codec_roundtrip<T: Codec<C> + Debug + Eq, C: Copy>(
68 etalon_struct: T,
69 etalon_bytes: &[u8],
70 context: C,
71 ) {
72 let mut encoded_bytes = vec![];
73 {
74 let writer = &mut Cursor::new(&mut encoded_bytes);
75 etalon_struct.encode(writer, context).unwrap();
76 }
77 assert_eq!(etalon_bytes, &encoded_bytes);
78
79 let decoded_struct = {
80 let reader = &mut Cursor::new(&mut encoded_bytes);
81 T::decode(reader, context).unwrap()
82 };
83 assert_eq!(etalon_struct, decoded_struct);
84
85 encoded_bytes.fill(0x00);
86 {
87 let writer = &mut Cursor::new(&mut encoded_bytes);
88 decoded_struct.encode(writer, context).unwrap();
89 }
90 assert_eq!(etalon_bytes, &encoded_bytes);
91 }
92
93 #[test]
94 fn change_cipher_spec() {
95 let etalon_bytes = &[0x01];
96 let etalon_struct = ChangeCipherSpec {
97 type_: ChangeCipherSpecType::ChangeCipherSpec,
98 };
99
100 codec_roundtrip(etalon_struct, etalon_bytes, ());
101 }
102}