diff --git a/Cargo.lock b/Cargo.lock index 378b04e..244e4e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,7 +7,6 @@ name = "bearssl" version = "0.0.2-pre.0" dependencies = [ "bearssl-sys", - "libc", "rand_core", "zeroize", ] @@ -23,9 +22,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.61.0" +version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a022e58a142a46fea340d68012b9201c094e93ec3d033a944a24f8fd4a4f09a" +checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885" dependencies = [ "bitflags", "cexpr", @@ -51,9 +50,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "cc" -version = "1.0.74" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581f5dba903aac52ea3feb5ec4810848460ee833876f1f9b0fdeab1f19091574" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" [[package]] name = "cexpr" @@ -118,15 +117,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.137" +version = "0.2.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" [[package]] name = "libloading" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ "cfg-if", "winapi", @@ -204,18 +203,18 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "rustc-hash" @@ -231,9 +230,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "syn" -version = "1.0.103" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" dependencies = [ "proc-macro2", "quote", diff --git a/bearssl-sys/Cargo.toml b/bearssl-sys/Cargo.toml index 31b9be1..b32fefc 100644 --- a/bearssl-sys/Cargo.toml +++ b/bearssl-sys/Cargo.toml @@ -15,11 +15,11 @@ rust-version = "1.65" maintenance = { status = "actively-developed" } [dependencies] -libc = { version = "0.2.137", optional = true } +libc = { version = "0.2.138", optional = true } [build-dependencies] -bindgen = "0.61.0" -cc = { version = "1.0.73", optional = true } +bindgen = "0.63.0" +cc = { version = "1.0.77", optional = true } [features] bundled = ["dep:cc"] diff --git a/bearssl/Cargo.toml b/bearssl/Cargo.toml index f107d61..850303f 100644 --- a/bearssl/Cargo.toml +++ b/bearssl/Cargo.toml @@ -15,7 +15,6 @@ maintenance = { status = "actively-developed" } [dependencies] bearssl-sys = { path = "../bearssl-sys" } -libc = { version = "0.2.137", optional = true } rand_core = { version = "0.6.3", default-features = false } zeroize = { version = "1.5.7", default-features = false, optional = true } @@ -24,5 +23,4 @@ default = ["zeroize"] std = ["rand_core/std", "zeroize?/std"] bundled = ["bearssl-sys/bundled"] -dont-assume-size_t-equals-uintptr_t = ["dep:libc", "bearssl-sys/dont-assume-size_t-equals-uintptr_t"] zeroize = ["dep:zeroize"] diff --git a/bearssl/src/ec/private.rs b/bearssl/src/ec/private.rs index d7956ed..75bc5ab 100644 --- a/bearssl/src/ec/private.rs +++ b/bearssl/src/ec/private.rs @@ -1,4 +1,3 @@ -use core::ops::Drop; use core::slice; use bearssl_sys::br_ec_private_key; diff --git a/bearssl/src/ec/public.rs b/bearssl/src/ec/public.rs index a1c0a8a..399d763 100644 --- a/bearssl/src/ec/public.rs +++ b/bearssl/src/ec/public.rs @@ -1,4 +1,3 @@ -use core::ops::Drop; use core::slice; use bearssl_sys::br_ec_public_key; diff --git a/bearssl/src/engine/tls.rs b/bearssl/src/engine/tls.rs index 6b8ff00..389bd98 100644 --- a/bearssl/src/engine/tls.rs +++ b/bearssl/src/engine/tls.rs @@ -23,6 +23,8 @@ pub struct TlsEngine { impl TlsEngine { /// Push some plaintext bytes into engine. + /// + /// Returns how many bytes were copied on success. pub fn push_write(&mut self, src: &[u8]) -> Result { let buf = unsafe { let mut l = MaybeUninit::::uninit(); @@ -55,7 +57,7 @@ impl TlsEngine { let buf = unsafe { let mut l = MaybeUninit::::uninit(); - let b = br_ssl_engine_sendrec_buf(&mut self.context, l.as_mut_ptr()); + let b = br_ssl_engine_sendrec_buf(&self.context, l.as_mut_ptr()); if b.is_null() { return Err(Error::Unknown); @@ -83,7 +85,7 @@ impl TlsEngine { let buf = unsafe { let mut l = MaybeUninit::::uninit(); - let b = br_ssl_engine_recvrec_buf(&mut self.context, l.as_mut_ptr()); + let b = br_ssl_engine_recvrec_buf(&self.context, l.as_mut_ptr()); if b.is_null() { return Err(Error::Unknown); @@ -111,7 +113,7 @@ impl TlsEngine { let buf = unsafe { let mut l = MaybeUninit::::uninit(); - let b = br_ssl_engine_recvapp_buf(&mut self.context, l.as_mut_ptr()); + let b = br_ssl_engine_recvapp_buf(&self.context, l.as_mut_ptr()); if b.is_null() { return Err(Error::Unknown); diff --git a/bearssl/src/internal/engine.rs b/bearssl/src/internal/engine.rs new file mode 100644 index 0000000..b28b04f --- /dev/null +++ b/bearssl/src/internal/engine.rs @@ -0,0 +1,3 @@ + + + diff --git a/bearssl/src/lib.rs b/bearssl/src/lib.rs index 831d2de..c380710 100644 --- a/bearssl/src/lib.rs +++ b/bearssl/src/lib.rs @@ -18,5 +18,4 @@ pub mod ec; pub mod engine; pub mod profile; pub mod rsa; -pub mod server; pub mod x509; diff --git a/bearssl/src/rsa/public.rs b/bearssl/src/rsa/public.rs index 99e1f75..bf8784b 100644 --- a/bearssl/src/rsa/public.rs +++ b/bearssl/src/rsa/public.rs @@ -1,4 +1,3 @@ -use core::ops::Drop; use core::slice; use bearssl_sys::br_rsa_public_key; @@ -8,6 +7,8 @@ pub struct PublicKey(pub(crate) br_rsa_public_key); #[cfg(feature = "zeroize")] impl zeroize::Zeroize for PublicKey { + // Safety: Slice constructions should be safe as long as lengths have not been modified + // outside what BearSSL set. fn zeroize(&mut self) { unsafe { let n = slice::from_raw_parts_mut(self.0.n, self.0.nlen); diff --git a/bearssl/src/server.rs b/bearssl/src/server.rs deleted file mode 100644 index a9c80fd..0000000 --- a/bearssl/src/server.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod builder; -mod conn; - -pub use builder::ServerBuilder; -pub use conn::ServerConnection; diff --git a/bearssl/src/server/builder.rs b/bearssl/src/server/builder.rs deleted file mode 100644 index dcc9078..0000000 --- a/bearssl/src/server/builder.rs +++ /dev/null @@ -1,45 +0,0 @@ -use core::marker::PhantomData; -use core::mem::MaybeUninit; - -use bearssl_sys::*; - -use crate::profile::{KeyType, TlsProfile}; -use crate::server::conn::ServerConnection; -use crate::x509::cert::X509Certificate; - -pub enum Error { - PrivateKeyType { expected: KeyType, actual: KeyType }, - UnsupportedProfile, -} - -pub struct ServerBuilder<'a> { - chain: &'a [X509Certificate<'a>], - rsa: Option, -} - -impl<'a> ServerBuilder<'a> { - pub fn build(&self, profile: TlsProfile) -> Result { - match profile { - TlsProfile::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 => {} - _ => return Err(Error::UnsupportedProfile), - } - - let context = unsafe { - let mut ctx = MaybeUninit::::uninit(); - - br_ssl_server_init_mine2c( - ctx.as_mut_ptr(), - self.chain.as_ptr() as *const _, - self.chain.len(), - core::ptr::null(), - ); - - ctx.assume_init_read() - }; - - Ok(ServerConnection { - context, - chain: PhantomData, - }) - } -} diff --git a/bearssl/src/server/conn.rs b/bearssl/src/server/conn.rs deleted file mode 100644 index f65b836..0000000 --- a/bearssl/src/server/conn.rs +++ /dev/null @@ -1,40 +0,0 @@ -use core::marker::PhantomData; -use core::mem::transmute; - -use bearssl_sys::*; - -use crate::engine::tls; -use crate::x509::cert::X509Certificate; - -/// Represents a connected client. -#[repr(transparent)] -pub struct ServerConnection<'a> { - pub(crate) context: br_ssl_server_context, - pub(crate) chain: PhantomData<&'a X509Certificate<'a>>, -} - -impl<'a> ServerConnection<'a> { - pub fn push_write(&mut self, src: &[u8]) -> Result { - let engine: &mut tls::TlsEngine = unsafe { transmute(&mut self.context.eng) }; - - engine.push_write(src) - } - - pub fn pull_write(&mut self, dst: &mut [u8]) -> Result { - let engine: &mut tls::TlsEngine = unsafe { transmute(&mut self.context.eng) }; - - engine.pull_write(dst) - } - - pub fn push_read(&mut self, src: &[u8]) -> Result { - let engine: &mut tls::TlsEngine = unsafe { transmute(&mut self.context.eng) }; - - engine.push_read(src) - } - - pub fn pull_read(&mut self, dst: &mut [u8]) -> Result { - let engine: &mut tls::TlsEngine = unsafe { transmute(&mut self.context.eng) }; - - engine.pull_read(dst) - } -} diff --git a/bearssl/src/x509.rs b/bearssl/src/x509.rs index f903370..62e0c08 100644 --- a/bearssl/src/x509.rs +++ b/bearssl/src/x509.rs @@ -1,3 +1,5 @@ -pub mod cert; -pub mod decoder; -pub mod engine; +mod cert; +mod name; + +pub use cert::Certificate; +pub use name::DistinguishedName; diff --git a/bearssl/src/x509/cert.rs b/bearssl/src/x509/cert.rs index 70e1ead..69bc0ec 100644 --- a/bearssl/src/x509/cert.rs +++ b/bearssl/src/x509/cert.rs @@ -3,20 +3,21 @@ use core::marker::PhantomData; use bearssl_sys::*; #[repr(transparent)] -pub struct X509Certificate<'a> { - pub(crate) inner: br_x509_certificate, - _marker: PhantomData<&'a mut u8>, +pub struct Certificate<'a> { + context: br_x509_certificate, + _marker: PhantomData<&'a u8>, } -impl<'a> X509Certificate<'a> { - pub fn from_unchecked_der(raw: &'a mut [u8]) -> X509Certificate<'a> { - let inner = br_x509_certificate { - data: raw.as_mut_ptr(), - data_len: raw.len(), +impl<'a> Certificate<'a> { + /// Validity of the certificate is not checked. + pub fn from_unchecked_der(slice: &'a mut [u8]) -> Certificate { + let context = br_x509_certificate { + data: slice.as_mut_ptr(), + data_len: slice.len(), }; - X509Certificate { - inner, + Certificate { + context, _marker: PhantomData, } } diff --git a/bearssl/src/x509/decoder.rs b/bearssl/src/x509/decoder.rs deleted file mode 100644 index 8b68a2b..0000000 --- a/bearssl/src/x509/decoder.rs +++ /dev/null @@ -1,94 +0,0 @@ -use core::default::Default; -use core::mem::MaybeUninit; -use core::ptr; - -use bearssl_sys::*; - -#[non_exhaustive] -pub enum Error { - Unknown, - DecodingNotFinished, - - EmptyCertificateChain, - Overflow, -} - -// TODO: Combine similar error types and add meaningful information (expected/actual etc.) -#[repr(i32)] -pub enum RawError { - InvalidValue = BR_ERR_X509_INVALID_VALUE, - TruncatedCertificate = BR_ERR_X509_TRUNCATED, - InnerElementExtendsOuterSize = BR_ERR_X509_INNER_TRUNC, - BadTagClass = BR_ERR_X509_BAD_TAG_CLASS, - BadTagValue = BR_ERR_X509_BAD_TAG_VALUE, - IndefiniteLength = BR_ERR_X509_INDEFINITE_LENGTH, - ExtraneousElement = BR_ERR_X509_EXTRA_ELEMENT, - UnexpectedElement = BR_ERR_X509_UNEXPECTED, - ElementNotConstructed = BR_ERR_X509_NOT_CONSTRUCTED, - ElementNotPrimitive = BR_ERR_X509_NOT_PRIMITIVE, - PartialByte = BR_ERR_X509_PARTIAL_BYTE, - BadBoolean = BR_ERR_X509_BAD_BOOLEAN, - BadDN = BR_ERR_X509_BAD_DN, - BadTime = BR_ERR_X509_BAD_TIME, - UnsupportedUnignorableExtension = BR_ERR_X509_UNSUPPORTED, - LimitExceeded = BR_ERR_X509_LIMIT_EXCEEDED, - WrongKeyType = BR_ERR_X509_WRONG_KEY_TYPE, - BadSignature = BR_ERR_X509_BAD_SIGNATURE, - TimeUnknown = BR_ERR_X509_TIME_UNKNOWN, - CertificateExpired = BR_ERR_X509_EXPIRED, - DNMismatch = BR_ERR_X509_DN_MISMATCH, - BadServerName = BR_ERR_X509_BAD_SERVER_NAME, - UnknownCriticalExtension = BR_ERR_X509_CRITICAL_EXTENSION, - IsNotCA = BR_ERR_X509_NOT_CA, - ForbiddenKeyUsage = BR_ERR_X509_FORBIDDEN_KEY_USAGE, - WeakPublicKey = BR_ERR_X509_WEAK_PUBLIC_KEY, - NotTrusted = BR_ERR_X509_NOT_TRUSTED, -} - -pub struct X509Decoder(br_x509_decoder_context); - -impl X509Decoder { - pub fn new() -> X509Decoder { - let context = unsafe { - let mut ctx = MaybeUninit::::uninit(); - - br_x509_decoder_init(ctx.as_mut_ptr(), None, ptr::null_mut()); - - ctx.assume_init_read() - }; - - X509Decoder(context) - } - - pub fn is_ca(&self) -> bool { - self.0.isCA != 0 - } - - pub fn raw_publickey(&'_ self) -> Result<&'_ br_x509_pkey, Error> { - if self.0.decoded != 0 { - return Err(Error::DecodingNotFinished); - } - - if self.0.err != 0 { - return Err(self.context_error_code()); - } - - Ok(&self.0.pkey) - } - - #[inline] - fn context_error_code(&self) -> Error { - match self.0.err { - BR_ERR_X509_OVERFLOW => Error::Overflow, - BR_ERR_X509_EMPTY_CHAIN => Error::EmptyCertificateChain, - 0 => unreachable!("0 should have been checked beforehand"), - _ => Error::Unknown, - } - } -} - -impl Default for X509Decoder { - fn default() -> Self { - X509Decoder::new() - } -} diff --git a/bearssl/src/x509/engine.rs b/bearssl/src/x509/engine.rs deleted file mode 100644 index 9a89534..0000000 --- a/bearssl/src/x509/engine.rs +++ /dev/null @@ -1 +0,0 @@ -use bearssl_sys::*; diff --git a/bearssl/src/x509/name.rs b/bearssl/src/x509/name.rs new file mode 100644 index 0000000..fb19777 --- /dev/null +++ b/bearssl/src/x509/name.rs @@ -0,0 +1,23 @@ +use core::marker::PhantomData; + +use bearssl_sys::*; + +#[repr(transparent)] +pub struct DistinguishedName<'a> { + context: br_x500_name, + _marker: PhantomData<&'a u8>, +} + +impl<'a> DistinguishedName<'a> { + pub fn from_bytes(slice: &'a mut [u8]) -> DistinguishedName { + let context = br_x500_name { + data: slice.as_mut_ptr(), + len: slice.len(), + }; + + DistinguishedName { + context, + _marker: PhantomData, + } + } +}