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.
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 #include "mbedtls/platform_util.h" 00043 00044 #include <string.h> 00045 00046 #if defined(MBEDTLS_PEM_PARSE_C) 00047 #include "mbedtls/pem.h" 00048 #endif 00049 00050 #if defined(MBEDTLS_PLATFORM_C) 00051 #include "mbedtls/platform.h" 00052 #else 00053 #include <stdlib.h> 00054 #include <stdio.h> 00055 #define mbedtls_free free 00056 #define mbedtls_calloc calloc 00057 #define mbedtls_snprintf snprintf 00058 #endif 00059 00060 #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) 00061 #include <stdio.h> 00062 #endif 00063 00064 /* 00065 * Version ::= INTEGER { v1(0) } 00066 */ 00067 static int x509_csr_get_version( unsigned char **p, 00068 const unsigned char *end, 00069 int *ver ) 00070 { 00071 int ret; 00072 00073 if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) 00074 { 00075 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 00076 { 00077 *ver = 0; 00078 return( 0 ); 00079 } 00080 00081 return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); 00082 } 00083 00084 return( 0 ); 00085 } 00086 00087 /* 00088 * Parse a CSR in DER format 00089 */ 00090 int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, 00091 const unsigned char *buf, size_t buflen ) 00092 { 00093 int ret; 00094 size_t len; 00095 unsigned char *p, *end; 00096 mbedtls_x509_buf sig_params; 00097 00098 memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) ); 00099 00100 /* 00101 * Check for valid input 00102 */ 00103 if( csr == NULL || buf == NULL || buflen == 0 ) 00104 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 00105 00106 mbedtls_x509_csr_init( csr ); 00107 00108 /* 00109 * first copy the raw DER data 00110 */ 00111 p = mbedtls_calloc( 1, len = buflen ); 00112 00113 if( p == NULL ) 00114 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 00115 00116 memcpy( p, buf, buflen ); 00117 00118 csr->raw.p = p; 00119 csr->raw.len = len; 00120 end = p + len; 00121 00122 /* 00123 * CertificationRequest ::= SEQUENCE { 00124 * certificationRequestInfo CertificationRequestInfo, 00125 * signatureAlgorithm AlgorithmIdentifier, 00126 * signature BIT STRING 00127 * } 00128 */ 00129 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00130 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00131 { 00132 mbedtls_x509_csr_free( csr ); 00133 return( MBEDTLS_ERR_X509_INVALID_FORMAT ); 00134 } 00135 00136 if( len != (size_t) ( end - p ) ) 00137 { 00138 mbedtls_x509_csr_free( csr ); 00139 return( MBEDTLS_ERR_X509_INVALID_FORMAT + 00140 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00141 } 00142 00143 /* 00144 * CertificationRequestInfo ::= SEQUENCE { 00145 */ 00146 csr->cri.p = p; 00147 00148 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00149 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00150 { 00151 mbedtls_x509_csr_free( csr ); 00152 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); 00153 } 00154 00155 end = p + len; 00156 csr->cri.len = end - csr->cri.p; 00157 00158 /* 00159 * Version ::= INTEGER { v1(0) } 00160 */ 00161 if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 ) 00162 { 00163 mbedtls_x509_csr_free( csr ); 00164 return( ret ); 00165 } 00166 00167 if( csr->version != 0 ) 00168 { 00169 mbedtls_x509_csr_free( csr ); 00170 return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); 00171 } 00172 00173 csr->version++; 00174 00175 /* 00176 * subject Name 00177 */ 00178 csr->subject_raw.p = p; 00179 00180 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00181 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00182 { 00183 mbedtls_x509_csr_free( csr ); 00184 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); 00185 } 00186 00187 if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 ) 00188 { 00189 mbedtls_x509_csr_free( csr ); 00190 return( ret ); 00191 } 00192 00193 csr->subject_raw.len = p - csr->subject_raw.p; 00194 00195 /* 00196 * subjectPKInfo SubjectPublicKeyInfo 00197 */ 00198 if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 ) 00199 { 00200 mbedtls_x509_csr_free( csr ); 00201 return( ret ); 00202 } 00203 00204 /* 00205 * attributes [0] Attributes 00206 * 00207 * The list of possible attributes is open-ended, though RFC 2985 00208 * (PKCS#9) defines a few in section 5.4. We currently don't support any, 00209 * so we just ignore them. This is a safe thing to do as the worst thing 00210 * that could happen is that we issue a certificate that does not match 00211 * the requester's expectations - this cannot cause a violation of our 00212 * signature policies. 00213 */ 00214 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00215 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 ) 00216 { 00217 mbedtls_x509_csr_free( csr ); 00218 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); 00219 } 00220 00221 p += len; 00222 00223 end = csr->raw.p + csr->raw.len; 00224 00225 /* 00226 * signatureAlgorithm AlgorithmIdentifier, 00227 * signature BIT STRING 00228 */ 00229 if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 ) 00230 { 00231 mbedtls_x509_csr_free( csr ); 00232 return( ret ); 00233 } 00234 00235 if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params, 00236 &csr->sig_md, &csr->sig_pk, 00237 &csr->sig_opts ) ) != 0 ) 00238 { 00239 mbedtls_x509_csr_free( csr ); 00240 return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG ); 00241 } 00242 00243 if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 ) 00244 { 00245 mbedtls_x509_csr_free( csr ); 00246 return( ret ); 00247 } 00248 00249 if( p != end ) 00250 { 00251 mbedtls_x509_csr_free( csr ); 00252 return( MBEDTLS_ERR_X509_INVALID_FORMAT + 00253 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00254 } 00255 00256 return( 0 ); 00257 } 00258 00259 /* 00260 * Parse a CSR, allowing for PEM or raw DER encoding 00261 */ 00262 int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen ) 00263 { 00264 #if defined(MBEDTLS_PEM_PARSE_C) 00265 int ret; 00266 size_t use_len; 00267 mbedtls_pem_context pem; 00268 #endif 00269 00270 /* 00271 * Check for valid input 00272 */ 00273 if( csr == NULL || buf == NULL || buflen == 0 ) 00274 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 00275 00276 #if defined(MBEDTLS_PEM_PARSE_C) 00277 mbedtls_pem_init( &pem ); 00278 00279 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ 00280 if( buf[buflen - 1] != '\0' ) 00281 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; 00282 else 00283 ret = mbedtls_pem_read_buffer( &pem, 00284 "-----BEGIN CERTIFICATE REQUEST-----", 00285 "-----END CERTIFICATE REQUEST-----", 00286 buf, NULL, 0, &use_len ); 00287 00288 if( ret == 0 ) 00289 { 00290 /* 00291 * Was PEM encoded, parse the result 00292 */ 00293 if( ( ret = mbedtls_x509_csr_parse_der( csr, pem.buf , pem.buflen ) ) != 0 ) 00294 return( ret ); 00295 00296 mbedtls_pem_free( &pem ); 00297 return( 0 ); 00298 } 00299 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 00300 { 00301 mbedtls_pem_free( &pem ); 00302 return( ret ); 00303 } 00304 else 00305 #endif /* MBEDTLS_PEM_PARSE_C */ 00306 return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) ); 00307 } 00308 00309 #if defined(MBEDTLS_FS_IO) 00310 /* 00311 * Load a CSR into the structure 00312 */ 00313 int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path ) 00314 { 00315 int ret; 00316 size_t n; 00317 unsigned char *buf; 00318 00319 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) 00320 return( ret ); 00321 00322 ret = mbedtls_x509_csr_parse( csr, buf, n ); 00323 00324 mbedtls_platform_zeroize( buf, n ); 00325 mbedtls_free( buf ); 00326 00327 return( ret ); 00328 } 00329 #endif /* MBEDTLS_FS_IO */ 00330 00331 #define BEFORE_COLON 14 00332 #define BC "14" 00333 /* 00334 * Return an informational string about the CSR. 00335 */ 00336 int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, 00337 const mbedtls_x509_csr *csr ) 00338 { 00339 int ret; 00340 size_t n; 00341 char *p; 00342 char key_size_str[BEFORE_COLON]; 00343 00344 p = buf; 00345 n = size; 00346 00347 ret = mbedtls_snprintf( p, n, "%sCSR version : %d", 00348 prefix, csr->version ); 00349 MBEDTLS_X509_SAFE_SNPRINTF; 00350 00351 ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); 00352 MBEDTLS_X509_SAFE_SNPRINTF; 00353 ret = mbedtls_x509_dn_gets( p, n, &csr->subject ); 00354 MBEDTLS_X509_SAFE_SNPRINTF; 00355 00356 ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); 00357 MBEDTLS_X509_SAFE_SNPRINTF; 00358 00359 ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md, 00360 csr->sig_opts ); 00361 MBEDTLS_X509_SAFE_SNPRINTF; 00362 00363 if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, 00364 mbedtls_pk_get_name( &csr->pk ) ) ) != 0 ) 00365 { 00366 return( ret ); 00367 } 00368 00369 ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, 00370 (int) mbedtls_pk_get_bitlen( &csr->pk ) ); 00371 MBEDTLS_X509_SAFE_SNPRINTF; 00372 00373 return( (int) ( size - n ) ); 00374 } 00375 00376 /* 00377 * Initialize a CSR 00378 */ 00379 void mbedtls_x509_csr_init( mbedtls_x509_csr *csr ) 00380 { 00381 memset( csr, 0, sizeof(mbedtls_x509_csr) ); 00382 } 00383 00384 /* 00385 * Unallocate all CSR data 00386 */ 00387 void mbedtls_x509_csr_free( mbedtls_x509_csr *csr ) 00388 { 00389 mbedtls_x509_name *name_cur; 00390 mbedtls_x509_name *name_prv; 00391 00392 if( csr == NULL ) 00393 return; 00394 00395 mbedtls_pk_free( &csr->pk ); 00396 00397 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 00398 mbedtls_free( csr->sig_opts ); 00399 #endif 00400 00401 name_cur = csr->subject.next; 00402 while( name_cur != NULL ) 00403 { 00404 name_prv = name_cur; 00405 name_cur = name_cur->next; 00406 mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); 00407 mbedtls_free( name_prv ); 00408 } 00409 00410 if( csr->raw.p != NULL ) 00411 { 00412 mbedtls_platform_zeroize( csr->raw.p, csr->raw.len ); 00413 mbedtls_free( csr->raw.p ); 00414 } 00415 00416 mbedtls_platform_zeroize( csr, sizeof( mbedtls_x509_csr ) ); 00417 } 00418 00419 #endif /* MBEDTLS_X509_CSR_PARSE_C */
Generated on Tue Jul 12 2022 12:46:20 by
