Merge remote-tracking branch 'origin/pr/2411' into development

This commit is contained in:
Jaeden Amero 2019-02-21 12:03:41 +00:00
commit 8963b0311c
9 changed files with 141 additions and 36 deletions

View file

@ -2,6 +2,16 @@ mbed TLS ChangeLog (Sorted per branch, date)
= mbed TLS 2.x.x branch released xxxx-xx-xx = mbed TLS 2.x.x branch released xxxx-xx-xx
Features
* Add a new X.509 API call `mbedtls_x509_parse_der_nocopy()`
which allows copy-less parsing of DER encoded X.509 CRTs,
at the cost of additional lifetime constraints on the input
buffer, but at the benefit of reduced RAM consumption.
API Changes
* Add a new X.509 API call `mbedtls_x509_parse_der_nocopy()`.
See the Features section for more information.
Bugfix Bugfix
* Fix a compilation issue with mbedtls_ecp_restart_ctx not being defined * Fix a compilation issue with mbedtls_ecp_restart_ctx not being defined
when MBEDTLS_ECP_ALT is defined. Reported by jwhui. Fixes #2242. when MBEDTLS_ECP_ALT is defined. Reported by jwhui. Fixes #2242.

View file

@ -52,6 +52,8 @@ extern "C" {
*/ */
typedef struct mbedtls_x509_crt typedef struct mbedtls_x509_crt
{ {
int own_buffer; /**< Indicates if \c raw is owned
* by the structure or not. */
mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ mbedtls_x509_buf raw; /**< The raw certificate data (DER). */
mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
@ -220,16 +222,58 @@ extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb;
/** /**
* \brief Parse a single DER formatted certificate and add it * \brief Parse a single DER formatted certificate and add it
* to the chained list. * to the end of the provided chained list.
* *
* \param chain points to the start of the chain * \param chain The pointer to the start of the CRT chain to attach to.
* \param buf buffer holding the certificate DER data * When parsing the first CRT in a chain, this should point
* \param buflen size of the buffer * to an instance of ::mbedtls_x509_crt initialized through
* mbedtls_x509_crt_init().
* \param buf The buffer holding the DER encoded certificate.
* \param buflen The size in Bytes of \p buf.
* *
* \return 0 if successful, or a specific X509 or PEM error code * \note This function makes an internal copy of the CRT buffer
* \p buf. In particular, \p buf may be destroyed or reused
* after this call returns. To avoid duplicating the CRT
* buffer (at the cost of stricter lifetime constraints),
* use mbedtls_x509_crt_parse_der_nocopy() instead.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/ */
int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf, int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain,
size_t buflen ); const unsigned char *buf,
size_t buflen );
/**
* \brief Parse a single DER formatted certificate and add it
* to the end of the provided chained list. This is a
* variant of mbedtls_x509_crt_parse_der() which takes
* temporary ownership of the CRT buffer until the CRT
* is destroyed.
*
* \param chain The pointer to the start of the CRT chain to attach to.
* When parsing the first CRT in a chain, this should point
* to an instance of ::mbedtls_x509_crt initialized through
* mbedtls_x509_crt_init().
* \param buf The address of the readable buffer holding the DER encoded
* certificate to use. On success, this buffer must be
* retained and not be changed for the liftetime of the
* CRT chain \p chain, that is, until \p chain is destroyed
* through a call to mbedtls_x509_crt_free().
* \param buflen The size in Bytes of \p buf.
*
* \note This call is functionally equivalent to
* mbedtls_x509_crt_parse_der(), but it avoids creating a
* copy of the input buffer at the cost of stronger lifetime
* constraints. This is useful in constrained environments
* where duplication of the CRT cannot be tolerated.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen );
/** /**
* \brief Parse one DER-encoded or one or more concatenated PEM-encoded * \brief Parse one DER-encoded or one or more concatenated PEM-encoded

View file

@ -834,8 +834,10 @@ static int x509_get_crt_ext( unsigned char **p,
/* /*
* Parse and fill a single X.509 certificate in DER format * Parse and fill a single X.509 certificate in DER format
*/ */
static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf, static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
size_t buflen ) const unsigned char *buf,
size_t buflen,
int make_copy )
{ {
int ret; int ret;
size_t len; size_t len;
@ -852,7 +854,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
if( crt == NULL || buf == NULL ) if( crt == NULL || buf == NULL )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
// Use the original buffer until we figure out actual length /* Use the original buffer until we figure out actual length. */
p = (unsigned char*) buf; p = (unsigned char*) buf;
len = buflen; len = buflen;
end = p + len; end = p + len;
@ -870,25 +872,26 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
return( MBEDTLS_ERR_X509_INVALID_FORMAT ); return( MBEDTLS_ERR_X509_INVALID_FORMAT );
} }
if( len > (size_t) ( end - p ) )
{
mbedtls_x509_crt_free( crt );
return( MBEDTLS_ERR_X509_INVALID_FORMAT +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
}
crt_end = p + len;
// Create and populate a new buffer for the raw field
crt->raw.len = crt_end - buf;
crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
if( p == NULL )
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
memcpy( p, buf, crt->raw.len );
// Direct pointers to the new buffer
p += crt->raw.len - len;
end = crt_end = p + len; end = crt_end = p + len;
crt->raw.len = crt_end - buf;
if( make_copy != 0 )
{
/* Create and populate a new buffer for the raw field. */
crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
if( crt->raw.p == NULL )
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
memcpy( crt->raw.p, buf, crt->raw.len );
crt->own_buffer = 1;
p += crt->raw.len - len;
end = crt_end = p + len;
}
else
{
crt->raw.p = (unsigned char*) buf;
crt->own_buffer = 0;
}
/* /*
* TBSCertificate ::= SEQUENCE { * TBSCertificate ::= SEQUENCE {
@ -1091,8 +1094,10 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
* Parse one X.509 certificate in DER format from a buffer and add them to a * Parse one X.509 certificate in DER format from a buffer and add them to a
* chained list * chained list
*/ */
int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf, static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain,
size_t buflen ) const unsigned char *buf,
size_t buflen,
int make_copy )
{ {
int ret; int ret;
mbedtls_x509_crt *crt = chain, *prev = NULL; mbedtls_x509_crt *crt = chain, *prev = NULL;
@ -1124,7 +1129,7 @@ int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *bu
crt = crt->next; crt = crt->next;
} }
if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 ) if( ( ret = x509_crt_parse_der_core( crt, buf, buflen, make_copy ) ) != 0 )
{ {
if( prev ) if( prev )
prev->next = NULL; prev->next = NULL;
@ -1138,11 +1143,27 @@ int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *bu
return( 0 ); return( 0 );
} }
int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen )
{
return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 0 ) );
}
int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen )
{
return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 1 ) );
}
/* /*
* Parse one or more PEM certificates from a buffer and add them to the chained * Parse one or more PEM certificates from a buffer and add them to the chained
* list * list
*/ */
int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen ) int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen )
{ {
#if defined(MBEDTLS_PEM_PARSE_C) #if defined(MBEDTLS_PEM_PARSE_C)
int success = 0, first_error = 0, total_failed = 0; int success = 0, first_error = 0, total_failed = 0;
@ -2699,7 +2720,7 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
mbedtls_free( seq_prv ); mbedtls_free( seq_prv );
} }
if( cert_cur->raw.p != NULL ) if( cert_cur->raw.p != NULL && cert_cur->own_buffer )
{ {
mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len ); mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len );
mbedtls_free( cert_cur->raw.p ); mbedtls_free( cert_cur->raw.p );

