-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Fix string downcast to PrintableString
as issued in #1033
#1641
Conversation
Thanks for the contribution and welcome to the project! This looks like it's your first contribution and I can't find you in our list of contributors. Unfortunately we have a policy of only accepting contributions with a Contributor’s Licence Agreement (CLA), signed or authorised by yourself, so to be able to accept your PR, we'll need your, or your company's approval of a CLA. The easiest way to do this is if you create an mbed account and accept this click through agreement which is applicable if this is a personal contribution. Alternatively, you can find a slightly different agreement to sign here, which can be signed and returned to us, and is applicable if you don't want to create an mbed account or alternatively if this is a corporate contribution. Thanks for your understanding! |
Ok, I just agreed to the CLA with my new mbed account. |
Thanks @thomas-dee! Could you please confirm that this is your profile? Thanks. |
Yes it is. I just linked my GitHub account in the Mbed profile settings. |
library/x509_create.c
Outdated
{ ADD_STRLEN( "serialNumber" ), MBEDTLS_OID_AT_SERIAL_NUMBER, MBEDTLS_ASN1_PRINTABLE_STRING }, | ||
{ ADD_STRLEN( "postalAddress" ), MBEDTLS_OID_AT_POSTAL_ADDRESS, MBEDTLS_ASN1_PRINTABLE_STRING }, | ||
{ ADD_STRLEN( "postalCode" ), MBEDTLS_OID_AT_POSTAL_CODE, MBEDTLS_ASN1_PRINTABLE_STRING }, | ||
{ ADD_STRLEN( "dnQualifier" ), MBEDTLS_OID_AT_DN_QUALIFIER, MBEDTLS_ASN1_PRINTABLE_STRING }, |
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.
@thomas-dee Could you explain the varying choices of encodings here?
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.
As mentioned in line 45 I tried to default to the types given in RFC3280. For the given types it was not clear for me, so I defaulted to PrintableString
.
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.
@thomas-dee I overlooked the reference to RFC 3280, thanks for pointing that out.
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.
We should reference the newer RFC 5280 here.
library/x509_create.c
Outdated
}; | ||
|
||
static const char *x509_at_oid_from_name( const char *name, size_t name_len ) | ||
static const x509_attr_descriptor_t *x509_at_oid_from_name( const char *name, size_t name_len ) |
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 name of this function is no longer accurate when it returns the entire descriptor, and not only the OID.
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.
What about x509_at_descr_from_name
?
library/asn1write.c
Outdated
@@ -253,34 +253,37 @@ int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ) | |||
return( (int) len ); | |||
} | |||
|
|||
int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start, | |||
const char *text, size_t text_len ) | |||
int mbedtls_asn1_write_any_string( unsigned char **p, unsigned char *start, int tag, |
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 don't like the name mbedtls_asn1_write_any_string
- what about mbedtls_asn1_write_tagged_string
, reflecting the flexibility in the tag?
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.
mbedtls_asn1_write_tagged_string
sounds nice.
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.
Overall the change looks good to me, thanks @thomas-dee for your work!
There are some issues that need to be addressed, though:
- The name of the new API function
mbedtls_asn1_write_any_string
should be changed. - The default choice of string format for RDN's should be explained.
- Multiple test suites fail because they compare the output of X.509 writing functions to hardcoded files. Since many RDNs now use the UTF8String format, as
opposed to PrintableString previously, the resulting ASN.1 data is different, and the files containing the expected output need to be updated.
@hanno-arm Thanks for your review. Do you have any ideas how to elaborate the choices of string formats besides referencing RFC3280? |
- renamed `mbedtls_asn1_write_any_string` to `mbedtls_asn1_write_tagged_string` - renamed `x509_at_oid_from_name` to `x509_attr_descr_from_name`
include/mbedtls/asn1write.h
Outdated
* | ||
* \param p reference to current position pointer | ||
* \param start start of the buffer (for bounds-checking) | ||
* \param tag the tag to write |
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.
Suggestion: The tag defining the character encoding used in \p text, e.g. #MBEDTLS_ASN1_UTF8_STRING or #MBEDTLS_ASN1_PRINTABLE_STRING
.
include/mbedtls/asn1write.h
Outdated
* \param p reference to current position pointer | ||
* \param start start of the buffer (for bounds-checking) | ||
* \param tag the tag to write | ||
* \param text the text to write |
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.
Suggestion: The string to write, encoded according to \p tag.
include/mbedtls/asn1write.h
Outdated
* \param start start of the buffer (for bounds-checking) | ||
* \param tag the tag to write | ||
* \param text the text to write | ||
* \param text_len length of the text |
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.
Suggestion: The length of \p text in bytes (not necessarily characters).
include/mbedtls/asn1write.h
Outdated
* | ||
* \param p reference to current position pointer | ||
* \param start start of the buffer (for bounds-checking) | ||
* \param text the text to write |
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.
Pre-existing, but in line with the above suggestion I'd find it clearer to write The string to write, in UTF-8 encoding.
here.
include/mbedtls/asn1write.h
Outdated
* \param p reference to current position pointer | ||
* \param start start of the buffer (for bounds-checking) | ||
* \param text the text to write | ||
* \param text_len length of the text |
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.
Pre-existing, but in line with the above suggestion I'd find it clearer to write The length of \p text in bytes.
here.
include/mbedtls/asn1write.h
Outdated
* \param text the text to write | ||
* \param text_len length of the text | ||
* | ||
* \return the length written or a negative error code |
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.
Pre-existing, but it should be clarified that "length" refers to the entire ASN.1 data, so The number of bytes written to the target buffer \c *p on success.
Also, a negative error code
should be in a separate line, i.e. \return A negative error code on failure.
@thomas-dee Do you mind making these changes while at it?
include/mbedtls/asn1write.h
Outdated
* \return the length written or a negative error code | ||
*/ | ||
int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start, | ||
const char *text, size_t text_len ); |
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 indentation is wrong here.
bf0c60d
to
710f203
Compare
This PR includes #2167 which should be merged first. |
Travis CI failed because of an unlucky seed leading to the UDP proxy dropping too much - such failures should be rare but in principle expected as long as we don't set a limit on how much the UDP proxy may drop. |
retest |
This commit introduces variants test-ca_utf8.crt, test-ca_printablestring.crt and test-ca_uppercase.crt of tests/data_files/test-ca.crt which differ from test-ca.crt in their choice of string encoding and upper and lower case letters in the DN field. These changes should be immaterial to the recovation check, and three tests are added that crl.pem, which applies to test-ca.crt, is also considered as applying to test-ca_*.crt. The test files were generated using PR Mbed-TLS#1641 which - adds a build instruction for test-ca.crt to tests/data_files/Makefile which allows easy change of the subject DN. - changes the default string format from `PrintableString` to `UTF8String`. Specifically: - `test-ca_utf8.crt` was generated by running `rm test-ca.crt && make test-ca.crt` on PR Mbed-TLS#1641. - `test-ca_uppercase.crt`, too, was generated by running `rm test-ca.crt && make test-ca.crt` on PR Mbed-TLS#1641, after modifying the subject DN line in the build instruction for `test-ca.crt` in `tests/data_files/Makefile`. - `test-ca_printable.crt` is a copy of `test-ca.crt` because at the time of this commit, `PrintableString` is still the default string format.
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.
Looks good. I only have one minor remark about preexisting code, also I noticed one commit message claiming to add something, whereas it was actually added in another commit, but in my opinion that is irrelevant.
/* | ||
* Like memcmp, but case-insensitive and always returns -1 if different | ||
*/ | ||
static int x509_memcasecmp( const void *s1, const void *s2, size_t len ) |
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.
This doesn't maintain the law of trichotomy like memcmp
does. Therefore, I'd change the documenting comment, or reimplement the function to return adequate values.
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.
@k-stachowiak Thanks for remarking that - however, while I agree that the documentation could be more verbose, it does already remark that the function 'always returns -1 if different`.
This commit introduces variants test-ca_utf8.crt, test-ca_printablestring.crt and test-ca_uppercase.crt of tests/data_files/test-ca.crt which differ from test-ca.crt in their choice of string encoding and upper and lower case letters in the DN field. These changes should be immaterial to the recovation check, and three tests are added that crl.pem, which applies to test-ca.crt, is also considered as applying to test-ca_*.crt. The test files were generated using PR Mbed-TLS#1641 which - adds a build instruction for test-ca.crt to tests/data_files/Makefile which allows easy change of the subject DN. - changes the default string format from `PrintableString` to `UTF8String`. Specifically: - `test-ca_utf8.crt` was generated by running `rm test-ca.crt && make test-ca.crt` on PR Mbed-TLS#1641. - `test-ca_uppercase.crt`, too, was generated by running `rm test-ca.crt && make test-ca.crt` on PR Mbed-TLS#1641, after modifying the subject DN line in the build instruction for `test-ca.crt` in `tests/data_files/Makefile`. - `test-ca_printable.crt` is a copy of `test-ca.crt` because at the time of this commit, `PrintableString` is still the default string format.
This commit introduces variants test-ca_utf8.crt, test-ca_printablestring.crt and test-ca_uppercase.crt of tests/data_files/test-ca.crt which differ from test-ca.crt in their choice of string encoding and upper and lower case letters in the DN field. These changes should be immaterial to the recovation check, and three tests are added that crl.pem, which applies to test-ca.crt, is also considered as applying to test-ca_*.crt. The test files were generated using PR Mbed-TLS#1641 which - adds a build instruction for test-ca.crt to tests/data_files/Makefile which allows easy change of the subject DN. - changes the default string format from `PrintableString` to `UTF8String`. Specifically: - `test-ca_utf8.crt` was generated by running `rm test-ca.crt && make test-ca.crt` on PR Mbed-TLS#1641. - `test-ca_uppercase.crt`, too, was generated by running `rm test-ca.crt && make test-ca.crt` on PR Mbed-TLS#1641, after modifying the subject DN line in the build instruction for `test-ca.crt` in `tests/data_files/Makefile`. - `test-ca_printable.crt` is a copy of `test-ca.crt` because at the time of this commit, `PrintableString` is still the default string format.
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 new commit looks good. As a side note, I can see, that the commit messages document the data files generation method; I wonder if these are documented equally well elsewhere. If not, then the commit messages could be published somewhere.
one using PrintableString and the other UTF8String) or | ||
in the choice of upper and lower case. Reported by | ||
HenrikRosenquistAndersson in #1784. | ||
|
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.
There needs to be credit to @thomas-dee here also as well as mention of his work in #1033!
* \param p reference to current position pointer | ||
* \param start start of the buffer (for bounds-checking) | ||
* \param len the length to write | ||
* \note This function works backwards in data buffer. |
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.
Not a blocker, but it should be 'This function works backwards in the data buffer'.
@sbutcher-arm Thanks for noticing, indeed this PR never got a ChangeLog entry. Are you adding it during merging? |
f42683f
f42683f
to
f143a78
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.
LGTM
Jenkins CI failed (again) on the BSD timing test, which is a known issue and good enough to be a pass. |
In the 2.7 branch, test-ca.crt has all the components of its Subject name encoded as PrintableString, because it's generated with our cert_write program, and our code writes all components that way until Mbed TLS 2.14. But the default RSA SHA-256 certificate, server2-sha256.crt, has the O and CN components of its Issuer name encoded as UTF8String, because it was generated with OpenSSL and that's what OpenSSL does, regardless of how those components were encoded in the CA's Subject name. This triggers some overly strict behaviour in some libraries, most notably NSS and GnuTLS (of interest to us in ssl-opt.sh) which won't recognize the trusted root as a possible parent for the presented certificate, see for example: Mbed-TLS#1033 Fortunately, we have at our disposal a version of test-ca.crt with encodings matching the ones in server2-sha256.crt, in the file test-ca_utf8.crt. So let's append that to gnutls-cli's list of trusted roots, so that it recognizes certs signed by this CA but with the O and CN components as UTF8String. Note: Since Mbed-TLS#1641 was merged (in Mbed TLS 2.14), we changed how we encode those components, so in the 2.16 branch, cert_write generates test-ca.crt with encodings that matches the ones used by openssl when generating server2-sha256.crt, so the issue of gnutls-cli rejecting server2-sha256.crt is specific to the 2.7 branch.
The test certificate used for clients in compat.sh, cert_sha256.crt, had the issuer ON and CN encoded as UTF8String, but the corresponding CA certificate test-ca_cat12.crt had them encoded as PrintableString. The strings matched, which is sufficient according to RFC 5280 §7.1 and RFC 4518 §2.1. However, GnuTLS 3.4.10 requires the strings to have the same encoding, so it did not accept that the certificate issued by UTF8String "PolarSSL Test CA" was validly issued by the PrintableString "PolarSSL Test CA" CA. ebc1f40, merged via Mbed-TLS#1641 and released in Mbed TLS 2.14, updated these certificates. 4f928c0 merged, via Mbed-TLS#2418 fixed this in the 2.7 LTS branch for the SHA-1 certificate which was used at the time. The present commit applies the same fix for the SHA-256 certificate that is now in use. For uniformity, this commit regenerates all the cert_*.crt. Signed-off-by: Gilles Peskine <[email protected]>
server2-sha256.crt had the issuer ON and CN encoded as UTF8String, but the corresponding CA certificate test-ca_cat12.crt had them encoded as PrintableString. The strings matched, which is sufficient according to RFC 5280 §7.1 and RFC 4518 §2.1. However, GnuTLS 3.4.10 requires the strings to have the same encoding, so it did not accept that the UTF8String "PolarSSL Test CA" certificate was signed by the PrintableString "PolarSSL Test CA" CA. Since Mbed TLS 2.14 (specifically ebc1f40 merged via Mbed-TLS#1641), server2-sha256.crt is generated by Mbed TLS's own cert_write program, which emits a PrintableString. In older versions, this file was generated by OpenSSL, which started emitting UTF8String at some point. 4f928c0 merged via Mbed-TLS#2418 fixed this for the SHA-1 certificate which was used at the time. The present commit applies the same fix for the SHA-256 certificate that is now in use. Signed-off-by: Gilles Peskine <[email protected]>
Description
Fix string downcast to
PrintableString
as issued in #1033.mbedtls_asn1_write_any_string
allowing to write a string with any given tagx509_attrs
inx509_create.c
to handle tag types correctlyx509_write_name
to usembedtls_asn1_write_any_string
using the tag types specified inx509_attrs
Status
READY
Requires Backporting
T.b.d.