blob: ac5eaaa4a75ec87b30d79a1c87bb90c0868877cd [file] [log] [blame]
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001/*
2 * X.509 Certificate Signing Request writing
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Paul Bakker7c6b2c32013-09-16 13:49:26 +020024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
45 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000046 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020047 */
48/*
49 * References:
50 * - CSRs: PKCS#10 v1.7 aka RFC 2986
51 * - attributes: PKCS#9 v2.0 aka RFC 2985
52 */
53
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000055#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020056#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020058#endif
Paul Bakker7c6b2c32013-09-16 13:49:26 +020059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_X509_CSR_WRITE_C)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020061
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000062#include "mbedtls/x509_csr.h"
63#include "mbedtls/oid.h"
64#include "mbedtls/asn1write.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050065#include "mbedtls/platform_util.h"
Paul Bakker7c6b2c32013-09-16 13:49:26 +020066
Rich Evans00ab4702015-02-06 13:43:58 +000067#include <string.h>
68#include <stdlib.h>
69
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070#if defined(MBEDTLS_PEM_WRITE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000071#include "mbedtls/pem.h"
Paul Bakker7c6b2c32013-09-16 13:49:26 +020072#endif
73
k-stachowiake79c9392019-05-31 20:11:26 +020074/*
75 * For the currently used signature algorithms the buffer to store any signature
76 * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)
77 */
78#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE
79#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
80#else
81#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
82#endif
83
Doru Guceaafc27172018-12-14 21:08:35 +020084#if defined(MBEDTLS_PLATFORM_C)
85#include "mbedtls/platform.h"
86#else
87#include <stdlib.h>
88#define mbedtls_calloc calloc
89#define mbedtls_free free
90#endif
91
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020092void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx )
Paul Bakker7c6b2c32013-09-16 13:49:26 +020093{
Hanno Becker81535d02017-09-13 15:39:59 +010094 memset( ctx, 0, sizeof( mbedtls_x509write_csr ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +020095}
96
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020097void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx )
Paul Bakker7c6b2c32013-09-16 13:49:26 +020098{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099 mbedtls_asn1_free_named_data_list( &ctx->subject );
100 mbedtls_asn1_free_named_data_list( &ctx->extensions );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200101
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500102 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_csr ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200103}
104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200106{
107 ctx->md_alg = md_alg;
108}
109
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200111{
112 ctx->key = key;
113}
114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx,
Paul Bakker50dc8502013-10-28 21:19:10 +0100116 const char *subject_name )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200117{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118 return mbedtls_x509_string_to_names( &ctx->subject, subject_name );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200119}
120
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200121int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx,
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200122 const char *oid, size_t oid_len,
123 const unsigned char *val, size_t val_len )
124{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125 return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200126 0, val, val_len );
127}
128
Andres Amaya Garciad60e3782018-09-26 10:48:24 +0100129static size_t csr_get_unused_bits_for_named_bitstring( unsigned char bitstring,
130 size_t bit_offset )
131{
132 size_t unused_bits;
133
134 /* Count the unused bits removing trailing 0s */
135 for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ )
136 if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 )
137 break;
138
139 return( unused_bits );
140}
141
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200142int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200143{
144 unsigned char buf[4];
145 unsigned char *c;
Andres Amaya Garciad60e3782018-09-26 10:48:24 +0100146 size_t unused_bits;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200147 int ret;
148
149 c = buf + 4;
150
Andres Amaya Garciad60e3782018-09-26 10:48:24 +0100151 unused_bits = csr_get_unused_bits_for_named_bitstring( key_usage, 0 );
152 ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 8 - unused_bits );
153
154 if( ret < 0 )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200155 return( ret );
Andres Amaya Garciad60e3782018-09-26 10:48:24 +0100156 else if( ret < 3 || ret > 4 )
157 return( MBEDTLS_ERR_X509_INVALID_FORMAT );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200158
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159 ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
160 MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
Andres Amaya Garciad60e3782018-09-26 10:48:24 +0100161 c, (size_t)ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200162 if( ret != 0 )
163 return( ret );
164
165 return( 0 );
166}
167
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200168int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx,
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200169 unsigned char ns_cert_type )
170{
171 unsigned char buf[4];
172 unsigned char *c;
Andres Amaya Garciad60e3782018-09-26 10:48:24 +0100173 size_t unused_bits;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200174 int ret;
175
176 c = buf + 4;
177
Andres Amaya Garciad60e3782018-09-26 10:48:24 +0100178 unused_bits = csr_get_unused_bits_for_named_bitstring( ns_cert_type, 0 );
179 ret = mbedtls_asn1_write_bitstring( &c,
180 buf,
181 &ns_cert_type,
182 8 - unused_bits );
183
184 if( ret < 0 )
185 return( ret );
186 else if( ret < 3 || ret > 4 )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200187 return( ret );
188
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189 ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
190 MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
Andres Amaya Garciad60e3782018-09-26 10:48:24 +0100191 c, (size_t)ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200192 if( ret != 0 )
193 return( ret );
194
195 return( 0 );
196}
197
Doru Guceaafc27172018-12-14 21:08:35 +0200198static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx,
199 unsigned char *buf,
Simon Leet1535a432020-06-26 21:23:32 +0000200 size_t size,
201 unsigned char *sig,
Doru Guceaafc27172018-12-14 21:08:35 +0200202 int (*f_rng)(void *, unsigned char *, size_t),
203 void *p_rng )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200204{
205 int ret;
206 const char *sig_oid;
207 size_t sig_oid_len = 0;
208 unsigned char *c, *c2;
209 unsigned char hash[64];
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200210 size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
211 size_t len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212 mbedtls_pk_type_t pk_alg;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200213
Simon Leet1535a432020-06-26 21:23:32 +0000214 /* Write the CSR backwards starting from the end of buf */
Doru Guceaafc27172018-12-14 21:08:35 +0200215 c = buf + size;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200216
Doru Guceaafc27172018-12-14 21:08:35 +0200217 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, buf,
218 ctx->extensions ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200219
220 if( len )
221 {
Doru Guceaafc27172018-12-14 21:08:35 +0200222 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
Simon Leet1535a432020-06-26 21:23:32 +0000223 MBEDTLS_ASN1_CHK_ADD( len,
224 mbedtls_asn1_write_tag(
225 &c, buf,
226 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200227
Doru Guceaafc27172018-12-14 21:08:35 +0200228 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
Simon Leet1535a432020-06-26 21:23:32 +0000229 MBEDTLS_ASN1_CHK_ADD( len,
230 mbedtls_asn1_write_tag(
231 &c, buf,
232 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200233
Simon Leet1535a432020-06-26 21:23:32 +0000234 MBEDTLS_ASN1_CHK_ADD( len,
235 mbedtls_asn1_write_oid(
236 &c, buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ,
237 MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200238
Doru Guceaafc27172018-12-14 21:08:35 +0200239 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
Simon Leet1535a432020-06-26 21:23:32 +0000240 MBEDTLS_ASN1_CHK_ADD( len,
241 mbedtls_asn1_write_tag(
242 &c, buf,
243 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200244 }
245
Doru Guceaafc27172018-12-14 21:08:35 +0200246 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
Simon Leet1535a432020-06-26 21:23:32 +0000247 MBEDTLS_ASN1_CHK_ADD( len,
248 mbedtls_asn1_write_tag(
249 &c, buf,
250 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200251
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200252 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key,
Doru Guceaafc27172018-12-14 21:08:35 +0200253 buf, c - buf ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200254 c -= pub_len;
255 len += pub_len;
256
257 /*
258 * Subject ::= Name
259 */
Doru Guceaafc27172018-12-14 21:08:35 +0200260 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, buf,
261 ctx->subject ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200262
263 /*
264 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
265 */
Doru Guceaafc27172018-12-14 21:08:35 +0200266 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200267
Doru Guceaafc27172018-12-14 21:08:35 +0200268 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
Simon Leet1535a432020-06-26 21:23:32 +0000269 MBEDTLS_ASN1_CHK_ADD( len,
270 mbedtls_asn1_write_tag(
271 &c, buf,
272 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200273
274 /*
Simon Leet1535a432020-06-26 21:23:32 +0000275 * Sign the written CSR data into the sig buffer
276 * Note: hash errors can happen only after an internal error
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200277 */
Gilles Peskine3a3b1612020-01-21 16:56:03 +0100278 ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
279 if( ret != 0 )
280 return( ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200281
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200282 if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
Hanno Beckerfc771442017-09-13 08:45:48 +0100283 f_rng, p_rng ) ) != 0 )
284 {
285 return( ret );
286 }
287
288 if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_RSA ) )
289 pk_alg = MBEDTLS_PK_RSA;
290 else if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_ECDSA ) )
291 pk_alg = MBEDTLS_PK_ECDSA;
292 else
Hanno Beckerd8a6f7c2017-09-22 16:05:43 +0100293 return( MBEDTLS_ERR_X509_INVALID_ALG );
Hanno Beckerfc771442017-09-13 08:45:48 +0100294
295 if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
Doru Guceaafc27172018-12-14 21:08:35 +0200296 &sig_oid, &sig_oid_len ) ) != 0 )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200297 {
298 return( ret );
299 }
300
Simon Leet1535a432020-06-26 21:23:32 +0000301 /*
302 * Move the written CSR data to the start of buf to create space for
303 * writing the signature into buf.
304 */
Doru Guceaafc27172018-12-14 21:08:35 +0200305 memmove( buf, c, len );
306
Simon Leet1535a432020-06-26 21:23:32 +0000307 /*
308 * Write sig and its OID into buf backwards from the end of buf.
309 * Note: mbedtls_x509_write_sig will check for c2 - ( buf + len ) < sig_len
310 * and return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if needed.
311 */
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200312 c2 = buf + size;
Simon Leet1535a432020-06-26 21:23:32 +0000313 MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len,
314 mbedtls_x509_write_sig( &c2, buf + len, sig_oid, sig_oid_len,
315 sig, sig_len ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200316
Simon Leet1535a432020-06-26 21:23:32 +0000317 /*
318 * Compact the space between the CSR data and signature by moving the
319 * CSR data to the start of the signature.
320 */
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200321 c2 -= len;
Doru Guceaafc27172018-12-14 21:08:35 +0200322 memmove( c2, buf, len );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200323
Simon Leet1535a432020-06-26 21:23:32 +0000324 /* ASN encode the total size and tag the CSR data with it. */
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200325 len += sig_and_oid_len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) );
Simon Leet1535a432020-06-26 21:23:32 +0000327 MBEDTLS_ASN1_CHK_ADD( len,
328 mbedtls_asn1_write_tag(
329 &c2, buf,
330 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
331
332 /* Zero the unused bytes at the start of buf */
Doru Guceaafc27172018-12-14 21:08:35 +0200333 memset( buf, 0, c2 - buf);
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200334
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200335 return( (int) len );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200336}
337
Doru Guceaafc27172018-12-14 21:08:35 +0200338int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf,
339 size_t size,
340 int (*f_rng)(void *, unsigned char *, size_t),
341 void *p_rng )
342{
343 int ret;
344 unsigned char *sig;
345
Simon Leet1535a432020-06-26 21:23:32 +0000346 if( ( sig = mbedtls_calloc( 1, SIGNATURE_MAX_SIZE ) ) == NULL )
Doru Guceaafc27172018-12-14 21:08:35 +0200347 {
Simon Leet1535a432020-06-26 21:23:32 +0000348 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
Doru Guceaafc27172018-12-14 21:08:35 +0200349 }
350
351 ret = x509write_csr_der_internal( ctx, buf, size, sig, f_rng, p_rng );
352
353 mbedtls_free( sig );
354
355 return( ret );
356}
357
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200358#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n"
359#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n"
360
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361#if defined(MBEDTLS_PEM_WRITE_C)
362int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200363 int (*f_rng)(void *, unsigned char *, size_t),
364 void *p_rng )
365{
366 int ret;
367 unsigned char output_buf[4096];
368 size_t olen = 0;
369
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200370 if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf),
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200371 f_rng, p_rng ) ) < 0 )
372 {
373 return( ret );
374 }
375
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376 if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR,
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200377 output_buf + sizeof(output_buf) - ret,
378 ret, buf, size, &olen ) ) != 0 )
379 {
380 return( ret );
381 }
382
383 return( 0 );
384}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385#endif /* MBEDTLS_PEM_WRITE_C */
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200386
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387#endif /* MBEDTLS_X509_CSR_WRITE_C */