View file

@ -45,7 +45,9 @@ all_intermediate += test-ca.req.sha256
test-ca.crt: $(test_ca_key_file_rsa) test-ca.req.sha256 test-ca.crt: $(test_ca_key_file_rsa) test-ca.req.sha256
$(MBEDTLS_CERT_WRITE) is_ca=1 serial=3 request_file=test-ca.req.sha256 selfsign=1 issuer_name="C=NL,O=PolarSSL,CN=PolarSSL Test CA" issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144400 not_after=20210212144400 md=SHA1 version=3 output_file=$@ $(MBEDTLS_CERT_WRITE) is_ca=1 serial=3 request_file=test-ca.req.sha256 selfsign=1 issuer_name="C=NL,O=PolarSSL,CN=PolarSSL Test CA" issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144400 not_after=20210212144400 md=SHA1 version=3 output_file=$@
all_final += test-ca.crt test-ca.der: test-ca.crt
$(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@
all_final += test-ca.crt test-ca.der
test-ca-sha1.crt: $(test_ca_key_file_rsa) test-ca.req.sha256 test-ca-sha1.crt: $(test_ca_key_file_rsa) test-ca.req.sha256
$(MBEDTLS_CERT_WRITE) is_ca=1 serial=3 request_file=test-ca.req.sha256 selfsign=1 issuer_name="C=NL,O=PolarSSL,CN=PolarSSL Test CA" issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144400 not_after=20210212144400 md=SHA1 version=3 output_file=$@ $(MBEDTLS_CERT_WRITE) is_ca=1 serial=3 request_file=test-ca.req.sha256 selfsign=1 issuer_name="C=NL,O=PolarSSL,CN=PolarSSL Test CA" issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144400 not_after=20210212144400 md=SHA1 version=3 output_file=$@
@ -873,7 +875,9 @@ server1_all: server1.crt server1.noauthid.crt server1.crt.openssl server1.v1.crt
server2.crt: server2.req.sha256 server2.crt: server2.req.sha256
$(MBEDTLS_CERT_WRITE) request_file=server2.req.sha256 serial=2 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144406 not_after=20210212144406 md=SHA1 version=3 output_file=$@ $(MBEDTLS_CERT_WRITE) request_file=server2.req.sha256 serial=2 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144406 not_after=20210212144406 md=SHA1 version=3 output_file=$@
all_final += server2.crt server2.der: server2.crt
$(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@
all_final += server2.crt server2.der
server2-sha256.crt: server2.req.sha256 server2-sha256.crt: server2.req.sha256
$(MBEDTLS_CERT_WRITE) request_file=server2.req.sha256 serial=2 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144406 not_after=20210212144406 md=SHA256 version=3 output_file=$@ $(MBEDTLS_CERT_WRITE) request_file=server2.req.sha256 serial=2 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144406 not_after=20210212144406 md=SHA256 version=3 output_file=$@

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -2,14 +2,26 @@ X509 Certificate information #1
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
x509_cert_info:"data_files/server1.crt":"cert. version \: 3\nserial number \: 01\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nissued on \: 2011-02-12 14\:44\:06\nexpires on \: 2021-02-12 14\:44\:06\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n" x509_cert_info:"data_files/server1.crt":"cert. version \: 3\nserial number \: 01\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nissued on \: 2011-02-12 14\:44\:06\nexpires on \: 2021-02-12 14\:44\:06\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n"
X509 Certificate information #1 (DER)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
x509_cert_info:"data_files/server1.der":"cert. version \: 3\nserial number \: 01\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nissued on \: 2011-02-12 14\:44\:06\nexpires on \: 2021-02-12 14\:44\:06\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n"
X509 Certificate information #2 X509 Certificate information #2
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
x509_cert_info:"data_files/server2.crt":"cert. version \: 3\nserial number \: 02\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=localhost\nissued on \: 2011-02-12 14\:44\:06\nexpires on \: 2021-02-12 14\:44\:06\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n" x509_cert_info:"data_files/server2.crt":"cert. version \: 3\nserial number \: 02\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=localhost\nissued on \: 2011-02-12 14\:44\:06\nexpires on \: 2021-02-12 14\:44\:06\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n"
X509 Certificate information #2 (DER)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
x509_cert_info:"data_files/server2.der":"cert. version \: 3\nserial number \: 02\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=localhost\nissued on \: 2011-02-12 14\:44\:06\nexpires on \: 2021-02-12 14\:44\:06\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n"
X509 Certificate information #3 X509 Certificate information #3
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
x509_cert_info:"data_files/test-ca.crt":"cert. version \: 3\nserial number \: 03\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nissued on \: 2011-02-12 14\:44\:00\nexpires on \: 2021-02-12 14\:44\:00\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=true\n" x509_cert_info:"data_files/test-ca.crt":"cert. version \: 3\nserial number \: 03\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nissued on \: 2011-02-12 14\:44\:00\nexpires on \: 2021-02-12 14\:44\:00\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=true\n"
X509 Certificate information #3 (DER)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
x509_cert_info:"data_files/test-ca.der":"cert. version \: 3\nserial number \: 03\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nissued on \: 2011-02-12 14\:44\:00\nexpires on \: 2021-02-12 14\:44\:00\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=true\n"
X509 Certificate information MD2 Digest X509 Certificate information MD2 Digest
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD2_C depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD2_C
x509_cert_info:"data_files/cert_md2.crt":"cert. version \: 3\nserial number \: 09\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Cert MD2\nissued on \: 2009-07-12 10\:56\:59\nexpires on \: 2011-07-12 10\:56\:59\nsigned using \: RSA with MD2\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n" x509_cert_info:"data_files/cert_md2.crt":"cert. version \: 3\nserial number \: 09\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Cert MD2\nissued on \: 2009-07-12 10\:56\:59\nexpires on \: 2011-07-12 10\:56\:59\nsigned using \: RSA with MD2\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n"

View file

@ -513,8 +513,22 @@ void x509parse_crt( data_t * buf, char * result_str, int result )
mbedtls_x509_crt_init( &crt ); mbedtls_x509_crt_init( &crt );
memset( output, 0, 2000 ); memset( output, 0, 2000 );
TEST_ASSERT( mbedtls_x509_crt_parse_der( &crt, buf->x, buf->len ) == ( result ) );
if( ( result ) == 0 )
{
res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );
TEST_ASSERT( mbedtls_x509_crt_parse( &crt, buf->x, buf->len ) == ( result ) ); TEST_ASSERT( res != -1 );
TEST_ASSERT( res != -2 );
TEST_ASSERT( strcmp( (char *) output, result_str ) == 0 );
}
mbedtls_x509_crt_free( &crt );
mbedtls_x509_crt_init( &crt );
memset( output, 0, 2000 );
TEST_ASSERT( mbedtls_x509_crt_parse_der_nocopy( &crt, buf->x, buf->len ) == ( result ) );
if( ( result ) == 0 ) if( ( result ) == 0 )
{ {
res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt ); res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );