X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=argon2i.go;fp=argon2i.go;h=d83a8fc97d987fadf562147b19e3a0d703081464;hb=bb73b0ffb472af0f90676aa24fd092475485565e;hp=0000000000000000000000000000000000000000;hpb=beb994417f69cf1dbb197e904477f4fbb39f2677;p=gocheese.git diff --git a/argon2i.go b/argon2i.go new file mode 100644 index 0000000..d83a8fc --- /dev/null +++ b/argon2i.go @@ -0,0 +1,89 @@ +/* +GoCheese -- Python private package repository and caching proxy +Copyright (C) 2019 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 . +*/ + +// Python private package repository and caching proxy +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 +}