-
Notifications
You must be signed in to change notification settings - Fork 1
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
Initial support for CMPv2 & CRMF #21
Conversation
- Add x509 extension: `SubjectDirectoryAttributes`. - Add RFC3281 `Role`.
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.
I have some concerns about whether cert_req_id and the certificate serial number need to be some kind of BigNum. The other feedback is all suggestions.
self.pvno.write(writer.next()); | ||
self.sender.write(writer.next()); | ||
self.recipient.write(writer.next()); | ||
if let Some(message_time) = self.message_time.as_ref() { |
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.
Minor: every one of these fields has essentially the same code for serialization, except they each have their own specific tag. Is there some way to reduce the duplicated code? Can you define something like
struct Asn1SerializableOption<V, T> {
value: Option<V>,
tag T,
}
impl Asn1SerializableOption<V, T> {
fn write(writer) {
if let Some(value) = self.value.as_ref() {
writer.netxt().write_tagged(Tag::context(self.tag.to_int()), |writer| self.value.write(writer))
}
}
}
And then the code for serializing all of the optional fields can just look like
self.message_time.write(writer);
self.protection_alg.write(writer);
self.sender_kid.write(writer);
...
Especially as there seem to be multiple structures with optional fields, something along these lines seems like it has the potential to reduce the amount of very similar code that's being repeated in the serialization functions.
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.
The other minor benefit to an approach like this is that it explicitly ties the tag value to the field in the declaration of the field in the struct like this:
pub struct PkiHeader<'a, A: SignatureAlgorithm = DerSequence<'static>> {
pub pvno: Pvno,
pub sender: GeneralName<'a>,
pub recipient: GeneralName<'a>,
pub message_time: Asn1SerializableOption<GeneralizedTime, TAG_MESSAGE_TIME>,
pub protection_alg: Asn1SerializableOption<A, TAG_MESSAGE_PROTECTION_ALG>,
Without this, it's possible for someone to make a mistake and use the wrong tag constant for a field in either the serializer or the deserializer. With my suggestion, it's still possible for there to be mistakes, but we only have to check one place very carefully. With the tags used in multiple places, there's more likelyhood that a mistake will be made, or that it will slip through code review.
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.
I have a PR for refactoring all these duplicate code using updated derive_sequence
macro:
#22
let pvno = <Pvno as BERDecodable>::decode_ber(reader.next())?; | ||
let sender = <GeneralName as BERDecodable>::decode_ber(reader.next())?; | ||
let recipient = <GeneralName as BERDecodable>::decode_ber(reader.next())?; | ||
let message_time: Option<GeneralizedTime> = reader.read_optional(|reader| { |
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.
Deserialization seems like it could use a similar approach I suggested above for serialization to reduce the amount of similar code needed for each field.
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.
LGTM.
bors r=[arai-fortanix] |
Build succeeded! The publicly hosted instance of bors-ng is deprecated and will go away soon. If you want to self-host your own instance, instructions are here. If you want to switch to GitHub's built-in merge queue, visit their help page.
|
22: Refactor with new/updated derive macros r=[arai-fortanix] a=Taowyoo This PR: - Enhance macro `derive_sequence` to support optional fields. - Add a new macro `derive_sequence_of` as a help to define a asn.1 sequence of same type. - Add a new type `AlgorithmIdentifierOwned` to represent owned type of X.509 `AlgorithmIdentifier` as defined in [RFC 5280 Section 4.1.1.2](https://tools.ietf.org/html/rfc5280#section-4.1.1.2). - Refactor implementation of types in #21 by using new macros. - [x] This PR should be merged **after** #21 Co-authored-by: Yuxiang Cao <[email protected]>
Changes
cmpv2
.crmf
.x509.rs
.types.rs
.Tests
cmpv2/message.rs
for testingPKIMessage
.x509.rs
for testingKeyUsage
.