BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlde_sha1.h
Go to the documentation of this file.
1/// @file bdlde_sha1.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlde_sha1.h -*-C++-*-
8#ifndef INCLUDED_BDLDE_SHA1
9#define INCLUDED_BDLDE_SHA1
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id$ $CSID$")
13
14/// @defgroup bdlde_sha1 bdlde_sha1
15/// @brief Provide a value-semantic type encoding a message in a SHA-1 digest.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlde
19/// @{
20/// @addtogroup bdlde_sha1
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlde_sha1-purpose"> Purpose</a>
25/// * <a href="#bdlde_sha1-classes"> Classes </a>
26/// * <a href="#bdlde_sha1-description"> Description </a>
27/// * <a href="#bdlde_sha1-security"> Security </a>
28/// * <a href="#bdlde_sha1-usage"> Usage </a>
29/// * <a href="#bdlde_sha1-example-1-basic-usage"> Example 1: Basic Usage </a>
30///
31/// # Purpose {#bdlde_sha1-purpose}
32/// Provide a value-semantic type encoding a message in a SHA-1 digest.
33///
34/// # Classes {#bdlde_sha1-classes}
35///
36/// - bdlde::Sha1: value-semantic type representing a SHA-1 digest
37///
38/// @see bdlde_md5, bdlde_sha2
39///
40/// # Description {#bdlde_sha1-description}
41/// This component provides the class `bdlde::Sha1`, which
42/// implements a mechanism for computing and updating a SHA-1 digest (a
43/// cryptographic hash). The specification for this is based on FIPS-180, which
44/// can be found at
45/// @code
46/// https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
47/// @endcode
48///
49/// Note that a SHA-1 digest does not aid in error correction.
50///
51/// ## Security {#bdlde_sha1-security}
52///
53///
54/// Practical collision and chosen-prefix collision attacks are known against
55/// SHA-1. Do not use SHA-1 to generate digital signatures under any
56/// circumstances, and do not use SHA-1 at all except when it is required for
57/// interoperation with legacy systems that use SHA-1. SHA-2 (available in the
58/// @ref bdlde_sha2 component) and SHA-3 are more secure alternatives to SHA-1.
59///
60/// You might think that your application doesn't require collision resistance.
61/// However, (1) you might be mistaken, (2) once you start using SHA-1, you
62/// prevent future versions of your application from being able to rely on
63/// collision resistance unless they break backward compatibility, (3) a
64/// maintainer of your application might accidentally make a change that
65/// implicitly assumes collision resistance, and (4) if you expose SHA-1 hashes
66/// to your users, they might assume that they are secure digital signatures,
67/// which will make their applications insecure. In light of the foregoing
68/// considerations, and the availability of SHA-2 and SHA-3 as alternatives,
69/// there is no justification for using SHA-1 unless you absolutely have to.
70///
71/// ## Usage {#bdlde_sha1-usage}
72///
73///
74/// This section illustrates intended use of this component.
75///
76/// ### Example 1: Basic Usage {#bdlde_sha1-example-1-basic-usage}
77///
78///
79/// The `validatePassword` function below returns whether a specified password
80/// has a specified hash value. The `assertPasswordIsExpected` function below
81/// has a sample password to hash and a hash value that matches it. Note that
82/// the output of `loadDigest` is a binary representation. When hashes are
83/// displayed for human consumption, they are typically converted to hex, but
84/// that would create unnecessary overhead here. Also note that because SHA-1
85/// digests are inexpensive to compute, they are vulnerable to brute force
86/// attacks and should not be used for password hashing in real-world
87/// applications. A function like `validatePassword` must only be used to
88/// validate passwords against previously computed SHA-1 hashes, and only during
89/// a transition period to a more secure password hashing function.
90/// @code
91/// /// Return `true` if the specified `password` concatenated with the
92/// /// specified `salt` has a SHA-1 hash equal to the specified `expected`,
93/// /// and `false` otherwise.
94/// bool validatePassword(const bsl::string_view& password,
95/// const bsl::string_view& salt,
96/// const unsigned char *expected)
97/// {
98/// bdlde::Sha1 hasher;
99/// hasher.update(password.data(), password.length());
100/// hasher.update(salt.data(), salt.length());
101///
102/// unsigned char digest[bdlde::Sha1::k_DIGEST_SIZE];
103/// hasher.loadDigest(digest);
104/// return bsl::equal(bsl::begin(digest), bsl::end(digest), expected);
105/// }
106///
107/// /// Asserts that the constant string `pass` salted with `word` has the
108/// /// expected hash value. In a real application, the expected hash would
109/// /// likely come from some sort of database.
110/// void assertPasswordIsExpected()
111/// {
112/// const bsl::string password = "pass";
113/// const bsl::string salt = "word";
114/// const unsigned char expected[bdlde::Sha1::k_DIGEST_SIZE] = {
115/// 0x5B, 0xAA, 0x61, 0xE4, 0xC9, 0xB9, 0x3F, 0x3F, 0x06, 0x82,
116/// 0x25, 0x0B, 0x6C, 0xF8, 0x33, 0x1B, 0x7E, 0xE6, 0x8F, 0xD8
117/// };
118///
119/// ASSERT(validatePassword(password, salt, expected));
120/// }
121/// @endcode
122/// @}
123/** @} */
124/** @} */
125
126/** @addtogroup bdl
127 * @{
128 */
129/** @addtogroup bdlde
130 * @{
131 */
132/** @addtogroup bdlde_sha1
133 * @{
134 */
135
136#include <bdlscm_version.h>
137
138#include <bsl_cstddef.h>
139#include <bsl_cstdint.h>
140#include <bsl_iosfwd.h>
141
142
143namespace bdlde {
144
145 // ==========
146 // class Sha1
147 // ==========
148
149/// This `class` represents a SHA-1 digest that can be updated as additional
150/// data is provided.
151///
152/// More generally, this class supports a complete set of *value*
153/// *semantic* operations, including copy construction, assignment, equality
154/// comparison, and `ostream` printing. (A precise operational definition
155/// of when two instances have the same value can be found in the
156/// description of `operator==` for the class.) This container is
157/// *exception* *neutral* with no guarantee of rollback: if an exception is
158/// thrown during the invocation of a method on a pre-existing instance, the
159/// class is left in a valid state, but its value is undefined. In no event
160/// is memory leaked. Finally, *aliasing* (e.g., using all or part of an
161/// object as both source and destination) is supported in all cases.
162///
163/// See @ref bdlde_sha1
164class Sha1 {
165
166 // PRIVATE TYPES
167
168 /// Alias for the word type of the SHA-1 algorithm.
169 typedef bsl::uint32_t Word;
170
171 /// Alias for the internal state type of the SHA-1 algorithm, an array
172 /// of 5 words that is updated after each message block is ingested and
173 /// eventually converted into the 160-bit message digest.
174 typedef Word State[5];
175
176 // CLASS DATA
177
178 // Size (in bytes) of the blocks into which the message is divided
179 // before being ingested into the SHA-1 state.
180 static const bsl::size_t k_BLOCK_SIZE = 512 / 8;
181
182 // DATA
183 bsl::uint64_t d_totalSize; // length of the entire message in bytes
184
185 bsl::uint64_t d_bufferSize; // bytes currently used for 'd_buffer'
186
187 // buffer for storing remaining part of message that is not yet
188 // incorporated into `d_state`
189 unsigned char d_buffer[k_BLOCK_SIZE];
190
191 State d_state; // current state of the SHA-1 algorithm
192 // instance represented by this 'Sha1' object
193
194 // FRIENDS
195 friend bool operator==(const Sha1&, const Sha1&);
196
197 public:
198 // PUBLIC CLASS DATA
199
200 /// The size (in bytes) of the output
201 static const bsl::size_t k_DIGEST_SIZE = 160 / 8;
202
203 // CREATORS
204
205 /// Construct a SHA-1 digest having the value corresponding to no data
206 /// having been provided.
208
209 /// Construct a SHA-1 digest corresponding to the specified `data`
210 /// having the specified `length` (in bytes). Note that if `data` is
211 /// null, then `length` must be 0.
212 Sha1(const void *data, bsl::size_t length);
213
214 // MANIPULATORS
215
216 /// Load the current value of this SHA-1 digest into the specified
217 /// `result` and reset this `Sha1` object to the default-constructed
218 /// state.
219 void loadDigestAndReset(unsigned char *result);
220
221 /// Reset the value of this SHA-1 digest to the value provided by the
222 /// default constructor.
223 void reset();
224
225 /// Update the value of this SHA-1 digest to incorporate the specified
226 /// `data` having the specified `length` in bytes. If the current
227 /// state is the default state, the resultant value of this SHA-1
228 /// digest is the application of the SHA-1 algorithm upon the currently
229 /// given `data` of the given `length`. If this digest has been
230 /// previously provided data and has not been subsequently reset, the
231 /// current state is not the default state and the resultant value is
232 /// equivalent to applying the SHA-1 algorithm upon the concatenation of
233 /// all the provided data. The behavior is undefined unless the range
234 /// `[data, data + length)` is a valid range. Note that if `data` is
235 /// null, then `length` must be 0.
236 void update(const void *data, bsl::size_t length);
237
238 // ACCESSORS
239
240 /// Load the current value of this SHA-1 digest into the specified
241 /// `result`.
242 void loadDigest(unsigned char *result) const;
243
244 /// Format the current value of this SHA-1 digest to the specified
245 /// output `stream` and return a reference to the modifiable `stream`.
246 bsl::ostream& print(bsl::ostream& stream) const;
247};
248
249// FREE OPERATORS
250
251/// Return `true` if the specified `lhs` and `rhs` SHA-1 digests have the
252/// same value, and `false` otherwise. Two digests have the same value if,
253/// after applying any number of equivalent updates to both (possibly
254/// including no updates), the values obtained from their respective
255/// `loadDigest` methods are identical.
256bool operator==(const Sha1& lhs, const Sha1& rhs);
257
258/// Return `true` if the specified `lhs` and `rhs` SHA-1 digests do not have
259/// the same value, and `false` otherwise. Two digests do not have the same
260/// value if there exists a set of updates (possibly including the empty
261/// set) that, if applied to both, lead to different values being obtained
262/// from their respective `loadDigest` methods.
263inline
264bool operator!=(const Sha1& lhs, const Sha1& rhs);
265
266/// Write to the specified output `stream` the specified SHA-1 `digest` and
267/// return a reference to the modifiable `stream`.
268inline
269bsl::ostream& operator<<(bsl::ostream& stream, const Sha1& digest);
270
271// ============================================================================
272// INLINE DEFINITIONS
273// ============================================================================
274
275} // close package namespace
276
277// FREE OPERATORS
278inline
279bool bdlde::operator!=(const Sha1& lhs, const Sha1& rhs)
280{
281 return !(lhs == rhs);
282}
283
284inline
285bsl::ostream& bdlde::operator<<(bsl::ostream& stream, const Sha1& digest)
286{
287 return digest.print(stream);
288}
289
290
291
292#endif
293
294// ----------------------------------------------------------------------------
295// Copyright 2022 Bloomberg Finance L.P.
296//
297// Licensed under the Apache License, Version 2.0 (the "License");
298// you may not use this file except in compliance with the License.
299// You may obtain a copy of the License at
300//
301// http://www.apache.org/licenses/LICENSE-2.0
302//
303// Unless required by applicable law or agreed to in writing, software
304// distributed under the License is distributed on an "AS IS" BASIS,
305// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
306// See the License for the specific language governing permissions and
307// limitations under the License.
308// ----------------------------- END-OF-FILE ----------------------------------
309
310/** @} */
311/** @} */
312/** @} */
Definition bdlde_sha1.h:164
friend bool operator==(const Sha1 &, const Sha1 &)
void loadDigestAndReset(unsigned char *result)
static const bsl::size_t k_DIGEST_SIZE
The size (in bytes) of the output.
Definition bdlde_sha1.h:201
bsl::ostream & print(bsl::ostream &stream) const
void loadDigest(unsigned char *result) const
void update(const void *data, bsl::size_t length)
Sha1(const void *data, bsl::size_t length)
void reset()
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlde_base64alphabet.h:118
bool operator!=(const Base64DecoderOptions &lhs, const Base64DecoderOptions &rhs)
bsl::ostream & operator<<(bsl::ostream &stream, Base64Alphabet::Enum value)