Skip to content

Commit 134cf8f

Browse files
committed
pkcs1: params: provide functions to construct RsaPss and RsaOaepParams
Implement RsaPssParams::new() and RsaOaepParams::new(), two functions to generate correct parameters for the provided Digest and data. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
1 parent 9eb0004 commit 134cf8f

2 files changed

Lines changed: 121 additions & 20 deletions

File tree

pkcs1/src/params.rs

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
//! PKCS#1 RSA parameters.
22
33
use crate::{Error, Result};
4-
use der::asn1::{AnyRef, ObjectIdentifier};
54
use der::{
6-
asn1::ContextSpecificRef, Decode, DecodeValue, Encode, EncodeValue, FixedTag, Length, Reader,
7-
Sequence, Tag, TagMode, TagNumber, Writer,
5+
asn1::{AnyRef, ContextSpecificRef, ObjectIdentifier},
6+
oid::AssociatedOid,
7+
Decode, DecodeValue, Encode, EncodeValue, FixedTag, Length, Reader, Sequence, Tag, TagMode,
8+
TagNumber, Writer,
89
};
910
use spki::{AlgorithmIdentifier, AlgorithmIdentifierRef};
1011

@@ -92,6 +93,28 @@ impl<'a> RsaPssParams<'a> {
9293
/// Default RSA PSS Salt length in RsaPssParams
9394
pub const SALT_LEN_DEFAULT: u8 = 20;
9495

96+
/// Create new RsaPssParams for the provided digest and salt len
97+
pub fn new<D>(salt_len: u8) -> Self
98+
where
99+
D: AssociatedOid,
100+
{
101+
Self {
102+
hash: AlgorithmIdentifierRef {
103+
oid: D::OID,
104+
parameters: Some(AnyRef::NULL),
105+
},
106+
mask_gen: AlgorithmIdentifier {
107+
oid: OID_MGF_1,
108+
parameters: Some(AlgorithmIdentifierRef {
109+
oid: D::OID,
110+
parameters: Some(AnyRef::NULL),
111+
}),
112+
},
113+
salt_len,
114+
trailer_field: Default::default(),
115+
}
116+
}
117+
95118
fn context_specific_hash(&self) -> Option<ContextSpecificRef<'_, AlgorithmIdentifierRef<'a>>> {
96119
if self.hash == SHA_1_AI {
97120
None
@@ -238,6 +261,35 @@ pub struct RsaOaepParams<'a> {
238261
}
239262

240263
impl<'a> RsaOaepParams<'a> {
264+
/// Create new RsaPssParams for the provided digest and default (empty) label
265+
pub fn new<D>() -> Self
266+
where
267+
D: AssociatedOid,
268+
{
269+
Self::new_with_label::<D>(&[])
270+
}
271+
272+
/// Create new RsaPssParams for the provided digest and specified label
273+
pub fn new_with_label<D>(label: &'a dyn AsRef<[u8]>) -> Self
274+
where
275+
D: AssociatedOid,
276+
{
277+
Self {
278+
hash: AlgorithmIdentifierRef {
279+
oid: D::OID,
280+
parameters: Some(AnyRef::NULL),
281+
},
282+
mask_gen: AlgorithmIdentifier {
283+
oid: OID_MGF_1,
284+
parameters: Some(AlgorithmIdentifierRef {
285+
oid: D::OID,
286+
parameters: Some(AnyRef::NULL),
287+
}),
288+
},
289+
p_source: pspecicied_algorithm_identifier(label),
290+
}
291+
}
292+
241293
fn context_specific_hash(&self) -> Option<ContextSpecificRef<'_, AlgorithmIdentifierRef<'a>>> {
242294
if self.hash == SHA_1_AI {
243295
None
@@ -332,12 +384,16 @@ impl<'a> TryFrom<&'a [u8]> for RsaOaepParams<'a> {
332384
}
333385
}
334386

335-
/// Default Source Algorithm, empty string
336-
fn default_pempty_string<'a>() -> AlgorithmIdentifierRef<'a> {
387+
fn pspecicied_algorithm_identifier(label: &dyn AsRef<[u8]>) -> AlgorithmIdentifierRef<'_> {
337388
AlgorithmIdentifierRef {
338389
oid: OID_PSPECIFIED,
339390
parameters: Some(
340-
AnyRef::new(Tag::OctetString, &[]).expect("error creating default OAEP params"),
391+
AnyRef::new(Tag::OctetString, label.as_ref()).expect("error creating OAEP params"),
341392
),
342393
}
343394
}
395+
396+
/// Default Source Algorithm, empty string
397+
fn default_pempty_string<'a>() -> AlgorithmIdentifierRef<'a> {
398+
pspecicied_algorithm_identifier(&[])
399+
}

pkcs1/tests/params.rs

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
33
use const_oid::db;
44
use der::{
5-
asn1::{AnyRef, OctetStringRef},
5+
asn1::{AnyRef, ObjectIdentifier, OctetStringRef},
6+
oid::AssociatedOid,
67
Encode,
78
};
89
use hex_literal::hex;
@@ -11,12 +12,22 @@ use pkcs1::{RsaOaepParams, RsaPssParams, TrailerField};
1112
/// Default PSS parameters using all default values (SHA1, MGF1)
1213
const RSA_PSS_PARAMETERS_DEFAULTS: &[u8] = &hex!("3000");
1314
/// Example PSS parameters using SHA256 instead of SHA1
14-
const RSA_PSS_PARAMETERS_SHA2_256: &[u8] = &hex!("3030a00d300b0609608648016503040201a11a301806092a864886f70d010108300b0609608648016503040201a203020120");
15+
const RSA_PSS_PARAMETERS_SHA2_256: &[u8] = &hex!("3034a00f300d06096086480165030402010500a11c301a06092a864886f70d010108300d06096086480165030402010500a203020120");
1516

1617
/// Default OAEP parameters using all default values (SHA1, MGF1, Empty)
1718
const RSA_OAEP_PARAMETERS_DEFAULTS: &[u8] = &hex!("3000");
18-
/// Example OAEP parameters using SHA256 instead of SHA1 and 'abc' as label
19-
const RSA_OAEP_PARAMETERS_SHA2_256: &[u8] = &hex!("303fa00d300b0609608648016503040201a11a301806092a864886f70d010108300b0609608648016503040201a212301006092a864886f70d0101090403abcdef");
19+
/// Example OAEP parameters using SHA256 instead of SHA1
20+
const RSA_OAEP_PARAMETERS_SHA2_256: &[u8] = &hex!("302fa00f300d06096086480165030402010500a11c301a06092a864886f70d010108300d06096086480165030402010500");
21+
22+
struct Sha1Mock {}
23+
impl AssociatedOid for Sha1Mock {
24+
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.14.3.2.26");
25+
}
26+
27+
struct Sha256Mock {}
28+
impl AssociatedOid for Sha256Mock {
29+
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.1");
30+
}
2031

2132
#[test]
2233
fn decode_pss_param() {
@@ -26,7 +37,7 @@ fn decode_pss_param() {
2637
.hash
2738
.assert_algorithm_oid(db::rfc5912::ID_SHA_256)
2839
.is_ok());
29-
assert_eq!(param.hash.parameters, None);
40+
assert_eq!(param.hash.parameters, Some(AnyRef::NULL));
3041
assert!(param
3142
.mask_gen
3243
.assert_algorithm_oid(db::rfc5912::ID_MGF_1)
@@ -88,6 +99,23 @@ fn encode_pss_param_default() {
8899
);
89100
}
90101

102+
#[test]
103+
fn new_pss_param() {
104+
let mut buf = [0_u8; 256];
105+
106+
let param = RsaPssParams::new::<Sha1Mock>(20);
107+
assert_eq!(
108+
param.encode_to_slice(&mut buf).unwrap(),
109+
RSA_PSS_PARAMETERS_DEFAULTS
110+
);
111+
112+
let param = RsaPssParams::new::<Sha256Mock>(32);
113+
assert_eq!(
114+
param.encode_to_slice(&mut buf).unwrap(),
115+
RSA_PSS_PARAMETERS_SHA2_256
116+
);
117+
}
118+
91119
#[test]
92120
fn decode_oaep_param() {
93121
let param = RsaOaepParams::try_from(RSA_OAEP_PARAMETERS_SHA2_256).unwrap();
@@ -96,7 +124,7 @@ fn decode_oaep_param() {
96124
.hash
97125
.assert_algorithm_oid(db::rfc5912::ID_SHA_256)
98126
.is_ok());
99-
assert_eq!(param.hash.parameters, None);
127+
assert_eq!(param.hash.parameters, Some(AnyRef::NULL));
100128
assert!(param
101129
.mask_gen
102130
.assert_algorithm_oid(db::rfc5912::ID_MGF_1)
@@ -111,14 +139,13 @@ fn decode_oaep_param() {
111139
.p_source
112140
.assert_algorithm_oid(db::rfc5912::ID_P_SPECIFIED)
113141
.is_ok());
114-
assert_eq!(
115-
param
116-
.p_source
117-
.parameters_any()
118-
.unwrap()
119-
.decode_as::<OctetStringRef<'_>>(),
120-
OctetStringRef::new(&[0xab, 0xcd, 0xef])
121-
);
142+
assert!(param
143+
.p_source
144+
.parameters_any()
145+
.unwrap()
146+
.decode_as::<OctetStringRef<'_>>()
147+
.unwrap()
148+
.is_empty(),);
122149
}
123150

124151
#[test]
@@ -176,3 +203,21 @@ fn encode_oaep_param_default() {
176203
RSA_OAEP_PARAMETERS_DEFAULTS
177204
);
178205
}
206+
207+
#[test]
208+
fn new_oaep_param() {
209+
let mut buf = [0_u8; 256];
210+
211+
let param = RsaOaepParams::new::<Sha1Mock>();
212+
assert_eq!(
213+
param.encode_to_slice(&mut buf).unwrap(),
214+
RSA_OAEP_PARAMETERS_DEFAULTS
215+
);
216+
217+
let param = RsaOaepParams::new::<Sha256Mock>();
218+
println!("{:02x?}", param.encode_to_slice(&mut buf).unwrap());
219+
assert_eq!(
220+
param.encode_to_slice(&mut buf).unwrap(),
221+
RSA_OAEP_PARAMETERS_SHA2_256
222+
);
223+
}

0 commit comments

Comments
 (0)