Skip to content

Additional extension support #2530

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

Merged
merged 27 commits into from
May 21, 2019

Conversation

RonEld
Copy link
Contributor

@RonEld RonEld commented Mar 24, 2019

Description

Add support for parsing the following X509 extensions:

  1. subject alternative name, of type otherName - HardwareModuleName , as defined in rfc 4108 section 5.
  2. certificate policy, only of type "Any Policy", as defined in rfc 5280 section 4.2.1.4

Status

READY

Requires Backporting

NO
This is an enhancement

Migrations

NO

Todos

  • Tests
  • Documentation
  • Changelog updated
  • Backported

Steps to test or reproduce

Outline the steps to test or reproduce the PR here.

@RonEld RonEld added enhancement mbed TLS team needs-review Every commit must be reviewed by at least two team members, component-x509 labels Mar 24, 2019
@RonEld RonEld force-pushed the additional_extension_support branch 2 times, most recently from 7808db6 to 77e0172 Compare March 24, 2019 15:51
@hanno-becker
Copy link

@RonEld How urgent is this? It would be good to base it on the recent reworkings of the X.509 module, especially #2478, but it's not clear when we'll have time to review and merge the latter.

@RonEld
Copy link
Contributor Author

RonEld commented Mar 25, 2019

@hanno-arm This is targeting 5.13.
I'll rebase, and see if there are differrnces in the behavior

@RonEld RonEld force-pushed the additional_extension_support branch from 77e0172 to f714116 Compare March 25, 2019 12:25
@RonEld
Copy link
Contributor Author

RonEld commented Mar 25, 2019

@hanno-arm I have just checked, and it seems that this is already on top of the latest x509 changes, except for the parsing on demand which is not merged yet

@RonEld RonEld force-pushed the additional_extension_support branch from f714116 to c2bf47d Compare March 25, 2019 12:58
@RonEld RonEld added the needs-preceding-pr Requires another PR to be merged first label Mar 26, 2019
@RonEld
Copy link
Contributor Author

RonEld commented Mar 26, 2019

This is dependent on #2531 to be merged, in order to pass CI

Copy link
Contributor

@k-stachowiak k-stachowiak 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 not found any critical issue. However, I am not sure whether the ABI break is feasible at this moment, and I would suggest removing redundant checks. If a rework is done I would also suggest fixing minor formatting issues.

@@ -79,6 +79,8 @@ typedef struct mbedtls_x509_crt
mbedtls_x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */
mbedtls_x509_name hardware_module_name; /**< Optional OtherName subject Alternative Name. */

mbedtls_x509_sequence certificate_policies; /**< Optional list of certificate4 policies (Only anyPolicy supported). */
Copy link
Contributor

Choose a reason for hiding this comment

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

To my understanding this line breaks the ABI compatibility. Is this intentional and acceptable in this moment in terms of the development cycle?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this breaks the ABI. As well as the hardware_module_name introduced in line 80.

Do you see another way to support these new extensions?
I believe that in this development cycle, it is ok to break the ABI in development branch. @Patater please confirm

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know, how else this could be implemented, especially in a natural way. I only wanted to point this out, as it will matter in case of a release. As far as I understand, merging an ABI break into development, effectively makes the next release a breaking one. If this is what we plan (this is what I meant by the development cycle), then it is fine. But if we plan to have non-breaking, minor releases first, then I think this PR should be somehow tagged and the merge should be held until we are ready for an ABI breaking release.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks,yes, of course.

Copy link
Contributor Author

@RonEld RonEld Mar 28, 2019

Choose a reason for hiding this comment

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

The only way to avoid ABI breakage is to add yet another configuration option ( even two for the two additions?), but I don't like adding more configuration options; at least for this purpose

ChangeLog Outdated
@@ -12,6 +12,10 @@ Features
* Add MBEDTLS_REMOVE_3DES_CIPHERSUITES to allow removing 3DES ciphersuites
from the default list (enabled by default). See
https://sweet32.info/SWEET32_CCS16.pdf.
* Add support for parsing subject alternative name, of type otherName,
HardwareModuleName , as defined in rfc 4108 section 5.
Copy link
Contributor

Choose a reason for hiding this comment

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

If there is a rework done, I would suggest removing an extra space before the comma here.

* { iso(1) identified-organization(3) dod(6) internet(1)
* private(4) enterprise(1) WiSUN(45605) FieldAreaNetwork(1) }
*/
#define MBEDTLS_OID_WISUN_FAN MBEDTLS_OID_INTERNET "\x04\x01\x82\xe4\x25\x01"
Copy link
Contributor

@k-stachowiak k-stachowiak Mar 26, 2019

Choose a reason for hiding this comment

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

Minor: the define's value is not aligned to the others.

