• Martin Sucha's avatar
    certtool: use larger serial and CRL numbers · ff3c40d9
    Martin Sucha authored
    Serial/CRL numbers can be up to 20 octets in length
    as per RFC 5280, so it should be possible to use
    such numbers as input to certtool. certtool
    only allowed to specify 63-bit numbers in
    template file or interactively (even though
    it generated larger numbers in batch mode
    by default).
    
    This patch allows large numbers to be specified
    as a hexadecimal string. Parsing of decimal numbers
    larger than native integers would require adding
    dependency on libgmp directly to certtool or
    extending the API exposed by GnuTLS library with parsing
    functions. Since most tools (including GnuTLS) display
    serial numbers in hexadecimal, it is not worth the
    trouble to support large decimal numbers.
    
    Default values are unified between batch mode and
    interactive input and their size is extended.
    
    CA/Browser forum recommends CAs to include at least
    64 bits of random data in the certificate serial
    numbers in Baseline Requirements[1] section 7.1, but
    gnutls adds only 32 bits. Some other
    implementations generate default serial numbers
    with more entropy as well, here is the current state
    as of May 2018:
    
    +----------------+-------------------------------+
    | Implementation | Random bits in default serial |
    +----------------+-------------------------------+
    | OpenSSL [2]    | 159                           |
    | CFSSL [3]      | 159                           |
    | wolfSSL [4]    | 128                           |
    | GnuTLS         | 32                            |
    | Mbed TLS [5]   | 0 (defaults to 1)             |
    +----------------+-------------------------------+
    
    The 20 octet field size can fit numbers up to 159 bits
    since the most significant bit must be zero as numbers
    in DER encoding are in two's complement and the serial
    and CRL numbers must be positive.
    
    Default serial numbers are extended to full 159 bits
    allowed by the field size and are completely random,
    which matches other implementations.
    
    CRL numbers have the same size requirements, but also
    need to be monotonic (RFC 5280, section 5.2.3). That's
    why timestamp is used in them. The timestamp portion
    is extended from 31 bits to 39 bits as 31 bits will
    overflow in year 2038. The rest of the available space
    up to 159 bits allowed in the 20 octet limit is filled
    with random bits.
    
    Since the new CRL numbers are larger, the requirement for them
    to be monotonically increasing is preserved when upgrading to a
    newer version. This does not hold the other way around though,
    so after using a newer version of certtool to generate a CRL
    with default number and publishing it, it's not possible
    to use older version anymore to generate subsequent CRLs.
    Unfortunately, there is no easy workaround for users of older
    certtool, since it is not possible to specify CRL numbers
    greater than 63 bits manually prior to this change.
    Users intending to downgrade to older version later are advised
    to specify the CRL numbers in new version of certtool
    manually with values they are smaller than what would get
    generated by default in the old version.
    
    grep does not recognize CRLF line endings generated
    in tests using MinGW, so we need to convert those to
    LF endings for $ in the regex to match test output
    correctly.
    
    datefudge 1.21 that is present in Fedora 26
    image trims the timestamp to 32 bits. That bug was
    fixed in datefudge 1.22 available in the Debian image,
    so we check if datefudge behaves correctly
    and skip the test that uses more than 32 bits if
    datefudge is broken.
    
    [1] https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-1.4.2.pdf
    [2] https://github.com/openssl/openssl/blob/6ebb49f3f9c9333611192561979bb799fa1eb76d/apps/apps.c#L1513
    [3] https://github.com/cloudflare/cfssl/blob/5d63dbd981b5c408effbb58c442d54761ff94fbd/signer/local/local.go#L295
    [4] https://github.com/wolfSSL/wolfssl/blob/d60b16c5b8c19cc61db4a5c3f5e085a7a158cd28/wolfcrypt/src/asn.c#L9791
    [5] https://github.com/ARMmbed/mbedtls/blob/84a1107818aaddfd2abe4c5a3478cf84ab2e26b4/programs/x509/cert_write.c#L81Signed-off-by: Martin Sucha's avatarMartin Sucha <anty.sk+git@gmail.com>
    ff3c40d9
certtool.c 89.9 KB