Skip to content

Commit 2f2af3a

Browse files
metze-sambaabartlet
authored andcommitted
lib/crypto: add legacy_gnutls_server_end_point_cb() if needed
gnutls_session_channel_binding(GNUTLS_CB_TLS_SERVER_END_POINT) is only available with gnutls 3.7.2, but we still want to support older gnutls versions and that's easily doable... BUG: https://bugzilla.samba.org/show_bug.cgi?id=15621 Signed-off-by: Stefan Metzmacher <[email protected]> Reviewed-by: Andrew Bartlett <[email protected]>
1 parent c200cf1 commit 2f2af3a

File tree

4 files changed

+146
-1
lines changed

4 files changed

+146
-1
lines changed

lib/crypto/gnutls_helpers.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,4 +233,10 @@ NTSTATUS samba_gnutls_sp800_108_derive_key(
233233
uint8_t *KO,
234234
size_t KO_len);
235235

236+
#ifndef HAVE_GNUTLS_CB_TLS_SERVER_END_POINT
237+
int legacy_gnutls_server_end_point_cb(gnutls_session_t session,
238+
bool is_server,
239+
gnutls_datum_t * cb);
240+
#endif /* HAVE_GNUTLS_CB_TLS_SERVER_END_POINT */
241+
236242
#endif /* _GNUTLS_HELPERS_H */
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Copyright (C) 2002-2016 Free Software Foundation, Inc.
3+
* Copyright (C) 2014-2016 Nikos Mavrogiannopoulos
4+
* Copyright (C) 2015-2018 Red Hat, Inc.
5+
*
6+
* Author: Nikos Mavrogiannopoulos
7+
*
8+
* This file is part of GnuTLS.
9+
*
10+
* The GnuTLS is free software; you can redistribute it and/or
11+
* modify it under the terms of the GNU Lesser General Public License
12+
* as published by the Free Software Foundation; either version 2.1 of
13+
* the License, or (at your option) any later version.
14+
*
15+
* This library is distributed in the hope that it will be useful, but
16+
* WITHOUT ANY WARRANTY; without even the implied warranty of
17+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18+
* Lesser General Public License for more details.
19+
*
20+
* You should have received a copy of the GNU Lesser General Public License
21+
* along with this program. If not, see <https://www.gnu.org/licenses/>
22+
*
23+
*/
24+
25+
#include "replace.h"
26+
#include "gnutls_helpers.h"
27+
#include <gnutls/gnutls.h>
28+
#include <gnutls/x509.h>
29+
30+
int legacy_gnutls_server_end_point_cb(gnutls_session_t session,
31+
bool is_server,
32+
gnutls_datum_t * cb)
33+
{
34+
/*
35+
* copied from the logic in gnutls_session_channel_binding()
36+
* introduced by gnutls commit (as LGPL 2.1+):
37+
*
38+
* commit 9ebee00c793e40e3e8c797c645577c9e025b9f1e
39+
* Author: Ruslan N. Marchenko <[email protected]>
40+
* Date: Sat May 1 23:05:54 2021 +0200
41+
*
42+
* Add tls-server-end-point tls channel binding implementation.
43+
* ...
44+
*/
45+
const gnutls_datum_t *ders = NULL;
46+
unsigned int num_certs = 1;
47+
int ret;
48+
size_t rlen;
49+
gnutls_x509_crt_t cert;
50+
gnutls_digest_algorithm_t algo;
51+
52+
/* Only X509 certificates are supported for this binding type */
53+
ret = gnutls_certificate_type_get(session);
54+
if (ret != GNUTLS_CRT_X509) {
55+
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
56+
}
57+
58+
if (is_server) {
59+
ders = gnutls_certificate_get_ours(session);
60+
} else {
61+
ders = gnutls_certificate_get_peers(session, &num_certs);
62+
}
63+
64+
/* Previous check indicated we have x509 but you never know */
65+
if (!ders || num_certs == 0) {
66+
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
67+
}
68+
69+
ret = gnutls_x509_crt_list_import(&cert,
70+
&num_certs,
71+
ders,
72+
GNUTLS_X509_FMT_DER,
73+
0);
74+
/* Again, this is not supposed to happen (normally) */
75+
if (ret < 0 || num_certs == 0) {
76+
return GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE;
77+
}
78+
79+
/* Obtain signature algorithm used by certificate */
80+
ret = gnutls_x509_crt_get_signature_algorithm(cert);
81+
if (ret < 0 || ret == GNUTLS_SIGN_UNKNOWN) {
82+
gnutls_x509_crt_deinit(cert);
83+
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
84+
}
85+
86+
/* obtain hash function from signature and normalize it */
87+
algo = gnutls_sign_get_hash_algorithm(ret);
88+
switch (algo) {
89+
case GNUTLS_DIG_MD5:
90+
case GNUTLS_DIG_SHA1:
91+
algo = GNUTLS_DIG_SHA256;
92+
break;
93+
case GNUTLS_DIG_UNKNOWN:
94+
case GNUTLS_DIG_NULL:
95+
case GNUTLS_DIG_MD5_SHA1:
96+
/* double hashing not supported either */
97+
gnutls_x509_crt_deinit(cert);
98+
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
99+
default:
100+
break;
101+
}
102+
103+
/* preallocate 512 bits buffer as maximum supported digest */
104+
rlen = 64;
105+
cb->data = gnutls_malloc(rlen);
106+
if (cb->data == NULL) {
107+
gnutls_x509_crt_deinit(cert);
108+
return GNUTLS_E_MEMORY_ERROR;
109+
}
110+
111+
ret = gnutls_x509_crt_get_fingerprint(cert,
112+
algo,
113+
cb->data,
114+
&rlen);
115+
if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
116+
cb->data = gnutls_realloc(cb->data, cb->size);
117+
if (cb->data == NULL) {
118+
gnutls_x509_crt_deinit(cert);
119+
return GNUTLS_E_MEMORY_ERROR;
120+
}
121+
ret = gnutls_x509_crt_get_fingerprint(cert,
122+
algo,
123+
cb->data,
124+
&rlen);
125+
}
126+
127+
cb->size = rlen;
128+
gnutls_x509_crt_deinit(cert);
129+
return ret;
130+
}

