From b052250a1b378a256901cb51a1be1a96cd5be772 Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Wed, 10 Aug 2016 10:12:00 +0200 Subject: [PATCH] make certificate serial number random by default --- tool/cmdline.ggo | 2 +- tool/yubico-piv-tool.c | 31 ++++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/tool/cmdline.ggo b/tool/cmdline.ggo index fa3e6dc..e7f18fc 100644 --- a/tool/cmdline.ggo +++ b/tool/cmdline.ggo @@ -57,7 +57,7 @@ option "subject" S "The subject to use for certificate request" string optional text " The subject must be written as: /CN=host.example.com/OU=test/O=example.com/\n" -option "serial" - "Serial number of the self-signed certificate" int optional default="1" +option "serial" - "Serial number of the self-signed certificate" int optional option "valid-days" - "Time (in days) until the self-signed certificate expires" int optional default="365" option "pin" P "Pin/puk code for verification" string optional option "new-pin" N "New pin/puk code for changing" string optional dependon="pin" diff --git a/tool/yubico-piv-tool.c b/tool/yubico-piv-tool.c index 55a03e7..56b72e9 100644 --- a/tool/yubico-piv-tool.c +++ b/tool/yubico-piv-tool.c @@ -781,7 +781,7 @@ request_out: static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_format, const char *input_file_name, const char *slot, char *subject, enum enum_hash hash, - int serial, int validDays, const char *output_file_name) { + const int *serial, int validDays, const char *output_file_name) { FILE *input_file = NULL; FILE *output_file = NULL; bool ret = false; @@ -799,6 +799,8 @@ static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_fo const unsigned char *oid; int nid; unsigned int md_len; + ASN1_INTEGER *sno = ASN1_INTEGER_new(); + BIGNUM *ser = NULL; sscanf(slot, "%2x", &key); @@ -847,7 +849,24 @@ static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_fo fprintf(stderr, "Failed to set the certificate public key.\n"); goto selfsign_out; } - if(!ASN1_INTEGER_set(X509_get_serialNumber(x509), serial)) { + if(serial) { + ASN1_INTEGER_set(sno, *serial); + } else { + ser = BN_new(); + if(!ser) { + fprintf(stderr, "Failed to allocate BIGNUM.\n"); + goto selfsign_out; + } + if(!BN_pseudo_rand(ser, 64, 0, 0)) { + fprintf(stderr, "Failed to generate randomness.\n"); + goto selfsign_out; + } + if(!BN_to_ASN1_INTEGER(ser, sno)) { + fprintf(stderr, "Failed to set random serial.\n"); + goto selfsign_out; + } + } + if(!X509_set_serialNumber(x509, sno)) { fprintf(stderr, "Failed to set certificate serial.\n"); goto selfsign_out; } @@ -930,6 +949,12 @@ selfsign_out: if(name) { X509_NAME_free(name); } + if(ser) { + BN_free(ser); + } + if(sno) { + ASN1_INTEGER_free(sno); + } return ret; } @@ -2085,7 +2110,7 @@ int main(int argc, char *argv[]) { case action_arg_selfsignMINUS_certificate: if(selfsign_certificate(state, args_info.key_format_arg, args_info.input_arg, args_info.slot_orig, args_info.subject_arg, args_info.hash_arg, - args_info.serial_arg, args_info.valid_days_arg, + args_info.serial_given ? &args_info.serial_arg : NULL, args_info.valid_days_arg, args_info.output_arg) == false) { ret = EXIT_FAILURE; } else {