1 /** 2 * Filters 3 * 4 * Copyright: 5 * (C) 1999-2007 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 module botan.filters.filters; 12 13 public import botan.filters.filter; 14 public import botan.filters.pipe; 15 public import botan.filters.basefilt; 16 public import botan.filters.key_filt; 17 import botan.algo_factory.algo_factory; 18 import botan.block.block_cipher; 19 import botan.stream.stream_cipher; 20 import botan.hash.hash; 21 import botan.mac.mac; 22 23 import botan.libstate.libstate; 24 import botan.algo_base.scan_token; 25 26 import botan.constants; 27 static if (BOTAN_HAS_CODEC_FILTERS) { 28 import botan.filters.b64_filt; 29 import botan.filters.hex_filt; 30 } 31 32 import std.algorithm; 33 34 /** 35 * Stream Cipher Filter 36 */ 37 final class StreamCipherFilter : KeyedFilter, Filterable 38 { 39 public: 40 41 override @property string name() const { return m_cipher.name; } 42 43 /** 44 * Write input data 45 * Params: 46 * input = data 47 * length = length of input in bytes 48 */ 49 override void write(const(ubyte)* input, size_t length) 50 { 51 while (length) 52 { 53 size_t copied = std.algorithm.min(length, m_buffer.length); 54 m_cipher.cipher(input, m_buffer.ptr, copied); 55 send(m_buffer, copied); 56 input += copied; 57 length -= copied; 58 } 59 } 60 61 override bool validIvLength(size_t iv_len) const 62 { return m_cipher.validIvLength(iv_len); } 63 64 /** 65 * Set the initialization vector for this filter. 66 * 67 * Params: 68 * iv = the initialization vector to set 69 */ 70 override void setIv(in InitializationVector iv) 71 { 72 m_cipher.setIv(iv.ptr, iv.length); 73 } 74 75 76 /** 77 * Set the key of this filter. 78 * 79 * Params: 80 * key = the key to set 81 */ 82 override void setKey(in SymmetricKey key) { m_cipher.setKey(key); } 83 84 override KeyLengthSpecification keySpec() const { return m_cipher.keySpec(); } 85 86 /** 87 * Construct a stream cipher filter. 88 * 89 * Params: 90 * stream_cipher = a cipher object to use 91 */ 92 this(StreamCipher stream_cipher) 93 { 94 m_buffer = SecureVector!ubyte(DEFAULT_BUFFERSIZE); 95 m_cipher = stream_cipher; 96 } 97 98 /** 99 * Construct a stream cipher filter. 100 * 101 * Params: 102 * stream_cipher = a cipher object to use 103 * key = the key to use inside this filter 104 */ 105 this(StreamCipher stream_cipher, in SymmetricKey key) 106 { 107 m_buffer = SecureVector!ubyte(DEFAULT_BUFFERSIZE); 108 m_cipher = stream_cipher; 109 m_cipher.setKey(key); 110 } 111 112 /** 113 * Construct a stream cipher filter. 114 * 115 * Params: 116 * sc_name = the name of the desired cipher 117 */ 118 this(in string sc_name) 119 120 { 121 m_buffer = SecureVector!ubyte(DEFAULT_BUFFERSIZE); 122 AlgorithmFactory af = globalState().algorithmFactory(); 123 m_cipher = af.makeStreamCipher(sc_name); 124 } 125 126 /** 127 * Construct a stream cipher filter. 128 * 129 * Params: 130 * sc_name = the name of the desired cipher 131 * key = the key to use inside this filter 132 */ 133 this(in string sc_name, in SymmetricKey key) 134 { 135 m_buffer = SecureVector!ubyte(DEFAULT_BUFFERSIZE); 136 AlgorithmFactory af = globalState().algorithmFactory(); 137 m_cipher = af.makeStreamCipher(sc_name); 138 m_cipher.setKey(key); 139 } 140 141 // Interface fallthrough 142 override bool attachable() { return super.attachable(); } 143 override void startMsg() { super.startMsg(); } 144 override void endMsg() { super.endMsg(); } 145 override void setNext(Filter* filters, size_t sz) { super.setNext(filters, sz); } 146 private: 147 SecureVector!ubyte m_buffer; 148 Unique!StreamCipher m_cipher; 149 } 150 151 /** 152 * Hash Filter. 153 */ 154 final class HashFilter : Filter, Filterable 155 { 156 public: 157 override void write(const(ubyte)* input, size_t len) { m_hash.update(input, len); } 158 159 /* 160 * Complete a calculation by a HashFilter 161 */ 162 override void endMsg() 163 { 164 SecureVector!ubyte output = m_hash.finished(); 165 if (m_OUTPUT_LENGTH) 166 send(output, std.algorithm.min(m_OUTPUT_LENGTH, output.length)); 167 else 168 send(output); 169 } 170 171 override @property string name() const { return m_hash.name; } 172 173 /** 174 * Construct a hash filter. 175 * 176 * Params: 177 * hash_fun = the hash function to use 178 * len = the output length of this filter. Leave the default 179 * value 0 if you want to use the full output of the hashfunction 180 * hash. Otherwise, specify a smaller value here so that the 181 * output of the hash algorithm will be cut off. 182 */ 183 this(HashFunction hash_fun, size_t len = 0) 184 { 185 m_OUTPUT_LENGTH = len; 186 m_hash = hash_fun; 187 } 188 189 /** 190 * Construct a hash filter. 191 * 192 * Params: 193 * algo_spec = the name of the hash algorithm to use 194 * len = the output length of this filter. Leave the default 195 * value 0 if you want to use the full output of the hashfunction 196 * hash. Otherwise, specify a smaller value here so that the 197 * output of the hash algorithm will be cut off. 198 */ 199 this(in string algo_spec, size_t len = 0) 200 { 201 m_OUTPUT_LENGTH = len; 202 AlgorithmFactory af = globalState().algorithmFactory(); 203 m_hash = af.makeHashFunction(algo_spec); 204 } 205 206 ~this() { } 207 208 // Interface fallthrough 209 override bool attachable() { return super.attachable(); } 210 override void startMsg() { super.startMsg(); } 211 override void setNext(Filter* filters, size_t sz) { super.setNext(filters, sz); } 212 private: 213 const size_t m_OUTPUT_LENGTH; 214 Unique!HashFunction m_hash; 215 } 216 217 /** 218 * MessageAuthenticationCode Filter. 219 */ 220 final class MACFilter : KeyedFilter, Filterable 221 { 222 public: 223 override void write(const(ubyte)* input, size_t len) { m_mac.update(input, len); } 224 225 /* 226 * Complete a calculation by a MACFilter 227 */ 228 override void endMsg() 229 { 230 SecureVector!ubyte output = m_mac.finished(); 231 if (m_OUTPUT_LENGTH) 232 send(output, std.algorithm.min(m_OUTPUT_LENGTH, output.length)); 233 else 234 send(output); 235 } 236 237 override @property string name() const { return m_mac.name; } 238 239 /** 240 * Set the key of this filter. 241 * 242 * Params: 243 * key = the key to set 244 */ 245 override void setKey(in SymmetricKey key) { m_mac.setKey(key); } 246 247 override KeyLengthSpecification keySpec() const { return m_mac.keySpec(); } 248 249 override bool validIvLength(size_t length) const { return length == 0; } 250 251 /** 252 * Construct a MAC filter. The MAC key will be left empty. 253 * 254 * Params: 255 * mac_obj = the MAC to use 256 * out_len = the output length of this filter. Leave the default 257 * value 0 if you want to use the full output of the 258 * MAC. Otherwise, specify a smaller value here so that the 259 * output of the MAC will be cut off. 260 */ 261 this(MessageAuthenticationCode mac_obj, size_t out_len = 0) 262 { 263 m_OUTPUT_LENGTH = out_len; 264 m_mac = mac_obj; 265 } 266 267 /** 268 * Construct a MAC filter. 269 * 270 * Params: 271 * mac_obj = the MAC to use 272 * key = the MAC key to use 273 * out_len = the output length of this filter. Leave the default 274 * value 0 if you want to use the full output of the 275 * MAC. Otherwise, specify a smaller value here so that the 276 * output of the MAC will be cut off. 277 */ 278 this(MessageAuthenticationCode mac_obj, in SymmetricKey key, size_t out_len = 0) 279 { 280 m_OUTPUT_LENGTH = out_len; 281 m_mac = mac_obj; 282 m_mac.setKey(key); 283 } 284 285 /** 286 * Construct a MAC filter. The MAC key will be left empty. 287 * 288 * Params: 289 * mac_name = the name of the MAC to use 290 * len = the output length of this filter. Leave the default 291 * value 0 if you want to use the full output of the 292 * MAC. Otherwise, specify a smaller value here so that the 293 * output of the MAC will be cut off. 294 */ 295 this(in string mac_name, size_t len = 0) 296 { 297 m_OUTPUT_LENGTH = len; 298 AlgorithmFactory af = globalState().algorithmFactory(); 299 m_mac = af.makeMac(mac_name); 300 } 301 302 /** 303 * Construct a MAC filter. 304 * 305 * Params: 306 * mac_name = the name of the MAC to use 307 * key = the MAC key to use 308 * len = the output length of this filter. Leave the default 309 * value 0 if you want to use the full output of the 310 * MAC. Otherwise, specify a smaller value here so that the 311 * output of the MAC will be cut off. 312 */ 313 this(in string mac_name, in SymmetricKey key, size_t len = 0) 314 { 315 m_OUTPUT_LENGTH = len; 316 AlgorithmFactory af = globalState().algorithmFactory(); 317 m_mac = af.makeMac(mac_name); 318 m_mac.setKey(key); 319 } 320 321 ~this() { } 322 323 // Interface fallthrough 324 override bool attachable() { return super.attachable(); } 325 override void startMsg() { super.startMsg(); } 326 override void setNext(Filter* filters, size_t sz) { super.setNext(filters, sz); } 327 private: 328 const size_t m_OUTPUT_LENGTH; 329 Unique!MessageAuthenticationCode m_mac; 330 }