-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cleanup EVP_PKEY serialization #669
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #669 +/- ##
==========================================
- Coverage 95.80% 92.87% -2.93%
==========================================
Files 61 69 +8
Lines 8143 9539 +1396
Branches 0 9539 +9539
==========================================
+ Hits 7801 8859 +1058
- Misses 342 399 +57
- Partials 0 281 +281 ☔ View full report in Codecov by Sentry. |
d22622c
to
eca53dc
Compare
eca53dc
to
7141306
Compare
10c07e9
to
e52f8ee
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a minor non-blocking comment about placing the encoding functions in the same file/module, but awesome change overall.
pub(crate) fn marshal_rfc5280_public_key(&self) -> Result<Vec<u8>, Unspecified> { | ||
// Data shows that the SubjectPublicKeyInfo is roughly 356% to 375% increase in size compared to the RSA key | ||
// size in bytes for keys ranging from 2048-bit to 4096-bit. So size the initial capacity to be roughly | ||
// 500% as a conservative estimate to avoid needing to reallocate for any key in that range. | ||
let mut cbb = LcCBB::new(self.key_size_bytes() * 5); | ||
if 1 != unsafe { EVP_marshal_public_key(cbb.as_mut_ptr(), *self.as_const()) } { | ||
return Err(Unspecified); | ||
}; | ||
cbb.into_vec() | ||
} | ||
|
||
let out_len = { | ||
let mut cbb = LcCBB::new_fixed(<&mut [u8; PKCS8_DOCUMENT_MAX_LEN]>::try_from( | ||
buffer.as_mut_slice(), | ||
)?); | ||
pub(crate) fn parse_rfc5280_public_key( | ||
bytes: &[u8], | ||
evp_pkey_type: c_int, | ||
) -> Result<Self, KeyRejected> { | ||
let mut cbs = cbs::build_CBS(bytes); | ||
// Also checks the validity of the key | ||
let evp_pkey = LcPtr::new(unsafe { EVP_parse_public_key(&mut cbs) }) | ||
.map_err(|()| KeyRejected::invalid_encoding())?; | ||
evp_pkey | ||
.id() | ||
.eq(&evp_pkey_type) | ||
.then_some(evp_pkey) | ||
.ok_or(KeyRejected::wrong_algorithm()) | ||
} | ||
|
||
match version { | ||
Version::V1 => { | ||
if 1 != unsafe { EVP_marshal_private_key(cbb.as_mut_ptr(), *self.as_const()) } { | ||
return Err(Unspecified); | ||
} | ||
pub(crate) fn marshal_rfc5208_private_key( | ||
&self, | ||
version: Version, | ||
) -> Result<Vec<u8>, Unspecified> { | ||
let key_size_bytes = TryInto::<usize>::try_into(unsafe { EVP_PKEY_bits(*self.as_const()) }) | ||
.expect("fit in usize") | ||
/ 8; | ||
let mut cbb = LcCBB::new(key_size_bytes * 5); | ||
match version { | ||
Version::V1 => { | ||
if 1 != unsafe { EVP_marshal_private_key(cbb.as_mut_ptr(), *self.as_const()) } { | ||
return Err(Unspecified); | ||
} | ||
Version::V2 => { | ||
if 1 != unsafe { | ||
EVP_marshal_private_key_v2(cbb.as_mut_ptr(), *self.as_const()) | ||
} { | ||
return Err(Unspecified); | ||
} | ||
} | ||
Version::V2 => { | ||
if 1 != unsafe { EVP_marshal_private_key_v2(cbb.as_mut_ptr(), *self.as_const()) } { | ||
return Err(Unspecified); | ||
} | ||
} | ||
cbb.finish()? | ||
}; | ||
|
||
buffer.truncate(out_len); | ||
} | ||
cbb.into_vec() | ||
} | ||
|
||
Ok(buffer.into_boxed_slice()) | ||
pub(crate) fn parse_rfc5208_private_key( | ||
bytes: &[u8], | ||
evp_pkey_type: c_int, | ||
) -> Result<Self, KeyRejected> { | ||
let mut cbs = cbs::build_CBS(bytes); | ||
// Also checks the validity of the key | ||
let evp_pkey = LcPtr::new(unsafe { EVP_parse_private_key(&mut cbs) }) | ||
.map_err(|()| KeyRejected::invalid_encoding())?; | ||
evp_pkey | ||
.id() | ||
.eq(&evp_pkey_type) | ||
.then_some(evp_pkey) | ||
.ok_or(KeyRejected::wrong_algorithm()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we consider following the same pattern as mod sec
and mod rfc5915
and move these functions to another mod rfc5208
in encoding.rs
? It seems like they belong in the same realm at first glance, but I do see how this makes things handy for EVP_PKEY
.
Description of changes:
EVP_marshal_private_key
,EVP_parse_private_key
,EVP_marshal_public_key
andEVP_parse_public_key
.EC_GROUP*
toconst
.ec:encoding
module.Call-outs:
N/A
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.