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

ASN1#to_der in pure ruby #777

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

HoneyryderChuck
Copy link
Contributor

@HoneyryderChuck HoneyryderChuck commented Jul 12, 2024

This is a draft request-for-comment proposal for implementing OpenSSL::ASN1::ASN1Data#to_der in ruby, as per suggestion on the previous MR. It already passes the test, although there is a part which hasn't been ported yet, and seems not be covered in the tests. I guess that the ruby code can benefit from being broke down in multiple files, but I'll keep it here just for easy of review, ,for now. I also didn't delete C code, not yet.

Currently, the whole of #to_der is implemented in the ASN1Data class. The reason is, one can build a primitive or constructive object "manually" (if tag and/or tag_class is known), or can just use arrays directly. It would benefit from moving specific implementations into the respective child classes, but then it'd be a breaking change because of what I said. Any suggestions?

I also didn't do any benchmarks yet. Is it relevant?

LMK what you think.

@rhenium
Copy link
Member

rhenium commented Jul 13, 2024

I think the tests outside test_basic_asn1data are still using the C implementation because #to_der is redefined on Primitive and Constructive.

Currently, the whole of #to_der is implemented in the ASN1Data class. The reason is, one can build a primitive or constructive object "manually" (if tag and/or tag_class is known), or can just use arrays directly. It would benefit from moving specific implementations into the respective child classes, but then it'd be a breaking change because of what I said. Any suggestions?

ossl_asn1_get_asn1type() in the C impl can definitely be broken down and moved to each class. It's currently done this way just because it's simpler to do so in C.

What breaking change do you expect?

@HoneyryderChuck
Copy link
Contributor Author

@rhenium made a few adjustments to the ruby code. I believe it got cleaner. The same point stands regarding ASN1Data class having to own to_der implementations for cons and prim though, not much one can do (?).

I broke down ossl_asn1_get_asn1type(), but not completely, as I didn't manage to port OID / UTCTime / GeneralizedTime impls to ruby. Not sure if worth pursuing.

Didn't start cutting C code just yet.

lib/openssl/asn1.rb Outdated Show resolved Hide resolved
lib/openssl/asn1.rb Outdated Show resolved Hide resolved
lib/openssl/asn1.rb Outdated Show resolved Hide resolved
lib/openssl/asn1.rb Outdated Show resolved Hide resolved
lib/openssl/asn1.rb Outdated Show resolved Hide resolved
lib/openssl/asn1.rb Outdated Show resolved Hide resolved
lib/openssl/asn1.rb Outdated Show resolved Hide resolved
@rhenium
Copy link
Member

rhenium commented Jul 18, 2024

The same point stands regarding ASN1Data class having to own to_der implementations for cons and prim though, not much one can do (?).

I think so, unfortunately.

OpenSSL::ASN1.decode produces an instance of OpenSSL::ASN1::ASN1Data when the data doesn't have a known universal class tag number, so ASN1Data#to_der has to be able to handle both. It would have been simpler if .decode produced Primitive/Constructed instance, and ASN1Data#to_der didn't exist, but I feel it's too late to make such an API change.

OID

Encoding the value should be trivial. I added in an inline comment.

UTCTime / GeneralizedTime

Please check X.690 for exact details, but encoding these types should be relatively simple too, since they are just encoded into ISO 8601 (except UTCTime uses 2-digit years).

@HoneyryderChuck HoneyryderChuck force-pushed the asn1-in-ruby branch 4 times, most recently from 95e2d8d to 005d32b Compare July 23, 2024 14:12
lib/openssl/asn1.rb Outdated Show resolved Hide resolved
lib/openssl/asn1.rb Show resolved Hide resolved
lib/openssl/asn1.rb Show resolved Hide resolved
lib/openssl/asn1.rb Outdated Show resolved Hide resolved
lib/openssl/asn1.rb Outdated Show resolved Hide resolved
@HoneyryderChuck HoneyryderChuck force-pushed the asn1-in-ruby branch 2 times, most recently from 2f32854 to 1e35012 Compare July 25, 2024 14:25
@HoneyryderChuck
Copy link
Contributor Author

@rhenium did UTCTime and GeneralizedTime, lmk what you think.

@HoneyryderChuck HoneyryderChuck force-pushed the asn1-in-ruby branch 3 times, most recently from 13e200e to 5785230 Compare July 25, 2024 14:42
lib/openssl/asn1.rb Outdated Show resolved Hide resolved
lib/openssl/asn1.rb Outdated Show resolved Hide resolved
xclass = take_asn1_tag_class(tag_class)

i = constructed ? V_ASN1_CONSTRUCTED : 0
i |= (xclass & V_ASN1_PRIVATE)
Copy link
Member

Choose a reason for hiding this comment

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

& V_ASN1_PRIVATE doesn't change the value, as a tag class can only be one of the 4 classes.

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 ported this from here

lib/openssl/asn1.rb Outdated Show resolved Hide resolved
lib/openssl/asn1.rb Outdated Show resolved Hide resolved
@HoneyryderChuck HoneyryderChuck force-pushed the asn1-in-ruby branch 2 times, most recently from d85de19 to 47e6cf5 Compare July 31, 2024 10:07
@HoneyryderChuck
Copy link
Contributor Author

@rhenium anything still pending?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants