1 /******************************************************************************* 2 3 The core of the libgcrypt message digest classes. 4 5 Be aware that not all versions of libcgrypt support all hash algorithms; the 6 constructor will throw if the specified algorithm is not supported by the 7 run-time version of libgcrypt. However, if the constructor does not throw, 8 it is safe to assume it will never throw for the same set of parameters 9 (except for the fatal situation that libgcrypt failed allocating memory). 10 11 Requires linking with libgcrypt: 12 -L-lgcrypt 13 14 Copyright: 15 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 16 All rights reserved. 17 18 License: 19 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 20 Alternatively, this file may be distributed under the terms of the Tango 21 3-Clause BSD License (see LICENSE_BSD.txt for details). 22 23 *******************************************************************************/ 24 25 module ocean.util.cipher.gcrypt.core.MessageDigestCore; 26 27 28 /******************************************************************************/ 29 30 abstract class MessageDigestCore 31 { 32 import ocean.util.cipher.gcrypt.c.md; 33 import ocean.util.cipher.gcrypt.core.Gcrypt: GcryptException; 34 35 /*************************************************************************** 36 37 libgcrypt message digest context object. 38 39 ***************************************************************************/ 40 41 protected gcry_md_hd_t md; 42 43 /*************************************************************************** 44 45 Constructor. 46 47 Params: 48 algorithm = the hash algorithm to use 49 flags = flags to `gcry_md_open()` 50 51 Throws: 52 `GcryptException` on error. There are two possible error causes: 53 - The parameters are invalid or not supported by the libcrypt 54 of the run-time enviromnent. 55 - libgcrypt failed allocating memory. 56 57 ***************************************************************************/ 58 59 protected this ( gcry_md_algos algorithm, gcry_md_flags flags = cast(gcry_md_flags)0, 60 string file = __FILE__, int line = __LINE__ ) 61 out 62 { 63 assert(this.md !is null); 64 } 65 do 66 { 67 // `gcry_md_open` sets `this.md = null` on failure. 68 GcryptException.throwNewIfGcryptError( 69 gcry_md_open(&this.md, algorithm, flags), file, line 70 ); 71 } 72 73 /*************************************************************************** 74 75 Destructor; closes the object opened by the constructor. 76 77 ***************************************************************************/ 78 79 ~this ( ) 80 { 81 // `gcry_md_close` ignores `null` so it is safe to call it after 82 // `gcry_md_open()` failed and made the constructor throw. 83 gcry_md_close(this.md); 84 this.md = null; 85 } 86 87 /*************************************************************************** 88 89 Calculates the hash a.k.a. message digest from the input data. 90 91 The length of the returned hash is the return value of 92 `gcry_md_get_algo_dlen(algorithm)` for the algorithm passed to the 93 constructor of this class. 94 95 Params: 96 input_data = data to hash; the elements will be concatenated 97 98 Returns: 99 the resuting hash. 100 101 ***************************************************************************/ 102 103 protected ubyte[] calculate_ ( const(ubyte)[][] input_data ) 104 { 105 foreach (chunk; input_data) 106 { 107 gcry_md_write(this.md, chunk.ptr, chunk.length); 108 } 109 110 return gcry_md_read_slice(this.md); 111 } 112 }