1 /*
2 ** Copyright (c) 2017 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 **   drh@hwaci.com
14 **   http://www.hwaci.com/drh/
15 **
16 *******************************************************************************
17 **
18 ** This file contains generic code for dealing with hashes used for
19 ** naming artifacts.  Specific hash algorithms are implemented separately
20 ** (for example in sha1.c and sha3.c).  This file contains the generic
21 ** interface logic.
22 **
23 ** "hname" is intended to be an abbreviation of "hash name".
24 */
25 #include "config.h"
26 #include "hname.h"
27 
28 
29 #if INTERFACE
30 /*
31 ** Code numbers for the allowed hash algorithms.
32 */
33 #define HNAME_ERROR  0      /* Not a valid hash */
34 #define HNAME_SHA1   1      /* SHA1 */
35 #define HNAME_K256   2      /* SHA3-256 */
36 
37 /*
38 ** Minimum and maximum lengths for a hash value when hex encoded.
39 */
40 #define HNAME_MIN  40     /* Length for SHA1 */
41 #define HNAME_MAX  64     /* Length for SHA3-256 */
42 
43 /*
44 ** Hash lengths for the various algorithms
45 */
46 #define HNAME_LEN_SHA1   40
47 #define HNAME_LEN_K256   64
48 
49 /*
50 ** The number of distinct hash algorithms:
51 */
52 #define HNAME_COUNT 2     /* Just SHA1 and SHA3-256. Let's keep it that way! */
53 
54 /*
55 ** Hash naming policies
56 */
57 #define HPOLICY_SHA1           0      /* Use SHA1 hashes */
58 #define HPOLICY_AUTO           1      /* SHA1 but auto-promote to SHA3 */
59 #define HPOLICY_SHA3           2      /* Use SHA3 hashes */
60 #define HPOLICY_SHA3_ONLY      3      /* Use SHA3 hashes exclusively */
61 #define HPOLICY_SHUN_SHA1      4      /* Shun all SHA1 objects */
62 
63 #endif /* INTERFACE */
64 
65 /*
66 ** Return a human-readable name for the hash algorithm given a hash with
67 ** a length of nHash hexadecimal digits.
68 */
hname_alg(int nHash)69 const char *hname_alg(int nHash){
70   if( nHash==HNAME_LEN_SHA1 ) return "SHA1";
71   if( nHash==HNAME_LEN_K256 ) return "SHA3-256";
72   return "?";
73 }
74 
75 /*
76 ** Return the integer hash algorithm code number (ex: HNAME_K256) for
77 ** the hash string provided.  Or return HNAME_ERROR (0) if the input string
78 ** is not a valid artifact hash string.
79 */
hname_validate(const char * zHash,int nHash)80 int hname_validate(const char *zHash, int nHash){
81   int id;
82   switch( nHash ){
83     case HNAME_LEN_SHA1:   id = HNAME_SHA1;  break;
84     case HNAME_LEN_K256:   id = HNAME_K256;  break;
85     default:               return HNAME_ERROR;
86   }
87   if( !validate16(zHash, nHash) ) return HNAME_ERROR;
88   return id;
89 }
90 
91 /*
92 ** Verify that zHash is a valid hash for the content in pContent.
93 ** Return true if the hash is correct.  Return false if the content
94 ** does not match the hash.
95 **
96 ** Actually, the returned value is one of the hash algorithm constants
97 ** corresponding to the hash that matched if the hash is correct.
98 ** (Examples: HNAME_SHA1 or HNAME_K256).  And the return is HNAME_ERROR
99 ** if the hash does not match.
100 */
hname_verify_hash(Blob * pContent,const char * zHash,int nHash)101 int hname_verify_hash(Blob *pContent, const char *zHash, int nHash){
102   int id = HNAME_ERROR;
103   switch( nHash ){
104     case HNAME_LEN_SHA1: {
105       Blob hash;
106       sha1sum_blob(pContent, &hash);
107       if( memcmp(blob_buffer(&hash),zHash,HNAME_LEN_SHA1)==0 ) id = HNAME_SHA1;
108       blob_reset(&hash);
109       break;
110     }
111     case HNAME_LEN_K256: {
112       sha3sum_init(256);
113       sha3sum_step_blob(pContent);
114       if( memcmp(sha3sum_finish(0),zHash,64)==0 ) id = HNAME_K256;
115       break;
116     }
117   }
118   return id;
119 }
120 
121 /*
122 ** Verify that zHash is a valid hash for the content of a file on
123 ** disk named zFile.
124 **
125 ** Return true if the hash is correct.  Return false if the content
126 ** does not match the hash.
127 **
128 ** Actually, the returned value is one of the hash algorithm constants
129 ** corresponding to the hash that matched if the hash is correct.
130 ** (Examples: HNAME_SHA1 or HNAME_K256).  And the return is HNAME_ERROR
131 ** if the hash does not match.
132 */
hname_verify_file_hash(const char * zFile,const char * zHash,int nHash)133 int hname_verify_file_hash(const char *zFile, const char *zHash, int nHash){
134   int id = HNAME_ERROR;
135   switch( nHash ){
136     case HNAME_LEN_SHA1: {
137       Blob hash;
138       if( sha1sum_file(zFile, RepoFILE, &hash) ) break;
139       if( memcmp(blob_buffer(&hash),zHash,HNAME_LEN_SHA1)==0 ) id = HNAME_SHA1;
140       blob_reset(&hash);
141       break;
142     }
143     case HNAME_LEN_K256: {
144       Blob hash;
145       if( sha3sum_file(zFile, RepoFILE, 256, &hash) ) break;
146       if( memcmp(blob_buffer(&hash),zHash,64)==0 ) id = HNAME_LEN_K256;
147       blob_reset(&hash);
148       break;
149     }
150   }
151   return id;
152 }
153 
154 /*
155 ** Compute a hash on blob pContent.  Write the hash into blob pHashOut.
156 ** This routine assumes that pHashOut is uninitialized.
157 **
158 ** The preferred hash is used for iHType==0 and the alternative hash is
159 ** used if iHType==1.  (The interface is designed to accommodate more than
160 ** just two hashes, but HNAME_COUNT is currently fixed at 2.)
161 **
162 ** Depending on the hash policy, the alternative hash may be disallowed.
163 ** If the alterative hash is disallowed, the routine returns 0.  This
164 ** routine returns 1 if iHType>0 and the alternative hash is allowed,
165 ** and it always returns 1 when iHType==0.
166 **
167 ** Alternative hash is disallowed for all hash policies except auto,
168 ** sha1 and sha3.
169 */
hname_hash(const Blob * pContent,unsigned int iHType,Blob * pHashOut)170 int hname_hash(const Blob *pContent, unsigned int iHType, Blob *pHashOut){
171   assert( iHType==0 || iHType==1 );
172   if( iHType==1 ){
173     switch( g.eHashPolicy ){
174       case HPOLICY_AUTO:
175       case HPOLICY_SHA1:
176         sha3sum_blob(pContent, 256, pHashOut);
177         return 1;
178       case HPOLICY_SHA3:
179         sha1sum_blob(pContent, pHashOut);
180         return 1;
181     }
182   }
183   if( iHType==0 ){
184     switch( g.eHashPolicy ){
185       case HPOLICY_SHA1:
186       case HPOLICY_AUTO:
187         sha1sum_blob(pContent, pHashOut);
188         return 1;
189       case HPOLICY_SHA3:
190       case HPOLICY_SHA3_ONLY:
191       case HPOLICY_SHUN_SHA1:
192         sha3sum_blob(pContent, 256, pHashOut);
193         return 1;
194     }
195   }
196   blob_init(pHashOut, 0, 0);
197   return 0;
198 }
199 
200 /*
201 ** Return the default hash policy for repositories that do not currently
202 ** have an assigned hash policy.
203 **
204 ** Make the default HPOLICY_AUTO if there are SHA1 artficates but no SHA3
205 ** artifacts in the repository.  Make the default HPOLICY_SHA3 if there
206 ** are one or more SHA3 artifacts or if the repository is initially empty.
207 */
hname_default_policy(void)208 int hname_default_policy(void){
209   if( db_exists("SELECT 1 FROM blob WHERE length(uuid)>40")
210    || !db_exists("SELECT 1 FROM blob WHERE length(uuid)==40")
211   ){
212     return HPOLICY_SHA3;
213   }else{
214     return HPOLICY_AUTO;
215   }
216 }
217 
218 /*
219 ** Names of the hash policies.
220 */
221 static const char *const azPolicy[] = {
222   "sha1", "auto", "sha3", "sha3-only", "shun-sha1"
223 };
224 
225 /* Return the name of the current hash policy.
226 */
hpolicy_name(void)227 const char *hpolicy_name(void){
228   return azPolicy[g.eHashPolicy];
229 }
230 
231 
232 /*
233 ** COMMAND: hash-policy*
234 **
235 ** Usage: fossil hash-policy ?NEW-POLICY?
236 **
237 ** Query or set the hash policy for the current repository.  Available hash
238 ** policies are as follows:
239 **
240 **   sha1              New artifact names are created using SHA1
241 **
242 **   auto              New artifact names are created using SHA1, but
243 **                     automatically change the policy to "sha3" when
244 **                     any SHA3 artifact enters the repository.
245 **
246 **   sha3              New artifact names are created using SHA3, but
247 **                     older artifacts with SHA1 names may be reused.
248 **
249 **   sha3-only         Use only SHA3 artifact names.  Do not reuse legacy
250 **                     SHA1 names.
251 **
252 **   shun-sha1         Shun any SHA1 artifacts received by sync operations
253 **                     other than clones.  Older legacy SHA1 artifacts are
254 **                     allowed during a clone.
255 **
256 ** The default hash policy for existing repositories is "auto", which will
257 ** immediately promote to "sha3" if the repository contains one or more
258 ** artifacts with SHA3 names.  The default hash policy for new repositories
259 ** is "shun-sha1".
260 */
hash_policy_command(void)261 void hash_policy_command(void){
262   int i;
263   db_find_and_open_repository(0, 0);
264   if( g.argc!=2 && g.argc!=3 ) usage("?NEW-POLICY?");
265   if( g.argc==2 ){
266     fossil_print("%s\n", azPolicy[g.eHashPolicy]);
267     return;
268   }
269   for(i=HPOLICY_SHA1; i<=HPOLICY_SHUN_SHA1; i++){
270     if( fossil_strcmp(g.argv[2],azPolicy[i])==0 ){
271       if( i==HPOLICY_AUTO
272        && db_exists("SELECT 1 FROM blob WHERE length(uuid)>40")
273       ){
274         i = HPOLICY_SHA3;
275       }
276       g.eHashPolicy = i;
277       db_set_int("hash-policy", i, 0);
278       fossil_print("%s\n", azPolicy[i]);
279       return;
280     }
281   }
282   fossil_fatal("unknown hash policy \"%s\" - should be one of: sha1 auto"
283                " sha3 sha3-only shun-sha1", g.argv[2]);
284 }
285