File: server.rs

package info (click to toggle)
rust-rustls 0.23.26%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 13,816 kB
  • sloc: sh: 199; python: 181; makefile: 23
file content (89 lines) | stat: -rw-r--r-- 2,418 bytes parent folder | download | duplicates (3)
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
#![no_main]
#[macro_use]
extern crate libfuzzer_sys;
extern crate rustls;

use std::io;
use std::sync::Arc;

use rustls::server::{Accepted, Acceptor};
use rustls::{ServerConfig, ServerConnection};

fuzz_target!(|data: &[u8]| {
    let _ = env_logger::try_init();
    match data.split_first() {
        Some((0x00, rest)) => fuzz_buffered_api(rest),
        Some((0x01, rest)) => fuzz_acceptor_api(rest),
        Some((_, _)) | None => {}
    }
});

fn fuzz_buffered_api(data: &[u8]) {
    let config = Arc::new(
        ServerConfig::builder_with_provider(rustls_fuzzing_provider::provider().into())
            .with_safe_default_protocol_versions()
            .unwrap()
            .with_no_client_auth()
            .with_cert_resolver(rustls_fuzzing_provider::server_cert_resolver()),
    );
    let mut stream = io::Cursor::new(data);
    let mut server = ServerConnection::new(config).unwrap();

    service_connection(&mut stream, &mut server);
}

fn fuzz_acceptor_api(data: &[u8]) {
    let mut server = Acceptor::default();
    let mut stream = io::Cursor::new(data);

    loop {
        let rd = server
            .read_tls(&mut stream)
            .unwrap_or(0);

        match server.accept() {
            Ok(Some(accepted)) => {
                fuzz_accepted(&mut stream, accepted);
                break;
            }
            Err(_) => {
                break;
            }
            Ok(None) => {}
        }
        if rd == 0 {
            break;
        }
    }
}

fn fuzz_accepted(stream: &mut dyn io::Read, accepted: Accepted) {
    let mut maybe_server = accepted.into_connection(Arc::new(
        ServerConfig::builder_with_provider(rustls_fuzzing_provider::provider().into())
            .with_safe_default_protocol_versions()
            .unwrap()
            .with_no_client_auth()
            .with_cert_resolver(rustls_fuzzing_provider::server_cert_resolver()),
    ));

    if let Ok(conn) = &mut maybe_server {
        service_connection(stream, conn);
    }
}

fn service_connection(stream: &mut dyn io::Read, server: &mut ServerConnection) {
    loop {
        let rd = server.read_tls(stream);
        if server.process_new_packets().is_err() {
            break;
        }

        if matches!(rd, Ok(0) | Err(_)) {
            break;
        }

        // gather and discard written data
        let mut wr = vec![];
        server.write_tls(&mut &mut wr).unwrap();
    }
}