Mercurial > hg > orthanc
annotate OrthancFramework/Sources/DicomNetworking/Internals/DicomTls.cpp @ 4518:cb8fcecf1b02
new option "Timeout" in "DicomModalities" to set DICOM SCU timeout on a per-modality basis
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 22 Feb 2021 16:32:11 +0100 |
parents | 4a4e33c9082d |
children | 82a314325351 |
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 | |
4437
d9473bd5ed43
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4432
diff
changeset
|
5 * Copyright (C) 2017-2021 Osimis S.A., Belgium |
4432 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with this program. If not, see | |
19 * <http://www.gnu.org/licenses/>. | |
20 **/ | |
21 | |
22 | |
23 #include "../../PrecompiledHeaders.h" | |
24 #include "DicomTls.h" | |
25 | |
26 #include "../../Logging.h" | |
27 #include "../../OrthancException.h" | |
28 #include "../../SystemToolbox.h" | |
29 | |
30 | |
31 #if DCMTK_VERSION_NUMBER < 364 | |
32 # define DCF_Filetype_PEM SSL_FILETYPE_PEM | |
33 # if OPENSSL_VERSION_NUMBER >= 0x0090700fL | |
34 // This seems to correspond to TSP_Profile_AES: https://support.dcmtk.org/docs/tlsciphr_8h.html | |
35 static std::string opt_ciphersuites(TLS1_TXT_RSA_WITH_AES_128_SHA ":" SSL3_TXT_RSA_DES_192_CBC3_SHA); | |
36 # else | |
37 // This seems to correspond to TSP_Profile_Basic in DCMTK >= 3.6.4: https://support.dcmtk.org/docs/tlsciphr_8h.html | |
38 static std::string opt_ciphersuites(SSL3_TXT_RSA_DES_192_CBC3_SHA); | |
39 # endif | |
40 #endif | |
41 | |
42 | |
43 namespace Orthanc | |
44 { | |
45 namespace Internals | |
46 { | |
47 DcmTLSTransportLayer* InitializeDicomTls(T_ASC_Network *network, | |
48 T_ASC_NetworkRole role, | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
49 const std::string& ownPrivateKeyPath, |
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
50 const std::string& ownCertificatePath, |
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
51 const std::string& trustedCertificatesPath) |
4432 | 52 { |
53 if (network == NULL) | |
54 { | |
55 throw OrthancException(ErrorCode_NullPointer); | |
56 } | |
57 | |
58 if (role != NET_ACCEPTOR && | |
59 role != NET_REQUESTOR) | |
60 { | |
61 throw OrthancException(ErrorCode_ParameterOutOfRange, "Unknown role"); | |
62 } | |
63 | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
64 if (!SystemToolbox::IsRegularFile(trustedCertificatesPath)) |
4432 | 65 { |
66 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
|
67 trustedCertificatesPath); |
4432 | 68 } |
69 | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
70 if (!SystemToolbox::IsRegularFile(ownPrivateKeyPath)) |
4432 | 71 { |
72 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
|
73 ownPrivateKeyPath); |
4432 | 74 } |
75 | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
76 if (!SystemToolbox::IsRegularFile(ownCertificatePath)) |
4432 | 77 { |
78 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
|
79 ownCertificatePath); |
4432 | 80 } |
81 | |
82 CLOG(INFO, DICOM) << "Initializing DICOM TLS for Orthanc " | |
83 << (role == NET_ACCEPTOR ? "SCP" : "SCU"); | |
84 | |
85 #if DCMTK_VERSION_NUMBER >= 364 | |
86 const T_ASC_NetworkRole tmpRole = role; | |
87 #else | |
88 int tmpRole; | |
89 switch (role) | |
90 { | |
91 case NET_ACCEPTOR: | |
92 tmpRole = DICOM_APPLICATION_ACCEPTOR; | |
93 break; | |
94 | |
95 case NET_REQUESTOR: | |
96 tmpRole = DICOM_APPLICATION_REQUESTOR; | |
97 break; | |
98 | |
99 default: | |
100 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
101 } | |
102 #endif | |
103 | |
104 std::unique_ptr<DcmTLSTransportLayer> tls( | |
105 new DcmTLSTransportLayer(tmpRole /*opt_networkRole*/, NULL /*opt_readSeedFile*/, | |
106 OFFalse /*initializeOpenSSL, done by Orthanc::Toolbox::InitializeOpenSsl()*/)); | |
107 | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
108 if (tls->addTrustedCertificateFile(trustedCertificatesPath.c_str(), DCF_Filetype_PEM /*opt_keyFileFormat*/) != TCS_ok) |
4432 | 109 { |
110 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
|
111 trustedCertificatesPath); |
4432 | 112 } |
113 | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
114 if (tls->setPrivateKeyFile(ownPrivateKeyPath.c_str(), DCF_Filetype_PEM /*opt_keyFileFormat*/) != TCS_ok) |
4432 | 115 { |
116 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
|
117 ownPrivateKeyPath); |
4432 | 118 } |
119 | |
4438
4a4e33c9082d
configuration options for DICOM TLS in Orthanc SCU
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
120 if (tls->setCertificateFile(ownCertificatePath.c_str(), DCF_Filetype_PEM /*opt_keyFileFormat*/) != TCS_ok) |
4432 | 121 { |
122 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
|
123 ownCertificatePath); |
4432 | 124 } |
125 | |
126 if (!tls->checkPrivateKeyMatchesCertificate()) | |
127 { | |
128 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
|
129 ownPrivateKeyPath + " vs. " + ownCertificatePath); |
4432 | 130 } |
131 | |
132 #if DCMTK_VERSION_NUMBER >= 364 | |
133 if (tls->setTLSProfile(TSP_Profile_BCP195 /*opt_tlsProfile*/) != TCS_ok) | |
134 { | |
135 throw OrthancException(ErrorCode_InternalError, "Cannot set the DICOM TLS profile"); | |
136 } | |
137 | |
138 if (tls->activateCipherSuites()) | |
139 { | |
140 throw OrthancException(ErrorCode_InternalError, "Cannot activate the cipher suites for DICOM TLS"); | |
141 } | |
142 #else | |
143 CLOG(INFO, DICOM) << "Using the following cipher suites for DICOM TLS: " << opt_ciphersuites; | |
144 if (tls->setCipherSuites(opt_ciphersuites.c_str()) != TCS_ok) | |
145 { | |
146 throw OrthancException(ErrorCode_InternalError, "Unable to set cipher suites to: " + opt_ciphersuites); | |
147 } | |
148 #endif | |
149 | |
150 tls->setCertificateVerification(DCV_requireCertificate /*opt_certVerification*/); | |
151 | |
152 if (ASC_setTransportLayer(network, tls.get(), 0).bad()) | |
153 { | |
154 throw OrthancException(ErrorCode_InternalError, "Cannot enable DICOM TLS in the Orthanc " + | |
155 std::string(role == NET_ACCEPTOR ? "SCP" : "SCU")); | |
156 } | |
157 | |
158 return tls.release(); | |
159 } | |
160 } | |
161 } |