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 || buflen == 0 ) 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 if( csr->version != 0 ) 00172 { 00173 mbedtls_x509_csr_free( csr ); 00174 return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); 00175 } 00176 00177 csr->version++; 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 * The list of possible attributes is open-ended, though RFC 2985 00212 * (PKCS#9) defines a few in section 5.4. We currently don't support any, 00213 * so we just ignore them. This is a safe thing to do as the worst thing 00214 * that could happen is that we issue a certificate that does not match 00215 * the requester's expectations - this cannot cause a violation of our 00216 * signature policies. 00217 */ 00218 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00219 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 ) 00220 { 00221 mbedtls_x509_csr_free( csr ); 00222 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); 00223 } 00224 00225 p += len; 00226 00227 end = csr->raw.p + csr->raw.len; 00228 00229 /* 00230 * signatureAlgorithm AlgorithmIdentifier, 00231 * signature BIT STRING 00232 */ 00233 if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 ) 00234 { 00235 mbedtls_x509_csr_free( csr ); 00236 return( ret ); 00237 } 00238 00239 if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params, 00240 &csr->sig_md, &csr->sig_pk, 00241 &csr->sig_opts ) ) != 0 ) 00242 { 00243 mbedtls_x509_csr_free( csr ); 00244 return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG ); 00245 } 00246 00247 if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 ) 00248 { 00249 mbedtls_x509_csr_free( csr ); 00250 return( ret ); 00251 } 00252 00253 if( p != end ) 00254 { 00255 mbedtls_x509_csr_free( csr ); 00256 return( MBEDTLS_ERR_X509_INVALID_FORMAT + 00257 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00258 } 00259 00260 return( 0 ); 00261 } 00262 00263 /* 00264 * Parse a CSR, allowing for PEM or raw DER encoding 00265 */ 00266 int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen ) 00267 { 00268 #if defined(MBEDTLS_PEM_PARSE_C) 00269 int ret; 00270 size_t use_len; 00271 mbedtls_pem_context pem; 00272 #endif 00273 00274 /* 00275 * Check for valid input 00276 */ 00277 if( csr == NULL || buf == NULL || buflen == 0 ) 00278 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 00279 00280 #if defined(MBEDTLS_PEM_PARSE_C) 00281 mbedtls_pem_init( &pem ); 00282 00283 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ 00284 if( buf[buflen - 1] != '\0' ) 00285 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; 00286 else 00287 ret = mbedtls_pem_read_buffer( &pem, 00288 "-----BEGIN CERTIFICATE REQUEST-----", 00289 "-----END CERTIFICATE REQUEST-----", 00290 buf, NULL, 0, &use_len ); 00291 00292 if( ret == 0 ) 00293 { 00294 /* 00295 * Was PEM encoded, parse the result 00296 */ 00297 if( ( ret = mbedtls_x509_csr_parse_der( csr, pem.buf , pem.buflen ) ) != 0 ) 00298 return( ret ); 00299 00300 mbedtls_pem_free( &pem ); 00301 return( 0 ); 00302 } 00303 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 00304 { 00305 mbedtls_pem_free( &pem ); 00306 return( ret ); 00307 } 00308 else 00309 #endif /* MBEDTLS_PEM_PARSE_C */ 00310 return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) ); 00311 } 00312 00313 #if defined(MBEDTLS_FS_IO) 00314 /* 00315 * Load a CSR into the structure 00316 */ 00317 int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path ) 00318 { 00319 int ret; 00320 size_t n; 00321 unsigned char *buf; 00322 00323 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) 00324 return( ret ); 00325 00326 ret = mbedtls_x509_csr_parse( csr, buf, n ); 00327 00328 mbedtls_zeroize( buf, n ); 00329 mbedtls_free( buf ); 00330 00331 return( ret ); 00332 } 00333 #endif /* MBEDTLS_FS_IO */ 00334 00335 #define BEFORE_COLON 14 00336 #define BC "14" 00337 /* 00338 * Return an informational string about the CSR. 00339 */ 00340 int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, 00341 const mbedtls_x509_csr *csr ) 00342 { 00343 int ret; 00344 size_t n; 00345 char *p; 00346 char key_size_str[BEFORE_COLON]; 00347 00348 p = buf; 00349 n = size; 00350 00351 ret = mbedtls_snprintf( p, n, "%sCSR version : %d", 00352 prefix, csr->version ); 00353 MBEDTLS_X509_SAFE_SNPRINTF; 00354 00355 ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); 00356 MBEDTLS_X509_SAFE_SNPRINTF; 00357 ret = mbedtls_x509_dn_gets( p, n, &csr->subject ); 00358 MBEDTLS_X509_SAFE_SNPRINTF; 00359 00360 ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); 00361 MBEDTLS_X509_SAFE_SNPRINTF; 00362 00363 ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md, 00364 csr->sig_opts ); 00365 MBEDTLS_X509_SAFE_SNPRINTF; 00366 00367 if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, 00368 mbedtls_pk_get_name( &csr->pk ) ) ) != 0 ) 00369 { 00370 return( ret ); 00371 } 00372 00373 ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, 00374 (int) mbedtls_pk_get_bitlen( &csr->pk ) ); 00375 MBEDTLS_X509_SAFE_SNPRINTF; 00376 00377 return( (int) ( size - n ) ); 00378 } 00379 00380 /* 00381 * Initialize a CSR 00382 */ 00383 void mbedtls_x509_csr_init( mbedtls_x509_csr *csr ) 00384 { 00385 memset( csr, 0, sizeof(mbedtls_x509_csr) ); 00386 } 00387 00388 /* 00389 * Unallocate all CSR data 00390 */ 00391 void mbedtls_x509_csr_free( mbedtls_x509_csr *csr ) 00392 { 00393 mbedtls_x509_name *name_cur; 00394 mbedtls_x509_name *name_prv; 00395 00396 if( csr == NULL ) 00397 return; 00398 00399 mbedtls_pk_free( &csr->pk ); 00400 00401 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 00402 mbedtls_free( csr->sig_opts ); 00403 #endif 00404 00405 name_cur = csr->subject.next; 00406 while( name_cur != NULL ) 00407 { 00408 name_prv = name_cur; 00409 name_cur = name_cur->next; 00410 mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); 00411 mbedtls_free( name_prv ); 00412 } 00413 00414 if( csr->raw.p != NULL ) 00415 { 00416 mbedtls_zeroize( csr->raw.p, csr->raw.len ); 00417 mbedtls_free( csr->raw.p ); 00418 } 00419 00420 mbedtls_zeroize( csr, sizeof( mbedtls_x509_csr ) ); 00421 } 00422 00423 #endif /* MBEDTLS_X509_CSR_PARSE_C */
Generated on Tue Jul 12 2022 17:25:44 by
