@@ -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,11 @@ int main(void)
159
169
" format=pem|der default: pem\n" \
160
170
"\n"
161
171
172
+ typedef enum {
173
+ SERIAL_FRMT_UNSPEC ,
174
+ SERIAL_FRMT_DEC ,
175
+ SERIAL_FRMT_HEX
176
+ } serial_format_t ;
162
177
163
178
/*
164
179
* global options
@@ -175,7 +190,8 @@ struct options {
175
190
const char * issuer_name ; /* issuer name for certificate */
176
191
const char * not_before ; /* validity period not before */
177
192
const char * not_after ; /* validity period not after */
178
- const char * serial ; /* serial number string */
193
+ const char * serial ; /* serial number string (decimal) */
194
+ const char * serial_hex ; /* serial number string (hex) */
179
195
int selfsign ; /* selfsign the certificate */
180
196
int is_ca ; /* is a CA certificate */
181
197
int max_pathlen ; /* maximum CA path length */
@@ -235,6 +251,44 @@ int write_certificate(mbedtls_x509write_cert *crt, const char *output_file,
235
251
return 0 ;
236
252
}
237
253
254
+ int parse_serial_decimal_format (unsigned char * obuf , size_t obufmax ,
255
+ const char * ibuf , size_t * len )
256
+ {
257
+ unsigned long long int dec ;
258
+ unsigned int remaining_bytes = sizeof (dec );
259
+ unsigned char * p = obuf ;
260
+ unsigned char val ;
261
+ char * end_ptr = NULL ;
262
+
263
+ errno = 0 ;
264
+ dec = strtoull (ibuf , & end_ptr , 10 );
265
+
266
+ if ((errno != 0 ) || (end_ptr == ibuf )) {
267
+ return -1 ;
268
+ }
269
+
270
+ * len = 0 ;
271
+
272
+ while (remaining_bytes > 0 ) {
273
+ if (obufmax < (* len + 1 )) {
274
+ return -1 ;
275
+ }
276
+
277
+ val = (dec >> ((remaining_bytes - 1 ) * 8 )) & 0xFF ;
278
+
279
+ /* Skip leading zeros */
280
+ if ((val != 0 ) || (* len != 0 )) {
281
+ * p = val ;
282
+ (* len )++ ;
283
+ p ++ ;
284
+ }
285
+
286
+ remaining_bytes -- ;
287
+ }
288
+
289
+ return 0 ;
290
+ }
291
+
238
292
int main (int argc , char * argv [])
239
293
{
240
294
int ret = 1 ;
@@ -252,7 +306,9 @@ int main(int argc, char *argv[])
252
306
mbedtls_x509_csr csr ;
253
307
#endif
254
308
mbedtls_x509write_cert crt ;
255
- mbedtls_mpi serial ;
309
+ serial_format_t serial_frmt = SERIAL_FRMT_UNSPEC ;
310
+ unsigned char serial [MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN ];
311
+ size_t serial_len ;
256
312
mbedtls_asn1_sequence * ext_key_usage ;
257
313
mbedtls_entropy_context entropy ;
258
314
mbedtls_ctr_drbg_context ctr_drbg ;
@@ -264,14 +320,14 @@ int main(int argc, char *argv[])
264
320
mbedtls_x509write_crt_init (& crt );
265
321
mbedtls_pk_init (& loaded_issuer_key );
266
322
mbedtls_pk_init (& loaded_subject_key );
267
- mbedtls_mpi_init (& serial );
268
323
mbedtls_ctr_drbg_init (& ctr_drbg );
269
324
mbedtls_entropy_init (& entropy );
270
325
#if defined(MBEDTLS_X509_CSR_PARSE_C )
271
326
mbedtls_x509_csr_init (& csr );
272
327
#endif
273
328
mbedtls_x509_crt_init (& issuer_crt );
274
329
memset (buf , 0 , sizeof (buf ));
330
+ memset (serial , 0 , sizeof (serial ));
275
331
276
332
if (argc == 0 ) {
277
333
usage :
@@ -291,6 +347,7 @@ int main(int argc, char *argv[])
291
347
opt .not_before = DFL_NOT_BEFORE ;
292
348
opt .not_after = DFL_NOT_AFTER ;
293
349
opt .serial = DFL_SERIAL ;
350
+ opt .serial_hex = DFL_SERIAL_HEX ;
294
351
opt .selfsign = DFL_SELFSIGN ;
295
352
opt .is_ca = DFL_IS_CA ;
296
353
opt .max_pathlen = DFL_MAX_PATHLEN ;
@@ -335,7 +392,19 @@ int main(int argc, char *argv[])
335
392
} else if (strcmp (p , "not_after" ) == 0 ) {
336
393
opt .not_after = q ;
337
394
} else if (strcmp (p , "serial" ) == 0 ) {
395
+ if (serial_frmt != SERIAL_FRMT_UNSPEC ) {
396
+ mbedtls_printf ("Invalid attempt to set the serial more than once\n" );
397
+ goto usage ;
398
+ }
399
+ serial_frmt = SERIAL_FRMT_DEC ;
338
400
opt .serial = q ;
401
+ } else if (strcmp (p , "serial_hex" ) == 0 ) {
402
+ if (serial_frmt != SERIAL_FRMT_UNSPEC ) {
403
+ mbedtls_printf ("Invalid attempt to set the serial more than once\n" );
404
+ goto usage ;
405
+ }
406
+ serial_frmt = SERIAL_FRMT_HEX ;
407
+ opt .serial_hex = q ;
339
408
} else if (strcmp (p , "authority_identifier" ) == 0 ) {
340
409
opt .authority_identifier = atoi (q );
341
410
if (opt .authority_identifier != 0 &&
@@ -514,10 +583,16 @@ int main(int argc, char *argv[])
514
583
mbedtls_printf (" . Reading serial number..." );
515
584
fflush (stdout );
516
585
517
- if ((ret = mbedtls_mpi_read_string (& serial , 10 , opt .serial )) != 0 ) {
518
- mbedtls_strerror (ret , buf , sizeof (buf ));
519
- mbedtls_printf (" failed\n ! mbedtls_mpi_read_string "
520
- "returned -0x%04x - %s\n\n" , (unsigned int ) - ret , buf );
586
+ if (serial_frmt == SERIAL_FRMT_HEX ) {
587
+ ret = mbedtls_test_unhexify (serial , sizeof (serial ),
588
+ opt .serial_hex , & serial_len );
589
+ } else { // SERIAL_FRMT_DEC || SERIAL_FRMT_UNSPEC
590
+ ret = parse_serial_decimal_format (serial , sizeof (serial ),
591
+ opt .serial , & serial_len );
592
+ }
593
+
594
+ if (ret != 0 ) {
595
+ mbedtls_printf (" failed\n ! Unable to parse serial\n" );
521
596
goto exit ;
522
597
}
523
598
@@ -661,10 +736,10 @@ int main(int argc, char *argv[])
661
736
mbedtls_x509write_crt_set_version (& crt , opt .version );
662
737
mbedtls_x509write_crt_set_md_alg (& crt , opt .md );
663
738
664
- ret = mbedtls_x509write_crt_set_serial (& crt , & serial );
739
+ ret = mbedtls_x509write_crt_set_serial_raw (& crt , serial , serial_len );
665
740
if (ret != 0 ) {
666
741
mbedtls_strerror (ret , buf , sizeof (buf ));
667
- mbedtls_printf (" failed\n ! mbedtls_x509write_crt_set_serial "
742
+ mbedtls_printf (" failed\n ! mbedtls_x509write_crt_set_serial_raw "
668
743
"returned -0x%04x - %s\n\n" , (unsigned int ) - ret , buf );
669
744
goto exit ;
670
745
}
@@ -807,7 +882,6 @@ int main(int argc, char *argv[])
807
882
mbedtls_x509write_crt_free (& crt );
808
883
mbedtls_pk_free (& loaded_subject_key );
809
884
mbedtls_pk_free (& loaded_issuer_key );
810
- mbedtls_mpi_free (& serial );
811
885
mbedtls_ctr_drbg_free (& ctr_drbg );
812
886
mbedtls_entropy_free (& entropy );
813
887
0 commit comments