lib/crypto/wscript

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22

33

44
def build(bld):
5+
legacy_gnutls_helpers = ''
6+
if not bld.CONFIG_SET('HAVE_GNUTLS_CB_TLS_SERVER_END_POINT'):
7+
legacy_gnutls_helpers += ' gnutls_server_end_point_cb.c'
8+
59
bld.SAMBA_SUBSYSTEM("GNUTLS_HELPERS",
610
source='''
711
gnutls_error.c
812
gnutls_aead_aes_256_cbc_hmac_sha512.c
913
gnutls_arcfour_confounded_md5.c
1014
gnutls_weak_crypto.c
1115
gnutls_sp800_108.c
12-
''',
16+
''' + legacy_gnutls_helpers,
1317
deps="gnutls samba-errors")
1418

1519
bld.SAMBA_SUBSYSTEM('LIBCRYPTO',

wscript_configure_system_gnutls

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ conf.SET_TARGET_TYPE('gnutls', 'SYSLIB')
3434
if (gnutls_version > parse_version('3.6.14')):
3535
conf.DEFINE('ALLOW_GNUTLS_AEAD_CIPHER_ENCRYPTV2_AES_CCM', 1)
3636

37+
# GNUTLS_CB_TLS_SERVER_END_POINT is available with
38+
# 3.7.2
39+
if (gnutls_version >= parse_version('3.7.2')):
40+
conf.DEFINE('HAVE_GNUTLS_CB_TLS_SERVER_END_POINT', 1)
41+
3742
# Check if gnutls has fips mode support
3843
# gnutls_fips140_mode_enabled() is available since 3.3.0
3944
fragment = '''

0 commit comments

Comments
 (0)