From: Alberto Leiva Popper Date: Tue, 14 Jul 2026 19:27:00 +0000 (-0600) Subject: Improve OpenSSL 4 glue code X-Git-Tag: 1.7.0.experimental~3^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e430f40992c90b448a65e5d35ecfa9ecb6134c93;p=thirdparty%2FFORT-validator.git Improve OpenSSL 4 glue code crypto/asn1.h is internal; I'm not supposed to `#include` it. Also fixes some inoffensive warnings. --- diff --git a/src/extension.c b/src/extension.c index e553763b..4cb98b20 100644 --- a/src/extension.c +++ b/src/extension.c @@ -1,8 +1,5 @@ #include "extension.h" -#if OPENSSL_VERSION_MAJOR >= 4 -#include -#endif #include #include #include @@ -123,44 +120,43 @@ static json_t * ku2json(void const *ext) { ASN1_BIT_STRING const *ku = ext; - unsigned char data[2]; + int ku_len; json_t *parent; json_t *child; - if (ku->length < 1 || 2 < ku->length) + ku_len = ASN1_STRING_length(ku); + if (ku_len != 1 || ku_len != 2) return NULL; - memset(data, 0, sizeof(data)); - memcpy(data, ku->data, ku->length); parent = json_obj_new(); if (parent == NULL) return NULL; - child = json_boolean(data[0] & 0x80u); + child = json_boolean(ASN1_BIT_STRING_get_bit(ku, 0)); if (json_object_add(parent, "digitalSignature", child)) goto fail; - child = json_boolean(data[0] & 0x40u); + child = json_boolean(ASN1_BIT_STRING_get_bit(ku, 1)); if (json_object_add(parent, "contentCommitment", child)) goto fail; - child = json_boolean(data[0] & 0x20u); + child = json_boolean(ASN1_BIT_STRING_get_bit(ku, 2)); if (json_object_add(parent, "keyEncipherment", child)) goto fail; - child = json_boolean(data[0] & 0x10u); + child = json_boolean(ASN1_BIT_STRING_get_bit(ku, 3)); if (json_object_add(parent, "dataEncipherment", child)) goto fail; - child = json_boolean(data[0] & 0x08u); + child = json_boolean(ASN1_BIT_STRING_get_bit(ku, 4)); if (json_object_add(parent, "keyAgreement", child)) goto fail; - child = json_boolean(data[0] & 0x04u); + child = json_boolean(ASN1_BIT_STRING_get_bit(ku, 5)); if (json_object_add(parent, "keyCertSign", child)) goto fail; - child = json_boolean(data[0] & 0x02u); + child = json_boolean(ASN1_BIT_STRING_get_bit(ku, 6)); if (json_object_add(parent, "cRLSign", child)) goto fail; - child = json_boolean(data[0] & 0x01u); + child = json_boolean(ASN1_BIT_STRING_get_bit(ku, 7)); if (json_object_add(parent, "encipherOnly", child)) goto fail; - child = json_boolean(data[1] & 0x80u); + child = json_boolean(ASN1_BIT_STRING_get_bit(ku, 8)); if (json_object_add(parent, "decipherOnly", child)) goto fail; @@ -453,6 +449,8 @@ static const struct extension_metadata CP = { static json_t * p2json(ASN1_BIT_STRING const *ap, int af) { + size_t ap_len; + int ap_unused_bits; unsigned char bin[16]; char str[INET6_ADDRSTRLEN]; unsigned int length; @@ -462,16 +460,33 @@ p2json(ASN1_BIT_STRING const *ap, int af) if (ap == NULL) return json_null(); + /* ASN1_BIT_STRING_get_length() thinks length zero is an error... */ + if (ASN1_STRING_length(ap) == 0) { + str[0] = 0; + length = 0; + goto end; + } + +#if OPENSSL_VERSION_MAJOR >= 4 + if (ASN1_BIT_STRING_get_length(ap, &ap_len, &ap_unused_bits) != 1) + return json_null(); +#else + ap_len = ap->length; + ap_unused_bits = (ap->flags & ASN1_STRING_FLAG_BITS_LEFT) + ? (ap->flags & 0x07) + : 0; +#endif + if (ap_len > 16) + return json_null(); + memset(bin, 0, sizeof(bin)); - memcpy(bin, ap->data, ap->length); + memcpy(bin, ASN1_STRING_get0_data(ap), ap_len); if (inet_ntop(af, bin, str, INET6_ADDRSTRLEN) == NULL) return NULL; - length = 8 * ap->length; - if (ap->flags & ASN1_STRING_FLAG_BITS_LEFT) - length -= ap->flags & 7; + length = 8 * ap_len - ap_unused_bits; - written = snprintf(full, INET6_ADDRSTRLEN + 4, "%s/%u", str, length); +end: written = snprintf(full, INET6_ADDRSTRLEN + 4, "%s/%u", str, length); return json_strn_new(full, written); } @@ -538,7 +553,8 @@ iaf2json(IPAddressFamily const *iaf) { json_t *parent; json_t *child; - ASN1_OCTET_STRING *af; + unsigned char const *af_data; + int af_len; char const *family; int afid; @@ -549,14 +565,16 @@ iaf2json(IPAddressFamily const *iaf) if (parent == NULL) return NULL; - af = iaf->addressFamily; - if (af->length != 2) + af_data = ASN1_STRING_get0_data(iaf->addressFamily); + af_len = ASN1_STRING_length(iaf->addressFamily); + + if (af_len != 2) goto fail; - if (af->data[0] == 0 && af->data[1] == 1) { + if (af_data[0] == 0 && af_data[1] == 1) { family = "IPv4"; afid = AF_INET; - } else if (af->data[0] == 0 && af->data[1] == 2) { + } else if (af_data[0] == 0 && af_data[1] == 2) { family = "IPv6"; afid = AF_INET6; } else { @@ -938,6 +956,8 @@ validate_public_key_hash(X509 *cert, ASN1_OCTET_STRING *hash) X509_PUBKEY const *pubkey; const unsigned char *spk; int spk_len; + unsigned char const *hash_data; + int hash_len; int ok; int error; @@ -981,17 +1001,20 @@ validate_public_key_hash(X509 *cert, ASN1_OCTET_STRING *hash) if (!ok) return val_crypto_err("X509_PUBKEY_get0_param() returned %d", ok); + hash_data = ASN1_STRING_get0_data(hash); + hash_len = ASN1_STRING_length(hash); + /* Hash the SPK, compare SPK hash with the SKI */ - if (hash->length < 0 || SIZE_MAX < hash->length) { + if (hash_len < 0 || SIZE_MAX < hash_len) { return pr_val_err("%s length (%d) is out of bounds. (0-%zu)", - ext_ski()->name, hash->length, SIZE_MAX); + ext_ski()->name, hash_len, SIZE_MAX); } if (spk_len < 0 || SIZE_MAX < spk_len) { return pr_val_err("Subject Public Key length (%d) is out of bounds. (0-%zu)", spk_len, SIZE_MAX); } - error = hash_validate("sha1", hash->data, hash->length, spk, spk_len); + error = hash_validate("sha1", hash_data, hash_len, spk, spk_len); if (error) { pr_val_err("The Subject Public Key's hash does not match the %s.", ext_ski()->name); diff --git a/src/libcrypto_util.c b/src/libcrypto_util.c index 5ef9c51e..7f95b599 100644 --- a/src/libcrypto_util.c +++ b/src/libcrypto_util.c @@ -1,8 +1,5 @@ #include "libcrypto_util.h" -#if OPENSSL_VERSION_MAJOR >= 4 -#include -#endif #include #include #include @@ -95,6 +92,8 @@ json_t * asn1str2json(ASN1_STRING const *str) { BIO *bio; + unsigned char const *str_data; + int str_len; int i; if (str == NULL) @@ -104,8 +103,11 @@ asn1str2json(ASN1_STRING const *str) if (bio == NULL) return NULL; - for (i = 0; i < str->length; i++) { - if (BIO_printf(bio, "%02x", str->data[i]) <= 0) { + str_data = ASN1_STRING_get0_data(str); + str_len = ASN1_STRING_length(str); + + for (i = 0; i < str_len; i++) { + if (BIO_printf(bio, "%02x", str_data[i]) <= 0) { BIO_free_all(bio); return NULL; } @@ -165,7 +167,8 @@ name2json(X509_NAME const *name) if (json_object_add(typeval, "type", child)) goto fail; - child = json_strn_new((char *)data->data, data->length); + child = json_strn_new((char *)ASN1_STRING_get0_data(data), + ASN1_STRING_length(data)); if (json_object_add(typeval, "value", child)) goto fail; } @@ -181,13 +184,18 @@ gn2json(GENERAL_NAME *gn) { ASN1_IA5STRING *str; int type; + unsigned char const *data; + int len; if (gn == NULL) return json_null(); str = GENERAL_NAME_get0_value(gn, &type); + data = ASN1_STRING_get0_data(str); + len = ASN1_STRING_length(str); + return (type == GEN_URI) - ? json_strn_new((char const *)str->data, str->length) + ? json_strn_new((char const *)data, len) : json_str_new(""); } diff --git a/src/object/certificate.c b/src/object/certificate.c index 911bd480..53a07ba9 100644 --- a/src/object/certificate.c +++ b/src/object/certificate.c @@ -1,8 +1,5 @@ #include "object/certificate.h" -#if OPENSSL_VERSION_MAJOR >= 4 -#include -#endif #include #include #if OPENSSL_VERSION_MAJOR >= 3 @@ -1134,7 +1131,13 @@ abort: } static int -handle_ip_extension(X509_EXTENSION const *ext, struct resources *resources) +handle_ip_extension( +#if OPENSSL_VERSION_MAJOR >= 4 + X509_EXTENSION const *ext, +#else + X509_EXTENSION *ext, +#endif + struct resources *resources) { ASN1_OCTET_STRING const *string; struct IPAddrBlocks *blocks; @@ -1143,7 +1146,8 @@ handle_ip_extension(X509_EXTENSION const *ext, struct resources *resources) int error; string = X509_EXTENSION_get_data(ext); - error = asn1_decode(string->data, string->length, &asn_DEF_IPAddrBlocks, + error = asn1_decode(ASN1_STRING_get0_data(string), + ASN1_STRING_length(string), &asn_DEF_IPAddrBlocks, (void **) &blocks, true); if (error) return error; @@ -1183,16 +1187,22 @@ end: } static int -handle_asn_extension(X509_EXTENSION const *ext, struct resources *resources, - bool allow_inherit) +handle_asn_extension( +#if OPENSSL_VERSION_MAJOR >= 4 + X509_EXTENSION const *ext, +#else + X509_EXTENSION *ext, +#endif + struct resources *resources, bool allow_inherit) { ASN1_OCTET_STRING const *string; struct ASIdentifiers *ids; int error; string = X509_EXTENSION_get_data(ext); - error = asn1_decode(string->data, string->length, - &asn_DEF_ASIdentifiers, (void **) &ids, true); + error = asn1_decode(ASN1_STRING_get0_data(string), + ASN1_STRING_length(string), &asn_DEF_ASIdentifiers, + (void **) &ids, true); if (error) return error; @@ -1207,7 +1217,11 @@ __certificate_get_resources(X509 *cert, struct resources *resources, int addr_nid, int asn_nid, int bad_addr_nid, int bad_asn_nid, char const *policy_rfc, char const *bad_ext_rfc, bool allow_asn_inherit) { +#if OPENSSL_VERSION_MAJOR >= 4 X509_EXTENSION const *ext; +#else + X509_EXTENSION *ext; +#endif int nid; int i; int error; @@ -1296,9 +1310,14 @@ is_rsync(ASN1_IA5STRING *uri) { static char const *const PREFIX = "rsync://"; size_t prefix_len = strlen(PREFIX); + unsigned char const *uri_data; + int uri_len; - return (uri->length >= prefix_len) - ? (strncmp((char *) uri->data, PREFIX, strlen(PREFIX)) == 0) + uri_data = ASN1_STRING_get0_data(uri); + uri_len = ASN1_STRING_length(uri); + + return (uri_len >= prefix_len) + ? (strncmp((char *) uri_data, PREFIX, prefix_len) == 0) : false; } @@ -1367,6 +1386,8 @@ handle_ski_ee(void *ext, void *arg) { ASN1_OCTET_STRING *ski = ext; struct ski_arguments *args = arg; + unsigned char const *ski_data; + int ski_len; OCTET_STRING_t *sid; int error; @@ -1376,11 +1397,11 @@ handle_ski_ee(void *ext, void *arg) /* rfc6488#section-2.1.6.2 */ /* rfc6488#section-3.1.c 2/2 */ + ski_data = ASN1_STRING_get0_data(ski); + ski_len = ASN1_STRING_length(ski); sid = args->sid; - if (ski->length != sid->size - || memcmp(ski->data, sid->buf, sid->size) != 0) { + if (ski_len != sid->size || memcmp(ski_data, sid->buf, sid->size) != 0) return pr_val_err("The EE certificate's subjectKeyIdentifier does not equal the Signed Object's sid."); - } return 0; } @@ -1421,16 +1442,26 @@ handle_ku(ASN1_BIT_STRING *ku, unsigned char byte1) * But zeroized rightmost bits can be omitted. * This implementation assumes that the ninth bit should always be zero. */ - + size_t ku_len; +#if OPENSSL_VERSION_MAJOR >= 4 + int ku_unused_bits; +#endif unsigned char data[2]; - if (ku->length != 2 && ku->length != 1) { - return pr_val_err("Bogus %s length: %d", - ext_ku()->name, ku->length); +#if OPENSSL_VERSION_MAJOR >= 4 + if (ASN1_BIT_STRING_get_length(ku, &ku_len, &ku_unused_bits) != 1) + return pr_val_err("Cannot read Key Usage string."); +#else + ku_len = ku->length; +#endif + + if (ku_len != 2 && ku_len != 1) { + return pr_val_err("Bogus %s length: %zu", + ext_ku()->name, ku_len); } memset(data, 0, sizeof(data)); - memcpy(data, ku->data, ku->length); + memcpy(data, ASN1_STRING_get0_data(ku), ku_len); if (data[0] != byte1 || data[1] != 0) { return pr_val_err("Illegal key usage flag string: %d%d%d%d%d%d%d%d%d", diff --git a/src/object/name.c b/src/object/name.c index 598781a0..07553ce5 100644 --- a/src/object/name.c +++ b/src/object/name.c @@ -1,8 +1,5 @@ #include "object/name.h" -#if OPENSSL_VERSION_MAJOR >= 4 -#include -#endif #include #include #include @@ -27,15 +24,20 @@ static int name2string(X509_NAME_ENTRY const *name, char **_result) { const ASN1_STRING *data; + unsigned char const *str; + int len; char *result; data = X509_NAME_ENTRY_get_data(name); if (data == NULL) return val_crypto_err("X509_NAME_ENTRY_get_data() returned NULL"); - result = pmalloc(data->length + 1); - memcpy(result, data->data, data->length); - result[data->length] = '\0'; + str = ASN1_STRING_get0_data(data); + len = ASN1_STRING_length(data); + + result = pmalloc(len + 1); + memcpy(result, str, len); + result[len] = '\0'; *_result = result; return 0; diff --git a/src/str_token.c b/src/str_token.c index 6963f43b..c44ea537 100644 --- a/src/str_token.c +++ b/src/str_token.c @@ -1,8 +1,5 @@ #include "str_token.h" -#if OPENSSL_VERSION_MAJOR >= 4 -#include -#endif #include #include #include @@ -29,10 +26,8 @@ string_clone(void const *string, size_t size) int ia5s2string(ASN1_IA5STRING *ia5, char **result) { - if (ia5->flags & ASN1_STRING_FLAG_BITS_LEFT) - return pr_val_err("CRL URI IA5String has unused bits."); - - *result = string_clone(ia5->data, ia5->length); + *result = string_clone(ASN1_STRING_get0_data(ia5), + ASN1_STRING_length(ia5)); return 0; }