00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "polarssl/config.h"
00032
00033 #if defined(POLARSSL_X509_CSR_WRITE_C)
00034
00035 #include "polarssl/x509_csr.h"
00036 #include "polarssl/oid.h"
00037 #include "polarssl/asn1write.h"
00038
00039 #if defined(POLARSSL_PEM_WRITE_C)
00040 #include "polarssl/pem.h"
00041 #endif
00042
00043 #include <string.h>
00044 #include <stdlib.h>
00045
00046 void x509write_csr_init( x509write_csr *ctx )
00047 {
00048 memset( ctx, 0, sizeof(x509write_csr) );
00049 }
00050
00051 void x509write_csr_free( x509write_csr *ctx )
00052 {
00053 asn1_free_named_data_list( &ctx->subject );
00054 asn1_free_named_data_list( &ctx->extensions );
00055
00056 memset( ctx, 0, sizeof(x509write_csr) );
00057 }
00058
00059 void x509write_csr_set_md_alg( x509write_csr *ctx, md_type_t md_alg )
00060 {
00061 ctx->md_alg = md_alg;
00062 }
00063
00064 void x509write_csr_set_key( x509write_csr *ctx, pk_context *key )
00065 {
00066 ctx->key = key;
00067 }
00068
00069 int x509write_csr_set_subject_name( x509write_csr *ctx,
00070 const char *subject_name )
00071 {
00072 return x509_string_to_names( &ctx->subject, subject_name );
00073 }
00074
00075 int x509write_csr_set_extension( x509write_csr *ctx,
00076 const char *oid, size_t oid_len,
00077 const unsigned char *val, size_t val_len )
00078 {
00079 return x509_set_extension( &ctx->extensions, oid, oid_len,
00080 0, val, val_len );
00081 }
00082
00083 int x509write_csr_set_key_usage( x509write_csr *ctx, unsigned char key_usage )
00084 {
00085 unsigned char buf[4];
00086 unsigned char *c;
00087 int ret;
00088
00089 c = buf + 4;
00090
00091 if( ( ret = asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 )
00092 return( ret );
00093
00094 ret = x509write_csr_set_extension( ctx, OID_KEY_USAGE,
00095 OID_SIZE( OID_KEY_USAGE ),
00096 buf, 4 );
00097 if( ret != 0 )
00098 return( ret );
00099
00100 return( 0 );
00101 }
00102
00103 int x509write_csr_set_ns_cert_type( x509write_csr *ctx,
00104 unsigned char ns_cert_type )
00105 {
00106 unsigned char buf[4];
00107 unsigned char *c;
00108 int ret;
00109
00110 c = buf + 4;
00111
00112 if( ( ret = asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 )
00113 return( ret );
00114
00115 ret = x509write_csr_set_extension( ctx, OID_NS_CERT_TYPE,
00116 OID_SIZE( OID_NS_CERT_TYPE ),
00117 buf, 4 );
00118 if( ret != 0 )
00119 return( ret );
00120
00121 return( 0 );
00122 }
00123
00124 int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size,
00125 int (*f_rng)(void *, unsigned char *, size_t),
00126 void *p_rng )
00127 {
00128 int ret;
00129 const char *sig_oid;
00130 size_t sig_oid_len = 0;
00131 unsigned char *c, *c2;
00132 unsigned char hash[64];
00133 unsigned char sig[POLARSSL_MPI_MAX_SIZE];
00134 unsigned char tmp_buf[2048];
00135 size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
00136 size_t len = 0;
00137 pk_type_t pk_alg;
00138
00139
00140
00141
00142 c = tmp_buf + sizeof( tmp_buf );
00143
00144 ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
00145
00146 if( len )
00147 {
00148 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
00149 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00150
00151 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
00152 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SET ) );
00153
00154 ASN1_CHK_ADD( len, asn1_write_oid( &c, tmp_buf, OID_PKCS9_CSR_EXT_REQ,
00155 OID_SIZE( OID_PKCS9_CSR_EXT_REQ ) ) );
00156
00157 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
00158 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00159 }
00160
00161 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
00162 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) );
00163
00164 ASN1_CHK_ADD( pub_len, pk_write_pubkey_der( ctx->key,
00165 tmp_buf, c - tmp_buf ) );
00166 c -= pub_len;
00167 len += pub_len;
00168
00169
00170
00171
00172 ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) );
00173
00174
00175
00176
00177 ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) );
00178
00179 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
00180 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00181
00182
00183
00184
00185 md( md_info_from_type( ctx->md_alg ), c, len, hash );
00186
00187 pk_alg = pk_get_type( ctx->key );
00188 if( pk_alg == POLARSSL_PK_ECKEY )
00189 pk_alg = POLARSSL_PK_ECDSA;
00190
00191 if( ( ret = pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
00192 f_rng, p_rng ) ) != 0 ||
00193 ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
00194 &sig_oid, &sig_oid_len ) ) != 0 )
00195 {
00196 return( ret );
00197 }
00198
00199
00200
00201
00202 c2 = buf + size;
00203 ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf,
00204 sig_oid, sig_oid_len, sig, sig_len ) );
00205
00206 c2 -= len;
00207 memcpy( c2, c, len );
00208
00209 len += sig_and_oid_len;
00210 ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
00211 ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00212
00213 return( (int) len );
00214 }
00215
00216 #define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n"
00217 #define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n"
00218
00219 #if defined(POLARSSL_PEM_WRITE_C)
00220 int x509write_csr_pem( x509write_csr *ctx, unsigned char *buf, size_t size,
00221 int (*f_rng)(void *, unsigned char *, size_t),
00222 void *p_rng )
00223 {
00224 int ret;
00225 unsigned char output_buf[4096];
00226 size_t olen = 0;
00227
00228 if( ( ret = x509write_csr_der( ctx, output_buf, sizeof(output_buf),
00229 f_rng, p_rng ) ) < 0 )
00230 {
00231 return( ret );
00232 }
00233
00234 if( ( ret = pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR,
00235 output_buf + sizeof(output_buf) - ret,
00236 ret, buf, size, &olen ) ) != 0 )
00237 {
00238 return( ret );
00239 }
00240
00241 return( 0 );
00242 }
00243 #endif
00244
00245 #endif