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
x509write_csr.c
00001 /* 00002 * X.509 Certificate Signing Request 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 * - CSRs: PKCS#10 v1.7 aka RFC 2986 00024 * - attributes: PKCS#9 v2.0 aka RFC 2985 00025 */ 00026 00027 #if !defined(MBEDTLS_CONFIG_FILE) 00028 #include "mbedtls/config.h" 00029 #else 00030 #include MBEDTLS_CONFIG_FILE 00031 #endif 00032 00033 #if defined(MBEDTLS_X509_CSR_WRITE_C) 00034 00035 #include "mbedtls/x509_csr.h" 00036 #include "mbedtls/oid.h" 00037 #include "mbedtls/asn1write.h" 00038 00039 #include <string.h> 00040 #include <stdlib.h> 00041 00042 #if defined(MBEDTLS_PEM_WRITE_C) 00043 #include "mbedtls/pem.h" 00044 #endif 00045 00046 /* Implementation that should never be optimized out by the compiler */ 00047 static void mbedtls_zeroize( void *v, size_t n ) { 00048 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00049 } 00050 00051 void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ) 00052 { 00053 memset( ctx, 0, sizeof(mbedtls_x509write_csr) ); 00054 } 00055 00056 void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx ) 00057 { 00058 mbedtls_asn1_free_named_data_list( &ctx->subject ); 00059 mbedtls_asn1_free_named_data_list( &ctx->extensions ); 00060 00061 mbedtls_zeroize( ctx, sizeof(mbedtls_x509write_csr) ); 00062 } 00063 00064 void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg ) 00065 { 00066 ctx->md_alg = md_alg; 00067 } 00068 00069 void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key ) 00070 { 00071 ctx->key = key; 00072 } 00073 00074 int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx, 00075 const char *subject_name ) 00076 { 00077 return mbedtls_x509_string_to_names( &ctx->subject, subject_name ); 00078 } 00079 00080 int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx, 00081 const char *oid, size_t oid_len, 00082 const unsigned char *val, size_t val_len ) 00083 { 00084 return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, 00085 0, val, val_len ); 00086 } 00087 00088 int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage ) 00089 { 00090 unsigned char buf[4]; 00091 unsigned char *c; 00092 int ret; 00093 00094 c = buf + 4; 00095 00096 if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 ) 00097 return( ret ); 00098 00099 ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, 00100 MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), 00101 buf, 4 ); 00102 if( ret != 0 ) 00103 return( ret ); 00104 00105 return( 0 ); 00106 } 00107 00108 int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx, 00109 unsigned char ns_cert_type ) 00110 { 00111 unsigned char buf[4]; 00112 unsigned char *c; 00113 int ret; 00114 00115 c = buf + 4; 00116 00117 if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 ) 00118 return( ret ); 00119 00120 ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, 00121 MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), 00122 buf, 4 ); 00123 if( ret != 0 ) 00124 return( ret ); 00125 00126 return( 0 ); 00127 } 00128 00129 int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, 00130 int (*f_rng)(void *, unsigned char *, size_t), 00131 void *p_rng ) 00132 { 00133 int ret; 00134 const char *sig_oid; 00135 size_t sig_oid_len = 0; 00136 unsigned char *c, *c2; 00137 unsigned char hash[64]; 00138 unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; 00139 unsigned char tmp_buf[2048]; 00140 size_t pub_len = 0, sig_and_oid_len = 0, sig_len; 00141 size_t len = 0; 00142 mbedtls_pk_type_t pk_alg; 00143 00144 /* 00145 * Prepare data to be signed in tmp_buf 00146 */ 00147 c = tmp_buf + sizeof( tmp_buf ); 00148 00149 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); 00150 00151 if( len ) 00152 { 00153 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); 00154 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | 00155 MBEDTLS_ASN1_SEQUENCE ) ); 00156 00157 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); 00158 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | 00159 MBEDTLS_ASN1_SET ) ); 00160 00161 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ, 00162 MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) ); 00163 00164 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); 00165 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | 00166 MBEDTLS_ASN1_SEQUENCE ) ); 00167 } 00168 00169 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); 00170 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | 00171 MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ); 00172 00173 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key, 00174 tmp_buf, c - tmp_buf ) ); 00175 c -= pub_len; 00176 len += pub_len; 00177 00178 /* 00179 * Subject ::= Name 00180 */ 00181 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) ); 00182 00183 /* 00184 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 00185 */ 00186 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) ); 00187 00188 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); 00189 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | 00190 MBEDTLS_ASN1_SEQUENCE ) ); 00191 00192 /* 00193 * Prepare signature 00194 */ 00195 mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); 00196 00197 pk_alg = mbedtls_pk_get_type( ctx->key ); 00198 if( pk_alg == MBEDTLS_PK_ECKEY ) 00199 pk_alg = MBEDTLS_PK_ECDSA; 00200 00201 if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, 00202 f_rng, p_rng ) ) != 0 || 00203 ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, 00204 &sig_oid, &sig_oid_len ) ) != 0 ) 00205 { 00206 return( ret ); 00207 } 00208 00209 /* 00210 * Write data to output buffer 00211 */ 00212 c2 = buf + size; 00213 MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, 00214 sig_oid, sig_oid_len, sig, sig_len ) ); 00215 00216 if( len > (size_t)( c2 - buf ) ) 00217 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00218 00219 c2 -= len; 00220 memcpy( c2, c, len ); 00221 00222 len += sig_and_oid_len; 00223 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); 00224 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED | 00225 MBEDTLS_ASN1_SEQUENCE ) ); 00226 00227 return( (int) len ); 00228 } 00229 00230 #define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" 00231 #define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" 00232 00233 #if defined(MBEDTLS_PEM_WRITE_C) 00234 int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, 00235 int (*f_rng)(void *, unsigned char *, size_t), 00236 void *p_rng ) 00237 { 00238 int ret; 00239 unsigned char output_buf[4096]; 00240 size_t olen = 0; 00241 00242 if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf), 00243 f_rng, p_rng ) ) < 0 ) 00244 { 00245 return( ret ); 00246 } 00247 00248 if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR, 00249 output_buf + sizeof(output_buf) - ret, 00250 ret, buf, size, &olen ) ) != 0 ) 00251 { 00252 return( ret ); 00253 } 00254 00255 return( 0 ); 00256 } 00257 #endif /* MBEDTLS_PEM_WRITE_C */ 00258 00259 #endif /* MBEDTLS_X509_CSR_WRITE_C */
Generated on Tue Jul 12 2022 17:25:44 by
