Skip to content

Commit 3bec131

Browse files
authored
dsa: enable and fix workspace-level lints (#1406)
1 parent d8d07e8 commit 3bec131

15 files changed

Lines changed: 115 additions & 25 deletions

dsa/Cargo.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@ default = ["pkcs8"]
4545
getrandom = ["crypto-common/getrandom"]
4646
hazmat = []
4747

48-
[package.metadata.docs.rs]
49-
all-features = true
50-
5148
[[example]]
5249
name = "sign"
5350
required-features = ["hazmat", "pkcs8"]
@@ -59,3 +56,9 @@ required-features = ["hazmat"]
5956
[[example]]
6057
name = "export"
6158
required-features = ["hazmat", "pkcs8"]
59+
60+
[lints]
61+
workspace = true
62+
63+
[package.metadata.docs.rs]
64+
all-features = true

dsa/examples/export.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
//! Example for serializing keys in SPKI/PKCS#8 format.
2+
13
#![cfg(feature = "hazmat")]
4+
#![allow(clippy::unwrap_used, reason = "tests")]
25

36
use dsa::{Components, KeySize, SigningKey};
47
use getrandom::SysRng;

dsa/examples/generate.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Key generation example.
2+
13
#![cfg(feature = "hazmat")]
24

35
use dsa::{Components, KeySize, SigningKey};

dsa/examples/sign.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
//! Signing example.
2+
3+
#![allow(clippy::unwrap_used, reason = "tests")]
4+
15
use digest::Digest;
26
use dsa::{Components, KeySize, SigningKey};
37
use getrandom::{SysRng, rand_core::UnwrapErr};

dsa/src/components.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,17 @@ pub struct Components {
3030
}
3131

3232
impl Components {
33-
/// Construct the common components container from its inner values (p, q and g)
33+
/// Construct the common components container from its inner values (`p`, `q`, and `g`).
34+
///
35+
/// - `p` must be odd
36+
/// - `g` must less than `p`
37+
///
38+
/// # Errors
39+
/// Returns [`signature::Error`] if any of the following occur:
40+
/// - components aren't sized appropriately for a 1024-bit, 2048-bit, or 3072-bit key
41+
/// - any of `p`, `q`, or `g` are less than `2`
42+
/// - `p` is even instead of odd
43+
/// - `g > p`
3444
pub fn from_components(p: BoxedUint, q: BoxedUint, g: BoxedUint) -> signature::Result<Self> {
3545
let (p, q, g) = Self::adapt_components(p, q, g)?;
3646

@@ -49,9 +59,14 @@ impl Components {
4959
/// Construct the common components container from its inner values (p, q and g)
5060
///
5161
/// # Safety
52-
///
5362
/// Any length of keys may be used, no checks are to be performed. You are responsible for
5463
/// checking the key strengths.
64+
///
65+
/// # Errors
66+
/// Returns [`signature::Error`] if any of the following occur:
67+
/// - any of `p`, `q`, or `g` are less than `2`
68+
/// - `p` is even instead of odd
69+
/// - `g > p`
5570
#[cfg(feature = "hazmat")]
5671
pub fn from_components_unchecked(
5772
p: BoxedUint,
@@ -60,11 +75,10 @@ impl Components {
6075
) -> signature::Result<Self> {
6176
let (p, q, g) = Self::adapt_components(p, q, g)?;
6277
let key_size = KeySize::other(p.bits_precision(), q.bits_precision());
63-
6478
Ok(Self { p, q, g, key_size })
6579
}
6680

67-
/// Helper method to build a [`Components`]
81+
/// Helper method to build [`Components`].
6882
fn adapt_components(
6983
p: BoxedUint,
7084
q: BoxedUint,
@@ -80,14 +94,18 @@ impl Components {
8094
.into_option()
8195
.ok_or_else(signature::Error::new)?;
8296

83-
if *p < two() || *q < two() || *g > *p {
97+
if *p < two() || *q < two() || *g >= *p {
8498
return Err(signature::Error::new());
8599
}
86100

87101
Ok((p, q, g))
88102
}
89103

90-
/// Generate a new pair of common components
104+
/// Generate a new pair of common components.
105+
///
106+
/// # Errors
107+
/// Propagates errors from `R`.
108+
#[allow(clippy::missing_panics_doc, reason = "shouldn't panic in practice")]
91109
pub fn try_generate_from_rng_with_key_size<R: TryCryptoRng + ?Sized>(
92110
rng: &mut R,
93111
key_size: KeySize,

dsa/src/generate/secret_number.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use alloc::vec;
77
use core::cmp::min;
88
use crypto_bigint::{BoxedUint, NonZero, NonZeroBoxedUint, RandomBits, Resize};
99
use digest::{Digest, common::BlockSizeUser};
10-
use rfc6979::KGenerator;
1110
use signature::rand_core::TryCryptoRng;
1211
use zeroize::Zeroizing;
1312

@@ -44,7 +43,7 @@ fn init_kgen<'a, D: BlockSizeUser + Digest>(
4443
x: &NonZeroBoxedUint,
4544
z: &[u8],
4645
q: &'a NonZeroBoxedUint,
47-
) -> KGenerator<'a, D, BoxedUint> {
46+
) -> rfc6979::KGenerator<'a, D, BoxedUint> {
4847
// Truncate to the right `size` most bytes
4948
fn truncate(b: &[u8], size: usize) -> &[u8] {
5049
&b[(b.len() - size)..]
@@ -66,6 +65,7 @@ fn bytes2uint(b: &[u8], q: &NonZeroBoxedUint) -> BoxedUint {
6665
BoxedUint::from_be_slice_truncated(b, q.bits_precision())
6766
}
6867

68+
#[allow(clippy::as_conversions)]
6969
fn qlen(q: &NonZeroBoxedUint) -> usize {
7070
q.bits().div_ceil(8) as usize
7171
}

dsa/src/key_size.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use core::cmp::Ordering;
22
use crypto_bigint::Limb;
33

44
/// DSA key size
5-
#[derive(Clone, Debug, Copy)]
5+
#[derive(Clone, Copy, Debug)]
66
pub struct KeySize {
77
/// Bit size of p
88
pub(crate) l: u32,
@@ -35,15 +35,15 @@ impl KeySize {
3535
Self { l, n }
3636
}
3737

38-
pub(crate) fn l_aligned(&self) -> u32 {
38+
pub(crate) fn l_aligned(self) -> u32 {
3939
self.l.div_ceil(Limb::BITS) * Limb::BITS
4040
}
4141

42-
pub(crate) fn n_aligned(&self) -> u32 {
42+
pub(crate) fn n_aligned(self) -> u32 {
4343
self.n.div_ceil(Limb::BITS) * Limb::BITS
4444
}
4545

46-
pub(crate) fn matches(&self, l: u32, n: u32) -> bool {
46+
pub(crate) fn matches(self, l: u32, n: u32) -> bool {
4747
l == self.l_aligned() && n == self.n_aligned()
4848
}
4949
}

dsa/src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![no_std]
2-
#![forbid(unsafe_code)]
3-
#![warn(missing_docs, rust_2018_idioms, unreachable_pub)]
2+
#![cfg_attr(docsrs, feature(doc_cfg))]
43
#![doc = include_str!("../README.md")]
54
#![doc(
65
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
@@ -105,6 +104,7 @@ pub struct Signature {
105104

106105
impl Signature {
107106
/// Create a new Signature container from its components
107+
#[must_use]
108108
pub fn from_components(r: BoxedUint, s: BoxedUint) -> Option<Self> {
109109
let r = NonZero::new(r).into_option()?;
110110
let s = NonZero::new(s).into_option()?;
@@ -127,6 +127,11 @@ impl Signature {
127127
impl<'a> DecodeValue<'a> for Signature {
128128
type Error = der::Error;
129129

130+
#[allow(
131+
clippy::as_conversions,
132+
clippy::cast_possible_truncation,
133+
reason = "TODO"
134+
)]
130135
fn decode_value<R: Reader<'a>>(reader: &mut R, _header: der::Header) -> der::Result<Self> {
131136
let r = UintRef::decode(reader)?;
132137
let s = UintRef::decode(reader)?;

dsa/src/signing_key.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,16 @@ pub struct SigningKey {
5050
}
5151

5252
impl SigningKey {
53-
/// Construct a new private key from the public key and private component
53+
/// Construct a new private key from the public key and private component.
54+
///
55+
/// # Errors
56+
/// Returns an error in the event `x` is zero or equal to or larger than `q`.
5457
pub fn from_components(verifying_key: VerifyingKey, x: BoxedUint) -> signature::Result<Self> {
5558
let x = NonZero::new(x)
5659
.into_option()
5760
.ok_or_else(signature::Error::new)?;
5861

59-
if x > *verifying_key.components().q() {
62+
if x >= *verifying_key.components().q() {
6063
return Err(signature::Error::new());
6164
}
6265

@@ -66,7 +69,10 @@ impl SigningKey {
6669
})
6770
}
6871

69-
/// Generate a new DSA keypair
72+
/// Generate a new DSA keypair.
73+
///
74+
/// # Errors
75+
/// Propagates errors from `R`.
7076
#[cfg(feature = "hazmat")]
7177
#[inline]
7278
pub fn try_generate_from_rng_with_components<R: TryCryptoRng + ?Sized>(
@@ -81,9 +87,17 @@ impl SigningKey {
8187
&self.verifying_key
8288
}
8389

84-
/// DSA private component
90+
/// DSA private component.
91+
///
92+
/// <div class="warning">
93+
/// <b>Security Warning</b>
94+
///
95+
/// This value is key material. Please treat it with care!
8596
///
86-
/// If you decide to clone this value, please consider using [`Zeroize::zeroize`](::zeroize::Zeroize::zeroize()) to zero out the memory after you're done using the clone
97+
/// If you decide to clone this value, please consider using
98+
/// [`Zeroize::zeroize`](::zeroize::Zeroize::zeroize) to zero out the memory after you're done
99+
/// using the clone.
100+
/// </div>
87101
#[must_use]
88102
pub fn x(&self) -> &NonZero<BoxedUint> {
89103
&self.x
@@ -94,15 +108,26 @@ impl SigningKey {
94108
///
95109
/// [RFC6979]: https://datatracker.ietf.org/doc/html/rfc6979
96110
#[cfg(feature = "hazmat")]
111+
#[allow(
112+
clippy::missing_errors_doc,
113+
reason = "errors shouldn't occur in practice"
114+
)]
97115
pub fn sign_prehashed_rfc6979<D>(&self, prehash: &[u8]) -> Result<Signature, signature::Error>
98116
where
99117
D: BlockSizeUser + Digest,
100118
{
119+
// TODO(tarcieri): make this operation infallible by retrying with a different `k`
101120
let k_kinv = generate::secret_number_rfc6979::<D>(self, prehash);
102121
self.sign_prehashed(k_kinv, prehash)
103122
}
104123

105-
/// Sign some pre-hashed data
124+
/// Sign some pre-hashed data.
125+
#[allow(
126+
clippy::as_conversions,
127+
clippy::cast_possible_truncation,
128+
clippy::integer_division_remainder_used,
129+
reason = "TODO"
130+
)]
106131
fn sign_prehashed(
107132
&self,
108133
(k, inv_k): (BoxedUint, BoxedUint),
@@ -285,7 +310,11 @@ impl<'a> TryFrom<PrivateKeyInfoRef<'a>> for SigningKey {
285310
.into_option()
286311
.ok_or(pkcs8::KeyError::Invalid)?;
287312

288-
let y = if let Some(y_bytes) = value.public_key.as_ref().and_then(|bs| bs.as_bytes()) {
313+
let y = if let Some(y_bytes) = value
314+
.public_key
315+
.as_ref()
316+
.and_then(der::asn1::BitStringRef::as_bytes)
317+
{
289318
let y = UintRef::from_der(y_bytes)?;
290319
BoxedUint::from_be_slice(y.as_bytes(), precision)
291320
.map_err(|_| pkcs8::KeyError::Invalid)?

dsa/src/verifying_key.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ pub struct VerifyingKey {
3636
}
3737

3838
impl VerifyingKey {
39-
/// Construct a new public key from the common components and the public component
39+
/// Construct a new public key from the common components and the public component.
40+
///
41+
/// # Errors
42+
/// Returns an error if `y < 2`.
4043
pub fn from_components(components: Components, y: BoxedUint) -> signature::Result<Self> {
4144
let params = BoxedMontyParams::new_vartime(components.p().clone());
4245
let form = BoxedMontyForm::new(y.clone(), &params);
@@ -65,6 +68,12 @@ impl VerifyingKey {
6568

6669
/// Verify some prehashed data
6770
#[must_use]
71+
#[allow(
72+
clippy::as_conversions,
73+
clippy::cast_possible_truncation,
74+
clippy::integer_division_remainder_used,
75+
reason = "TODO"
76+
)]
6877
fn verify_prehashed(&self, hash: &[u8], signature: &Signature) -> Option<bool> {
6978
let components = self.components();
7079
let (p, q, g) = (components.p(), components.q(), components.g());

0 commit comments

Comments
 (0)