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 }