Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qssldiffiehellmanparameters_openssl.cpp
Go to the documentation of this file.
1
// Copyright (C) 2015 Mikkel Krautz <mikkel@krautz.dk>
2
// Copyright (C) 2016 Richard J. Moore <rich@kde.org>
3
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
// Qt-Security score:critical reason:cryptography
5
6
#
include
"qsslsocket_openssl_symbols_p.h"
7
#
include
"qtlsbackend_openssl_p.h"
8
9
#
include
<
QtNetwork
/
private
/
qsslsocket_p
.
h
>
10
11
#
include
<
QtCore
/
qscopeguard
.
h
>
12
#
include
<
QtCore
/
qbytearray
.
h
>
13
#
include
<
QtCore
/
qiodevice
.
h
>
14
#
include
<
QtCore
/
qdebug
.
h
>
15
16
#
include
<
openssl
/
bn
.
h
>
17
#
include
<
openssl
/
dh
.
h
>
18
19
QT_BEGIN_NAMESPACE
20
21
#
ifndef
OPENSSL_NO_DEPRECATED_3_0
22
23
namespace
{
24
25
bool
isSafeDH
(DH *dh)
26
{
27
int
status = 0;
28
int
bad = 0;
29
30
// TLSTODO: check it's needed or if supportsSsl()
31
// is enough.
32
QSslSocketPrivate::ensureInitialized();
33
34
// From https://wiki.openssl.org/index.php/Diffie-Hellman_parameters:
35
//
36
// The additional call to BN_mod_word(dh->p, 24)
37
// (and unmasking of DH_NOT_SUITABLE_GENERATOR)
38
// is performed to ensure your program accepts
39
// IETF group parameters. OpenSSL checks the prime
40
// is congruent to 11 when g = 2; while the IETF's
41
// primes are congruent to 23 when g = 2.
42
// Without the test, the IETF parameters would
43
// fail validation. For details, see Diffie-Hellman
44
// Parameter Check (when g = 2, must p mod 24 == 11?).
45
// Mark p < 1024 bits as unsafe.
46
if
(
q_DH_bits
(
dh
)
< 1024)
47
return
false
;
48
49
if
(
q_DH_check
(
dh
,
&status
)
!= 1)
50
return
false
;
51
52
const
BIGNUM *p =
nullptr
;
53
const
BIGNUM *q =
nullptr
;
54
const
BIGNUM *g =
nullptr
;
55
q_DH_get0_pqg
(
dh
,
&p
,
&q
,
&g
)
;
56
57
if
(
q_BN_is_word
(
const_cast
<BIGNUM *>(g)
,
DH_GENERATOR_2
)
) {
58
const
unsigned
long
residue =
q_BN_mod_word
(
p
,
24
)
;
59
if
(residue == 11 || residue == 23)
60
status &= ~DH_NOT_SUITABLE_GENERATOR;
61
}
62
63
bad |= DH_CHECK_P_NOT_PRIME;
64
bad |= DH_CHECK_P_NOT_SAFE_PRIME;
65
bad |= DH_NOT_SUITABLE_GENERATOR;
66
67
return
!(status & bad);
68
}
69
70
}
// unnamed namespace
71
72
#
endif
73
74
int
QTlsBackendOpenSSL::
dhParametersFromDer
(
const
QByteArray &der, QByteArray *derData)
const
75
{
76
#
ifndef
OPENSSL_NO_DEPRECATED_3_0
77
Q_ASSERT(derData);
78
79
if
(der.isEmpty())
80
return
DHParams::InvalidInputDataError;
81
82
const
unsigned
char
*data =
reinterpret_cast
<
const
unsigned
char
*>(der.data());
83
const
int
len = der.size();
84
85
// TLSTODO: check it's needed (loading ciphers and certs in
86
// addition to the library!)
87
QSslSocketPrivate::ensureInitialized();
88
89
DH *dh =
q_d2i_DHparams
(
nullptr
,
&data
,
len
)
;
90
if
(dh) {
91
const
auto
dhRaii = qScopeGuard([dh] {
q_DH_free
(
dh
)
;});
92
93
if
(
isSafeDH
(
dh
)
)
94
*derData = der;
95
else
96
return
DHParams::UnsafeParametersError;
97
}
else
{
98
return
DHParams::InvalidInputDataError;
99
}
100
#
else
101
Q_UNUSED(der);
102
Q_UNUSED(derData);
103
qCWarning(lcTlsBackend,
"Diffie-Hellman parameters are not supported, because OpenSSL v3 was built with deprecated API removed"
);
104
#
endif
105
return
DHParams::NoError;
106
}
107
108
int
QTlsBackendOpenSSL::
dhParametersFromPem
(
const
QByteArray &pem, QByteArray *data)
const
109
{
110
#
ifndef
OPENSSL_NO_DEPRECATED_3_0
111
Q_ASSERT(data);
112
113
if
(pem.isEmpty())
114
return
DHParams::InvalidInputDataError;
115
116
// TLSTODO: check it was not a cargo-cult programming in case of
117
// DH ...
118
QSslSocketPrivate::ensureInitialized();
119
120
BIO *bio = q_BIO_new_mem_buf(
const_cast
<
char
*>(pem.data()), pem.size());
121
if
(!bio)
122
return
DHParams::InvalidInputDataError;
123
124
const
auto
bioRaii = qScopeGuard([bio]
125
{
126
q_BIO_free
(
bio
)
;
127
});
128
129
DH *dh =
nullptr
;
130
q_PEM_read_bio_DHparams
(
bio
,
&dh
,
nullptr
,
nullptr
)
;
131
132
if
(dh) {
133
const
auto
dhGuard = qScopeGuard([dh]
134
{
135
q_DH_free
(
dh
)
;
136
});
137
138
if
(
isSafeDH
(
dh
)
) {
139
char
*buf =
nullptr
;
140
const
int
len =
q_i2d_DHparams
(
dh
,
reinterpret_cast
<
unsigned
char
**>(&buf)
)
;
141
const
auto
freeBuf = qScopeGuard([&] {
q_OPENSSL_free
(buf); });
142
if
(len > 0)
143
data->assign({buf, len});
144
else
145
return
DHParams::InvalidInputDataError;
146
}
else
{
147
return
DHParams::UnsafeParametersError;
148
}
149
}
else
{
150
return
DHParams::InvalidInputDataError;
151
}
152
#
else
153
Q_UNUSED(pem);
154
Q_UNUSED(data);
155
qCWarning(lcTlsBackend,
"Diffie-Hellman parameters are not supported, because OpenSSL v3 was built with deprecated API removed"
);
156
#
endif
157
return
DHParams::NoError;
158
}
159
160
QT_END_NAMESPACE
QTlsBackendOpenSSL::dhParametersFromDer
int dhParametersFromDer(const QByteArray &derData, QByteArray *data) const override
Definition
qssldiffiehellmanparameters_openssl.cpp:74
QTlsBackendOpenSSL::dhParametersFromPem
int dhParametersFromPem(const QByteArray &pemData, QByteArray *data) const override
Definition
qssldiffiehellmanparameters_openssl.cpp:108
QT_BEGIN_NAMESPACE::isSafeDH
bool isSafeDH(DH *dh)
Definition
qssldiffiehellmanparameters_openssl.cpp:25
q_d2i_DHparams
DH * q_d2i_DHparams(DH **a, const unsigned char **pp, long length)
q_DH_check
int q_DH_check(DH *dh, int *codes)
q_DH_free
void q_DH_free(DH *dh)
q_BN_mod_word
BN_ULONG q_BN_mod_word(const BIGNUM *a, BN_ULONG w)
q_i2d_DHparams
int q_i2d_DHparams(DH *a, unsigned char **p)
q_DH_bits
int q_DH_bits(DH *dh)
q_BN_is_word
int q_BN_is_word(BIGNUM *a, BN_ULONG w)
q_PEM_read_bio_DHparams
DH * q_PEM_read_bio_DHparams(BIO *a, DH **b, pem_password_cb *c, void *d)
q_DH_get0_pqg
void q_DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
q_BIO_free
int q_BIO_free(BIO *a)
q_OPENSSL_free
#define q_OPENSSL_free(addr)
Definition
qsslsocket_openssl_symbols_p.h:688
qtbase
src
plugins
tls
openssl
qssldiffiehellmanparameters_openssl.cpp
Generated on
for Qt by
1.18.0