Hi Lev,
I believe that this kind of functionality could be implemented on top of the existing
verify-with-callback API `mbedtls_x509_crt_verify_with_cb()`. More precisely,
you can enable `MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION`
to ignore unknown extensions initially, and then chekc them yourself in the
verification callback by manually traversing `mbedtls_x509_crt::v3_ext`. If you detect
an extension you cannot make sense of and which is marked critical, you can modify the
verification flags.
Would that work for you, in principle? Note, though, that this would work at the level
of verification, not parsing, which might or might not be acceptable.
In this regard you might also be interested in knowing about a significant rewrite
of CRT parsing on the `baremetal` branch. The main difference is that the X.509 CRT
structure has been stripped down to no longer make use of dynamically allocated
memory but instead only provide pointers to the various fields in the certificate.
In the case of dynamic-length fields such as the Subject or Issuer names, but also
the extension list, inspection shall be done through a newline introduced ASN.1
parsing function
int mbedtls_asn1_traverse_sequence_of(
unsigned char **p,
const unsigned char *end,
uint8_t tag_must_mask, uint8_t tag_must_val,
uint8_t tag_may_mask, uint8_t tag_may_val,
int (*cb)( void *ctx, int tag,
unsigned char* start, size_t len ),
void *ctx );
https://github.com/ARMmbed/mbedtls/blob/baremetal/include/mbedtls/asn1.h#L3…
This function traverses an ASN.1 sequence and triggers a callback for each item found.
This functionality could be used to perform the extension traversal in the verification callback
or directly after parsing.
Which extensions are you interested in, particularly, by the way? If it is a standardized
extension, feel free to add support for it under a new compile-time feature flag and
file a PR to add it.
Cheers,
Hanno
________________________________
From: mbed-tls <mbed-tls-bounces(a)lists.trustedfirmware.org> on behalf of Lev Stipakov via mbed-tls <mbed-tls(a)lists.trustedfirmware.org>
Sent: Friday, April 3, 2020 8:32 AM
To: mbed-tls(a)lists.trustedfirmware.org <mbed-tls(a)lists.trustedfirmware.org>
Subject: Re: [mbed-tls] Allowing unsupported extensions in X.509 certificates
Hi,
I am not too much into mbedTLS design and not sure if this would make sense,
but what about if we introduce an API to let client decide, what to do
with unknown extensions?
Let's provide a way for a client to specify a callback
typedef int (*mbedtls_x509_crt_unsupported_extension_cb_t)(
const mbedtls_asn1_buf *oid );
which could be an argument to a new method
int mbedtls_x509_crt_parse_with_ext_cb( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen,
mbedtls_x509_crt_unsupported_extension_cb_t f_ext_cb );
which is called when parser encounters unsupported extension:
/*
* Detect supported extensions
*/
ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type );
if( ret != 0 )
{
/* No parser found, skip extension */
*p = end_ext_octet;
if( is_critical )
{
/* Data is marked as critical: ask client what to do */
if( f_ext_cb != NULL )
{
ret = f_ext_cb( &extn_oid );
}
/* Client is OK with unsupported critical extension, continue */
if( ret == 0 )
continue;
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
}
continue;
}
This would allow us to deprecate
MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION -
those clients which want to allow all extensions could pass a callback
which always returns 0.
What do you think?
--
-Lev
--
mbed-tls mailing list
mbed-tls(a)lists.trustedfirmware.org
https://lists.trustedfirmware.org/mailman/listinfo/mbed-tls
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Hi,
I am not too much into mbedTLS design and not sure if this would make sense,
but what about if we introduce an API to let client decide, what to do
with unknown extensions?
Let's provide a way for a client to specify a callback
typedef int (*mbedtls_x509_crt_unsupported_extension_cb_t)(
const mbedtls_asn1_buf *oid );
which could be an argument to a new method
int mbedtls_x509_crt_parse_with_ext_cb( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen,
mbedtls_x509_crt_unsupported_extension_cb_t f_ext_cb );
which is called when parser encounters unsupported extension:
/*
* Detect supported extensions
*/
ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type );
if( ret != 0 )
{
/* No parser found, skip extension */
*p = end_ext_octet;
if( is_critical )
{
/* Data is marked as critical: ask client what to do */
if( f_ext_cb != NULL )
{
ret = f_ext_cb( &extn_oid );
}
/* Client is OK with unsupported critical extension, continue */
if( ret == 0 )
continue;
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
}
continue;
}
This would allow us to deprecate
MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION -
those clients which want to allow all extensions could pass a callback
which always returns 0.
What do you think?
--
-Lev
Hello,
I have a problem generating the following content in an certificate request :
Requested Extensions:
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Basic Constraints:
CA:FALSE
The only thing I could produce was :
Requested Extensions:
X509v3 Key Usage:
Digital Signature
X509v3 Extended Key Usage:
TLS Web Server Authentication:
Can anybody help me with the function :
mbedtls_x509write_csr_set_extension
Mit freundlichen Grüßen
Thomas Volgmann
---------------------------------------
DSA-Volgmann
Redcarstr. 20
53842 Troisdorf
Tel: 02241 23416 11
Fax: 02241 23416 61
email : thomas.volgmann(a)dsa-volgmann.de<mailto:thomas.volgmann@dsa-volgmann.de>
web: www.dsa-volgmann.de<http://www.dsa-volgmann.de/>
---------------------------------------
Hi Dmitrii!
The reason why we focused on DTLS 1.2 + AEAD for the context serialization was because that's
what we needed to support quickly at the time, and not because we saw some fundamental
technical obstacles in implementing context serialization for TLS 1.2.
I did the same as you, commenting out DTLS checks, and ran into the same problem during
`mbedtls_cipher_auth_decrypt()`. The problem turns out to be the following: In TLS, the
context contains an incoming record counter which, while in DTLS, the record counter
is explicit and hence need not be maintained.
In particular, when using the current serialization+deserialization functions with TLS 1.2,
the incoming record counter will be corrupted.
The core of the fix is simple: You need to duplicate https://github.com/ARMmbed/mbedtls/blob/development/library/ssl_tls.c#L6228…
and https://github.com/ARMmbed/mbedtls/blob/development/library/ssl_tls.c#L6496… -- which save/load the _outgoing_ counter --
for the incoming counter `ssl->in_ctr`. I just tried this and things worked afterwards.
Could you try and see if it works for you, too? If so, please feel free to adapt the serialization
functions and file a PR to add support for serialization in TLS, and mark me as a reviewer.
Note: There will likely be other things that need fixing, too, so please be careful in
using the above patch as-is unless for experimentation.
Cheers,
Hanno
________________________________
From: mbed-tls <mbed-tls-bounces(a)lists.trustedfirmware.org> on behalf of Kuvaiskii, Dmitrii via mbed-tls <mbed-tls(a)lists.trustedfirmware.org>
Sent: Tuesday, March 31, 2020 8:58 PM
To: mbed-tls(a)lists.trustedfirmware.org <mbed-tls(a)lists.trustedfirmware.org>
Subject: [mbed-tls] TLS context serialization: can it be done?
Dear all,
I have the following question. mbedTLS v2.21.0 has support for TLS context serialization in the form of two functions: `mbedtls_ssl_context_save()` and `mbedtls_ssl_context_load()`. I'm trying to use these functions in another project (Graphene, an Intel SGX framework). Slightly oversimplifying, I want to establish a secure communication channel between two different Linux processes. I'd like to persist one of them and then re-spawn it again with the communication channel intact (so that there is no need for a new TLS handshake).
However, I notice that currently these functions support only DTLS 1.2, see e.g.: https://github.com/ARMmbed/mbedtls/blob/aaabe86ac1f47193f4fc499846a0b3abeae…
But I want to use a normal TLS channel, in particular with a ciphersuite `MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256`.
I commented out the checks on DTLS in these functions just to see what will happen. As expected, both functions serialized and then deserialized the context, but when doing a `write(ssl_ctx)` in one (not-persisted) process and a `read(loaded_ssl_ctx)` in another (re-spawned) process, I get an error in `mbedtls_cipher_auth_decrypt()`. Clearly, my deserialized context didn't restore some vital information on the TLS session, and this led to failure in decryption.
Thus, I have two questions:
1. Is there any version of this code that also works on TLS?
2. What are the additional internal objects that must be serialized for TLS (if it makes things easier, in my particular case with AES-GCM and a pre-shared key)? I looked at the code and tried to dump more fields in `mbedtls_ssl_transform`, but it didn't help much. If you'd provide me with some pointers, I could tinker more with mbedTLS code and hopefully make it work.
Thanks in advance for any pointers!
--
Dmitrii
--
mbed-tls mailing list
mbed-tls(a)lists.trustedfirmware.org
https://lists.trustedfirmware.org/mailman/listinfo/mbed-tls
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
On 01/04/2020 11:29, Anibal Portero via mbed-tls wrote:
> SIGPIPE is handled with a signal( SIGPIPE, SIG_IGN ) in
mbedtls_net_connect. While the examples in programs/ssl/ssl_client1.c or
programs/ssl/ssl_client2.c are calling mbedtls_net_connect,
programs/ssl/mini_client.c is not, and therefore not changing the
default behavior of SIGPIPE.
> Our client is based on mini_client.c. What would the best way to
handle SIGPIPE? Would it be worth it to add signal( SIGPIPE, SIG_IGN )
to the mini_client.c example for future reference? maybe even make
net_prepare() visible from outside so a mini client like application can
use it?
That's a good question. I wonder why mbedtls_net_connect() calls
signal(). It's been the case ever since net.c was introduced in XySSL
0.5. But that's a global setting and I don't think a library function
that's supposed to act on a specific socket should modify a global setting.
Should mbedtls_net_send() call send(MSG_NOSIGNAL) instead of write()?
But what about older systems without MSG_NOSIGNAL? Is there a portable
way to disable SIGPIPE for a specific socket?
--
Gilles Peskine
Mbed TLS developer
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Hello,
This is a discussion about the design of a new feature in X.509 parsing,
and a possible deprecation of
MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION.
Normally, when mbedtls_x509_crt_parse() (specifically
x509_get_crt_ext()) encounters an extension that it doesn't support
(unknown OID), it rejects the certificate if the extension is marked as
critical and ignores it otherwise. This is usually the right thing. The
application can inspect all extensions, including ignored ones, in
crt->v3_ext.
However there are use cases where it's useful to pass extensions through
to the application and let the application decide, even for critical
extensions. There's a compilation flag
MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION (default off) which
causes critical extensions to be ignored. However the application must
then parse the extension list again to check for all critical
extensions, including ones that it doesn't support.
https://github.com/ARMmbed/mbedtls/pull/1425 proposes to give the
application better control. At least the application should be able to
specify at runtime which extensions it allows. And perhaps the parser
should provide pointers to the extensions that it finds. The design
needs to reconcile several aspects, in particular:
• With default compile-time and run-time options, unsupported critical
extensions must be rejected, both for security and for backward
compatibility.
• With MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION and default
run-time options, all critical extensions must be accepted, for backward
compatibility.
• It's nicer if the library includes knowledge about extension OIDs.
However this needs to be balanced against the needs of embedded systems
where code size is important and the current size of oid.o is already a
problem.
• Compile-time options increase the testing burden, so it's better not
to add one. And non-default compile-time options aren't useful for
platforms that use a shared library built by a distribution.
With these considerations, how should a runtime mechanism to select
pass-through critical extensions be implemented? Can we do it without a
new compile-time option and without increasing the code size? Should the
new mechanism be present in the default build, only with
MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION or only with a new
compile-time option?
MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION has been around since
before my time. I don't know who might be using it. Should we deprecate
it if there's a more flexible runtime mechanism that doesn't involve
turning it on?
--
Gilles Peskine
Mbed TLS developer
Hi,
> I am not sure how much memory to assign?
I don't think there's a simple answer to that. I think the best you can do is measure how much memory is consumed in your workflow, and add a margin. When doing measurements, you should keep in mind that DTLS handshakes may consume more memory when happening over an unreliable transport, as it then needs to cache out-of-order messages, so you might want to use something like our programs/test/udp_proxy to simulate an unreliable link for you measurements. Also, the size of the messages exchanged (and potentially cached) depends on the size of the certificate chain, so you'll want to do you measurements with a configuration as close as possible to the final one.
> > Current use: 33 blocks / 2508 bytes, max: 99 blocks / 5392 bytes (total 8560 bytes), alloc / free: 8803 / 8771
> What is blocks here and how many bytes per block?
> My understanding is that - out of 99 blocks, 33 blocks are used. Is it right?
In this context, a block just means an area of memory that is or was allocated. So for example if you do `malloc(128); malloc(1024);` you'll have two blocks used, the first being
128 bytes (plus overhead) and the second 1024 bytes (plus overhead). There is no fixed number or size of blocks in the allocator, so here the "max" means the peak of memory consumption - at that time, 5392 bytes had been allocated, over 99 blocks. You'll notice our allocator has a pretty large overhead: when adding administrative data used by the allocator, the peak memory consumption was actually 8560 bytes, out of which only 5392 were actually available to the application.
> Does the memory fragmentation and de-fragmentation is handled inside mbedTLS itself?
No, the provided allocator is very basic and doesn't protect against memory fragmentation.
> And also after every handshake, does it release the used memory buffer for the connection?
Once the handshake is complete, all the RAM that was allocated just for the handshake is freed, and the only buffers that are kept are those that are still necessary for the rest of the connection.
Hope that helps!
Best regards,
Manuel.
Hi,
SIGPIPE is handled with a signal( SIGPIPE, SIG_IGN ) in
mbedtls_net_connect. While the examples in programs/ssl/ssl_client1.c or
programs/ssl/ssl_client2.c are calling mbedtls_net_connect,
programs/ssl/mini_client.c is not, and therefore not changing the default
behavior of SIGPIPE.
Our client is based on mini_client.c. What would the best way to handle
SIGPIPE? Would it be worth it to add signal( SIGPIPE, SIG_IGN ) to the
mini_client.c example for future reference? maybe even make net_prepare()
visible from outside so a mini client like application can use it?
Thanks!
I am directing the issue - https://github.com/ARMmbed/mbedtls/issues/3146
The content of the issue is - Hello,
Currently I am using mbed tls 2.16.3 and I am using it on STM32L4xx
platform.
Before I was using dynamic memory allocation (heap), now planning to shift
to static memory allocation.
I am using x509 ecc based certificate.
I am using DTLS handshake.
I am also using "mbedtls_memory_buffer_alloc_status" to print the status of
static buffer.
The queries are -
1. I am not sure how much memory to assign?
2. I am not able to understand the message -
*Current use: 33 blocks / 2508 bytes, max: 99 blocks / 5392 bytes (total
8560 bytes), alloc / free: 8803 / 8771*
What is blocks here and how many bytes per block?
My understanding is that - out of 99 blocks, 33 blocks are used. Is it
right?
1. Does the memory fragmentation and de-fragmentation is handled inside
mbedTLS itself? And also after every handshake, does it release the used
memory buffer for the connection?
I need the values correct to make sure not to get the memory allocation
failure
Please help me in these queries.
Dear all,
I have the following question. mbedTLS v2.21.0 has support for TLS context serialization in the form of two functions: `mbedtls_ssl_context_save()` and `mbedtls_ssl_context_load()`. I'm trying to use these functions in another project (Graphene, an Intel SGX framework). Slightly oversimplifying, I want to establish a secure communication channel between two different Linux processes. I'd like to persist one of them and then re-spawn it again with the communication channel intact (so that there is no need for a new TLS handshake).
However, I notice that currently these functions support only DTLS 1.2, see e.g.: https://github.com/ARMmbed/mbedtls/blob/aaabe86ac1f47193f4fc499846a0b3abeae…
But I want to use a normal TLS channel, in particular with a ciphersuite `MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256`.
I commented out the checks on DTLS in these functions just to see what will happen. As expected, both functions serialized and then deserialized the context, but when doing a `write(ssl_ctx)` in one (not-persisted) process and a `read(loaded_ssl_ctx)` in another (re-spawned) process, I get an error in `mbedtls_cipher_auth_decrypt()`. Clearly, my deserialized context didn't restore some vital information on the TLS session, and this led to failure in decryption.
Thus, I have two questions:
1. Is there any version of this code that also works on TLS?
2. What are the additional internal objects that must be serialized for TLS (if it makes things easier, in my particular case with AES-GCM and a pre-shared key)? I looked at the code and tried to dump more fields in `mbedtls_ssl_transform`, but it didn't help much. If you'd provide me with some pointers, I could tinker more with mbedTLS code and hopefully make it work.
Thanks in advance for any pointers!
--
Dmitrii