Marco Zecchini
/
Example_RTOS
Rtos API example
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 || 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 Sun Jul 17 2022 08:25:33 by 1.7.2