diff --git a/include/mbedtls/asn1write.h b/include/mbedtls/asn1write.h index a439268b0e..f453169e2e 100644 --- a/include/mbedtls/asn1write.h +++ b/include/mbedtls/asn1write.h @@ -158,6 +158,27 @@ int mbedtls_asn1_write_algorithm_identifier(unsigned char **p, const char *oid, size_t oid_len, size_t par_len); +/** + * \brief Write an AlgorithmIdentifier sequence in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param oid The OID of the algorithm to write. + * \param oid_len The length of the algorithm's OID. + * \param par_len The length of the parameters, which must be already written. + * \param has_par If there are any parameters. If 0, par_len must be 0. If 1 + * and \p par_len is 0, NULL parameters are added. + * + * \return The number of bytes written to \p p on success. + * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p, + unsigned char *start, + const char *oid, size_t oid_len, + size_t par_len, int has_par); + /** * \brief Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value * in ASN.1 format. diff --git a/library/asn1write.c b/library/asn1write.c index 0b487dceaa..f9c3830564 100644 --- a/library/asn1write.c +++ b/library/asn1write.c @@ -194,25 +194,34 @@ int mbedtls_asn1_write_oid(unsigned char **p, unsigned char *start, int mbedtls_asn1_write_algorithm_identifier(unsigned char **p, unsigned char *start, const char *oid, size_t oid_len, size_t par_len) +{ + return mbedtls_asn1_write_algorithm_identifier_ext(p, start, oid, oid_len, par_len, 1); +} + +int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + size_t par_len, int has_par) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t len = 0; - if (par_len == 0) { - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_null(p, start)); - } else { - len += par_len; + if (has_par) { + if (par_len == 0) { + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_null(p, start)); + } else { + len += par_len; + } } MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len)); MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE)); return (int) len; -} + } int mbedtls_asn1_write_bool(unsigned char **p, unsigned char *start, int boolean) {