Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbedtls by
x509_csr.c
00001 /* 00002 * X.509 Certificate Signing Request (CSR) parsing 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 /* 00022 * The ITU-T X.509 standard defines a certificate format for PKI. 00023 * 00024 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) 00025 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) 00026 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) 00027 * 00028 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf 00029 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf 00030 */ 00031 00032 #if !defined(MBEDTLS_CONFIG_FILE) 00033 #include "mbedtls/config.h" 00034 #else 00035 #include MBEDTLS_CONFIG_FILE 00036 #endif 00037 00038 #if defined(MBEDTLS_X509_CSR_PARSE_C) 00039 00040 #include "mbedtls/x509_csr.h" 00041 #include "mbedtls/oid.h" 00042 00043 #include <string.h> 00044 00045 #if defined(MBEDTLS_PEM_PARSE_C) 00046 #include "mbedtls/pem.h" 00047 #endif 00048 00049 #if defined(MBEDTLS_PLATFORM_C) 00050 #include "mbedtls/platform.h" 00051 #else 00052 #include <stdlib.h> 00053 #include <stdio.h> 00054 #define mbedtls_free free 00055 #define mbedtls_calloc calloc 00056 #define mbedtls_snprintf snprintf 00057 #endif 00058 00059 #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) 00060 #include <stdio.h> 00061 #endif 00062 00063 /* Implementation that should never be optimized out by the compiler */ 00064 static void mbedtls_zeroize( void *v, size_t n ) { 00065 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00066 } 00067 00068 /* 00069 * Version ::= INTEGER { v1(0) } 00070 */ 00071 static int x509_csr_get_version( unsigned char **p, 00072 const unsigned char *end, 00073 int *ver ) 00074 { 00075 int ret; 00076 00077 if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) 00078 { 00079 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 00080 { 00081 *ver = 0; 00082 return( 0 ); 00083 } 00084 00085 return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); 00086 } 00087 00088 return( 0 ); 00089 } 00090 00091 /* 00092 * Parse a CSR in DER format 00093 */ 00094 int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, 00095 const unsigned char *buf, size_t buflen ) 00096 { 00097 int ret; 00098 size_t len; 00099 unsigned char *p, *end; 00100 mbedtls_x509_buf sig_params; 00101 00102 memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) ); 00103 00104 /* 00105 * Check for valid input 00106 */ 00107 if( csr == NULL || buf == NULL ) 00108 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 00109 00110 mbedtls_x509_csr_init( csr ); 00111 00112 /* 00113 * first copy the raw DER data 00114 */ 00115 p = mbedtls_calloc( 1, len = buflen ); 00116 00117 if( p == NULL ) 00118 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 00119 00120 memcpy( p, buf, buflen ); 00121 00122 csr->raw.p = p; 00123 csr->raw.len = len; 00124 end = p + len; 00125 00126 /* 00127 * CertificationRequest ::= SEQUENCE { 00128 * certificationRequestInfo CertificationRequestInfo, 00129 * signatureAlgorithm AlgorithmIdentifier, 00130 * signature BIT STRING 00131 * } 00132 */ 00133 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00134 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00135 { 00136 mbedtls_x509_csr_free( csr ); 00137 return( MBEDTLS_ERR_X509_INVALID_FORMAT ); 00138 } 00139 00140 if( len != (size_t) ( end - p ) ) 00141 { 00142 mbedtls_x509_csr_free( csr ); 00143 return( MBEDTLS_ERR_X509_INVALID_FORMAT + 00144 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00145 } 00146 00147 /* 00148 * CertificationRequestInfo ::= SEQUENCE { 00149 */ 00150 csr->cri.p = p; 00151 00152 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00153 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00154 { 00155 mbedtls_x509_csr_free( csr ); 00156 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); 00157 } 00158 00159 end = p + len; 00160 csr->cri.len = end - csr->cri.p; 00161 00162 /* 00163 * Version ::= INTEGER { v1(0) } 00164 */ 00165 if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 ) 00166 { 00167 mbedtls_x509_csr_free( csr ); 00168 return( ret ); 00169 } 00170 00171 csr->version++; 00172 00173 if( csr->version != 1 ) 00174 { 00175 mbedtls_x509_csr_free( csr ); 00176 return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); 00177 } 00178 00179 /* 00180 * subject Name 00181 */ 00182 csr->subject_raw.p = p; 00183 00184 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00185 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00186 { 00187 mbedtls_x509_csr_free( csr ); 00188 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); 00189 } 00190 00191 if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 ) 00192 { 00193 mbedtls_x509_csr_free( csr ); 00194 return( ret ); 00195 } 00196 00197 csr->subject_raw.len = p - csr->subject_raw.p; 00198 00199 /* 00200 * subjectPKInfo SubjectPublicKeyInfo 00201 */ 00202 if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 ) 00203 { 00204 mbedtls_x509_csr_free( csr ); 00205 return( ret ); 00206 } 00207 00208 /* 00209 * attributes [0] Attributes 00210 */ 00211 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00212 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 ) 00213 { 00214 mbedtls_x509_csr_free( csr ); 00215 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); 00216 } 00217 // TODO Parse Attributes / extension requests 00218 00219 p += len; 00220 00221 end = csr->raw.p + csr->raw.len; 00222 00223 /* 00224 * signatureAlgorithm AlgorithmIdentifier, 00225 * signature BIT STRING 00226 */ 00227 if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 ) 00228 { 00229 mbedtls_x509_csr_free( csr ); 00230 return( ret ); 00231 } 00232 00233 if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params, 00234 &csr->sig_md, &csr->sig_pk, 00235 &csr->sig_opts ) ) != 0 ) 00236 { 00237 mbedtls_x509_csr_free( csr ); 00238 return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG ); 00239 } 00240 00241 if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 ) 00242 { 00243 mbedtls_x509_csr_free( csr ); 00244 return( ret ); 00245 } 00246 00247 if( p != end ) 00248 { 00249 mbedtls_x509_csr_free( csr ); 00250 return( MBEDTLS_ERR_X509_INVALID_FORMAT + 00251 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00252 } 00253 00254 return( 0 ); 00255 } 00256 00257 /* 00258 * Parse a CSR, allowing for PEM or raw DER encoding 00259 */ 00260 int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen ) 00261 { 00262 int ret; 00263 #if defined(MBEDTLS_PEM_PARSE_C) 00264 size_t use_len; 00265 mbedtls_pem_context pem; 00266 #endif 00267 00268 /* 00269 * Check for valid input 00270 */ 00271 if( csr == NULL || buf == NULL ) 00272 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 00273 00274 #if defined(MBEDTLS_PEM_PARSE_C) 00275 mbedtls_pem_init( &pem ); 00276 00277 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ 00278 if( buflen == 0 || buf[buflen - 1] != '\0' ) 00279 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; 00280 else 00281 ret = mbedtls_pem_read_buffer( &pem, 00282 "-----BEGIN CERTIFICATE REQUEST-----", 00283 "-----END CERTIFICATE REQUEST-----", 00284 buf, NULL, 0, &use_len ); 00285 00286 if( ret == 0 ) 00287 { 00288 /* 00289 * Was PEM encoded, parse the result 00290 */ 00291 if( ( ret = mbedtls_x509_csr_parse_der( csr, pem.buf , pem.buflen ) ) != 0 ) 00292 return( ret ); 00293 00294 mbedtls_pem_free( &pem ); 00295 return( 0 ); 00296 } 00297 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 00298 { 00299 mbedtls_pem_free( &pem ); 00300 return( ret ); 00301 } 00302 else 00303 #endif /* MBEDTLS_PEM_PARSE_C */ 00304 return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) ); 00305 } 00306 00307 #if defined(MBEDTLS_FS_IO) 00308 /* 00309 * Load a CSR into the structure 00310 */ 00311 int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path ) 00312 { 00313 int ret; 00314 size_t n; 00315 unsigned char *buf; 00316 00317 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) 00318 return( ret ); 00319 00320 ret = mbedtls_x509_csr_parse( csr, buf, n ); 00321 00322 mbedtls_zeroize( buf, n ); 00323 mbedtls_free( buf ); 00324 00325 return( ret ); 00326 } 00327 #endif /* MBEDTLS_FS_IO */ 00328 00329 #define BEFORE_COLON 14 00330 #define BC "14" 00331 /* 00332 * Return an informational string about the CSR. 00333 */ 00334 int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, 00335 const mbedtls_x509_csr *csr ) 00336 { 00337 int ret; 00338 size_t n; 00339 char *p; 00340 char key_size_str[BEFORE_COLON]; 00341 00342 p = buf; 00343 n = size; 00344 00345 ret = mbedtls_snprintf( p, n, "%sCSR version : %d", 00346 prefix, csr->version ); 00347 MBEDTLS_X509_SAFE_SNPRINTF; 00348 00349 ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); 00350 MBEDTLS_X509_SAFE_SNPRINTF; 00351 ret = mbedtls_x509_dn_gets( p, n, &csr->subject ); 00352 MBEDTLS_X509_SAFE_SNPRINTF; 00353 00354 ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); 00355 MBEDTLS_X509_SAFE_SNPRINTF; 00356 00357 ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md, 00358 csr->sig_opts ); 00359 MBEDTLS_X509_SAFE_SNPRINTF; 00360 00361 if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, 00362 mbedtls_pk_get_name( &csr->pk ) ) ) != 0 ) 00363 { 00364 return( ret ); 00365 } 00366 00367 ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, 00368 (int) mbedtls_pk_get_bitlen( &csr->pk ) ); 00369 MBEDTLS_X509_SAFE_SNPRINTF; 00370 00371 return( (int) ( size - n ) ); 00372 } 00373 00374 /* 00375 * Initialize a CSR 00376 */ 00377 void mbedtls_x509_csr_init( mbedtls_x509_csr *csr ) 00378 { 00379 memset( csr, 0, sizeof(mbedtls_x509_csr) ); 00380 } 00381 00382 /* 00383 * Unallocate all CSR data 00384 */ 00385 void mbedtls_x509_csr_free( mbedtls_x509_csr *csr ) 00386 { 00387 mbedtls_x509_name *name_cur; 00388 mbedtls_x509_name *name_prv; 00389 00390 if( csr == NULL ) 00391 return; 00392 00393 mbedtls_pk_free( &csr->pk ); 00394 00395 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 00396 mbedtls_free( csr->sig_opts ); 00397 #endif 00398 00399 name_cur = csr->subject.next; 00400 while( name_cur != NULL ) 00401 { 00402 name_prv = name_cur; 00403 name_cur = name_cur->next; 00404 mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); 00405 mbedtls_free( name_prv ); 00406 } 00407 00408 if( csr->raw.p != NULL ) 00409 { 00410 mbedtls_zeroize( csr->raw.p, csr->raw.len ); 00411 mbedtls_free( csr->raw.p ); 00412 } 00413 00414 mbedtls_zeroize( csr, sizeof( mbedtls_x509_csr ) ); 00415 } 00416 00417 #endif /* MBEDTLS_X509_CSR_PARSE_C */
Generated on Tue Jul 12 2022 12:52:50 by
