Download raw body.
rpki-client: simplify x509_get_ski()
On Wed, Feb 14, 2024 at 08:38:32AM +0100, Theo Buehler wrote:
> X509_pubkey_digest() is the blessed API to compute the SKI. This saves
> a couple of dances and some consonant soup variable names.
>
> Index: x509.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/x509.c,v
> diff -u -p -r1.78 x509.c
> --- x509.c 13 Feb 2024 20:37:15 -0000 1.78
> +++ x509.c 14 Feb 2024 07:28:45 -0000
> @@ -191,7 +191,7 @@ out:
> }
>
> /*
> - * Parse X509v3 subject key identifier (SKI), RFC 6487 section 4.8.2:
> + * Validate the X509v3 subject key identifier (SKI), RFC 6487 section 4.8.2:
> * "The SKI is a SHA-1 hash of the value of the DER-encoded ASN.1 BIT STRING of
> * the Subject Public Key, as described in Section 4.2.1.2 of RFC 5280."
> * Returns the SKI formatted as hex string, or NULL if it couldn't be parsed.
> @@ -199,11 +199,9 @@ out:
> int
> x509_get_ski(X509 *x, const char *fn, char **ski)
> {
> - const unsigned char *d, *spk;
> ASN1_OCTET_STRING *os;
> - X509_PUBKEY *pubkey;
> - unsigned char spkd[SHA_DIGEST_LENGTH];
> - int crit, dsz, spkz, rc = 0;
> + unsigned char md[SHA_DIGEST_LENGTH];
> + int crit, rc = 0;
>
> *ski = NULL;
> os = X509_get_ext_d2i(x, NID_subject_key_identifier, &crit, NULL);
> @@ -221,36 +219,24 @@ x509_get_ski(X509 *x, const char *fn, ch
> goto out;
> }
>
> - d = os->data;
> - dsz = os->length;
> -
> - if (dsz != SHA_DIGEST_LENGTH) {
> - warnx("%s: RFC 6487 section 4.8.2: SKI: "
> - "want %d bytes SHA1 hash, have %d bytes",
> - fn, SHA_DIGEST_LENGTH, dsz);
> - goto out;
> - }
> -
> - if ((pubkey = X509_get_X509_PUBKEY(x)) == NULL) {
> - warnx("%s: X509_get_X509_PUBKEY", fn);
> - goto out;
> - }
> - if (!X509_PUBKEY_get0_param(NULL, &spk, &spkz, NULL, pubkey)) {
> - warnx("%s: X509_PUBKEY_get0_param", fn);
> + if (!X509_pubkey_digest(x, EVP_sha1(), md, NULL)) {
> + warnx("%s: X509_pubkey_digest", fn);
> goto out;
> }
>
> - if (!EVP_Digest(spk, spkz, spkd, NULL, EVP_sha1(), NULL)) {
> - warnx("%s: EVP_Digest failed", fn);
> + if (os->length != SHA_DIGEST_LENGTH) {
> + warnx("%s: RFC 6487 section 4.8.2: SKI: "
> + "want %d bytes SHA1 hash, have %d bytes",
> + fn, SHA_DIGEST_LENGTH, os->length);
> goto out;
> }
>
> - if (memcmp(spkd, d, dsz) != 0) {
> + if (memcmp(os->data, md, sizeof(md)) != 0) {
> warnx("%s: SKI does not match SHA1 hash of SPK", fn);
> goto out;
> }
>
> - *ski = hex_encode(d, dsz);
> + *ski = hex_encode(md, sizeof(md));
> rc = 1;
> out:
> ASN1_OCTET_STRING_free(os);
>
This is indeed much nicer. Should md use EVP_MAX_MD_SIZE? But then I
guess the code needs to pass a len param to X509_pubkey_digest() so
that the memcmp() can use it. Also why did you move the
if (os->length != SHA_DIGEST_LENGTH) {
check after X509_pubkey_digest()? It is a cheap check that is currently
done before.
--
:wq Claudio
rpki-client: simplify x509_get_ski()