|
1
|
/* |
|
2
|
** Copyright (c) 2006 D. Richard Hipp |
|
3
|
** |
|
4
|
** This program is free software; you can redistribute it and/or |
|
5
|
** modify it under the terms of the Simplified BSD License (also |
|
6
|
** known as the "2-Clause License" or "FreeBSD License".) |
|
7
|
** |
|
8
|
** This program is distributed in the hope that it will be useful, |
|
9
|
** but without any warranty; without even the implied warranty of |
|
10
|
** merchantability or fitness for a particular purpose. |
|
11
|
** |
|
12
|
** Author contact information: |
|
13
|
** [email protected] |
|
14
|
** http://www.hwaci.com/drh/ |
|
15
|
** |
|
16
|
******************************************************************************* |
|
17
|
** |
|
18
|
** This implementation of SHA1. |
|
19
|
*/ |
|
20
|
#include "config.h" |
|
21
|
#include <sys/types.h> |
|
22
|
#include "sha1.h" |
|
23
|
|
|
24
|
|
|
25
|
/* |
|
26
|
** SHA1 Implementation #1 is the hardened SHA1 implementation by |
|
27
|
** Marc Stevens. Code obtained from GitHub |
|
28
|
** |
|
29
|
** https://github.com/cr-marcstevens/sha1collisiondetection |
|
30
|
** |
|
31
|
** Downloaded on 2017-03-01 then repackaged to work with Fossil |
|
32
|
** and makeheaders. |
|
33
|
*/ |
|
34
|
#if FOSSIL_HARDENED_SHA1 |
|
35
|
|
|
36
|
#if INTERFACE |
|
37
|
typedef void(*collision_block_callback)(uint64_t, const uint32_t*, |
|
38
|
const uint32_t*, const uint32_t*, const uint32_t*); |
|
39
|
struct SHA1_CTX { |
|
40
|
uint64_t total; |
|
41
|
uint32_t ihv[5]; |
|
42
|
unsigned char buffer[64]; |
|
43
|
int bigendian; |
|
44
|
int found_collision; |
|
45
|
int safe_hash; |
|
46
|
int detect_coll; |
|
47
|
int ubc_check; |
|
48
|
int reduced_round_coll; |
|
49
|
collision_block_callback callback; |
|
50
|
|
|
51
|
uint32_t ihv1[5]; |
|
52
|
uint32_t ihv2[5]; |
|
53
|
uint32_t m1[80]; |
|
54
|
uint32_t m2[80]; |
|
55
|
uint32_t states[80][5]; |
|
56
|
}; |
|
57
|
#endif |
|
58
|
void SHA1DCInit(SHA1_CTX*); |
|
59
|
void SHA1DCUpdate(SHA1_CTX*, const unsigned char*, unsigned); |
|
60
|
int SHA1DCFinal(unsigned char[20], SHA1_CTX*); |
|
61
|
|
|
62
|
#define SHA1Context SHA1_CTX |
|
63
|
#define SHA1Init SHA1DCInit |
|
64
|
#define SHA1Update SHA1DCUpdate |
|
65
|
#define SHA1Final SHA1DCFinal |
|
66
|
|
|
67
|
/* |
|
68
|
** SHA1 Implementation #2: use the SHA1 algorithm built into SSL |
|
69
|
*/ |
|
70
|
#elif defined(FOSSIL_ENABLE_SSL) |
|
71
|
|
|
72
|
# include <openssl/sha.h> |
|
73
|
# define SHA1Context SHA_CTX |
|
74
|
# define SHA1Init SHA1_Init |
|
75
|
# define SHA1Update SHA1_Update |
|
76
|
# define SHA1Final SHA1_Final |
|
77
|
|
|
78
|
/* |
|
79
|
** SHA1 Implementation #3: If none of the previous two SHA1 |
|
80
|
** algorithms work, there is this built-in. This built-in was the |
|
81
|
** original implementation used by Fossil. |
|
82
|
*/ |
|
83
|
#else |
|
84
|
/* |
|
85
|
** The SHA1 implementation below is adapted from: |
|
86
|
** |
|
87
|
** $NetBSD: sha1.c,v 1.6 2009/11/06 20:31:18 joerg Exp $ |
|
88
|
** $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ |
|
89
|
** |
|
90
|
** SHA-1 in C |
|
91
|
** By Steve Reid <[email protected]> |
|
92
|
** 100% Public Domain |
|
93
|
*/ |
|
94
|
typedef struct SHA1Context SHA1Context; |
|
95
|
struct SHA1Context { |
|
96
|
unsigned int state[5]; |
|
97
|
unsigned int count[2]; |
|
98
|
unsigned char buffer[64]; |
|
99
|
}; |
|
100
|
|
|
101
|
/* |
|
102
|
* blk0() and blk() perform the initial expand. |
|
103
|
* I got the idea of expanding during the round function from SSLeay |
|
104
|
* |
|
105
|
* blk0le() for little-endian and blk0be() for big-endian. |
|
106
|
*/ |
|
107
|
#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) |
|
108
|
#define rol(x,k) SHA_ROT(x,k,32-(k)) |
|
109
|
#define ror(x,k) SHA_ROT(x,32-(k),k) |
|
110
|
#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ |
|
111
|
|(rol(block[i],8)&0x00FF00FF)) |
|
112
|
#define blk0be(i) block[i] |
|
113
|
#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ |
|
114
|
^block[(i+2)&15]^block[i&15],1)) |
|
115
|
|
|
116
|
/* |
|
117
|
* (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 |
|
118
|
* |
|
119
|
* Rl0() for little-endian and Rb0() for big-endian. Endianness is |
|
120
|
* determined at run-time. |
|
121
|
*/ |
|
122
|
#define Rl0(v,w,x,y,z,i) \ |
|
123
|
z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); |
|
124
|
#define Rb0(v,w,x,y,z,i) \ |
|
125
|
z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2); |
|
126
|
#define R1(v,w,x,y,z,i) \ |
|
127
|
z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2); |
|
128
|
#define R2(v,w,x,y,z,i) \ |
|
129
|
z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2); |
|
130
|
#define R3(v,w,x,y,z,i) \ |
|
131
|
z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2); |
|
132
|
#define R4(v,w,x,y,z,i) \ |
|
133
|
z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); |
|
134
|
|
|
135
|
/* |
|
136
|
* Hash a single 512-bit block. This is the core of the algorithm. |
|
137
|
*/ |
|
138
|
#define a qq[0] |
|
139
|
#define b qq[1] |
|
140
|
#define c qq[2] |
|
141
|
#define d qq[3] |
|
142
|
#define e qq[4] |
|
143
|
|
|
144
|
void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]) |
|
145
|
{ |
|
146
|
unsigned int qq[5]; /* a, b, c, d, e; */ |
|
147
|
static int one = 1; |
|
148
|
unsigned int block[16]; |
|
149
|
memcpy(block, buffer, 64); |
|
150
|
memcpy(qq,state,5*sizeof(unsigned int)); |
|
151
|
|
|
152
|
/* Copy context->state[] to working vars */ |
|
153
|
/* |
|
154
|
a = state[0]; |
|
155
|
b = state[1]; |
|
156
|
c = state[2]; |
|
157
|
d = state[3]; |
|
158
|
e = state[4]; |
|
159
|
*/ |
|
160
|
|
|
161
|
/* 4 rounds of 20 operations each. Loop unrolled. */ |
|
162
|
if( 1 == *(unsigned char*)&one ){ |
|
163
|
Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3); |
|
164
|
Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7); |
|
165
|
Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11); |
|
166
|
Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15); |
|
167
|
}else{ |
|
168
|
Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3); |
|
169
|
Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7); |
|
170
|
Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11); |
|
171
|
Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15); |
|
172
|
} |
|
173
|
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); |
|
174
|
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); |
|
175
|
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); |
|
176
|
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); |
|
177
|
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); |
|
178
|
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); |
|
179
|
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); |
|
180
|
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); |
|
181
|
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); |
|
182
|
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); |
|
183
|
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); |
|
184
|
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); |
|
185
|
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); |
|
186
|
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); |
|
187
|
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); |
|
188
|
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); |
|
189
|
|
|
190
|
/* Add the working vars back into context.state[] */ |
|
191
|
state[0] += a; |
|
192
|
state[1] += b; |
|
193
|
state[2] += c; |
|
194
|
state[3] += d; |
|
195
|
state[4] += e; |
|
196
|
} |
|
197
|
|
|
198
|
|
|
199
|
/* |
|
200
|
* SHA1Init - Initialize new context |
|
201
|
*/ |
|
202
|
static void SHA1Init(SHA1Context *context){ |
|
203
|
/* SHA1 initialization constants */ |
|
204
|
context->state[0] = 0x67452301; |
|
205
|
context->state[1] = 0xEFCDAB89; |
|
206
|
context->state[2] = 0x98BADCFE; |
|
207
|
context->state[3] = 0x10325476; |
|
208
|
context->state[4] = 0xC3D2E1F0; |
|
209
|
context->count[0] = context->count[1] = 0; |
|
210
|
} |
|
211
|
|
|
212
|
|
|
213
|
/* |
|
214
|
* Run your data through this. |
|
215
|
*/ |
|
216
|
static void SHA1Update( |
|
217
|
SHA1Context *context, |
|
218
|
const unsigned char *data, |
|
219
|
unsigned int len |
|
220
|
){ |
|
221
|
unsigned int i, j; |
|
222
|
|
|
223
|
j = context->count[0]; |
|
224
|
if ((context->count[0] += len << 3) < j) |
|
225
|
context->count[1] += (len>>29)+1; |
|
226
|
j = (j >> 3) & 63; |
|
227
|
if ((j + len) > 63) { |
|
228
|
(void)memcpy(&context->buffer[j], data, (i = 64-j)); |
|
229
|
SHA1Transform(context->state, context->buffer); |
|
230
|
for ( ; i + 63 < len; i += 64) |
|
231
|
SHA1Transform(context->state, &data[i]); |
|
232
|
j = 0; |
|
233
|
} else { |
|
234
|
i = 0; |
|
235
|
} |
|
236
|
(void)memcpy(&context->buffer[j], &data[i], len - i); |
|
237
|
} |
|
238
|
|
|
239
|
|
|
240
|
/* |
|
241
|
* Add padding and return the message digest. |
|
242
|
*/ |
|
243
|
static void SHA1Final(unsigned char *digest, SHA1Context *context){ |
|
244
|
unsigned int i; |
|
245
|
unsigned char finalcount[8]; |
|
246
|
|
|
247
|
for (i = 0; i < 8; i++) { |
|
248
|
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] |
|
249
|
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ |
|
250
|
} |
|
251
|
SHA1Update(context, (const unsigned char *)"\200", 1); |
|
252
|
while ((context->count[0] & 504) != 448) |
|
253
|
SHA1Update(context, (const unsigned char *)"\0", 1); |
|
254
|
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ |
|
255
|
|
|
256
|
if (digest) { |
|
257
|
for (i = 0; i < 20; i++) |
|
258
|
digest[i] = (unsigned char) |
|
259
|
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); |
|
260
|
} |
|
261
|
} |
|
262
|
#endif /* Built-in SHA1 implementation */ |
|
263
|
|
|
264
|
/* |
|
265
|
** Convert a digest into base-16. digest should be declared as |
|
266
|
** "unsigned char digest[20]" in the calling function. The SHA1 |
|
267
|
** digest is stored in the first 20 bytes. zBuf should |
|
268
|
** be "char zBuf[41]". |
|
269
|
*/ |
|
270
|
static void DigestToBase16(unsigned char *digest, char *zBuf){ |
|
271
|
static const char zEncode[] = "0123456789abcdef"; |
|
272
|
int ix; |
|
273
|
|
|
274
|
for(ix=0; ix<20; ix++){ |
|
275
|
*zBuf++ = zEncode[(*digest>>4)&0xf]; |
|
276
|
*zBuf++ = zEncode[*digest++ & 0xf]; |
|
277
|
} |
|
278
|
*zBuf = '\0'; |
|
279
|
} |
|
280
|
|
|
281
|
/* |
|
282
|
** The state of an incremental SHA1 checksum computation. Only one |
|
283
|
** such computation can be underway at a time, of course. |
|
284
|
*/ |
|
285
|
static SHA1Context incrCtx; |
|
286
|
static int incrInit = 0; |
|
287
|
|
|
288
|
/* |
|
289
|
** Add more text to the incremental SHA1 checksum. |
|
290
|
*/ |
|
291
|
void sha1sum_step_text(const char *zText, int nBytes){ |
|
292
|
if( !incrInit ){ |
|
293
|
SHA1Init(&incrCtx); |
|
294
|
incrInit = 1; |
|
295
|
} |
|
296
|
if( nBytes<=0 ){ |
|
297
|
if( nBytes==0 ) return; |
|
298
|
nBytes = strlen(zText); |
|
299
|
} |
|
300
|
SHA1Update(&incrCtx, (unsigned char*)zText, nBytes); |
|
301
|
} |
|
302
|
|
|
303
|
/* |
|
304
|
** Add the content of a blob to the incremental SHA1 checksum. |
|
305
|
*/ |
|
306
|
void sha1sum_step_blob(Blob *p){ |
|
307
|
sha1sum_step_text(blob_buffer(p), blob_size(p)); |
|
308
|
} |
|
309
|
|
|
310
|
/* |
|
311
|
** Finish the incremental SHA1 checksum. Store the result in blob pOut |
|
312
|
** if pOut!=0. Also return a pointer to the result. |
|
313
|
** |
|
314
|
** This resets the incremental checksum preparing for the next round |
|
315
|
** of computation. The return pointer points to a static buffer that |
|
316
|
** is overwritten by subsequent calls to this function. |
|
317
|
*/ |
|
318
|
char *sha1sum_finish(Blob *pOut){ |
|
319
|
unsigned char zResult[20]; |
|
320
|
static char zOut[41]; |
|
321
|
sha1sum_step_text(0,0); |
|
322
|
SHA1Final(zResult, &incrCtx); |
|
323
|
incrInit = 0; |
|
324
|
DigestToBase16(zResult, zOut); |
|
325
|
if( pOut ){ |
|
326
|
blob_zero(pOut); |
|
327
|
blob_append(pOut, zOut, 40); |
|
328
|
} |
|
329
|
return zOut; |
|
330
|
} |
|
331
|
|
|
332
|
|
|
333
|
/* |
|
334
|
** Compute the SHA1 checksum of a file on disk. Store the resulting |
|
335
|
** checksum in the blob pCksum. pCksum is assumed to be initialized. |
|
336
|
** |
|
337
|
** Return the number of errors. |
|
338
|
*/ |
|
339
|
int sha1sum_file(const char *zFilename, int eFType, Blob *pCksum){ |
|
340
|
FILE *in; |
|
341
|
SHA1Context ctx; |
|
342
|
unsigned char zResult[20]; |
|
343
|
char zBuf[10240]; |
|
344
|
|
|
345
|
if( eFType==RepoFILE && file_islink(zFilename) ){ |
|
346
|
/* Instead of file content, return sha1 of link destination path */ |
|
347
|
Blob destinationPath; |
|
348
|
int rc; |
|
349
|
|
|
350
|
blob_read_link(&destinationPath, zFilename); |
|
351
|
rc = sha1sum_blob(&destinationPath, pCksum); |
|
352
|
blob_reset(&destinationPath); |
|
353
|
return rc; |
|
354
|
} |
|
355
|
|
|
356
|
in = fossil_fopen(zFilename,"rb"); |
|
357
|
if( in==0 ){ |
|
358
|
return 1; |
|
359
|
} |
|
360
|
SHA1Init(&ctx); |
|
361
|
for(;;){ |
|
362
|
int n; |
|
363
|
n = fread(zBuf, 1, sizeof(zBuf), in); |
|
364
|
if( n<=0 ) break; |
|
365
|
SHA1Update(&ctx, (unsigned char*)zBuf, (unsigned)n); |
|
366
|
} |
|
367
|
fclose(in); |
|
368
|
blob_zero(pCksum); |
|
369
|
blob_resize(pCksum, 40); |
|
370
|
SHA1Final(zResult, &ctx); |
|
371
|
DigestToBase16(zResult, blob_buffer(pCksum)); |
|
372
|
return 0; |
|
373
|
} |
|
374
|
|
|
375
|
/* |
|
376
|
** Compute the SHA1 checksum of a blob in memory. Store the resulting |
|
377
|
** checksum in the blob pCksum. pCksum is assumed to be either |
|
378
|
** uninitialized or the same blob as pIn. |
|
379
|
** |
|
380
|
** Return the number of errors. |
|
381
|
*/ |
|
382
|
int sha1sum_blob(const Blob *pIn, Blob *pCksum){ |
|
383
|
SHA1Context ctx; |
|
384
|
unsigned char zResult[20]; |
|
385
|
|
|
386
|
SHA1Init(&ctx); |
|
387
|
SHA1Update(&ctx, (unsigned char*)blob_buffer(pIn), blob_size(pIn)); |
|
388
|
if( pIn==pCksum ){ |
|
389
|
blob_reset(pCksum); |
|
390
|
}else{ |
|
391
|
blob_zero(pCksum); |
|
392
|
} |
|
393
|
blob_resize(pCksum, 40); |
|
394
|
SHA1Final(zResult, &ctx); |
|
395
|
DigestToBase16(zResult, blob_buffer(pCksum)); |
|
396
|
return 0; |
|
397
|
} |
|
398
|
|
|
399
|
/* |
|
400
|
** Compute a binary SHA1 checksum of a zero-terminated string. The |
|
401
|
** result is stored in zOut, which is a buffer that must be at least |
|
402
|
** 20 bytes in size. |
|
403
|
*/ |
|
404
|
void sha1sum_binary(const char *zIn, unsigned char *zOut){ |
|
405
|
SHA1Context ctx; |
|
406
|
|
|
407
|
SHA1Init(&ctx); |
|
408
|
SHA1Update(&ctx, (unsigned const char*)zIn, strlen(zIn)); |
|
409
|
SHA1Final(zOut, &ctx); |
|
410
|
} |
|
411
|
|
|
412
|
/* |
|
413
|
** Compute the SHA1 checksum of a zero-terminated string. The |
|
414
|
** result is held in memory obtained from mprintf(). |
|
415
|
*/ |
|
416
|
char *sha1sum(const char *zIn){ |
|
417
|
SHA1Context ctx; |
|
418
|
unsigned char zResult[20]; |
|
419
|
char zDigest[41]; |
|
420
|
|
|
421
|
SHA1Init(&ctx); |
|
422
|
SHA1Update(&ctx, (unsigned const char*)zIn, strlen(zIn)); |
|
423
|
SHA1Final(zResult, &ctx); |
|
424
|
DigestToBase16(zResult, zDigest); |
|
425
|
return fossil_strdup(zDigest); |
|
426
|
} |
|
427
|
|
|
428
|
/* |
|
429
|
** Convert a cleartext password for a specific user into a SHA1 hash. |
|
430
|
** |
|
431
|
** The algorithm here is: |
|
432
|
** |
|
433
|
** SHA1( project-code + "/" + login + "/" + password ) |
|
434
|
** |
|
435
|
** In words: The users login name and password are appended to the |
|
436
|
** project ID code and the SHA1 hash of the result is computed. |
|
437
|
** |
|
438
|
** The result of this function is the shared secret used by a client |
|
439
|
** to authenticate to a server for the sync protocol. It is also the |
|
440
|
** value stored in the USER.PW field of the database. By mixing in the |
|
441
|
** login name and the project id with the hash, different shared secrets |
|
442
|
** are obtained even if two users select the same password, or if a |
|
443
|
** single user selects the same password for multiple projects. |
|
444
|
*/ |
|
445
|
char *sha1_shared_secret( |
|
446
|
const char *zPw, /* The password to encrypt */ |
|
447
|
const char *zLogin, /* Username */ |
|
448
|
const char *zProjCode /* Project-code. Use built-in project code if NULL */ |
|
449
|
){ |
|
450
|
static char *zProjectId = 0; |
|
451
|
SHA1Context ctx; |
|
452
|
unsigned char zResult[20]; |
|
453
|
char zDigest[41]; |
|
454
|
|
|
455
|
SHA1Init(&ctx); |
|
456
|
if( zProjCode==0 ){ |
|
457
|
if( zProjectId==0 ){ |
|
458
|
zProjectId = db_get("project-code", 0); |
|
459
|
|
|
460
|
/* On the first xfer request of a clone, the project-code is not yet |
|
461
|
** known. Use the cleartext password, since that is all we have. |
|
462
|
*/ |
|
463
|
if( zProjectId==0 ){ |
|
464
|
return fossil_strdup(zPw); |
|
465
|
} |
|
466
|
} |
|
467
|
zProjCode = zProjectId; |
|
468
|
} |
|
469
|
SHA1Update(&ctx, (unsigned char*)zProjCode, strlen(zProjCode)); |
|
470
|
SHA1Update(&ctx, (unsigned char*)"/", 1); |
|
471
|
SHA1Update(&ctx, (unsigned char*)zLogin, strlen(zLogin)); |
|
472
|
SHA1Update(&ctx, (unsigned char*)"/", 1); |
|
473
|
SHA1Update(&ctx, (unsigned const char*)zPw, strlen(zPw)); |
|
474
|
SHA1Final(zResult, &ctx); |
|
475
|
DigestToBase16(zResult, zDigest); |
|
476
|
return fossil_strdup(zDigest); |
|
477
|
} |
|
478
|
|
|
479
|
/* |
|
480
|
** Implement the shared_secret() SQL function. shared_secret() takes two or |
|
481
|
** three arguments; the third argument is optional. |
|
482
|
** |
|
483
|
** (1) The cleartext password |
|
484
|
** (2) The login name |
|
485
|
** (3) The project code |
|
486
|
** |
|
487
|
** Returns sha1($password/$login/$projcode). |
|
488
|
*/ |
|
489
|
void sha1_shared_secret_sql_function( |
|
490
|
sqlite3_context *context, |
|
491
|
int argc, |
|
492
|
sqlite3_value **argv |
|
493
|
){ |
|
494
|
const char *zPw; |
|
495
|
const char *zLogin; |
|
496
|
const char *zProjid; |
|
497
|
|
|
498
|
assert( argc==2 || argc==3 ); |
|
499
|
zPw = (const char*)sqlite3_value_text(argv[0]); |
|
500
|
if( zPw==0 || zPw[0]==0 ) return; |
|
501
|
zLogin = (const char*)sqlite3_value_text(argv[1]); |
|
502
|
if( zLogin==0 ) return; |
|
503
|
if( argc==3 ){ |
|
504
|
zProjid = (const char*)sqlite3_value_text(argv[2]); |
|
505
|
if( zProjid && zProjid[0]==0 ) zProjid = 0; |
|
506
|
}else{ |
|
507
|
zProjid = 0; |
|
508
|
} |
|
509
|
sqlite3_result_text(context, sha1_shared_secret(zPw, zLogin, zProjid), -1, |
|
510
|
fossil_free); |
|
511
|
} |
|
512
|
|
|
513
|
/* |
|
514
|
** COMMAND: sha1sum* |
|
515
|
** |
|
516
|
** Usage: %fossil sha1sum FILE... |
|
517
|
** |
|
518
|
** Compute an SHA1 checksum of all files named on the command-line. |
|
519
|
** If a file is named "-" then take its content from standard input. |
|
520
|
** |
|
521
|
** Options: |
|
522
|
** -h|--dereference If FILE is a symbolic link, compute the hash |
|
523
|
** on the object that the link points to. Normally, |
|
524
|
** the hash is over the name of the object that |
|
525
|
** the link points to. |
|
526
|
** |
|
527
|
** See also: [[md5sum]], [[sha3sum]] |
|
528
|
*/ |
|
529
|
void sha1sum_test(void){ |
|
530
|
int i; |
|
531
|
Blob in; |
|
532
|
Blob cksum; |
|
533
|
int eFType = SymFILE; |
|
534
|
if( find_option("dereference","h",0)!=0 ){ |
|
535
|
eFType = ExtFILE; |
|
536
|
} |
|
537
|
|
|
538
|
for(i=2; i<g.argc; i++){ |
|
539
|
blob_init(&cksum, "************** not found ***************", -1); |
|
540
|
if( g.argv[i][0]=='-' && g.argv[i][1]==0 ){ |
|
541
|
blob_read_from_channel(&in, stdin, -1); |
|
542
|
sha1sum_blob(&in, &cksum); |
|
543
|
}else{ |
|
544
|
sha1sum_file(g.argv[i], eFType, &cksum); |
|
545
|
} |
|
546
|
fossil_print("%s %s\n", blob_str(&cksum), g.argv[i]); |
|
547
|
blob_reset(&cksum); |
|
548
|
} |
|
549
|
} |
|
550
|
|