1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
Bug 973539 - Part of commit 5e4e8452328804948d042235bbf58ca457795857
diff --git a/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index d1fe18e5ab..aa969aa37c 100644
--- a/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -209,13 +209,20 @@ create_identifiers_from_stack(STACK_OF(X509) *sk,
#define EVP_MD_CTX_new EVP_MD_CTX_create
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
#define ASN1_STRING_get0_data ASN1_STRING_data
+#define X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_trusted_stack
/*
- * 1.1 adds DHX support, which uses the RFC 3279 DomainParameters encoding we
+ * 1.0.2 adds DHX support, which uses the RFC 3279 DomainParameters encoding we
* need for PKINIT. For 1.0 we must use the original DH type when creating
* EVP_PKEY objects.
*/
+#ifndef EVP_PKEY_DHX
#define EVP_PKEY_DHX EVP_PKEY_DH
+#endif
+
+/* Make X509_NAME_print_ex() accept a const name pointer by adding a cast. */
+#define X509_NAME_print_ex(a, b, c, d) \
+ X509_NAME_print_ex(a, (X509_NAME *)b, c, d)
/* 1.1 makes many handle types opaque and adds accessors. Add compatibility
* versions of the new accessors we use for pre-1.1. */
@@ -295,6 +302,10 @@ compat_ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
#define EVP_PKEY_get_bits EVP_PKEY_bits
#define EVP_PKEY_get_base_id EVP_PKEY_base_id
+/* Make X509_dup() accept a const pointer by adding a cast. */
+#define X509_dup(a) X509_dup((X509 *)a)
+#define i2d_X509_NAME(a, b) i2d_X509_NAME((X509_NAME *)a, b)
+
/*
* Convert *dh to an EVP_PKEY object, taking ownership of *dh and setting it to
* NULL. On error, return NULL and do not take ownership of or change *dh.
@@ -318,6 +329,11 @@ dh_to_pkey(DH **dh)
}
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
+#if OPENSSL_VERSION_NUMBER < 0x40000000L
+/* Make X509V3_EXT_d2i() accept a const pointer by adding a cast. */
+#define X509V3_EXT_d2i(a) X509V3_EXT_d2i((X509_EXTENSION *)a)
+#endif
+
/* Encode a bignum as an ASN.1 integer in DER. */
static int
encode_bn_der(const BIGNUM *bn, uint8_t **der_out, int *len_out)
@@ -1134,6 +1150,13 @@ oerr_cert(krb5_context context, krb5_error_code code, X509_STORE_CTX *certctx,
return oerr(context, code, _("%s (depth %d): %s"), msg, depth, errstr);
}
+/* Convert an OpenSSL ASN.1 string value to krb5_data, without copying. */
+static inline krb5_data
+asn1string_to_data(ASN1_STRING *s)
+{
+ return make_data((char *)ASN1_STRING_get0_data(s), ASN1_STRING_length(s));
+}
+
krb5_error_code
pkinit_init_plg_crypto(krb5_context context,
pkinit_plg_crypto_context *cryptoctx)
@@ -1775,7 +1798,7 @@ cms_signeddata_create(krb5_context context,
goto cleanup;
X509_STORE_CTX_init(certctx, certstore, id_cryptoctx->my_cert,
id_cryptoctx->intermediateCAs);
- X509_STORE_CTX_trusted_stack(certctx, id_cryptoctx->trustedCAs);
+ X509_STORE_CTX_set0_trusted_stack(certctx, id_cryptoctx->trustedCAs);
if (!X509_verify_cert(certctx)) {
retval = oerr_cert(context, 0, certctx,
_("Failed to verify own certificate"));
@@ -2002,7 +2025,7 @@ cms_signeddata_verify(krb5_context context,
unsigned char *d;
*is_signed = 0;
octets = CMS_get0_content(cms);
- if (!octets || ((*octets)->type != V_ASN1_OCTET_STRING)) {
+ if (!octets || (ASN1_STRING_type(*octets) != V_ASN1_OCTET_STRING)) {
retval = KRB5KDC_ERR_PREAUTH_FAILED;
krb5_set_error_message(context, retval,
_("Invalid pkinit packet: octet string "
@@ -2058,7 +2081,8 @@ cms_signeddata_verify(krb5_context context,
/* We cannot use CMS_dataInit because there may be no digest */
octets = CMS_get0_content(cms);
if (octets)
- out = BIO_new_mem_buf((*octets)->data, (*octets)->length);
+ out = BIO_new_mem_buf(ASN1_STRING_get0_data(*octets),
+ ASN1_STRING_length(*octets));
if (out == NULL)
goto cleanup;
} else {
@@ -2118,7 +2142,7 @@ cms_signeddata_verify(krb5_context context,
/* add trusted CAs certificates for cert verification */
if (idctx->trustedCAs != NULL)
- X509_STORE_CTX_trusted_stack(cert_ctx, idctx->trustedCAs);
+ X509_STORE_CTX_set0_trusted_stack(cert_ctx, idctx->trustedCAs);
else {
pkiDebug("unable to find any trusted CAs\n");
goto cleanup;
@@ -2156,7 +2180,7 @@ cms_signeddata_verify(krb5_context context,
i = X509_verify_cert(cert_ctx);
if (i <= 0) {
int j = X509_STORE_CTX_get_error(cert_ctx);
- X509 *cert;
+ const X509 *cert;
cert = X509_STORE_CTX_get_current_cert(cert_ctx);
reqctx->received_cert = X509_dup(cert);
@@ -2316,7 +2340,7 @@ crypto_retrieve_X509_sans(krb5_context context,
krb5_principal *princs = NULL;
char **upns = NULL;
unsigned char **dnss = NULL;
- X509_EXTENSION *ext = NULL;
+ const X509_EXTENSION *ext = NULL;
GENERAL_NAMES *ialt = NULL;
GENERAL_NAME *gen = NULL;
@@ -2379,8 +2403,7 @@ crypto_retrieve_X509_sans(krb5_context context,
gen = sk_GENERAL_NAME_value(ialt, i);
switch (gen->type) {
case GEN_OTHERNAME:
- name.length = gen->d.otherName->value->value.sequence->length;
- name.data = (char *)gen->d.otherName->value->value.sequence->data;
+ name = asn1string_to_data(gen->d.otherName->value->value.sequence);
if (princs != NULL &&
OBJ_cmp(plgctx->id_pkinit_san,
gen->d.otherName->type_id) == 0) {
@@ -2414,12 +2437,13 @@ crypto_retrieve_X509_sans(krb5_context context,
case GEN_DNS:
if (dnss != NULL) {
/* Prevent abuse of embedded null characters. */
- if (memchr(gen->d.dNSName->data, '\0', gen->d.dNSName->length))
+ if (memchr(ASN1_STRING_get0_data(gen->d.dNSName), '\0',
+ ASN1_STRING_length(gen->d.dNSName)))
break;
pkiDebug("%s: found dns name = %s\n", __FUNCTION__,
- gen->d.dNSName->data);
+ ASN1_STRING_get0_data(gen->d.dNSName));
dnss[d] = (unsigned char *)
- strdup((char *)gen->d.dNSName->data);
+ strdup((char *)ASN1_STRING_get0_data(gen->d.dNSName));
if (dnss[d] == NULL) {
pkiDebug("%s: failed to duplicate dns name\n",
__FUNCTION__);
@@ -3094,8 +3118,10 @@ int
pkinit_openssl_init(void)
{
/* Initialize OpenSSL. */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
+#endif
return 0;
}
@@ -4766,7 +4792,7 @@ crypto_retrieve_X509_key_usage(krb5_context context,
}
static krb5_error_code
-rfc2253_name(X509_NAME *name, char **str_out)
+rfc2253_name(const X509_NAME *name, char **str_out)
{
BIO *b = NULL;
char *str;
@@ -5227,7 +5253,7 @@ create_identifiers_from_stack(STACK_OF(X509) *sk,
int i = 0, sk_size = sk_X509_num(sk);
krb5_external_principal_identifier **krb5_cas = NULL;
X509 *x = NULL;
- X509_NAME *xn = NULL;
+ const X509_NAME *xn = NULL;
unsigned char *p = NULL;
int len = 0;
PKCS7_ISSUER_AND_SERIAL *is = NULL;
diff --git a/plugins/tls/k5tls/openssl.c b/plugins/tls/k5tls/openssl.c
index 42d72dc9ec..7763327b7a 100644
--- a/plugins/tls/k5tls/openssl.c
+++ b/plugins/tls/k5tls/openssl.c
@@ -38,6 +38,24 @@
#include <openssl/x509v3.h>
#include <dirent.h>
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+/* Make X509_get_subject_name() accept a const pointer by adding a cast. */
+#define X509_get_subject_name(a) X509_get_subject_name((X509 *)a)
+
+/* OpenSSL 1.0 did not have TLS_client_method(); use the best alternative. */
+#define TLS_client_method() SSLv23_client_method()
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x40000000L
+/*
+ * OpenSSL 4.0 constifies the result of X509_STORE_CTX_get_current_cert() and
+ * the input of X509_check_host() and X509_check_ip_asc(). For prior versions,
+ * make the latter two functions accept const pointers via a cast.
+ */
+#define X509_check_host(a, b, c, d, e) X509_check_host((X509 *)a, b, c, d, e)
+#define X509_check_ip_asc(a, b, c) X509_check_ip_asc((X509 *)a, b, c)
+#endif
+
struct k5_tls_handle_st {
SSL *ssl;
char *servername;
@@ -51,9 +69,11 @@ MAKE_INIT_FUNCTION(init_openssl);
int
init_openssl(void)
{
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
+#endif
ex_context_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
ex_handle_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
return 0;
@@ -72,7 +92,7 @@ flush_errors(krb5_context context)
}
static krb5_boolean
-check_cert_name_or_ip(X509 *x, const char *expected_name)
+check_cert_name_or_ip(const X509 *x, const char *expected_name)
{
struct in_addr in;
struct in6_addr in6;
@@ -89,7 +109,7 @@ check_cert_name_or_ip(X509 *x, const char *expected_name)
static int
verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx)
{
- X509 *x;
+ const X509 *x;
SSL *ssl;
BIO *bio;
krb5_context context;
@@ -246,7 +266,7 @@ setup(krb5_context context, SOCKET fd, const char *servername,
return KRB5_PLUGIN_OP_NOTSUPP;
/* Do general SSL library setup. */
- ctx = SSL_CTX_new(SSLv23_client_method());
+ ctx = SSL_CTX_new(TLS_client_method());
if (ctx == NULL)
goto error;
|