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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
pub mod record_layer_header;
#[cfg(test)]
mod record_layer_test;
use record_layer_header::*;
use crate::alert::Alert;
use crate::application_data::ApplicationData;
use crate::change_cipher_spec::ChangeCipherSpec;
use crate::handshake::Handshake;
use super::content::*;
use super::error::*;
use std::io::{Read, Write};
#[derive(Debug, Clone, PartialEq)]
pub struct RecordLayer {
pub record_layer_header: RecordLayerHeader,
pub content: Content,
}
impl RecordLayer {
pub fn new(protocol_version: ProtocolVersion, epoch: u16, content: Content) -> Self {
RecordLayer {
record_layer_header: RecordLayerHeader {
content_type: content.content_type(),
protocol_version,
epoch,
sequence_number: 0,
content_len: content.size() as u16,
},
content,
}
}
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
self.record_layer_header.marshal(writer)?;
self.content.marshal(writer)?;
Ok(())
}
pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self, Error> {
let record_layer_header = RecordLayerHeader::unmarshal(reader)?;
let content = match record_layer_header.content_type {
ContentType::Alert => Content::Alert(Alert::unmarshal(reader)?),
ContentType::ApplicationData => {
Content::ApplicationData(ApplicationData::unmarshal(reader)?)
}
ContentType::ChangeCipherSpec => {
Content::ChangeCipherSpec(ChangeCipherSpec::unmarshal(reader)?)
}
ContentType::Handshake => Content::Handshake(Handshake::unmarshal(reader)?),
_ => return Err(Error::ErrOthers("Invalid Content Type".to_owned())),
};
Ok(RecordLayer {
record_layer_header,
content,
})
}
}
pub(crate) fn unpack_datagram(buf: &[u8]) -> Result<Vec<Vec<u8>>, Error> {
let mut out = vec![];
let mut offset = 0;
while buf.len() != offset {
if buf.len() - offset <= RECORD_LAYER_HEADER_SIZE {
return Err(Error::ErrInvalidPacketLength);
}
let pkt_len = RECORD_LAYER_HEADER_SIZE
+ (((buf[offset + RECORD_LAYER_HEADER_SIZE - 2] as usize) << 8)
| buf[offset + RECORD_LAYER_HEADER_SIZE - 1] as usize);
if offset + pkt_len > buf.len() {
return Err(Error::ErrInvalidPacketLength);
}
out.push(buf[offset..offset + pkt_len].to_vec());
offset += pkt_len
}
Ok(out)
}