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 import ocean.transition; 29 30 /******************************************************************************/ 31 32 abstract class MessageDigestCore 33 { 34 import ocean.util.cipher.gcrypt.c.md; 35 import ocean.util.cipher.gcrypt.core.Gcrypt: GcryptException; 36 37 /*************************************************************************** 38 39 libgcrypt message digest context object. 40 41 ***************************************************************************/ 42 43 protected gcry_md_hd_t md; 44 45 /*************************************************************************** 46 47 Constructor. 48 49 Params: 50 algorithm = the hash algorithm to use 51 flags = flags to `gcry_md_open()` 52 53 Throws: 54 `GcryptException` on error. There are two possible error causes: 55 - The parameters are invalid or not supported by the libcrypt 56 of the run-time enviromnent. 57 - libgcrypt failed allocating memory. 58 59 ***************************************************************************/ 60 61 protected this ( gcry_md_algos algorithm, gcry_md_flags flags = cast(gcry_md_flags)0, 62 istring file = __FILE__, int line = __LINE__ ) 63 out 64 { 65 assert(this.md !is null); 66 } 67 body 68 { 69 // `gcry_md_open` sets `this.md = null` on failure. 70 GcryptException.throwNewIfGcryptError( 71 gcry_md_open(&this.md, algorithm, flags), file, line 72 ); 73 } 74 75 /*************************************************************************** 76 77 Destructor; closes the object opened by the constructor. 78 79 ***************************************************************************/ 80 81 ~this ( ) 82 { 83 // `gcry_md_close` ignores `null` so it is safe to call it after 84 // `gcry_md_open()` failed and made the constructor throw. 85 gcry_md_close(this.md); 86 this.md = null; 87 } 88 89 /*************************************************************************** 90 91 Calculates the hash a.k.a. message digest from the input data. 92 93 The length of the returned hash is the return value of 94 `gcry_md_get_algo_dlen(algorithm)` for the algorithm passed to the 95 constructor of this class. 96 97 Params: 98 input_data = data to hash; the elements will be concatenated 99 100 Returns: 101 the resuting hash. 102 103 ***************************************************************************/ 104 105 protected ubyte[] calculate_ ( Const!(ubyte)[][] input_data ) 106 { 107 foreach (chunk; input_data) 108 { 109 gcry_md_write(this.md, chunk.ptr, chunk.length); 110 } 111 112 return gcry_md_read_slice(this.md); 113 } 114 }