sasl: Make this crate no_std

Emmanuel Gil Peyrot created

We mostly had to import from alloc some structs that are part of the std
prelude, such as Vec and String.

Change summary

sasl/CHANGELOG.md                       |  4 ++++
sasl/README.md                          |  2 ++
sasl/src/client/mechanisms/plain.rs     |  2 ++
sasl/src/client/mechanisms/scram.rs     | 23 ++++++++++++++---------
sasl/src/client/mod.rs                  |  5 +++--
sasl/src/common/mod.rs                  |  6 ++++--
sasl/src/common/scram.rs                | 10 +++++++---
sasl/src/error.rs                       |  1 +
sasl/src/lib.rs                         |  5 +++++
sasl/src/secret.rs                      |  3 +++
sasl/src/server/mechanisms/anonymous.rs |  2 ++
sasl/src/server/mechanisms/plain.rs     |  2 ++
sasl/src/server/mechanisms/scram.rs     |  6 +++++-
sasl/src/server/mod.rs                  |  5 +++--
14 files changed, 57 insertions(+), 19 deletions(-)

Detailed changes

sasl/CHANGELOG.md ๐Ÿ”—

@@ -1,3 +1,7 @@
+Version NEXT, released 20??-??-??:
+	* Improvements
+		- This crate is now `no_std`, you can use it even on platforms which donโ€™t provide the `std` crate.
+
 Version 0.5.2, released 2024-07-22:
 	* Improvements
 		- Add SCRAM client extensions support (thanks to Lucas Kent)

sasl/README.md ๐Ÿ”—

@@ -6,6 +6,8 @@ What's this?
 
 A crate which handles SASL authentication. Still unstable until 1.0.0.
 
+It can be used in `no_std` environments.
+
 Can I see an example?
 ---------------------
 

sasl/src/client/mechanisms/plain.rs ๐Ÿ”—

@@ -2,6 +2,8 @@
 
 use crate::client::{Mechanism, MechanismError};
 use crate::common::{Credentials, Identity, Password, Secret};
