boring_imp/ssl/
cert_compression.rs1use brotli::enc::encode::BrotliEncoderInitParams;
2use ffi;
3use libc::c_int;
4use std::{io::Read, slice};
5
6#[repr(u16)]
8#[derive(Debug, Copy, Clone, PartialEq, Eq)]
9pub enum CertCompressionAlgorithm {
10 Brotli = ffi::TLSEXT_cert_compression_brotli as _,
11 Zlib = ffi::TLSEXT_cert_compression_zlib as _,
12}
13
14impl CertCompressionAlgorithm {
15 pub fn compression_fn(&self) -> ffi::ssl_cert_compression_func_t {
16 match &self {
17 Self::Brotli => Some(brotli_compressor),
18 Self::Zlib => Some(zlib_compressor),
19 }
20 }
21
22 pub fn decompression_fn(&self) -> ffi::ssl_cert_decompression_func_t {
23 match &self {
24 Self::Brotli => Some(brotli_decompressor),
25 Self::Zlib => Some(zlib_decompressor),
26 }
27 }
28}
29
30unsafe extern "C" fn brotli_compressor(
31 _ssl: *mut ffi::SSL,
32 out: *mut ffi::CBB,
33 in_: *const u8,
34 in_len: usize,
35) -> c_int {
36 let mut uncompressed = slice::from_raw_parts(in_, in_len);
37 let mut compressed: Vec<u8> = Vec::new();
38
39 let params = BrotliEncoderInitParams();
40
41 if let Err(_) = brotli::BrotliCompress(&mut uncompressed, &mut compressed, ¶ms) {
42 return 0;
43 }
44
45 ffi::CBB_add_bytes(out, compressed.as_ptr(), compressed.len())
46}
47
48unsafe extern "C" fn zlib_compressor(
49 _ssl: *mut ffi::SSL,
50 out: *mut ffi::CBB,
51 in_: *const u8,
52 in_len: usize,
53) -> c_int {
54 let mut uncompressed = slice::from_raw_parts(in_, in_len);
55 let mut compressed: Vec<u8> = Vec::new();
56
57 let params = flate2::Compression::default();
58
59 let mut encoder = flate2::bufread::ZlibEncoder::new(&mut uncompressed, params);
60 if let Err(_) = encoder.read_to_end(&mut compressed) {
61 return 0;
62 }
63
64 ffi::CBB_add_bytes(out, compressed.as_ptr(), compressed.len())
65}
66
67unsafe extern "C" fn brotli_decompressor(
68 _ssl: *mut ffi::SSL,
69 out: *mut *mut ffi::CRYPTO_BUFFER,
70 uncompressed_len: usize,
71 in_: *const u8,
72 in_len: usize,
73) -> c_int {
74 let mut compressed = slice::from_raw_parts(in_, in_len);
75 let mut uncompressed: Vec<u8> = Vec::with_capacity(uncompressed_len);
76
77 if let Err(_) = brotli::BrotliDecompress(&mut compressed, &mut uncompressed) {
78 return 0;
79 }
80
81 if uncompressed.len() != uncompressed_len {
82 return 0;
83 }
84
85 let buffer = ffi::CRYPTO_BUFFER_new(
86 uncompressed.as_ptr(),
87 uncompressed_len,
88 std::ptr::null_mut(),
89 );
90
91 *out = buffer;
92
93 return 1;
94}
95
96unsafe extern "C" fn zlib_decompressor(
97 _ssl: *mut ffi::SSL,
98 out: *mut *mut ffi::CRYPTO_BUFFER,
99 uncompressed_len: usize,
100 in_: *const u8,
101 in_len: usize,
102) -> c_int {
103 let mut compressed = slice::from_raw_parts(in_, in_len);
104 let mut uncompressed: Vec<u8> = Vec::with_capacity(uncompressed_len);
105
106 let mut decoder = flate2::bufread::ZlibDecoder::new(&mut compressed);
107 if let Err(_) = decoder.read_to_end(&mut uncompressed) {
108 return 0;
109 }
110
111 if uncompressed.len() != uncompressed_len {
112 return 0;
113 }
114
115 let buffer = ffi::CRYPTO_BUFFER_new(
116 uncompressed.as_ptr(),
117 uncompressed_len,
118 std::ptr::null_mut(),
119 );
120
121 *out = buffer;
122
123 return 1;
124}