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
00032 #include "polarssl/config.h"
00033
00034 #if defined(POLARSSL_X509_CRT_WRITE_C)
00035
00036 #include "polarssl/x509_crt.h"
00037 #include "polarssl/oid.h"
00038 #include "polarssl/asn1write.h"
00039 #include "polarssl/sha1.h"
00040
00041 #if defined(POLARSSL_PEM_WRITE_C)
00042 #include "polarssl/pem.h"
00043 #endif
00044
00045 void x509write_crt_init( x509write_cert *ctx )
00046 {
00047 memset( ctx, 0, sizeof(x509write_cert) );
00048
00049 mpi_init( &ctx->serial );
00050 ctx->version = X509_CRT_VERSION_3;
00051 }
00052
00053 void x509write_crt_free( x509write_cert *ctx )
00054 {
00055 mpi_free( &ctx->serial );
00056
00057 asn1_free_named_data_list( &ctx->subject );
00058 asn1_free_named_data_list( &ctx->issuer );
00059 asn1_free_named_data_list( &ctx->extensions );
00060
00061 memset( ctx, 0, sizeof(x509write_cert) );
00062 }
00063
00064 void x509write_crt_set_version( x509write_cert *ctx, int version )
00065 {
00066 ctx->version = version;
00067 }
00068
00069 void x509write_crt_set_md_alg( x509write_cert *ctx, md_type_t md_alg )
00070 {
00071 ctx->md_alg = md_alg;
00072 }
00073
00074 void x509write_crt_set_subject_key( x509write_cert *ctx, pk_context *key )
00075 {
00076 ctx->subject_key = key;
00077 }
00078
00079 void x509write_crt_set_issuer_key( x509write_cert *ctx, pk_context *key )
00080 {
00081 ctx->issuer_key = key;
00082 }
00083
00084 int x509write_crt_set_subject_name( x509write_cert *ctx,
00085 const char *subject_name )
00086 {
00087 return x509_string_to_names( &ctx->subject, subject_name );
00088 }
00089
00090 int x509write_crt_set_issuer_name( x509write_cert *ctx,
00091 const char *issuer_name )
00092 {
00093 return x509_string_to_names( &ctx->issuer, issuer_name );
00094 }
00095
00096 int x509write_crt_set_serial( x509write_cert *ctx, const mpi *serial )
00097 {
00098 int ret;
00099
00100 if( ( ret = mpi_copy( &ctx->serial, serial ) ) != 0 )
00101 return( ret );
00102
00103 return( 0 );
00104 }
00105
00106 int x509write_crt_set_validity( x509write_cert *ctx, const char *not_before,
00107 const char *not_after )
00108 {
00109 if( strlen(not_before) != X509_RFC5280_UTC_TIME_LEN - 1 ||
00110 strlen(not_after) != X509_RFC5280_UTC_TIME_LEN - 1 )
00111 {
00112 return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00113 }
00114 strncpy( ctx->not_before, not_before, X509_RFC5280_UTC_TIME_LEN );
00115 strncpy( ctx->not_after , not_after , X509_RFC5280_UTC_TIME_LEN );
00116 ctx->not_before[X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
00117 ctx->not_after[X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
00118
00119 return( 0 );
00120 }
00121
00122 int x509write_crt_set_extension( x509write_cert *ctx,
00123 const char *oid, size_t oid_len,
00124 int critical,
00125 const unsigned char *val, size_t val_len )
00126 {
00127 return x509_set_extension( &ctx->extensions, oid, oid_len,
00128 critical, val, val_len );
00129 }
00130
00131 int x509write_crt_set_basic_constraints( x509write_cert *ctx,
00132 int is_ca, int max_pathlen )
00133 {
00134 int ret;
00135 unsigned char buf[9];
00136 unsigned char *c = buf + sizeof(buf);
00137 size_t len = 0;
00138
00139 memset( buf, 0, sizeof(buf) );
00140
00141 if( is_ca && max_pathlen > 127 )
00142 return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00143
00144 if( is_ca )
00145 {
00146 if( max_pathlen >= 0 )
00147 {
00148 ASN1_CHK_ADD( len, asn1_write_int( &c, buf, max_pathlen ) );
00149 }
00150 ASN1_CHK_ADD( len, asn1_write_bool( &c, buf, 1 ) );
00151 }
00152
00153 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
00154 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00155
00156 return x509write_crt_set_extension( ctx, OID_BASIC_CONSTRAINTS,
00157 OID_SIZE( OID_BASIC_CONSTRAINTS ),
00158 0, buf + sizeof(buf) - len, len );
00159 }
00160
00161 #if defined(POLARSSL_SHA1_C)
00162 int x509write_crt_set_subject_key_identifier( x509write_cert *ctx )
00163 {
00164 int ret;
00165 unsigned char buf[POLARSSL_MPI_MAX_SIZE * 2 + 20];
00166 unsigned char *c = buf + sizeof(buf);
00167 size_t len = 0;
00168
00169 memset( buf, 0, sizeof(buf));
00170 ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, ctx->subject_key ) );
00171
00172 sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 );
00173 c = buf + sizeof(buf) - 20;
00174 len = 20;
00175
00176 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
00177 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_OCTET_STRING ) );
00178
00179 return x509write_crt_set_extension( ctx, OID_SUBJECT_KEY_IDENTIFIER,
00180 OID_SIZE( OID_SUBJECT_KEY_IDENTIFIER ),
00181 0, buf + sizeof(buf) - len, len );
00182 }
00183
00184 int x509write_crt_set_authority_key_identifier( x509write_cert *ctx )
00185 {
00186 int ret;
00187 unsigned char buf[POLARSSL_MPI_MAX_SIZE * 2 + 20];
00188 unsigned char *c = buf + sizeof(buf);
00189 size_t len = 0;
00190
00191 memset( buf, 0, sizeof(buf));
00192 ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, ctx->issuer_key ) );
00193
00194 sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 );
00195 c = buf + sizeof(buf) - 20;
00196 len = 20;
00197
00198 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
00199 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONTEXT_SPECIFIC | 0 ) );
00200
00201 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
00202 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00203
00204 return x509write_crt_set_extension( ctx, OID_AUTHORITY_KEY_IDENTIFIER,
00205 OID_SIZE( OID_AUTHORITY_KEY_IDENTIFIER ),
00206 0, buf + sizeof(buf) - len, len );
00207 }
00208 #endif
00209
00210 int x509write_crt_set_key_usage( x509write_cert *ctx, unsigned char key_usage )
00211 {
00212 unsigned char buf[4];
00213 unsigned char *c;
00214 int ret;
00215
00216 c = buf + 4;
00217
00218 if( ( ret = asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 )
00219 return( ret );
00220
00221 ret = x509write_crt_set_extension( ctx, OID_KEY_USAGE,
00222 OID_SIZE( OID_KEY_USAGE ),
00223 1, buf, 4 );
00224 if( ret != 0 )
00225 return( ret );
00226
00227 return( 0 );
00228 }
00229
00230 int x509write_crt_set_ns_cert_type( x509write_cert *ctx,
00231 unsigned char ns_cert_type )
00232 {
00233 unsigned char buf[4];
00234 unsigned char *c;
00235 int ret;
00236
00237 c = buf + 4;
00238
00239 if( ( ret = asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 )
00240 return( ret );
00241
00242 ret = x509write_crt_set_extension( ctx, OID_NS_CERT_TYPE,
00243 OID_SIZE( OID_NS_CERT_TYPE ),
00244 0, buf, 4 );
00245 if( ret != 0 )
00246 return( ret );
00247
00248 return( 0 );
00249 }
00250
00251 static int x509_write_time( unsigned char **p, unsigned char *start,
00252 const char *time, size_t size )
00253 {
00254 int ret;
00255 size_t len = 0;
00256
00257
00258
00259
00260 if( time[0] == '2' && time[1] == '0' && time [2] < '5' )
00261 {
00262 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
00263 (const unsigned char *) time + 2,
00264 size - 2 ) );
00265 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00266 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_UTC_TIME ) );
00267 }
00268 else
00269 {
00270 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
00271 (const unsigned char *) time,
00272 size ) );
00273 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00274 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_GENERALIZED_TIME ) );
00275 }
00276
00277 return( (int) len );
00278 }
00279
00280 int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size,
00281 int (*f_rng)(void *, unsigned char *, size_t),
00282 void *p_rng )
00283 {
00284 int ret;
00285 const char *sig_oid;
00286 size_t sig_oid_len = 0;
00287 unsigned char *c, *c2;
00288 unsigned char hash[64];
00289 unsigned char sig[POLARSSL_MPI_MAX_SIZE];
00290 unsigned char tmp_buf[2048];
00291 size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
00292 size_t len = 0;
00293 pk_type_t pk_alg;
00294
00295
00296
00297
00298 c = tmp_buf + sizeof( tmp_buf );
00299
00300
00301 pk_alg = pk_get_type( ctx->issuer_key );
00302 if( pk_alg == POLARSSL_PK_ECKEY )
00303 pk_alg = POLARSSL_PK_ECDSA;
00304
00305 if( ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
00306 &sig_oid, &sig_oid_len ) ) != 0 )
00307 {
00308 return( ret );
00309 }
00310
00311
00312
00313
00314 ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
00315 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
00316 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00317 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
00318 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) );
00319
00320
00321
00322
00323 ASN1_CHK_ADD( pub_len, pk_write_pubkey_der( ctx->subject_key,
00324 tmp_buf, c - tmp_buf ) );
00325 c -= pub_len;
00326 len += pub_len;
00327
00328
00329
00330
00331 ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) );
00332
00333
00334
00335
00336
00337
00338 sub_len = 0;
00339
00340 ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after,
00341 X509_RFC5280_UTC_TIME_LEN ) );
00342
00343 ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before,
00344 X509_RFC5280_UTC_TIME_LEN ) );
00345
00346 len += sub_len;
00347 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) );
00348 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00349
00350
00351
00352
00353 ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->issuer ) );
00354
00355
00356
00357
00358 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, tmp_buf,
00359 sig_oid, strlen( sig_oid ), 0 ) );
00360
00361
00362
00363
00364 ASN1_CHK_ADD( len, asn1_write_mpi( &c, tmp_buf, &ctx->serial ) );
00365
00366
00367
00368
00369 sub_len = 0;
00370 ASN1_CHK_ADD( sub_len, asn1_write_int( &c, tmp_buf, ctx->version ) );
00371 len += sub_len;
00372 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) );
00373 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) );
00374
00375 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
00376 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00377
00378
00379
00380
00381 md( md_info_from_type( ctx->md_alg ), c, len, hash );
00382
00383 if( ( ret = pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len,
00384 f_rng, p_rng ) ) != 0 )
00385 {
00386 return( ret );
00387 }
00388
00389
00390
00391
00392 c2 = buf + size;
00393 ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf,
00394 sig_oid, sig_oid_len, sig, sig_len ) );
00395
00396 c2 -= len;
00397 memcpy( c2, c, len );
00398
00399 len += sig_and_oid_len;
00400 ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
00401 ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00402
00403 return( (int) len );
00404 }
00405
00406 #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n"
00407 #define PEM_END_CRT "-----END CERTIFICATE-----\n"
00408
00409 #if defined(POLARSSL_PEM_WRITE_C)
00410 int x509write_crt_pem( x509write_cert *crt, unsigned char *buf, size_t size,
00411 int (*f_rng)(void *, unsigned char *, size_t),
00412 void *p_rng )
00413 {
00414 int ret;
00415 unsigned char output_buf[4096];
00416 size_t olen = 0;
00417
00418 if( ( ret = x509write_crt_der( crt, output_buf, sizeof(output_buf),
00419 f_rng, p_rng ) ) < 0 )
00420 {
00421 return( ret );
00422 }
00423
00424 if( ( ret = pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT,
00425 output_buf + sizeof(output_buf) - ret,
00426 ret, buf, size, &olen ) ) != 0 )
00427 {
00428 return( ret );
00429 }
00430
00431 return( 0 );
00432 }
00433 #endif
00434
00435 #endif