mbed TLS library
Dependents: HTTPClient-SSL WS_SERVER
x509write_csr.c
00001 /* 00002 * X.509 Certificate Signing Request writing 00003 * 00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved 00005 * 00006 * This file is part of mbed TLS (https://tls.mbed.org) 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with this program; if not, write to the Free Software Foundation, Inc., 00020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 */ 00022 /* 00023 * References: 00024 * - CSRs: PKCS#10 v1.7 aka RFC 2986 00025 * - attributes: PKCS#9 v2.0 aka RFC 2985 00026 */ 00027 00028 #if !defined(POLARSSL_CONFIG_FILE) 00029 #include "polarssl/config.h" 00030 #else 00031 #include POLARSSL_CONFIG_FILE 00032 #endif 00033 00034 #if defined(POLARSSL_X509_CSR_WRITE_C) 00035 00036 #include "polarssl/x509_csr.h" 00037 #include "polarssl/oid.h" 00038 #include "polarssl/asn1write.h" 00039 00040 #include <string.h> 00041 #include <stdlib.h> 00042 00043 #if defined(POLARSSL_PEM_WRITE_C) 00044 #include "polarssl/pem.h" 00045 #endif 00046 00047 /* Implementation that should never be optimized out by the compiler */ 00048 static void polarssl_zeroize( void *v, size_t n ) { 00049 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00050 } 00051 00052 void x509write_csr_init( x509write_csr *ctx ) 00053 { 00054 memset( ctx, 0, sizeof(x509write_csr) ); 00055 } 00056 00057 void x509write_csr_free( x509write_csr *ctx ) 00058 { 00059 asn1_free_named_data_list( &ctx->subject ); 00060 asn1_free_named_data_list( &ctx->extensions ); 00061 00062 polarssl_zeroize( ctx, sizeof(x509write_csr) ); 00063 } 00064 00065 void x509write_csr_set_md_alg( x509write_csr *ctx, md_type_t md_alg ) 00066 { 00067 ctx->md_alg = md_alg; 00068 } 00069 00070 void x509write_csr_set_key( x509write_csr *ctx, pk_context *key ) 00071 { 00072 ctx->key = key; 00073 } 00074 00075 int x509write_csr_set_subject_name( x509write_csr *ctx, 00076 const char *subject_name ) 00077 { 00078 return x509_string_to_names( &ctx->subject, subject_name ); 00079 } 00080 00081 int x509write_csr_set_extension( x509write_csr *ctx, 00082 const char *oid, size_t oid_len, 00083 const unsigned char *val, size_t val_len ) 00084 { 00085 return x509_set_extension( &ctx->extensions, oid, oid_len, 00086 0, val, val_len ); 00087 } 00088 00089 int x509write_csr_set_key_usage( x509write_csr *ctx, unsigned char key_usage ) 00090 { 00091 unsigned char buf[4]; 00092 unsigned char *c; 00093 int ret; 00094 00095 c = buf + 4; 00096 00097 if( ( ret = asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 ) 00098 return( ret ); 00099 00100 ret = x509write_csr_set_extension( ctx, OID_KEY_USAGE, 00101 OID_SIZE( OID_KEY_USAGE ), 00102 buf, 4 ); 00103 if( ret != 0 ) 00104 return( ret ); 00105 00106 return( 0 ); 00107 } 00108 00109 int x509write_csr_set_ns_cert_type( x509write_csr *ctx, 00110 unsigned char ns_cert_type ) 00111 { 00112 unsigned char buf[4]; 00113 unsigned char *c; 00114 int ret; 00115 00116 c = buf + 4; 00117 00118 if( ( ret = asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 ) 00119 return( ret ); 00120 00121 ret = x509write_csr_set_extension( ctx, OID_NS_CERT_TYPE, 00122 OID_SIZE( OID_NS_CERT_TYPE ), 00123 buf, 4 ); 00124 if( ret != 0 ) 00125 return( ret ); 00126 00127 return( 0 ); 00128 } 00129 00130 int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size, 00131 int (*f_rng)(void *, unsigned char *, size_t), 00132 void *p_rng ) 00133 { 00134 int ret; 00135 const char *sig_oid; 00136 size_t sig_oid_len = 0; 00137 unsigned char *c, *c2; 00138 unsigned char hash[64]; 00139 unsigned char sig[POLARSSL_MPI_MAX_SIZE]; 00140 unsigned char tmp_buf[2048]; 00141 size_t pub_len = 0, sig_and_oid_len = 0, sig_len; 00142 size_t len = 0; 00143 pk_type_t pk_alg; 00144 00145 /* 00146 * Prepare data to be signed in tmp_buf 00147 */ 00148 c = tmp_buf + sizeof( tmp_buf ); 00149 00150 ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); 00151 00152 if( len ) 00153 { 00154 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); 00155 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | 00156 ASN1_SEQUENCE ) ); 00157 00158 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); 00159 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | 00160 ASN1_SET ) ); 00161 00162 ASN1_CHK_ADD( len, asn1_write_oid( &c, tmp_buf, OID_PKCS9_CSR_EXT_REQ, 00163 OID_SIZE( OID_PKCS9_CSR_EXT_REQ ) ) ); 00164 00165 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); 00166 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | 00167 ASN1_SEQUENCE ) ); 00168 } 00169 00170 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); 00171 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | 00172 ASN1_CONTEXT_SPECIFIC ) ); 00173 00174 ASN1_CHK_ADD( pub_len, pk_write_pubkey_der( ctx->key, 00175 tmp_buf, c - tmp_buf ) ); 00176 c -= pub_len; 00177 len += pub_len; 00178 00179 /* 00180 * Subject ::= Name 00181 */ 00182 ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) ); 00183 00184 /* 00185 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 00186 */ 00187 ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) ); 00188 00189 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); 00190 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | 00191 ASN1_SEQUENCE ) ); 00192 00193 /* 00194 * Prepare signature 00195 */ 00196 md( md_info_from_type( ctx->md_alg ), c, len, hash ); 00197 00198 pk_alg = pk_get_type( ctx->key ); 00199 if( pk_alg == POLARSSL_PK_ECKEY ) 00200 pk_alg = POLARSSL_PK_ECDSA; 00201 00202 if( ( ret = pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, 00203 f_rng, p_rng ) ) != 0 || 00204 ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, 00205 &sig_oid, &sig_oid_len ) ) != 0 ) 00206 { 00207 return( ret ); 00208 } 00209 00210 /* 00211 * Write data to output buffer 00212 */ 00213 c2 = buf + size; 00214 ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf, 00215 sig_oid, sig_oid_len, sig, sig_len ) ); 00216 00217 c2 -= len; 00218 memcpy( c2, c, len ); 00219 00220 len += sig_and_oid_len; 00221 ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) ); 00222 ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | 00223 ASN1_SEQUENCE ) ); 00224 00225 return( (int) len ); 00226 } 00227 00228 #define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" 00229 #define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" 00230 00231 #if defined(POLARSSL_PEM_WRITE_C) 00232 int x509write_csr_pem( x509write_csr *ctx, unsigned char *buf, size_t size, 00233 int (*f_rng)(void *, unsigned char *, size_t), 00234 void *p_rng ) 00235 { 00236 int ret; 00237 unsigned char output_buf[4096]; 00238 size_t olen = 0; 00239 00240 if( ( ret = x509write_csr_der( ctx, output_buf, sizeof(output_buf), 00241 f_rng, p_rng ) ) < 0 ) 00242 { 00243 return( ret ); 00244 } 00245 00246 if( ( ret = pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR, 00247 output_buf + sizeof(output_buf) - ret, 00248 ret, buf, size, &olen ) ) != 0 ) 00249 { 00250 return( ret ); 00251 } 00252 00253 return( 0 ); 00254 } 00255 #endif /* POLARSSL_PEM_WRITE_C */ 00256 00257 #endif /* POLARSSL_X509_CSR_WRITE_C */ 00258
Generated on Tue Jul 12 2022 13:50:39 by 1.7.2