mbedtls ported to mbed-classic
Fork of mbedtls by
Embed:
(wiki syntax)
Show/hide line numbers
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 1.7.2