@@ -43,10 +43,12 @@ int main( void )
43
43
#include "mbedtls/ctr_drbg.h"
44
44
#include "mbedtls/md.h"
45
45
#include "mbedtls/error.h"
46
+ #include "test/helpers.h"
46
47
47
48
#include <stdio.h>
48
49
#include <stdlib.h>
49
50
#include <string.h>
51
+ #include <errno.h>
50
52
51
53
#define SET_OID (x , oid ) \
52
54
do { x.len = MBEDTLS_OID_SIZE(oid); x.p = (unsigned char*)oid; } while( 0 )
@@ -75,6 +77,7 @@ int main( void )
75
77
#define DFL_NOT_BEFORE "20010101000000"
76
78
#define DFL_NOT_AFTER "20301231235959"
77
79
#define DFL_SERIAL "1"
80
+ #define DFL_SERIAL_HEX "1"
78
81
#define DFL_SELFSIGN 0
79
82
#define DFL_IS_CA 0
80
83
#define DFL_MAX_PATHLEN -1
@@ -110,6 +113,13 @@ int main( void )
110
113
" issuer_pwd=%%s default: (empty)\n" \
111
114
" output_file=%%s default: cert.crt\n" \
112
115
" serial=%%s default: 1\n" \
116
+ " In decimal format; it can be used as\n" \
117
+ " alternative to serial_hex, but it's\n" \
118
+ " limited in max length to\n" \
119
+ " unsigned long long int\n" \
120
+ " serial_hex=%%s default: 1\n" \
121
+ " In hex format; it can be used as\n" \
122
+ " alternative to serial\n" \
113
123
" not_before=%%s default: 20010101000000\n"\
114
124
" not_after=%%s default: 20301231235959\n"\
115
125
" is_ca=%%d default: 0 (disabled)\n" \
@@ -159,6 +169,12 @@ int main( void )
159
169
" format=pem|der default: pem\n" \
160
170
"\n"
161
171
172
+ typedef enum
173
+ {
174
+ SERIAL_FRMT_UNSPEC ,
175
+ SERIAL_FRMT_DEC ,
176
+ SERIAL_FRMT_HEX
177
+ } serial_format_t ;
162
178
163
179
/*
164
180
* global options
@@ -176,7 +192,8 @@ struct options
176
192
const char * issuer_name ; /* issuer name for certificate */
177
193
const char * not_before ; /* validity period not before */
178
194
const char * not_after ; /* validity period not after */
179
- const char * serial ; /* serial number string */
195
+ const char * serial ; /* serial number string (decimal) */
196
+ const char * serial_hex ; /* serial number string (hex) */
180
197
int selfsign ; /* selfsign the certificate */
181
198
int is_ca ; /* is a CA certificate */
182
199
int max_pathlen ; /* maximum CA path length */
@@ -235,39 +252,42 @@ int write_certificate( mbedtls_x509write_cert *crt, const char *output_file,
235
252
return ( 0 );
236
253
}
237
254
238
- /*
239
- * Convert the input "in_buff" string to a raw byte array "out_buff". The amount
240
- * of converted data is returned on "written_data".
241
- */
242
- static int parse_serial ( const char * in_buff , size_t in_buff_len ,
243
- unsigned char * out_buff , size_t out_buff_len ,
244
- size_t * written_data )
255
+ int parse_serial_decimal_format ( unsigned char * obuf , size_t obufmax ,
256
+ const char * ibuf , size_t * len )
245
257
{
246
- char c ;
258
+ unsigned long long int dec ;
259
+ unsigned int remaining_bytes = sizeof ( dec );
260
+ unsigned char * p = obuf ;
247
261
unsigned char val ;
248
- int i ;
262
+ char * end_ptr = NULL ;
249
263
250
- if ( out_buff_len < in_buff_len )
251
- return ( -1 );
264
+ errno = 0 ;
265
+ dec = strtoull ( ibuf , & end_ptr , 10 );
266
+
267
+ if ( ( errno != 0 ) || ( end_ptr == ibuf ) )
268
+ return -1 ;
252
269
253
- * written_data = 0 ;
270
+ * len = 0 ;
254
271
255
- for ( i = 0 ; i < ( int ) in_buff_len ; i ++ , ( * written_data ) ++ )
272
+ while ( remaining_bytes > 0 )
256
273
{
257
- c = in_buff [i ];
258
- if ( c >= 0x30 && c <= 0x39 )
259
- val = c - 0x30 ;
260
- else if ( c >= 0x41 && c <= 0x46 )
261
- val = c - 0x37 ;
262
- else if ( c >= 0x61 && c <= 0x66 )
263
- val = c - 0x57 ;
264
- else
265
- return ( -1 );
274
+ if ( obufmax < ( * len + 1 ) )
275
+ return -1 ;
276
+
277
+ val = ( dec >> ( ( remaining_bytes - 1 ) * 8 ) ) & 0xFF ;
266
278
267
- out_buff [i ] = val ;
279
+ /* Skip leading zeros */
280
+ if ( ( val ) != 0 )
281
+ {
282
+ * p = val ;
283
+ (* len )++ ;
284
+ p ++ ;
285
+ }
286
+
287
+ remaining_bytes -- ;
268
288
}
269
289
270
- return ( 0 ) ;
290
+ return 0 ;
271
291
}
272
292
273
293
int main ( int argc , char * argv [] )
@@ -287,6 +307,7 @@ int main( int argc, char *argv[] )
287
307
mbedtls_x509_csr csr ;
288
308
#endif
289
309
mbedtls_x509write_cert crt ;
310
+ serial_format_t serial_frmt = SERIAL_FRMT_UNSPEC ;
290
311
unsigned char serial [MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN ];
291
312
size_t serial_len ;
292
313
mbedtls_asn1_sequence * ext_key_usage ;
@@ -307,6 +328,7 @@ int main( int argc, char *argv[] )
307
328
#endif
308
329
mbedtls_x509_crt_init ( & issuer_crt );
309
330
memset ( buf , 0 , sizeof (buf ) );
331
+ memset ( serial , 0 , sizeof ( serial ) );
310
332
311
333
if ( argc == 0 )
312
334
{
@@ -327,6 +349,7 @@ int main( int argc, char *argv[] )
327
349
opt .not_before = DFL_NOT_BEFORE ;
328
350
opt .not_after = DFL_NOT_AFTER ;
329
351
opt .serial = DFL_SERIAL ;
352
+ opt .serial_hex = DFL_SERIAL_HEX ;
330
353
opt .selfsign = DFL_SELFSIGN ;
331
354
opt .is_ca = DFL_IS_CA ;
332
355
opt .max_pathlen = DFL_MAX_PATHLEN ;
@@ -380,8 +403,24 @@ int main( int argc, char *argv[] )
380
403
}
381
404
else if ( strcmp ( p , "serial" ) == 0 )
382
405
{
406
+ if ( serial_frmt != SERIAL_FRMT_UNSPEC )
407
+ {
408
+ mbedtls_printf ( "Invalid attempt to set the serial more than once\n" );
409
+ goto usage ;
410
+ }
411
+ serial_frmt = SERIAL_FRMT_DEC ;
383
412
opt .serial = q ;
384
413
}
414
+ else if ( strcmp ( p , "serial_hex" ) == 0 )
415
+ {
416
+ if ( serial_frmt != SERIAL_FRMT_UNSPEC )
417
+ {
418
+ mbedtls_printf ( "Invalid attempt to set the serial more than once\n" );
419
+ goto usage ;
420
+ }
421
+ serial_frmt = SERIAL_FRMT_HEX ;
422
+ opt .serial_hex = q ;
423
+ }
385
424
else if ( strcmp ( p , "authority_identifier" ) == 0 )
386
425
{
387
426
opt .authority_identifier = atoi ( q );
@@ -594,6 +633,23 @@ int main( int argc, char *argv[] )
594
633
mbedtls_printf ( " . Reading serial number..." );
595
634
fflush ( stdout );
596
635
636
+ if ( serial_frmt == SERIAL_FRMT_HEX )
637
+ {
638
+ ret = mbedtls_test_unhexify ( serial , sizeof ( serial ),
639
+ opt .serial_hex , & serial_len );
640
+ }
641
+ else // SERIAL_FRMT_DEC || SERIAL_FRMT_UNSPEC
642
+ {
643
+ ret = parse_serial_decimal_format ( serial , sizeof ( serial ),
644
+ opt .serial , & serial_len );
645
+ }
646
+
647
+ if ( ret != 0 )
648
+ {
649
+ mbedtls_printf ( " failed\n ! Unable to parse serial\n" );
650
+ goto exit ;
651
+ }
652
+
597
653
mbedtls_printf ( " ok\n" );
598
654
599
655
// Parse issuer certificate if present
@@ -748,12 +804,6 @@ int main( int argc, char *argv[] )
748
804
mbedtls_x509write_crt_set_version ( & crt , opt .version );
749
805
mbedtls_x509write_crt_set_md_alg ( & crt , opt .md );
750
806
751
- if ( parse_serial ( opt .serial , strlen ( opt .serial ),
752
- serial , sizeof ( serial ), & serial_len ) < 0 )
753
- {
754
- mbedtls_printf ( " failed\n ! Unable to parse serial\n\n" );
755
- goto exit ;
756
- }
757
807
ret = mbedtls_x509write_crt_set_serial_new ( & crt , serial , serial_len );
758
808
if ( ret != 0 )
759
809
{
0 commit comments