mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2025-01-22 16:51:08 +00:00
Merge remote-tracking branch 'restricted/pr/584' into baremetal-proposed
* restricted/pr/584: (140 commits) Remove superfluous new line in x509.c Add comment about X.509 name comparison of buffer with itself [Fixup] Add missing PK release call in Cert Verify parsing Fix guard controlling whether nested acquire calls are allowed Add X.509 CRT test for nested calls for CRT frame / PK acquire Don't return threading error on release()-without-acquire() calls Don't allow nested CRT acquire()-calls if MBEDTLS_X509_ALWAYS_FLUSH Make X.509 CRT cache reference counting unconditional Remove memory buffer alloc from i386 test in all.sh Don't mention pk_sign() in the context of public-key contexts Don't use assertion for failures of mbedtls_x509_crt_x_acquire() Fix copy pasta in x509_crt.h Reference copy-less versions of X.509 CRT frame/PK getters x509_crt.c: Add blank line to increase readability [FIXUP] Fix bug in ASN.1 traversal of silently ignored tag [FIXUP] Fix typo in declaration of mbedtls_x509_memcasecmp() Move signature-info extraction out of MBEDTLS_X509_REMOVE_INFO Fix certificate validity checking logic to work with !TIME_DATE Simplify X.509 CRT version check in UID parsing Remove unused variable warning in on-demand X.509 parsing ...
This commit is contained in:
commit
417d2ce076
|
@ -49,6 +49,13 @@ API Changes
|
|||
always return NULL, and removes the peer_cert field from the
|
||||
mbedtls_ssl_session structure which otherwise stores the peer's
|
||||
certificate.
|
||||
* Add a new compile-time option `MBEDTLS_X509_ON_DEMAND_PARSING`,
|
||||
disabled by default, which allows to parse and cache X.509 CRTs
|
||||
on demand only, at the benefit of lower RAM usage. Enabling
|
||||
this option breaks the structure API of X.509 in that most
|
||||
fields of `mbedtls_x509_crt` are removed, but it keeps the
|
||||
X.509 function API. See the API changes section as well as
|
||||
the documentation in `config.h` for more information.
|
||||
|
||||
Bugfix
|
||||
* Server's RSA certificate in certs.c was SHA-1 signed. In the default
|
||||
|
|
|
@ -91,6 +91,8 @@
|
|||
#define MBEDTLS_X509_CHECK_KEY_USAGE
|
||||
#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
|
||||
#define MBEDTLS_X509_REMOVE_INFO
|
||||
#define MBEDTLS_X509_ON_DEMAND_PARSING
|
||||
#define MBEDTLS_X509_ALWAYS_FLUSH
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
|
||||
/* X.509 CSR writing */
|
||||
|
|
|
@ -89,6 +89,18 @@
|
|||
#define MBEDTLS_ASN1_CONSTRUCTED 0x20
|
||||
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
|
||||
|
||||
/* Slightly smaller way to check if tag is a string tag
|
||||
* compared to canonical implementation. */
|
||||
#define MBEDTLS_ASN1_IS_STRING_TAG( tag ) \
|
||||
( ( tag ) < 32u && ( \
|
||||
( ( 1u << ( tag ) ) & ( ( 1u << MBEDTLS_ASN1_BMP_STRING ) | \
|
||||
( 1u << MBEDTLS_ASN1_UTF8_STRING ) | \
|
||||
( 1u << MBEDTLS_ASN1_T61_STRING ) | \
|
||||
( 1u << MBEDTLS_ASN1_IA5_STRING ) | \
|
||||
( 1u << MBEDTLS_ASN1_UNIVERSAL_STRING ) | \
|
||||
( 1u << MBEDTLS_ASN1_PRINTABLE_STRING ) | \
|
||||
( 1u << MBEDTLS_ASN1_BIT_STRING ) ) ) != 0 ) )
|
||||
|
||||
/*
|
||||
* Bit masks for each of the components of an ASN.1 tag as specified in
|
||||
* ITU X.690 (08/2015), section 8.1 "General rules for encoding",
|
||||
|
@ -119,6 +131,10 @@
|
|||
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \
|
||||
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
|
||||
|
||||
#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len) \
|
||||
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len) ) || \
|
||||
memcmp( (oid_str), (oid_buf), (oid_buf_len) ) != 0 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -260,20 +276,97 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end
|
|||
size_t *len );
|
||||
|
||||
/**
|
||||
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>"
|
||||
* Updated the pointer to immediately behind the full sequence tag.
|
||||
* \brief Free a heap-allocated linked list presentation of
|
||||
* an ASN.1 sequence, including the first element.
|
||||
*
|
||||
* \param p The position in the ASN.1 data
|
||||
* \param end End of data
|
||||
* \param cur First variable in the chain to fill
|
||||
* \param tag Type of sequence
|
||||
* \param seq The address of the first sequence component. This may
|
||||
* be \c NULL, in which case this functions returns
|
||||
* immediately.
|
||||
*/
|
||||
void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq );
|
||||
|
||||
/**
|
||||
* \brief This function parses and splits an ASN.1 "SEQUENCE OF <tag>"
|
||||
* and updates the source buffer pointer to immediately behind
|
||||
* the full sequence.
|
||||
*
|
||||
* \param p The address of the pointer to the beginning of the
|
||||
* ASN.1 SEQUENCE OF structure, including ASN.1 tag+length header.
|
||||
* On success, `*p` is advanced to point to the first byte
|
||||
* following the parsed ASN.1 sequence.
|
||||
* \param end The end of the ASN.1 input buffer starting at \p p. This is
|
||||
* used for bounds checking.
|
||||
* \param cur The address at which to store the first entry in the parsed
|
||||
* sequence. Further entries are heap-allocated and referenced
|
||||
* from \p cur.
|
||||
* \param tag The common tag of the entries in the ASN.1 sequence.
|
||||
*
|
||||
* \note Ownership for the heap-allocated elements \c cur->next,
|
||||
* \c cur->next->next, ..., is passed to the caller. It
|
||||
* is hence the caller's responsibility to free them when
|
||||
* no longer needed, and mbedtls_asn1_sequence_free() can
|
||||
* be used for that, passing \c cur->next as the \c seq
|
||||
* argument (or \p cur if \p cur itself was heap-allocated
|
||||
* by the caller).
|
||||
*
|
||||
* \return 0 if successful or a specific ASN.1 error code.
|
||||
*/
|
||||
int mbedtls_asn1_get_sequence_of( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_asn1_sequence *cur,
|
||||
int tag);
|
||||
int tag );
|
||||
|
||||
/**
|
||||
* \brief Traverse an ASN.1 SEQUENCE container and
|
||||
* call a callback for each entry.
|
||||
*
|
||||
* \warning This function is still experimental and may change
|
||||
* at any time.
|
||||
*
|
||||
* \param p The address of the pointer to the beginning of
|
||||
* the ASN.1 SEQUENCE header. This is updated to
|
||||
* point to the end of the ASN.1 SEQUENCE container
|
||||
* on a successful invocation.
|
||||
* \param end The end of the ASN.1 SEQUENCE container.
|
||||
* \param tag_must_mask A mask to be applied to the ASN.1 tags found within
|
||||
* the SEQUENCE before comparing to \p tag_must_value.
|
||||
* \param tag_must_val The required value of each ASN.1 tag found in the
|
||||
* SEQUENCE, after masking with \p tag_must_mask.
|
||||
* Mismatching tags lead to an error.
|
||||
* For example, a value of \c 0 for both \p tag_must_mask
|
||||
* and \p tag_must_val means that every tag is allowed,
|
||||
* while a value of \c 0xFF for \p tag_must_mask means
|
||||
* that \p tag_must_val is the only allowed tag.
|
||||
* \param tag_may_mask A mask to be applied to the ASN.1 tags found within
|
||||
* the SEQUENCE before comparing to \p tag_may_value.
|
||||
* \param tag_may_val The desired value of each ASN.1 tag found in the
|
||||
* SEQUENCE, after masking with \p tag_may_mask.
|
||||
* Mismatching tags will be silently ignored.
|
||||
* For example, a value of \c 0 for \p tag_may_mask and
|
||||
* \p tag_may_val means that any tag will be considered,
|
||||
* while a value of \c 0xFF for \p tag_may_mask means
|
||||
* that all tags with value different from \p tag_may_val
|
||||
* will be ignored.
|
||||
* \param cb The callback to trigger for each component
|
||||
* in the ASN.1 SEQUENCE. If the callback returns
|
||||
* a non-zero value, the function stops immediately,
|
||||
* forwarding the callback's return value.
|
||||
* \param ctx The context to be passed to the callback \p cb.
|
||||
*
|
||||
* \return \c 0 if successful the entire ASN.1 SEQUENCE
|
||||
* was traversed without parsing or callback errors.
|
||||
* \return A negative ASN.1 error code on a parsing failure.
|
||||
* \return A non-zero error code forwarded from the callback
|
||||
* \p cb in case the latter returns a non-zero value.
|
||||
*/
|
||||
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 );
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
/**
|
||||
|
|
|
@ -1757,6 +1757,54 @@
|
|||
*/
|
||||
#define MBEDTLS_VERSION_FEATURES
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_X509_ON_DEMAND_PARSING
|
||||
*
|
||||
* Save RAM by reducing mbedtls_x509_crt to a pointer
|
||||
* to the raw CRT data and parsing CRTs on demand only.
|
||||
*
|
||||
* \warning This option changes the API by removing most of
|
||||
* the structure fields of mbedtls_x509_crt.
|
||||
*
|
||||
* \warning This option and its corresponding X.509 API are currently
|
||||
* under development and may change at any time.
|
||||
*
|
||||
* Regardless of whether this option is enabled or not, direct access of
|
||||
* structure fields of `mbedtls_x509_crt` should be replaced by calls to
|
||||
* one of the following functions:
|
||||
* - mbedtls_x509_crt_get_frame(), to obtain a CRT frame giving
|
||||
* access to several basic CRT fields (such as the CRT version),
|
||||
* as well as pointers to the raw ASN.1 data of more complex fields
|
||||
* (such as the issuer).
|
||||
* - mbedtls_x509_crt_get_pk(), to obtain a public key context
|
||||
* for the public key contained in the certificate.
|
||||
* - mbedtls_x509_crt_get_issuer(), to obtain the issuer name.
|
||||
* - mbedtls_x509_crt_get_subject(), to obtain the subject name.
|
||||
* - mbedtls_x509_crt_get_subject_alt_names(), to obtain the
|
||||
* alternative names from the subject alternative names extension.
|
||||
* - mbedtls_x509_crt_get_ext_key_usage(), to obtain the state of
|
||||
* the extended key usage extension.
|
||||
*
|
||||
* Uncomment this to enable on-demand CRT parsing to save RAM.
|
||||
*/
|
||||
//#define MBEDTLS_X509_ON_DEMAND_PARSING
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_X509_ALWAYS_FLUSH
|
||||
*
|
||||
* Save RAM by having Mbed TLS always flush caches for parsed X.509
|
||||
* structures after use: This means, firstly, that caches of X.509
|
||||
* structures used by an API call are flushed when the call returns,
|
||||
* but it also encompasses immediate flushing of caches when Mbed TLS uses
|
||||
* multiple structures in succession, thereby reducing the peak RAM usage.
|
||||
* Setting this option leads to minimal RAM usage of the X.509 module at
|
||||
* the cost of performance penalties when using X.509 structures multiple
|
||||
* times (such as trusted CRTs on systems serving many connections).
|
||||
*
|
||||
* Uncomment this to always flush caches for unused X.509 structures.
|
||||
*/
|
||||
#define MBEDTLS_X509_ALWAYS_FLUSH
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
|
||||
*
|
||||
|
|
|
@ -183,6 +183,15 @@ extern "C" {
|
|||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basic length-value buffer structure
|
||||
*/
|
||||
typedef struct mbedtls_x509_buf_raw
|
||||
{
|
||||
unsigned char *p; /*!< The address of the first byte in the buffer. */
|
||||
size_t len; /*!< The number of Bytes in the buffer. */
|
||||
} mbedtls_x509_buf_raw;
|
||||
|
||||
/**
|
||||
* Type-length-value structure that allows for ASN1 using DER.
|
||||
*/
|
||||
|
@ -269,6 +278,29 @@ int mbedtls_x509_time_is_past( const mbedtls_x509_time *to );
|
|||
*/
|
||||
int mbedtls_x509_time_is_future( const mbedtls_x509_time *from );
|
||||
|
||||
/**
|
||||
* \brief Free a dynamic linked list presentation of an X.509 name
|
||||
* as returned e.g. by mbedtls_x509_crt_get_subject().
|
||||
*
|
||||
* \param name The address of the first name component. This may
|
||||
* be \c NULL, in which case this functions returns
|
||||
* immediately.
|
||||
*/
|
||||
void mbedtls_x509_name_free( mbedtls_x509_name *name );
|
||||
|
||||
/**
|
||||
* \brief Free a dynamic linked list presentation of an X.509 sequence
|
||||
* as returned e.g. by mbedtls_x509_crt_get_subject_alt_name().
|
||||
*
|
||||
* \param seq The address of the first sequence component. This may
|
||||
* be \c NULL, in which case this functions returns
|
||||
* immediately.
|
||||
*/
|
||||
static inline void mbedtls_x509_sequence_free( mbedtls_x509_sequence *seq )
|
||||
{
|
||||
mbedtls_asn1_sequence_free( (mbedtls_asn1_sequence*) seq );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
/**
|
||||
|
@ -280,49 +312,6 @@ int mbedtls_x509_self_test( int verbose );
|
|||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
/*
|
||||
* Internal module functions. You probably do not want to use these unless you
|
||||
* know you do.
|
||||
*/
|
||||
int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_name *cur );
|
||||
int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_buf *alg );
|
||||
int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_buf *alg, mbedtls_x509_buf *params );
|
||||
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
|
||||
int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
|
||||
mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
|
||||
int *salt_len );
|
||||
#endif
|
||||
int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig );
|
||||
int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
|
||||
mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
|
||||
void **sig_opts );
|
||||
int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_time *t );
|
||||
int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_buf *serial );
|
||||
int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_buf *ext, int tag );
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
|
||||
mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
|
||||
const void *sig_opts );
|
||||
#endif
|
||||
int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name );
|
||||
int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name );
|
||||
int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
|
||||
int critical, const unsigned char *val,
|
||||
size_t val_len );
|
||||
int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
|
||||
mbedtls_asn1_named_data *first );
|
||||
int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
|
||||
mbedtls_asn1_named_data *first );
|
||||
int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
unsigned char *sig, size_t size );
|
||||
|
||||
#define MBEDTLS_X509_SAFE_SNPRINTF \
|
||||
do { \
|
||||
if( ret < 0 || (size_t) ret >= n ) \
|
||||
|
@ -332,6 +321,18 @@ int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
|
|||
p += (size_t) ret; \
|
||||
} while( 0 )
|
||||
|
||||
#define MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP \
|
||||
do { \
|
||||
if( ret < 0 || (size_t) ret >= n ) \
|
||||
{ \
|
||||
ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; \
|
||||
goto cleanup; \
|
||||
} \
|
||||
\
|
||||
n -= (size_t) ret; \
|
||||
p += (size_t) ret; \
|
||||
} while( 0 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -75,7 +75,7 @@ typedef struct mbedtls_x509_crl
|
|||
int version; /**< CRL version (1=v1, 2=v2) */
|
||||
mbedtls_x509_buf sig_oid; /**< CRL signature type identifier */
|
||||
|
||||
mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). */
|
||||
mbedtls_x509_buf_raw issuer_raw; /**< The raw issuer data (DER). */
|
||||
|
||||
mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "x509.h"
|
||||
#include "x509_crl.h"
|
||||
#include "x509_internal.h"
|
||||
|
||||
/**
|
||||
* \addtogroup x509_module
|
||||
|
@ -47,14 +48,69 @@ extern "C" {
|
|||
* \{
|
||||
*/
|
||||
|
||||
typedef struct mbedtls_x509_crt_frame
|
||||
{
|
||||
/* Keep these 8-bit fields at the front of the structure to allow them to
|
||||
* be fetched in a single instruction on Thumb2; putting them at the back
|
||||
* requires an intermediate address calculation. */
|
||||
|
||||
uint8_t version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */
|
||||
uint8_t ca_istrue; /**< Optional Basic Constraint extension value:
|
||||
* 1 if this certificate belongs to a CA, 0 otherwise. */
|
||||
uint8_t max_pathlen; /**< Optional Basic Constraint extension value:
|
||||
* The maximum path length to the root certificate.
|
||||
* Path length is 1 higher than RFC 5280 'meaning', so 1+ */
|
||||
uint8_t ns_cert_type; /**< Optional Netscape certificate type extension value:
|
||||
* See the values in x509.h */
|
||||
|
||||
mbedtls_md_type_t sig_md; /**< The hash algorithm used to hash CRT before signing. */
|
||||
mbedtls_pk_type_t sig_pk; /**< The signature algorithm used to sign the CRT hash. */
|
||||
|
||||
uint16_t key_usage; /**< Optional key usage extension value: See the values in x509.h */
|
||||
uint32_t ext_types; /**< Bitfield indicating which extensions are present.
|
||||
* See the values in x509.h. */
|
||||
|
||||
mbedtls_x509_time valid_from; /**< The start time of certificate validity. */
|
||||
mbedtls_x509_time valid_to; /**< The end time of certificate validity. */
|
||||
|
||||
mbedtls_x509_buf_raw raw; /**< The raw certificate data in DER. */
|
||||
mbedtls_x509_buf_raw tbs; /**< The part of the CRT that is [T]o [B]e [S]igned. */
|
||||
|
||||
mbedtls_x509_buf_raw serial; /**< The unique ID for certificate issued by a specific CA. */
|
||||
|
||||
mbedtls_x509_buf_raw pubkey_raw; /**< The raw public key data (DER). */
|
||||
|
||||
mbedtls_x509_buf_raw issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */
|
||||
mbedtls_x509_buf_raw issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */
|
||||
|
||||
mbedtls_x509_buf_raw subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */
|
||||
mbedtls_x509_buf_raw subject_raw; /**< The raw subject data (DER). Used for quick comparison. */
|
||||
|
||||
mbedtls_x509_buf_raw sig; /**< Signature: hash of the tbs part signed with the private key. */
|
||||
mbedtls_x509_buf_raw sig_alg; /**< The signature algorithm used for \p sig. */
|
||||
|
||||
mbedtls_x509_buf_raw v3_ext; /**< The raw data for the extension list in the certificate.
|
||||
* Might be useful for manual inspection of extensions that
|
||||
* Mbed TLS doesn't yet support. */
|
||||
mbedtls_x509_buf_raw subject_alt_raw; /**< The raw data for the SubjectAlternativeNames extension. */
|
||||
mbedtls_x509_buf_raw ext_key_usage_raw; /**< The raw data for the ExtendedKeyUsage extension. */
|
||||
|
||||
} mbedtls_x509_crt_frame;
|
||||
|
||||
/**
|
||||
* Container for an X.509 certificate. The certificate may be chained.
|
||||
*/
|
||||
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). */
|
||||
* by the structure or not. */
|
||||
mbedtls_x509_buf raw; /**< The raw certificate data (DER). */
|
||||
mbedtls_x509_crt_cache *cache; /**< Internal parsing cache. */
|
||||
|
||||
struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */
|
||||
|
||||
/* Legacy fields */
|
||||
#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING)
|
||||
mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
|
||||
|
||||
int version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */
|
||||
|
@ -84,7 +140,7 @@ typedef struct mbedtls_x509_crt
|
|||
|
||||
unsigned int key_usage; /**< Optional key usage extension value: See the values in x509.h */
|
||||
|
||||
mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */
|
||||
mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */
|
||||
|
||||
unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */
|
||||
|
||||
|
@ -92,8 +148,7 @@ typedef struct mbedtls_x509_crt
|
|||
mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
|
||||
mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
|
||||
void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
|
||||
|
||||
struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */
|
||||
#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */
|
||||
}
|
||||
mbedtls_x509_crt;
|
||||
|
||||
|
@ -586,6 +641,366 @@ void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx );
|
|||
*/
|
||||
void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx );
|
||||
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
/**
|
||||
* \brief Request CRT frame giving access to basic CRT fields
|
||||
* and raw ASN.1 data of complex fields.
|
||||
*
|
||||
* \param crt The CRT to use. This must be initialized and set up.
|
||||
* \param dst The address of the destination frame structure.
|
||||
* This need not be initialized.
|
||||
*
|
||||
* \note ::mbedtls_x509_crt_frame does not contain pointers to
|
||||
* dynamically allocated memory, and hence need not be freed.
|
||||
* Users may e.g. allocate an instance of
|
||||
* ::mbedtls_x509_crt_frame on the stack and call this function
|
||||
* on it, in which case no allocation/freeing has to be done.
|
||||
*
|
||||
* \note You may also use mbedtls_x509_crt_frame_acquire() and
|
||||
* mbedtls_x509_crt_frame_release() for copy-less variants
|
||||
* of this function.
|
||||
*
|
||||
* \return \c 0 on success. In this case, \p dst is updated
|
||||
* to hold the frame for the given CRT.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_x509_crt_get_frame( mbedtls_x509_crt const *crt,
|
||||
mbedtls_x509_crt_frame *dst );
|
||||
|
||||
/**
|
||||
* \brief Set up a PK context with the public key in a certificate.
|
||||
*
|
||||
* \param crt The certificate to use. This must be initialized and set up.
|
||||
* \param pk The address of the destination PK context to fill.
|
||||
* This must be initialized via mbedtls_pk_init().
|
||||
*
|
||||
* \note You may also use mbedtls_x509_crt_pk_acquire() and
|
||||
* mbedtls_x509_crt_pk_release() for copy-less variants
|
||||
* of this function.
|
||||
*
|
||||
* \return \c 0 on success. In this case, the user takes ownership
|
||||
* of the destination PK context, and is responsible for
|
||||
* calling mbedtls_pk_free() on it once it's no longer needed.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_x509_crt_get_pk( mbedtls_x509_crt const *crt,
|
||||
mbedtls_pk_context *pk );
|
||||
|
||||
/**
|
||||
* \brief Request the subject name of a CRT, presented
|
||||
* as a dynamically allocated linked list.
|
||||
*
|
||||
* \param crt The CRT to use. This must be initialized and set up.
|
||||
* \param subject The address at which to store the address of the
|
||||
* first entry of the generated linked list holding
|
||||
* the subject name.
|
||||
*
|
||||
* \note Depending on your use case, consider using the raw ASN.1
|
||||
* describing the subject name instead of the heap-allocated
|
||||
* linked list generated by this call. The pointers to the
|
||||
* raw ASN.1 data are part of the CRT frame that can be queried
|
||||
* via mbedtls_x509_crt_get_frame(), and they can be traversed
|
||||
* via mbedtls_asn1_traverse_sequence_of().
|
||||
*
|
||||
* \return \c 0 on success. In this case, the user takes ownership
|
||||
* of the name context, and is responsible for freeing it
|
||||
* through a call to mbedtls_x509_name_free() once it's no
|
||||
* longer needed.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_x509_crt_get_subject( mbedtls_x509_crt const *crt,
|
||||
mbedtls_x509_name **subject );
|
||||
|
||||
/**
|
||||
* \brief Request the subject name of a CRT, presented
|
||||
* as a dynamically allocated linked list.
|
||||
*
|
||||
* \param crt The CRT to use. This must be initialized and set up.
|
||||
* \param issuer The address at which to store the address of the
|
||||
* first entry of the generated linked list holding
|
||||
* the subject name.
|
||||
*
|
||||
* \note Depending on your use case, consider using the raw ASN.1
|
||||
* describing the issuer name instead of the heap-allocated
|
||||
* linked list generated by this call. The pointers to the
|
||||
* raw ASN.1 data are part of the CRT frame that can be queried
|
||||
* via mbedtls_x509_crt_get_frame(), and they can be traversed
|
||||
* via mbedtls_asn1_traverse_sequence_of().
|
||||
*
|
||||
* \return \c 0 on success. In this case, the user takes ownership
|
||||
* of the name context, and is responsible for freeing it
|
||||
* through a call to mbedtls_x509_name_free() once it's no
|
||||
* longer needed.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_x509_crt_get_issuer( mbedtls_x509_crt const *crt,
|
||||
mbedtls_x509_name **issuer );
|
||||
|
||||
/**
|
||||
* \brief Request the subject alternative name of a CRT, presented
|
||||
* as a dynamically allocated linked list.
|
||||
*
|
||||
* \param crt The CRT to use. This must be initialized and set up.
|
||||
* \param subj_alt The address at which to store the address of the
|
||||
* first component of the subject alternative names list.
|
||||
*
|
||||
* \note Depending in your use case, consider using the raw ASN.1
|
||||
* describing the subject alternative names extension
|
||||
* instead of the heap-allocated linked list generated by this
|
||||
* call. The pointers to the raw ASN.1 data are part of the CRT
|
||||
* frame that can be queried via mbedtls_x509_crt_get_frame(),
|
||||
* and mbedtls_asn1_traverse_sequence_of() can be used to
|
||||
* traverse the list of subject alternative names.
|
||||
*
|
||||
* \return \c 0 on success. In this case, the user takes ownership
|
||||
* of the name context, and is responsible for freeing it
|
||||
* through a call to mbedtls_x509_sequence_free() once it's
|
||||
* no longer needed.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_x509_crt_get_subject_alt_names( mbedtls_x509_crt const *crt,
|
||||
mbedtls_x509_sequence **subj_alt );
|
||||
|
||||
/**
|
||||
* \brief Request the ExtendedKeyUsage extension of a CRT,
|
||||
* presented as a dynamically allocated linked list.
|
||||
*
|
||||
* \param crt The CRT to use. This must be initialized and set up.
|
||||
* \param ext_key_usage The address at which to store the address of the
|
||||
* first entry of the ExtendedKeyUsage extension.
|
||||
*
|
||||
* \note Depending in your use case, consider using the raw ASN.1
|
||||
* describing the extended key usage extension instead of
|
||||
* the heap-allocated linked list generated by this call.
|
||||
* The pointers to the raw ASN.1 data are part of the CRT
|
||||
* frame that can be queried via mbedtls_x509_crt_get_frame(),
|
||||
* and mbedtls_asn1_traverse_sequence_of() can be used to
|
||||
* traverse the entries in the extended key usage extension.
|
||||
*
|
||||
* \return \c 0 on success. In this case, the user takes ownership
|
||||
* of the name context, and is responsible for freeing it
|
||||
* through a call to mbedtls_x509_sequence_free() once it's
|
||||
* no longer needed.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_x509_crt_get_ext_key_usage( mbedtls_x509_crt const *crt,
|
||||
mbedtls_x509_sequence **ext_key_usage );
|
||||
|
||||
/**
|
||||
* \brief Flush internal X.509 CRT parsing cache, if present.
|
||||
*
|
||||
* \param crt The CRT structure whose cache to flush.
|
||||
*
|
||||
* \note Calling this function frequently reduces RAM usage
|
||||
* at the cost of performance.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_x509_crt_flush_cache( mbedtls_x509_crt const *crt );
|
||||
|
||||
/**
|
||||
* \brief Request temporary read-access to a certificate frame
|
||||
* for a given certificate.
|
||||
*
|
||||
* Once no longer needed, the frame must be released
|
||||
* through a call to mbedtls_x509_crt_frame_release().
|
||||
*
|
||||
* This is a copy-less version of mbedtls_x509_crt_get_frame().
|
||||
* See there for more information.
|
||||
*
|
||||
* \param crt The certificate to use. This must be initialized and set up.
|
||||
* \param dst The address at which to store the address of a readable
|
||||
* certificate frame for the input certificate \p crt which the
|
||||
* caller can use until calling mbedtls_x509_crt_frame_release().
|
||||
*
|
||||
* \note The certificate frame `**frame_ptr` returned by this function
|
||||
* is owned by the X.509 module and must not be freed or modified
|
||||
* by the caller. The X.509 module guarantees its validity as long
|
||||
* as \p crt is valid and mbedtls_x509_crt_frame_release() hasn't
|
||||
* been issued.
|
||||
*
|
||||
* \note In a single-threaded application using
|
||||
* MBEDTLS_X509_ALWAYS_FLUSH, nested calls to this function
|
||||
* are not allowed and will fail gracefully with
|
||||
* MBEDTLS_ERR_X509_FATAL_ERROR.
|
||||
*
|
||||
* \return \c 0 on success. In this case, `*frame_ptr` is updated
|
||||
* to hold the address of a frame for the given CRT.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
static inline int mbedtls_x509_crt_frame_acquire( mbedtls_x509_crt const *crt,
|
||||
mbedtls_x509_crt_frame const **dst )
|
||||
{
|
||||
int ret = 0;
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
|
||||
defined(MBEDTLS_THREADING_C)
|
||||
if( crt->cache->frame_readers == 0 )
|
||||
#endif
|
||||
ret = mbedtls_x509_crt_cache_provide_frame( crt );
|
||||
|
||||
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
|
||||
defined(MBEDTLS_THREADING_C)
|
||||
if( crt->cache->frame_readers == MBEDTLS_X509_CACHE_FRAME_READERS_MAX )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
|
||||
crt->cache->frame_readers++;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &crt->cache->frame_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
*dst = crt->cache->frame;
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Release access to a certificate frame acquired
|
||||
* through a prior call to mbedtls_x509_crt_frame_acquire().
|
||||
*
|
||||
* \param crt The certificate for which a certificate frame has
|
||||
* previously been acquired.
|
||||
*/
|
||||
static inline int mbedtls_x509_crt_frame_release( mbedtls_x509_crt const *crt )
|
||||
{
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
|
||||
defined(MBEDTLS_THREADING_C)
|
||||
if( crt->cache->frame_readers == 0 )
|
||||
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
||||
|
||||
crt->cache->frame_readers--;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_unlock( &crt->cache->frame_mutex );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
#if defined(MBEDTLS_X509_ALWAYS_FLUSH)
|
||||
(void) mbedtls_x509_crt_flush_cache_frame( crt );
|
||||
#endif /* MBEDTLS_X509_ALWAYS_FLUSH */
|
||||
|
||||
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) && \
|
||||
!defined(MBEDTLS_THREADING_C)
|
||||
((void) crt);
|
||||
#endif
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Request temporary access to a public key context
|
||||
* for a given certificate.
|
||||
*
|
||||
* Once no longer needed, the frame must be released
|
||||
* through a call to mbedtls_x509_crt_pk_release().
|
||||
*
|
||||
* This is a copy-less version of mbedtls_x509_crt_get_pk().
|
||||
* See there for more information.
|
||||
*
|
||||
* \param crt The certificate to use. This must be initialized and set up.
|
||||
* \param dst The address at which to store the address of a public key
|
||||
* context for the public key in the input certificate \p crt.
|
||||
*
|
||||
* \warning The public key context `**pk_ptr` returned by this function
|
||||
* is owned by the X.509 module and must be used by the caller
|
||||
* in a thread-safe way. In particular, the caller must only
|
||||
* use the context with functions which are `const` on the input
|
||||
* context, or those which are known to be thread-safe. The latter
|
||||
* for example includes mbedtls_pk_verify() for ECC or RSA public
|
||||
* key contexts.
|
||||
*
|
||||
* \note In a single-threaded application using
|
||||
* MBEDTLS_X509_ALWAYS_FLUSH, nested calls to this function
|
||||
* are not allowed and will fail gracefully with
|
||||
* MBEDTLS_ERR_X509_FATAL_ERROR.
|
||||
*
|
||||
* \return \c 0 on success. In this case, `*pk_ptr` is updated
|
||||
* to hold the address of a public key context for the given
|
||||
* certificate.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
static inline int mbedtls_x509_crt_pk_acquire( mbedtls_x509_crt const *crt,
|
||||
mbedtls_pk_context **dst )
|
||||
{
|
||||
int ret = 0;
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
|
||||
defined(MBEDTLS_THREADING_C)
|
||||
if( crt->cache->pk_readers == 0 )
|
||||
#endif
|
||||
ret = mbedtls_x509_crt_cache_provide_pk( crt );
|
||||
|
||||
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
|
||||
defined(MBEDTLS_THREADING_C)
|
||||
if( crt->cache->pk_readers == MBEDTLS_X509_CACHE_PK_READERS_MAX )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
|
||||
crt->cache->pk_readers++;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_unlock( &crt->cache->pk_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
*dst = crt->cache->pk;
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Release access to a public key context acquired
|
||||
* through a prior call to mbedtls_x509_crt_frame_acquire().
|
||||
*
|
||||
* \param crt The certificate for which a certificate frame has
|
||||
* previously been acquired.
|
||||
*/
|
||||
static inline int mbedtls_x509_crt_pk_release( mbedtls_x509_crt const *crt )
|
||||
{
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 )
|
||||
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
|
||||
defined(MBEDTLS_THREADING_C)
|
||||
if( crt->cache->pk_readers == 0 )
|
||||
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
||||
|
||||
crt->cache->pk_readers--;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_unlock( &crt->cache->pk_mutex );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
#if defined(MBEDTLS_X509_ALWAYS_FLUSH)
|
||||
(void) mbedtls_x509_crt_flush_cache_pk( crt );
|
||||
#endif /* MBEDTLS_X509_ALWAYS_FLUSH */
|
||||
|
||||
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) && \
|
||||
!defined(MBEDTLS_THREADING_C)
|
||||
((void) crt);
|
||||
#endif
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
/* \} name */
|
||||
|
|
117
include/mbedtls/x509_internal.h
Normal file
117
include/mbedtls/x509_internal.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* \file x509_internal.h
|
||||
*
|
||||
* \brief Internal X.509 functions
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2006-2019, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of Mbed TLS (https://tls.mbed.org)
|
||||
*
|
||||
*/
|
||||
#ifndef MBEDTLS_X509_INTERNAL_H
|
||||
#define MBEDTLS_X509_INTERNAL_H
|
||||
|
||||
#include "x509.h"
|
||||
#include "threading.h"
|
||||
|
||||
/* Internal structure used for caching parsed data from an X.509 CRT. */
|
||||
|
||||
struct mbedtls_x509_crt;
|
||||
struct mbedtls_pk_context;
|
||||
struct mbedtls_x509_crt_frame;
|
||||
#define MBEDTLS_X509_CACHE_PK_READERS_MAX ((uint32_t) -1)
|
||||
#define MBEDTLS_X509_CACHE_FRAME_READERS_MAX ((uint32_t) -1)
|
||||
typedef struct mbedtls_x509_crt_cache
|
||||
{
|
||||
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
|
||||
defined(MBEDTLS_THREADING_C)
|
||||
uint32_t frame_readers;
|
||||
uint32_t pk_readers;
|
||||
#endif /* !MBEDTLS_X509_ALWAYS_FLUSH || MBEDTLS_THREADING_C */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_threading_mutex_t frame_mutex;
|
||||
mbedtls_threading_mutex_t pk_mutex;
|
||||
#endif
|
||||
mbedtls_x509_buf_raw pk_raw;
|
||||
struct mbedtls_x509_crt_frame *frame;
|
||||
struct mbedtls_pk_context *pk;
|
||||
} mbedtls_x509_crt_cache;
|
||||
|
||||
/* Internal X.509 CRT cache handling functions. */
|
||||
|
||||
int mbedtls_x509_crt_flush_cache_frame( struct mbedtls_x509_crt const *crt );
|
||||
int mbedtls_x509_crt_flush_cache_pk( struct mbedtls_x509_crt const *crt );
|
||||
|
||||
int mbedtls_x509_crt_cache_provide_frame( struct mbedtls_x509_crt const *crt );
|
||||
int mbedtls_x509_crt_cache_provide_pk( struct mbedtls_x509_crt const *crt );
|
||||
|
||||
/* Uncategorized internal X.509 functions */
|
||||
|
||||
int mbedtls_x509_get_name( unsigned char *p, size_t len,
|
||||
mbedtls_x509_name *cur );
|
||||
int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_buf *alg );
|
||||
int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_buf *alg, mbedtls_x509_buf *params );
|
||||
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
|
||||
int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
|
||||
mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
|
||||
int *salt_len );
|
||||
#endif
|
||||
int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig );
|
||||
int mbedtls_x509_get_sig_alg_raw( unsigned char **p, unsigned char const *end,
|
||||
mbedtls_md_type_t *md_alg,
|
||||
mbedtls_pk_type_t *pk_alg,
|
||||
void **sig_opts );
|
||||
int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
|
||||
mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
|
||||
void **sig_opts );
|
||||
int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_time *t );
|
||||
int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_buf *serial );
|
||||
int mbedtls_x509_name_cmp_raw( mbedtls_x509_buf_raw const *a,
|
||||
mbedtls_x509_buf_raw const *b,
|
||||
int (*check)( void *ctx,
|
||||
mbedtls_x509_buf *oid,
|
||||
mbedtls_x509_buf *val,
|
||||
int next_merged ),
|
||||
void *check_ctx );
|
||||
int mbedtls_x509_memcasecmp( const void *s1, const void *s2,
|
||||
size_t len1, size_t len2 );
|
||||
int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_buf *ext, int tag );
|
||||
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
int mbedtls_x509_sig_alg_gets( char *buf, size_t size,
|
||||
mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
|
||||
const void *sig_opts );
|
||||
#endif
|
||||
int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name );
|
||||
int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name );
|
||||
int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
|
||||
int critical, const unsigned char *val,
|
||||
size_t val_len );
|
||||
int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
|
||||
mbedtls_asn1_named_data *first );
|
||||
int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
|
||||
mbedtls_asn1_named_data *first );
|
||||
int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
unsigned char *sig, size_t size );
|
||||
|
||||
#endif /* MBEDTLS_X509_INTERNAL_H */
|
|
@ -229,6 +229,103 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq )
|
||||
{
|
||||
while( seq != NULL )
|
||||
{
|
||||
mbedtls_asn1_sequence *next = seq->next;
|
||||
mbedtls_platform_zeroize( seq, sizeof( *seq ) );
|
||||
mbedtls_free( seq );
|
||||
seq = next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Traverse an ASN.1 "SEQUENCE OF <tag>"
|
||||
* and call a callback for each entry found.
|
||||
*/
|
||||
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 )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
/* Get main sequence tag */
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( *p + len != end )
|
||||
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
while( *p < end )
|
||||
{
|
||||
unsigned char const tag = *(*p)++;
|
||||
|
||||
if( ( tag & tag_must_mask ) != tag_must_val )
|
||||
return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_len( p, end, &len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( tag & tag_may_mask ) == tag_may_val )
|
||||
{
|
||||
if( cb != NULL )
|
||||
{
|
||||
ret = cb( ctx, tag, *p, len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
|
||||
*p += len;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int tag;
|
||||
mbedtls_asn1_sequence *cur;
|
||||
} asn1_get_sequence_of_cb_ctx_t;
|
||||
|
||||
static int asn1_get_sequence_of_cb( void *ctx,
|
||||
int tag,
|
||||
unsigned char *start,
|
||||
size_t len )
|
||||
{
|
||||
asn1_get_sequence_of_cb_ctx_t *cb_ctx =
|
||||
(asn1_get_sequence_of_cb_ctx_t *) ctx;
|
||||
mbedtls_asn1_sequence *cur =
|
||||
cb_ctx->cur;
|
||||
|
||||
if( cur->buf.p != NULL )
|
||||
{
|
||||
cur->next =
|
||||
mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
|
||||
|
||||
if( cur->next == NULL )
|
||||
return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
cur->buf.p = start;
|
||||
cur->buf.len = len;
|
||||
cur->buf.tag = tag;
|
||||
|
||||
cb_ctx->cur = cur;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
@ -239,49 +336,11 @@ int mbedtls_asn1_get_sequence_of( unsigned char **p,
|
|||
mbedtls_asn1_sequence *cur,
|
||||
int tag)
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
mbedtls_asn1_buf *buf;
|
||||
|
||||
/* Get main sequence tag */
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( *p + len != end )
|
||||
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
while( *p < end )
|
||||
{
|
||||
buf = &(cur->buf);
|
||||
buf->tag = **p;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
buf->p = *p;
|
||||
*p += buf->len;
|
||||
|
||||
/* Allocate and assign next pointer */
|
||||
if( *p < end )
|
||||
{
|
||||
cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1,
|
||||
sizeof( mbedtls_asn1_sequence ) );
|
||||
|
||||
if( cur->next == NULL )
|
||||
return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set final sequence entry's next pointer to NULL */
|
||||
cur->next = NULL;
|
||||
|
||||
if( *p != end )
|
||||
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
|
||||
memset( cur, 0, sizeof( mbedtls_asn1_sequence ) );
|
||||
return( mbedtls_asn1_traverse_sequence_of(
|
||||
p, end, 0xFF, tag, 0, 0,
|
||||
asn1_get_sequence_of_cb, &cb_ctx ) );
|
||||
}
|
||||
|
||||
int mbedtls_asn1_get_alg( unsigned char **p,
|
||||
|
@ -295,15 +354,12 @@ int mbedtls_asn1_get_alg( unsigned char **p,
|
|||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( end - *p ) < 1 )
|
||||
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
alg->tag = **p;
|
||||
end = *p + len;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
alg->tag = MBEDTLS_ASN1_OID;
|
||||
alg->p = *p;
|
||||
*p += alg->len;
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
|
|||
|
||||
if( X->n < nblimbs )
|
||||
{
|
||||
if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL )
|
||||
if( ( p = (mbedtls_mpi_uint *)mbedtls_calloc( nblimbs, ciL ) ) == NULL )
|
||||
return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
|
||||
|
||||
if( X->p != NULL )
|
||||
|
@ -169,7 +169,7 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
|
|||
if( i < nblimbs )
|
||||
i = nblimbs;
|
||||
|
||||
if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL )
|
||||
if( ( p = (mbedtls_mpi_uint *)mbedtls_calloc( i, ciL ) ) == NULL )
|
||||
return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
|
||||
|
||||
if( X->p != NULL )
|
||||
|
|
|
@ -331,13 +331,13 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
|
|||
? MBEDTLS_CHACHAPOLY_ENCRYPT
|
||||
: MBEDTLS_CHACHAPOLY_DECRYPT;
|
||||
|
||||
result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
|
||||
result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context *) ctx->cipher_ctx,
|
||||
ctx->iv,
|
||||
mode );
|
||||
if ( result != 0 )
|
||||
return( result );
|
||||
|
||||
return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
|
||||
return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context *) ctx->cipher_ctx,
|
||||
ad, ad_len ) );
|
||||
}
|
||||
#endif
|
||||
|
@ -391,7 +391,7 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
|
|||
if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
|
||||
{
|
||||
*olen = ilen;
|
||||
return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
|
||||
return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context *) ctx->cipher_ctx,
|
||||
ilen, input, output ) );
|
||||
}
|
||||
#endif
|
||||
|
@ -924,7 +924,7 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
|
|||
if ( tag_len != 16U )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
|
||||
return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context *) ctx->cipher_ctx,
|
||||
tag ) );
|
||||
}
|
||||
#endif
|
||||
|
@ -975,7 +975,7 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
|
|||
if ( tag_len != sizeof( check_tag ) )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
|
||||
ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context *) ctx->cipher_ctx,
|
||||
check_tag );
|
||||
if ( ret != 0 )
|
||||
{
|
||||
|
|
|
@ -1987,7 +1987,7 @@ static int chachapoly_setkey_wrap( void *ctx,
|
|||
if( key_bitlen != 256U )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context*)ctx, key ) )
|
||||
if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context *)ctx, key ) )
|
||||
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
|
||||
|
||||
return( 0 );
|
||||
|
|
|
@ -71,7 +71,7 @@ static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level,
|
|||
*/
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */
|
||||
mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", (void*)ssl, str );
|
||||
mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", (void *)ssl, str );
|
||||
ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, idstr );
|
||||
#else
|
||||
ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, str );
|
||||
|
@ -382,6 +382,8 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
|
|||
|
||||
while( crt != NULL )
|
||||
{
|
||||
int ret;
|
||||
mbedtls_pk_context *pk;
|
||||
char buf[1024];
|
||||
|
||||
mbedtls_snprintf( str, sizeof( str ), "%s #%d:\n", text, ++i );
|
||||
|
@ -390,7 +392,17 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
|
|||
mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
|
||||
debug_print_line_by_line( ssl, level, file, line, buf );
|
||||
|
||||
debug_print_pk( ssl, level, file, line, "crt->", &crt->pk );
|
||||
ret = mbedtls_x509_crt_pk_acquire( crt, &pk );
|
||||
if( ret != 0 )
|
||||
{
|
||||
mbedtls_snprintf( str, sizeof( str ),
|
||||
"mbedtls_x509_crt_pk_acquire() failed with -%#04x\n",
|
||||
-ret );
|
||||
debug_send_line( ssl, level, file, line, str );
|
||||
return;
|
||||
}
|
||||
debug_print_pk( ssl, level, file, line, "crt->", pk );
|
||||
mbedtls_x509_crt_pk_release( crt );
|
||||
|
||||
crt = crt->next;
|
||||
}
|
||||
|
|
|
@ -72,8 +72,8 @@
|
|||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#define read(fd,buf,len) recv( fd, (char*)( buf ), (int)( len ), 0 )
|
||||
#define write(fd,buf,len) send( fd, (char*)( buf ), (int)( len ), 0 )
|
||||
#define read(fd,buf,len) recv( fd, (char *)( buf ), (int)( len ), 0 )
|
||||
#define write(fd,buf,len) send( fd, (char *)( buf ), (int)( len ), 0 )
|
||||
#define close(fd) closesocket(fd)
|
||||
|
||||
static int wsa_init_done = 0;
|
||||
|
|
|
@ -2334,7 +2334,15 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
|
|||
peer_pk = &ssl->handshake->peer_pubkey;
|
||||
#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
if( ssl->session_negotiate->peer_cert != NULL )
|
||||
peer_pk = &ssl->session_negotiate->peer_cert->pk;
|
||||
{
|
||||
ret = mbedtls_x509_crt_pk_acquire( ssl->session_negotiate->peer_cert,
|
||||
&peer_pk );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret );
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
|
||||
if( peer_pk == NULL )
|
||||
|
@ -2350,7 +2358,8 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
|
|||
if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_RSA ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
|
||||
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
|
||||
ret = MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if( ( ret = mbedtls_pk_encrypt( peer_pk,
|
||||
|
@ -2360,7 +2369,7 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
|
|||
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret );
|
||||
return( ret );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
||||
|
@ -2373,11 +2382,16 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
|
|||
}
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
|
||||
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||
/* We don't need the peer's public key anymore. Free it. */
|
||||
mbedtls_pk_free( peer_pk );
|
||||
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
return( 0 );
|
||||
#else
|
||||
mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert );
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
|
||||
MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
|
||||
|
@ -2463,13 +2477,21 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
|
|||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
}
|
||||
peer_pk = &ssl->session_negotiate->peer_cert->pk;
|
||||
|
||||
ret = mbedtls_x509_crt_pk_acquire( ssl->session_negotiate->peer_cert,
|
||||
&peer_pk );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret );
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
|
||||
if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECKEY ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
|
||||
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
|
||||
ret = MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
peer_key = mbedtls_pk_ec( *peer_pk );
|
||||
|
@ -2478,21 +2500,26 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
|
|||
MBEDTLS_ECDH_THEIRS ) ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
|
||||
return( ret );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if( ssl_check_server_ecdh_params( ssl ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
|
||||
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||
/* We don't need the peer's public key anymore. Free it,
|
||||
* so that more RAM is available for upcoming expensive
|
||||
* operations like ECDHE. */
|
||||
mbedtls_pk_free( peer_pk );
|
||||
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
#else
|
||||
mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert );
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
@ -2799,7 +2826,14 @@ start_processing:
|
|||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
}
|
||||
peer_pk = &ssl->session_negotiate->peer_cert->pk;
|
||||
|
||||
ret = mbedtls_x509_crt_pk_acquire( ssl->session_negotiate->peer_cert,
|
||||
&peer_pk );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret );
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
|
||||
/*
|
||||
|
@ -2810,6 +2844,9 @@ start_processing:
|
|||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
|
||||
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
|
||||
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
|
||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||
mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert );
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
|
||||
}
|
||||
|
||||
|
@ -2831,6 +2868,9 @@ start_processing:
|
|||
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
|
||||
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||
mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert );
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
return( ret );
|
||||
}
|
||||
|
||||
|
@ -2839,7 +2879,9 @@ start_processing:
|
|||
* so that more RAM is available for upcoming expensive
|
||||
* operations like ECDHE. */
|
||||
mbedtls_pk_free( peer_pk );
|
||||
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
#else
|
||||
mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert );
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
|
||||
|
||||
|
|
|
@ -791,15 +791,58 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
|
|||
|
||||
for( cur = list; cur != NULL; cur = cur->next )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
|
||||
cur->cert );
|
||||
int match = 1;
|
||||
mbedtls_pk_context *pk;
|
||||
|
||||
if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) )
|
||||
/* WARNING: With the current X.509 caching architecture, this MUST
|
||||
* happen outside of the PK acquire/release block, because it moves
|
||||
* the cached PK context. In a threading-enabled build, this would
|
||||
* rightfully fail, but lead to a use-after-free otherwise. */
|
||||
MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
|
||||
cur->cert );
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
/* ASYNC_PRIVATE may use a NULL entry for the opaque private key, so
|
||||
* we have to use the public key context to infer the capabilities
|
||||
* of the key. */
|
||||
{
|
||||
int ret;
|
||||
ret = mbedtls_x509_crt_pk_acquire( cur->cert, &pk );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret );
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Outside of ASYNC_PRIVATE, use private key context directly
|
||||
* instead of querying for the public key context from the
|
||||
* certificate, so save a few bytes of code. */
|
||||
pk = cur->key;
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
if( ! mbedtls_pk_can_do( pk, pk_alg ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) );
|
||||
continue;
|
||||
match = 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_C)
|
||||
if( pk_alg == MBEDTLS_PK_ECDSA &&
|
||||
ssl_check_key_curve( pk, ssl->handshake->curves ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) );
|
||||
match = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
mbedtls_x509_crt_pk_release( cur->cert );
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
if( match == 0 )
|
||||
continue;
|
||||
|
||||
/*
|
||||
* This avoids sending the client a cert it'll reject based on
|
||||
* keyUsage or other extensions.
|
||||
|
@ -816,31 +859,42 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
|
|||
continue;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_C)
|
||||
if( pk_alg == MBEDTLS_PK_ECDSA &&
|
||||
ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) );
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_1)
|
||||
/*
|
||||
* Try to select a SHA-1 certificate for pre-1.2 clients, but still
|
||||
* present them a SHA-higher cert rather than failing if it's the only
|
||||
* one we got that satisfies the other conditions.
|
||||
*/
|
||||
if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 &&
|
||||
cur->cert->sig_md != MBEDTLS_MD_SHA1 )
|
||||
if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
|
||||
{
|
||||
if( fallback == NULL )
|
||||
fallback = cur;
|
||||
mbedtls_md_type_t sig_md;
|
||||
{
|
||||
int ret;
|
||||
mbedtls_x509_crt_frame const *frame;
|
||||
ret = mbedtls_x509_crt_frame_acquire( cur->cert, &frame );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_frame_acquire", ret );
|
||||
return( ret );
|
||||
}
|
||||
sig_md = frame->sig_md;
|
||||
mbedtls_x509_crt_frame_release( cur->cert );
|
||||
}
|
||||
|
||||
if( sig_md != MBEDTLS_MD_SHA1 )
|
||||
{
|
||||
if( fallback == NULL )
|
||||
fallback = cur;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate not preferred: "
|
||||
"sha-2 with pre-TLS 1.2 client" ) );
|
||||
continue;
|
||||
"sha-2 with pre-TLS 1.2 client" ) );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1 ||
|
||||
MBEDTLS_SSL_PROTO_TLS1_1 ||
|
||||
MBEDTLS_SSL_PROTO_SSL3 */
|
||||
|
||||
/* If we get there, we got a winner */
|
||||
break;
|
||||
|
@ -2953,26 +3007,38 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
|
|||
#endif
|
||||
crt = ssl->conf->ca_chain;
|
||||
|
||||
while( crt != NULL && crt->version != 0 )
|
||||
while( crt != NULL && crt->raw.p != NULL )
|
||||
{
|
||||
dn_size = crt->subject_raw.len;
|
||||
mbedtls_x509_crt_frame const *frame;
|
||||
ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_frame_acquire", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
dn_size = frame->subject_raw.len;
|
||||
|
||||
if( end < p ||
|
||||
(size_t)( end - p ) < dn_size ||
|
||||
(size_t)( end - p ) < 2 + dn_size )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) );
|
||||
mbedtls_x509_crt_frame_release( crt );
|
||||
break;
|
||||
}
|
||||
|
||||
*p++ = (unsigned char)( dn_size >> 8 );
|
||||
*p++ = (unsigned char)( dn_size );
|
||||
memcpy( p, crt->subject_raw.p, dn_size );
|
||||
memcpy( p, frame->subject_raw.p, dn_size );
|
||||
p += dn_size;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "requested DN", p - dn_size, dn_size );
|
||||
|
||||
total_dn_size += 2 + dn_size;
|
||||
|
||||
mbedtls_x509_crt_frame_release( crt );
|
||||
|
||||
crt = crt->next;
|
||||
}
|
||||
}
|
||||
|
@ -3614,9 +3680,8 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
|
|||
size_t peer_pmssize )
|
||||
{
|
||||
int ret;
|
||||
size_t len = (size_t)( end - p ); /* Cast is safe because p <= end. */
|
||||
mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl );
|
||||
mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk;
|
||||
size_t len = mbedtls_pk_get_len( public_key );
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
/* If we have already started decoding the message and there is an ongoing
|
||||
|
@ -3634,12 +3699,17 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
|
|||
*/
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#if defined(MBEDTLS_SSL_PROTO_SSL3)
|
||||
if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
|
||||
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
|
||||
{
|
||||
if ( p + 2 > end ) {
|
||||
if( len < 2 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
|
||||
}
|
||||
len -= 2;
|
||||
|
||||
if( *p++ != ( ( len >> 8 ) & 0xFF ) ||
|
||||
*p++ != ( ( len ) & 0xFF ) )
|
||||
{
|
||||
|
@ -3649,12 +3719,6 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
|
|||
}
|
||||
#endif
|
||||
|
||||
if( p + len != end )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrypt the premaster secret
|
||||
*/
|
||||
|
@ -4194,7 +4258,15 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
|
|||
peer_pk = &ssl->handshake->peer_pubkey;
|
||||
#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
if( ssl->session_negotiate->peer_cert != NULL )
|
||||
peer_pk = &ssl->session_negotiate->peer_cert->pk;
|
||||
{
|
||||
ret = mbedtls_x509_crt_pk_acquire( ssl->session_negotiate->peer_cert,
|
||||
&peer_pk );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret );
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
|
||||
if( peer_pk == NULL )
|
||||
|
@ -4209,7 +4281,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
|
|||
if( 0 != ret )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record" ), ret );
|
||||
return( ret );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ssl->state++;
|
||||
|
@ -4219,7 +4291,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
|
|||
ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
||||
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
i = mbedtls_ssl_hs_hdr_len( ssl );
|
||||
|
@ -4254,7 +4327,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
|
|||
if( i + 2 > ssl->in_hslen )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
||||
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4266,7 +4340,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
|
|||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
|
||||
" for verify message" ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
||||
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_MD_SHA1)
|
||||
|
@ -4287,7 +4362,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
|
|||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
|
||||
" for verify message" ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
||||
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4296,7 +4372,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
|
|||
if( !mbedtls_pk_can_do( peer_pk, pk_alg ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
||||
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
@ -4311,7 +4388,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
|
|||
if( i + 2 > ssl->in_hslen )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
||||
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sig_len = ( ssl->in_msg[i] << 8 ) | ssl->in_msg[i+1];
|
||||
|
@ -4320,7 +4398,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
|
|||
if( i + sig_len != ssl->in_hslen )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
||||
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Calculate hash and verify signature */
|
||||
|
@ -4334,13 +4413,19 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
|
|||
ssl->in_msg + i, sig_len ) ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
|
||||
return( ret );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mbedtls_ssl_update_handshake_status( ssl );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) );
|
||||
|
||||
exit:
|
||||
|
||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||
mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert );
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
|
||||
|
|
|
@ -6456,6 +6456,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
|
|||
void *rs_ctx )
|
||||
{
|
||||
int ret = 0;
|
||||
int verify_ret;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
|
||||
ssl->handshake->ciphersuite_info;
|
||||
mbedtls_x509_crt *ca_chain;
|
||||
|
@ -6480,7 +6481,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
|
|||
/*
|
||||
* Main check: verify certificate
|
||||
*/
|
||||
ret = mbedtls_x509_crt_verify_restartable(
|
||||
verify_ret = mbedtls_x509_crt_verify_restartable(
|
||||
chain,
|
||||
ca_chain, ca_crl,
|
||||
ssl->conf->cert_profile,
|
||||
|
@ -6488,13 +6489,13 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
|
|||
&ssl->session_negotiate->verify_result,
|
||||
ssl->conf->f_vrfy, ssl->conf->p_vrfy, rs_ctx );
|
||||
|
||||
if( ret != 0 )
|
||||
if( verify_ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", verify_ret );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
|
||||
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
|
||||
if( verify_ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
|
||||
return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS );
|
||||
#endif
|
||||
|
||||
|
@ -6504,29 +6505,40 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
|
|||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
{
|
||||
const mbedtls_pk_context *pk = &chain->pk;
|
||||
mbedtls_pk_context *pk;
|
||||
ret = mbedtls_x509_crt_pk_acquire( chain, &pk );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* If certificate uses an EC key, make sure the curve is OK */
|
||||
if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
|
||||
mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
|
||||
if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) )
|
||||
ret = mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id );
|
||||
|
||||
mbedtls_x509_crt_pk_release( chain );
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
|
||||
if( ret == 0 )
|
||||
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
|
||||
if( verify_ret == 0 )
|
||||
verify_ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
|
||||
if( mbedtls_ssl_check_cert_usage( chain,
|
||||
ciphersuite_info,
|
||||
! ssl->conf->endpoint,
|
||||
&ssl->session_negotiate->verify_result ) != 0 )
|
||||
ret = mbedtls_ssl_check_cert_usage( chain,
|
||||
ciphersuite_info,
|
||||
! ssl->conf->endpoint,
|
||||
&ssl->session_negotiate->verify_result );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
|
||||
if( ret == 0 )
|
||||
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
|
||||
if( verify_ret == 0 )
|
||||
verify_ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
|
||||
}
|
||||
|
||||
/* mbedtls_x509_crt_verify_with_profile is supposed to report a
|
||||
|
@ -6536,19 +6548,19 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
|
|||
* functions, are treated as fatal and lead to a failure of
|
||||
* ssl_parse_certificate even if verification was optional. */
|
||||
if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
|
||||
( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
|
||||
ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
|
||||
( verify_ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
|
||||
verify_ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
|
||||
{
|
||||
ret = 0;
|
||||
verify_ret = 0;
|
||||
}
|
||||
|
||||
if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
|
||||
ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
|
||||
verify_ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
|
||||
}
|
||||
|
||||
if( ret != 0 )
|
||||
if( verify_ret != 0 )
|
||||
{
|
||||
uint8_t alert;
|
||||
|
||||
|
@ -6593,7 +6605,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
|
|||
}
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
|
||||
return( ret );
|
||||
return( verify_ret );
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||
|
@ -6760,8 +6772,8 @@ crt_verify:
|
|||
crt_len = chain->raw.len;
|
||||
#endif /* MBEDTLS_SSL_RENEGOTIATION */
|
||||
|
||||
pk_start = chain->pk_raw.p;
|
||||
pk_len = chain->pk_raw.len;
|
||||
pk_start = chain->cache->pk_raw.p;
|
||||
pk_len = chain->cache->pk_raw.len;
|
||||
|
||||
/* Free the CRT structures before computing
|
||||
* digest and copying the peer's public key. */
|
||||
|
|
|
@ -534,6 +534,12 @@ static const char *features[] = {
|
|||
#if defined(MBEDTLS_VERSION_FEATURES)
|
||||
"MBEDTLS_VERSION_FEATURES",
|
||||
#endif /* MBEDTLS_VERSION_FEATURES */
|
||||
#if defined(MBEDTLS_X509_ON_DEMAND_PARSING)
|
||||
"MBEDTLS_X509_ON_DEMAND_PARSING",
|
||||
#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */
|
||||
#if defined(MBEDTLS_X509_ALWAYS_FLUSH)
|
||||
"MBEDTLS_X509_ALWAYS_FLUSH",
|
||||
#endif /* MBEDTLS_X509_ALWAYS_FLUSH */
|
||||
#if defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
|
||||
"MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3",
|
||||
#endif /* MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 */
|
||||
|
|
378
library/x509.c
378
library/x509.c
|
@ -38,6 +38,7 @@
|
|||
#if defined(MBEDTLS_X509_USE_C)
|
||||
|
||||
#include "mbedtls/x509.h"
|
||||
#include "mbedtls/x509_internal.h"
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "mbedtls/oid.h"
|
||||
|
||||
|
@ -347,64 +348,59 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
|
|||
* AttributeType ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* AttributeValue ::= ANY DEFINED BY AttributeType
|
||||
*
|
||||
* NOTE: This function returns an ASN.1 low-level error code.
|
||||
*/
|
||||
static int x509_get_attr_type_value( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_x509_name *cur )
|
||||
mbedtls_x509_buf *oid,
|
||||
mbedtls_x509_buf *val )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
mbedtls_x509_buf *oid;
|
||||
mbedtls_x509_buf *val;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||
return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
|
||||
ret = mbedtls_asn1_get_tag( p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
end = *p + len;
|
||||
|
||||
if( ( end - *p ) < 1 )
|
||||
return( MBEDTLS_ERR_X509_INVALID_NAME +
|
||||
MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
oid = &cur->oid;
|
||||
oid->tag = **p;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 )
|
||||
return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
|
||||
ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
oid->tag = MBEDTLS_ASN1_OID;
|
||||
oid->p = *p;
|
||||
*p += oid->len;
|
||||
|
||||
if( ( end - *p ) < 1 )
|
||||
return( MBEDTLS_ERR_X509_INVALID_NAME +
|
||||
MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
if( *p == end )
|
||||
{
|
||||
ret = MBEDTLS_ERR_ASN1_OUT_OF_DATA;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING &&
|
||||
**p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
|
||||
**p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
|
||||
**p != MBEDTLS_ASN1_BIT_STRING )
|
||||
return( MBEDTLS_ERR_X509_INVALID_NAME +
|
||||
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
|
||||
if( !MBEDTLS_ASN1_IS_STRING_TAG( **p ) )
|
||||
{
|
||||
ret = MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
val = &cur->val;
|
||||
val->tag = *(*p)++;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 )
|
||||
return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
|
||||
ret = mbedtls_asn1_get_len( p, end, &val->len );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
val->p = *p;
|
||||
*p += val->len;
|
||||
|
||||
if( *p != end )
|
||||
{
|
||||
return( MBEDTLS_ERR_X509_INVALID_NAME +
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||
}
|
||||
ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
|
||||
|
||||
cur->next = NULL;
|
||||
|
||||
return( 0 );
|
||||
exit:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -429,58 +425,235 @@ static int x509_get_attr_type_value( unsigned char **p,
|
|||
* For the general case we still use a flat list, but we mark elements of the
|
||||
* same set so that they are "merged" together in the functions that consume
|
||||
* this list, eg mbedtls_x509_dn_gets().
|
||||
*
|
||||
* NOTE: This function returns an ASN.1 low-level error code.
|
||||
*/
|
||||
int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_name *cur )
|
||||
static int x509_set_sequence_iterate( unsigned char **p,
|
||||
unsigned char const **end_set,
|
||||
unsigned char const *end,
|
||||
mbedtls_x509_buf *oid,
|
||||
mbedtls_x509_buf *val )
|
||||
{
|
||||
int ret;
|
||||
size_t set_len;
|
||||
const unsigned char *end_set;
|
||||
|
||||
/* don't use recursion, we'd risk stack overflow if not optimized */
|
||||
while( 1 )
|
||||
if( *p == *end_set )
|
||||
{
|
||||
/*
|
||||
* parse SET
|
||||
*/
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 )
|
||||
return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
|
||||
/* Parse next TLV of ASN.1 SET structure. */
|
||||
ret = mbedtls_asn1_get_tag( p, end, &set_len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SET );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
end_set = *p + set_len;
|
||||
*end_set = *p + set_len;
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
/* x509_get_attr_type_value() returns ASN.1 low-level error codes. */
|
||||
ret = x509_get_attr_type_value( p, *end_set, oid, val );
|
||||
|
||||
exit:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Like memcmp, but case-insensitive and always returns -1 if different
|
||||
*/
|
||||
int mbedtls_x509_memcasecmp( const void *s1, const void *s2,
|
||||
size_t len1, size_t len2 )
|
||||
{
|
||||
size_t i;
|
||||
unsigned char diff;
|
||||
const unsigned char *n1 = s1, *n2 = s2;
|
||||
|
||||
if( len1 != len2 )
|
||||
return( -1 );
|
||||
|
||||
for( i = 0; i < len1; i++ )
|
||||
{
|
||||
diff = n1[i] ^ n2[i];
|
||||
|
||||
if( diff == 0 )
|
||||
continue;
|
||||
|
||||
if( diff == 32 &&
|
||||
( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
|
||||
( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
|
||||
{
|
||||
if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( *p == end_set )
|
||||
break;
|
||||
|
||||
/* Mark this item as being no the only one in a set */
|
||||
cur->next_merged = 1;
|
||||
|
||||
cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
|
||||
|
||||
if( cur->next == NULL )
|
||||
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
|
||||
|
||||
cur = cur->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* continue until end of SEQUENCE is reached
|
||||
*/
|
||||
if( *p == end )
|
||||
return( 0 );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare two X.509 strings, case-insensitive, and allowing for some encoding
|
||||
* variations (but not all).
|
||||
*
|
||||
* Return 0 if equal, -1 otherwise.
|
||||
*/
|
||||
static int x509_string_cmp( const mbedtls_x509_buf *a,
|
||||
const mbedtls_x509_buf *b )
|
||||
{
|
||||
if( a->tag == b->tag &&
|
||||
a->len == b->len &&
|
||||
memcmp( a->p, b->p, b->len ) == 0 )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
|
||||
( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
|
||||
mbedtls_x509_memcasecmp( a->p, b->p,
|
||||
a->len, b->len ) == 0 )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare two X.509 Names (aka rdnSequence) given as raw ASN.1 data.
|
||||
*
|
||||
* See RFC 5280 section 7.1, though we don't implement the whole algorithm:
|
||||
* We sometimes return unequal when the full algorithm would return equal,
|
||||
* but never the other way. (In particular, we don't do Unicode normalisation
|
||||
* or space folding.)
|
||||
*
|
||||
* Further, this function allows to pass a callback to be triggered for every
|
||||
* pair of well-formed and equal entries in the two input name lists.
|
||||
*
|
||||
* Returns:
|
||||
* - 0 if both sequences are well-formed, present the same X.509 name,
|
||||
* and the callback (if provided) hasn't returned a non-zero value
|
||||
* on any of the name components.
|
||||
* - 1 if a difference was detected in the name components.
|
||||
* - A non-zero error code if the abort callback returns a non-zero value.
|
||||
* In this case, the returned error code is the error code from the callback.
|
||||
* - A negative error code if a parsing error occurred in either
|
||||
* of the two buffers.
|
||||
*
|
||||
* This function can be used to verify that a buffer contains a well-formed
|
||||
* ASN.1 encoded X.509 name by calling it with equal parameters.
|
||||
*/
|
||||
int mbedtls_x509_name_cmp_raw( mbedtls_x509_buf_raw const *a,
|
||||
mbedtls_x509_buf_raw const *b,
|
||||
int (*abort_check)( void *ctx,
|
||||
mbedtls_x509_buf *oid,
|
||||
mbedtls_x509_buf *val,
|
||||
int next_merged ),
|
||||
void *abort_check_ctx )
|
||||
{
|
||||
int ret;
|
||||
size_t idx;
|
||||
unsigned char *p[2], *end[2], *set[2];
|
||||
|
||||
p[0] = a->p;
|
||||
p[1] = b->p;
|
||||
end[0] = p[0] + a->len;
|
||||
end[1] = p[1] + b->len;
|
||||
|
||||
for( idx = 0; idx < 2; idx++ )
|
||||
{
|
||||
size_t len;
|
||||
ret = mbedtls_asn1_get_tag( &p[idx], end[idx], &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE );
|
||||
|
||||
if( end[idx] != p[idx] + len )
|
||||
{
|
||||
return( MBEDTLS_ERR_X509_INVALID_NAME +
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||
}
|
||||
|
||||
set[idx] = p[idx];
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
int next_merged;
|
||||
mbedtls_x509_buf oid[2], val[2];
|
||||
|
||||
ret = x509_set_sequence_iterate( &p[0], (const unsigned char **) &set[0],
|
||||
end[0], &oid[0], &val[0] );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
ret = x509_set_sequence_iterate( &p[1], (const unsigned char **) &set[1],
|
||||
end[1], &oid[1], &val[1] );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
if( oid[0].len != oid[1].len ||
|
||||
memcmp( oid[0].p, oid[1].p, oid[1].len ) != 0 )
|
||||
{
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if( x509_string_cmp( &val[0], &val[1] ) != 0 )
|
||||
return( 1 );
|
||||
|
||||
next_merged = ( set[0] != p[0] );
|
||||
if( next_merged != ( set[1] != p[1] ) )
|
||||
return( 1 );
|
||||
|
||||
if( abort_check != NULL )
|
||||
{
|
||||
ret = abort_check( abort_check_ctx, &oid[0], &val[0],
|
||||
next_merged );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( p[0] == end[0] && p[1] == end[1] )
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
if( ret < 0 )
|
||||
ret += MBEDTLS_ERR_X509_INVALID_NAME;
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
static int x509_get_name_cb( void *ctx,
|
||||
mbedtls_x509_buf *oid,
|
||||
mbedtls_x509_buf *val,
|
||||
int next_merged )
|
||||
{
|
||||
mbedtls_x509_name **cur_ptr = (mbedtls_x509_name**) ctx;
|
||||
mbedtls_x509_name *cur = *cur_ptr;
|
||||
|
||||
if( cur->oid.p != NULL )
|
||||
{
|
||||
cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
|
||||
|
||||
if( cur->next == NULL )
|
||||
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
|
||||
return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
cur->oid = *oid;
|
||||
cur->val = *val;
|
||||
cur->next_merged = next_merged;
|
||||
|
||||
*cur_ptr = cur;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_x509_get_name( unsigned char *p,
|
||||
size_t len,
|
||||
mbedtls_x509_name *cur )
|
||||
{
|
||||
mbedtls_x509_buf_raw name_buf = { p, len };
|
||||
memset( cur, 0, sizeof( mbedtls_x509_name ) );
|
||||
return( mbedtls_x509_name_cmp_raw( &name_buf, &name_buf,
|
||||
x509_get_name_cb,
|
||||
&cur ) );
|
||||
}
|
||||
|
||||
static int x509_parse_int( unsigned char **p, size_t n, int *res )
|
||||
|
@ -655,6 +828,21 @@ int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_x509_get_sig_alg_raw( unsigned char **p, unsigned char const *end,
|
||||
mbedtls_md_type_t *md_alg,
|
||||
mbedtls_pk_type_t *pk_alg,
|
||||
void **sig_opts )
|
||||
{
|
||||
int ret;
|
||||
mbedtls_asn1_buf alg, params;
|
||||
ret = mbedtls_asn1_get_alg( p, end, &alg, ¶ms );
|
||||
if( ret != 0 )
|
||||
return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
|
||||
|
||||
return( mbedtls_x509_get_sig_alg( &alg, ¶ms, md_alg,
|
||||
pk_alg, sig_opts ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Get signature algorithm from alg OID and optional parameters
|
||||
*/
|
||||
|
@ -664,9 +852,6 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50
|
|||
{
|
||||
int ret;
|
||||
|
||||
if( *sig_opts != NULL )
|
||||
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
|
||||
|
||||
if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
|
||||
return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret );
|
||||
|
||||
|
@ -689,7 +874,10 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50
|
|||
return( ret );
|
||||
}
|
||||
|
||||
*sig_opts = (void *) pss_opts;
|
||||
if( sig_opts != NULL )
|
||||
*sig_opts = (void *) pss_opts;
|
||||
else
|
||||
mbedtls_free( pss_opts );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
|
||||
|
@ -697,7 +885,10 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50
|
|||
/* Make sure parameters are absent or NULL */
|
||||
if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) ||
|
||||
sig_params->len != 0 )
|
||||
return( MBEDTLS_ERR_X509_INVALID_ALG );
|
||||
return( MBEDTLS_ERR_X509_INVALID_ALG );
|
||||
|
||||
if( sig_opts != NULL )
|
||||
*sig_opts = NULL;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
|
@ -840,20 +1031,34 @@ int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *se
|
|||
/*
|
||||
* Helper for writing signature algorithms
|
||||
*/
|
||||
int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
|
||||
mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
|
||||
const void *sig_opts )
|
||||
int mbedtls_x509_sig_alg_gets( char *buf, size_t size, mbedtls_pk_type_t pk_alg,
|
||||
mbedtls_md_type_t md_alg, const void *sig_opts )
|
||||
{
|
||||
int ret;
|
||||
char *p = buf;
|
||||
size_t n = size;
|
||||
const char *desc = NULL;
|
||||
mbedtls_x509_buf sig_oid;
|
||||
mbedtls_md_type_t tmp_md_alg = md_alg;
|
||||
|
||||
ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc );
|
||||
if( ret != 0 )
|
||||
ret = mbedtls_snprintf( p, n, "???" );
|
||||
else
|
||||
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
|
||||
/* The hash for RSASSA is determined by the algorithm parameters;
|
||||
* in the OID list, the hash is set to MBEDTLS_MD_NONE. */
|
||||
if( pk_alg == MBEDTLS_PK_RSASSA_PSS )
|
||||
tmp_md_alg = MBEDTLS_MD_NONE;
|
||||
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
|
||||
|
||||
sig_oid.tag = MBEDTLS_ASN1_OID;
|
||||
ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, tmp_md_alg,
|
||||
(const char**) &sig_oid.p,
|
||||
&sig_oid.len );
|
||||
if( ret == 0 &&
|
||||
mbedtls_oid_get_sig_alg_desc( &sig_oid, &desc ) == 0 )
|
||||
{
|
||||
ret = mbedtls_snprintf( p, n, "%s", desc );
|
||||
}
|
||||
else
|
||||
ret = mbedtls_snprintf( p, n, "???" );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
|
||||
|
@ -1003,6 +1208,17 @@ int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
|
|||
}
|
||||
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
||||
|
||||
void mbedtls_x509_name_free( mbedtls_x509_name *name )
|
||||
{
|
||||
while( name != NULL )
|
||||
{
|
||||
mbedtls_x509_name *next = name->next;
|
||||
mbedtls_platform_zeroize( name, sizeof( *name ) );
|
||||
mbedtls_free( name );
|
||||
name = next;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
#include "mbedtls/x509_crt.h"
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#if defined(MBEDTLS_X509_CREATE_C)
|
||||
|
||||
#include "mbedtls/x509.h"
|
||||
#include "mbedtls/x509_internal.h"
|
||||
#include "mbedtls/asn1write.h"
|
||||
#include "mbedtls/oid.h"
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#if defined(MBEDTLS_X509_CRL_PARSE_C)
|
||||
|
||||
#include "mbedtls/x509_crl.h"
|
||||
#include "mbedtls/x509_internal.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
|
@ -428,15 +429,17 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
|
|||
mbedtls_x509_crl_free( crl );
|
||||
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
|
||||
}
|
||||
p += len;
|
||||
crl->issuer_raw.len = p - crl->issuer_raw.p;
|
||||
|
||||
if( ( ret = mbedtls_x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
|
||||
if( ( ret = mbedtls_x509_get_name( crl->issuer_raw.p,
|
||||
crl->issuer_raw.len,
|
||||
&crl->issuer ) ) != 0 )
|
||||
{
|
||||
mbedtls_x509_crl_free( crl );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
crl->issuer_raw.len = p - crl->issuer_raw.p;
|
||||
|
||||
/*
|
||||
* thisUpdate Time
|
||||
* nextUpdate Time OPTIONAL
|
||||
|
@ -690,8 +693,8 @@ int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix,
|
|||
ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_x509_sig_alg_gets( p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md,
|
||||
crl->sig_opts );
|
||||
ret = mbedtls_x509_sig_alg_gets( p, n, crl->sig_pk,
|
||||
crl->sig_md, crl->sig_opts );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_snprintf( p, n, "\n" );
|
||||
|
|
2508
library/x509_crt.c
2508
library/x509_crt.c
File diff suppressed because it is too large
Load diff
|
@ -38,6 +38,7 @@
|
|||
#if defined(MBEDTLS_X509_CSR_PARSE_C)
|
||||
|
||||
#include "mbedtls/x509_csr.h"
|
||||
#include "mbedtls/x509_internal.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
|
@ -183,15 +184,17 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
|
|||
mbedtls_x509_csr_free( csr );
|
||||
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
|
||||
}
|
||||
p += len;
|
||||
csr->subject_raw.len = p - csr->subject_raw.p;
|
||||
|
||||
if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
|
||||
if( ( ret = mbedtls_x509_get_name( csr->subject_raw.p,
|
||||
csr->subject_raw.len,
|
||||
&csr->subject ) ) != 0 )
|
||||
{
|
||||
mbedtls_x509_csr_free( csr );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
csr->subject_raw.len = p - csr->subject_raw.p;
|
||||
|
||||
/*
|
||||
* subjectPKInfo SubjectPublicKeyInfo
|
||||
*/
|
||||
|
@ -357,8 +360,8 @@ int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
|
|||
ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
|
||||
csr->sig_opts );
|
||||
ret = mbedtls_x509_sig_alg_gets( p, n, csr->sig_pk,
|
||||
csr->sig_md, csr->sig_opts );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#if defined(MBEDTLS_X509_CRT_WRITE_C)
|
||||
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include "mbedtls/x509_internal.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/asn1write.h"
|
||||
#include "mbedtls/sha1.h"
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#if defined(MBEDTLS_X509_CSR_WRITE_C)
|
||||
|
||||
#include "mbedtls/x509_csr.h"
|
||||
#include "mbedtls/x509_internal.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/asn1write.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
|
|
@ -1466,6 +1466,22 @@ int query_config( const char *config )
|
|||
}
|
||||
#endif /* MBEDTLS_VERSION_FEATURES */
|
||||
|
||||
#if defined(MBEDTLS_X509_ON_DEMAND_PARSING)
|
||||
if( strcmp( "MBEDTLS_X509_ON_DEMAND_PARSING", config ) == 0 )
|
||||
{
|
||||
MACRO_EXPANSION_TO_STR( MBEDTLS_X509_ON_DEMAND_PARSING );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */
|
||||
|
||||
#if defined(MBEDTLS_X509_ALWAYS_FLUSH)
|
||||
if( strcmp( "MBEDTLS_X509_ALWAYS_FLUSH", config ) == 0 )
|
||||
{
|
||||
MACRO_EXPANSION_TO_STR( MBEDTLS_X509_ALWAYS_FLUSH );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_X509_ALWAYS_FLUSH */
|
||||
|
||||
#if defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
|
||||
if( strcmp( "MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3", config ) == 0 )
|
||||
{
|
||||
|
|
|
@ -1067,6 +1067,7 @@ static int ssl_async_start( mbedtls_ssl_context *ssl,
|
|||
const unsigned char *input,
|
||||
size_t input_len )
|
||||
{
|
||||
int ret;
|
||||
ssl_async_key_context_t *config_data =
|
||||
mbedtls_ssl_conf_get_async_config_data( ssl->conf );
|
||||
unsigned slot;
|
||||
|
@ -1075,9 +1076,17 @@ static int ssl_async_start( mbedtls_ssl_context *ssl,
|
|||
|
||||
{
|
||||
char dn[100];
|
||||
if( mbedtls_x509_dn_gets( dn, sizeof( dn ), &cert->subject ) > 0 )
|
||||
mbedtls_x509_name *subject;
|
||||
|
||||
ret = mbedtls_x509_crt_get_subject( cert, &subject );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
if( mbedtls_x509_dn_gets( dn, sizeof( dn ), subject ) > 0 )
|
||||
mbedtls_printf( "Async %s callback: looking for DN=%s\n",
|
||||
op_name, dn );
|
||||
|
||||
mbedtls_x509_name_free( subject );
|
||||
}
|
||||
|
||||
/* Look for a private key that matches the public key in cert.
|
||||
|
@ -1086,8 +1095,14 @@ static int ssl_async_start( mbedtls_ssl_context *ssl,
|
|||
* public key. */
|
||||
for( slot = 0; slot < config_data->slots_used; slot++ )
|
||||
{
|
||||
if( mbedtls_pk_check_pair( &cert->pk,
|
||||
config_data->slots[slot].pk ) == 0 )
|
||||
mbedtls_pk_context *pk;
|
||||
int match;
|
||||
ret = mbedtls_x509_crt_pk_acquire( cert, &pk );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
match = mbedtls_pk_check_pair( pk, config_data->slots[slot].pk );
|
||||
mbedtls_x509_crt_pk_release( cert );
|
||||
if( match == 0 )
|
||||
break;
|
||||
}
|
||||
if( slot == config_data->slots_used )
|
||||
|
|
|
@ -524,6 +524,8 @@ int main( int argc, char *argv[] )
|
|||
//
|
||||
if( !opt.selfsign && strlen( opt.issuer_crt ) )
|
||||
{
|
||||
mbedtls_x509_name *subject;
|
||||
|
||||
/*
|
||||
* 1.0.a. Load the certificates
|
||||
*/
|
||||
|
@ -538,8 +540,17 @@ int main( int argc, char *argv[] )
|
|||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509_crt_get_subject( &issuer_crt, &subject );
|
||||
if( ret != 0 )
|
||||
{
|
||||
mbedtls_strerror( ret, buf, 1024 );
|
||||
mbedtls_printf( " failed\n ! mbedtls_x509_crt_get_subject "
|
||||
"returned -0x%04x - %s\n\n", -ret, buf );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509_dn_gets( issuer_name, sizeof(issuer_name),
|
||||
&issuer_crt.subject );
|
||||
subject );
|
||||
if( ret < 0 )
|
||||
{
|
||||
mbedtls_strerror( ret, buf, 1024 );
|
||||
|
@ -550,6 +561,8 @@ int main( int argc, char *argv[] )
|
|||
|
||||
opt.issuer_name = issuer_name;
|
||||
|
||||
mbedtls_x509_name_free( subject );
|
||||
|
||||
mbedtls_printf( " ok\n" );
|
||||
}
|
||||
|
||||
|
@ -627,12 +640,24 @@ int main( int argc, char *argv[] )
|
|||
//
|
||||
if( strlen( opt.issuer_crt ) )
|
||||
{
|
||||
if( mbedtls_pk_check_pair( &issuer_crt.pk, issuer_key ) != 0 )
|
||||
mbedtls_pk_context pk;
|
||||
ret = mbedtls_x509_crt_get_pk( &issuer_crt, &pk );
|
||||
if( ret != 0 )
|
||||
{
|
||||
mbedtls_strerror( ret, buf, 1024 );
|
||||
mbedtls_printf( " failed\n ! mbedtls_x509_crt_get_pk "
|
||||
"returned -0x%04x - %s\n\n", -ret, buf );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( mbedtls_pk_check_pair( &pk, issuer_key ) != 0 )
|
||||
{
|
||||
mbedtls_printf( " failed\n ! issuer_key does not match "
|
||||
"issuer certificate\n\n" );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mbedtls_pk_free( &pk );
|
||||
}
|
||||
|
||||
mbedtls_printf( " ok\n" );
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
option(LINK_WITH_PTHREAD "Explicitly link mbed TLS library to pthread." OFF)
|
||||
|
||||
set(libs
|
||||
mbedtls
|
||||
)
|
||||
|
@ -10,6 +12,10 @@ if(ENABLE_ZLIB_SUPPORT)
|
|||
set(libs ${libs} ${ZLIB_LIBRARIES})
|
||||
endif(ENABLE_ZLIB_SUPPORT)
|
||||
|
||||
if(LINK_WITH_PTHREAD)
|
||||
set(libs ${libs} pthread)
|
||||
endif(LINK_WITH_PTHREAD)
|
||||
|
||||
find_package(Perl)
|
||||
if(NOT PERL_FOUND)
|
||||
message(FATAL_ERROR "Cannot build test suites without Perl")
|
||||
|
|
|
@ -53,11 +53,20 @@ ifdef ZLIB
|
|||
LOCAL_LDFLAGS += -lz
|
||||
endif
|
||||
|
||||
# Pthread shared library extension
|
||||
ifdef PTHREAD
|
||||
LOCAL_LDFLAGS += -lpthread
|
||||
endif
|
||||
|
||||
# A test application is built for each suites/test_suite_*.data file.
|
||||
# Application name is same as .data file's base name and can be
|
||||
# constructed by stripping path 'suites/' and extension .data.
|
||||
APPS = $(basename $(subst suites/,,$(wildcard suites/test_suite_*.data)))
|
||||
|
||||
ifndef PTHREAD
|
||||
APPS := $(filter-out test_suite_x509parse_pthread, $(APPS))
|
||||
endif
|
||||
|
||||
# Construct executable name by adding OS specific suffix $(EXEXT).
|
||||
BINARIES := $(addsuffix $(EXEXT),$(APPS))
|
||||
|
||||
|
@ -136,4 +145,3 @@ $(EMBEDDED_TESTS): embedded_%: suites/$$(firstword $$(subst ., ,$$*)).function s
|
|||
-o ./TESTS/mbedtls/$*
|
||||
|
||||
generate-target-tests: $(EMBEDDED_TESTS)
|
||||
|
||||
|
|
|
@ -728,7 +728,7 @@ component_test_full_cmake_clang () {
|
|||
msg "build: cmake, full config, clang" # ~ 50s
|
||||
scripts/config.pl full
|
||||
scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
|
||||
CC=clang cmake -D CMAKE_BUILD_TYPE:String=Check -D ENABLE_TESTING=On .
|
||||
CC=clang cmake -D LINK_WITH_PTHREAD=1 -D CMAKE_BUILD_TYPE:String=Check -D ENABLE_TESTING=On .
|
||||
make
|
||||
|
||||
msg "test: main suites (full config)" # ~ 5s
|
||||
|
@ -750,7 +750,7 @@ component_build_deprecated () {
|
|||
scripts/config.pl set MBEDTLS_DEPRECATED_WARNING
|
||||
# Build with -O -Wextra to catch a maximum of issues.
|
||||
make CC=gcc CFLAGS='-O -Werror -Wall -Wextra' lib programs
|
||||
make CC=gcc CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests
|
||||
make PTHREAD=1 CC=gcc CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests
|
||||
|
||||
msg "build: make, full config + DEPRECATED_REMOVED, clang -O" # ~ 30s
|
||||
# No cleanup, just tweak the configuration and rebuild
|
||||
|
@ -759,7 +759,7 @@ component_build_deprecated () {
|
|||
scripts/config.pl set MBEDTLS_DEPRECATED_REMOVED
|
||||
# Build with -O -Wextra to catch a maximum of issues.
|
||||
make CC=clang CFLAGS='-O -Werror -Wall -Wextra' lib programs
|
||||
make CC=clang CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests
|
||||
make PTHREAD=1 CC=clang CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests
|
||||
}
|
||||
|
||||
|
||||
|
@ -807,7 +807,7 @@ component_test_check_params_without_platform () {
|
|||
scripts/config.pl unset MBEDTLS_PLATFORM_SNPRINTF_ALT
|
||||
scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
|
||||
scripts/config.pl unset MBEDTLS_PLATFORM_C
|
||||
make CC=gcc CFLAGS='-Werror -O1' all test
|
||||
make CC=gcc PTHREAD=1 CFLAGS='-Werror -O1' all test
|
||||
}
|
||||
|
||||
component_test_check_params_silent () {
|
||||
|
@ -815,7 +815,7 @@ component_test_check_params_silent () {
|
|||
scripts/config.pl full # includes CHECK_PARAMS
|
||||
scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
|
||||
sed -i 's/.*\(#define MBEDTLS_PARAM_FAILED( cond )\).*/\1/' "$CONFIG_H"
|
||||
make CC=gcc CFLAGS='-Werror -O1' all test
|
||||
make CC=gcc PTHREAD=1 CFLAGS='-Werror -O1' all test
|
||||
}
|
||||
|
||||
component_test_no_platform () {
|
||||
|
@ -837,8 +837,8 @@ component_test_no_platform () {
|
|||
scripts/config.pl unset MBEDTLS_FS_IO
|
||||
# Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19,
|
||||
# to re-enable platform integration features otherwise disabled in C99 builds
|
||||
make CC=gcc CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -O0 -D_DEFAULT_SOURCE' lib programs
|
||||
make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0' test
|
||||
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -O0 -D_DEFAULT_SOURCE' lib programs
|
||||
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0' test
|
||||
}
|
||||
|
||||
component_build_no_std_function () {
|
||||
|
@ -847,21 +847,21 @@ component_build_no_std_function () {
|
|||
scripts/config.pl full
|
||||
scripts/config.pl set MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
|
||||
scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
|
||||
make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0'
|
||||
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0'
|
||||
}
|
||||
|
||||
component_build_no_ssl_srv () {
|
||||
msg "build: full config except ssl_srv.c, make, gcc" # ~ 30s
|
||||
scripts/config.pl full
|
||||
scripts/config.pl unset MBEDTLS_SSL_SRV_C
|
||||
make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0'
|
||||
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0'
|
||||
}
|
||||
|
||||
component_build_no_ssl_cli () {
|
||||
msg "build: full config except ssl_cli.c, make, gcc" # ~ 30s
|
||||
scripts/config.pl full
|
||||
scripts/config.pl unset MBEDTLS_SSL_CLI_C
|
||||
make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0'
|
||||
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0'
|
||||
}
|
||||
|
||||
component_build_no_sockets () {
|
||||
|
@ -871,7 +871,7 @@ component_build_no_sockets () {
|
|||
scripts/config.pl full
|
||||
scripts/config.pl unset MBEDTLS_NET_C # getaddrinfo() undeclared, etc.
|
||||
scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY # uses syscall() on GNU/Linux
|
||||
make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0 -std=c99 -pedantic' lib
|
||||
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0 -std=c99 -pedantic' lib
|
||||
}
|
||||
|
||||
component_test_no_max_fragment_length () {
|
||||
|
@ -918,6 +918,22 @@ component_test_asan_remove_peer_certificate_no_renego () {
|
|||
if_build_succeeded tests/compat.sh
|
||||
}
|
||||
|
||||
component_test_asan_on_demand_parsing_remove_peer_cert () {
|
||||
msg "build: default config, no peer CRT, on-demand CRT parsing (ASan build)"
|
||||
scripts/config.pl unset MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
|
||||
scripts/config.pl set MBEDTLS_X509_ON_DEMAND_PARSING
|
||||
scripts/config.pl set MBEDTLS_THREADING_C
|
||||
scripts/config.pl set MBEDTLS_THREADING_PTHREAD
|
||||
CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan -D LINK_WITH_PTHREAD=1 .
|
||||
make
|
||||
|
||||
msg "test: !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, MBEDTLS_X509_ON_DEMAND_PARSING"
|
||||
make test
|
||||
|
||||
msg "test: ssl-opt.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, MBEDTLS_X509_ON_DEMAND_PARSING"
|
||||
if_build_succeeded tests/ssl-opt.sh
|
||||
}
|
||||
|
||||
component_test_no_max_fragment_length_small_ssl_out_content_len () {
|
||||
msg "build: no MFL extension, small SSL_OUT_CONTENT_LEN (ASan build)"
|
||||
scripts/config.pl unset MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
|
||||
|
@ -1008,7 +1024,10 @@ component_test_m32_o0 () {
|
|||
# Build once with -O0, to compile out the i386 specific inline assembly
|
||||
msg "build: i386, make, gcc -O0 (ASan build)" # ~ 30s
|
||||
scripts/config.pl full
|
||||
make CC=gcc CFLAGS='-O0 -Werror -Wall -Wextra -m32 -fsanitize=address'
|
||||
scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE
|
||||
scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
scripts/config.pl unset MBEDTLS_MEMORY_DEBUG
|
||||
make CC=gcc PTHREAD=1 CFLAGS='-O0 -Werror -Wall -Wextra -m32 -fsanitize=address'
|
||||
|
||||
msg "test: i386, make, gcc -O0 (ASan build)"
|
||||
make test
|
||||
|
@ -1027,7 +1046,7 @@ component_test_m32_o1 () {
|
|||
scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE
|
||||
scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
scripts/config.pl unset MBEDTLS_MEMORY_DEBUG
|
||||
make CC=gcc CFLAGS='-O1 -Werror -Wall -Wextra -m32 -fsanitize=address'
|
||||
make CC=gcc PTHREAD=1 CFLAGS='-O1 -Werror -Wall -Wextra -m32 -fsanitize=address'
|
||||
|
||||
msg "test: i386, make, gcc -O1 (ASan build)"
|
||||
make test
|
||||
|
@ -1042,7 +1061,7 @@ support_test_m32_o1 () {
|
|||
component_test_mx32 () {
|
||||
msg "build: 64-bit ILP32, make, gcc" # ~ 30s
|
||||
scripts/config.pl full
|
||||
make CC=gcc CFLAGS='-Werror -Wall -Wextra -mx32'
|
||||
make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -mx32'
|
||||
|
||||
msg "test: 64-bit ILP32, make, gcc"
|
||||
make test
|
||||
|
|
|
@ -935,6 +935,10 @@ X509 Parse Selftest
|
|||
depends_on:MBEDTLS_SHA1_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CERTS_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
|
||||
x509_selftest:
|
||||
|
||||
X509 nested acquire
|
||||
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
|
||||
x509_nested_acquire:"308196308180a0030201008204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff300d06092a864886f70d01010b0500030200ff"
|
||||
|
||||
X509 CRT ASN1 (Empty Certificate)
|
||||
x509parse_crt:"":"":MBEDTLS_ERR_X509_INVALID_FORMAT
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "mbedtls/x509_crt.h"
|
||||
#include "mbedtls/x509_crl.h"
|
||||
#include "mbedtls/x509_csr.h"
|
||||
#include "mbedtls/x509_internal.h"
|
||||
#include "mbedtls/pem.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/base64.h"
|
||||
|
@ -142,25 +143,48 @@ int verify_print( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint
|
|||
verify_print_context *ctx = (verify_print_context *) data;
|
||||
char *p = ctx->p;
|
||||
size_t n = ctx->buf + sizeof( ctx->buf ) - ctx->p;
|
||||
mbedtls_x509_crt_frame const *frame;
|
||||
mbedtls_x509_name *subject;
|
||||
((void) flags);
|
||||
|
||||
ret = mbedtls_snprintf( p, n, "depth %d - serial ", certificate_depth );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
ret = mbedtls_x509_crt_get_subject( crt, &subject );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_x509_serial_gets( p, n, &crt->serial );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_snprintf( p, n, "depth %d - serial ", certificate_depth );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
||||
|
||||
{
|
||||
mbedtls_x509_buf serial;
|
||||
serial.p = frame->serial.p;
|
||||
serial.len = frame->serial.len;
|
||||
ret = mbedtls_x509_serial_gets( p, n, &serial );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
||||
}
|
||||
|
||||
ret = mbedtls_snprintf( p, n, " - subject " );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
||||
|
||||
ret = mbedtls_x509_dn_gets( p, n, &crt->subject );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
ret = mbedtls_x509_dn_gets( p, n, subject );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
||||
|
||||
ret = mbedtls_snprintf( p, n, " - flags 0x%08x\n", *flags );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
||||
|
||||
ctx->p = p;
|
||||
|
||||
cleanup:
|
||||
|
||||
mbedtls_x509_name_free( subject );
|
||||
mbedtls_x509_crt_frame_release( crt );
|
||||
|
||||
if( ret < 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
@ -428,15 +452,19 @@ void mbedtls_x509_dn_gets( char * crt_file, char * entity, char * result_str )
|
|||
mbedtls_x509_crt crt;
|
||||
char buf[2000];
|
||||
int res = 0;
|
||||
mbedtls_x509_name *subject = NULL, *issuer = NULL;
|
||||
|
||||
mbedtls_x509_crt_init( &crt );
|
||||
memset( buf, 0, 2000 );
|
||||
|
||||
TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_crt_get_subject( &crt, &subject ) == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_crt_get_issuer( &crt, &issuer ) == 0 );
|
||||
|
||||
if( strcmp( entity, "subject" ) == 0 )
|
||||
res = mbedtls_x509_dn_gets( buf, 2000, &crt.subject );
|
||||
res = mbedtls_x509_dn_gets( buf, 2000, subject );
|
||||
else if( strcmp( entity, "issuer" ) == 0 )
|
||||
res = mbedtls_x509_dn_gets( buf, 2000, &crt.issuer );
|
||||
res = mbedtls_x509_dn_gets( buf, 2000, issuer );
|
||||
else
|
||||
TEST_ASSERT( "Unknown entity" == 0 );
|
||||
|
||||
|
@ -446,6 +474,8 @@ void mbedtls_x509_dn_gets( char * crt_file, char * entity, char * result_str )
|
|||
TEST_ASSERT( strcmp( buf, result_str ) == 0 );
|
||||
|
||||
exit:
|
||||
mbedtls_x509_name_free( issuer );
|
||||
mbedtls_x509_name_free( subject );
|
||||
mbedtls_x509_crt_free( &crt );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
@ -453,16 +483,18 @@ exit:
|
|||
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
|
||||
void mbedtls_x509_time_is_past( char * crt_file, char * entity, int result )
|
||||
{
|
||||
mbedtls_x509_crt crt;
|
||||
mbedtls_x509_crt crt;
|
||||
mbedtls_x509_crt_frame frame;
|
||||
|
||||
mbedtls_x509_crt_init( &crt );
|
||||
|
||||
TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_crt_get_frame( &crt, &frame ) == 0 );
|
||||
|
||||
if( strcmp( entity, "valid_from" ) == 0 )
|
||||
TEST_ASSERT( mbedtls_x509_time_is_past( &crt.valid_from ) == result );
|
||||
TEST_ASSERT( mbedtls_x509_time_is_past( &frame.valid_from ) == result );
|
||||
else if( strcmp( entity, "valid_to" ) == 0 )
|
||||
TEST_ASSERT( mbedtls_x509_time_is_past( &crt.valid_to ) == result );
|
||||
TEST_ASSERT( mbedtls_x509_time_is_past( &frame.valid_to ) == result );
|
||||
else
|
||||
TEST_ASSERT( "Unknown entity" == 0 );
|
||||
|
||||
|
@ -474,16 +506,18 @@ exit:
|
|||
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
|
||||
void mbedtls_x509_time_is_future( char * crt_file, char * entity, int result )
|
||||
{
|
||||
mbedtls_x509_crt crt;
|
||||
mbedtls_x509_crt crt;
|
||||
mbedtls_x509_crt_frame frame;
|
||||
|
||||
mbedtls_x509_crt_init( &crt );
|
||||
|
||||
TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_crt_get_frame( &crt, &frame ) == 0 );
|
||||
|
||||
if( strcmp( entity, "valid_from" ) == 0 )
|
||||
TEST_ASSERT( mbedtls_x509_time_is_future( &crt.valid_from ) == result );
|
||||
TEST_ASSERT( mbedtls_x509_time_is_future( &frame.valid_from ) == result );
|
||||
else if( strcmp( entity, "valid_to" ) == 0 )
|
||||
TEST_ASSERT( mbedtls_x509_time_is_future( &crt.valid_to ) == result );
|
||||
TEST_ASSERT( mbedtls_x509_time_is_future( &frame.valid_to ) == result );
|
||||
else
|
||||
TEST_ASSERT( "Unknown entity" == 0 );
|
||||
|
||||
|
@ -563,6 +597,99 @@ exit:
|
|||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
|
||||
void x509_nested_acquire( data_t * buf )
|
||||
{
|
||||
/* This tests exercises the behavior of the library when
|
||||
* facing nested calls to mbedtls_x509_crt_xxx_acquire().
|
||||
* This is allowed if !MBEDTLS_X509_ALWAYS_FLUSH or
|
||||
* MBEDTLS_THREADING_C, but forbidden otherwise. */
|
||||
|
||||
mbedtls_x509_crt crt;
|
||||
mbedtls_x509_crt_init( &crt );
|
||||
TEST_ASSERT( mbedtls_x509_crt_parse_der( &crt, buf->x, buf->len ) == 0 );
|
||||
|
||||
/* Nested aquire for CRT frames */
|
||||
{
|
||||
int ret;
|
||||
mbedtls_x509_crt_frame const *frame1;
|
||||
mbedtls_x509_crt_frame const *frame2;
|
||||
|
||||
/* Perform a (hopefully) innocent acquire-release pair first. */
|
||||
|
||||
TEST_ASSERT( mbedtls_x509_crt_frame_acquire( &crt, &frame1 ) == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_crt_frame_release( &crt ) == 0 );
|
||||
|
||||
/* Perform two nested acquire calls. */
|
||||
|
||||
TEST_ASSERT( mbedtls_x509_crt_frame_acquire( &crt, &frame1 ) == 0 );
|
||||
|
||||
ret = mbedtls_x509_crt_frame_acquire( &crt, &frame2 );
|
||||
#if defined(MBEDTLS_X509_ALWAYS_FLUSH) && \
|
||||
!defined(MBEDTLS_THREADING_C)
|
||||
TEST_ASSERT( ret == MBEDTLS_ERR_X509_FATAL_ERROR );
|
||||
#else
|
||||
TEST_ASSERT( ret == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_crt_frame_release( &crt ) == 0 );
|
||||
#endif
|
||||
|
||||
TEST_ASSERT( mbedtls_x509_crt_frame_release( &crt ) == 0 );
|
||||
|
||||
ret = mbedtls_x509_crt_frame_release( &crt );
|
||||
|
||||
/* In contexts which use resource counting, we expect an
|
||||
* error on an attempted release() without prior acquire(). */
|
||||
#if defined(MBEDTLS_X509_ALWAYS_FLUSH) && \
|
||||
!defined(MBEDTLS_THREADING_C)
|
||||
TEST_ASSERT( ret == 0 );
|
||||
#else
|
||||
TEST_ASSERT( ret == MBEDTLS_ERR_X509_FATAL_ERROR );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Nested aquire for PK contexts */
|
||||
{
|
||||
int ret;
|
||||
mbedtls_pk_context *pk1;
|
||||
mbedtls_pk_context *pk2;
|
||||
|
||||
/* Perform a (hopefully) innocent acquire-release pair first. */
|
||||
|
||||
TEST_ASSERT( mbedtls_x509_crt_pk_acquire( &crt, &pk1 ) == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_crt_pk_release( &crt ) == 0 );
|
||||
|
||||
/* Perform two nested acquire calls. */
|
||||
|
||||
TEST_ASSERT( mbedtls_x509_crt_pk_acquire( &crt, &pk1 ) == 0 );
|
||||
|
||||
ret = mbedtls_x509_crt_pk_acquire( &crt, &pk2 );
|
||||
#if defined(MBEDTLS_X509_ALWAYS_FLUSH) && \
|
||||
!defined(MBEDTLS_THREADING_C)
|
||||
TEST_ASSERT( ret == MBEDTLS_ERR_X509_FATAL_ERROR );
|
||||
#else
|
||||
TEST_ASSERT( ret == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_crt_pk_release( &crt ) == 0 );
|
||||
#endif
|
||||
|
||||
TEST_ASSERT( mbedtls_x509_crt_pk_release( &crt ) == 0 );
|
||||
|
||||
ret = mbedtls_x509_crt_pk_release( &crt );
|
||||
|
||||
/* In contexts which use resource counting, we expect an
|
||||
* error on an attempted release() without prior acquire(). */
|
||||
#if defined(MBEDTLS_X509_ALWAYS_FLUSH) && \
|
||||
!defined(MBEDTLS_THREADING_C)
|
||||
TEST_ASSERT( ret == 0 );
|
||||
#else
|
||||
TEST_ASSERT( ret == MBEDTLS_ERR_X509_FATAL_ERROR );
|
||||
#endif
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_x509_crt_free( &crt );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRL_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
|
||||
void x509parse_crl( data_t * buf, char * result_str, int result )
|
||||
{
|
||||
|
|
19
tests/suites/test_suite_x509parse_pthread.data
Normal file
19
tests/suites/test_suite_x509parse_pthread.data
Normal file
|
@ -0,0 +1,19 @@
|
|||
X509 CRT concurrent verification #1 (RSA cert, RSA CA)
|
||||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA1_C
|
||||
x509_verify_thread:"data_files/server1.crt":"data_files/test-ca.crt":0:0:25:50
|
||||
|
||||
X509 CRT concurrent verification #2 (EC cert, RSA CA)
|
||||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA1_C
|
||||
x509_verify_thread:"data_files/server3.crt":"data_files/test-ca.crt":0:0:25:50
|
||||
|
||||
X509 CRT concurrent verification #3 (RSA cert, EC CA)
|
||||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||
x509_verify_thread:"data_files/server4.crt":"data_files/test-ca2.crt":0:0:25:50
|
||||
|
||||
X509 CRT concurrent verification #4 (EC cert, EC CA)
|
||||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||
x509_verify_thread:"data_files/server5.crt":"data_files/test-ca2.crt":0:0:25:50
|
||||
|
||||
X509 CRT concurrent verification #5 (RSA cert, RSA CA, RSASSA-PSS)
|
||||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT:MBEDTLS_SHA1_C
|
||||
x509_verify_thread:"data_files/server9-with-ca.crt":"data_files/test-ca.crt":0:0:25:50
|
125
tests/suites/test_suite_x509parse_pthread.function
Normal file
125
tests/suites/test_suite_x509parse_pthread.function
Normal file
|
@ -0,0 +1,125 @@
|
|||
/* BEGIN_HEADER */
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "mbedtls/x509.h"
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include "mbedtls/x509_crl.h"
|
||||
#include "mbedtls/x509_csr.h"
|
||||
#include "mbedtls/x509_internal.h"
|
||||
#include "mbedtls/pem.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/base64.h"
|
||||
#include "string.h"
|
||||
|
||||
/* Profile for backward compatibility. Allows SHA-1, unlike the default
|
||||
profile. */
|
||||
const mbedtls_x509_crt_profile compat_profile =
|
||||
{
|
||||
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
|
||||
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) |
|
||||
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
|
||||
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
|
||||
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
|
||||
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
|
||||
0xFFFFFFF, /* Any PK alg */
|
||||
0xFFFFFFF, /* Any curve */
|
||||
1024,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mbedtls_x509_crt *crt;
|
||||
mbedtls_x509_crt *ca;
|
||||
uint32_t expected_flags;
|
||||
unsigned id;
|
||||
int expected_result;
|
||||
int iter_total;
|
||||
int result;
|
||||
} x509_verify_thread_ctx;
|
||||
|
||||
void* x509_verify_thread_worker( void *p )
|
||||
{
|
||||
unsigned iter_cnt;
|
||||
x509_verify_thread_ctx *ctx = (x509_verify_thread_ctx *) p;
|
||||
|
||||
for( iter_cnt=0; iter_cnt < (unsigned) ctx->iter_total; iter_cnt++ )
|
||||
{
|
||||
uint32_t flags;
|
||||
int res;
|
||||
|
||||
res = mbedtls_x509_crt_verify_with_profile( ctx->crt, ctx->ca,
|
||||
NULL, &compat_profile,
|
||||
NULL, &flags, NULL, NULL );
|
||||
if( res != ctx->expected_result ||
|
||||
flags != ctx->expected_flags )
|
||||
{
|
||||
ctx->result = 1;
|
||||
pthread_exit( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
ctx->result = 0;
|
||||
pthread_exit( NULL );
|
||||
return( NULL );
|
||||
}
|
||||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_DEPENDENCIES
|
||||
* depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_X509_CRT_PARSE_C
|
||||
* END_DEPENDENCIES
|
||||
*/
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
|
||||
void x509_verify_thread( char *crt_file, char *ca_file,
|
||||
int result, int flags_result,
|
||||
int thread_total,
|
||||
int iterations_per_thread )
|
||||
{
|
||||
x509_verify_thread_ctx *thread_ctx;
|
||||
pthread_t *threads;
|
||||
int cur_thread;
|
||||
|
||||
mbedtls_x509_crt crt;
|
||||
mbedtls_x509_crt ca;
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
TEST_ASSERT( psa_crypto_init() == 0 );
|
||||
#endif
|
||||
|
||||
mbedtls_x509_crt_init( &crt );
|
||||
mbedtls_x509_crt_init( &ca );
|
||||
threads = mbedtls_calloc( thread_total, sizeof( pthread_t ) );
|
||||
thread_ctx = mbedtls_calloc( thread_total, sizeof( x509_verify_thread_ctx ) );
|
||||
|
||||
TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
|
||||
TEST_ASSERT( threads != NULL );
|
||||
|
||||
/* Start all verify threads */
|
||||
for( cur_thread = 0; cur_thread < thread_total; cur_thread++ )
|
||||
{
|
||||
thread_ctx[ cur_thread ].id = (unsigned) cur_thread;
|
||||
thread_ctx[ cur_thread ].ca = &ca;
|
||||
thread_ctx[ cur_thread ].crt = &crt;
|
||||
thread_ctx[ cur_thread ].expected_result = result;
|
||||
thread_ctx[ cur_thread ].expected_flags = flags_result;
|
||||
thread_ctx[ cur_thread ].iter_total = iterations_per_thread;
|
||||
TEST_ASSERT( pthread_create( &threads[ cur_thread ], NULL,
|
||||
&x509_verify_thread_worker,
|
||||
&thread_ctx[ cur_thread ] ) == 0 );
|
||||
}
|
||||
|
||||
/* Wait for all threads to complete */
|
||||
for( cur_thread = 0; cur_thread < thread_total; cur_thread++ )
|
||||
TEST_ASSERT( pthread_join( threads[ cur_thread ], NULL ) == 0 );
|
||||
|
||||
/* Check their results */
|
||||
for( cur_thread = 0; cur_thread < thread_total; cur_thread++ )
|
||||
TEST_ASSERT( thread_ctx[ cur_thread ].result == 0 );
|
||||
|
||||
exit:
|
||||
mbedtls_free( threads );
|
||||
mbedtls_free( thread_ctx );
|
||||
mbedtls_x509_crt_free( &crt );
|
||||
mbedtls_x509_crt_free( &ca );
|
||||
}
|
||||
/* END_CASE */
|
|
@ -2,6 +2,7 @@
|
|||
#include "mbedtls/bignum.h"
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include "mbedtls/x509_csr.h"
|
||||
#include "mbedtls/x509_internal.h"
|
||||
#include "mbedtls/pem.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
|
@ -216,7 +217,7 @@ void mbedtls_x509_string_to_names( char * name, char * parsed_name, int result
|
|||
)
|
||||
{
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
size_t len;
|
||||
mbedtls_asn1_named_data *names = NULL;
|
||||
mbedtls_x509_name parsed, *parsed_cur, *parsed_prv;
|
||||
unsigned char buf[1024], out[1024], *c;
|
||||
|
@ -234,10 +235,9 @@ void mbedtls_x509_string_to_names( char * name, char * parsed_name, int result
|
|||
|
||||
ret = mbedtls_x509_write_names( &c, buf, names );
|
||||
TEST_ASSERT( ret > 0 );
|
||||
len = (size_t) ret;
|
||||
|
||||
TEST_ASSERT( mbedtls_asn1_get_tag( &c, buf + sizeof( buf ), &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_get_name( &c, buf + sizeof( buf ), &parsed ) == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_get_name( c, len, &parsed ) == 0 );
|
||||
|
||||
ret = mbedtls_x509_dn_gets( (char *) out, sizeof( out ), &parsed );
|
||||
TEST_ASSERT( ret > 0 );
|
||||
|
|
|
@ -223,6 +223,7 @@
|
|||
<ClInclude Include="..\..\include\mbedtls\x509_crl.h" />
|
||||
<ClInclude Include="..\..\include\mbedtls\x509_crt.h" />
|
||||
<ClInclude Include="..\..\include\mbedtls\x509_csr.h" />
|
||||
<ClInclude Include="..\..\include\mbedtls\x509_internal.h" />
|
||||
<ClInclude Include="..\..\include\mbedtls\xtea.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
Loading…
Reference in a new issue