Skip to content

Commit 25ed30d

Browse files
committed
nmap: allow build with OpenSSL 4.0.0
1 parent b1144e6 commit 25ed30d

File tree

1 file changed

+272
-0
lines changed

1 file changed

+272
-0
lines changed
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
From c3276a9fe1c180ca2d3899350e0439230ab22805 Mon Sep 17 00:00:00 2001
2+
From: Rudi Heitbaum <rudi@heitbaum.com>
3+
Date: Sat, 21 Mar 2026 05:30:46 +0000
4+
Subject: [PATCH 1/3] nse_ssl_cert: allow build with OpenSSL 4.x
5+
MIME-Version: 1.0
6+
Content-Type: text/plain; charset=UTF-8
7+
Content-Transfer-Encoding: 8bit
8+
9+
ASN1_STRING are now opaque types — the internal data and length fields
10+
are no longer directly accessible. Use the accessor API instead.
11+
Accessors have been available since OpenSSL 1.1.0
12+
13+
Signatures of numerous API functions, including those that are related
14+
to X509 processing, are changed to include const qualifiers for argument
15+
and return types, where suitable. Add const qualifer to variables.
16+
17+
Signed-off-by: Rudi Heitbaum <rudi@heitbaum.com>
18+
---
19+
nse_ssl_cert.cc | 28 +++++++++++++++-------------
20+
1 file changed, 15 insertions(+), 13 deletions(-)
21+
22+
diff --git a/nse_ssl_cert.cc b/nse_ssl_cert.cc
23+
index a8d4e0d770..5313d9b900 100644
24+
--- a/nse_ssl_cert.cc
25+
+++ b/nse_ssl_cert.cc
26+
@@ -194,14 +194,14 @@ static void obj_to_key(lua_State *L, const ASN1_OBJECT *obj)
27+
/* This is a helper function for l_get_ssl_certificate. It builds a table from
28+
the given X509_NAME, using keys returned from obj_to_key as keys. The result
29+
is pushed on the stack. */
30+
-static void x509_name_to_table(lua_State *L, X509_NAME *name)
31+
+static void x509_name_to_table(lua_State *L, const X509_NAME *name)
32+
{
33+
int i;
34+
35+
lua_createtable(L, 0, X509_NAME_entry_count(name));
36+
37+
for (i = 0; i < X509_NAME_entry_count(name); i++) {
38+
- X509_NAME_ENTRY *entry;
39+
+ const X509_NAME_ENTRY *entry;
40+
const ASN1_OBJECT *obj;
41+
const ASN1_STRING *value;
42+
43+
@@ -210,7 +210,7 @@ static void x509_name_to_table(lua_State *L, X509_NAME *name)
44+
value = X509_NAME_ENTRY_get_data(entry);
45+
46+
obj_to_key(L, obj);
47+
- lua_pushlstring(L, (const char *) value->data, value->length);
48+
+ lua_pushlstring(L, (const char *) ASN1_STRING_get0_data(value), ASN1_STRING_length(value));
49+
50+
lua_settable(L, -3);
51+
}
52+
@@ -224,7 +224,7 @@ static bool x509_extensions_to_table(lua_State *L, const STACK_OF(X509_EXTENSION
53+
lua_createtable(L, sk_X509_EXTENSION_num(exts), 0);
54+
55+
for (int i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
56+
- ASN1_OBJECT *obj;
57+
+ const ASN1_OBJECT *obj;
58+
X509_EXTENSION *ext;
59+
char *value = NULL;
60+
BIO *out;
61+
@@ -298,14 +298,16 @@ static int parse_int(const unsigned char *s, size_t len)
62+
-1 on a parse error. */
63+
static int time_to_tm(const ASN1_TIME *t, struct tm *result)
64+
{
65+
+ const unsigned char *data = ASN1_STRING_get0_data(t);
66+
+ int length = ASN1_STRING_length(t);
67+
const unsigned char *p;
68+
69+
- p = t->data;
70+
- if (t->length == 13 && t->data[t->length - 1] == 'Z') {
71+
+ p = data;
72+
+ if (length == 13 && data[length - 1] == 'Z') {
73+
/* yymmddhhmmssZ */
74+
int year;
75+
76+
- year = parse_int(t->data, 2);
77+
+ year = parse_int(data, 2);
78+
if (year < 0)
79+
return -1;
80+
/* "In coming up with the worlds least efficient machine-readable time
81+
@@ -318,13 +320,13 @@ static int time_to_tm(const ASN1_TIME *t, struct tm *result)
82+
result->tm_year = 2000 + year;
83+
else
84+
result->tm_year = 1900 + year;
85+
- p = t->data + 2;
86+
- } else if (t->length == 15 && t->data[t->length - 1] == 'Z') {
87+
+ p = data + 2;
88+
+ } else if (length == 15 && data[length - 1] == 'Z') {
89+
/* yyyymmddhhmmssZ */
90+
- result->tm_year = parse_int(t->data, 4);
91+
+ result->tm_year = parse_int(data, 4);
92+
if (result->tm_year < 0)
93+
return -1;
94+
- p = t->data + 4;
95+
+ p = data + 4;
96+
} else {
97+
return -1;
98+
}
99+
@@ -385,7 +387,7 @@ static void asn1_time_to_obj(lua_State *L, const ASN1_TIME *s)
100+
} else if (time_to_tm(s, &tm) == 0) {
101+
tm_to_table(L, &tm);
102+
} else {
103+
- lua_pushlstring(L, (const char *) s->data, s->length);
104+
+ lua_pushlstring(L, (const char *) ASN1_STRING_get0_data(s), ASN1_STRING_length(s));
105+
}
106+
}
107+
108+
@@ -568,7 +570,7 @@ int l_get_ssl_certificate(lua_State *L)
109+
static int parse_ssl_cert(lua_State *L, X509 *cert)
110+
{
111+
struct cert_userdata *udata;
112+
- X509_NAME *subject, *issuer;
113+
+ const X509_NAME *subject, *issuer;
114+
EVP_PKEY *pubkey;
115+
int pkey_type;
116+
117+
118+
From b41fc1db888ff5ef59aace9abb32ea536c743f0a Mon Sep 17 00:00:00 2001
119+
From: Rudi Heitbaum <rudi@heitbaum.com>
120+
Date: Sat, 21 Mar 2026 05:45:46 +0000
121+
Subject: [PATCH 2/3] nsock: allow build with OpenSSL 4.x
122+
123+
OPENSSL_atexit() was removed in OpenSSL 4.0.0. The function was deprecated.
124+
Maintain SSL_CTX_free() using atexit() when
125+
OPENSSL_VERSION_NUMBER >= 0x40000000L
126+
127+
Signed-off-by: Rudi Heitbaum <rudi@heitbaum.com>
128+
---
129+
nsock/src/nsock_ssl.c | 4 ++++
130+
1 file changed, 4 insertions(+)
131+
132+
diff --git a/nsock/src/nsock_ssl.c b/nsock/src/nsock_ssl.c
133+
index c1ff6082d9..337351e14e 100644
134+
--- a/nsock/src/nsock_ssl.c
135+
+++ b/nsock/src/nsock_ssl.c
136+
@@ -118,7 +118,11 @@ static SSL_CTX *ssl_init_helper(const SSL_METHOD *method) {
137+
SSL_load_error_strings();
138+
SSL_library_init();
139+
#else
140+
+#if OPENSSL_VERSION_NUMBER < 0x40000000L
141+
OPENSSL_atexit(nsock_ssl_atexit);
142+
+#else
143+
+ atexit(nsock_ssl_atexit);
144+
+#endif
145+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
146+
if (NULL == OSSL_PROVIDER_load(NULL, "legacy"))
147+
{
148+
149+
From b86afa15b18d3d2fc71ea588cb700877b83e2852 Mon Sep 17 00:00:00 2001
150+
From: Rudi Heitbaum <rudi@heitbaum.com>
151+
Date: Sat, 21 Mar 2026 06:10:27 +0000
152+
Subject: [PATCH 3/3] ncat: allow build with OpenSSL 4.x
153+
MIME-Version: 1.0
154+
Content-Type: text/plain; charset=UTF-8
155+
Content-Transfer-Encoding: 8bit
156+
157+
ASN1_STRING are now opaque types — the internal data and length fields
158+
are no longer directly accessible. Use the accessor API instead.
159+
Accessors have been available since OpenSSL 1.1.0
160+
161+
Signatures of numerous API functions, including those that are related
162+
to X509 processing, are changed to include const qualifiers for argument
163+
and return types, where suitable. Add const qualifer to variables.
164+
165+
Signed-off-by: Rudi Heitbaum <rudi@heitbaum.com>
166+
---
167+
ncat/ncat_connect.c | 2 +-
168+
ncat/ncat_ssl.c | 28 +++++++++++++++-------------
169+
2 files changed, 16 insertions(+), 14 deletions(-)
170+
171+
diff --git a/ncat/ncat_connect.c b/ncat/ncat_connect.c
172+
index ee04695fcd..3bd6d46e70 100644
173+
--- a/ncat/ncat_connect.c
174+
+++ b/ncat/ncat_connect.c
175+
@@ -237,7 +237,7 @@ static void connect_report(nsock_iod nsi)
176+
#ifdef HAVE_OPENSSL
177+
if (nsock_iod_check_ssl(nsi)) {
178+
X509 *cert;
179+
- X509_NAME *subject;
180+
+ const X509_NAME *subject;
181+
char digest_buf[SHA1_STRING_LENGTH + 1];
182+
char *fp;
183+
184+
diff --git a/ncat/ncat_ssl.c b/ncat/ncat_ssl.c
185+
index a9c34d4047..a1fdc789f5 100644
186+
--- a/ncat/ncat_ssl.c
187+
+++ b/ncat/ncat_ssl.c
188+
@@ -262,10 +262,10 @@ static int wildcard_match(const char *pattern, const char *hostname, int len)
189+
static int cert_match_dnsname(X509 *cert, const char *hostname,
190+
unsigned int *num_checked)
191+
{
192+
- X509_EXTENSION *ext;
193+
+ const X509_EXTENSION *ext;
194+
STACK_OF(GENERAL_NAME) *gen_names;
195+
const X509V3_EXT_METHOD *method;
196+
- unsigned char *data;
197+
+ const unsigned char *data;
198+
int i;
199+
200+
if (num_checked != NULL)
201+
@@ -287,8 +287,8 @@ static int cert_match_dnsname(X509 *cert, const char *hostname,
202+
203+
/* We must copy this address into a temporary variable because ASN1_item_d2i
204+
increments it. We don't want it to corrupt ext->value->data. */
205+
- ASN1_OCTET_STRING* asn1_str = X509_EXTENSION_get_data(ext);
206+
- data = asn1_str->data;
207+
+ const ASN1_OCTET_STRING* asn1_str = X509_EXTENSION_get_data(ext);
208+
+ data = ASN1_STRING_get0_data(asn1_str);
209+
/* Here we rely on the fact that the internal representation (the "i" in
210+
"i2d") for NID_subject_alt_name is STACK_OF(GENERAL_NAME). Converting it
211+
to a stack of CONF_VALUE with a i2v method is not satisfactory, because a
212+
@@ -296,15 +296,17 @@ static int cert_match_dnsname(X509 *cert, const char *hostname,
213+
presence of null bytes. */
214+
#if (OPENSSL_VERSION_NUMBER > 0x00907000L)
215+
if (method->it != NULL) {
216+
- ASN1_OCTET_STRING* asn1_str_a = X509_EXTENSION_get_data(ext);
217+
+ const ASN1_OCTET_STRING* asn1_str_a = X509_EXTENSION_get_data(ext);
218+
+ int length = ASN1_STRING_length(asn1_str_a);
219+
gen_names = (STACK_OF(GENERAL_NAME) *) ASN1_item_d2i(NULL,
220+
(const unsigned char **) &data,
221+
- asn1_str_a->length, ASN1_ITEM_ptr(method->it));
222+
+ length, ASN1_ITEM_ptr(method->it));
223+
} else {
224+
- ASN1_OCTET_STRING* asn1_str_b = X509_EXTENSION_get_data(ext);
225+
+ const ASN1_OCTET_STRING* asn1_str_b = X509_EXTENSION_get_data(ext);
226+
+ int length = ASN1_STRING_length(asn1_str_b);
227+
gen_names = (STACK_OF(GENERAL_NAME) *) method->d2i(NULL,
228+
(const unsigned char **) &data,
229+
- asn1_str_b->length);
230+
+ length);
231+
}
232+
#else
233+
gen_names = (STACK_OF(GENERAL_NAME) *) method->d2i(NULL,
234+
@@ -371,9 +373,9 @@ static int less_specific(const unsigned char *a, size_t a_len,
235+
return num_components(a, a_len) < num_components(b, b_len);
236+
}
237+
238+
-static int most_specific_commonname(X509_NAME *subject, const char **result)
239+
+static int most_specific_commonname(const X509_NAME *subject, const char **result)
240+
{
241+
- ASN1_STRING *best, *cur;
242+
+ const ASN1_STRING *best, *cur;
243+
int i;
244+
245+
i = -1;
246+
@@ -407,7 +409,7 @@ static int most_specific_commonname(X509_NAME *subject, const char **result)
247+
components, the one that comes later in the certificate is more specific. */
248+
static int cert_match_commonname(X509 *cert, const char *hostname)
249+
{
250+
- X509_NAME *subject;
251+
+ const X509_NAME *subject;
252+
const char *commonname;
253+
int n;
254+
255+
@@ -470,7 +472,7 @@ int ssl_post_connect_check(SSL *ssl, const char *hostname)
256+
"Making Certificates"; and apps/req.c in the OpenSSL source. */
257+
static int ssl_gen_cert(X509 **cert, EVP_PKEY **key)
258+
{
259+
- X509_NAME *subj;
260+
+ const X509_NAME *subj;
261+
X509_EXTENSION *ext;
262+
X509V3_CTX ctx;
263+
const char *commonName = "localhost";
264+
@@ -527,7 +529,7 @@ static int ssl_gen_cert(X509 **cert, EVP_PKEY **key)
265+
subj = X509_get_subject_name(*cert);
266+
if (o.target != NULL)
267+
commonName = o.target;
268+
- if (X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC,
269+
+ if (X509_NAME_add_entry_by_txt((X509_NAME *) subj, "commonName", MBSTRING_ASC,
270+
(unsigned char *) commonName, -1, -1, 0) == 0) {
271+
goto err;
272+
}

0 commit comments

Comments
 (0)