xref: /optee_os/lib/libmbedtls/mbedtls/library/x509write_csr.c (revision 273a583ea99627ff3b8ccbbaedbdacecd0909b2e)
1817466cbSJens Wiklander /*
2817466cbSJens Wiklander  *  X.509 Certificate Signing Request writing
3817466cbSJens Wiklander  *
47901324dSJerome Forissier  *  Copyright The Mbed TLS Contributors
5b0563631STom Van Eyck  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6817466cbSJens Wiklander  */
7817466cbSJens Wiklander /*
8817466cbSJens Wiklander  * References:
9817466cbSJens Wiklander  * - CSRs: PKCS#10 v1.7 aka RFC 2986
10817466cbSJens Wiklander  * - attributes: PKCS#9 v2.0 aka RFC 2985
11817466cbSJens Wiklander  */
12817466cbSJens Wiklander 
137901324dSJerome Forissier #include "common.h"
14817466cbSJens Wiklander 
15817466cbSJens Wiklander #if defined(MBEDTLS_X509_CSR_WRITE_C)
16817466cbSJens Wiklander 
17b0563631STom Van Eyck #include "x509_internal.h"
18817466cbSJens Wiklander #include "mbedtls/x509_csr.h"
19817466cbSJens Wiklander #include "mbedtls/asn1write.h"
2011fa71b9SJerome Forissier #include "mbedtls/error.h"
2111fa71b9SJerome Forissier #include "mbedtls/oid.h"
223d3b0591SJens Wiklander #include "mbedtls/platform_util.h"
23817466cbSJens Wiklander 
2411fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO)
2511fa71b9SJerome Forissier #include "psa/crypto.h"
26b0563631STom Van Eyck #include "psa_util_internal.h"
2711fa71b9SJerome Forissier #include "mbedtls/psa_util.h"
2832b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
2911fa71b9SJerome Forissier 
30817466cbSJens Wiklander #include <string.h>
31817466cbSJens Wiklander #include <stdlib.h>
32817466cbSJens Wiklander 
33817466cbSJens Wiklander #if defined(MBEDTLS_PEM_WRITE_C)
34817466cbSJens Wiklander #include "mbedtls/pem.h"
35817466cbSJens Wiklander #endif
36817466cbSJens Wiklander 
377901324dSJerome Forissier #include "mbedtls/platform.h"
387901324dSJerome Forissier 
mbedtls_x509write_csr_init(mbedtls_x509write_csr * ctx)39817466cbSJens Wiklander void mbedtls_x509write_csr_init(mbedtls_x509write_csr *ctx)
40817466cbSJens Wiklander {
41817466cbSJens Wiklander     memset(ctx, 0, sizeof(mbedtls_x509write_csr));
42817466cbSJens Wiklander }
43817466cbSJens Wiklander 
mbedtls_x509write_csr_free(mbedtls_x509write_csr * ctx)44817466cbSJens Wiklander void mbedtls_x509write_csr_free(mbedtls_x509write_csr *ctx)
45817466cbSJens Wiklander {
46cb034002SJerome Forissier     if (ctx == NULL) {
47cb034002SJerome Forissier         return;
48cb034002SJerome Forissier     }
49cb034002SJerome Forissier 
50817466cbSJens Wiklander     mbedtls_asn1_free_named_data_list(&ctx->subject);
51817466cbSJens Wiklander     mbedtls_asn1_free_named_data_list(&ctx->extensions);
52817466cbSJens Wiklander 
533d3b0591SJens Wiklander     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_x509write_csr));
54817466cbSJens Wiklander }
55817466cbSJens Wiklander 
mbedtls_x509write_csr_set_md_alg(mbedtls_x509write_csr * ctx,mbedtls_md_type_t md_alg)56817466cbSJens Wiklander void mbedtls_x509write_csr_set_md_alg(mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg)
57817466cbSJens Wiklander {
58817466cbSJens Wiklander     ctx->md_alg = md_alg;
59817466cbSJens Wiklander }
60817466cbSJens Wiklander 
mbedtls_x509write_csr_set_key(mbedtls_x509write_csr * ctx,mbedtls_pk_context * key)61817466cbSJens Wiklander void mbedtls_x509write_csr_set_key(mbedtls_x509write_csr *ctx, mbedtls_pk_context *key)
62817466cbSJens Wiklander {
63817466cbSJens Wiklander     ctx->key = key;
64817466cbSJens Wiklander }
65817466cbSJens Wiklander 
mbedtls_x509write_csr_set_subject_name(mbedtls_x509write_csr * ctx,const char * subject_name)66817466cbSJens Wiklander int mbedtls_x509write_csr_set_subject_name(mbedtls_x509write_csr *ctx,
67817466cbSJens Wiklander                                            const char *subject_name)
68817466cbSJens Wiklander {
69*273a583eSThomas Bourgoin     mbedtls_asn1_free_named_data_list(&ctx->subject);
70817466cbSJens Wiklander     return mbedtls_x509_string_to_names(&ctx->subject, subject_name);
71817466cbSJens Wiklander }
72817466cbSJens Wiklander 
mbedtls_x509write_csr_set_extension(mbedtls_x509write_csr * ctx,const char * oid,size_t oid_len,int critical,const unsigned char * val,size_t val_len)73817466cbSJens Wiklander int mbedtls_x509write_csr_set_extension(mbedtls_x509write_csr *ctx,
74817466cbSJens Wiklander                                         const char *oid, size_t oid_len,
7532b31808SJens Wiklander                                         int critical,
76817466cbSJens Wiklander                                         const unsigned char *val, size_t val_len)
77817466cbSJens Wiklander {
78817466cbSJens Wiklander     return mbedtls_x509_set_extension(&ctx->extensions, oid, oid_len,
7932b31808SJens Wiklander                                       critical, val, val_len);
8032b31808SJens Wiklander }
8132b31808SJens Wiklander 
mbedtls_x509write_csr_set_subject_alternative_name(mbedtls_x509write_csr * ctx,const mbedtls_x509_san_list * san_list)8232b31808SJens Wiklander int mbedtls_x509write_csr_set_subject_alternative_name(mbedtls_x509write_csr *ctx,
8332b31808SJens Wiklander                                                        const mbedtls_x509_san_list *san_list)
8432b31808SJens Wiklander {
85b0563631STom Van Eyck     return mbedtls_x509_write_set_san_common(&ctx->extensions, san_list);
86817466cbSJens Wiklander }
87817466cbSJens Wiklander 
mbedtls_x509write_csr_set_key_usage(mbedtls_x509write_csr * ctx,unsigned char key_usage)88817466cbSJens Wiklander int mbedtls_x509write_csr_set_key_usage(mbedtls_x509write_csr *ctx, unsigned char key_usage)
89817466cbSJens Wiklander {
907901324dSJerome Forissier     unsigned char buf[4] = { 0 };
91817466cbSJens Wiklander     unsigned char *c;
9211fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
93817466cbSJens Wiklander 
94817466cbSJens Wiklander     c = buf + 4;
95817466cbSJens Wiklander 
9611fa71b9SJerome Forissier     ret = mbedtls_asn1_write_named_bitstring(&c, buf, &key_usage, 8);
9732b31808SJens Wiklander     if (ret < 3 || ret > 4) {
9832b31808SJens Wiklander         return ret;
9932b31808SJens Wiklander     }
100817466cbSJens Wiklander 
101817466cbSJens Wiklander     ret = mbedtls_x509write_csr_set_extension(ctx, MBEDTLS_OID_KEY_USAGE,
102817466cbSJens Wiklander                                               MBEDTLS_OID_SIZE(MBEDTLS_OID_KEY_USAGE),
10332b31808SJens Wiklander                                               0, c, (size_t) ret);
10432b31808SJens Wiklander     if (ret != 0) {
10532b31808SJens Wiklander         return ret;
10632b31808SJens Wiklander     }
107817466cbSJens Wiklander 
10832b31808SJens Wiklander     return 0;
109817466cbSJens Wiklander }
110817466cbSJens Wiklander 
mbedtls_x509write_csr_set_ns_cert_type(mbedtls_x509write_csr * ctx,unsigned char ns_cert_type)111817466cbSJens Wiklander int mbedtls_x509write_csr_set_ns_cert_type(mbedtls_x509write_csr *ctx,
112817466cbSJens Wiklander                                            unsigned char ns_cert_type)
113817466cbSJens Wiklander {
1147901324dSJerome Forissier     unsigned char buf[4] = { 0 };
115817466cbSJens Wiklander     unsigned char *c;
11611fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
117817466cbSJens Wiklander 
118817466cbSJens Wiklander     c = buf + 4;
119817466cbSJens Wiklander 
12011fa71b9SJerome Forissier     ret = mbedtls_asn1_write_named_bitstring(&c, buf, &ns_cert_type, 8);
12132b31808SJens Wiklander     if (ret < 3 || ret > 4) {
12232b31808SJens Wiklander         return ret;
12332b31808SJens Wiklander     }
124817466cbSJens Wiklander 
125817466cbSJens Wiklander     ret = mbedtls_x509write_csr_set_extension(ctx, MBEDTLS_OID_NS_CERT_TYPE,
126817466cbSJens Wiklander                                               MBEDTLS_OID_SIZE(MBEDTLS_OID_NS_CERT_TYPE),
12732b31808SJens Wiklander                                               0, c, (size_t) ret);
12832b31808SJens Wiklander     if (ret != 0) {
12932b31808SJens Wiklander         return ret;
13032b31808SJens Wiklander     }
131817466cbSJens Wiklander 
13232b31808SJens Wiklander     return 0;
133817466cbSJens Wiklander }
134817466cbSJens Wiklander 
x509write_csr_der_internal(mbedtls_x509write_csr * ctx,unsigned char * buf,size_t size,unsigned char * sig,size_t sig_size,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1357901324dSJerome Forissier static int x509write_csr_der_internal(mbedtls_x509write_csr *ctx,
1367901324dSJerome Forissier                                       unsigned char *buf,
1377901324dSJerome Forissier                                       size_t size,
13832b31808SJens Wiklander                                       unsigned char *sig, size_t sig_size,
139817466cbSJens Wiklander                                       int (*f_rng)(void *, unsigned char *, size_t),
140817466cbSJens Wiklander                                       void *p_rng)
141817466cbSJens Wiklander {
14211fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
143817466cbSJens Wiklander     const char *sig_oid;
144817466cbSJens Wiklander     size_t sig_oid_len = 0;
145817466cbSJens Wiklander     unsigned char *c, *c2;
146b0563631STom Van Eyck     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
147817466cbSJens Wiklander     size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
148817466cbSJens Wiklander     size_t len = 0;
149817466cbSJens Wiklander     mbedtls_pk_type_t pk_alg;
15011fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO)
15111fa71b9SJerome Forissier     size_t hash_len;
152b0563631STom Van Eyck     psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(ctx->md_alg);
15311fa71b9SJerome Forissier #endif /* MBEDTLS_USE_PSA_CRYPTO */
154817466cbSJens Wiklander 
1557901324dSJerome Forissier     /* Write the CSR backwards starting from the end of buf */
1567901324dSJerome Forissier     c = buf + size;
1577901324dSJerome Forissier 
1587901324dSJerome Forissier     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_x509_write_extensions(&c, buf,
1597901324dSJerome Forissier                                                             ctx->extensions));
160817466cbSJens Wiklander 
16132b31808SJens Wiklander     if (len) {
1627901324dSJerome Forissier         MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
1637901324dSJerome Forissier         MBEDTLS_ASN1_CHK_ADD(len,
1647901324dSJerome Forissier                              mbedtls_asn1_write_tag(
1657901324dSJerome Forissier                                  &c, buf,
1667901324dSJerome Forissier                                  MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
167817466cbSJens Wiklander 
1687901324dSJerome Forissier         MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
1697901324dSJerome Forissier         MBEDTLS_ASN1_CHK_ADD(len,
1707901324dSJerome Forissier                              mbedtls_asn1_write_tag(
1717901324dSJerome Forissier                                  &c, buf,
1727901324dSJerome Forissier                                  MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET));
173817466cbSJens Wiklander 
1747901324dSJerome Forissier         MBEDTLS_ASN1_CHK_ADD(len,
1757901324dSJerome Forissier                              mbedtls_asn1_write_oid(
1767901324dSJerome Forissier                                  &c, buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ,
177817466cbSJens Wiklander                                  MBEDTLS_OID_SIZE(MBEDTLS_OID_PKCS9_CSR_EXT_REQ)));
178817466cbSJens Wiklander 
1797901324dSJerome Forissier         MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
1807901324dSJerome Forissier         MBEDTLS_ASN1_CHK_ADD(len,
1817901324dSJerome Forissier                              mbedtls_asn1_write_tag(
1827901324dSJerome Forissier                                  &c, buf,
1837901324dSJerome Forissier                                  MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
184817466cbSJens Wiklander     }
185817466cbSJens Wiklander 
1867901324dSJerome Forissier     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
1877901324dSJerome Forissier     MBEDTLS_ASN1_CHK_ADD(len,
1887901324dSJerome Forissier                          mbedtls_asn1_write_tag(
1897901324dSJerome Forissier                              &c, buf,
1907901324dSJerome Forissier                              MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC));
191817466cbSJens Wiklander 
192817466cbSJens Wiklander     MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_pk_write_pubkey_der(ctx->key,
193b0563631STom Van Eyck                                                               buf, (size_t) (c - buf)));
194817466cbSJens Wiklander     c -= pub_len;
195817466cbSJens Wiklander     len += pub_len;
196817466cbSJens Wiklander 
197817466cbSJens Wiklander     /*
198817466cbSJens Wiklander      *  Subject  ::=  Name
199817466cbSJens Wiklander      */
2007901324dSJerome Forissier     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_x509_write_names(&c, buf,
2017901324dSJerome Forissier                                                        ctx->subject));
202817466cbSJens Wiklander 
203817466cbSJens Wiklander     /*
204817466cbSJens Wiklander      *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
205817466cbSJens Wiklander      */
2067901324dSJerome Forissier     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(&c, buf, 0));
207817466cbSJens Wiklander 
2087901324dSJerome Forissier     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
2097901324dSJerome Forissier     MBEDTLS_ASN1_CHK_ADD(len,
2107901324dSJerome Forissier                          mbedtls_asn1_write_tag(
2117901324dSJerome Forissier                              &c, buf,
2127901324dSJerome Forissier                              MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
213817466cbSJens Wiklander 
214817466cbSJens Wiklander     /*
2157901324dSJerome Forissier      * Sign the written CSR data into the sig buffer
21611fa71b9SJerome Forissier      * Note: hash errors can happen only after an internal error
217817466cbSJens Wiklander      */
21811fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO)
21932b31808SJens Wiklander     if (psa_hash_compute(hash_alg,
22032b31808SJens Wiklander                          c,
22132b31808SJens Wiklander                          len,
22232b31808SJens Wiklander                          hash,
22332b31808SJens Wiklander                          sizeof(hash),
22432b31808SJens Wiklander                          &hash_len) != PSA_SUCCESS) {
22532b31808SJens Wiklander         return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
22611fa71b9SJerome Forissier     }
22711fa71b9SJerome Forissier #else /* MBEDTLS_USE_PSA_CRYPTO */
2285b25c76aSJerome Forissier     ret = mbedtls_md(mbedtls_md_info_from_type(ctx->md_alg), c, len, hash);
22932b31808SJens Wiklander     if (ret != 0) {
23032b31808SJens Wiklander         return ret;
23132b31808SJens Wiklander     }
23211fa71b9SJerome Forissier #endif
23332b31808SJens Wiklander     if ((ret = mbedtls_pk_sign(ctx->key, ctx->md_alg, hash, 0,
23432b31808SJens Wiklander                                sig, sig_size, &sig_len,
23532b31808SJens Wiklander                                f_rng, p_rng)) != 0) {
23632b31808SJens Wiklander         return ret;
2373d3b0591SJens Wiklander     }
2383d3b0591SJens Wiklander 
23932b31808SJens Wiklander     if (mbedtls_pk_can_do(ctx->key, MBEDTLS_PK_RSA)) {
2403d3b0591SJens Wiklander         pk_alg = MBEDTLS_PK_RSA;
24132b31808SJens Wiklander     } else if (mbedtls_pk_can_do(ctx->key, MBEDTLS_PK_ECDSA)) {
2423d3b0591SJens Wiklander         pk_alg = MBEDTLS_PK_ECDSA;
24332b31808SJens Wiklander     } else {
24432b31808SJens Wiklander         return MBEDTLS_ERR_X509_INVALID_ALG;
24532b31808SJens Wiklander     }
2463d3b0591SJens Wiklander 
2473d3b0591SJens Wiklander     if ((ret = mbedtls_oid_get_oid_by_sig_alg(pk_alg, ctx->md_alg,
24832b31808SJens Wiklander                                               &sig_oid, &sig_oid_len)) != 0) {
24932b31808SJens Wiklander         return ret;
250817466cbSJens Wiklander     }
251817466cbSJens Wiklander 
252817466cbSJens Wiklander     /*
2537901324dSJerome Forissier      * Move the written CSR data to the start of buf to create space for
2547901324dSJerome Forissier      * writing the signature into buf.
2557901324dSJerome Forissier      */
2567901324dSJerome Forissier     memmove(buf, c, len);
2577901324dSJerome Forissier 
2587901324dSJerome Forissier     /*
2597901324dSJerome Forissier      * Write sig and its OID into buf backwards from the end of buf.
2607901324dSJerome Forissier      * Note: mbedtls_x509_write_sig will check for c2 - ( buf + len ) < sig_len
2617901324dSJerome Forissier      * and return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if needed.
262817466cbSJens Wiklander      */
263817466cbSJens Wiklander     c2 = buf + size;
2647901324dSJerome Forissier     MBEDTLS_ASN1_CHK_ADD(sig_and_oid_len,
2657901324dSJerome Forissier                          mbedtls_x509_write_sig(&c2, buf + len, sig_oid, sig_oid_len,
266b0563631STom Van Eyck                                                 sig, sig_len, pk_alg));
267817466cbSJens Wiklander 
2687901324dSJerome Forissier     /*
2697901324dSJerome Forissier      * Compact the space between the CSR data and signature by moving the
2707901324dSJerome Forissier      * CSR data to the start of the signature.
2717901324dSJerome Forissier      */
272817466cbSJens Wiklander     c2 -= len;
2737901324dSJerome Forissier     memmove(c2, buf, len);
274817466cbSJens Wiklander 
2757901324dSJerome Forissier     /* ASN encode the total size and tag the CSR data with it. */
276817466cbSJens Wiklander     len += sig_and_oid_len;
277817466cbSJens Wiklander     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c2, buf, len));
2787901324dSJerome Forissier     MBEDTLS_ASN1_CHK_ADD(len,
2797901324dSJerome Forissier                          mbedtls_asn1_write_tag(
2807901324dSJerome Forissier                              &c2, buf,
2817901324dSJerome Forissier                              MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
2827901324dSJerome Forissier 
2837901324dSJerome Forissier     /* Zero the unused bytes at the start of buf */
284b0563631STom Van Eyck     memset(buf, 0, (size_t) (c2 - buf));
285817466cbSJens Wiklander 
28632b31808SJens Wiklander     return (int) len;
287817466cbSJens Wiklander }
288817466cbSJens Wiklander 
mbedtls_x509write_csr_der(mbedtls_x509write_csr * ctx,unsigned char * buf,size_t size,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)2897901324dSJerome Forissier int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf,
2907901324dSJerome Forissier                               size_t size,
2917901324dSJerome Forissier                               int (*f_rng)(void *, unsigned char *, size_t),
2927901324dSJerome Forissier                               void *p_rng)
2937901324dSJerome Forissier {
2947901324dSJerome Forissier     int ret;
2957901324dSJerome Forissier     unsigned char *sig;
2967901324dSJerome Forissier 
29732b31808SJens Wiklander     if ((sig = mbedtls_calloc(1, MBEDTLS_PK_SIGNATURE_MAX_SIZE)) == NULL) {
29832b31808SJens Wiklander         return MBEDTLS_ERR_X509_ALLOC_FAILED;
2997901324dSJerome Forissier     }
3007901324dSJerome Forissier 
30132b31808SJens Wiklander     ret = x509write_csr_der_internal(ctx, buf, size,
30232b31808SJens Wiklander                                      sig, MBEDTLS_PK_SIGNATURE_MAX_SIZE,
30332b31808SJens Wiklander                                      f_rng, p_rng);
3047901324dSJerome Forissier 
3057901324dSJerome Forissier     mbedtls_free(sig);
3067901324dSJerome Forissier 
30732b31808SJens Wiklander     return ret;
3087901324dSJerome Forissier }
3097901324dSJerome Forissier 
310817466cbSJens Wiklander #define PEM_BEGIN_CSR           "-----BEGIN CERTIFICATE REQUEST-----\n"
311817466cbSJens Wiklander #define PEM_END_CSR             "-----END CERTIFICATE REQUEST-----\n"
312817466cbSJens Wiklander 
313817466cbSJens Wiklander #if defined(MBEDTLS_PEM_WRITE_C)
mbedtls_x509write_csr_pem(mbedtls_x509write_csr * ctx,unsigned char * buf,size_t size,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)314817466cbSJens Wiklander int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
315817466cbSJens Wiklander                               int (*f_rng)(void *, unsigned char *, size_t),
316817466cbSJens Wiklander                               void *p_rng)
317817466cbSJens Wiklander {
31811fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
319817466cbSJens Wiklander     size_t olen = 0;
320817466cbSJens Wiklander 
32111fa71b9SJerome Forissier     if ((ret = mbedtls_x509write_csr_der(ctx, buf, size,
32232b31808SJens Wiklander                                          f_rng, p_rng)) < 0) {
32332b31808SJens Wiklander         return ret;
324817466cbSJens Wiklander     }
325817466cbSJens Wiklander 
326817466cbSJens Wiklander     if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_CSR, PEM_END_CSR,
32711fa71b9SJerome Forissier                                         buf + size - ret,
32832b31808SJens Wiklander                                         ret, buf, size, &olen)) != 0) {
32932b31808SJens Wiklander         return ret;
330817466cbSJens Wiklander     }
331817466cbSJens Wiklander 
33232b31808SJens Wiklander     return 0;
333817466cbSJens Wiklander }
334817466cbSJens Wiklander #endif /* MBEDTLS_PEM_WRITE_C */
335817466cbSJens Wiklander 
336817466cbSJens Wiklander #endif /* MBEDTLS_X509_CSR_WRITE_C */
337