diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h index a98748cdcb..57e0727716 100644 --- a/include/mbedtls/x509.h +++ b/include/mbedtls/x509.h @@ -379,6 +379,14 @@ int x509_get_key_usage(unsigned char **p, int x509_get_subject_alt_name(unsigned char **p, const unsigned char *end, mbedtls_x509_sequence *subject_alt_name); +int x509_info_subject_alt_name(char **buf, size_t *size, + const mbedtls_x509_sequence + *subject_alt_name, + const char *prefix); +int x509_info_cert_type(char **buf, size_t *size, + unsigned char ns_cert_type); +int x509_info_key_usage(char **buf, size_t *size, + unsigned int key_usage); #define MBEDTLS_X509_SAFE_SNPRINTF \ do { \ diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h index 216a0a2e9d..0c204be067 100644 --- a/include/mbedtls/x509_csr.h +++ b/include/mbedtls/x509_csr.h @@ -62,6 +62,8 @@ typedef struct mbedtls_x509_csr { unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */ mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName and OtherName are listed). */ + int MBEDTLS_PRIVATE(ext_types); /**< Bit string containing detected and parsed extensions */ + mbedtls_x509_buf sig_oid; mbedtls_x509_buf MBEDTLS_PRIVATE(sig); mbedtls_md_type_t MBEDTLS_PRIVATE(sig_md); /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ diff --git a/library/x509_crt.c b/library/x509_crt.c index e02d18e05c..261525d388 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -1849,10 +1849,10 @@ int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf, } #if !defined(MBEDTLS_X509_REMOVE_INFO) -static int x509_info_subject_alt_name(char **buf, size_t *size, - const mbedtls_x509_sequence - *subject_alt_name, - const char *prefix) +int x509_info_subject_alt_name(char **buf, size_t *size, + const mbedtls_x509_sequence + *subject_alt_name, + const char *prefix) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t i; @@ -1965,8 +1965,8 @@ static int x509_info_subject_alt_name(char **buf, size_t *size, if (ns_cert_type & (type)) \ PRINT_ITEM(name); -static int x509_info_cert_type(char **buf, size_t *size, - unsigned char ns_cert_type) +int x509_info_cert_type(char **buf, size_t *size, + unsigned char ns_cert_type) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t n = *size; @@ -1992,8 +1992,8 @@ static int x509_info_cert_type(char **buf, size_t *size, if (key_usage & (code)) \ PRINT_ITEM(name); -static int x509_info_key_usage(char **buf, size_t *size, - unsigned int key_usage) +int x509_info_key_usage(char **buf, size_t *size, + unsigned int key_usage) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t n = *size; diff --git a/library/x509_csr.c b/library/x509_csr.c index 824d17a75b..f1c4c6654e 100644 --- a/library/x509_csr.c +++ b/library/x509_csr.c @@ -111,7 +111,19 @@ static int x509_csr_parse_extensions(mbedtls_x509_csr *csr, MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; } - if (mbedtls_oid_get_x509_ext_type(&extn_oid, &ext_type) == 0) { + /* + * Detect supported extensions + */ + ret = mbedtls_oid_get_x509_ext_type(&extn_oid, &ext_type); + + if (ret == 0) { + /* Forbid repeated extensions */ + if ((csr->ext_types & ext_type) != 0) { + return MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + } + + csr->ext_types |= ext_type; + switch (ext_type) { case MBEDTLS_X509_EXT_KEY_USAGE: /* Parse key usage */ @@ -497,6 +509,44 @@ int mbedtls_x509_csr_info(char *buf, size_t size, const char *prefix, (int) mbedtls_pk_get_bitlen(&csr->pk)); MBEDTLS_X509_SAFE_SNPRINTF; + /* + * Optional extensions + */ + + if (csr->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) { + ret = mbedtls_snprintf(p, n, "\n%ssubject alt name :", prefix); + MBEDTLS_X509_SAFE_SNPRINTF; + + if ((ret = x509_info_subject_alt_name(&p, &n, + &csr->subject_alt_names, + prefix)) != 0) { + return ret; + } + } + + if (csr->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) { + ret = mbedtls_snprintf(p, n, "\n%scert. type : ", prefix); + MBEDTLS_X509_SAFE_SNPRINTF; + + if ((ret = x509_info_cert_type(&p, &n, csr->ns_cert_type)) != 0) { + return ret; + } + } + + if (csr->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) { + ret = mbedtls_snprintf(p, n, "\n%skey usage : ", prefix); + MBEDTLS_X509_SAFE_SNPRINTF; + + if ((ret = x509_info_key_usage(&p, &n, csr->key_usage)) != 0) { + return ret; + } + } + + if (csr->ext_types != 0) { + ret = mbedtls_snprintf(p, n, "\n"); + MBEDTLS_X509_SAFE_SNPRINTF; + } + return (int) (size - n); } #endif /* MBEDTLS_X509_REMOVE_INFO */