Skip to content

Commit 11cbd9c

Browse files
committed
ssh-key: enable and fix workspace-level lints
Applies the workspace-level config added in #509 to this crate and fixes any failures.
1 parent cee1d81 commit 11cbd9c

44 files changed

Lines changed: 687 additions & 311 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ssh-key/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ rsa = ["dep:rsa", "alloc", "encoding/bigint", "rand_core"]
8181
sha1 = ["dep:sha1"]
8282
tdes = ["cipher/tdes", "encryption"]
8383

84+
[lints]
85+
workspace = true
86+
8487
[package.metadata.docs.rs]
8588
all-features = true
86-
rustdoc-args = ["--cfg", "docsrs"]

ssh-key/README.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,6 @@ The "Feature" column lists the name of `ssh-key` crate features which can
8484
be enabled to provide full support for the "Keygen", "Sign", and "Verify"
8585
functionality for a particular SSH key algorithm.
8686

87-
## Minimum Supported Rust Version
88-
89-
This crate requires **Rust 1.85** at a minimum.
90-
91-
We may change the MSRV in the future, but it will be accompanied by a minor
92-
version bump.
93-
9487
## License
9588

9689
Licensed under either of:

ssh-key/src/algorithm.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,14 @@ impl Algorithm {
140140
/// - `sk-ssh-ed25519@openssh.com` (FIDO/U2F key)
141141
///
142142
/// Any other algorithms are mapped to the [`Algorithm::Other`] variant.
143+
///
144+
/// # Errors
145+
/// Returns [`Error::Encoding`] in the event the algorithm name is not known.
143146
pub fn new(id: &str) -> Result<Self> {
144147
Ok(id.parse()?)
145148
}
146149

147-
/// Decode algorithm from the given string identifier as used by
148-
/// the OpenSSH certificate format.
150+
/// Decode algorithm from the given string identifier as used by the OpenSSH certificate format.
149151
///
150152
/// OpenSSH certificate algorithms end in `*-cert-v01@openssh.com`.
151153
/// See [PROTOCOL.certkeys] for more information.
@@ -163,6 +165,9 @@ impl Algorithm {
163165
/// Any other algorithms are mapped to the [`Algorithm::Other`] variant.
164166
///
165167
/// [PROTOCOL.certkeys]: https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL.certkeys?annotate=HEAD
168+
///
169+
/// # Errors
170+
/// Returns [`Error::AlgorithmUnknown`] in the event the algorithm is not known.
166171
pub fn new_certificate(id: &str) -> Result<Self> {
167172
match id {
168173
CERT_DSA => Ok(Algorithm::Dsa),
@@ -193,6 +198,7 @@ impl Algorithm {
193198
}
194199

195200
/// Get the string identifier which corresponds to this algorithm.
201+
#[must_use]
196202
pub fn as_str(&self) -> &str {
197203
match self {
198204
Algorithm::Dsa => SSH_DSA,
@@ -222,6 +228,7 @@ impl Algorithm {
222228
///
223229
/// [PROTOCOL.certkeys]: https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL.certkeys?annotate=HEAD
224230
#[cfg(feature = "alloc")]
231+
#[must_use]
225232
pub fn to_certificate_type(&self) -> String {
226233
match self {
227234
Algorithm::Dsa => CERT_DSA,
@@ -246,21 +253,25 @@ impl Algorithm {
246253
}
247254

248255
/// Is the algorithm DSA?
256+
#[must_use]
249257
pub fn is_dsa(self) -> bool {
250258
self == Algorithm::Dsa
251259
}
252260

253261
/// Is the algorithm ECDSA?
262+
#[must_use]
254263
pub fn is_ecdsa(self) -> bool {
255264
matches!(self, Algorithm::Ecdsa { .. })
256265
}
257266

258267
/// Is the algorithm Ed25519?
268+
#[must_use]
259269
pub fn is_ed25519(self) -> bool {
260270
self == Algorithm::Ed25519
261271
}
262272

263273
/// Is the algorithm RSA?
274+
#[must_use]
264275
pub fn is_rsa(self) -> bool {
265276
matches!(self, Algorithm::Rsa { .. })
266277
}
@@ -340,11 +351,15 @@ impl EcdsaCurve {
340351
/// - `nistp256`
341352
/// - `nistp384`
342353
/// - `nistp521`
354+
///
355+
/// # Errors
356+
/// Returns [`Error::Encoding`] in the event the algorithm name is not known.
343357
pub fn new(id: &str) -> Result<Self> {
344358
Ok(id.parse()?)
345359
}
346360

347361
/// Get the string identifier which corresponds to this ECDSA elliptic curve.
362+
#[must_use]
348363
pub fn as_str(self) -> &'static str {
349364
match self {
350365
EcdsaCurve::NistP256 => "nistp256",
@@ -410,11 +425,15 @@ impl HashAlg {
410425
///
411426
/// - `sha256`
412427
/// - `sha512`
428+
///
429+
/// # Errors
430+
/// Returns [`Error::Encoding`] in the event the algorithm name is not known.
413431
pub fn new(id: &str) -> Result<Self> {
414432
Ok(id.parse()?)
415433
}
416434

417435
/// Get the string identifier for this hash algorithm.
436+
#[must_use]
418437
pub fn as_str(self) -> &'static str {
419438
match self {
420439
HashAlg::Sha256 => SHA256,
@@ -423,6 +442,7 @@ impl HashAlg {
423442
}
424443

425444
/// Get the size of a digest produced by this hash function.
445+
#[must_use]
426446
pub const fn digest_size(self) -> usize {
427447
match self {
428448
HashAlg::Sha256 => 32,
@@ -432,6 +452,7 @@ impl HashAlg {
432452

433453
/// Compute a digest of the given message using this hash function.
434454
#[cfg(feature = "alloc")]
455+
#[must_use]
435456
pub fn digest(self, msg: &[u8]) -> Vec<u8> {
436457
match self {
437458
HashAlg::Sha256 => Sha256::digest(msg).to_vec(),
@@ -497,11 +518,16 @@ impl KdfAlg {
497518
///
498519
/// # Supported KDF names
499520
/// - `none`
521+
/// - `bcrypt`
522+
///
523+
/// # Errors
524+
/// Returns [`Error::Encoding`] in the event the algorithm name is not known.
500525
pub fn new(kdfname: &str) -> Result<Self> {
501526
Ok(kdfname.parse()?)
502527
}
503528

504529
/// Get the string identifier which corresponds to this algorithm.
530+
#[must_use]
505531
pub fn as_str(self) -> &'static str {
506532
match self {
507533
Self::None => NONE,
@@ -510,6 +536,7 @@ impl KdfAlg {
510536
}
511537

512538
/// Is the KDF algorithm "none"?
539+
#[must_use]
513540
pub fn is_none(self) -> bool {
514541
self == Self::None
515542
}

ssh-key/src/algorithm/name.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,14 @@ impl AlgorithmName {
4545
}
4646

4747
/// Get the string identifier which corresponds to this algorithm name.
48+
#[must_use]
4849
pub fn as_str(&self) -> &str {
4950
&self.id
5051
}
5152

5253
/// Get the string identifier which corresponds to the OpenSSH certificate format.
54+
#[must_use]
55+
#[allow(clippy::missing_panics_doc, reason = "should not panic")]
5356
pub fn certificate_type(&self) -> String {
5457
let (name, domain) = split_algorithm_id(&self.id).expect("format checked in constructor");
5558
format!("{name}{CERT_STR_SUFFIX}@{domain}")

ssh-key/src/authorized_keys.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
//! Parser for `AuthorizedKeysFile`-formatted data.
22
33
use crate::{Error, PublicKey, Result};
4-
use core::str;
4+
use core::{
5+
fmt::{self, Debug},
6+
str,
7+
};
58

69
#[cfg(feature = "alloc")]
7-
use {
8-
alloc::string::{String, ToString},
9-
core::fmt,
10-
};
10+
use alloc::string::{String, ToString};
1111

1212
#[cfg(feature = "std")]
1313
use {
@@ -44,14 +44,19 @@ pub struct AuthorizedKeys<'a> {
4444

4545
impl<'a> AuthorizedKeys<'a> {
4646
/// Create a new parser for the given input buffer.
47+
#[must_use]
4748
pub fn new(input: &'a str) -> Self {
4849
Self {
4950
lines: input.lines(),
5051
}
5152
}
5253

53-
/// Read an [`AuthorizedKeys`] file from the filesystem, returning an
54-
/// [`Entry`] vector on success.
54+
/// Read an [`AuthorizedKeys`] file from the filesystem, returning an [`Entry`] vector on
55+
/// success.
56+
///
57+
/// # Errors
58+
/// - Returns [`Error::Io`] in event of I/O errors reading the file.
59+
/// - Propagates [`Entry`] parsing errors as [`Error::FormatEncoding`].
5560
#[cfg(feature = "std")]
5661
pub fn read_file(path: impl AsRef<Path>) -> Result<Vec<Entry>> {
5762
// TODO(tarcieri): permissions checks
@@ -81,11 +86,17 @@ impl<'a> AuthorizedKeys<'a> {
8186
}
8287
}
8388

89+
impl Debug for AuthorizedKeys<'_> {
90+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91+
f.debug_struct("AuthorizedKeys").finish_non_exhaustive()
92+
}
93+
}
94+
8495
impl Iterator for AuthorizedKeys<'_> {
8596
type Item = Result<Entry>;
8697

8798
fn next(&mut self) -> Option<Result<Entry>> {
88-
self.next_line_trimmed().map(|line| line.parse())
99+
self.next_line_trimmed().map(str::parse)
89100
}
90101
}
91102

@@ -103,11 +114,13 @@ pub struct Entry {
103114
impl Entry {
104115
/// Get configuration options for this entry.
105116
#[cfg(feature = "alloc")]
117+
#[must_use]
106118
pub fn config_opts(&self) -> &ConfigOpts {
107119
&self.config_opts
108120
}
109121

110122
/// Get public key for this entry.
123+
#[must_use]
111124
pub fn public_key(&self) -> &PublicKey {
112125
&self.public_key
113126
}
@@ -206,23 +219,29 @@ pub struct ConfigOpts(String);
206219
#[cfg(feature = "alloc")]
207220
impl ConfigOpts {
208221
/// Parse an options string.
222+
///
223+
/// # Errors
224+
///
209225
pub fn new(string: impl Into<String>) -> Result<Self> {
210226
let ret = Self(string.into());
211227
ret.iter().validate()?;
212228
Ok(ret)
213229
}
214230

215231
/// Borrow the configuration options as a `str`.
232+
#[must_use]
216233
pub fn as_str(&self) -> &str {
217234
self.0.as_str()
218235
}
219236

220237
/// Are there no configuration options?
238+
#[must_use]
221239
pub fn is_empty(&self) -> bool {
222240
self.0.is_empty()
223241
}
224242

225243
/// Iterate over the comma-delimited configuration options.
244+
#[must_use]
226245
pub fn iter(&self) -> ConfigOptsIter<'_> {
227246
ConfigOptsIter(self.as_str())
228247
}
@@ -259,6 +278,9 @@ impl<'a> ConfigOptsIter<'a> {
259278
/// Create new configuration options iterator.
260279
///
261280
/// Validates that the options are well-formed.
281+
///
282+
/// # Errors
283+
/// Returns [`Error::Encoding`] in the event of encoding errors.
262284
pub fn new(s: &'a str) -> Result<Self> {
263285
let ret = Self(s);
264286
ret.clone().validate()?;

0 commit comments

Comments
 (0)