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 #include "polarssl/config.h"
00027
00028 #if defined(POLARSSL_ASN1_WRITE_C)
00029
00030 #include "polarssl/asn1write.h"
00031
00032 #if defined(POLARSSL_MEMORY_C)
00033 #include "polarssl/memory.h"
00034 #else
00035 #include <stdlib.h>
00036 #define polarssl_malloc malloc
00037 #define polarssl_free free
00038 #endif
00039
00040 int asn1_write_len( unsigned char **p, unsigned char *start, size_t len )
00041 {
00042 if( len < 0x80 )
00043 {
00044 if( *p - start < 1 )
00045 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00046
00047 *--(*p) = (unsigned char) len;
00048 return( 1 );
00049 }
00050
00051 if( len <= 0xFF )
00052 {
00053 if( *p - start < 2 )
00054 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00055
00056 *--(*p) = (unsigned char) len;
00057 *--(*p) = 0x81;
00058 return( 2 );
00059 }
00060
00061 if( *p - start < 3 )
00062 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00063
00064
00065
00066 *--(*p) = len % 256;
00067 *--(*p) = ( len / 256 ) % 256;
00068 *--(*p) = 0x82;
00069
00070 return( 3 );
00071 }
00072
00073 int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
00074 {
00075 if( *p - start < 1 )
00076 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00077
00078 *--(*p) = tag;
00079
00080 return( 1 );
00081 }
00082
00083 int asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
00084 const unsigned char *buf, size_t size )
00085 {
00086 size_t len = 0;
00087
00088 if( *p - start < (int) size )
00089 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00090
00091 len = size;
00092 (*p) -= len;
00093 memcpy( *p, buf, len );
00094
00095 return( (int) len );
00096 }
00097
00098 #if defined(POLARSSL_BIGNUM_C)
00099 int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X )
00100 {
00101 int ret;
00102 size_t len = 0;
00103
00104
00105
00106 len = mpi_size( X );
00107
00108 if( *p - start < (int) len )
00109 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00110
00111 (*p) -= len;
00112 mpi_write_binary( X, *p, len );
00113
00114
00115
00116
00117 if ( X->s ==1 && **p & 0x80 )
00118 {
00119 if( *p - start < 1 )
00120 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00121
00122 *--(*p) = 0x00;
00123 len += 1;
00124 }
00125
00126 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00127 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
00128
00129 return( (int) len );
00130 }
00131 #endif
00132
00133 int asn1_write_null( unsigned char **p, unsigned char *start )
00134 {
00135 int ret;
00136 size_t len = 0;
00137
00138
00139
00140 ASN1_CHK_ADD( len, asn1_write_len( p, start, 0) );
00141 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_NULL ) );
00142
00143 return( (int) len );
00144 }
00145
00146 int asn1_write_oid( unsigned char **p, unsigned char *start,
00147 const char *oid, size_t oid_len )
00148 {
00149 int ret;
00150 size_t len = 0;
00151
00152 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
00153 (const unsigned char *) oid, oid_len ) );
00154 ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) );
00155 ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) );
00156
00157 return( (int) len );
00158 }
00159
00160 int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
00161 const char *oid, size_t oid_len,
00162 size_t par_len )
00163 {
00164 int ret;
00165 size_t len = 0;
00166
00167 if( par_len == 0 )
00168 ASN1_CHK_ADD( len, asn1_write_null( p, start ) );
00169 else
00170 len += par_len;
00171
00172 ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
00173
00174 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00175 ASN1_CHK_ADD( len, asn1_write_tag( p, start,
00176 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00177
00178 return( (int) len );
00179 }
00180
00181 int asn1_write_bool( unsigned char **p, unsigned char *start, int boolean )
00182 {
00183 int ret;
00184 size_t len = 0;
00185
00186 if( *p - start < 1 )
00187 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00188
00189 *--(*p) = (boolean) ? 1 : 0;
00190 len++;
00191
00192 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00193 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BOOLEAN ) );
00194
00195 return( (int) len );
00196 }
00197
00198 int asn1_write_int( unsigned char **p, unsigned char *start, int val )
00199 {
00200 int ret;
00201 size_t len = 0;
00202
00203
00204
00205
00206
00207 if( *p - start < 1 )
00208 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00209
00210 len += 1;
00211 *--(*p) = val;
00212
00213 if ( val > 0 && **p & 0x80 )
00214 {
00215 if( *p - start < 1 )
00216 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00217
00218 *--(*p) = 0x00;
00219 len += 1;
00220 }
00221
00222 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00223 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
00224
00225 return( (int) len );
00226 }
00227
00228 int asn1_write_printable_string( unsigned char **p, unsigned char *start,
00229 const char *text, size_t text_len )
00230 {
00231 int ret;
00232 size_t len = 0;
00233
00234 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
00235 (const unsigned char *) text, text_len ) );
00236
00237 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00238 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_PRINTABLE_STRING ) );
00239
00240 return( (int) len );
00241 }
00242
00243 int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
00244 const char *text, size_t text_len )
00245 {
00246 int ret;
00247 size_t len = 0;
00248
00249 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
00250 (const unsigned char *) text, text_len ) );
00251
00252 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00253 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) );
00254
00255 return( (int) len );
00256 }
00257
00258 int asn1_write_bitstring( unsigned char **p, unsigned char *start,
00259 const unsigned char *buf, size_t bits )
00260 {
00261 int ret;
00262 size_t len = 0, size;
00263
00264 size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 );
00265
00266
00267
00268 if( *p - start < (int) size + 1 )
00269 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00270
00271 len = size + 1;
00272 (*p) -= size;
00273 memcpy( *p, buf, size );
00274
00275
00276
00277 *--(*p) = (unsigned char) (size * 8 - bits);
00278
00279 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00280 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) );
00281
00282 return( (int) len );
00283 }
00284
00285 int asn1_write_octet_string( unsigned char **p, unsigned char *start,
00286 const unsigned char *buf, size_t size )
00287 {
00288 int ret;
00289 size_t len = 0;
00290
00291 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, buf, size ) );
00292
00293 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00294 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) );
00295
00296 return( (int) len );
00297 }
00298
00299 asn1_named_data *asn1_store_named_data( asn1_named_data **head,
00300 const char *oid, size_t oid_len,
00301 const unsigned char *val,
00302 size_t val_len )
00303 {
00304 asn1_named_data *cur;
00305
00306 if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
00307 {
00308
00309
00310 if( ( cur = polarssl_malloc( sizeof(asn1_named_data) ) ) == NULL )
00311 return( NULL );
00312
00313 memset( cur, 0, sizeof(asn1_named_data) );
00314
00315 cur->oid.len = oid_len;
00316 cur->oid.p = polarssl_malloc( oid_len );
00317 if( cur->oid.p == NULL )
00318 {
00319 polarssl_free( cur );
00320 return( NULL );
00321 }
00322
00323 cur->val.len = val_len;
00324 cur->val.p = polarssl_malloc( val_len );
00325 if( cur->val.p == NULL )
00326 {
00327 polarssl_free( cur->oid.p );
00328 polarssl_free( cur );
00329 return( NULL );
00330 }
00331
00332 memcpy( cur->oid.p, oid, oid_len );
00333
00334 cur->next = *head;
00335 *head = cur;
00336 }
00337 else if( cur->val.len < val_len )
00338 {
00339
00340
00341 polarssl_free( cur->val.p );
00342 cur->val.p = NULL;
00343
00344 cur->val.len = val_len;
00345 cur->val.p = polarssl_malloc( val_len );
00346 if( cur->val.p == NULL )
00347 {
00348 polarssl_free( cur->oid.p );
00349 polarssl_free( cur );
00350 return( NULL );
00351 }
00352 }
00353
00354 if( val != NULL )
00355 memcpy( cur->val.p, val, val_len );
00356
00357 return( cur );
00358 }
00359 #endif