1/**
2 * @copyright
3 * ====================================================================
4 *    Licensed to the Apache Software Foundation (ASF) under one
5 *    or more contributor license agreements.  See the NOTICE file
6 *    distributed with this work for additional information
7 *    regarding copyright ownership.  The ASF licenses this file
8 *    to you under the Apache License, Version 2.0 (the
9 *    "License"); you may not use this file except in compliance
10 *    with the License.  You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 *    Unless required by applicable law or agreed to in writing,
15 *    software distributed under the License is distributed on an
16 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 *    KIND, either express or implied.  See the License for the
18 *    specific language governing permissions and limitations
19 *    under the License.
20 * ====================================================================
21 * @endcopyright
22 *
23 * @file svn_checksum.h
24 * @brief Subversion checksum routines
25 */
26
27#ifndef SVN_CHECKSUM_H
28#define SVN_CHECKSUM_H
29
30#include <apr.h>        /* for apr_size_t */
31#include <apr_pools.h>  /* for apr_pool_t */
32
33#include "svn_types.h"  /* for svn_boolean_t, svn_error_t */
34
35#ifdef __cplusplus
36extern "C" {
37#endif /* __cplusplus */
38
39
40/**
41 * Various types of checksums.
42 *
43 * @since New in 1.6.
44 */
45typedef enum svn_checksum_kind_t
46{
47  /** The checksum is (or should be set to) an MD5 checksum. */
48  svn_checksum_md5,
49
50  /** The checksum is (or should be set to) a SHA1 checksum. */
51  svn_checksum_sha1,
52
53  /** The checksum is (or should be set to) a FNV-1a 32 bit checksum,
54   * in big endian byte order.
55   * @since New in 1.9. */
56  svn_checksum_fnv1a_32,
57
58  /** The checksum is (or should be set to) a modified FNV-1a 32 bit,
59   * in big endian byte order.
60   * @since New in 1.9. */
61  svn_checksum_fnv1a_32x4
62} svn_checksum_kind_t;
63
64/**
65 * A generic checksum representation.
66 *
67 * @since New in 1.6.
68 */
69typedef struct svn_checksum_t
70{
71  /** The bytes of the checksum. */
72  const unsigned char *digest;
73
74  /** The type of the checksum.  This should never be changed by consumers
75      of the APIs. */
76  svn_checksum_kind_t kind;
77} svn_checksum_t;
78
79/**
80 * Opaque type for creating checksums of data.
81 */
82typedef struct svn_checksum_ctx_t svn_checksum_ctx_t;
83
84/** Return a new checksum structure of type @a kind, initialized to the all-
85 * zeros value, allocated in @a pool.
86 *
87 * @since New in 1.6.
88 */
89svn_checksum_t *
90svn_checksum_create(svn_checksum_kind_t kind,
91                    apr_pool_t *pool);
92
93/** Set @a checksum->digest to all zeros, which, by convention, matches
94 * all other checksums.
95 *
96 * @since New in 1.6.
97 */
98svn_error_t *
99svn_checksum_clear(svn_checksum_t *checksum);
100
101/** Compare checksums @a checksum1 and @a checksum2.  If their kinds do not
102 * match or if neither is all zeros, and their content does not match, then
103 * return FALSE; else return TRUE.
104 *
105 * @since New in 1.6.
106 */
107svn_boolean_t
108svn_checksum_match(const svn_checksum_t *checksum1,
109                   const svn_checksum_t *checksum2);
110
111
112/**
113 * Return a deep copy of @a checksum, allocated in @a pool.  If @a
114 * checksum is NULL then NULL is returned.
115 *
116 * @since New in 1.6.
117 */
118svn_checksum_t *
119svn_checksum_dup(const svn_checksum_t *checksum,
120                 apr_pool_t *pool);
121
122
123/** Return the hex representation of @a checksum, allocating the string
124 * in @a pool.
125 *
126 * @since New in 1.6.
127 */
128const char *
129svn_checksum_to_cstring_display(const svn_checksum_t *checksum,
130                                apr_pool_t *pool);
131
132
133/** Return the hex representation of @a checksum, allocating the
134 * string in @a pool.  If @a checksum->digest is all zeros (that is,
135 * 0, not '0') then return NULL. In 1.7+, @a checksum may be NULL
136 * and NULL will be returned in that case.
137 *
138 * @since New in 1.6.
139 * @note Passing NULL for @a checksum in 1.6 will cause a segfault.
140 */
141const char *
142svn_checksum_to_cstring(const svn_checksum_t *checksum,
143                        apr_pool_t *pool);
144
145
146/** Return a serialized representation of @a checksum, allocated in
147 * @a result_pool. Temporary allocations are performed in @a scratch_pool.
148 *
149 * Note that @a checksum may not be NULL.
150 *
151 * @since New in 1.7.
152 */
153const char *
154svn_checksum_serialize(const svn_checksum_t *checksum,
155                       apr_pool_t *result_pool,
156                       apr_pool_t *scratch_pool);
157
158
159/** Return @a checksum from the serialized format at @a data. The checksum
160 * will be allocated in @a result_pool, with any temporary allocations
161 * performed in @a scratch_pool.
162 *
163 * @since New in 1.7.
164 */
165svn_error_t *
166svn_checksum_deserialize(const svn_checksum_t **checksum,
167                         const char *data,
168                         apr_pool_t *result_pool,
169                         apr_pool_t *scratch_pool);
170
171
172/** Parse the hex representation @a hex of a checksum of kind @a kind and
173 * set @a *checksum to the result, allocating in @a pool.
174 *
175 * If @a hex is @c NULL or is the all-zeros checksum, then set @a *checksum
176 * to @c NULL.
177 *
178 * @since New in 1.6.
179 */
180/* ### TODO: When revving this, make it set @a *checksum to a non-NULL struct
181 * ###       when @a hex is the all-zeroes checksum.  See
182 * ### http://mail-archives.apache.org/mod_mbox/subversion-dev/201609.mbox/%3c00cd26ab-bdb3-67b4-ca6b-063266493874%40apache.org%3e
183 */
184svn_error_t *
185svn_checksum_parse_hex(svn_checksum_t **checksum,
186                       svn_checksum_kind_t kind,
187                       const char *hex,
188                       apr_pool_t *pool);
189
190/**
191 * Return in @a *checksum the checksum of type @a kind for the bytes beginning
192 * at @a data, and going for @a len.  @a *checksum is allocated in @a pool.
193 *
194 * @since New in 1.6.
195 */
196svn_error_t *
197svn_checksum(svn_checksum_t **checksum,
198             svn_checksum_kind_t kind,
199             const void *data,
200             apr_size_t len,
201             apr_pool_t *pool);
202
203
204/**
205 * Return in @a pool a newly allocated checksum populated with the checksum
206 * of type @a kind for the empty string.
207 *
208 * @since New in 1.6.
209 */
210svn_checksum_t *
211svn_checksum_empty_checksum(svn_checksum_kind_t kind,
212                            apr_pool_t *pool);
213
214
215/**
216 * Create a new @c svn_checksum_ctx_t structure, allocated from @a pool for
217 * calculating checksums of type @a kind.  @see svn_checksum_final()
218 *
219 * @since New in 1.6.
220 */
221svn_checksum_ctx_t *
222svn_checksum_ctx_create(svn_checksum_kind_t kind,
223                        apr_pool_t *pool);
224
225/**
226 * Reset an existing checksum @a ctx to initial state.
227 * @see svn_checksum_ctx_create()
228 *
229 * @since New in 1.10.
230 */
231svn_error_t *
232svn_checksum_ctx_reset(svn_checksum_ctx_t *ctx);
233
234/**
235 * Update the checksum represented by @a ctx, with @a len bytes starting at
236 * @a data.
237 *
238 * @since New in 1.6.
239 */
240svn_error_t *
241svn_checksum_update(svn_checksum_ctx_t *ctx,
242                    const void *data,
243                    apr_size_t len);
244
245
246/**
247 * Finalize the checksum used when creating @a ctx, and put the resultant
248 * checksum in @a *checksum, allocated in @a pool.
249 *
250 * @since New in 1.6.
251 */
252svn_error_t *
253svn_checksum_final(svn_checksum_t **checksum,
254                   const svn_checksum_ctx_t *ctx,
255                   apr_pool_t *pool);
256
257
258/**
259 * Return the digest size of @a checksum.
260 *
261 * @since New in 1.6.
262 */
263apr_size_t
264svn_checksum_size(const svn_checksum_t *checksum);
265
266/**
267 * Return @c TRUE iff @a checksum matches the checksum for the empty
268 * string.
269 *
270 * @since New in 1.8.
271 */
272svn_boolean_t
273svn_checksum_is_empty_checksum(svn_checksum_t *checksum);
274
275
276/**
277 * Return an error of type #SVN_ERR_CHECKSUM_MISMATCH for @a actual and
278 * @a expected checksums which do not match.  Use @a fmt, and the following
279 * parameters to populate the error message.
280 *
281 * @note This function does not actually check for the mismatch, it just
282 * constructs the error.
283 *
284 * @a scratch_pool is used for temporary allocations; the returned error
285 * will be allocated in its own pool (as is typical).
286 *
287 * @since New in 1.7.
288 */
289svn_error_t *
290svn_checksum_mismatch_err(const svn_checksum_t *expected,
291                          const svn_checksum_t *actual,
292                          apr_pool_t *scratch_pool,
293                          const char *fmt,
294                          ...)
295  __attribute__ ((format(printf, 4, 5)));
296
297#ifdef __cplusplus
298}
299#endif /* __cplusplus */
300
301#endif /* SVN_CHECKSUM_H */
302