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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
x509write_crt.c
00001 /* 00002 * X.509 certificate writing 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 * References: 00023 * - certificates: RFC 5280, updated by RFC 6818 00024 * - CSRs: PKCS#10 v1.7 aka RFC 2986 00025 * - attributes: PKCS#9 v2.0 aka RFC 2985 00026 */ 00027 00028 #if !defined(MBEDTLS_CONFIG_FILE) 00029 #include "mbedtls/config.h" 00030 #else 00031 #include MBEDTLS_CONFIG_FILE 00032 #endif 00033 00034 #if defined(MBEDTLS_X509_CRT_WRITE_C) 00035 00036 #include "mbedtls/x509_crt.h" 00037 #include "mbedtls/oid.h" 00038 #include "mbedtls/asn1write.h" 00039 #include "mbedtls/sha1.h" 00040 #include "mbedtls/platform_util.h" 00041 00042 #include <string.h> 00043 00044 #if defined(MBEDTLS_PEM_WRITE_C) 00045 #include "mbedtls/pem.h" 00046 #endif /* MBEDTLS_PEM_WRITE_C */ 00047 00048 /* 00049 * For the currently used signature algorithms the buffer to store any signature 00050 * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE) 00051 */ 00052 #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE 00053 #define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN 00054 #else 00055 #define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE 00056 #endif 00057 00058 void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ) 00059 { 00060 memset( ctx, 0, sizeof( mbedtls_x509write_cert ) ); 00061 00062 mbedtls_mpi_init( &ctx->serial ); 00063 ctx->version = MBEDTLS_X509_CRT_VERSION_3; 00064 } 00065 00066 void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ) 00067 { 00068 mbedtls_mpi_free( &ctx->serial ); 00069 00070 mbedtls_asn1_free_named_data_list( &ctx->subject ); 00071 mbedtls_asn1_free_named_data_list( &ctx->issuer ); 00072 mbedtls_asn1_free_named_data_list( &ctx->extensions ); 00073 00074 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_cert ) ); 00075 } 00076 00077 void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, 00078 int version ) 00079 { 00080 ctx->version = version; 00081 } 00082 00083 void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, 00084 mbedtls_md_type_t md_alg ) 00085 { 00086 ctx->md_alg = md_alg; 00087 } 00088 00089 void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, 00090 mbedtls_pk_context *key ) 00091 { 00092 ctx->subject_key = key; 00093 } 00094 00095 void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, 00096 mbedtls_pk_context *key ) 00097 { 00098 ctx->issuer_key = key; 00099 } 00100 00101 int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx, 00102 const char *subject_name ) 00103 { 00104 return mbedtls_x509_string_to_names( &ctx->subject, subject_name ); 00105 } 00106 00107 int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx, 00108 const char *issuer_name ) 00109 { 00110 return mbedtls_x509_string_to_names( &ctx->issuer, issuer_name ); 00111 } 00112 00113 int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, 00114 const mbedtls_mpi *serial ) 00115 { 00116 int ret; 00117 00118 if( ( ret = mbedtls_mpi_copy( &ctx->serial, serial ) ) != 0 ) 00119 return( ret ); 00120 00121 return( 0 ); 00122 } 00123 00124 int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, 00125 const char *not_before, 00126 const char *not_after ) 00127 { 00128 if( strlen( not_before ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 || 00129 strlen( not_after ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 ) 00130 { 00131 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 00132 } 00133 strncpy( ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN ); 00134 strncpy( ctx->not_after , not_after , MBEDTLS_X509_RFC5280_UTC_TIME_LEN ); 00135 ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; 00136 ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; 00137 00138 return( 0 ); 00139 } 00140 00141 int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx, 00142 const char *oid, size_t oid_len, 00143 int critical, 00144 const unsigned char *val, size_t val_len ) 00145 { 00146 return( mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, 00147 critical, val, val_len ) ); 00148 } 00149 00150 int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx, 00151 int is_ca, int max_pathlen ) 00152 { 00153 int ret; 00154 unsigned char buf[9]; 00155 unsigned char *c = buf + sizeof(buf); 00156 size_t len = 0; 00157 00158 memset( buf, 0, sizeof(buf) ); 00159 00160 if( is_ca && max_pathlen > 127 ) 00161 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 00162 00163 if( is_ca ) 00164 { 00165 if( max_pathlen >= 0 ) 00166 { 00167 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 00168 max_pathlen ) ); 00169 } 00170 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) ); 00171 } 00172 00173 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 00174 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, 00175 MBEDTLS_ASN1_CONSTRUCTED | 00176 MBEDTLS_ASN1_SEQUENCE ) ); 00177 00178 return( 00179 mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS, 00180 MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ), 00181 0, buf + sizeof(buf) - len, len ) ); 00182 } 00183 00184 #if defined(MBEDTLS_SHA1_C) 00185 int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx ) 00186 { 00187 int ret; 00188 unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ 00189 unsigned char *c = buf + sizeof(buf); 00190 size_t len = 0; 00191 00192 memset( buf, 0, sizeof(buf) ); 00193 MBEDTLS_ASN1_CHK_ADD( len, 00194 mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) ); 00195 00196 ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, 00197 buf + sizeof( buf ) - 20 ); 00198 if( ret != 0 ) 00199 return( ret ); 00200 c = buf + sizeof( buf ) - 20; 00201 len = 20; 00202 00203 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 00204 MBEDTLS_ASN1_CHK_ADD( len, 00205 mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) ); 00206 00207 return mbedtls_x509write_crt_set_extension( ctx, 00208 MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, 00209 MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ), 00210 0, buf + sizeof(buf) - len, len ); 00211 } 00212 00213 int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx ) 00214 { 00215 int ret; 00216 unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ 00217 unsigned char *c = buf + sizeof( buf ); 00218 size_t len = 0; 00219 00220 memset( buf, 0, sizeof(buf) ); 00221 MBEDTLS_ASN1_CHK_ADD( len, 00222 mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) ); 00223 00224 ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, 00225 buf + sizeof( buf ) - 20 ); 00226 if( ret != 0 ) 00227 return( ret ); 00228 c = buf + sizeof( buf ) - 20; 00229 len = 20; 00230 00231 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 00232 MBEDTLS_ASN1_CHK_ADD( len, 00233 mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) ); 00234 00235 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 00236 MBEDTLS_ASN1_CHK_ADD( len, 00237 mbedtls_asn1_write_tag( &c, buf, 00238 MBEDTLS_ASN1_CONSTRUCTED | 00239 MBEDTLS_ASN1_SEQUENCE ) ); 00240 00241 return mbedtls_x509write_crt_set_extension( 00242 ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, 00243 MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ), 00244 0, buf + sizeof( buf ) - len, len ); 00245 } 00246 #endif /* MBEDTLS_SHA1_C */ 00247 00248 int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx, 00249 unsigned int key_usage ) 00250 { 00251 unsigned char buf[5], ku[2]; 00252 unsigned char *c; 00253 int ret; 00254 const unsigned int allowed_bits = MBEDTLS_X509_KU_DIGITAL_SIGNATURE | 00255 MBEDTLS_X509_KU_NON_REPUDIATION | 00256 MBEDTLS_X509_KU_KEY_ENCIPHERMENT | 00257 MBEDTLS_X509_KU_DATA_ENCIPHERMENT | 00258 MBEDTLS_X509_KU_KEY_AGREEMENT | 00259 MBEDTLS_X509_KU_KEY_CERT_SIGN | 00260 MBEDTLS_X509_KU_CRL_SIGN | 00261 MBEDTLS_X509_KU_ENCIPHER_ONLY | 00262 MBEDTLS_X509_KU_DECIPHER_ONLY; 00263 00264 /* Check that nothing other than the allowed flags is set */ 00265 if( ( key_usage & ~allowed_bits ) != 0 ) 00266 return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); 00267 00268 c = buf + 5; 00269 ku[0] = (unsigned char)( key_usage ); 00270 ku[1] = (unsigned char)( key_usage >> 8 ); 00271 ret = mbedtls_asn1_write_named_bitstring( &c, buf, ku, 9 ); 00272 00273 if( ret < 0 ) 00274 return( ret ); 00275 else if( ret < 3 || ret > 5 ) 00276 return( MBEDTLS_ERR_X509_INVALID_FORMAT ); 00277 00278 ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, 00279 MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), 00280 1, c, (size_t)ret ); 00281 if( ret != 0 ) 00282 return( ret ); 00283 00284 return( 0 ); 00285 } 00286 00287 int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, 00288 unsigned char ns_cert_type ) 00289 { 00290 unsigned char buf[4]; 00291 unsigned char *c; 00292 int ret; 00293 00294 c = buf + 4; 00295 00296 ret = mbedtls_asn1_write_named_bitstring( &c, buf, &ns_cert_type, 8 ); 00297 if( ret < 3 || ret > 4 ) 00298 return( ret ); 00299 00300 ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, 00301 MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), 00302 0, c, (size_t)ret ); 00303 if( ret != 0 ) 00304 return( ret ); 00305 00306 return( 0 ); 00307 } 00308 00309 static int x509_write_time( unsigned char **p, unsigned char *start, 00310 const char *t, size_t size ) 00311 { 00312 int ret; 00313 size_t len = 0; 00314 00315 /* 00316 * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter) 00317 */ 00318 if( t[0] == '2' && t[1] == '0' && t[2] < '5' ) 00319 { 00320 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 00321 (const unsigned char *) t + 2, 00322 size - 2 ) ); 00323 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00324 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, 00325 MBEDTLS_ASN1_UTC_TIME ) ); 00326 } 00327 else 00328 { 00329 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 00330 (const unsigned char *) t, 00331 size ) ); 00332 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00333 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, 00334 MBEDTLS_ASN1_GENERALIZED_TIME ) ); 00335 } 00336 00337 return( (int) len ); 00338 } 00339 00340 int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, 00341 unsigned char *buf, size_t size, 00342 int (*f_rng)(void *, unsigned char *, size_t), 00343 void *p_rng ) 00344 { 00345 int ret; 00346 const char *sig_oid; 00347 size_t sig_oid_len = 0; 00348 unsigned char *c, *c2; 00349 unsigned char hash[64]; 00350 unsigned char sig[SIGNATURE_MAX_SIZE]; 00351 size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; 00352 size_t len = 0; 00353 mbedtls_pk_type_t pk_alg; 00354 00355 /* 00356 * Prepare data to be signed at the end of the target buffer 00357 */ 00358 c = buf + size; 00359 00360 /* Signature algorithm needed in TBS, and later for actual signature */ 00361 00362 /* There's no direct way of extracting a signature algorithm 00363 * (represented as an element of mbedtls_pk_type_t) from a PK instance. */ 00364 if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_RSA ) ) 00365 pk_alg = MBEDTLS_PK_RSA; 00366 else if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_ECDSA ) ) 00367 pk_alg = MBEDTLS_PK_ECDSA; 00368 else 00369 return( MBEDTLS_ERR_X509_INVALID_ALG ); 00370 00371 if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, 00372 &sig_oid, &sig_oid_len ) ) != 0 ) 00373 { 00374 return( ret ); 00375 } 00376 00377 /* 00378 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 00379 */ 00380 00381 /* Only for v3 */ 00382 if( ctx->version == MBEDTLS_X509_CRT_VERSION_3 ) 00383 { 00384 MBEDTLS_ASN1_CHK_ADD( len, 00385 mbedtls_x509_write_extensions( &c, 00386 buf, ctx->extensions ) ); 00387 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 00388 MBEDTLS_ASN1_CHK_ADD( len, 00389 mbedtls_asn1_write_tag( &c, buf, 00390 MBEDTLS_ASN1_CONSTRUCTED | 00391 MBEDTLS_ASN1_SEQUENCE ) ); 00392 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 00393 MBEDTLS_ASN1_CHK_ADD( len, 00394 mbedtls_asn1_write_tag( &c, buf, 00395 MBEDTLS_ASN1_CONTEXT_SPECIFIC | 00396 MBEDTLS_ASN1_CONSTRUCTED | 3 ) ); 00397 } 00398 00399 /* 00400 * SubjectPublicKeyInfo 00401 */ 00402 MBEDTLS_ASN1_CHK_ADD( pub_len, 00403 mbedtls_pk_write_pubkey_der( ctx->subject_key, 00404 buf, c - buf ) ); 00405 c -= pub_len; 00406 len += pub_len; 00407 00408 /* 00409 * Subject ::= Name 00410 */ 00411 MBEDTLS_ASN1_CHK_ADD( len, 00412 mbedtls_x509_write_names( &c, buf, 00413 ctx->subject ) ); 00414 00415 /* 00416 * Validity ::= SEQUENCE { 00417 * notBefore Time, 00418 * notAfter Time } 00419 */ 00420 sub_len = 0; 00421 00422 MBEDTLS_ASN1_CHK_ADD( sub_len, 00423 x509_write_time( &c, buf, ctx->not_after, 00424 MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); 00425 00426 MBEDTLS_ASN1_CHK_ADD( sub_len, 00427 x509_write_time( &c, buf, ctx->not_before, 00428 MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); 00429 00430 len += sub_len; 00431 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, sub_len ) ); 00432 MBEDTLS_ASN1_CHK_ADD( len, 00433 mbedtls_asn1_write_tag( &c, buf, 00434 MBEDTLS_ASN1_CONSTRUCTED | 00435 MBEDTLS_ASN1_SEQUENCE ) ); 00436 00437 /* 00438 * Issuer ::= Name 00439 */ 00440 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, buf, 00441 ctx->issuer ) ); 00442 00443 /* 00444 * Signature ::= AlgorithmIdentifier 00445 */ 00446 MBEDTLS_ASN1_CHK_ADD( len, 00447 mbedtls_asn1_write_algorithm_identifier( &c, buf, 00448 sig_oid, strlen( sig_oid ), 0 ) ); 00449 00450 /* 00451 * Serial ::= INTEGER 00452 */ 00453 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, 00454 &ctx->serial ) ); 00455 00456 /* 00457 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 00458 */ 00459 00460 /* Can be omitted for v1 */ 00461 if( ctx->version != MBEDTLS_X509_CRT_VERSION_1 ) 00462 { 00463 sub_len = 0; 00464 MBEDTLS_ASN1_CHK_ADD( sub_len, 00465 mbedtls_asn1_write_int( &c, buf, ctx->version ) ); 00466 len += sub_len; 00467 MBEDTLS_ASN1_CHK_ADD( len, 00468 mbedtls_asn1_write_len( &c, buf, sub_len ) ); 00469 MBEDTLS_ASN1_CHK_ADD( len, 00470 mbedtls_asn1_write_tag( &c, buf, 00471 MBEDTLS_ASN1_CONTEXT_SPECIFIC | 00472 MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); 00473 } 00474 00475 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 00476 MBEDTLS_ASN1_CHK_ADD( len, 00477 mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | 00478 MBEDTLS_ASN1_SEQUENCE ) ); 00479 00480 /* 00481 * Make signature 00482 */ 00483 00484 /* Compute hash of CRT. */ 00485 if( ( ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, 00486 len, hash ) ) != 0 ) 00487 { 00488 return( ret ); 00489 } 00490 00491 if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, 00492 hash, 0, sig, &sig_len, 00493 f_rng, p_rng ) ) != 0 ) 00494 { 00495 return( ret ); 00496 } 00497 00498 /* Move CRT to the front of the buffer to have space 00499 * for the signature. */ 00500 memmove( buf, c, len ); 00501 c = buf + len; 00502 00503 /* Add signature at the end of the buffer, 00504 * making sure that it doesn't underflow 00505 * into the CRT buffer. */ 00506 c2 = buf + size; 00507 MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, c, 00508 sig_oid, sig_oid_len, sig, sig_len ) ); 00509 00510 /* 00511 * Memory layout after this step: 00512 * 00513 * buf c=buf+len c2 buf+size 00514 * [CRT0,...,CRTn, UNUSED, ..., UNUSED, SIG0, ..., SIGm] 00515 */ 00516 00517 /* Move raw CRT to just before the signature. */ 00518 c = c2 - len; 00519 memmove( c, buf, len ); 00520 00521 len += sig_and_oid_len; 00522 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 00523 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, 00524 MBEDTLS_ASN1_CONSTRUCTED | 00525 MBEDTLS_ASN1_SEQUENCE ) ); 00526 00527 return( (int) len ); 00528 } 00529 00530 #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" 00531 #define PEM_END_CRT "-----END CERTIFICATE-----\n" 00532 00533 #if defined(MBEDTLS_PEM_WRITE_C) 00534 int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt, 00535 unsigned char *buf, size_t size, 00536 int (*f_rng)(void *, unsigned char *, size_t), 00537 void *p_rng ) 00538 { 00539 int ret; 00540 size_t olen; 00541 00542 if( ( ret = mbedtls_x509write_crt_der( crt, buf, size, 00543 f_rng, p_rng ) ) < 0 ) 00544 { 00545 return( ret ); 00546 } 00547 00548 if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT, 00549 buf + size - ret, ret, 00550 buf, size, &olen ) ) != 0 ) 00551 { 00552 return( ret ); 00553 } 00554 00555 return( 0 ); 00556 } 00557 #endif /* MBEDTLS_PEM_WRITE_C */ 00558 00559 #endif /* MBEDTLS_X509_CRT_WRITE_C */
Generated on Tue Jul 12 2022 13:55:05 by
