This repository has been archived on 2025-03-28. You can view files and clone it, but cannot push or open issues or pull requests.
tcp-over-http/src/base/cert_utils.rs

88 lines
2.3 KiB
Rust

use std::error::Error;
use std::io::{Cursor, ErrorKind};
use rustls::{Certificate, PrivateKey};
use rustls_pemfile::{read_one, Item};
/// Parse PEM certificates bytes into a [`rustls::Certificate`] structure
///
/// An error is returned if not any certificate could be found
pub fn parse_pem_certificates(certs: &[u8]) -> Result<Vec<Certificate>, Box<dyn Error>> {
let certs = rustls_pemfile::certs(&mut Cursor::new(certs))?
.into_iter()
.map(Certificate)
.collect::<Vec<_>>();
if certs.is_empty() {
Err(std::io::Error::new(
ErrorKind::InvalidData,
"Could not find any certificate!",
))?;
unreachable!();
}
Ok(certs)
}
/// Parse PEM private key bytes into a [`rustls::PrivateKey`] structure
pub fn parse_pem_private_key(privkey: &[u8]) -> Result<PrivateKey, Box<dyn Error>> {
let key = match read_one(&mut Cursor::new(privkey))? {
None => {
Err(std::io::Error::new(
ErrorKind::Other,
"Failed to extract private key!",
))?;
unreachable!()
}
Some(Item::PKCS8Key(key)) => key,
Some(Item::RSAKey(key)) => key,
_ => {
Err(std::io::Error::new(
ErrorKind::Other,
"Unsupported private key type!",
))?;
unreachable!();
}
};
Ok(PrivateKey(key))
}
#[cfg(test)]
mod test {
use crate::cert_utils::{parse_pem_certificates, parse_pem_private_key};
const SAMPLE_CERT: &[u8] = include_bytes!("../samples/TCPTunnelTest.crt");
const SAMPLE_KEY: &[u8] = include_bytes!("../samples/TCPTunnelTest.key");
#[test]
fn parse_valid_cert() {
parse_pem_certificates(SAMPLE_CERT).unwrap();
}
#[test]
fn parse_invalid_cert_1() {
parse_pem_certificates("Random content".as_bytes()).unwrap_err();
}
#[test]
fn parse_invalid_cert_2() {
parse_pem_certificates(SAMPLE_KEY).unwrap_err();
}
#[test]
fn parse_valid_key() {
parse_pem_private_key(SAMPLE_KEY).unwrap();
}
#[test]
fn parse_invalid_key_1() {
parse_pem_private_key("Random content".as_bytes()).unwrap_err();
}
#[test]
fn parse_invalid_key_2() {
parse_pem_private_key(SAMPLE_CERT).unwrap_err();
}
}