mirror of
https://github.com/NixOS/nix
synced 2025-07-06 21:41:48 +02:00
Support SRI hashes
SRI hashes (https://www.w3.org/TR/SRI/) combine the hash algorithm and a base-64 hash. This allows more concise and standard hash specifications. For example, instead of import <nix/fetchurl.nl> { url = https://nixos.org/releases/nix/nix-2.1.3/nix-2.1.3.tar.xz; sha256 = "5d22dad058d5c800d65a115f919da22938c50dd6ba98c5e3a183172d149840a4"; }; you can write import <nix/fetchurl.nl> { url = https://nixos.org/releases/nix/nix-2.1.3/nix-2.1.3.tar.xz; hash = "sha256-XSLa0FjVyADWWhFfkZ2iKTjFDda6mMXjoYMXLRSYQKQ="; }; In fixed-output derivations, the outputHashAlgo is no longer mandatory if outputHash specifies the hash (either as an SRI or in the old "<type>:<hash>" format). 'nix hash-{file,path}' now print hashes in SRI format by default. I also reverted them to use SHA-256 by default because that's what we're using most of the time in Nixpkgs. Suggested by @zimbatm.
This commit is contained in:
parent
c37e6d77ea
commit
6024dc1d97
8 changed files with 72 additions and 34 deletions
|
@ -105,9 +105,9 @@ string printHash16or32(const Hash & hash)
|
|||
std::string Hash::to_string(Base base, bool includeType) const
|
||||
{
|
||||
std::string s;
|
||||
if (includeType) {
|
||||
if (base == SRI || includeType) {
|
||||
s += printHashType(type);
|
||||
s += ':';
|
||||
s += base == SRI ? '-' : ':';
|
||||
}
|
||||
switch (base) {
|
||||
case Base16:
|
||||
|
@ -117,6 +117,7 @@ std::string Hash::to_string(Base base, bool includeType) const
|
|||
s += printHash32(*this);
|
||||
break;
|
||||
case Base64:
|
||||
case SRI:
|
||||
s += base64Encode(std::string((const char *) hash, hashSize));
|
||||
break;
|
||||
}
|
||||
|
@ -127,28 +128,33 @@ std::string Hash::to_string(Base base, bool includeType) const
|
|||
Hash::Hash(const std::string & s, HashType type)
|
||||
: type(type)
|
||||
{
|
||||
auto colon = s.find(':');
|
||||
|
||||
size_t pos = 0;
|
||||
bool isSRI = false;
|
||||
|
||||
if (colon == string::npos) {
|
||||
if (type == htUnknown)
|
||||
auto sep = s.find(':');
|
||||
if (sep == string::npos) {
|
||||
sep = s.find('-');
|
||||
if (sep != string::npos) {
|
||||
isSRI = true;
|
||||
} else if (type == htUnknown)
|
||||
throw BadHash("hash '%s' does not include a type", s);
|
||||
} else {
|
||||
string hts = string(s, 0, colon);
|
||||
}
|
||||
|
||||
if (sep != string::npos) {
|
||||
string hts = string(s, 0, sep);
|
||||
this->type = parseHashType(hts);
|
||||
if (this->type == htUnknown)
|
||||
throw BadHash("unknown hash type '%s'", hts);
|
||||
if (type != htUnknown && type != this->type)
|
||||
throw BadHash("hash '%s' should have type '%s'", s, printHashType(type));
|
||||
pos = colon + 1;
|
||||
pos = sep + 1;
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
size_t size = s.size() - pos;
|
||||
|
||||
if (size == base16Len()) {
|
||||
if (!isSRI && size == base16Len()) {
|
||||
|
||||
auto parseHexDigit = [&](char c) {
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
|
@ -164,7 +170,7 @@ Hash::Hash(const std::string & s, HashType type)
|
|||
}
|
||||
}
|
||||
|
||||
else if (size == base32Len()) {
|
||||
else if (!isSRI && size == base32Len()) {
|
||||
|
||||
for (unsigned int n = 0; n < size; ++n) {
|
||||
char c = s[pos + size - n - 1];
|
||||
|
@ -187,10 +193,10 @@ Hash::Hash(const std::string & s, HashType type)
|
|||
}
|
||||
}
|
||||
|
||||
else if (size == base64Len()) {
|
||||
else if (isSRI || size == base64Len()) {
|
||||
auto d = base64Decode(std::string(s, pos));
|
||||
if (d.size() != hashSize)
|
||||
throw BadHash("invalid base-64 hash '%s'", s);
|
||||
throw BadHash("invalid %s hash '%s'", isSRI ? "SRI" : "base-64", s);
|
||||
assert(hashSize);
|
||||
memcpy(hash, d.data(), hashSize);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue