summaryrefslogtreecommitdiffstats
path: root/thirdparty/mbedtls/library/x509write_crt.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/mbedtls/library/x509write_crt.c')
-rw-r--r--thirdparty/mbedtls/library/x509write_crt.c249
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;
}