1 #pragma once 2 3 #include "types.hh" 4 #include "serialise.hh" 5 6 7 namespace nix { 8 9 10 MakeError(BadHash, Error); 11 12 13 enum HashType : char { htUnknown, htMD5, htSHA1, htSHA256, htSHA512 }; 14 15 16 const int md5HashSize = 16; 17 const int sha1HashSize = 20; 18 const int sha256HashSize = 32; 19 const int sha512HashSize = 64; 20 21 extern const string base32Chars; 22 23 enum Base : int { Base64, Base32, Base16, SRI }; 24 25 26 struct Hash 27 { 28 static const unsigned int maxHashSize = 64; 29 unsigned int hashSize = 0; 30 unsigned char hash[maxHashSize] = {}; 31 32 HashType type = htUnknown; 33 34 /* Create an unset hash object. */ Hashnix::Hash35 Hash() { }; 36 37 /* Create a zero-filled hash object. */ Hashnix::Hash38 Hash(HashType type) : type(type) { init(); }; 39 40 /* Initialize the hash from a string representation, in the format 41 "[<type>:]<base16|base32|base64>" or "<type>-<base64>" (a 42 Subresource Integrity hash expression). If the 'type' argument 43 is htUnknown, then the hash type must be specified in the 44 string. */ 45 Hash(const std::string & s, HashType type = htUnknown); 46 47 void init(); 48 49 /* Check whether a hash is set. */ operator boolnix::Hash50 operator bool () const { return type != htUnknown; } 51 52 /* Check whether two hash are equal. */ 53 bool operator == (const Hash & h2) const; 54 55 /* Check whether two hash are not equal. */ 56 bool operator != (const Hash & h2) const; 57 58 /* For sorting. */ 59 bool operator < (const Hash & h) const; 60 61 /* Returns the length of a base-16 representation of this hash. */ base16Lennix::Hash62 size_t base16Len() const 63 { 64 return hashSize * 2; 65 } 66 67 /* Returns the length of a base-32 representation of this hash. */ base32Lennix::Hash68 size_t base32Len() const 69 { 70 return (hashSize * 8 - 1) / 5 + 1; 71 } 72 73 /* Returns the length of a base-64 representation of this hash. */ base64Lennix::Hash74 size_t base64Len() const 75 { 76 return ((4 * hashSize / 3) + 3) & ~3; 77 } 78 79 /* Return a string representation of the hash, in base-16, base-32 80 or base-64. By default, this is prefixed by the hash type 81 (e.g. "sha256:"). */ 82 std::string to_string(Base base = Base32, bool includeType = true) const; 83 }; 84 85 86 /* Print a hash in base-16 if it's MD5, or base-32 otherwise. */ 87 string printHash16or32(const Hash & hash); 88 89 /* Compute the hash of the given string. */ 90 Hash hashString(HashType ht, const string & s); 91 92 /* Compute the hash of the given file. */ 93 Hash hashFile(HashType ht, const Path & path); 94 95 /* Compute the hash of the given path. The hash is defined as 96 (essentially) hashString(ht, dumpPath(path)). */ 97 typedef std::pair<Hash, unsigned long long> HashResult; 98 HashResult hashPath(HashType ht, const Path & path, 99 PathFilter & filter = defaultPathFilter); 100 101 /* Compress a hash to the specified number of bytes by cyclically 102 XORing bytes together. */ 103 Hash compressHash(const Hash & hash, unsigned int newSize); 104 105 /* Parse a string representing a hash type. */ 106 HashType parseHashType(const string & s); 107 108 /* And the reverse. */ 109 string printHashType(HashType ht); 110 111 112 union Ctx; 113 114 class HashSink : public BufferedSink 115 { 116 private: 117 HashType ht; 118 Ctx * ctx; 119 unsigned long long bytes; 120 121 public: 122 HashSink(HashType ht); 123 HashSink(const HashSink & h); 124 ~HashSink(); 125 void write(const unsigned char * data, size_t len); 126 HashResult finish(); 127 HashResult currentHash(); 128 }; 129 130 131 } 132