library/oid.c Outdated
@@ -290,12 +294,22 @@ static const mbedtls_oid_descriptor_t oid_ext_key_usage[] =
{ ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
{ ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" },
{ ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" },
{ ADD_LEN( MBEDTLS_OID_WISUN_FAN ), "id-kp-wisun-fan-device","Wi-Sun alliance field area network" },
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: all the description strings could be shifted one space to the right here, to have a space after the comma.

unsigned char tag;
mbedtls_x509_buf cur_oid = { 0, 0, NULL };

if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
Copy link
Contributor

Choose a reason for hiding this comment

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

The function is mis-indented starting from this line until the next return statement.

while( *p < end )
{
mbedtls_x509_buf policy_oid = { 0, 0, NULL };
if( ( end - *p ) < 1 )
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems to me that this test is not necessary, as it is repeated inside the ...get_tag function below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok


policy_oid.tag = **p;

if( policy_oid.tag != MBEDTLS_ASN1_OID )
Copy link
Contributor

Choose a reason for hiding this comment

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

As above, this test repeats part of the algorithm executed in ...get_tag below.

@RonEld
Copy link
Contributor Author

RonEld commented Mar 27, 2019

@k-stachowiak Thank you for your comments. Yes, this PR will need re work, as the crypto submodule should be updated, once #2531 will be merged into it.

@RonEld RonEld added needs-work and removed needs-review Every commit must be reviewed by at least two team members, labels Mar 27, 2019
return( 0 );
}
*p += len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,

Choose a reason for hiding this comment

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

Minor: The indentation is off here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, the indentation error described in #2530 (comment) is continued until this line

hardware_module_name->oid.len = len;

*p += len;
tag = **p;
Copy link

@hanno-becker hanno-becker Mar 27, 2019

Choose a reason for hiding this comment

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

Blocker: This looks like it reads **p before validating that there's space available.

Suggestion (we've had this in other places before, too): Remove the assignment entirely and set hardware_module_name->val.tag to MBEDTLS_ASN1_OCTET_STRING, because a successful call to mbedtls_asn1_get_tag() determines the ASN.1 tag uniquely.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

{
case( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ):

Choose a reason for hiding this comment

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

The indentation is off here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is same indentation as in the switch case in x509_get_crt_ext().
I took the example from that function. Am I missing something?

Copy link

@hanno-becker hanno-becker left a comment

Choose a reason for hiding this comment

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

I noticed a missing bounds check and some style issues.

In general, I am concerned that this is in severe conflict with #2478, and would appreciate if we could rebase it on top of the latter in case #2478 is targeted for the next release, too. Ping @Patater.

@RonEld
Copy link
Contributor Author

RonEld commented Mar 27, 2019

@hanno-arm Thank you for your comments.
As mentioned, if #2478 will be merged prior to this PR, then I will rebase this PR on top of it, and make the necessary adjustments.

@RonEld
Copy link
Contributor Author

RonEld commented Apr 1, 2019

This PR is pending #2535 and #2536 to be merged to the crypto submodule

@@ -77,6 +77,9 @@ typedef struct mbedtls_x509_crt
mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */
mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */
mbedtls_x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */
mbedtls_x509_name hardware_module_name; /**< Optional OtherName subject Alternative Name. */

Choose a reason for hiding this comment

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

Note: The storage of names and sequences in mbedtls_x509_name and mbedtls_x509_sequence is very RAM heavy, and I am removing them in #2478, which will also affect these new fields.

*/
static int x509_get_other_name( unsigned char **p,
const unsigned char *end,
mbedtls_x509_name *hardware_module_name )

Choose a reason for hiding this comment

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

I think there is mismatch between the generic name of the function and the specific name of its hardware_module_name argument. However, given that it's static and can change at any time, it's not a blocker.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I am aware. My intention was this function can be enhanced to support other "other names" in the future, but currently only hardware module name supported.
In addition, this function parses the other name SAN section, and returns only the hardware module name

*/
static int x509_get_subject_alt_name( unsigned char **p,
const unsigned char *end,
mbedtls_x509_sequence *subject_alt_name )
mbedtls_x509_sequence *subject_alt_name,

Choose a reason for hiding this comment

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

Similar to above, I think the naming is not optimal here. Now that we distinguish more than one kind of subject alternative name, with subject_alt_name only holding the dNSName entries, and hardware_module_name the HwModuleName entries, the parameter names should reflect that.

However, again this is not a blocker because the function is static, and is also largely rewritten in #2478 anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The subject_alt_name should hold more than just dnsName in the future, such as ipAddress.
However, the HardwareModuleName is a different structure, as it is actually a sequence of an oid and an Octet String, while dnsName and iPAddress are strings. We could think of a way to combine the two

1. Typo fix.
2. Change byte by byte coipy to `memcpy`.
3. Remove parenthesis in switch cases.
@RonEld
Copy link
Contributor Author

RonEld commented May 16, 2019

@k-stachowiak Thank you for your comments!
I believe I have addressed them

k-stachowiak
k-stachowiak previously approved these changes May 16, 2019
Copy link
Contributor

@k-stachowiak k-stachowiak left a comment

Choose a reason for hiding this comment

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

@RonEld Thanks for addressing my comments. The issues I raised have been resolved.

Add some invalid certificate tests for certifiate policies extension.
@RonEld
Copy link
Contributor Author

RonEld commented May 16, 2019

@hanno-arm I have added some negative tests, however I am not sure about how it is correct

@yanesca
Copy link
Contributor

yanesca commented May 17, 2019

@RonEld Can you please share how you generated the test data. Being a negative test, my generic ASN1 parser chokes on it and I can't confirm that they indeed test what they should. For example osting the correct data that you modified to get them would be very helpful. Best would be to put it in a comment or at least in the commit message.

@andresag01 I am on leave next week, can you please work with @RonEld and double check the test vectors, before you renew your approval?

@RonEld
Copy link
Contributor Author

RonEld commented May 19, 2019

@yanesca @andresag01 I have generated the flawd data according to #2530 (comment)
I took the data from the "basic constraints" tests and modified the OID to certificate policies OID, and and manually changed relevant bytes. This is why I am not sure about the data too much, except that it's invalid.. Using the debugger, I saw that the error is returned from the x509_get_crt_ext function, and not the x509_get_certificate_policies function.

Update the test data for the negative certificate policies
extension tests with correct lengths, to test the correct behaviour.
Add another test.
@RonEld RonEld force-pushed the additional_extension_support branch from 30c4584 to 8a59d6b Compare May 19, 2019 11:12
andresag01
andresag01 previously approved these changes May 19, 2019
Copy link
Contributor

@andresag01 andresag01 left a comment

Choose a reason for hiding this comment

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

I looked over the PR once again very briefly. Found a small style issue that is not a blocker.

IMHO we could always use more tests, specially negative testing. But these test vectors are extremely hard to create and generally that is better done using something like fuzzing. This PR adds about 6 negative tests (+/- 1). This is not a lot and I would recommend at least a couple more, but I do not think this is a blocker.

MBEDTLS_X509_SAFE_SNPRINTF;

if( ( ret = x509_info_subject_alt_name( &p, &n,
&crt->subject_alt_names ) ) != 0 )
&crt->subject_alt_names,
prefix) ) != 0 )
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: Please add space before )

@RonEld
Copy link
Contributor Author

RonEld commented May 20, 2019

@andresag01 Thank you for your review!
I think that we can always have more tests.
My main concern is whether the test data itself tests what it claims it does, and that it checks the correct error code. For example. the test "(TBSCertificate v3, ext CertificatePolicies tag, data not oid)" I would expect the error to be :MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG instead of MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_OUT_OF_DATA which is currently returned. I am investigating if this is an issue with the data or the code

@k-stachowiak
Copy link
Contributor

@RonEld I used a windows' utility program to analyze the certificates that you provided, and it fails for all of them with a following error:

C:\Users\krzsta01\Documents\temp>certutil cert1
OCSP Request:
Cannot decode object: ASN1 bad tag value met. 0x8009310b (ASN: 267 CRYPT_E_ASN1_BADTAG)
CertUtil: -dump command FAILED: 0x8009310b (ASN: 267 CRYPT_E_ASN1_BADTAG)
CertUtil: ASN1 bad tag value met.

I tried generating the binary file from the test string in two ways: with and xxd -r -p command in cygwin, and using an online converter. I have md5 compared them to make sure I'm getting a right certificate file.

I am willing to approve the PR, but I'm not entirely sure that the tests should be added if, as you mentioned, they may not test what they are supposed to. Once this question is resolved, I'll gladly tick it green.

Fix test data to test what it actually intends to test.
@RonEld
Copy link
Contributor Author

RonEld commented May 20, 2019

@andresag01 THank you for your review!
I think that we can always have more tests.
My main concern is whether the test data itself tests what it claims it does, and that it checks the correct error code.

Add whitespace before parenthesis.
@RonEld
Copy link
Contributor Author

RonEld commented May 20, 2019

@andresag01 @k-stachowiak I believe I have fixed the test data to test what it actually intends to test, and fixed the error codes accordingly.

I have also fixed the style fix mentioned in #2530 (comment)

Frankly I think some of the commits require some squashing, but that's up to you to decide

@RonEld RonEld dismissed hanno-becker’s stale review May 20, 2019 11:55

Considering the comments were addressed, dismissing the review, to be re-reviewed if have the capacity

Copy link
Contributor

@k-stachowiak k-stachowiak left a comment

Choose a reason for hiding this comment

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

I checked the new test data files in practice to see, where the parsing fails, and it looked good as far as I could tell.

Regarding the commit history, I would normally advise against the rewriting, but I have noticed there is a conflict on the ChangeLog. If that cannot be resolved without a rebase, the history cleanup may be a reasonable thing to do.

On that account, please note that "style fix" is an incorrect commit message (on the last commit). A minimal change I'd suggest is to make it "Fix style", to put it in the required form.

@Patater Patater added approved Design and code approved - may be waiting for CI or backports and removed needs-review Every commit must be reviewed by at least two team members, labels May 20, 2019
@Patater
Copy link
Contributor

Patater commented May 20, 2019

Thanks all for your reviews. We'll consider @andresag01's review as still valid, since only whitespace changes have been made since. With two approvals, this is ready for merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Design and code approved - may be waiting for CI or backports component-x509 enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants