mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-03-29 22:20:30 +00:00
Move common functions for crt/csr parsing to x509.c
Signed-off-by: Przemek Stekiel <przemyslaw.stekiel@mobica.com>
This commit is contained in:
parent
db128f518c
commit
cf6ff0fb43
@ -250,6 +250,56 @@ typedef struct mbedtls_x509_time {
|
||||
}
|
||||
mbedtls_x509_time;
|
||||
|
||||
/**
|
||||
* From RFC 5280 section 4.2.1.6:
|
||||
* OtherName ::= SEQUENCE {
|
||||
* type-id OBJECT IDENTIFIER,
|
||||
* value [0] EXPLICIT ANY DEFINED BY type-id }
|
||||
*
|
||||
* Future versions of the library may add new fields to this structure or
|
||||
* to its embedded union and structure.
|
||||
*/
|
||||
typedef struct mbedtls_x509_san_other_name {
|
||||
/**
|
||||
* The type_id is an OID as defined in RFC 5280.
|
||||
* To check the value of the type id, you should use
|
||||
* \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf.
|
||||
*/
|
||||
mbedtls_x509_buf type_id; /**< The type id. */
|
||||
union {
|
||||
/**
|
||||
* From RFC 4108 section 5:
|
||||
* HardwareModuleName ::= SEQUENCE {
|
||||
* hwType OBJECT IDENTIFIER,
|
||||
* hwSerialNum OCTET STRING }
|
||||
*/
|
||||
struct {
|
||||
mbedtls_x509_buf oid; /**< The object identifier. */
|
||||
mbedtls_x509_buf val; /**< The named value. */
|
||||
}
|
||||
hardware_module_name;
|
||||
}
|
||||
value;
|
||||
}
|
||||
mbedtls_x509_san_other_name;
|
||||
|
||||
/**
|
||||
* A structure for holding the parsed Subject Alternative Name,
|
||||
* according to type.
|
||||
*
|
||||
* Future versions of the library may add new fields to this structure or
|
||||
* to its embedded union and structure.
|
||||
*/
|
||||
typedef struct mbedtls_x509_subject_alternative_name {
|
||||
int type; /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */
|
||||
union {
|
||||
mbedtls_x509_san_other_name other_name; /**< The otherName supported type. */
|
||||
mbedtls_x509_buf unstructured_name; /**< The buffer for the un constructed types. Only dnsName currently supported */
|
||||
}
|
||||
san; /**< A union of the supported SAN types */
|
||||
}
|
||||
mbedtls_x509_subject_alternative_name;
|
||||
|
||||
/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */
|
||||
|
||||
/**
|
||||
@ -326,6 +376,36 @@ int mbedtls_x509_time_is_past(const mbedtls_x509_time *to);
|
||||
*/
|
||||
int mbedtls_x509_time_is_future(const mbedtls_x509_time *from);
|
||||
|
||||
/**
|
||||
* \brief This function parses an item in the SubjectAlternativeNames
|
||||
* extension.
|
||||
*
|
||||
* \param san_buf The buffer holding the raw data item of the subject
|
||||
* alternative name.
|
||||
* \param san The target structure to populate with the parsed presentation
|
||||
* of the subject alternative name encoded in \p san_raw.
|
||||
*
|
||||
* \note Only "dnsName" and "otherName" of type hardware_module_name
|
||||
* as defined in RFC 4180 is supported.
|
||||
*
|
||||
* \note This function should be called on a single raw data of
|
||||
* subject alternative name. For example, after successful
|
||||
* certificate parsing, one must iterate on every item in the
|
||||
* \p crt->subject_alt_names sequence, and pass it to
|
||||
* this function.
|
||||
*
|
||||
* \warning The target structure contains pointers to the raw data of the
|
||||
* parsed certificate, and its lifetime is restricted by the
|
||||
* lifetime of the certificate.
|
||||
*
|
||||
* \return \c 0 on success
|
||||
* \return #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported
|
||||
* SAN type.
|
||||
* \return Another negative value for any other failure.
|
||||
*/
|
||||
int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
|
||||
mbedtls_x509_subject_alternative_name *san);
|
||||
|
||||
/** \} addtogroup x509_module */
|
||||
|
||||
/*
|
||||
|
@ -102,56 +102,6 @@ typedef struct mbedtls_x509_crt {
|
||||
}
|
||||
mbedtls_x509_crt;
|
||||
|
||||
/**
|
||||
* From RFC 5280 section 4.2.1.6:
|
||||
* OtherName ::= SEQUENCE {
|
||||
* type-id OBJECT IDENTIFIER,
|
||||
* value [0] EXPLICIT ANY DEFINED BY type-id }
|
||||
*
|
||||
* Future versions of the library may add new fields to this structure or
|
||||
* to its embedded union and structure.
|
||||
*/
|
||||
typedef struct mbedtls_x509_san_other_name {
|
||||
/**
|
||||
* The type_id is an OID as defined in RFC 5280.
|
||||
* To check the value of the type id, you should use
|
||||
* \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf.
|
||||
*/
|
||||
mbedtls_x509_buf type_id; /**< The type id. */
|
||||
union {
|
||||
/**
|
||||
* From RFC 4108 section 5:
|
||||
* HardwareModuleName ::= SEQUENCE {
|
||||
* hwType OBJECT IDENTIFIER,
|
||||
* hwSerialNum OCTET STRING }
|
||||
*/
|
||||
struct {
|
||||
mbedtls_x509_buf oid; /**< The object identifier. */
|
||||
mbedtls_x509_buf val; /**< The named value. */
|
||||
}
|
||||
hardware_module_name;
|
||||
}
|
||||
value;
|
||||
}
|
||||
mbedtls_x509_san_other_name;
|
||||
|
||||
/**
|
||||
* A structure for holding the parsed Subject Alternative Name,
|
||||
* according to type.
|
||||
*
|
||||
* Future versions of the library may add new fields to this structure or
|
||||
* to its embedded union and structure.
|
||||
*/
|
||||
typedef struct mbedtls_x509_subject_alternative_name {
|
||||
int type; /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */
|
||||
union {
|
||||
mbedtls_x509_san_other_name other_name; /**< The otherName supported type. */
|
||||
mbedtls_x509_buf unstructured_name; /**< The buffer for the un constructed types. Only dnsName currently supported */
|
||||
}
|
||||
san; /**< A union of the supported SAN types */
|
||||
}
|
||||
mbedtls_x509_subject_alternative_name;
|
||||
|
||||
/**
|
||||
* Build flag from an algorithm/curve identifier (pk, md, ecp)
|
||||
* Since 0 is always XXX_NONE, ignore it.
|
||||
@ -589,36 +539,6 @@ int mbedtls_x509_crt_parse_file(mbedtls_x509_crt *chain, const char *path);
|
||||
int mbedtls_x509_crt_parse_path(mbedtls_x509_crt *chain, const char *path);
|
||||
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
/**
|
||||
* \brief This function parses an item in the SubjectAlternativeNames
|
||||
* extension.
|
||||
*
|
||||
* \param san_buf The buffer holding the raw data item of the subject
|
||||
* alternative name.
|
||||
* \param san The target structure to populate with the parsed presentation
|
||||
* of the subject alternative name encoded in \p san_raw.
|
||||
*
|
||||
* \note Only "dnsName" and "otherName" of type hardware_module_name
|
||||
* as defined in RFC 4180 is supported.
|
||||
*
|
||||
* \note This function should be called on a single raw data of
|
||||
* subject alternative name. For example, after successful
|
||||
* certificate parsing, one must iterate on every item in the
|
||||
* \p crt->subject_alt_names sequence, and pass it to
|
||||
* this function.
|
||||
*
|
||||
* \warning The target structure contains pointers to the raw data of the
|
||||
* parsed certificate, and its lifetime is restricted by the
|
||||
* lifetime of the certificate.
|
||||
*
|
||||
* \return \c 0 on success
|
||||
* \return #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported
|
||||
* SAN type.
|
||||
* \return Another negative value for any other failure.
|
||||
*/
|
||||
int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
|
||||
mbedtls_x509_subject_alternative_name *san);
|
||||
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
/**
|
||||
* \brief Returns an informational string about the
|
||||
|
486
library/x509.c
486
library/x509.c
@ -1107,4 +1107,490 @@ int mbedtls_x509_time_is_future(const mbedtls_x509_time *from)
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
||||
|
||||
/* Common functions for parsing CRT and CSR. */
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C)
|
||||
/*
|
||||
* OtherName ::= SEQUENCE {
|
||||
* type-id OBJECT IDENTIFIER,
|
||||
* value [0] EXPLICIT ANY DEFINED BY type-id }
|
||||
*
|
||||
* HardwareModuleName ::= SEQUENCE {
|
||||
* hwType OBJECT IDENTIFIER,
|
||||
* hwSerialNum OCTET STRING }
|
||||
*
|
||||
* NOTE: we currently only parse and use otherName of type HwModuleName,
|
||||
* as defined in RFC 4108.
|
||||
*/
|
||||
static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
|
||||
mbedtls_x509_san_other_name *other_name)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t len;
|
||||
unsigned char *p = subject_alt_name->p;
|
||||
const unsigned char *end = p + subject_alt_name->len;
|
||||
mbedtls_x509_buf cur_oid;
|
||||
|
||||
if ((subject_alt_name->tag &
|
||||
(MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK)) !=
|
||||
(MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME)) {
|
||||
/*
|
||||
* The given subject alternative name is not of type "othername".
|
||||
*/
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_OID)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
cur_oid.tag = MBEDTLS_ASN1_OID;
|
||||
cur_oid.p = p;
|
||||
cur_oid.len = len;
|
||||
|
||||
/*
|
||||
* Only HwModuleName is currently supported.
|
||||
*/
|
||||
if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) != 0) {
|
||||
return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
if (p + len >= end) {
|
||||
mbedtls_platform_zeroize(other_name, sizeof(*other_name));
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
p += len;
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
|
||||
0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID;
|
||||
other_name->value.hardware_module_name.oid.p = p;
|
||||
other_name->value.hardware_module_name.oid.len = len;
|
||||
|
||||
if (p + len >= end) {
|
||||
mbedtls_platform_zeroize(other_name, sizeof(*other_name));
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
p += len;
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_OCTET_STRING)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING;
|
||||
other_name->value.hardware_module_name.val.p = p;
|
||||
other_name->value.hardware_module_name.val.len = len;
|
||||
p += len;
|
||||
if (p != end) {
|
||||
mbedtls_platform_zeroize(other_name,
|
||||
sizeof(*other_name));
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* SubjectAltName ::= GeneralNames
|
||||
*
|
||||
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
|
||||
*
|
||||
* GeneralName ::= CHOICE {
|
||||
* otherName [0] OtherName,
|
||||
* rfc822Name [1] IA5String,
|
||||
* dNSName [2] IA5String,
|
||||
* x400Address [3] ORAddress,
|
||||
* directoryName [4] Name,
|
||||
* ediPartyName [5] EDIPartyName,
|
||||
* uniformResourceIdentifier [6] IA5String,
|
||||
* iPAddress [7] OCTET STRING,
|
||||
* registeredID [8] OBJECT IDENTIFIER }
|
||||
*
|
||||
* OtherName ::= SEQUENCE {
|
||||
* type-id OBJECT IDENTIFIER,
|
||||
* value [0] EXPLICIT ANY DEFINED BY type-id }
|
||||
*
|
||||
* EDIPartyName ::= SEQUENCE {
|
||||
* nameAssigner [0] DirectoryString OPTIONAL,
|
||||
* partyName [1] DirectoryString }
|
||||
*
|
||||
* NOTE: we list all types, but only use dNSName and otherName
|
||||
* of type HwModuleName, as defined in RFC 4108, at this point.
|
||||
*/
|
||||
int mbedtls_x509_get_subject_alt_name(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_x509_sequence *subject_alt_name)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len, tag_len;
|
||||
mbedtls_asn1_buf *buf;
|
||||
unsigned char tag;
|
||||
mbedtls_asn1_sequence *cur = subject_alt_name;
|
||||
|
||||
/* Get main sequence tag */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if (*p + len != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
while (*p < end) {
|
||||
mbedtls_x509_subject_alternative_name dummy_san_buf;
|
||||
memset(&dummy_san_buf, 0, sizeof(dummy_san_buf));
|
||||
|
||||
tag = **p;
|
||||
(*p)++;
|
||||
if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if ((tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the SAN is structured correctly.
|
||||
*/
|
||||
ret = mbedtls_x509_parse_subject_alt_name(&(cur->buf), &dummy_san_buf);
|
||||
/*
|
||||
* In case the extension is malformed, return an error,
|
||||
* and clear the allocated sequences.
|
||||
*/
|
||||
if (ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
|
||||
mbedtls_asn1_sequence_free(subject_alt_name->next);
|
||||
subject_alt_name->next = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Allocate and assign next pointer */
|
||||
if (cur->buf.p != NULL) {
|
||||
if (cur->next != NULL) {
|
||||
return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
|
||||
}
|
||||
|
||||
cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
|
||||
|
||||
if (cur->next == NULL) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_ALLOC_FAILED);
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
buf = &(cur->buf);
|
||||
buf->tag = tag;
|
||||
buf->p = *p;
|
||||
buf->len = tag_len;
|
||||
*p += buf->len;
|
||||
}
|
||||
|
||||
/* Set final sequence entry's next pointer to NULL */
|
||||
cur->next = NULL;
|
||||
|
||||
if (*p != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_x509_get_ns_cert_type(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
unsigned char *ns_cert_type)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_x509_bitstring bs = { 0, 0, NULL };
|
||||
|
||||
if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if (bs.len == 0) {
|
||||
*ns_cert_type = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bs.len != 1) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_INVALID_LENGTH);
|
||||
}
|
||||
|
||||
/* Get actual bitstring */
|
||||
*ns_cert_type = *bs.p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_x509_get_key_usage(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
unsigned int *key_usage)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t i;
|
||||
mbedtls_x509_bitstring bs = { 0, 0, NULL };
|
||||
|
||||
if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if (bs.len == 0) {
|
||||
*key_usage = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bs.len < 1) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_INVALID_LENGTH);
|
||||
}
|
||||
|
||||
/* Get actual bitstring */
|
||||
*key_usage = 0;
|
||||
for (i = 0; i < bs.len && i < sizeof(unsigned int); i++) {
|
||||
*key_usage |= (unsigned int) bs.p[i] << (8*i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
|
||||
mbedtls_x509_subject_alternative_name *san)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
switch (san_buf->tag &
|
||||
(MBEDTLS_ASN1_TAG_CLASS_MASK |
|
||||
MBEDTLS_ASN1_TAG_VALUE_MASK)) {
|
||||
/*
|
||||
* otherName
|
||||
*/
|
||||
case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME):
|
||||
{
|
||||
mbedtls_x509_san_other_name other_name;
|
||||
|
||||
ret = x509_get_other_name(san_buf, &other_name);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
|
||||
san->type = MBEDTLS_X509_SAN_OTHER_NAME;
|
||||
memcpy(&san->san.other_name,
|
||||
&other_name, sizeof(other_name));
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* dNSName
|
||||
*/
|
||||
case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME):
|
||||
{
|
||||
memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
|
||||
san->type = MBEDTLS_X509_SAN_DNS_NAME;
|
||||
|
||||
memcpy(&san->san.unstructured_name,
|
||||
san_buf, sizeof(*san_buf));
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* Type not supported
|
||||
*/
|
||||
default:
|
||||
return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
int mbedtls_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;
|
||||
size_t n = *size;
|
||||
char *p = *buf;
|
||||
const mbedtls_x509_sequence *cur = subject_alt_name;
|
||||
mbedtls_x509_subject_alternative_name san;
|
||||
int parse_ret;
|
||||
|
||||
while (cur != NULL) {
|
||||
memset(&san, 0, sizeof(san));
|
||||
parse_ret = mbedtls_x509_parse_subject_alt_name(&cur->buf, &san);
|
||||
if (parse_ret != 0) {
|
||||
if (parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
|
||||
ret = mbedtls_snprintf(p, n, "\n%s <unsupported>", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
} else {
|
||||
ret = mbedtls_snprintf(p, n, "\n%s <malformed>", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
}
|
||||
cur = cur->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (san.type) {
|
||||
/*
|
||||
* otherName
|
||||
*/
|
||||
case MBEDTLS_X509_SAN_OTHER_NAME:
|
||||
{
|
||||
mbedtls_x509_san_other_name *other_name = &san.san.other_name;
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "\n%s otherName :", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME,
|
||||
&other_name->value.hardware_module_name.oid) != 0) {
|
||||
ret = mbedtls_snprintf(p, n, "\n%s hardware module name :", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
ret =
|
||||
mbedtls_snprintf(p, n, "\n%s hardware type : ", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_oid_get_numeric_string(p,
|
||||
n,
|
||||
&other_name->value.hardware_module_name.oid);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret =
|
||||
mbedtls_snprintf(p, n, "\n%s hardware serial number : ", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
for (i = 0; i < other_name->value.hardware_module_name.val.len; i++) {
|
||||
ret = mbedtls_snprintf(p,
|
||||
n,
|
||||
"%02X",
|
||||
other_name->value.hardware_module_name.val.p[i]);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
}
|
||||
}/* MBEDTLS_OID_ON_HW_MODULE_NAME */
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* dNSName
|
||||
*/
|
||||
case MBEDTLS_X509_SAN_DNS_NAME:
|
||||
{
|
||||
ret = mbedtls_snprintf(p, n, "\n%s dNSName : ", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
if (san.san.unstructured_name.len >= n) {
|
||||
*p = '\0';
|
||||
return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len);
|
||||
p += san.san.unstructured_name.len;
|
||||
n -= san.san.unstructured_name.len;
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* Type not supported, skip item.
|
||||
*/
|
||||
default:
|
||||
ret = mbedtls_snprintf(p, n, "\n%s <unsupported>", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
break;
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
*size = n;
|
||||
*buf = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PRINT_ITEM(i) \
|
||||
{ \
|
||||
ret = mbedtls_snprintf(p, n, "%s" i, sep); \
|
||||
MBEDTLS_X509_SAFE_SNPRINTF; \
|
||||
sep = ", "; \
|
||||
}
|
||||
|
||||
#define CERT_TYPE(type, name) \
|
||||
if (ns_cert_type & (type)) \
|
||||
PRINT_ITEM(name);
|
||||
|
||||
int mbedtls_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;
|
||||
char *p = *buf;
|
||||
const char *sep = "";
|
||||
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA");
|
||||
|
||||
*size = n;
|
||||
*buf = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define KEY_USAGE(code, name) \
|
||||
if (key_usage & (code)) \
|
||||
PRINT_ITEM(name);
|
||||
|
||||
int mbedtls_x509_info_key_usage(char **buf, size_t *size,
|
||||
unsigned int key_usage)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t n = *size;
|
||||
char *p = *buf;
|
||||
const char *sep = "";
|
||||
|
||||
KEY_USAGE(MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only");
|
||||
|
||||
*size = n;
|
||||
*buf = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_X509_REMOVE_INFO */
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C || MBEDTLS_X509_CSR_PARSE_C */
|
||||
#endif /* MBEDTLS_X509_USE_C */
|
||||
|
@ -562,63 +562,6 @@ static int x509_get_basic_constraints(unsigned char **p,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_x509_get_ns_cert_type(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
unsigned char *ns_cert_type)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_x509_bitstring bs = { 0, 0, NULL };
|
||||
|
||||
if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if (bs.len == 0) {
|
||||
*ns_cert_type = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bs.len != 1) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_INVALID_LENGTH);
|
||||
}
|
||||
|
||||
/* Get actual bitstring */
|
||||
*ns_cert_type = *bs.p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_x509_get_key_usage(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
unsigned int *key_usage)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t i;
|
||||
mbedtls_x509_bitstring bs = { 0, 0, NULL };
|
||||
|
||||
if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if (bs.len == 0) {
|
||||
*key_usage = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bs.len < 1) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_INVALID_LENGTH);
|
||||
}
|
||||
|
||||
/* Get actual bitstring */
|
||||
*key_usage = 0;
|
||||
for (i = 0; i < bs.len && i < sizeof(unsigned int); i++) {
|
||||
*key_usage |= (unsigned int) bs.p[i] << (8*i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
|
||||
*
|
||||
@ -643,118 +586,6 @@ static int x509_get_ext_key_usage(unsigned char **p,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* SubjectAltName ::= GeneralNames
|
||||
*
|
||||
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
|
||||
*
|
||||
* GeneralName ::= CHOICE {
|
||||
* otherName [0] OtherName,
|
||||
* rfc822Name [1] IA5String,
|
||||
* dNSName [2] IA5String,
|
||||
* x400Address [3] ORAddress,
|
||||
* directoryName [4] Name,
|
||||
* ediPartyName [5] EDIPartyName,
|
||||
* uniformResourceIdentifier [6] IA5String,
|
||||
* iPAddress [7] OCTET STRING,
|
||||
* registeredID [8] OBJECT IDENTIFIER }
|
||||
*
|
||||
* OtherName ::= SEQUENCE {
|
||||
* type-id OBJECT IDENTIFIER,
|
||||
* value [0] EXPLICIT ANY DEFINED BY type-id }
|
||||
*
|
||||
* EDIPartyName ::= SEQUENCE {
|
||||
* nameAssigner [0] DirectoryString OPTIONAL,
|
||||
* partyName [1] DirectoryString }
|
||||
*
|
||||
* NOTE: we list all types, but only use dNSName and otherName
|
||||
* of type HwModuleName, as defined in RFC 4108, at this point.
|
||||
*/
|
||||
int mbedtls_x509_get_subject_alt_name(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_x509_sequence *subject_alt_name)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len, tag_len;
|
||||
mbedtls_asn1_buf *buf;
|
||||
unsigned char tag;
|
||||
mbedtls_asn1_sequence *cur = subject_alt_name;
|
||||
|
||||
/* Get main sequence tag */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if (*p + len != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
while (*p < end) {
|
||||
mbedtls_x509_subject_alternative_name dummy_san_buf;
|
||||
memset(&dummy_san_buf, 0, sizeof(dummy_san_buf));
|
||||
|
||||
tag = **p;
|
||||
(*p)++;
|
||||
if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if ((tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the SAN is structured correctly.
|
||||
*/
|
||||
ret = mbedtls_x509_parse_subject_alt_name(&(cur->buf), &dummy_san_buf);
|
||||
/*
|
||||
* In case the extension is malformed, return an error,
|
||||
* and clear the allocated sequences.
|
||||
*/
|
||||
if (ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
|
||||
mbedtls_asn1_sequence_free(subject_alt_name->next);
|
||||
subject_alt_name->next = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Allocate and assign next pointer */
|
||||
if (cur->buf.p != NULL) {
|
||||
if (cur->next != NULL) {
|
||||
return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
|
||||
}
|
||||
|
||||
cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
|
||||
|
||||
if (cur->next == NULL) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_ALLOC_FAILED);
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
buf = &(cur->buf);
|
||||
buf->tag = tag;
|
||||
buf->p = *p;
|
||||
buf->len = tag_len;
|
||||
*p += buf->len;
|
||||
}
|
||||
|
||||
/* Set final sequence entry's next pointer to NULL */
|
||||
cur->next = NULL;
|
||||
|
||||
if (*p != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
|
||||
*
|
||||
@ -1713,319 +1544,7 @@ cleanup:
|
||||
}
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
||||
/*
|
||||
* OtherName ::= SEQUENCE {
|
||||
* type-id OBJECT IDENTIFIER,
|
||||
* value [0] EXPLICIT ANY DEFINED BY type-id }
|
||||
*
|
||||
* HardwareModuleName ::= SEQUENCE {
|
||||
* hwType OBJECT IDENTIFIER,
|
||||
* hwSerialNum OCTET STRING }
|
||||
*
|
||||
* NOTE: we currently only parse and use otherName of type HwModuleName,
|
||||
* as defined in RFC 4108.
|
||||
*/
|
||||
static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
|
||||
mbedtls_x509_san_other_name *other_name)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t len;
|
||||
unsigned char *p = subject_alt_name->p;
|
||||
const unsigned char *end = p + subject_alt_name->len;
|
||||
mbedtls_x509_buf cur_oid;
|
||||
|
||||
if ((subject_alt_name->tag &
|
||||
(MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK)) !=
|
||||
(MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME)) {
|
||||
/*
|
||||
* The given subject alternative name is not of type "othername".
|
||||
*/
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_OID)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
cur_oid.tag = MBEDTLS_ASN1_OID;
|
||||
cur_oid.p = p;
|
||||
cur_oid.len = len;
|
||||
|
||||
/*
|
||||
* Only HwModuleName is currently supported.
|
||||
*/
|
||||
if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) != 0) {
|
||||
return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
if (p + len >= end) {
|
||||
mbedtls_platform_zeroize(other_name, sizeof(*other_name));
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
p += len;
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
|
||||
0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID;
|
||||
other_name->value.hardware_module_name.oid.p = p;
|
||||
other_name->value.hardware_module_name.oid.len = len;
|
||||
|
||||
if (p + len >= end) {
|
||||
mbedtls_platform_zeroize(other_name, sizeof(*other_name));
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
p += len;
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_OCTET_STRING)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING;
|
||||
other_name->value.hardware_module_name.val.p = p;
|
||||
other_name->value.hardware_module_name.val.len = len;
|
||||
p += len;
|
||||
if (p != end) {
|
||||
mbedtls_platform_zeroize(other_name,
|
||||
sizeof(*other_name));
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
|
||||
mbedtls_x509_subject_alternative_name *san)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
switch (san_buf->tag &
|
||||
(MBEDTLS_ASN1_TAG_CLASS_MASK |
|
||||
MBEDTLS_ASN1_TAG_VALUE_MASK)) {
|
||||
/*
|
||||
* otherName
|
||||
*/
|
||||
case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME):
|
||||
{
|
||||
mbedtls_x509_san_other_name other_name;
|
||||
|
||||
ret = x509_get_other_name(san_buf, &other_name);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
|
||||
san->type = MBEDTLS_X509_SAN_OTHER_NAME;
|
||||
memcpy(&san->san.other_name,
|
||||
&other_name, sizeof(other_name));
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* dNSName
|
||||
*/
|
||||
case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME):
|
||||
{
|
||||
memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
|
||||
san->type = MBEDTLS_X509_SAN_DNS_NAME;
|
||||
|
||||
memcpy(&san->san.unstructured_name,
|
||||
san_buf, sizeof(*san_buf));
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* Type not supported
|
||||
*/
|
||||
default:
|
||||
return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
int mbedtls_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;
|
||||
size_t n = *size;
|
||||
char *p = *buf;
|
||||
const mbedtls_x509_sequence *cur = subject_alt_name;
|
||||
mbedtls_x509_subject_alternative_name san;
|
||||
int parse_ret;
|
||||
|
||||
while (cur != NULL) {
|
||||
memset(&san, 0, sizeof(san));
|
||||
parse_ret = mbedtls_x509_parse_subject_alt_name(&cur->buf, &san);
|
||||
if (parse_ret != 0) {
|
||||
if (parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
|
||||
ret = mbedtls_snprintf(p, n, "\n%s <unsupported>", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
} else {
|
||||
ret = mbedtls_snprintf(p, n, "\n%s <malformed>", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
}
|
||||
cur = cur->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (san.type) {
|
||||
/*
|
||||
* otherName
|
||||
*/
|
||||
case MBEDTLS_X509_SAN_OTHER_NAME:
|
||||
{
|
||||
mbedtls_x509_san_other_name *other_name = &san.san.other_name;
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "\n%s otherName :", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME,
|
||||
&other_name->value.hardware_module_name.oid) != 0) {
|
||||
ret = mbedtls_snprintf(p, n, "\n%s hardware module name :", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
ret =
|
||||
mbedtls_snprintf(p, n, "\n%s hardware type : ", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_oid_get_numeric_string(p,
|
||||
n,
|
||||
&other_name->value.hardware_module_name.oid);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret =
|
||||
mbedtls_snprintf(p, n, "\n%s hardware serial number : ", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
for (i = 0; i < other_name->value.hardware_module_name.val.len; i++) {
|
||||
ret = mbedtls_snprintf(p,
|
||||
n,
|
||||
"%02X",
|
||||
other_name->value.hardware_module_name.val.p[i]);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
}
|
||||
}/* MBEDTLS_OID_ON_HW_MODULE_NAME */
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* dNSName
|
||||
*/
|
||||
case MBEDTLS_X509_SAN_DNS_NAME:
|
||||
{
|
||||
ret = mbedtls_snprintf(p, n, "\n%s dNSName : ", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
if (san.san.unstructured_name.len >= n) {
|
||||
*p = '\0';
|
||||
return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len);
|
||||
p += san.san.unstructured_name.len;
|
||||
n -= san.san.unstructured_name.len;
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* Type not supported, skip item.
|
||||
*/
|
||||
default:
|
||||
ret = mbedtls_snprintf(p, n, "\n%s <unsupported>", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
break;
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
*size = n;
|
||||
*buf = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PRINT_ITEM(i) \
|
||||
{ \
|
||||
ret = mbedtls_snprintf(p, n, "%s" i, sep); \
|
||||
MBEDTLS_X509_SAFE_SNPRINTF; \
|
||||
sep = ", "; \
|
||||
}
|
||||
|
||||
#define CERT_TYPE(type, name) \
|
||||
if (ns_cert_type & (type)) \
|
||||
PRINT_ITEM(name);
|
||||
|
||||
int mbedtls_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;
|
||||
char *p = *buf;
|
||||
const char *sep = "";
|
||||
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA");
|
||||
CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA");
|
||||
|
||||
*size = n;
|
||||
*buf = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define KEY_USAGE(code, name) \
|
||||
if (key_usage & (code)) \
|
||||
PRINT_ITEM(name);
|
||||
|
||||
int mbedtls_x509_info_key_usage(char **buf, size_t *size,
|
||||
unsigned int key_usage)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t n = *size;
|
||||
char *p = *buf;
|
||||
const char *sep = "";
|
||||
|
||||
KEY_USAGE(MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only");
|
||||
KEY_USAGE(MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only");
|
||||
|
||||
*size = n;
|
||||
*buf = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int x509_info_ext_key_usage(char **buf, size_t *size,
|
||||
const mbedtls_x509_sequence *extended_key_usage)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user