From 8ad96adc5fea0cef923a2a679600f3a5c4c5bfce Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 15 Apr 2026 15:10:42 -0500 Subject: [PATCH] Changes for OpenSSL-4.0.0 Changes to get OpenSC to compile with OpenSSl-4.0.0 OpenSSL says: "Opaque Structures: ASN1_STRING has been made opaque, and further work has been done to make X509 structures more memory-efficient and const-correct." ASN1_STRING was made opaque thus requiring the use of ASN1_STRING_get0_data, and ASN1_STRING_length. These routines have been in OpenSSL since 1.1.1 and are also in libressl. ASN1_STRING_get0_data returns a const pointer, so the data can not be changed. There are a number of reverse() functions one of which was reversing the bytes in a EC pubkey. Changes not addressed: "Global Cleanup: libcrypto no longer uses atexit() for cleanup; OPENSSL_cleanup() now runs in a global destructor." On branch OpenSSL-4.0.0 Changes to be committed: modified: src/libopensc/cwa-dnie.c modified: src/pkcs11/openssl.c modified: src/pkcs15init/pkcs15-oberthur-awp.c modified: src/tests/p11test/p11test_case_common.c modified: src/tools/netkey-tool.c modified: src/tools/pkcs11-tool.c modified: src/tools/pkcs15-init.c --- src/libopensc/cwa-dnie.c | 2 +- src/pkcs11/openssl.c | 14 ++++++---- src/pkcs15init/pkcs15-oberthur-awp.c | 16 +++++------ src/tests/p11test/p11test_case_common.c | 24 ++++++++-------- src/tools/netkey-tool.c | 37 +++++++++++++++++-------- src/tools/pkcs11-tool.c | 22 +++++++-------- src/tools/pkcs15-init.c | 4 +-- 7 files changed, 68 insertions(+), 51 deletions(-) diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index 47f3792dad..6020921dbc 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -646,7 +646,7 @@ static int dnie_set_channel_data(sc_card_t * card, X509 * icc_intermediate_ca_ce dnie_private_data_t *priv_data = GET_DNIE_PRIV_DATA(card); LOG_FUNC_CALLED(card->ctx); - X509_NAME *issuer = X509_get_issuer_name(icc_intermediate_ca_cert); + const X509_NAME *issuer = X509_get_issuer_name(icc_intermediate_ca_cert); if (issuer) { buf = X509_NAME_oneline(issuer, buf, 0); if (!buf) { diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 0a5d4394a2..a4027339b2 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -463,6 +463,7 @@ static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len EC_POINT *P; BIGNUM *X, *Y; ASN1_OCTET_STRING *octet = NULL; + unsigned char *octet_rev = NULL; char paramset[2] = "A"; int r = -1, ret_vrf = 0; #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -516,13 +517,16 @@ static CK_RV gostr3410_verify_data(const CK_BYTE_PTR pubkey, CK_ULONG pubkey_len if (group && pubkey_len <= LONG_MAX) { const unsigned char *p = pubkey; octet = d2i_ASN1_OCTET_STRING(NULL, &p, (long)pubkey_len); + if (octet) + octet_rev = malloc(ASN1_STRING_length(octet)); } - if (group && octet) { - reverse(octet->data, octet->length); - Y = BN_bin2bn(octet->data, octet->length / 2, NULL); - X = BN_bin2bn((const unsigned char*)octet->data + - octet->length / 2, octet->length / 2, NULL); + if (group && octet && octet_rev) { + memcpy(octet_rev, ASN1_STRING_get0_data(octet), ASN1_STRING_length(octet)); + reverse(octet_rev, ASN1_STRING_length(octet)); + Y = BN_bin2bn(octet_rev, ASN1_STRING_length(octet) / 2, NULL); + X = BN_bin2bn(octet_rev + ASN1_STRING_length(octet) / 2, ASN1_STRING_length(octet) / 2, NULL); ASN1_OCTET_STRING_free(octet); + free(octet_rev); P = EC_POINT_new(group); if (P && X && Y) r = EC_POINT_set_affine_coordinates(group, P, X, Y, NULL); diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index 22c943127b..fdb06ab6b4 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -51,21 +51,21 @@ awp_get_commonName(X509 *x) r = X509_NAME_get_index_by_NID(X509_get_subject_name(x), NID_commonName, -1); if (r >= 0) { - X509_NAME_ENTRY *ne; - ASN1_STRING *a_str; + const X509_NAME_ENTRY *ne; + const ASN1_STRING *a_str; if (!(ne = X509_NAME_get_entry(X509_get_subject_name(x), r))) ; else if (!(a_str = X509_NAME_ENTRY_get_data(ne))) ; - else if (a_str->type == 0x0C) { - ret = malloc(a_str->length + 1); + else if (ASN1_STRING_type(a_str) == V_ASN1_UTF8STRING) { + ret = malloc(ASN1_STRING_length(a_str) + 1); if (ret) { - memcpy(ret, a_str->data, a_str->length); - *(ret + a_str->length) = '\0'; + memcpy(ret, ASN1_STRING_get0_data(a_str), ASN1_STRING_length(a_str)); + + *(ret + ASN1_STRING_length(a_str)) = '\0'; } - } - else { + } else { unsigned char *tmp = NULL; r = ASN1_STRING_to_UTF8(&tmp, a_str); diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c index 1dd6eaba67..f571cd1598 100644 --- a/src/tests/p11test/p11test_case_common.c +++ b/src/tests/p11test/p11test_case_common.c @@ -776,34 +776,34 @@ int callback_public_keys(test_certs_t *objects, switch (o->key_type) { #ifdef EVP_PKEY_ED25519 case CKK_EC_EDWARDS: - if (strcmp((char *)curve->data, "edwards25519") == 0) { + if (strcmp((char *)ASN1_STRING_get0_data(curve), "edwards25519") == 0) { evp_type = EVP_PKEY_ED25519; break; #ifdef EVP_PKEY_ED448 - } else if (strcmp((char *)curve->data, "edwards448") == 0) { + } else if (strcmp((char *)ASN1_STRING_get0_data(curve), "edwards448") == 0) { evp_type = EVP_PKEY_ED448; break; #endif /* EVP_PKEY_ED448 */ } debug_print(" [WARN %s ] Unknown curve name. " " expected edwards25519 or edwards448, got %s", - o->id_str, curve->data); + o->id_str, ASN1_STRING_get0_data(curve)); break; #endif #ifdef EVP_PKEY_X25519 case CKK_EC_MONTGOMERY: - if (strcmp((char *)curve->data, "curve25519") == 0) { + if (strcmp((char *)ASN1_STRING_get0_data(curve), "curve25519") == 0) { evp_type = EVP_PKEY_X25519; break; #ifdef EVP_PKEY_X448 - } else if (strcmp((char *)curve->data, "curve448") == 0) { + } else if (strcmp((char *)ASN1_STRING_get0_data(curve), "curve448") == 0) { evp_type = EVP_PKEY_X448; break; #endif /* EVP_PKEY_X448 */ } debug_print(" [WARN %s ] Unknown curve name. " " expected curve25519 or curve448, got %s", - o->id_str, curve->data); + o->id_str, ASN1_STRING_get0_data(curve)); break; #endif default: @@ -893,14 +893,14 @@ int callback_public_keys(test_certs_t *objects, break; #endif } - if (os->length != exp_length) { + if (ASN1_STRING_length(os) != exp_length) { debug_print(" [WARN %s ] Invalid length of EC_POINT value. Got %d, expected %d", - o->id_str, os->length, exp_length); + o->id_str, ASN1_STRING_length(os), exp_length); return -1; } key = EVP_PKEY_new_raw_public_key(evp_type, NULL, - (const uint8_t *)os->data, - os->length); + (const uint8_t *)ASN1_STRING_get0_data(os), + ASN1_STRING_length(os)); if (key == NULL) { debug_print(" [WARN %s ] Out of memory", o->id_str); ASN1_STRING_free(os); @@ -925,8 +925,8 @@ int callback_public_keys(test_certs_t *objects, } if (EVP_PKEY_get_raw_public_key(o->key, pub, &publen) != 1 || - publen != (size_t)os->length || - memcmp(pub, os->data, publen) != 0) { + publen != (size_t)ASN1_STRING_length(os) || + memcmp(pub, ASN1_STRING_get0_data(os), publen) != 0) { debug_print(" [WARN %s ] Got different public" "key then from the certificate", o->id_str); diff --git a/src/tools/netkey-tool.c b/src/tools/netkey-tool.c index 23bab2a8ec..683ac182bd 100644 --- a/src/tools/netkey-tool.c +++ b/src/tools/netkey-tool.c @@ -144,25 +144,38 @@ static void show_certs(sc_card_t *card) if(q[4]==6 && q[5]<10 && q[q[5]+6]==0x30 && q[q[5]+7]==0x82) q+=q[5]+6; printf(", Len=%d\n", (q[2]<<8)|q[3]); if((c=d2i_X509(NULL,&q,f->size))){ - char buf2[2000]; - if (X509_NAME_get_text_by_NID(X509_get_subject_name(c), NID_commonName, buf2, sizeof(buf2)) < 0) { + int idx; + const X509_NAME_ENTRY *ne = NULL; /* no free */ + const ASN1_STRING *a_str = NULL; /* no free */ + int out_len = 0; + unsigned char *tmp = NULL; + + idx = X509_NAME_get_index_by_NID(X509_get_subject_name(c), NID_commonName, -1); + if (idx >= 0 && + ((ne = X509_NAME_get_entry(X509_get_subject_name(c), idx)) != NULL) && + ((a_str = X509_NAME_ENTRY_get_data(ne)) != NULL) && + ((out_len = ASN1_STRING_to_UTF8(&tmp, a_str)) > 0)) { + printf(" Subject-CN: %s\n", tmp); + OPENSSL_free(tmp); + tmp = NULL; + } else { sc_log_openssl(card->ctx); printf(" Invalid Subject-CN\n"); - X509_free(c); - continue; } - printf(" Subject-CN: %s\n", buf2); - if (X509_NAME_get_text_by_NID(X509_get_issuer_name(c), NID_commonName, buf2, sizeof(buf2)) < 0) { + + idx = X509_NAME_get_index_by_NID(X509_get_issuer_name(c), NID_commonName, -1); + if (idx >= 0 && + ((ne = X509_NAME_get_entry(X509_get_issuer_name(c), idx)) != NULL) && + ((a_str = X509_NAME_ENTRY_get_data(ne)) != NULL) && + ((out_len = ASN1_STRING_to_UTF8(&tmp, a_str)) > 0)) { + printf(" Issuer-CN: %s\n", tmp); + OPENSSL_free(tmp); + tmp = NULL; + } else { sc_log_openssl(card->ctx); printf(" Invalid Issuer-CN\n"); - X509_free(c); - continue; } - printf(" Issuer-CN: %s\n", buf2); X509_free(c); - } else { - sc_log_openssl(card->ctx); - printf(" Invalid Certificate-Data\n"); } } else printf(", empty\n"); } diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 452ac49617..cfc7486faa 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -7389,8 +7389,8 @@ static int read_object(CK_SESSION_HANDLE session) #endif point = EC_POINT_new(group); if (os) { - a = os->data; - a_len = os->length; + a = ASN1_STRING_get0_data(os); + a_len = ASN1_STRING_length(os); success = EC_POINT_oct2point(group, point, a, a_len, NULL); } if (!success) { /* Workaround for broken PKCS#11 modules */ @@ -7464,9 +7464,9 @@ static int read_object(CK_SESSION_HANDLE session) a = params; if (d2i_ASN1_PRINTABLESTRING(&curve, &a, (long)len) != NULL) { - if (strcmp((char *)curve->data, "edwards25519") && - strcmp((char *)curve->data, "curve25519")) { - util_fatal("Unknown curve name \"%si\"", curve->data); + if (strcmp((char *)ASN1_STRING_get0_data(curve), "edwards25519") && + strcmp((char *)ASN1_STRING_get0_data(curve), "curve25519")) { + util_fatal("Unknown curve name \"%si\"", (char *)ASN1_STRING_get0_data(curve)); } ASN1_PRINTABLESTRING_free(curve); } else if (d2i_ASN1_OBJECT(&obj, &a, (long)len) != NULL) { @@ -7526,26 +7526,26 @@ static int read_object(CK_SESSION_HANDLE session) } } - if (type == CKK_EC_EDWARDS && os->length == BYTES4BITS(256)) /* note extra bit */ + if (type == CKK_EC_EDWARDS && len == BYTES4BITS(256)) /* note extra bit */ raw_pk = EVP_PKEY_ED25519; #ifdef EVP_PKEY_ED448 - else if (type == CKK_EC_EDWARDS && os->length == ED448_KEY_SIZE_BYTES) + else if (type == CKK_EC_EDWARDS && len == ED448_KEY_SIZE_BYTES) raw_pk = EVP_PKEY_ED448; #endif /* EVP_PKEY_ED448 */ #ifdef EVP_PKEY_X25519 - else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(256)) /* note extra bit */ + else if (type == CKK_EC_MONTGOMERY && len == BYTES4BITS(256)) /* note extra bit */ raw_pk = EVP_PKEY_X25519; #endif /*EVP_PKEY_X25519 */ #ifdef EVP_PKEY_X448 - else if (type == CKK_EC_MONTGOMERY && os->length == BYTES4BITS(448)) + else if (type == CKK_EC_MONTGOMERY && len == BYTES4BITS(448)) raw_pk = EVP_PKEY_X448; #endif /* EVP_PKEY_X448 */ else util_fatal("Invalid or not supported CKK_EC_EDWARDS or CKK_EC_MONTGOMERY public key"); key = EVP_PKEY_new_raw_public_key(raw_pk, NULL, - (const uint8_t *)os->data, - os->length); + (const uint8_t *)ASN1_STRING_get0_data(os), + ASN1_STRING_length(os)); ASN1_STRING_free(os); if (key == NULL) { util_fatal("out of memory"); diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index e011232987..b978e0677a 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -2593,8 +2593,8 @@ do_read_data_object(const char *name, u8 **out, size_t *outlen, size_t expected) static char * cert_common_name(X509 *x509) { - X509_NAME_ENTRY *ne = NULL; - ASN1_STRING *a_str = NULL; + const X509_NAME_ENTRY *ne = NULL; + const ASN1_STRING *a_str = NULL; char *out = NULL; unsigned char *tmp = NULL; int idx, out_len = 0;