xref: /optee_os/lib/libmbedtls/mbedtls/library/x509_csr.c (revision 817466cb476de705a8e3dabe1ef165fe27a18c2f)
1*817466cbSJens Wiklander /*
2*817466cbSJens Wiklander  *  X.509 Certificate Signing Request (CSR) parsing
3*817466cbSJens Wiklander  *
4*817466cbSJens Wiklander  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5*817466cbSJens Wiklander  *  SPDX-License-Identifier: Apache-2.0
6*817466cbSJens Wiklander  *
7*817466cbSJens Wiklander  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8*817466cbSJens Wiklander  *  not use this file except in compliance with the License.
9*817466cbSJens Wiklander  *  You may obtain a copy of the License at
10*817466cbSJens Wiklander  *
11*817466cbSJens Wiklander  *  http://www.apache.org/licenses/LICENSE-2.0
12*817466cbSJens Wiklander  *
13*817466cbSJens Wiklander  *  Unless required by applicable law or agreed to in writing, software
14*817466cbSJens Wiklander  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15*817466cbSJens Wiklander  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*817466cbSJens Wiklander  *  See the License for the specific language governing permissions and
17*817466cbSJens Wiklander  *  limitations under the License.
18*817466cbSJens Wiklander  *
19*817466cbSJens Wiklander  *  This file is part of mbed TLS (https://tls.mbed.org)
20*817466cbSJens Wiklander  */
21*817466cbSJens Wiklander /*
22*817466cbSJens Wiklander  *  The ITU-T X.509 standard defines a certificate format for PKI.
23*817466cbSJens Wiklander  *
24*817466cbSJens Wiklander  *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
25*817466cbSJens Wiklander  *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
26*817466cbSJens Wiklander  *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
27*817466cbSJens Wiklander  *
28*817466cbSJens Wiklander  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
29*817466cbSJens Wiklander  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
30*817466cbSJens Wiklander  */
31*817466cbSJens Wiklander 
32*817466cbSJens Wiklander #if !defined(MBEDTLS_CONFIG_FILE)
33*817466cbSJens Wiklander #include "mbedtls/config.h"
34*817466cbSJens Wiklander #else
35*817466cbSJens Wiklander #include MBEDTLS_CONFIG_FILE
36*817466cbSJens Wiklander #endif
37*817466cbSJens Wiklander 
38*817466cbSJens Wiklander #if defined(MBEDTLS_X509_CSR_PARSE_C)
39*817466cbSJens Wiklander 
40*817466cbSJens Wiklander #include "mbedtls/x509_csr.h"
41*817466cbSJens Wiklander #include "mbedtls/oid.h"
42*817466cbSJens Wiklander 
43*817466cbSJens Wiklander #include <string.h>
44*817466cbSJens Wiklander 
45*817466cbSJens Wiklander #if defined(MBEDTLS_PEM_PARSE_C)
46*817466cbSJens Wiklander #include "mbedtls/pem.h"
47*817466cbSJens Wiklander #endif
48*817466cbSJens Wiklander 
49*817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C)
50*817466cbSJens Wiklander #include "mbedtls/platform.h"
51*817466cbSJens Wiklander #else
52*817466cbSJens Wiklander #include <stdlib.h>
53*817466cbSJens Wiklander #include <stdio.h>
54*817466cbSJens Wiklander #define mbedtls_free       free
55*817466cbSJens Wiklander #define mbedtls_calloc    calloc
56*817466cbSJens Wiklander #define mbedtls_snprintf   snprintf
57*817466cbSJens Wiklander #endif
58*817466cbSJens Wiklander 
59*817466cbSJens Wiklander #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
60*817466cbSJens Wiklander #include <stdio.h>
61*817466cbSJens Wiklander #endif
62*817466cbSJens Wiklander 
63*817466cbSJens Wiklander /* Implementation that should never be optimized out by the compiler */
64*817466cbSJens Wiklander static void mbedtls_zeroize( void *v, size_t n ) {
65*817466cbSJens Wiklander     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
66*817466cbSJens Wiklander }
67*817466cbSJens Wiklander 
68*817466cbSJens Wiklander /*
69*817466cbSJens Wiklander  *  Version  ::=  INTEGER  {  v1(0)  }
70*817466cbSJens Wiklander  */
71*817466cbSJens Wiklander static int x509_csr_get_version( unsigned char **p,
72*817466cbSJens Wiklander                              const unsigned char *end,
73*817466cbSJens Wiklander                              int *ver )
74*817466cbSJens Wiklander {
75*817466cbSJens Wiklander     int ret;
76*817466cbSJens Wiklander 
77*817466cbSJens Wiklander     if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
78*817466cbSJens Wiklander     {
79*817466cbSJens Wiklander         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
80*817466cbSJens Wiklander         {
81*817466cbSJens Wiklander             *ver = 0;
82*817466cbSJens Wiklander             return( 0 );
83*817466cbSJens Wiklander         }
84*817466cbSJens Wiklander 
85*817466cbSJens Wiklander         return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
86*817466cbSJens Wiklander     }
87*817466cbSJens Wiklander 
88*817466cbSJens Wiklander     return( 0 );
89*817466cbSJens Wiklander }
90*817466cbSJens Wiklander 
91*817466cbSJens Wiklander /*
92*817466cbSJens Wiklander  * Parse a CSR in DER format
93*817466cbSJens Wiklander  */
94*817466cbSJens Wiklander int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
95*817466cbSJens Wiklander                         const unsigned char *buf, size_t buflen )
96*817466cbSJens Wiklander {
97*817466cbSJens Wiklander     int ret;
98*817466cbSJens Wiklander     size_t len;
99*817466cbSJens Wiklander     unsigned char *p, *end;
100*817466cbSJens Wiklander     mbedtls_x509_buf sig_params;
101*817466cbSJens Wiklander 
102*817466cbSJens Wiklander     memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) );
103*817466cbSJens Wiklander 
104*817466cbSJens Wiklander     /*
105*817466cbSJens Wiklander      * Check for valid input
106*817466cbSJens Wiklander      */
107*817466cbSJens Wiklander     if( csr == NULL || buf == NULL || buflen == 0 )
108*817466cbSJens Wiklander         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
109*817466cbSJens Wiklander 
110*817466cbSJens Wiklander     mbedtls_x509_csr_init( csr );
111*817466cbSJens Wiklander 
112*817466cbSJens Wiklander     /*
113*817466cbSJens Wiklander      * first copy the raw DER data
114*817466cbSJens Wiklander      */
115*817466cbSJens Wiklander     p = mbedtls_calloc( 1, len = buflen );
116*817466cbSJens Wiklander 
117*817466cbSJens Wiklander     if( p == NULL )
118*817466cbSJens Wiklander         return( MBEDTLS_ERR_X509_ALLOC_FAILED );
119*817466cbSJens Wiklander 
120*817466cbSJens Wiklander     memcpy( p, buf, buflen );
121*817466cbSJens Wiklander 
122*817466cbSJens Wiklander     csr->raw.p = p;
123*817466cbSJens Wiklander     csr->raw.len = len;
124*817466cbSJens Wiklander     end = p + len;
125*817466cbSJens Wiklander 
126*817466cbSJens Wiklander     /*
127*817466cbSJens Wiklander      *  CertificationRequest ::= SEQUENCE {
128*817466cbSJens Wiklander      *       certificationRequestInfo CertificationRequestInfo,
129*817466cbSJens Wiklander      *       signatureAlgorithm AlgorithmIdentifier,
130*817466cbSJens Wiklander      *       signature          BIT STRING
131*817466cbSJens Wiklander      *  }
132*817466cbSJens Wiklander      */
133*817466cbSJens Wiklander     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
134*817466cbSJens Wiklander             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
135*817466cbSJens Wiklander     {
136*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
137*817466cbSJens Wiklander         return( MBEDTLS_ERR_X509_INVALID_FORMAT );
138*817466cbSJens Wiklander     }
139*817466cbSJens Wiklander 
140*817466cbSJens Wiklander     if( len != (size_t) ( end - p ) )
141*817466cbSJens Wiklander     {
142*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
143*817466cbSJens Wiklander         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
144*817466cbSJens Wiklander                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
145*817466cbSJens Wiklander     }
146*817466cbSJens Wiklander 
147*817466cbSJens Wiklander     /*
148*817466cbSJens Wiklander      *  CertificationRequestInfo ::= SEQUENCE {
149*817466cbSJens Wiklander      */
150*817466cbSJens Wiklander     csr->cri.p = p;
151*817466cbSJens Wiklander 
152*817466cbSJens Wiklander     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
153*817466cbSJens Wiklander             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
154*817466cbSJens Wiklander     {
155*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
156*817466cbSJens Wiklander         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
157*817466cbSJens Wiklander     }
158*817466cbSJens Wiklander 
159*817466cbSJens Wiklander     end = p + len;
160*817466cbSJens Wiklander     csr->cri.len = end - csr->cri.p;
161*817466cbSJens Wiklander 
162*817466cbSJens Wiklander     /*
163*817466cbSJens Wiklander      *  Version  ::=  INTEGER {  v1(0) }
164*817466cbSJens Wiklander      */
165*817466cbSJens Wiklander     if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 )
166*817466cbSJens Wiklander     {
167*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
168*817466cbSJens Wiklander         return( ret );
169*817466cbSJens Wiklander     }
170*817466cbSJens Wiklander 
171*817466cbSJens Wiklander     if( csr->version != 0 )
172*817466cbSJens Wiklander     {
173*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
174*817466cbSJens Wiklander         return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
175*817466cbSJens Wiklander     }
176*817466cbSJens Wiklander 
177*817466cbSJens Wiklander     csr->version++;
178*817466cbSJens Wiklander 
179*817466cbSJens Wiklander     /*
180*817466cbSJens Wiklander      *  subject               Name
181*817466cbSJens Wiklander      */
182*817466cbSJens Wiklander     csr->subject_raw.p = p;
183*817466cbSJens Wiklander 
184*817466cbSJens Wiklander     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
185*817466cbSJens Wiklander             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
186*817466cbSJens Wiklander     {
187*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
188*817466cbSJens Wiklander         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
189*817466cbSJens Wiklander     }
190*817466cbSJens Wiklander 
191*817466cbSJens Wiklander     if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
192*817466cbSJens Wiklander     {
193*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
194*817466cbSJens Wiklander         return( ret );
195*817466cbSJens Wiklander     }
196*817466cbSJens Wiklander 
197*817466cbSJens Wiklander     csr->subject_raw.len = p - csr->subject_raw.p;
198*817466cbSJens Wiklander 
199*817466cbSJens Wiklander     /*
200*817466cbSJens Wiklander      *  subjectPKInfo SubjectPublicKeyInfo
201*817466cbSJens Wiklander      */
202*817466cbSJens Wiklander     if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 )
203*817466cbSJens Wiklander     {
204*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
205*817466cbSJens Wiklander         return( ret );
206*817466cbSJens Wiklander     }
207*817466cbSJens Wiklander 
208*817466cbSJens Wiklander     /*
209*817466cbSJens Wiklander      *  attributes    [0] Attributes
210*817466cbSJens Wiklander      *
211*817466cbSJens Wiklander      *  The list of possible attributes is open-ended, though RFC 2985
212*817466cbSJens Wiklander      *  (PKCS#9) defines a few in section 5.4. We currently don't support any,
213*817466cbSJens Wiklander      *  so we just ignore them. This is a safe thing to do as the worst thing
214*817466cbSJens Wiklander      *  that could happen is that we issue a certificate that does not match
215*817466cbSJens Wiklander      *  the requester's expectations - this cannot cause a violation of our
216*817466cbSJens Wiklander      *  signature policies.
217*817466cbSJens Wiklander      */
218*817466cbSJens Wiklander     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
219*817466cbSJens Wiklander             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
220*817466cbSJens Wiklander     {
221*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
222*817466cbSJens Wiklander         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
223*817466cbSJens Wiklander     }
224*817466cbSJens Wiklander 
225*817466cbSJens Wiklander     p += len;
226*817466cbSJens Wiklander 
227*817466cbSJens Wiklander     end = csr->raw.p + csr->raw.len;
228*817466cbSJens Wiklander 
229*817466cbSJens Wiklander     /*
230*817466cbSJens Wiklander      *  signatureAlgorithm   AlgorithmIdentifier,
231*817466cbSJens Wiklander      *  signature            BIT STRING
232*817466cbSJens Wiklander      */
233*817466cbSJens Wiklander     if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 )
234*817466cbSJens Wiklander     {
235*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
236*817466cbSJens Wiklander         return( ret );
237*817466cbSJens Wiklander     }
238*817466cbSJens Wiklander 
239*817466cbSJens Wiklander     if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params,
240*817466cbSJens Wiklander                                   &csr->sig_md, &csr->sig_pk,
241*817466cbSJens Wiklander                                   &csr->sig_opts ) ) != 0 )
242*817466cbSJens Wiklander     {
243*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
244*817466cbSJens Wiklander         return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG );
245*817466cbSJens Wiklander     }
246*817466cbSJens Wiklander 
247*817466cbSJens Wiklander     if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 )
248*817466cbSJens Wiklander     {
249*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
250*817466cbSJens Wiklander         return( ret );
251*817466cbSJens Wiklander     }
252*817466cbSJens Wiklander 
253*817466cbSJens Wiklander     if( p != end )
254*817466cbSJens Wiklander     {
255*817466cbSJens Wiklander         mbedtls_x509_csr_free( csr );
256*817466cbSJens Wiklander         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
257*817466cbSJens Wiklander                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
258*817466cbSJens Wiklander     }
259*817466cbSJens Wiklander 
260*817466cbSJens Wiklander     return( 0 );
261*817466cbSJens Wiklander }
262*817466cbSJens Wiklander 
263*817466cbSJens Wiklander /*
264*817466cbSJens Wiklander  * Parse a CSR, allowing for PEM or raw DER encoding
265*817466cbSJens Wiklander  */
266*817466cbSJens Wiklander int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen )
267*817466cbSJens Wiklander {
268*817466cbSJens Wiklander #if defined(MBEDTLS_PEM_PARSE_C)
269*817466cbSJens Wiklander     int ret;
270*817466cbSJens Wiklander     size_t use_len;
271*817466cbSJens Wiklander     mbedtls_pem_context pem;
272*817466cbSJens Wiklander #endif
273*817466cbSJens Wiklander 
274*817466cbSJens Wiklander     /*
275*817466cbSJens Wiklander      * Check for valid input
276*817466cbSJens Wiklander      */
277*817466cbSJens Wiklander     if( csr == NULL || buf == NULL || buflen == 0 )
278*817466cbSJens Wiklander         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
279*817466cbSJens Wiklander 
280*817466cbSJens Wiklander #if defined(MBEDTLS_PEM_PARSE_C)
281*817466cbSJens Wiklander     mbedtls_pem_init( &pem );
282*817466cbSJens Wiklander 
283*817466cbSJens Wiklander     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
284*817466cbSJens Wiklander     if( buf[buflen - 1] != '\0' )
285*817466cbSJens Wiklander         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
286*817466cbSJens Wiklander     else
287*817466cbSJens Wiklander         ret = mbedtls_pem_read_buffer( &pem,
288*817466cbSJens Wiklander                                "-----BEGIN CERTIFICATE REQUEST-----",
289*817466cbSJens Wiklander                                "-----END CERTIFICATE REQUEST-----",
290*817466cbSJens Wiklander                                buf, NULL, 0, &use_len );
291*817466cbSJens Wiklander 
292*817466cbSJens Wiklander     if( ret == 0 )
293*817466cbSJens Wiklander     {
294*817466cbSJens Wiklander         /*
295*817466cbSJens Wiklander          * Was PEM encoded, parse the result
296*817466cbSJens Wiklander          */
297*817466cbSJens Wiklander         if( ( ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen ) ) != 0 )
298*817466cbSJens Wiklander             return( ret );
299*817466cbSJens Wiklander 
300*817466cbSJens Wiklander         mbedtls_pem_free( &pem );
301*817466cbSJens Wiklander         return( 0 );
302*817466cbSJens Wiklander     }
303*817466cbSJens Wiklander     else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
304*817466cbSJens Wiklander     {
305*817466cbSJens Wiklander         mbedtls_pem_free( &pem );
306*817466cbSJens Wiklander         return( ret );
307*817466cbSJens Wiklander     }
308*817466cbSJens Wiklander     else
309*817466cbSJens Wiklander #endif /* MBEDTLS_PEM_PARSE_C */
310*817466cbSJens Wiklander     return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) );
311*817466cbSJens Wiklander }
312*817466cbSJens Wiklander 
313*817466cbSJens Wiklander #if defined(MBEDTLS_FS_IO)
314*817466cbSJens Wiklander /*
315*817466cbSJens Wiklander  * Load a CSR into the structure
316*817466cbSJens Wiklander  */
317*817466cbSJens Wiklander int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path )
318*817466cbSJens Wiklander {
319*817466cbSJens Wiklander     int ret;
320*817466cbSJens Wiklander     size_t n;
321*817466cbSJens Wiklander     unsigned char *buf;
322*817466cbSJens Wiklander 
323*817466cbSJens Wiklander     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
324*817466cbSJens Wiklander         return( ret );
325*817466cbSJens Wiklander 
326*817466cbSJens Wiklander     ret = mbedtls_x509_csr_parse( csr, buf, n );
327*817466cbSJens Wiklander 
328*817466cbSJens Wiklander     mbedtls_zeroize( buf, n );
329*817466cbSJens Wiklander     mbedtls_free( buf );
330*817466cbSJens Wiklander 
331*817466cbSJens Wiklander     return( ret );
332*817466cbSJens Wiklander }
333*817466cbSJens Wiklander #endif /* MBEDTLS_FS_IO */
334*817466cbSJens Wiklander 
335*817466cbSJens Wiklander #define BEFORE_COLON    14
336*817466cbSJens Wiklander #define BC              "14"
337*817466cbSJens Wiklander /*
338*817466cbSJens Wiklander  * Return an informational string about the CSR.
339*817466cbSJens Wiklander  */
340*817466cbSJens Wiklander int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
341*817466cbSJens Wiklander                    const mbedtls_x509_csr *csr )
342*817466cbSJens Wiklander {
343*817466cbSJens Wiklander     int ret;
344*817466cbSJens Wiklander     size_t n;
345*817466cbSJens Wiklander     char *p;
346*817466cbSJens Wiklander     char key_size_str[BEFORE_COLON];
347*817466cbSJens Wiklander 
348*817466cbSJens Wiklander     p = buf;
349*817466cbSJens Wiklander     n = size;
350*817466cbSJens Wiklander 
351*817466cbSJens Wiklander     ret = mbedtls_snprintf( p, n, "%sCSR version   : %d",
352*817466cbSJens Wiklander                                prefix, csr->version );
353*817466cbSJens Wiklander     MBEDTLS_X509_SAFE_SNPRINTF;
354*817466cbSJens Wiklander 
355*817466cbSJens Wiklander     ret = mbedtls_snprintf( p, n, "\n%ssubject name  : ", prefix );
356*817466cbSJens Wiklander     MBEDTLS_X509_SAFE_SNPRINTF;
357*817466cbSJens Wiklander     ret = mbedtls_x509_dn_gets( p, n, &csr->subject );
358*817466cbSJens Wiklander     MBEDTLS_X509_SAFE_SNPRINTF;
359*817466cbSJens Wiklander 
360*817466cbSJens Wiklander     ret = mbedtls_snprintf( p, n, "\n%ssigned using  : ", prefix );
361*817466cbSJens Wiklander     MBEDTLS_X509_SAFE_SNPRINTF;
362*817466cbSJens Wiklander 
363*817466cbSJens Wiklander     ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
364*817466cbSJens Wiklander                              csr->sig_opts );
365*817466cbSJens Wiklander     MBEDTLS_X509_SAFE_SNPRINTF;
366*817466cbSJens Wiklander 
367*817466cbSJens Wiklander     if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
368*817466cbSJens Wiklander                                       mbedtls_pk_get_name( &csr->pk ) ) ) != 0 )
369*817466cbSJens Wiklander     {
370*817466cbSJens Wiklander         return( ret );
371*817466cbSJens Wiklander     }
372*817466cbSJens Wiklander 
373*817466cbSJens Wiklander     ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
374*817466cbSJens Wiklander                           (int) mbedtls_pk_get_bitlen( &csr->pk ) );
375*817466cbSJens Wiklander     MBEDTLS_X509_SAFE_SNPRINTF;
376*817466cbSJens Wiklander 
377*817466cbSJens Wiklander     return( (int) ( size - n ) );
378*817466cbSJens Wiklander }
379*817466cbSJens Wiklander 
380*817466cbSJens Wiklander /*
381*817466cbSJens Wiklander  * Initialize a CSR
382*817466cbSJens Wiklander  */
383*817466cbSJens Wiklander void mbedtls_x509_csr_init( mbedtls_x509_csr *csr )
384*817466cbSJens Wiklander {
385*817466cbSJens Wiklander     memset( csr, 0, sizeof(mbedtls_x509_csr) );
386*817466cbSJens Wiklander }
387*817466cbSJens Wiklander 
388*817466cbSJens Wiklander /*
389*817466cbSJens Wiklander  * Unallocate all CSR data
390*817466cbSJens Wiklander  */
391*817466cbSJens Wiklander void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
392*817466cbSJens Wiklander {
393*817466cbSJens Wiklander     mbedtls_x509_name *name_cur;
394*817466cbSJens Wiklander     mbedtls_x509_name *name_prv;
395*817466cbSJens Wiklander 
396*817466cbSJens Wiklander     if( csr == NULL )
397*817466cbSJens Wiklander         return;
398*817466cbSJens Wiklander 
399*817466cbSJens Wiklander     mbedtls_pk_free( &csr->pk );
400*817466cbSJens Wiklander 
401*817466cbSJens Wiklander #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
402*817466cbSJens Wiklander     mbedtls_free( csr->sig_opts );
403*817466cbSJens Wiklander #endif
404*817466cbSJens Wiklander 
405*817466cbSJens Wiklander     name_cur = csr->subject.next;
406*817466cbSJens Wiklander     while( name_cur != NULL )
407*817466cbSJens Wiklander     {
408*817466cbSJens Wiklander         name_prv = name_cur;
409*817466cbSJens Wiklander         name_cur = name_cur->next;
410*817466cbSJens Wiklander         mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
411*817466cbSJens Wiklander         mbedtls_free( name_prv );
412*817466cbSJens Wiklander     }
413*817466cbSJens Wiklander 
414*817466cbSJens Wiklander     if( csr->raw.p != NULL )
415*817466cbSJens Wiklander     {
416*817466cbSJens Wiklander         mbedtls_zeroize( csr->raw.p, csr->raw.len );
417*817466cbSJens Wiklander         mbedtls_free( csr->raw.p );
418*817466cbSJens Wiklander     }
419*817466cbSJens Wiklander 
420*817466cbSJens Wiklander     mbedtls_zeroize( csr, sizeof( mbedtls_x509_csr ) );
421*817466cbSJens Wiklander }
422*817466cbSJens Wiklander 
423*817466cbSJens Wiklander #endif /* MBEDTLS_X509_CSR_PARSE_C */
424