1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Hashing function for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2015-2019 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker *
6*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
7*5e7646d2SAndroid Build Coastguard Worker * information.
8*5e7646d2SAndroid Build Coastguard Worker */
9*5e7646d2SAndroid Build Coastguard Worker
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker */
13*5e7646d2SAndroid Build Coastguard Worker
14*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
15*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
16*5e7646d2SAndroid Build Coastguard Worker # include <CommonCrypto/CommonDigest.h>
17*5e7646d2SAndroid Build Coastguard Worker #elif defined(HAVE_GNUTLS)
18*5e7646d2SAndroid Build Coastguard Worker # include <gnutls/crypto.h>
19*5e7646d2SAndroid Build Coastguard Worker # include "md5-internal.h"
20*5e7646d2SAndroid Build Coastguard Worker #else
21*5e7646d2SAndroid Build Coastguard Worker # include "md5-internal.h"
22*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
23*5e7646d2SAndroid Build Coastguard Worker
24*5e7646d2SAndroid Build Coastguard Worker
25*5e7646d2SAndroid Build Coastguard Worker /*
26*5e7646d2SAndroid Build Coastguard Worker * 'cupsHashData()' - Perform a hash function on the given data.
27*5e7646d2SAndroid Build Coastguard Worker *
28*5e7646d2SAndroid Build Coastguard Worker * The "algorithm" argument can be any of the registered, non-deprecated IPP
29*5e7646d2SAndroid Build Coastguard Worker * hash algorithms for the "job-password-encryption" attribute, including
30*5e7646d2SAndroid Build Coastguard Worker * "sha" for SHA-1, "sha-256" for SHA2-256, etc.
31*5e7646d2SAndroid Build Coastguard Worker *
32*5e7646d2SAndroid Build Coastguard Worker * The "hash" argument points to a buffer of "hashsize" bytes and should be at
33*5e7646d2SAndroid Build Coastguard Worker * least 64 bytes in length for all of the supported algorithms.
34*5e7646d2SAndroid Build Coastguard Worker *
35*5e7646d2SAndroid Build Coastguard Worker * The returned hash is binary data.
36*5e7646d2SAndroid Build Coastguard Worker *
37*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 2.2/macOS 10.12@
38*5e7646d2SAndroid Build Coastguard Worker */
39*5e7646d2SAndroid Build Coastguard Worker
40*5e7646d2SAndroid Build Coastguard Worker ssize_t /* O - Size of hash or -1 on error */
cupsHashData(const char * algorithm,const void * data,size_t datalen,unsigned char * hash,size_t hashsize)41*5e7646d2SAndroid Build Coastguard Worker cupsHashData(const char *algorithm, /* I - Algorithm name */
42*5e7646d2SAndroid Build Coastguard Worker const void *data, /* I - Data to hash */
43*5e7646d2SAndroid Build Coastguard Worker size_t datalen, /* I - Length of data to hash */
44*5e7646d2SAndroid Build Coastguard Worker unsigned char *hash, /* I - Hash buffer */
45*5e7646d2SAndroid Build Coastguard Worker size_t hashsize) /* I - Size of hash buffer */
46*5e7646d2SAndroid Build Coastguard Worker {
47*5e7646d2SAndroid Build Coastguard Worker if (!algorithm || !data || datalen == 0 || !hash || hashsize == 0)
48*5e7646d2SAndroid Build Coastguard Worker {
49*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad arguments to function"), 1);
50*5e7646d2SAndroid Build Coastguard Worker return (-1);
51*5e7646d2SAndroid Build Coastguard Worker }
52*5e7646d2SAndroid Build Coastguard Worker
53*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
54*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(algorithm, "md5"))
55*5e7646d2SAndroid Build Coastguard Worker {
56*5e7646d2SAndroid Build Coastguard Worker /*
57*5e7646d2SAndroid Build Coastguard Worker * MD5 (deprecated but widely used...)
58*5e7646d2SAndroid Build Coastguard Worker */
59*5e7646d2SAndroid Build Coastguard Worker
60*5e7646d2SAndroid Build Coastguard Worker CC_MD5_CTX ctx; /* MD5 context */
61*5e7646d2SAndroid Build Coastguard Worker
62*5e7646d2SAndroid Build Coastguard Worker if (hashsize < CC_MD5_DIGEST_LENGTH)
63*5e7646d2SAndroid Build Coastguard Worker goto too_small;
64*5e7646d2SAndroid Build Coastguard Worker
65*5e7646d2SAndroid Build Coastguard Worker CC_MD5_Init(&ctx);
66*5e7646d2SAndroid Build Coastguard Worker CC_MD5_Update(&ctx, data, (CC_LONG)datalen);
67*5e7646d2SAndroid Build Coastguard Worker CC_MD5_Final(hash, &ctx);
68*5e7646d2SAndroid Build Coastguard Worker
69*5e7646d2SAndroid Build Coastguard Worker return (CC_MD5_DIGEST_LENGTH);
70*5e7646d2SAndroid Build Coastguard Worker }
71*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha"))
72*5e7646d2SAndroid Build Coastguard Worker {
73*5e7646d2SAndroid Build Coastguard Worker /*
74*5e7646d2SAndroid Build Coastguard Worker * SHA-1...
75*5e7646d2SAndroid Build Coastguard Worker */
76*5e7646d2SAndroid Build Coastguard Worker
77*5e7646d2SAndroid Build Coastguard Worker CC_SHA1_CTX ctx; /* SHA-1 context */
78*5e7646d2SAndroid Build Coastguard Worker
79*5e7646d2SAndroid Build Coastguard Worker if (hashsize < CC_SHA1_DIGEST_LENGTH)
80*5e7646d2SAndroid Build Coastguard Worker goto too_small;
81*5e7646d2SAndroid Build Coastguard Worker
82*5e7646d2SAndroid Build Coastguard Worker CC_SHA1_Init(&ctx);
83*5e7646d2SAndroid Build Coastguard Worker CC_SHA1_Update(&ctx, data, (CC_LONG)datalen);
84*5e7646d2SAndroid Build Coastguard Worker CC_SHA1_Final(hash, &ctx);
85*5e7646d2SAndroid Build Coastguard Worker
86*5e7646d2SAndroid Build Coastguard Worker return (CC_SHA1_DIGEST_LENGTH);
87*5e7646d2SAndroid Build Coastguard Worker }
88*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha2-224"))
89*5e7646d2SAndroid Build Coastguard Worker {
90*5e7646d2SAndroid Build Coastguard Worker CC_SHA256_CTX ctx; /* SHA-224 context */
91*5e7646d2SAndroid Build Coastguard Worker
92*5e7646d2SAndroid Build Coastguard Worker if (hashsize < CC_SHA224_DIGEST_LENGTH)
93*5e7646d2SAndroid Build Coastguard Worker goto too_small;
94*5e7646d2SAndroid Build Coastguard Worker
95*5e7646d2SAndroid Build Coastguard Worker CC_SHA224_Init(&ctx);
96*5e7646d2SAndroid Build Coastguard Worker CC_SHA224_Update(&ctx, data, (CC_LONG)datalen);
97*5e7646d2SAndroid Build Coastguard Worker CC_SHA224_Final(hash, &ctx);
98*5e7646d2SAndroid Build Coastguard Worker
99*5e7646d2SAndroid Build Coastguard Worker return (CC_SHA224_DIGEST_LENGTH);
100*5e7646d2SAndroid Build Coastguard Worker }
101*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha2-256"))
102*5e7646d2SAndroid Build Coastguard Worker {
103*5e7646d2SAndroid Build Coastguard Worker CC_SHA256_CTX ctx; /* SHA-256 context */
104*5e7646d2SAndroid Build Coastguard Worker
105*5e7646d2SAndroid Build Coastguard Worker if (hashsize < CC_SHA256_DIGEST_LENGTH)
106*5e7646d2SAndroid Build Coastguard Worker goto too_small;
107*5e7646d2SAndroid Build Coastguard Worker
108*5e7646d2SAndroid Build Coastguard Worker CC_SHA256_Init(&ctx);
109*5e7646d2SAndroid Build Coastguard Worker CC_SHA256_Update(&ctx, data, (CC_LONG)datalen);
110*5e7646d2SAndroid Build Coastguard Worker CC_SHA256_Final(hash, &ctx);
111*5e7646d2SAndroid Build Coastguard Worker
112*5e7646d2SAndroid Build Coastguard Worker return (CC_SHA256_DIGEST_LENGTH);
113*5e7646d2SAndroid Build Coastguard Worker }
114*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha2-384"))
115*5e7646d2SAndroid Build Coastguard Worker {
116*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_CTX ctx; /* SHA-384 context */
117*5e7646d2SAndroid Build Coastguard Worker
118*5e7646d2SAndroid Build Coastguard Worker if (hashsize < CC_SHA384_DIGEST_LENGTH)
119*5e7646d2SAndroid Build Coastguard Worker goto too_small;
120*5e7646d2SAndroid Build Coastguard Worker
121*5e7646d2SAndroid Build Coastguard Worker CC_SHA384_Init(&ctx);
122*5e7646d2SAndroid Build Coastguard Worker CC_SHA384_Update(&ctx, data, (CC_LONG)datalen);
123*5e7646d2SAndroid Build Coastguard Worker CC_SHA384_Final(hash, &ctx);
124*5e7646d2SAndroid Build Coastguard Worker
125*5e7646d2SAndroid Build Coastguard Worker return (CC_SHA384_DIGEST_LENGTH);
126*5e7646d2SAndroid Build Coastguard Worker }
127*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha2-512"))
128*5e7646d2SAndroid Build Coastguard Worker {
129*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_CTX ctx; /* SHA-512 context */
130*5e7646d2SAndroid Build Coastguard Worker
131*5e7646d2SAndroid Build Coastguard Worker if (hashsize < CC_SHA512_DIGEST_LENGTH)
132*5e7646d2SAndroid Build Coastguard Worker goto too_small;
133*5e7646d2SAndroid Build Coastguard Worker
134*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_Init(&ctx);
135*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_Update(&ctx, data, (CC_LONG)datalen);
136*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_Final(hash, &ctx);
137*5e7646d2SAndroid Build Coastguard Worker
138*5e7646d2SAndroid Build Coastguard Worker return (CC_SHA512_DIGEST_LENGTH);
139*5e7646d2SAndroid Build Coastguard Worker }
140*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha2-512_224"))
141*5e7646d2SAndroid Build Coastguard Worker {
142*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_CTX ctx; /* SHA-512 context */
143*5e7646d2SAndroid Build Coastguard Worker unsigned char temp[CC_SHA512_DIGEST_LENGTH];
144*5e7646d2SAndroid Build Coastguard Worker /* SHA-512 hash */
145*5e7646d2SAndroid Build Coastguard Worker
146*5e7646d2SAndroid Build Coastguard Worker /*
147*5e7646d2SAndroid Build Coastguard Worker * SHA2-512 truncated to 224 bits (28 bytes)...
148*5e7646d2SAndroid Build Coastguard Worker */
149*5e7646d2SAndroid Build Coastguard Worker
150*5e7646d2SAndroid Build Coastguard Worker if (hashsize < CC_SHA224_DIGEST_LENGTH)
151*5e7646d2SAndroid Build Coastguard Worker goto too_small;
152*5e7646d2SAndroid Build Coastguard Worker
153*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_Init(&ctx);
154*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_Update(&ctx, data, (CC_LONG)datalen);
155*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_Final(temp, &ctx);
156*5e7646d2SAndroid Build Coastguard Worker
157*5e7646d2SAndroid Build Coastguard Worker memcpy(hash, temp, CC_SHA224_DIGEST_LENGTH);
158*5e7646d2SAndroid Build Coastguard Worker
159*5e7646d2SAndroid Build Coastguard Worker return (CC_SHA224_DIGEST_LENGTH);
160*5e7646d2SAndroid Build Coastguard Worker }
161*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha2-512_256"))
162*5e7646d2SAndroid Build Coastguard Worker {
163*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_CTX ctx; /* SHA-512 context */
164*5e7646d2SAndroid Build Coastguard Worker unsigned char temp[CC_SHA512_DIGEST_LENGTH];
165*5e7646d2SAndroid Build Coastguard Worker /* SHA-512 hash */
166*5e7646d2SAndroid Build Coastguard Worker
167*5e7646d2SAndroid Build Coastguard Worker /*
168*5e7646d2SAndroid Build Coastguard Worker * SHA2-512 truncated to 256 bits (32 bytes)...
169*5e7646d2SAndroid Build Coastguard Worker */
170*5e7646d2SAndroid Build Coastguard Worker
171*5e7646d2SAndroid Build Coastguard Worker if (hashsize < CC_SHA256_DIGEST_LENGTH)
172*5e7646d2SAndroid Build Coastguard Worker goto too_small;
173*5e7646d2SAndroid Build Coastguard Worker
174*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_Init(&ctx);
175*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_Update(&ctx, data, (CC_LONG)datalen);
176*5e7646d2SAndroid Build Coastguard Worker CC_SHA512_Final(temp, &ctx);
177*5e7646d2SAndroid Build Coastguard Worker
178*5e7646d2SAndroid Build Coastguard Worker memcpy(hash, temp, CC_SHA256_DIGEST_LENGTH);
179*5e7646d2SAndroid Build Coastguard Worker
180*5e7646d2SAndroid Build Coastguard Worker return (CC_SHA256_DIGEST_LENGTH);
181*5e7646d2SAndroid Build Coastguard Worker }
182*5e7646d2SAndroid Build Coastguard Worker
183*5e7646d2SAndroid Build Coastguard Worker #elif defined(HAVE_GNUTLS)
184*5e7646d2SAndroid Build Coastguard Worker gnutls_digest_algorithm_t alg = GNUTLS_DIG_UNKNOWN;
185*5e7646d2SAndroid Build Coastguard Worker /* Algorithm */
186*5e7646d2SAndroid Build Coastguard Worker unsigned char temp[64]; /* Temporary hash buffer */
187*5e7646d2SAndroid Build Coastguard Worker size_t tempsize = 0; /* Truncate to this size? */
188*5e7646d2SAndroid Build Coastguard Worker
189*5e7646d2SAndroid Build Coastguard Worker
190*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(algorithm, "md5"))
191*5e7646d2SAndroid Build Coastguard Worker {
192*5e7646d2SAndroid Build Coastguard Worker /*
193*5e7646d2SAndroid Build Coastguard Worker * Some versions of GNU TLS disable MD5 without warning...
194*5e7646d2SAndroid Build Coastguard Worker */
195*5e7646d2SAndroid Build Coastguard Worker
196*5e7646d2SAndroid Build Coastguard Worker _cups_md5_state_t state; /* MD5 state info */
197*5e7646d2SAndroid Build Coastguard Worker
198*5e7646d2SAndroid Build Coastguard Worker if (hashsize < 16)
199*5e7646d2SAndroid Build Coastguard Worker goto too_small;
200*5e7646d2SAndroid Build Coastguard Worker
201*5e7646d2SAndroid Build Coastguard Worker _cupsMD5Init(&state);
202*5e7646d2SAndroid Build Coastguard Worker _cupsMD5Append(&state, data, (int)datalen);
203*5e7646d2SAndroid Build Coastguard Worker _cupsMD5Finish(&state, hash);
204*5e7646d2SAndroid Build Coastguard Worker
205*5e7646d2SAndroid Build Coastguard Worker return (16);
206*5e7646d2SAndroid Build Coastguard Worker }
207*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha"))
208*5e7646d2SAndroid Build Coastguard Worker alg = GNUTLS_DIG_SHA1;
209*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha2-224"))
210*5e7646d2SAndroid Build Coastguard Worker alg = GNUTLS_DIG_SHA224;
211*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha2-256"))
212*5e7646d2SAndroid Build Coastguard Worker alg = GNUTLS_DIG_SHA256;
213*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha2-384"))
214*5e7646d2SAndroid Build Coastguard Worker alg = GNUTLS_DIG_SHA384;
215*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha2-512"))
216*5e7646d2SAndroid Build Coastguard Worker alg = GNUTLS_DIG_SHA512;
217*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha2-512_224"))
218*5e7646d2SAndroid Build Coastguard Worker {
219*5e7646d2SAndroid Build Coastguard Worker alg = GNUTLS_DIG_SHA512;
220*5e7646d2SAndroid Build Coastguard Worker tempsize = 28;
221*5e7646d2SAndroid Build Coastguard Worker }
222*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(algorithm, "sha2-512_256"))
223*5e7646d2SAndroid Build Coastguard Worker {
224*5e7646d2SAndroid Build Coastguard Worker alg = GNUTLS_DIG_SHA512;
225*5e7646d2SAndroid Build Coastguard Worker tempsize = 32;
226*5e7646d2SAndroid Build Coastguard Worker }
227*5e7646d2SAndroid Build Coastguard Worker
228*5e7646d2SAndroid Build Coastguard Worker if (alg != GNUTLS_DIG_UNKNOWN)
229*5e7646d2SAndroid Build Coastguard Worker {
230*5e7646d2SAndroid Build Coastguard Worker if (tempsize > 0)
231*5e7646d2SAndroid Build Coastguard Worker {
232*5e7646d2SAndroid Build Coastguard Worker /*
233*5e7646d2SAndroid Build Coastguard Worker * Truncate result to tempsize bytes...
234*5e7646d2SAndroid Build Coastguard Worker */
235*5e7646d2SAndroid Build Coastguard Worker
236*5e7646d2SAndroid Build Coastguard Worker if (hashsize < tempsize)
237*5e7646d2SAndroid Build Coastguard Worker goto too_small;
238*5e7646d2SAndroid Build Coastguard Worker
239*5e7646d2SAndroid Build Coastguard Worker gnutls_hash_fast(alg, data, datalen, temp);
240*5e7646d2SAndroid Build Coastguard Worker memcpy(hash, temp, tempsize);
241*5e7646d2SAndroid Build Coastguard Worker
242*5e7646d2SAndroid Build Coastguard Worker return ((ssize_t)tempsize);
243*5e7646d2SAndroid Build Coastguard Worker }
244*5e7646d2SAndroid Build Coastguard Worker
245*5e7646d2SAndroid Build Coastguard Worker if (hashsize < gnutls_hash_get_len(alg))
246*5e7646d2SAndroid Build Coastguard Worker goto too_small;
247*5e7646d2SAndroid Build Coastguard Worker
248*5e7646d2SAndroid Build Coastguard Worker gnutls_hash_fast(alg, data, datalen, hash);
249*5e7646d2SAndroid Build Coastguard Worker
250*5e7646d2SAndroid Build Coastguard Worker return ((ssize_t)gnutls_hash_get_len(alg));
251*5e7646d2SAndroid Build Coastguard Worker }
252*5e7646d2SAndroid Build Coastguard Worker
253*5e7646d2SAndroid Build Coastguard Worker #else
254*5e7646d2SAndroid Build Coastguard Worker /*
255*5e7646d2SAndroid Build Coastguard Worker * No hash support beyond MD5 without CommonCrypto or GNU TLS...
256*5e7646d2SAndroid Build Coastguard Worker */
257*5e7646d2SAndroid Build Coastguard Worker
258*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(algorithm, "md5"))
259*5e7646d2SAndroid Build Coastguard Worker {
260*5e7646d2SAndroid Build Coastguard Worker _cups_md5_state_t state; /* MD5 state info */
261*5e7646d2SAndroid Build Coastguard Worker
262*5e7646d2SAndroid Build Coastguard Worker if (hashsize < 16)
263*5e7646d2SAndroid Build Coastguard Worker goto too_small;
264*5e7646d2SAndroid Build Coastguard Worker
265*5e7646d2SAndroid Build Coastguard Worker _cupsMD5Init(&state);
266*5e7646d2SAndroid Build Coastguard Worker _cupsMD5Append(&state, data, datalen);
267*5e7646d2SAndroid Build Coastguard Worker _cupsMD5Finish(&state, hash);
268*5e7646d2SAndroid Build Coastguard Worker
269*5e7646d2SAndroid Build Coastguard Worker return (16);
270*5e7646d2SAndroid Build Coastguard Worker }
271*5e7646d2SAndroid Build Coastguard Worker else if (hashsize < 64)
272*5e7646d2SAndroid Build Coastguard Worker goto too_small;
273*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
274*5e7646d2SAndroid Build Coastguard Worker
275*5e7646d2SAndroid Build Coastguard Worker /*
276*5e7646d2SAndroid Build Coastguard Worker * Unknown hash algorithm...
277*5e7646d2SAndroid Build Coastguard Worker */
278*5e7646d2SAndroid Build Coastguard Worker
279*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unknown hash algorithm."), 1);
280*5e7646d2SAndroid Build Coastguard Worker
281*5e7646d2SAndroid Build Coastguard Worker return (-1);
282*5e7646d2SAndroid Build Coastguard Worker
283*5e7646d2SAndroid Build Coastguard Worker /*
284*5e7646d2SAndroid Build Coastguard Worker * We get here if the buffer is too small.
285*5e7646d2SAndroid Build Coastguard Worker */
286*5e7646d2SAndroid Build Coastguard Worker
287*5e7646d2SAndroid Build Coastguard Worker too_small:
288*5e7646d2SAndroid Build Coastguard Worker
289*5e7646d2SAndroid Build Coastguard Worker _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Hash buffer too small."), 1);
290*5e7646d2SAndroid Build Coastguard Worker return (-1);
291*5e7646d2SAndroid Build Coastguard Worker }
292*5e7646d2SAndroid Build Coastguard Worker
293*5e7646d2SAndroid Build Coastguard Worker
294*5e7646d2SAndroid Build Coastguard Worker /*
295*5e7646d2SAndroid Build Coastguard Worker * 'cupsHashString()' - Format a hash value as a hexadecimal string.
296*5e7646d2SAndroid Build Coastguard Worker *
297*5e7646d2SAndroid Build Coastguard Worker * The passed buffer must be at least 2 * hashsize + 1 characters in length.
298*5e7646d2SAndroid Build Coastguard Worker *
299*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 2.2.7@
300*5e7646d2SAndroid Build Coastguard Worker */
301*5e7646d2SAndroid Build Coastguard Worker
302*5e7646d2SAndroid Build Coastguard Worker const char * /* O - Formatted string */
cupsHashString(const unsigned char * hash,size_t hashsize,char * buffer,size_t bufsize)303*5e7646d2SAndroid Build Coastguard Worker cupsHashString(
304*5e7646d2SAndroid Build Coastguard Worker const unsigned char *hash, /* I - Hash */
305*5e7646d2SAndroid Build Coastguard Worker size_t hashsize, /* I - Size of hash */
306*5e7646d2SAndroid Build Coastguard Worker char *buffer, /* I - String buffer */
307*5e7646d2SAndroid Build Coastguard Worker size_t bufsize) /* I - Size of string buffer */
308*5e7646d2SAndroid Build Coastguard Worker {
309*5e7646d2SAndroid Build Coastguard Worker char *bufptr = buffer; /* Pointer into buffer */
310*5e7646d2SAndroid Build Coastguard Worker static const char *hex = "0123456789abcdef";
311*5e7646d2SAndroid Build Coastguard Worker /* Hex characters (lowercase!) */
312*5e7646d2SAndroid Build Coastguard Worker
313*5e7646d2SAndroid Build Coastguard Worker
314*5e7646d2SAndroid Build Coastguard Worker /*
315*5e7646d2SAndroid Build Coastguard Worker * Range check input...
316*5e7646d2SAndroid Build Coastguard Worker */
317*5e7646d2SAndroid Build Coastguard Worker
318*5e7646d2SAndroid Build Coastguard Worker if (!hash || hashsize < 1 || !buffer || bufsize < (2 * hashsize + 1))
319*5e7646d2SAndroid Build Coastguard Worker {
320*5e7646d2SAndroid Build Coastguard Worker if (buffer)
321*5e7646d2SAndroid Build Coastguard Worker *buffer = '\0';
322*5e7646d2SAndroid Build Coastguard Worker return (NULL);
323*5e7646d2SAndroid Build Coastguard Worker }
324*5e7646d2SAndroid Build Coastguard Worker
325*5e7646d2SAndroid Build Coastguard Worker /*
326*5e7646d2SAndroid Build Coastguard Worker * Loop until we've converted the whole hash...
327*5e7646d2SAndroid Build Coastguard Worker */
328*5e7646d2SAndroid Build Coastguard Worker
329*5e7646d2SAndroid Build Coastguard Worker while (hashsize > 0)
330*5e7646d2SAndroid Build Coastguard Worker {
331*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = hex[*hash >> 4];
332*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = hex[*hash & 15];
333*5e7646d2SAndroid Build Coastguard Worker
334*5e7646d2SAndroid Build Coastguard Worker hash ++;
335*5e7646d2SAndroid Build Coastguard Worker hashsize --;
336*5e7646d2SAndroid Build Coastguard Worker }
337*5e7646d2SAndroid Build Coastguard Worker
338*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
339*5e7646d2SAndroid Build Coastguard Worker
340*5e7646d2SAndroid Build Coastguard Worker return (buffer);
341*5e7646d2SAndroid Build Coastguard Worker }
342