1 /*
2 *
3 * Copyright (C) 2019-2020, OFFIS e.V.
4 * All rights reserved. See COPYRIGHT file for details.
5 *
6 * This software and supporting documentation were developed by
7 *
8 * OFFIS e.V.
9 * R&D Division Health
10 * Escherweg 2
11 * D-26121 Oldenburg, Germany
12 *
13 *
14 * Module: dcmsign
15 *
16 * Author: Marco Eichelberg
17 *
18 * Purpose:
19 * classes: SiTimeStamp
20 *
21 */
22
23 #include "dcmtk/config/osconfig.h"
24
25 #ifdef WITH_OPENSSL
26
27 #include "dcmtk/dcmsign/sitsfs.h"
28 #include "dcmtk/dcmdata/dcerror.h" /* for EC_IllegalCall */
29 #include "dcmtk/dcmdata/dcfilefo.h" /* for class DcmFileFormat */
30 #include "dcmtk/dcmdata/dcdeftag.h" /* for DCM_DigitalSignatureUID */
31
32 BEGIN_EXTERN_C
33 #include <openssl/ts.h>
34 #include <openssl/bio.h>
35 END_EXTERN_C
36
37
38
SiTimeStampFS()39 SiTimeStampFS::SiTimeStampFS()
40 : SiTimeStamp()
41 , tsqFilename_()
42 , tsrFilename_()
43 , uidFilename_()
44 {
45 }
46
47
~SiTimeStampFS()48 SiTimeStampFS::~SiTimeStampFS()
49 {
50 }
51
52
setTSQFilename(const char * fname)53 void SiTimeStampFS::setTSQFilename(const char *fname)
54 {
55 if (fname)
56 tsqFilename_ = fname;
57 else tsqFilename_ = "";
58 }
59
60
setTSRFilename(const char * fname)61 void SiTimeStampFS::setTSRFilename(const char *fname)
62 {
63 if (fname)
64 tsrFilename_ = fname;
65 else tsrFilename_ = "";
66 }
67
68
setUIDFilename(const char * fname)69 void SiTimeStampFS::setUIDFilename(const char *fname)
70 {
71 if (fname)
72 uidFilename_ = fname;
73 else uidFilename_ = "";
74 }
75
76
stamp(const unsigned char * inputData,unsigned long inputDataSize)77 OFCondition SiTimeStampFS::stamp(
78 const unsigned char *inputData,
79 unsigned long inputDataSize)
80 {
81 return create_ts_query(inputData, inputDataSize);
82 }
83
84
write(DcmItem & item)85 OFCondition SiTimeStampFS::write(DcmItem& item)
86 {
87
88 TS_REQ *query = getTSQ();
89 if (query == NULL)
90 {
91 DCMSIGN_ERROR("No timestamp query object available, cannot write to file.");
92 return EC_IllegalCall;
93 }
94
95 OFCondition result = EC_Normal;
96
97 // first we write the time stamp query file
98 if (tsqFilename_.length() == 0)
99 {
100 DCMSIGN_WARN("Name of timestamp query file not set, will not write file.");
101 }
102 else
103 {
104 BIO *out_bio = BIO_new_file(tsqFilename_.c_str(), "wb");
105 if (out_bio == NULL)
106 {
107 DCMSIGN_WARN("Unable to create time stamp query file '" << tsqFilename_ << "'");
108 result = SI_EC_CannotWriteTSQ;
109 }
110 else
111 {
112 if (!i2d_TS_REQ_bio(out_bio, query))
113 {
114 DCMSIGN_WARN("Writing time stamp query file '" << tsqFilename_ << "' failed");
115 result = SI_EC_CannotWriteTSQ;
116 }
117 BIO_free_all(out_bio);
118 }
119 }
120
121 if (result.bad()) return result;
122
123 // now we write the UID file
124 if (uidFilename_.length() == 0)
125 {
126 DCMSIGN_WARN("Name of UID file for time stamp query not set, will not write file.");
127 }
128 else
129 {
130 OFString uid;
131 DcmFileFormat dfile;
132 if (item.findAndGetOFString(DCM_DigitalSignatureUID, uid).good())
133 {
134 result = dfile.getDataset()->putAndInsertString(DCM_DigitalSignatureUID, uid.c_str());
135 if (result.good()) result = dfile.saveFile(uidFilename_, EXS_LittleEndianImplicit);
136 }
137 else
138 {
139 DCMSIGN_ERROR("Signature UID not found in dataset.");
140 result = EC_IllegalCall;
141 }
142 }
143
144 return result;
145 }
146
147
getUIDFromFile(OFString & uid)148 OFCondition SiTimeStampFS::getUIDFromFile(OFString& uid)
149 {
150 if (uidFilename_.length() == 0)
151 {
152 DCMSIGN_ERROR("Cannot load UID file, filename not set");
153 return EC_IllegalCall;
154 }
155
156 DcmFileFormat dfile;
157 OFCondition result = dfile.loadFile(uidFilename_);
158 if (result.good())
159 {
160 result = dfile.getDataset()->findAndGetOFString(DCM_DigitalSignatureUID, uid);
161 if (result.bad()) DCMSIGN_ERROR("No Digital Signature UID found in UID file '" << uidFilename_ << "'");
162 }
163 else
164 {
165 DCMSIGN_ERROR("Cannot load UID file '" << uidFilename_ << "'");
166 }
167
168 return result;
169 }
170
171
load_ts_query_from_file()172 OFCondition SiTimeStampFS::load_ts_query_from_file()
173 {
174 if (tsqFilename_.length() == 0)
175 {
176 DCMSIGN_ERROR("Cannot load timestamp query file, filename not set");
177 return EC_IllegalCall;
178 }
179
180 return SiTimeStamp::load_ts_query(tsqFilename_.c_str());
181 }
182
183
load_ts_response_from_file()184 OFCondition SiTimeStampFS::load_ts_response_from_file()
185 {
186 if (tsrFilename_.length() == 0)
187 {
188 DCMSIGN_ERROR("Cannot load timestamp response file, filename not set");
189 return EC_IllegalCall;
190 }
191
192 return SiTimeStamp::load_ts_response(tsrFilename_.c_str());
193 }
194
195
check_ts_response(DcmItem & ditem)196 OFCondition SiTimeStampFS::check_ts_response(DcmItem& ditem)
197 {
198 if (getTSQ() == NULL)
199 {
200 DCMSIGN_ERROR("Cannot check timestamp response, timestamp query not loaded");
201 return EC_IllegalCall;
202 }
203
204 if (getTSR() == NULL)
205 {
206 DCMSIGN_ERROR("Cannot check timestamp response, not loaded");
207 return EC_IllegalCall;
208 }
209
210 return SiTimeStamp::check_ts_response(getTSQ(), getTSR(), ditem);
211
212 }
213
214
write_ts_token(DcmItem & ditem)215 OFCondition SiTimeStampFS::write_ts_token(DcmItem& ditem)
216 {
217 return SiTimeStamp::write_ts_token(getTSR(), ditem);
218 }
219
220
221
222 #else /* WITH_OPENSSL */
223
224 int sitsfs_cc_dummy_to_keep_linker_from_moaning = 0;
225
226 #endif
227