1 /* 2 * 3 * Copyright (C) 1998-2019, 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: SiMACConstructor 20 * 21 */ 22 23 #ifndef SIMACCON_H 24 #define SIMACCON_H 25 26 #include "dcmtk/config/osconfig.h" 27 28 #ifdef WITH_OPENSSL 29 30 #include "dcmtk/dcmsign/sitypes.h" 31 #include "dcmtk/dcmdata/dcostrmb.h" /* for DcmOutputBufferStream */ 32 #include "dcmtk/dcmdata/dcxfer.h" /* for E_TransferSyntax */ 33 #include "dcmtk/dcmdata/dcdeftag.h" 34 35 #define INCLUDE_CSTDIO 36 #include "dcmtk/ofstd/ofstdinc.h" 37 38 class SiMAC; 39 class DcmItem; 40 class DcmElement; 41 class DcmAttributeTag; 42 43 /** a class that allows to feed selected parts of a DICOM dataset into the MAC generation code 44 * @remark this class is only available if DCMTK is compiled with 45 * OpenSSL support enabled. 46 */ 47 class DCMTK_DCMSIGN_EXPORT SiMACConstructor 48 { 49 public: 50 51 /// constructor 52 SiMACConstructor(); 53 54 /// destructor 55 virtual ~SiMACConstructor(); 56 57 /** encodes a DICOM dataset (or parts of it) as a byte stream in the format 58 * required for DICOM digital signatures and feeds the byte stream into 59 * the given MAC codec. 60 * If a dump file was set with setDumpFile(), the byte stream is written 61 * to file as well. 62 * @param item the DICOM dataset to be encoded 63 * @param mac the MAC codec into which the resulting byte stream is fed 64 * @param oxfer the transfer syntax to be used when encoding the dataset. 65 * The caller might wish to use DcmItem::canWriteXfer() to check beforehand 66 * whether this transfer syntax can be used. 67 * @param tagListOut upon return this parameter contains the list of attribute 68 * tags which were fed into the MAC codec. For sequences, only the sequence 69 * attribute tag is contained in this list; the items and elements within the items 70 * are not encoded. 71 * @param tagListIn optional parameter restricting the parts of the dataset 72 * to be encoded. Only elements which are present in this list of tags, 73 * which are signable (see DcmTagKey::isSignable()) and are present in the dataset 74 * are encoded. Upon verification of a signature the caller might wish to compare 75 * tagListIn and tagListOut after successful return to see whether the lists of 76 * attributes are the same. 77 * If parameter is absent or NULL, a global match is assumed, i.e. all elements 78 * of the dataset which are present and signable are encoded. 79 * @return status code 80 */ 81 OFCondition encodeDataset( 82 DcmItem& item, 83 SiMAC& mac, 84 E_TransferSyntax oxfer, 85 DcmAttributeTag &tagListOut, 86 DcmAttributeTag *tagListIn = NULL); 87 88 /** encodes a DICOM dataset (or parts of it) as a byte stream in the format 89 * required for DICOM digital signatures and feeds the byte stream into 90 * the given MAC codec, for the purpose of signature verification 91 * If a dump file was set with setDumpFile(), the byte stream is written 92 * to file as well. 93 * @param item the DICOM dataset to be encoded 94 * @param mac the MAC codec into which the resulting byte stream is fed 95 * @param oxfer the transfer syntax to be used when encoding the dataset. 96 * The caller might wish to use DcmItem::canWriteXfer() to check beforehand 97 * whether this transfer syntax can be used. 98 * @param tagListIn list of elements to be encoded. 99 * @return status code 100 */ 101 OFCondition encodeDatasetForVerification( 102 DcmItem& item, 103 SiMAC& mac, 104 E_TransferSyntax oxfer, 105 DcmAttributeTag *tagListIn); 106 107 /** encodes the contents of the digital signature sequence 108 * except CertificateOfSigner, Signature, CertifiedTimestampType 109 * and CertifiedTimestamp as a byte stream in the format 110 * required for DICOM digital signatures and feeds the byte stream into 111 * the given MAC codec. 112 * If a dump file was set with setDumpFile(), the byte stream is written 113 * to file as well. 114 * @param signatureItem the DICOM digital signature item to be encoded 115 * @param mac the MAC codec into which the resulting byte stream is fed 116 * @param oxfer the transfer syntax to be used when encoding the dataset. 117 * The caller might wish to use DcmItem::canWriteXfer() to check beforehand 118 * whether this transfer syntax can be used. 119 * @return status code 120 */ 121 OFCondition encodeDigitalSignatureItem( 122 DcmItem& signatureItem, 123 SiMAC& mac, 124 E_TransferSyntax oxfer); 125 126 /** flushes all buffers inside this object, finalizing the MAC code 127 * @param mac the MAC codec into which the resulting byte stream is fed 128 * @return status code 129 */ 130 OFCondition flush(SiMAC& mac); 131 132 /** dump all data that is fed into the MAC algorithm into the given file, 133 * which must be opened and closed by caller. 134 * @param f pointer to file already opened for writing; may be NULL. 135 */ 136 void setDumpFile(FILE *f); 137 138 private: 139 140 /// private undefined copy constructor 141 SiMACConstructor(SiMACConstructor& arg); 142 143 /// private undefined copy assignment operator 144 SiMACConstructor& operator=(SiMACConstructor& arg); 145 146 /** flushes the internal buffer to the given MAC and to dumpFile if open 147 * @param mac MAC to which the buffer content is added 148 * @return error code from MAC 149 */ 150 OFCondition flushBuffer(SiMAC& mac); 151 152 /** feeds a DcmElement into the MAC data stream if is signable. 153 * If the element is a sequence, all signable elements from all items are added. 154 * @param element pointer to element, must not be NULL 155 * @param mac MAC to use 156 * @param oxfer transfer syntax in which data is encoded 157 * @return status code 158 */ 159 OFCondition encodeElement(DcmElement *element, SiMAC& mac, E_TransferSyntax oxfer); 160 161 /** checks whether the attribute tag of the given DcmElement is contained 162 * in the given list of tags. If the list is absent (NULL), a universal match 163 * is assumed, i.e. always returns true if element is nonzero. 164 * Does not check whether an element is signable. 165 * @param element pointer to element to check 166 * @param tagList pointer to list of attribute tags, may be NULL 167 * @return true if attribute is in tag list, false otherwise 168 */ 169 static OFBool inTagList(const DcmElement *element, DcmAttributeTag *tagList); 170 171 /// the buffer to which data is written 172 unsigned char *buf; 173 174 /// the internal buffer stream 175 DcmOutputBufferStream stream; 176 177 /** if nonzero, the data fed to the MAC algorithm 178 * is also stored in this file. 179 */ 180 FILE *dumpFile; 181 }; 182 183 184 #endif 185 #endif 186