/* GoCheese -- Python private package repository and caching proxy Copyright (C) 2019-2020 Elena Balakhonova This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package main import ( "bytes" "encoding/base64" "errors" "fmt" "strings" "golang.org/x/crypto/argon2" ) type Argon2iAuthData struct { version int memory uint32 time uint32 threads uint8 salt []byte password []byte } func (ad Argon2iAuthData) Auth(password string) bool { hashedPassword := argon2.Key( []byte(password), ad.salt, ad.time, ad.memory, ad.threads, uint32(len(ad.password)), ) return bytes.Equal(hashedPassword, ad.password) } func parseArgon2i(params string) (Auther, error) { var time, memory uint32 var threads uint8 var version int var saltAndPasswordUnitedB64 string n, err := fmt.Sscanf( params, "v=%d$m=%d,t=%d,p=%d$%s", &version, &memory, &time, &threads, &saltAndPasswordUnitedB64, ) if n != 5 || err != nil { return nil, fmt.Errorf("argon2i parameters %q have wrong format", params) } if version != argon2.Version { return nil, errors.New("unsupported argon2i version") } saltAndPasswordSplittedB64 := strings.Split(saltAndPasswordUnitedB64, "$") salt, err := base64.RawStdEncoding.DecodeString(saltAndPasswordSplittedB64[0]) if err != nil { return nil, errors.New("invalid salt format") } password, err := base64.RawStdEncoding.DecodeString(saltAndPasswordSplittedB64[1]) if err != nil { return nil, errors.New("invalid password format") } return Argon2iAuthData{ version: version, time: time, memory: memory, threads: threads, salt: salt, password: password, }, nil }