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