diff options
Diffstat (limited to 'thirdparty/mbedtls/library/x509write_crt.c')
-rw-r--r-- | thirdparty/mbedtls/library/x509write_crt.c | 249 |
1 files changed, 193 insertions, 56 deletions
diff --git a/thirdparty/mbedtls/library/x509write_crt.c b/thirdparty/mbedtls/library/x509write_crt.c index 1e16b53b3d..72f5a10a17 100644 --- a/thirdparty/mbedtls/library/x509write_crt.c +++ b/thirdparty/mbedtls/library/x509write_crt.c @@ -16,30 +16,36 @@ #if defined(MBEDTLS_X509_CRT_WRITE_C) #include "mbedtls/x509_crt.h" +#include "x509_internal.h" #include "mbedtls/asn1write.h" #include "mbedtls/error.h" #include "mbedtls/oid.h" +#include "mbedtls/platform.h" #include "mbedtls/platform_util.h" -#include "mbedtls/sha1.h" +#include "mbedtls/md.h" #include <string.h> +#include <stdint.h> #if defined(MBEDTLS_PEM_WRITE_C) #include "mbedtls/pem.h" #endif /* MBEDTLS_PEM_WRITE_C */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#include "psa/crypto.h" +#include "psa_util_internal.h" +#include "mbedtls/psa_util.h" +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + void mbedtls_x509write_crt_init(mbedtls_x509write_cert *ctx) { memset(ctx, 0, sizeof(mbedtls_x509write_cert)); - mbedtls_mpi_init(&ctx->serial); ctx->version = MBEDTLS_X509_CRT_VERSION_3; } void mbedtls_x509write_crt_free(mbedtls_x509write_cert *ctx) { - mbedtls_mpi_free(&ctx->serial); - mbedtls_asn1_free_named_data_list(&ctx->subject); mbedtls_asn1_free_named_data_list(&ctx->issuer); mbedtls_asn1_free_named_data_list(&ctx->extensions); @@ -83,21 +89,42 @@ int mbedtls_x509write_crt_set_issuer_name(mbedtls_x509write_cert *ctx, return mbedtls_x509_string_to_names(&ctx->issuer, issuer_name); } +#if defined(MBEDTLS_BIGNUM_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) int mbedtls_x509write_crt_set_serial(mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + int ret; + size_t tmp_len; - if (mbedtls_mpi_size(serial) > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) { + /* Ensure that the MPI value fits into the buffer */ + tmp_len = mbedtls_mpi_size(serial); + if (tmp_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) { return MBEDTLS_ERR_X509_BAD_INPUT_DATA; } - if ((ret = mbedtls_mpi_copy(&ctx->serial, serial)) != 0) { + ctx->serial_len = tmp_len; + + ret = mbedtls_mpi_write_binary(serial, ctx->serial, tmp_len); + if (ret < 0) { return ret; } return 0; } +#endif // MBEDTLS_BIGNUM_C && !MBEDTLS_DEPRECATED_REMOVED + +int mbedtls_x509write_crt_set_serial_raw(mbedtls_x509write_cert *ctx, + unsigned char *serial, size_t serial_len) +{ + if (serial_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) { + return MBEDTLS_ERR_X509_BAD_INPUT_DATA; + } + + ctx->serial_len = serial_len; + memcpy(ctx->serial, serial, serial_len); + + return 0; +} int mbedtls_x509write_crt_set_validity(mbedtls_x509write_cert *ctx, const char *not_before, @@ -115,6 +142,13 @@ int mbedtls_x509write_crt_set_validity(mbedtls_x509write_cert *ctx, return 0; } +int mbedtls_x509write_crt_set_subject_alternative_name(mbedtls_x509write_cert *ctx, + const mbedtls_x509_san_list *san_list) +{ + return mbedtls_x509_write_set_san_common(&ctx->extensions, san_list); +} + + int mbedtls_x509write_crt_set_extension(mbedtls_x509write_cert *ctx, const char *oid, size_t oid_len, int critical, @@ -157,71 +191,92 @@ int mbedtls_x509write_crt_set_basic_constraints(mbedtls_x509write_cert *ctx, is_ca, buf + sizeof(buf) - len, len); } -#if defined(MBEDTLS_SHA1_C) -int mbedtls_x509write_crt_set_subject_key_identifier(mbedtls_x509write_cert *ctx) +#if defined(MBEDTLS_MD_CAN_SHA1) +static int mbedtls_x509write_crt_set_key_identifier(mbedtls_x509write_cert *ctx, + int is_ca, + unsigned char tag) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ unsigned char *c = buf + sizeof(buf); size_t len = 0; +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + size_t hash_length; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ memset(buf, 0, sizeof(buf)); MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_pk_write_pubkey(&c, buf, ctx->subject_key)); - - ret = mbedtls_sha1_ret(buf + sizeof(buf) - len, len, - buf + sizeof(buf) - 20); + mbedtls_pk_write_pubkey(&c, + buf, + is_ca ? + ctx->issuer_key : + ctx->subject_key)); + + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + status = psa_hash_compute(PSA_ALG_SHA_1, + buf + sizeof(buf) - len, + len, + buf + sizeof(buf) - 20, + 20, + &hash_length); + if (status != PSA_SUCCESS) { + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } +#else + ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), + buf + sizeof(buf) - len, len, + buf + sizeof(buf) - 20); if (ret != 0) { return ret; } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + c = buf + sizeof(buf) - 20; len = 20; MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_OCTET_STRING)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, tag)); - return mbedtls_x509write_crt_set_extension(ctx, - MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, - MBEDTLS_OID_SIZE(MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER), - 0, buf + sizeof(buf) - len, len); -} - -int mbedtls_x509write_crt_set_authority_key_identifier(mbedtls_x509write_cert *ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ - unsigned char *c = buf + sizeof(buf); - size_t len = 0; - - memset(buf, 0, sizeof(buf)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_pk_write_pubkey(&c, buf, ctx->issuer_key)); - - ret = mbedtls_sha1_ret(buf + sizeof(buf) - len, len, - buf + sizeof(buf) - 20); - if (ret != 0) { - return ret; + if (is_ca) { // writes AuthorityKeyIdentifier sequence + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); + MBEDTLS_ASN1_CHK_ADD(len, + mbedtls_asn1_write_tag(&c, + buf, + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE)); } - c = buf + sizeof(buf) - 20; - len = 20; - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0)); + if (is_ca) { + return mbedtls_x509write_crt_set_extension(ctx, + MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, + MBEDTLS_OID_SIZE( + MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER), + 0, buf + sizeof(buf) - len, len); + } else { + return mbedtls_x509write_crt_set_extension(ctx, + MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, + MBEDTLS_OID_SIZE( + MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER), + 0, buf + sizeof(buf) - len, len); + } +} - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); +int mbedtls_x509write_crt_set_subject_key_identifier(mbedtls_x509write_cert *ctx) +{ + return mbedtls_x509write_crt_set_key_identifier(ctx, + 0, + MBEDTLS_ASN1_OCTET_STRING); +} - return mbedtls_x509write_crt_set_extension( - ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, - MBEDTLS_OID_SIZE(MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER), - 0, buf + sizeof(buf) - len, len); +int mbedtls_x509write_crt_set_authority_key_identifier(mbedtls_x509write_cert *ctx) +{ + return mbedtls_x509write_crt_set_key_identifier(ctx, + 1, + (MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0)); } -#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_MD_CAN_SHA1 */ int mbedtls_x509write_crt_set_key_usage(mbedtls_x509write_cert *ctx, unsigned int key_usage) @@ -264,6 +319,47 @@ int mbedtls_x509write_crt_set_key_usage(mbedtls_x509write_cert *ctx, return 0; } +int mbedtls_x509write_crt_set_ext_key_usage(mbedtls_x509write_cert *ctx, + const mbedtls_asn1_sequence *exts) +{ + unsigned char buf[256]; + unsigned char *c = buf + sizeof(buf); + int ret; + size_t len = 0; + const mbedtls_asn1_sequence *last_ext = NULL; + const mbedtls_asn1_sequence *ext; + + memset(buf, 0, sizeof(buf)); + + /* We need at least one extension: SEQUENCE SIZE (1..MAX) OF KeyPurposeId */ + if (exts == NULL) { + return MBEDTLS_ERR_X509_BAD_INPUT_DATA; + } + + /* Iterate over exts backwards, so we write them out in the requested order */ + while (last_ext != exts) { + for (ext = exts; ext->next != last_ext; ext = ext->next) { + } + if (ext->buf.tag != MBEDTLS_ASN1_OID) { + return MBEDTLS_ERR_X509_BAD_INPUT_DATA; + } + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf, ext->buf.p, ext->buf.len)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, ext->buf.len)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_OID)); + last_ext = ext; + } + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); + MBEDTLS_ASN1_CHK_ADD(len, + mbedtls_asn1_write_tag(&c, buf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); + + return mbedtls_x509write_crt_set_extension(ctx, + MBEDTLS_OID_EXTENDED_KEY_USAGE, + MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE), + 1, c, len); +} + int mbedtls_x509write_crt_set_ns_cert_type(mbedtls_x509write_cert *ctx, unsigned char ns_cert_type) { @@ -325,8 +421,14 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, const char *sig_oid; size_t sig_oid_len = 0; unsigned char *c, *c2; - unsigned char hash[64]; unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; + size_t hash_length = 0; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_algorithm_t psa_algorithm; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; size_t len = 0; mbedtls_pk_type_t pk_alg; @@ -380,7 +482,7 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, */ MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_pk_write_pubkey_der(ctx->subject_key, - buf, c - buf)); + buf, (size_t) (c - buf))); c -= pub_len; len += pub_len; @@ -439,9 +541,29 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, /* * Serial ::= INTEGER + * + * Written data is: + * - "ctx->serial_len" bytes for the raw serial buffer + * - if MSb of "serial" is 1, then prepend an extra 0x00 byte + * - 1 byte for the length + * - 1 byte for the TAG */ - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&c, buf, - &ctx->serial)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf, + ctx->serial, ctx->serial_len)); + if (*c & 0x80) { + if (c - buf < 1) { + return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; + } + *(--c) = 0x0; + len++; + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, + ctx->serial_len + 1)); + } else { + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, + ctx->serial_len)); + } + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, + MBEDTLS_ASN1_INTEGER)); /* * Version ::= INTEGER { v1(0), v2(1), v3(2) } @@ -471,13 +593,28 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, */ /* Compute hash of CRT. */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_algorithm = mbedtls_md_psa_alg_from_type(ctx->md_alg); + + status = psa_hash_compute(psa_algorithm, + c, + len, + hash, + sizeof(hash), + &hash_length); + if (status != PSA_SUCCESS) { + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } +#else if ((ret = mbedtls_md(mbedtls_md_info_from_type(ctx->md_alg), c, len, hash)) != 0) { return ret; } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + if ((ret = mbedtls_pk_sign(ctx->issuer_key, ctx->md_alg, - hash, 0, sig, &sig_len, + hash, hash_length, sig, sizeof(sig), &sig_len, f_rng, p_rng)) != 0) { return ret; } |