Mercurial > hg > orthanc
annotate OrthancFramework/Sources/DicomNetworking/Internals/DicomTls.cpp @ 5853:4d932683049d get-scu tip
very first implementation of C-Get SCU
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Tue, 29 Oct 2024 17:25:49 +0100 |
parents | 343149762476 |
children |
rev | line source |
---|---|
4432 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5640
f7adfb22e20e
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5632
diff
changeset
|
5 * Copyright (C) 2017-2023 Osimis S.A., Belgium |
f7adfb22e20e
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5632
diff
changeset
|
6 * Copyright (C) 2024-2024 Orthanc Team SRL, Belgium |
5485
48b8dae6dc77
upgrade to year 2024
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5185
diff
changeset
|
7 * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium |
4432 | 8 * |
9 * This program is free software: you can redistribute it and/or | |
10 * modify it under the terms of the GNU Lesser General Public License | |
11 * as published by the Free Software Foundation, either version 3 of | |
12 * the License, or (at your option) any later version. | |
13 * | |
14 * This program is distributed in the hope that it will be useful, but | |
15 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * Lesser General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU Lesser General Public | |
20 * License along with this program. If not, see | |
21 * <http://www.gnu.org/licenses/>. | |
22 **/ | |
23 | |
24 | |
25 #include "../../PrecompiledHeaders.h" | |
26 #include "DicomTls.h" | |
27 | |
28 #include "../../Logging.h" | |
29 #include "../../OrthancException.h" | |
30 #include "../../SystemToolbox.h" | |
5643
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
31 #include "../../Toolbox.h" |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
32 #include <openssl/ssl.h> |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
33 #include <openssl/err.h> |
4432 | 34 |
35 #if DCMTK_VERSION_NUMBER < 364 | |
36 # define DCF_Filetype_PEM SSL_FILETYPE_PEM | |
37 # if OPENSSL_VERSION_NUMBER >= 0x0090700fL | |
38 // This seems to correspond to TSP_Profile_AES: https://support.dcmtk.org/docs/tlsciphr_8h.html | |
39 static std::string opt_ciphersuites(TLS1_TXT_RSA_WITH_AES_128_SHA ":" SSL3_TXT_RSA_DES_192_CBC3_SHA); | |
40 # else | |
41 // This seems to correspond to TSP_Profile_Basic in DCMTK >= 3.6.4: https://support.dcmtk.org/docs/tlsciphr_8h.html | |
42 static std::string opt_ciphersuites(SSL3_TXT_RSA_DES_192_CBC3_SHA); | |
43 # endif | |
44 #endif | |
45 | |
46 | |
47 namespace Orthanc | |
48 { | |
49 namespace Internals | |
50 { | |
4997
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
51 #if DCMTK_VERSION_NUMBER >= 367 |
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
52 static bool IsFailure(OFCondition cond) |
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
53 { |
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
54 return !cond.good(); |
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
55 } |
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
56 #else |
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
57 static bool IsFailure(DcmTransportLayerStatus status) |
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
58 { |
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
59 return (status != TCS_ok); |
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
60 } |
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
61 #endif |
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
62 |
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
63 |
5644
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
64 #if DCMTK_VERSION_NUMBER >= 367 |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
65 static OFCondition MyConvertOpenSSLError(unsigned long errorCode, OFBool logAsError) |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
66 { |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
67 return DcmTLSTransportLayer::convertOpenSSLError(errorCode, logAsError); |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
68 } |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
69 #else |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
70 static OFCondition MyConvertOpenSSLError(unsigned long errorCode, OFBool logAsError) |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
71 { |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
72 if (errorCode == 0) |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
73 { |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
74 return EC_Normal; |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
75 } |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
76 else |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
77 { |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
78 const char *err = ERR_reason_error_string(errorCode); |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
79 if (err == NULL) |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
80 { |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
81 err = "OpenSSL error"; |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
82 } |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
83 |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
84 if (logAsError) |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
85 { |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
86 DCMTLS_ERROR("OpenSSL error " << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
87 << STD_NAMESPACE setw(8) << errorCode << ": " << err); |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
88 } |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
89 |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
90 // The "2" below corresponds to the same error code as "DCMTLS_EC_FailedToSetCiphersuites" |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
91 return OFCondition(OFM_dcmtls, 2, OF_error, err); |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
92 } |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
93 } |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
94 #endif |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
95 |
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
96 |
4432 | 97 DcmTLSTransportLayer* InitializeDicomTls(T_ASC_Network *network, |
98 T_ASC_NetworkRole role, | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
99 const std::string& ownPrivateKeyPath, |
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
100 const std::string& ownCertificatePath, |
4656
82a314325351
New configuration option: "DicomTlsRemoteCertificateRequired"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4438
diff
changeset
|
101 const std::string& trustedCertificatesPath, |
5643
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
102 bool requireRemoteCertificate, |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
103 unsigned int minimalTlsVersion, |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
104 const std::set<std::string>& ciphers) |
4432 | 105 { |
106 if (network == NULL) | |
107 { | |
108 throw OrthancException(ErrorCode_NullPointer); | |
109 } | |
110 | |
111 if (role != NET_ACCEPTOR && | |
112 role != NET_REQUESTOR) | |
113 { | |
114 throw OrthancException(ErrorCode_ParameterOutOfRange, "Unknown role"); | |
115 } | |
116 | |
5598
317850cd46bc
fix DicomTlsTrustedCertificates configuration that should not be mandatory if DicomTlsRemoteCertificateRequired is false
Alain Mazy <am@orthanc.team>
parents:
5487
diff
changeset
|
117 if (requireRemoteCertificate && !SystemToolbox::IsRegularFile(trustedCertificatesPath)) |
4432 | 118 { |
119 throw OrthancException(ErrorCode_InexistentFile, "Cannot read file with trusted certificates for DICOM TLS: " + | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
120 trustedCertificatesPath); |
4432 | 121 } |
122 | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
123 if (!SystemToolbox::IsRegularFile(ownPrivateKeyPath)) |
4432 | 124 { |
125 throw OrthancException(ErrorCode_InexistentFile, "Cannot read file with own private key for DICOM TLS: " + | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
126 ownPrivateKeyPath); |
4432 | 127 } |
128 | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
129 if (!SystemToolbox::IsRegularFile(ownCertificatePath)) |
4432 | 130 { |
131 throw OrthancException(ErrorCode_InexistentFile, "Cannot read file with own certificate for DICOM TLS: " + | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
132 ownCertificatePath); |
4432 | 133 } |
134 | |
135 CLOG(INFO, DICOM) << "Initializing DICOM TLS for Orthanc " | |
136 << (role == NET_ACCEPTOR ? "SCP" : "SCU"); | |
137 | |
138 #if DCMTK_VERSION_NUMBER >= 364 | |
139 const T_ASC_NetworkRole tmpRole = role; | |
140 #else | |
141 int tmpRole; | |
142 switch (role) | |
143 { | |
144 case NET_ACCEPTOR: | |
145 tmpRole = DICOM_APPLICATION_ACCEPTOR; | |
146 break; | |
147 | |
148 case NET_REQUESTOR: | |
149 tmpRole = DICOM_APPLICATION_REQUESTOR; | |
150 break; | |
151 | |
152 default: | |
153 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
154 } | |
155 #endif | |
156 | |
157 std::unique_ptr<DcmTLSTransportLayer> tls( | |
158 new DcmTLSTransportLayer(tmpRole /*opt_networkRole*/, NULL /*opt_readSeedFile*/, | |
159 OFFalse /*initializeOpenSSL, done by Orthanc::Toolbox::InitializeOpenSsl()*/)); | |
160 | |
5598
317850cd46bc
fix DicomTlsTrustedCertificates configuration that should not be mandatory if DicomTlsRemoteCertificateRequired is false
Alain Mazy <am@orthanc.team>
parents:
5487
diff
changeset
|
161 if (requireRemoteCertificate && IsFailure(tls->addTrustedCertificateFile(trustedCertificatesPath.c_str(), DCF_Filetype_PEM /*opt_keyFileFormat*/))) |
4432 | 162 { |
163 throw OrthancException(ErrorCode_BadFileFormat, "Cannot parse PEM file with trusted certificates for DICOM TLS: " + | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
164 trustedCertificatesPath); |
4432 | 165 } |
166 | |
4997
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
167 if (IsFailure(tls->setPrivateKeyFile(ownPrivateKeyPath.c_str(), DCF_Filetype_PEM /*opt_keyFileFormat*/))) |
4432 | 168 { |
169 throw OrthancException(ErrorCode_BadFileFormat, "Cannot parse PEM file with private key for DICOM TLS: " + | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
170 ownPrivateKeyPath); |
4432 | 171 } |
172 | |
5487
33f8e180edcf
upgraded static build to dcmtk 3.6.8
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
173 if (IsFailure(tls->setCertificateFile( |
33f8e180edcf
upgraded static build to dcmtk 3.6.8
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
174 ownCertificatePath.c_str(), DCF_Filetype_PEM /*opt_keyFileFormat*/ |
33f8e180edcf
upgraded static build to dcmtk 3.6.8
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
175 #if DCMTK_VERSION_NUMBER >= 368 |
33f8e180edcf
upgraded static build to dcmtk 3.6.8
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
176 /** |
33f8e180edcf
upgraded static build to dcmtk 3.6.8
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
177 * DICOM BCP 195 RFC 8996 TLS Profile, based on RFC 8996 and RFC 9325. |
33f8e180edcf
upgraded static build to dcmtk 3.6.8
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
178 * This profile only negotiates TLS 1.2 or newer, and will not fall back to |
33f8e180edcf
upgraded static build to dcmtk 3.6.8
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
179 * previous TLS versions. It provides the higher security level offered by the |
33f8e180edcf
upgraded static build to dcmtk 3.6.8
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
180 * 2021 revised edition of BCP 195. |
33f8e180edcf
upgraded static build to dcmtk 3.6.8
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
181 **/ |
33f8e180edcf
upgraded static build to dcmtk 3.6.8
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
182 , TSP_Profile_BCP_195_RFC_8996 |
33f8e180edcf
upgraded static build to dcmtk 3.6.8
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
183 #endif |
33f8e180edcf
upgraded static build to dcmtk 3.6.8
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
184 ))) |
4432 | 185 { |
186 throw OrthancException(ErrorCode_BadFileFormat, "Cannot parse PEM file with own certificate for DICOM TLS: " + | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
187 ownCertificatePath); |
4432 | 188 } |
189 | |
190 if (!tls->checkPrivateKeyMatchesCertificate()) | |
191 { | |
192 throw OrthancException(ErrorCode_BadFileFormat, "The private key doesn't match the own certificate: " + | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
193 ownPrivateKeyPath + " vs. " + ownCertificatePath); |
4432 | 194 } |
195 | |
196 #if DCMTK_VERSION_NUMBER >= 364 | |
5643
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
197 if (minimalTlsVersion == 0) // use the default values (same behavior as before 1.12.4) |
4432 | 198 { |
5643
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
199 if (ciphers.size() > 0) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
200 { |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
201 throw OrthancException(ErrorCode_BadFileFormat, "The cipher suites can not be specified when using the default BCP profile"); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
202 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
203 |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
204 if (IsFailure(tls->setTLSProfile(TSP_Profile_BCP195 /*opt_tlsProfile*/))) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
205 { |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
206 throw OrthancException(ErrorCode_InternalError, "Cannot set the DICOM TLS profile"); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
207 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
208 |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
209 if (IsFailure(tls->activateCipherSuites())) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
210 { |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
211 throw OrthancException(ErrorCode_InternalError, "Cannot activate the cipher suites for DICOM TLS"); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
212 } |
4432 | 213 } |
5643
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
214 else |
4432 | 215 { |
5643
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
216 // Fine tune the SSL context |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
217 if (IsFailure(tls->setTLSProfile(TSP_Profile_None))) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
218 { |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
219 throw OrthancException(ErrorCode_InternalError, "Cannot set the DICOM TLS profile"); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
220 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
221 |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
222 DcmTLSTransportLayer::native_handle_type sslNativeHandle = tls->getNativeHandle(); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
223 SSL_CTX_clear_options(sslNativeHandle, SSL_OP_NO_SSL_MASK); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
224 if (minimalTlsVersion > 1) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
225 { |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
226 SSL_CTX_set_options(sslNativeHandle, SSL_OP_NO_SSLv3); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
227 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
228 if (minimalTlsVersion > 2) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
229 { |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
230 SSL_CTX_set_options(sslNativeHandle, SSL_OP_NO_TLSv1); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
231 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
232 if (minimalTlsVersion > 3) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
233 { |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
234 SSL_CTX_set_options(sslNativeHandle, SSL_OP_NO_TLSv1_1); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
235 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
236 if (minimalTlsVersion > 4) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
237 { |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
238 SSL_CTX_set_options(sslNativeHandle, SSL_OP_NO_TLSv1_2); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
239 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
240 |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
241 std::set<std::string> ciphersTls; |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
242 std::set<std::string> ciphersTls13; |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
243 |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
244 // DCMTK 3.8 is missing a method to add TLS13 cipher suite in the DcmTLSTransportLayer interface. |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
245 // And, anyway, since we do not run dcmtkPrepare.cmake, DCMTK is not aware of TLS v1.3 cipher suite names. |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
246 for (std::set<std::string>::const_iterator it = ciphers.begin(); it != ciphers.end(); ++it) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
247 { |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
248 bool isValid = false; |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
249 if (DcmTLSCiphersuiteHandler::lookupCiphersuiteByOpenSSLName(it->c_str()) != DcmTLSCiphersuiteHandler::unknownCipherSuiteIndex) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
250 { |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
251 ciphersTls.insert(it->c_str()); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
252 isValid = true; |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
253 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
254 |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
255 // list of TLS v1.3 ciphers according to https://www.openssl.org/docs/man3.3/man1/openssl-ciphers.html |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
256 if (strstr("TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256", it->c_str()) != NULL) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
257 { |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
258 ciphersTls13.insert(it->c_str()); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
259 isValid = true; |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
260 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
261 |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
262 if (!isValid) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
263 { |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
264 throw OrthancException(ErrorCode_BadFileFormat, "The cipher suite " + *it + " is not recognized as valid cipher suite by OpenSSL "); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
265 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
266 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
267 |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
268 std::string joinedCiphersTls; |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
269 std::string joinedCiphersTls13; |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
270 Toolbox::JoinStrings(joinedCiphersTls, ciphersTls, ":"); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
271 Toolbox::JoinStrings(joinedCiphersTls13, ciphersTls13, ":"); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
272 |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
273 if (joinedCiphersTls.size() > 0 && SSL_CTX_set_cipher_list(sslNativeHandle, joinedCiphersTls.c_str()) != 1) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
274 { |
5644
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
275 OFCondition cond = MyConvertOpenSSLError(ERR_get_error(), OFTrue); |
5643
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
276 throw OrthancException(ErrorCode_InternalError, "Unable to configure cipher suite. OpenSSL error: " + boost::lexical_cast<std::string>(cond.code()) + " - " + cond.text()); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
277 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
278 |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
279 if (joinedCiphersTls13.size() > 0 && SSL_CTX_set_ciphersuites(sslNativeHandle, joinedCiphersTls13.c_str()) != 1) |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
280 { |
5644
343149762476
fix build with DCMTK <= 3.6.6
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5643
diff
changeset
|
281 OFCondition cond = MyConvertOpenSSLError(ERR_get_error(), OFTrue); |
5643
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
282 throw OrthancException(ErrorCode_InternalError, "Unable to configure cipher suite for TLS 1.3. OpenSSL error: " + boost::lexical_cast<std::string>(cond.code()) + " - " + cond.text()); |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
283 } |
b1a18218860c
2 new configurations: DicomTlsMinimumProtocolVersion + DicomTlsCiphersAccepted
Alain Mazy <am@orthanc.team>
parents:
5640
diff
changeset
|
284 |
4432 | 285 } |
286 #else | |
287 CLOG(INFO, DICOM) << "Using the following cipher suites for DICOM TLS: " << opt_ciphersuites; | |
4997
1f93dc290628
fix compatibility with dcmtk 3.6.7
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4870
diff
changeset
|
288 if (IsFailure(tls->setCipherSuites(opt_ciphersuites.c_str()))) |
4432 | 289 { |
290 throw OrthancException(ErrorCode_InternalError, "Unable to set cipher suites to: " + opt_ciphersuites); | |
291 } | |
292 #endif | |
293 | |
4656
82a314325351
New configuration option: "DicomTlsRemoteCertificateRequired"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4438
diff
changeset
|
294 if (requireRemoteCertificate) |
82a314325351
New configuration option: "DicomTlsRemoteCertificateRequired"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4438
diff
changeset
|
295 { |
82a314325351
New configuration option: "DicomTlsRemoteCertificateRequired"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4438
diff
changeset
|
296 // Check remote certificate, fail if no certificate is present |
82a314325351
New configuration option: "DicomTlsRemoteCertificateRequired"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4438
diff
changeset
|
297 tls->setCertificateVerification(DCV_requireCertificate /*opt_certVerification*/); |
82a314325351
New configuration option: "DicomTlsRemoteCertificateRequired"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4438
diff
changeset
|
298 } |
82a314325351
New configuration option: "DicomTlsRemoteCertificateRequired"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4438
diff
changeset
|
299 else |
82a314325351
New configuration option: "DicomTlsRemoteCertificateRequired"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4438
diff
changeset
|
300 { |
5632
cfb67c7ccb4d
DicomTlsRemoteCertificateRequired=false is now equivalent to --ignore-peer-cert DCMTK option instead of --verify-peer-cert
Alain Mazy <am@orthanc.team>
parents:
5598
diff
changeset
|
301 // From 1.12.4, do not even request remote certificate (prior to 1.12.4, we were requesting a certificates, checking it if present and succeeding if not present) |
cfb67c7ccb4d
DicomTlsRemoteCertificateRequired=false is now equivalent to --ignore-peer-cert DCMTK option instead of --verify-peer-cert
Alain Mazy <am@orthanc.team>
parents:
5598
diff
changeset
|
302 tls->setCertificateVerification(DCV_ignoreCertificate /*opt_certVerification*/); |
4656
82a314325351
New configuration option: "DicomTlsRemoteCertificateRequired"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4438
diff
changeset
|
303 } |
4432 | 304 |
305 if (ASC_setTransportLayer(network, tls.get(), 0).bad()) | |
306 { | |
307 throw OrthancException(ErrorCode_InternalError, "Cannot enable DICOM TLS in the Orthanc " + | |
308 std::string(role == NET_ACCEPTOR ? "SCP" : "SCU")); | |
309 } | |
310 | |
311 return tls.release(); | |
312 } | |
313 } | |
314 } |