bertie/
server.rs

1//! # TLS 1.3 Server
2//!
3//! This module implements a simple TLS 1.3 server database to handle the server
4//! * name
5//! * certificate
6//! * private signature key
7//! * optional PSKs
8
9use crate::{
10    tls13crypto::{Algorithms, Psk, SignatureKey},
11    tls13utils::{check_eq, eq, parse_failed, Bytes, TLSError, PSK_MODE_MISMATCH},
12};
13
14/// The Server Database
15#[derive(Debug, Clone, Default)]
16pub struct ServerDB {
17    pub(crate) server_name: Bytes,
18    pub(crate) cert: Bytes,
19    pub(crate) sk: SignatureKey,
20    pub(crate) psk_opt: Option<(Bytes, Psk)>,
21}
22
23impl ServerDB {
24    /// Create a new server database.
25    ///
26    /// Note that this only holds one value at a time right now. #51
27    pub fn new(
28        server_name: Bytes,
29        cert: Bytes,
30        sk: SignatureKey,
31        psk_opt: Option<(Bytes, Psk)>,
32    ) -> Self {
33        Self {
34            server_name,
35            cert,
36            sk,
37            psk_opt,
38        }
39    }
40}
41
42/// Global server information.
43pub(crate) struct ServerInfo {
44    pub(crate) cert: Bytes,
45    pub(crate) sk: SignatureKey,
46    pub(crate) psk_opt: Option<Psk>,
47}
48
49/// Look up a server for the given `ciphersuite`.
50///
51/// The function returns a server with the first algorithm it finds.
52pub(crate) fn lookup_db(
53    ciphersuite: Algorithms,
54    db: &ServerDB,
55    sni: &Bytes,
56    tkt: &Option<Bytes>,
57) -> Result<ServerInfo, TLSError> {
58    if eq(sni, &Bytes::new()) || eq(sni, &db.server_name) {
59        match (ciphersuite.psk_mode(), tkt, &db.psk_opt) {
60            (true, Some(ctkt), Some((stkt, psk))) => {
61                check_eq(ctkt, stkt)?;
62                let server = ServerInfo {
63                    cert: db.cert.clone(),
64                    sk: db.sk.clone(),
65                    psk_opt: Some(psk.clone()),
66                };
67                Ok(server)
68            }
69            (false, _, _) => {
70                let server = ServerInfo {
71                    cert: db.cert.clone(),
72                    sk: db.sk.clone(),
73                    psk_opt: None,
74                };
75                Ok(server)
76            }
77            _ => Err(PSK_MODE_MISMATCH),
78        }
79    } else {
80        Err(parse_failed())
81    }
82}