diff options
author | Jonathan M. Wilbur <jonathan@wilbur.space> | 2024-09-12 12:52:20 +0200 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2024-09-16 22:56:02 +0200 |
commit | 935f6e63c96b44a03e12a7272b01c23956f3d4f3 (patch) | |
tree | 49a4cdd32d521618c5f0954b68053cfaa678c070 | |
parent | test: the roleSpecCertIdentifier X.509v3 extension (diff) | |
download | openssl-935f6e63c96b44a03e12a7272b01c23956f3d4f3.tar.xz openssl-935f6e63c96b44a03e12a7272b01c23956f3d4f3.zip |
feat: add ossl_serial_number_print
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25428)
-rw-r--r-- | crypto/x509/t_x509.c | 46 | ||||
-rw-r--r-- | crypto/x509/v3_rolespec.c | 2 | ||||
-rw-r--r-- | doc/internal/man3/ossl_serial_number_print.pod | 38 | ||||
-rw-r--r-- | include/crypto/x509.h | 2 | ||||
-rw-r--r-- | test/recipes/25-test_x509.t | 2 |
5 files changed, 86 insertions, 4 deletions
diff --git a/crypto/x509/t_x509.c b/crypto/x509/t_x509.c index 192998d453..4befbe25da 100644 --- a/crypto/x509/t_x509.c +++ b/crypto/x509/t_x509.c @@ -54,11 +54,10 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag) { long l; - int ret = 0, i; + int ret = 0; char mlch = ' '; int nmindent = 0, printok = 0; EVP_PKEY *pkey = NULL; - const char *neg; if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { mlch = '\n'; @@ -531,3 +530,46 @@ int X509_STORE_CTX_print_verify_cb(int ok, X509_STORE_CTX *ctx) return ok; } + +/* + * Prints serial numbers in decimal and hexadecimal. The indent argument is only + * used if the serial number is too large to fit in a long int. + */ +int ossl_serial_number_print(BIO *out, const ASN1_INTEGER *bs, int indent) +{ + int i; + long l; + unsigned long ul; + const char *neg; + + if (bs->length <= (int)sizeof(long)) { + ERR_set_mark(); + l = ASN1_INTEGER_get(bs); + ERR_pop_to_mark(); + } else { + l = -1; + } + if (l != -1) { /* Reading a long int succeeded: print decimal and hex. */ + if (bs->type == V_ASN1_NEG_INTEGER) { + ul = 0 - (unsigned long)l; + neg = "-"; + } else { + ul = l; + neg = ""; + } + if (BIO_printf(out, " %s%lu (%s0x%lx)", neg, ul, neg, ul) <= 0) + return -1; + } else { /* Reading a long int failed: just print hex. */ + neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : ""; + if (BIO_printf(out, "\n%*s%s", indent, "", neg) <= 0) + return -1; + + for (i = 0; i < bs->length - 1; i++) { + if (BIO_printf(out, "%02x%c", bs->data[i], ':') <= 0) + return -1; + } + if (BIO_printf(out, "%02x", bs->data[i]) <= 0) + return -1; + } + return 0; +} diff --git a/crypto/x509/v3_rolespec.c b/crypto/x509/v3_rolespec.c index c371e145d7..57111b1f0f 100644 --- a/crypto/x509/v3_rolespec.c +++ b/crypto/x509/v3_rolespec.c @@ -45,7 +45,7 @@ static int i2r_OSSL_ROLE_SPEC_CERT_ID(X509V3_EXT_METHOD *method, if (rscid->roleCertSerialNumber != NULL) { if (BIO_puts(out, "\n") <= 0) return 0; - if (BIO_printf(out, "%*sRole Certificate Serial Number: ", indent, "") <= 0) + if (BIO_printf(out, "%*sRole Certificate Serial Number:", indent, "") <= 0) return 0; if (ossl_serial_number_print(out, rscid->roleCertSerialNumber, indent) != 0) return 0; diff --git a/doc/internal/man3/ossl_serial_number_print.pod b/doc/internal/man3/ossl_serial_number_print.pod new file mode 100644 index 0000000000..9ea4802350 --- /dev/null +++ b/doc/internal/man3/ossl_serial_number_print.pod @@ -0,0 +1,38 @@ +=pod + +=head1 NAME + +ossl_serial_number_print +- Print a CertificateSerialNumber + +=head1 SYNOPSIS + + #include <crypto/x509.h> + + int ossl_serial_number_print(BIO *out, const ASN1_INTEGER *bs, int indent); + +=head1 DESCRIPTION + +This function writes a certificate serial number I<bs> to BIO I<out> in decimal if the serial +number can be read into a long int, as well as hexadecimal. It notifies the +user of negative serial numbers, and handles wrapping of huge serial numbers. +The output is written to a newline and indented by I<indent> spaces if the +serial number cannot be read into a long int. + +If the serial number fits into a long int, it is printed on the same line as +whatever precedes it, after a single SPACE character. + +=head1 RETURN VALUES + +This function returns 0 on success and -1 on failure. + +=head1 COPYRIGHT + +Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L<https://www.openssl.org/source/license.html>. + +=cut diff --git a/include/crypto/x509.h b/include/crypto/x509.h index 338e58b491..332108d1bb 100644 --- a/include/crypto/x509.h +++ b/include/crypto/x509.h @@ -394,4 +394,6 @@ int ossl_print_attribute_value(BIO *out, const ASN1_TYPE *av, int indent); +int ossl_serial_number_print(BIO *out, const ASN1_INTEGER *bs, int indent); + #endif /* OSSL_CRYPTO_X509_H */ diff --git a/test/recipes/25-test_x509.t b/test/recipes/25-test_x509.t index 1d458d3362..39440498ef 100644 --- a/test/recipes/25-test_x509.t +++ b/test/recipes/25-test_x509.t @@ -323,7 +323,7 @@ cert_contains($role_spec_cert, "Role Certificate Issuer: DirName:CN", 1, 'X.509 Role Spec Certificate Identifier'); cert_contains($role_spec_cert, - "Role Certificate Serial Number: 0x02040608", + "Role Certificate Serial Number: 33818120 \\(0x2040608\\)", 1, 'X.509 Role Spec Certificate Identifier'); cert_contains($role_spec_cert, "DNS:wildboarsoftware.com", |