Skip to content
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

Merged
merged 10 commits into from
Sep 15, 2023
Merged

Initial support for CMPv2 & CRMF #21

merged 10 commits into from
Sep 15, 2023

Conversation

Taowyoo
Copy link
Contributor

@Taowyoo Taowyoo commented Aug 29, 2023

Changes

  • Add part of implementation of the Certificate Management Protocol (CMP) as described in RFC 4210, see mod cmpv2.
  • Add part of implementation of the Certificate Request Message Format (CRMF) as described in RFC 4211, see mod crmf.
  • Add some type implementation of X.509 Public Key Infrastructure Certificate format as described in RFC 5280, see changes in x509.rs.
    • Add some general type implementation, see changes in types.rs.

Tests

  • Tests added under cmpv2/message.rs for testing PKIMessage.
  • Tests added under x509.rs for testing KeyUsage.

@Taowyoo Taowyoo requested review from Pagten and removed request for Pagten August 29, 2023 00:01
@Taowyoo Taowyoo self-assigned this Aug 29, 2023
@Taowyoo Taowyoo added enhancement New feature or request crmf x509 cmpv2 labels Aug 29, 2023
- Add x509 extension: `SubjectDirectoryAttributes`.
- Add RFC3281 `Role`.
Copy link

@arai-fortanix arai-fortanix left a 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() {

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.

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.

Copy link
Contributor Author

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| {

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.

@Taowyoo Taowyoo changed the title Add some types in cmpv2,crmf and some oids or x509 types Initial support for CMPv2 & CRMF and some new OIDs & x509 types Sep 14, 2023
@Taowyoo Taowyoo changed the title Initial support for CMPv2 & CRMF and some new OIDs & x509 types Initial support for CMPv2 & CRMF Sep 14, 2023
Copy link

@arai-fortanix arai-fortanix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@Taowyoo
Copy link
Contributor Author

Taowyoo commented Sep 15, 2023

bors r=[arai-fortanix]

@bors
Copy link
Contributor

bors bot commented Sep 15, 2023

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.
For more help, visit the forum.

If you want to switch to GitHub's built-in merge queue, visit their help page.

  • continuous-integration/travis-ci/push

@bors bors bot merged commit 0e8f5ed into master Sep 15, 2023
@Taowyoo Taowyoo deleted the yx/add-cmp branch September 15, 2023 21:06
@Taowyoo Taowyoo linked an issue Sep 15, 2023 that may be closed by this pull request
bors bot added a commit that referenced this pull request Sep 18, 2023
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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Complete the implementation of CRMF and CMP
4 participants