Use BLAKE2b checksum instead of SHA-1 and SHA-512

This commit is contained in:
nemunaire 2017-11-24 20:08:14 +01:00
parent 9325419002
commit e6e6e6c206
7 changed files with 58 additions and 38 deletions

View file

@ -2,7 +2,6 @@ package api
import (
"bufio"
"crypto/sha512"
"encoding/base32"
"encoding/hex"
"errors"
@ -14,6 +13,8 @@ import (
"strings"
"srs.epita.fr/fic-server/libfic"
"github.com/dchest/blake2b"
)
var CloudDAVBase string
@ -29,13 +30,13 @@ type uploadedFile struct {
}
func importFile(uf uploadedFile, next func(string, string, []byte) (interface{}, error)) (interface{}, error) {
var hash [sha512.Size]byte
var hash [blake2b.Size]byte
var logStr string
var fromURI string
var getFile func(string) error
if uf.URI != "" && len(uf.Parts) > 0 {
hash = sha512.Sum512([]byte(uf.URI))
hash = blake2b.Sum512([]byte(uf.URI))
logStr = fmt.Sprintf("Import file from Cloud: %s =>", uf.Parts)
fromURI = uf.URI
getFile = func(dest string) error {
@ -53,12 +54,12 @@ func importFile(uf uploadedFile, next func(string, string, []byte) (interface{},
return nil
}
} else if uf.URI != "" {
hash = sha512.Sum512([]byte(uf.URI))
hash = blake2b.Sum512([]byte(uf.URI))
logStr = "Import file from Cloud: " + uf.URI + " =>"
fromURI = uf.URI
getFile = func(dest string) error { return getCloudFile(uf.URI, dest) }
} else if uf.Path != "" && len(uf.Parts) > 0 {
hash = sha512.Sum512([]byte(uf.Path))
hash = blake2b.Sum512([]byte(uf.Path))
logStr = fmt.Sprintf("Import file from local FS: %s =>", uf.Parts)
fromURI = uf.Path
getFile = func(dest string) error {
@ -81,7 +82,7 @@ func importFile(uf uploadedFile, next func(string, string, []byte) (interface{},
return nil
}
} else if uf.Path != "" {
hash = sha512.Sum512([]byte(uf.Path))
hash = blake2b.Sum512([]byte(uf.Path))
logStr = "Import file from local FS: " + uf.Path + " =>"
fromURI = uf.Path
getFile = func(dest string) error { return os.Symlink(uf.Path, dest) }

View file

@ -74,6 +74,7 @@ func main() {
flag.StringVar(&api.CloudPassword, "cloudpass", "", "Password used to sync")
flag.BoolVar(&api.RapidImport, "rapidimport", false, "Don't try to reimport an existing file")
flag.BoolVar(&fic.OptionalDigest, "optionaldigest", false, "Is the digest required when importing files?")
flag.BoolVar(&fic.StrongDigest, "strongdigest", false, "Are BLAKE2b digests required instead of SHA-1 or BLAKE2b?")
flag.Parse()
log.SetPrefix("[admin] ")

View file

@ -70,7 +70,7 @@
<a ng-click="deleteFile()" class="btn btn-danger"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a>
<button type="submit" class="btn btn-success"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button><br>
Taille : <span title="{{ file.size }} octets">{{ file.size | size }}</span><br>
SHA-1 : <samp>{{ file.checksum | cksum }}</samp>
BLAKE2b sum : <samp>{{ file.checksum | cksum }}</samp>
</form>
</div>
</div>

View file

@ -21,7 +21,7 @@
<a ng-href="{{ file.path }}" target="_self" class="list-group-item" ng-repeat="file in my.exercices[current_exercice].files">
<h1 class="pull-left" style="margin: 7px 7px 5px -5px"><span class="glyphicon glyphicon-download" aria-hidden="true"></span></h1>
<h4 class="list-group-item-heading"><strong><samp>{{ file.name }}</samp></strong></h4>
<p class="list-group-item-text">Taille : <span title="{{ file.size }} octets">{{ file.size | size }}</span> &ndash; SHA-1 : <samp>{{ file.checksum }}</samp></p>
<p class="list-group-item-text">Taille : <span title="{{ file.size }} octets">{{ file.size | size }}</span> &ndash; <a href="https://blake2.net/">b2sum</a> : <samp>{{ file.checksum }}</samp></p>
</a>
</div>
</div>
@ -80,7 +80,7 @@
</div>
<div class="panel-body">
<p>
Vérifiez les clefs que vous trouvez en comparant leur SHA-512 :
Vérifiez les clefs que vous trouvez en comparant leur <a href="https://blake2.net/">BLAKE2b</a> :
</p>
<dl class="dl-horizontal" ng-repeat="key in my.exercices[current_exercice].keys">
<dt title="{{ key.slice(128) }}">{{ key.slice(128) }}</dt>

View file

@ -110,7 +110,7 @@ CREATE TABLE IF NOT EXISTS exercice_files(
path VARCHAR(255) NOT NULL UNIQUE,
id_exercice INTEGER NOT NULL,
name VARCHAR(255) NOT NULL,
sha1 BINARY(20) NOT NULL,
cksum BINARY(64) NOT NULL,
size INTEGER NOT NULL,
FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice)
);
@ -134,7 +134,7 @@ CREATE TABLE IF NOT EXISTS exercice_keys(
id_key INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
id_exercice INTEGER NOT NULL,
type VARCHAR(255) NOT NULL,
value BINARY(64) NOT NULL,
cksum BINARY(64) NOT NULL,
FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice)
);
`); err != nil {

View file

@ -9,10 +9,13 @@ import (
"os"
"path"
"strings"
"github.com/dchest/blake2b"
)
var FilesDir string
var OptionalDigest bool
var StrongDigest bool
type EFile struct {
Id int64 `json:"id"`
@ -25,7 +28,7 @@ type EFile struct {
}
func GetFiles() ([]EFile, error) {
if rows, err := DBQuery("SELECT id_file, id_exercice, origin, path, name, sha1, size FROM exercice_files"); err != nil {
if rows, err := DBQuery("SELECT id_file, id_exercice, origin, path, name, cksum, size FROM exercice_files"); err != nil {
return nil, err
} else {
defer rows.Close()
@ -47,7 +50,7 @@ func GetFiles() ([]EFile, error) {
}
func (e Exercice) GetFiles() ([]EFile, error) {
if rows, err := DBQuery("SELECT id_file, origin, path, name, sha1, size FROM exercice_files WHERE id_exercice = ?", e.Id); err != nil {
if rows, err := DBQuery("SELECT id_file, origin, path, name, cksum, size FROM exercice_files WHERE id_exercice = ?", e.Id); err != nil {
return nil, err
} else {
defer rows.Close()
@ -80,28 +83,42 @@ func (e Exercice) ImportFile(filePath string, origin string, digest []byte) (int
defer fd.Close()
reader := bufio.NewReader(fd)
hash := sha1.New()
if _, err := io.Copy(hash, reader); err != nil {
hash160 := sha1.New()
hash512 := blake2b.New512()
w := io.MultiWriter(hash160, hash512)
if _, err := io.Copy(w, reader); err != nil {
return EFile{}, err
}
result := hash.Sum(nil)
result160 := hash160.Sum(nil)
result512 := hash512.Sum(nil)
if len(digest) != len(result) {
return EFile{}, errors.New("Digests doesn't match: calculated: " + hex.EncodeToString(result) + " vs. given: " + hex.EncodeToString(digest))
}
if len(digest) != len(result512) {
if len(digest) != len(result160) {
return EFile{}, errors.New("Digests doesn't match: calculated: sha1:" + hex.EncodeToString(result160) + " & blake2b:" + hex.EncodeToString(result512) + " vs. given: " + hex.EncodeToString(digest))
} else if StrongDigest {
return EFile{}, errors.New("Invalid digests: SHA-1 checksums are no more accepted. Calculated sha1:" + hex.EncodeToString(result160) + " & blake2b:" + hex.EncodeToString(result512) + " vs. given: " + hex.EncodeToString(digest))
}
for k := range result {
if result[k] != digest[k] {
return EFile{}, errors.New("Digests doesn't match: calculated: " + hex.EncodeToString(result) + " vs. given: " + hex.EncodeToString(digest))
for k := range result160 {
if result160[k] != digest[k] {
return EFile{}, errors.New("Digests doesn't match: calculated: sha1:" + hex.EncodeToString(result160) + " & blake2b:" + hex.EncodeToString(result512) + " vs. given: " + hex.EncodeToString(digest))
}
}
} else {
for k := range result512 {
if result512[k] != digest[k] {
return EFile{}, errors.New("Digests doesn't match: calculated: " + hex.EncodeToString(result512) + " vs. given: " + hex.EncodeToString(digest))
}
}
}
return e.AddFile(strings.TrimPrefix(filePath, FilesDir), origin, path.Base(filePath), result, fi.Size())
return e.AddFile(strings.TrimPrefix(filePath, FilesDir), origin, path.Base(filePath), result512, fi.Size())
}
}
func (e Exercice) AddFile(path string, origin string, name string, checksum []byte, size int64) (EFile, error) {
if res, err := DBExec("INSERT INTO exercice_files (id_exercice, origin, path, name, sha1, size) VALUES (?, ?, ?, ?, ?, ?)", e.Id, origin, path, name, checksum, size); err != nil {
if res, err := DBExec("INSERT INTO exercice_files (id_exercice, origin, path, name, cksum, size) VALUES (?, ?, ?, ?, ?, ?)", e.Id, origin, path, name, checksum, size); err != nil {
return EFile{}, err
} else if fid, err := res.LastInsertId(); err != nil {
return EFile{}, err
@ -111,7 +128,7 @@ func (e Exercice) AddFile(path string, origin string, name string, checksum []by
}
func (f EFile) Update() (int64, error) {
if res, err := DBExec("UPDATE exercice_files SET id_exercice = ?, origin = ?, path = ?, name = ?, sha1 = ?, size = ? WHERE id_file = ?", f.IdExercice, f.origin, f.Path, f.Name, f.Checksum, f.Size, f.Id); err != nil {
if res, err := DBExec("UPDATE exercice_files SET id_exercice = ?, origin = ?, path = ?, name = ?, cksum = ?, size = ? WHERE id_file = ?", f.IdExercice, f.origin, f.Path, f.Name, f.Checksum, f.Size, f.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err
@ -130,6 +147,6 @@ func (f EFile) Delete() (int64, error) {
}
}
func (f EFile) GetOrigin() (string) {
func (f EFile) GetOrigin() string {
return f.origin
}

View file

@ -1,19 +1,20 @@
package fic
import (
"crypto/sha512"
"time"
"github.com/dchest/blake2b"
)
type Key struct {
Id int64 `json:"id"`
IdExercice int64 `json:"idExercice"`
Type string `json:"type"`
Value []byte `json:"value"`
Id int64 `json:"id"`
IdExercice int64 `json:"idExercice"`
Type string `json:"type"`
Value [blake2b.KeySize]byte `json:"value"`
}
func (e Exercice) GetKeys() ([]Key, error) {
if rows, err := DBQuery("SELECT id_key, id_exercice, type, value FROM exercice_keys WHERE id_exercice = ?", e.Id); err != nil {
if rows, err := DBQuery("SELECT id_key, id_exercice, type, cksum FROM exercice_keys WHERE id_exercice = ?", e.Id); err != nil {
return nil, err
} else {
defer rows.Close()
@ -36,17 +37,17 @@ func (e Exercice) GetKeys() ([]Key, error) {
}
}
func getHashedKey(raw_value string) []byte {
hash := sha512.Sum512([]byte(raw_value))
return hash[:]
func getHashedKey(raw_value string) [blake2b.KeySize]byte {
hash := blake2b.Sum512([]byte(raw_value))
return hash
}
func (e Exercice) AddRawKey(name string, raw_value string) (Key, error) {
return e.AddKey(name, getHashedKey(raw_value))
}
func (e Exercice) AddKey(name string, value []byte) (Key, error) {
if res, err := DBExec("INSERT INTO exercice_keys (id_exercice, type, value) VALUES (?, ?, ?)", e.Id, name, value); err != nil {
func (e Exercice) AddKey(name string, value [blake2b.KeySize]byte) (Key, error) {
if res, err := DBExec("INSERT INTO exercice_keys (id_exercice, type, cksum) VALUES (?, ?, ?)", e.Id, name, value); err != nil {
return Key{}, err
} else if kid, err := res.LastInsertId(); err != nil {
return Key{}, err
@ -56,7 +57,7 @@ func (e Exercice) AddKey(name string, value []byte) (Key, error) {
}
func (k Key) Update() (int64, error) {
if res, err := DBExec("UPDATE exercice_keys SET id_exercice = ?, type = ?, value = ? WHERE id_key = ?", k.IdExercice, k.Type, k.Value, k.Id); err != nil {
if res, err := DBExec("UPDATE exercice_keys SET id_exercice = ?, type = ?, cksum = ? WHERE id_key = ?", k.IdExercice, k.Type, k.Value, k.Id); err != nil {
return 0, err
} else if nb, err := res.RowsAffected(); err != nil {
return 0, err