+use alloc::string::String;
+use alloc::vec::Vec;
 
 /// A struct for the SASL PLAIN mechanism.
 pub struct Plain {

sasl/src/client/mechanisms/scram.rs ๐Ÿ”—

@@ -8,7 +8,10 @@ use crate::common::{parse_frame, xor, ChannelBinding, Credentials, Identity, Pas
 
 use crate::error::Error;
 
-use std::marker::PhantomData;
+use alloc::format;
+use alloc::string::String;
+use alloc::vec::Vec;
+use core::marker::PhantomData;
 
 enum ScramState {
     Init,
@@ -226,6 +229,8 @@ mod tests {
     use crate::client::mechanisms::Scram;
     use crate::client::Mechanism;
     use crate::common::scram::{Sha1, Sha256};
+    use alloc::borrow::ToOwned;
+    use alloc::string::String;
 
     #[test]
     fn scram_sha1_works() {
@@ -293,13 +298,13 @@ mod tests {
                 .with_first_extensions("tokenauth=true".to_owned());
         let init = mechanism.initial();
         assert_eq!(
-            std::str::from_utf8(&init).unwrap(),
-            std::str::from_utf8(client_init).unwrap()
+            core::str::from_utf8(&init).unwrap(),
+            core::str::from_utf8(client_init).unwrap()
         ); // depends on orderingโ€ฆ
         let resp = mechanism.response(server_init).unwrap();
         assert_eq!(
-            std::str::from_utf8(&resp).unwrap(),
-            std::str::from_utf8(client_final).unwrap()
+            core::str::from_utf8(&resp).unwrap(),
+            core::str::from_utf8(client_final).unwrap()
         ); // again, depends on orderingโ€ฆ
         mechanism.success(server_final).unwrap();
     }
@@ -318,13 +323,13 @@ mod tests {
                 .with_final_extensions("foo=true".to_owned());
         let init = mechanism.initial();
         assert_eq!(
-            std::str::from_utf8(&init).unwrap(),
-            std::str::from_utf8(client_init).unwrap()
+            core::str::from_utf8(&init).unwrap(),
+            core::str::from_utf8(client_init).unwrap()
         ); // depends on orderingโ€ฆ
         let resp = mechanism.response(server_init).unwrap();
         assert_eq!(
-            std::str::from_utf8(&resp).unwrap(),
-            std::str::from_utf8(client_final).unwrap()
+            core::str::from_utf8(&resp).unwrap(),
+            core::str::from_utf8(client_final).unwrap()
         ); // again, depends on orderingโ€ฆ
     }
 }

sasl/src/client/mod.rs ๐Ÿ”—

@@ -1,4 +1,5 @@
-use std::fmt;
+use alloc::vec::Vec;
+use core::fmt;
 
 use crate::common::Credentials;
 
@@ -84,7 +85,7 @@ impl fmt::Display for MechanismError {
     }
 }
 
-impl std::error::Error for MechanismError {}
+impl core::error::Error for MechanismError {}
 
 /// A trait which defines SASL mechanisms.
 pub trait Mechanism {

sasl/src/common/mod.rs ๐Ÿ”—

@@ -1,5 +1,7 @@
-use std::collections::BTreeMap;
-use std::string::FromUtf8Error;
+use alloc::borrow::ToOwned;
+use alloc::collections::BTreeMap;
+use alloc::string::{FromUtf8Error, String};
+use alloc::vec::Vec;
 
 #[cfg(feature = "scram")]
 pub mod scram;

sasl/src/common/scram.rs ๐Ÿ”—

@@ -1,3 +1,7 @@
+use alloc::string::{String, ToString};
+use alloc::vec;
+use alloc::vec::Vec;
+use core::fmt;
 use getrandom::{getrandom, Error as RngError};
 use hmac::{digest::InvalidLength, Hmac, Mac};
 use pbkdf2::pbkdf2;
@@ -25,8 +29,8 @@ pub enum DeriveError {
     IncompatibleIterationCount(u32, u32),
 }
 
-impl std::fmt::Display for DeriveError {
-    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
+impl fmt::Display for DeriveError {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         match self {
             DeriveError::IncompatibleHashingMethod(one, two) => {
                 write!(fmt, "incompatible hashing method, {} is not {}", one, two)
@@ -40,7 +44,7 @@ impl std::fmt::Display for DeriveError {
     }
 }
 
-impl std::error::Error for DeriveError {}
+impl core::error::Error for DeriveError {}
 
 impl From<hmac::digest::InvalidLength> for DeriveError {
     fn from(_err: hmac::digest::InvalidLength) -> DeriveError {

sasl/src/error.rs ๐Ÿ”—

@@ -1,3 +1,4 @@
+use alloc::string::String;
 #[cfg(feature = "scram")]
 use getrandom::Error as RngError;
 

sasl/src/lib.rs ๐Ÿ”—

@@ -1,8 +1,11 @@
 //#![deny(missing_docs)]
+#![no_std]
 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
 
 //! This crate provides a framework for SASL authentication and a few authentication mechanisms.
 //!
+//! It can be used in `no_std` environments.
+//!
 //! # Examples
 //!
 //! ## Simple client-sided usage
@@ -184,6 +187,8 @@
 //! sasl = "*"
 //! ```
 
+extern crate alloc;
+
 mod error;
 
 pub mod client;

sasl/src/secret.rs ๐Ÿ”—

@@ -1,5 +1,8 @@
 #[cfg(feature = "scram")]
 use crate::common::scram::DeriveError;
+use alloc::borrow::ToOwned;
+use alloc::string::String;
+use alloc::vec::Vec;
 
 pub trait Secret {}
 

sasl/src/server/mechanisms/plain.rs ๐Ÿ”—

@@ -1,6 +1,8 @@
 use crate::common::Identity;
 use crate::secret;
 use crate::server::{Mechanism, MechanismError, Response, Validator};
+use alloc::string::String;
+use alloc::vec::Vec;
 
 pub struct Plain<V: Validator<secret::Plain>> {
     validator: V,

sasl/src/server/mechanisms/scram.rs ๐Ÿ”—

@@ -1,4 +1,8 @@
-use std::marker::PhantomData;
+use alloc::borrow::ToOwned;
+use alloc::format;
+use alloc::string::{String, ToString};
+use alloc::vec::Vec;
+use core::marker::PhantomData;
 
 use base64::{engine::general_purpose::STANDARD as Base64, Engine};
 

sasl/src/server/mod.rs ๐Ÿ”—

@@ -1,6 +1,8 @@
 use crate::common::Identity;
 use crate::secret::Secret;
-use std::fmt;
+use alloc::vec::Vec;
+use core::error::Error;
+use core::fmt;
 
 #[cfg(feature = "scram")]
 use crate::common::scram::DeriveError;
@@ -171,7 +173,6 @@ impl Error for ProviderError {}
 
 impl Error for ValidatorError {}
 
-use std::error::Error;
 impl Error for MechanismError {
     fn source(&self) -> Option<&(dyn Error + 'static)> {
         match self {