Skip to content

Commit 92da52c

Browse files
committed
feat: support no_std contexts
This update modifies the library to be usable in no_std environments by replacing std with core where applicable and using the 'alloc' crate for dynamic memory allocation.
1 parent 4e1ff5a commit 92da52c

File tree

4 files changed

+36
-18
lines changed

4 files changed

+36
-18
lines changed

Cargo.toml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,21 @@ keywords = ["ssh", "ssh-keys", "keys", "rsa", "openssh"]
1313
license = "MIT OR Apache-2.0"
1414
exclude = [".github", ".gitignore", "examples", "fixtures"]
1515

16+
[features]
17+
default = ["std"]
18+
std = ["base64/std", "byteorder/std", "md-5/std", "sha2/std", "thiserror/std"]
19+
1620
[dependencies]
1721
# Private dependencies.
18-
base64 = "0.21"
19-
byteorder = "1.1"
22+
base64 = { version = "0.21", default-features = false, features = ["alloc"] }
23+
byteorder = { version = "1.1", default-features = false }
2024
# Do not use a range on the crates md-5 or sha2. RustCrypto crate
2125
# versions cannot be mixed and matched. Doing so will cause hard
2226
# to understand build failures. Read about it at
2327
# https://github.com/coreos/openssh-keys/issues/89
24-
md-5 = "0.10"
25-
sha2 = "0.10"
26-
thiserror = "1.0"
28+
md-5 = { version = "0.10", default-features = false }
29+
sha2 = { version = "0.10", default-features = false }
30+
thiserror = { version = "2.0", default-features = false }
2731
# Public dependencies, exposed through library API.
2832
# <none>
2933

src/lib.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,23 @@
2727
//! println!(" * Pubkey #{} -> {}", i + 1, pubkey.to_fingerprint_string());
2828
//! }
2929
//! }
30+
#![cfg_attr(not(any(feature = "std", test)), no_std)]
31+
32+
extern crate alloc;
3033

3134
mod reader;
3235
mod writer;
3336

3437
pub mod errors {
3538
use thiserror::Error;
3639

37-
pub type Result<T> = std::result::Result<T, OpenSSHKeyError>;
40+
use alloc::string::String;
41+
42+
pub type Result<T> = core::result::Result<T, OpenSSHKeyError>;
3843

3944
#[derive(Error, Debug)]
4045
pub enum OpenSSHKeyError {
46+
#[cfg(any(feature = "std", test, doc))]
4147
#[error("I/O error")]
4248
IO {
4349
#[from]
@@ -47,7 +53,7 @@ pub mod errors {
4753
#[error("invalid UTF-8")]
4854
InvalidUtf8 {
4955
#[from]
50-
source: std::str::Utf8Error,
56+
source: core::str::Utf8Error,
5157
},
5258

5359
// keep base64::DecodeError out of the public API
@@ -74,8 +80,12 @@ use sha2::{Digest, Sha256};
7480
use crate::reader::Reader;
7581
use crate::writer::Writer;
7682

77-
use std::fmt;
78-
use std::io::{BufRead, BufReader, Read};
83+
use core::fmt;
84+
85+
use alloc::borrow::ToOwned;
86+
use alloc::format;
87+
use alloc::string::{String, ToString};
88+
use alloc::vec::Vec;
7989

8090
const SSH_RSA: &str = "ssh-rsa";
8191
const SSH_DSA: &str = "ssh-dss";
@@ -185,7 +195,7 @@ impl core::cmp::PartialEq for PublicKey {
185195
}
186196
}
187197

188-
impl std::str::FromStr for PublicKey {
198+
impl core::str::FromStr for PublicKey {
189199
type Err = OpenSSHKeyError;
190200
fn from_str(s: &str) -> Result<Self> {
191201
PublicKey::parse(s)
@@ -398,13 +408,15 @@ impl PublicKey {
398408
/// read_keys takes a reader and parses it as an authorized_keys file. it
399409
/// returns an error if it can't read or parse any of the public keys in the
400410
/// list.
411+
#[cfg(any(feature = "std", test, doc))]
401412
pub fn read_keys<R>(r: R) -> Result<Vec<Self>>
402413
where
403-
R: Read,
414+
R: std::io::Read,
404415
{
416+
use std::io::{BufRead, BufReader};
405417
let keybuf = BufReader::new(r);
406418
// authorized_keys files are newline-separated lists of public keys
407-
let mut keys = vec![];
419+
let mut keys = Vec::new();
408420
for key in keybuf.lines() {
409421
let key = key?;
410422
// skip any empty lines and any comment lines (prefixed with '#')

src/reader.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ impl<'a> Reader<'a> {
2323
}
2424

2525
pub fn read_string(&mut self) -> Result<&'a str> {
26-
Ok(std::str::from_utf8(self.read_bytes()?)?)
26+
Ok(core::str::from_utf8(self.read_bytes()?)?)
2727
}
2828

2929
pub fn read_mpint(&mut self) -> Result<&'a [u8]> {

src/writer.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
//! This module provides a struct for writing bytes in the OpenSSH public key format.
22
3-
use byteorder::{BigEndian, WriteBytesExt};
3+
use byteorder::{BigEndian, ByteOrder};
4+
5+
use alloc::vec::Vec;
46

57
pub struct Writer {
68
data: Vec<u8>,
79
}
810

911
impl Writer {
1012
pub fn new() -> Writer {
11-
Writer { data: vec![] }
13+
Writer { data: Vec::new() }
1214
}
1315

1416
pub fn into_vec(self) -> Vec<u8> {
1517
self.data
1618
}
1719

1820
pub fn write_int(&mut self, val: u32) {
19-
if self.data.write_u32::<BigEndian>(val).is_err() {
20-
unreachable!()
21-
};
21+
let mut buf = [0; 4];
22+
BigEndian::write_u32(&mut buf, val);
23+
self.data.extend_from_slice(&buf);
2224
}
2325

2426
pub fn write_bytes(&mut self, mut buf: Vec<u8>) {

0 commit comments

Comments
 (0)