You've already forked nyx
mirror of
https://github.com/rls-moe/nyx
synced 2025-09-13 12:04:13 +00:00
MVP, no mod tools or anything but it works
This commit is contained in:
72
vendor/gopkg.in/hlandau/passlib.v1/hash/bcrypt/bcrypt.go
generated
vendored
Normal file
72
vendor/gopkg.in/hlandau/passlib.v1/hash/bcrypt/bcrypt.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// Package bcrypt implements the bcrypt password hashing mechanism.
|
||||
//
|
||||
// Please note that bcrypt truncates passwords to 72 characters in length. Consider using
|
||||
// a more modern hashing scheme such as scrypt or sha-crypt. If you must use bcrypt,
|
||||
// consider using bcrypt-sha256 instead.
|
||||
package bcrypt
|
||||
|
||||
import "golang.org/x/crypto/bcrypt"
|
||||
import "gopkg.in/hlandau/passlib.v1/abstract"
|
||||
import "fmt"
|
||||
|
||||
// An implementation of Scheme implementing bcrypt.
|
||||
//
|
||||
// Uses RecommendedCost.
|
||||
var Crypter abstract.Scheme
|
||||
|
||||
// The recommended cost for bcrypt. This may change with subsequent releases.
|
||||
const RecommendedCost = 12
|
||||
|
||||
// bcrypt.DefaultCost is a bit low (10), so use 12 instead.
|
||||
|
||||
func init() {
|
||||
Crypter = New(RecommendedCost)
|
||||
}
|
||||
|
||||
// Create a new scheme implementing bcrypt. The recommended cost is RecommendedCost.
|
||||
func New(cost int) abstract.Scheme {
|
||||
return &scheme{
|
||||
Cost: cost,
|
||||
}
|
||||
}
|
||||
|
||||
type scheme struct {
|
||||
Cost int
|
||||
}
|
||||
|
||||
func (s *scheme) SupportsStub(stub string) bool {
|
||||
return len(stub) >= 3 && stub[0] == '$' && stub[1] == '2' &&
|
||||
(stub[2] == '$' || (len(stub) >= 4 && stub[3] == '$' &&
|
||||
(stub[2] == 'a' || stub[2] == 'b' || stub[2] == 'y')))
|
||||
}
|
||||
|
||||
func (s *scheme) Hash(password string) (string, error) {
|
||||
h, err := bcrypt.GenerateFromPassword([]byte(password), s.Cost)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(h), nil
|
||||
}
|
||||
|
||||
func (s *scheme) Verify(password, hash string) error {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||
if err == bcrypt.ErrMismatchedHashAndPassword {
|
||||
err = abstract.ErrInvalidPassword
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *scheme) NeedsUpdate(stub string) bool {
|
||||
cost, err := bcrypt.Cost([]byte(stub))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return cost < s.Cost
|
||||
}
|
||||
|
||||
func (s *scheme) String() string {
|
||||
return fmt.Sprintf("bcrypt(%d)", s.Cost)
|
||||
}
|
96
vendor/gopkg.in/hlandau/passlib.v1/hash/bcryptsha256/bcryptsha256.go
generated
vendored
Normal file
96
vendor/gopkg.in/hlandau/passlib.v1/hash/bcryptsha256/bcryptsha256.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
// Package bcryptsha256 implements bcrypt with a SHA256 prehash in a format that is compatible with Python passlib's equivalent bcrypt-sha256 scheme.
|
||||
//
|
||||
// This is preferred over bcrypt because the prehash essentially renders bcrypt's password length
|
||||
// limitation irrelevant; although of course it is less compatible.
|
||||
package bcryptsha256
|
||||
|
||||
import "gopkg.in/hlandau/passlib.v1/abstract"
|
||||
import "gopkg.in/hlandau/passlib.v1/hash/bcrypt"
|
||||
import "encoding/base64"
|
||||
import "crypto/sha256"
|
||||
import "strings"
|
||||
import "fmt"
|
||||
|
||||
type scheme struct {
|
||||
underlying abstract.Scheme
|
||||
cost int
|
||||
}
|
||||
|
||||
// An implementation of Scheme implementing Python passlib's `$bcrypt-sha256$`
|
||||
// bcrypt variant. This is bcrypt with a SHA256 prehash, which removes bcrypt's
|
||||
// password length limitation.
|
||||
var Crypter abstract.Scheme
|
||||
|
||||
// The recommended cost for bcrypt-sha256. This may change with subsequent releases.
|
||||
const RecommendedCost = bcrypt.RecommendedCost
|
||||
|
||||
func init() {
|
||||
Crypter = New(bcrypt.RecommendedCost)
|
||||
}
|
||||
|
||||
// Instantiates a new Scheme implementing bcrypt with the given cost.
|
||||
//
|
||||
// The recommended cost is RecommendedCost.
|
||||
func New(cost int) abstract.Scheme {
|
||||
return &scheme{
|
||||
underlying: bcrypt.New(cost),
|
||||
cost: cost,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *scheme) Hash(password string) (string, error) {
|
||||
p := s.prehash(password)
|
||||
h, err := s.underlying.Hash(p)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return mangle(h), nil
|
||||
}
|
||||
|
||||
func (s *scheme) Verify(password, hash string) error {
|
||||
p := s.prehash(password)
|
||||
return s.underlying.Verify(p, demangle(hash))
|
||||
}
|
||||
|
||||
func (s *scheme) prehash(password string) string {
|
||||
h := sha256.New()
|
||||
h.Write([]byte(password))
|
||||
v := base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
return v
|
||||
}
|
||||
|
||||
func (s *scheme) SupportsStub(stub string) bool {
|
||||
return strings.HasPrefix(stub, "$bcrypt-sha256$") && s.underlying.SupportsStub(demangle(stub))
|
||||
}
|
||||
|
||||
func (s *scheme) NeedsUpdate(stub string) bool {
|
||||
return s.underlying.NeedsUpdate(demangle(stub))
|
||||
}
|
||||
|
||||
func (s *scheme) String() string {
|
||||
return fmt.Sprintf("bcrypt-sha256(%d)", s.cost)
|
||||
}
|
||||
|
||||
func demangle(stub string) string {
|
||||
if strings.HasPrefix(stub, "$bcrypt-sha256$2") {
|
||||
parts := strings.Split(stub[15:], "$")
|
||||
// 0: 2a,12
|
||||
// 1: salt
|
||||
// 2: hash
|
||||
parts0 := strings.Split(parts[0], ",")
|
||||
return "$" + parts0[0] + "$" + fmt.Sprintf("%02s", parts0[1]) + "$" + parts[1] + parts[2]
|
||||
} else {
|
||||
return stub
|
||||
}
|
||||
}
|
||||
|
||||
func mangle(hash string) string {
|
||||
parts := strings.Split(hash[1:], "$")
|
||||
// 0: 2a
|
||||
// 1: rounds
|
||||
// 2: salt + hash
|
||||
salt := parts[2][0:22]
|
||||
h := parts[2][22:]
|
||||
return "$bcrypt-sha256$" + parts[0] + "," + parts[1] + "$" + salt + "$" + h
|
||||
}
|
95
vendor/gopkg.in/hlandau/passlib.v1/hash/scrypt/raw/scrypt.go
generated
vendored
Normal file
95
vendor/gopkg.in/hlandau/passlib.v1/hash/scrypt/raw/scrypt.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// Package raw provides a raw implementation of the modular-crypt-wrapped scrypt primitive.
|
||||
package raw
|
||||
|
||||
import "golang.org/x/crypto/scrypt"
|
||||
import "encoding/base64"
|
||||
import "strings"
|
||||
import "strconv"
|
||||
import "fmt"
|
||||
|
||||
// The current recommended N value for interactive logins.
|
||||
const RecommendedN = 16384
|
||||
|
||||
// The current recommended r value for interactive logins.
|
||||
const Recommendedr = 8
|
||||
|
||||
// The current recommended p value for interactive logins.
|
||||
const Recommendedp = 1
|
||||
|
||||
// Wrapper for golang.org/x/crypto/scrypt implementing a sensible
|
||||
// modular crypt interface.
|
||||
//
|
||||
// password should be a UTF-8 plaintext password.
|
||||
// salt should be a random salt value in binary form.
|
||||
//
|
||||
// N, r and p are parameters to scrypt.
|
||||
//
|
||||
// Returns a modular crypt hash.
|
||||
func ScryptSHA256(password string, salt []byte, N, r, p int) string {
|
||||
passwordb := []byte(password)
|
||||
|
||||
hash, err := scrypt.Key(passwordb, salt, N, r, p, 32)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
hstr := base64.StdEncoding.EncodeToString(hash)
|
||||
sstr := base64.StdEncoding.EncodeToString(salt)
|
||||
|
||||
return fmt.Sprintf("$s2$%d$%d$%d$%s$%s", N, r, p, sstr, hstr)
|
||||
}
|
||||
|
||||
// Indicates that a password hash or stub is invalid.
|
||||
var ErrInvalidStub = fmt.Errorf("invalid scrypt password stub")
|
||||
|
||||
// Parses an scrypt modular hash or stub string.
|
||||
//
|
||||
// The format is as follows:
|
||||
//
|
||||
// $s2$N$r$p$salt$hash // hash
|
||||
// $s2$N$r$p$salt // stub
|
||||
//
|
||||
func Parse(stub string) (salt, hash []byte, N, r, p int, err error) {
|
||||
if len(stub) < 10 || !strings.HasPrefix(stub, "$s2$") {
|
||||
err = ErrInvalidStub
|
||||
return
|
||||
}
|
||||
|
||||
// $s2$ N$r$p$salt-base64$hash-base64
|
||||
parts := strings.Split(stub[4:], "$")
|
||||
|
||||
if len(parts) < 4 {
|
||||
err = ErrInvalidStub
|
||||
return
|
||||
}
|
||||
|
||||
var Ni, ri, pi uint64
|
||||
|
||||
Ni, err = strconv.ParseUint(parts[0], 10, 31)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ri, err = strconv.ParseUint(parts[1], 10, 31)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
pi, err = strconv.ParseUint(parts[2], 10, 31)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
N, r, p = int(Ni), int(ri), int(pi)
|
||||
|
||||
salt, err = base64.StdEncoding.DecodeString(parts[3])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(parts) >= 5 {
|
||||
hash, err = base64.StdEncoding.DecodeString(parts[4])
|
||||
}
|
||||
|
||||
return
|
||||
}
|
113
vendor/gopkg.in/hlandau/passlib.v1/hash/scrypt/scrypt.go
generated
vendored
Normal file
113
vendor/gopkg.in/hlandau/passlib.v1/hash/scrypt/scrypt.go
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
// Package scrypt implements the scrypt password hashing mechanism, wrapped in
|
||||
// the modular crypt format.
|
||||
package scrypt
|
||||
|
||||
import "fmt"
|
||||
import "expvar"
|
||||
import "strings"
|
||||
import "crypto/rand"
|
||||
import "encoding/base64"
|
||||
import "gopkg.in/hlandau/passlib.v1/hash/scrypt/raw"
|
||||
import "gopkg.in/hlandau/passlib.v1/abstract"
|
||||
|
||||
var cScryptSHA256HashCalls = expvar.NewInt("passlib.scryptsha256.hashCalls")
|
||||
var cScryptSHA256VerifyCalls = expvar.NewInt("passlib.scryptsha256.verifyCalls")
|
||||
|
||||
// An implementation of Scheme performing scrypt-sha256.
|
||||
//
|
||||
// Uses the recommended values for N,r,p defined in raw.
|
||||
var SHA256Crypter abstract.Scheme
|
||||
|
||||
func init() {
|
||||
SHA256Crypter = NewSHA256(
|
||||
raw.RecommendedN,
|
||||
raw.Recommendedr,
|
||||
raw.Recommendedp,
|
||||
)
|
||||
}
|
||||
|
||||
// Returns an implementation of Scheme implementing scrypt-sha256
|
||||
// with the specified parameters.
|
||||
func NewSHA256(N, r, p int) abstract.Scheme {
|
||||
return &scryptSHA256Crypter{
|
||||
nN: N,
|
||||
r: r,
|
||||
p: p,
|
||||
}
|
||||
}
|
||||
|
||||
type scryptSHA256Crypter struct {
|
||||
nN, r, p int
|
||||
}
|
||||
|
||||
func (c *scryptSHA256Crypter) SetParams(N, r, p int) error {
|
||||
c.nN = N
|
||||
c.r = r
|
||||
c.p = p
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *scryptSHA256Crypter) SupportsStub(stub string) bool {
|
||||
return strings.HasPrefix(stub, "$s2$")
|
||||
}
|
||||
|
||||
func (c *scryptSHA256Crypter) Hash(password string) (string, error) {
|
||||
cScryptSHA256HashCalls.Add(1)
|
||||
|
||||
stub, err := c.makeStub()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, newHash, _, _, _, _, err := c.hash(password, stub)
|
||||
return newHash, err
|
||||
}
|
||||
|
||||
func (c *scryptSHA256Crypter) Verify(password, hash string) (err error) {
|
||||
cScryptSHA256VerifyCalls.Add(1)
|
||||
|
||||
_, newHash, _, _, _, _, err := c.hash(password, hash)
|
||||
if err == nil && !abstract.SecureCompare(hash, newHash) {
|
||||
err = abstract.ErrInvalidPassword
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *scryptSHA256Crypter) NeedsUpdate(stub string) bool {
|
||||
salt, _, N, r, p, err := raw.Parse(stub)
|
||||
if err != nil {
|
||||
return false // ...
|
||||
}
|
||||
|
||||
return c.needsUpdate(salt, N, r, p)
|
||||
}
|
||||
|
||||
func (c *scryptSHA256Crypter) needsUpdate(salt []byte, N, r, p int) bool {
|
||||
return len(salt) < 18 || N < c.nN || r < c.r || p < c.p
|
||||
}
|
||||
|
||||
func (c *scryptSHA256Crypter) hash(password, stub string) (oldHashRaw []byte, newHash string, salt []byte, N, r, p int, err error) {
|
||||
salt, oldHashRaw, N, r, p, err = raw.Parse(stub)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return oldHashRaw, raw.ScryptSHA256(password, salt, N, r, p), salt, N, r, p, nil
|
||||
}
|
||||
|
||||
func (c *scryptSHA256Crypter) makeStub() (string, error) {
|
||||
buf := make([]byte, 18)
|
||||
_, err := rand.Read(buf)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
salt := base64.StdEncoding.EncodeToString(buf)
|
||||
|
||||
return fmt.Sprintf("$s2$%d$%d$%d$%s", c.nN, c.r, c.p, salt), nil
|
||||
}
|
||||
|
||||
func (c *scryptSHA256Crypter) String() string {
|
||||
return fmt.Sprintf("scrypt-sha256(%d,%d,%d)", c.nN, c.r, c.p)
|
||||
}
|
34
vendor/gopkg.in/hlandau/passlib.v1/hash/sha2crypt/raw/base64.go
generated
vendored
Normal file
34
vendor/gopkg.in/hlandau/passlib.v1/hash/sha2crypt/raw/base64.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package raw
|
||||
|
||||
const bmap = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
// Encodes a byte string using the sha2-crypt base64 variant.
|
||||
func EncodeBase64(b []byte) string {
|
||||
o := make([]byte, len(b)/3*4+4)
|
||||
|
||||
for i, j := 0, 0; i < len(b); {
|
||||
b1 := b[i]
|
||||
b2 := byte(0)
|
||||
b3 := byte(0)
|
||||
|
||||
if (i + 1) < len(b) {
|
||||
b2 = b[i+1]
|
||||
}
|
||||
if (i + 2) < len(b) {
|
||||
b3 = b[i+2]
|
||||
}
|
||||
|
||||
o[j] = bmap[(b1 & 0x3F)]
|
||||
o[j+1] = bmap[((b1&0xC0)>>6)|((b2&0x0F)<<2)]
|
||||
o[j+2] = bmap[((b2&0xF0)>>4)|((b3&0x03)<<4)]
|
||||
o[j+3] = bmap[(b3&0xFC)>>2]
|
||||
i += 3
|
||||
j += 4
|
||||
}
|
||||
|
||||
s := string(o)
|
||||
return s[0 : len(b)*4/3-(len(b)%4)+1]
|
||||
}
|
||||
|
||||
// © 2008-2012 Assurance Technologies LLC. (Python passlib) BSD License
|
||||
// © 2014 Hugo Landau <hlandau@devever.net> BSD License
|
82
vendor/gopkg.in/hlandau/passlib.v1/hash/sha2crypt/raw/parse.go
generated
vendored
Normal file
82
vendor/gopkg.in/hlandau/passlib.v1/hash/sha2crypt/raw/parse.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
package raw
|
||||
|
||||
import "fmt"
|
||||
import "strings"
|
||||
import "strconv"
|
||||
|
||||
// Indicates that a password hash or stub is invalid.
|
||||
var ErrInvalidStub = fmt.Errorf("invalid stub")
|
||||
|
||||
// Indicates that the number of rounds specified is not in the valid range.
|
||||
var ErrInvalidRounds = fmt.Errorf("invalid number of rounds")
|
||||
|
||||
// Scans a sha256-crypt or sha512-crypt modular crypt stub or modular crypt hash
|
||||
// to determine configuration parameters.
|
||||
func Parse(stub string) (isSHA512 bool, salt, hash string, rounds int, err error) {
|
||||
// $5$
|
||||
if len(stub) < 3 || stub[0] != '$' || stub[2] != '$' {
|
||||
err = ErrInvalidStub
|
||||
return
|
||||
}
|
||||
|
||||
if stub[1] == '6' {
|
||||
isSHA512 = true
|
||||
} else if stub[1] != '5' {
|
||||
err = ErrInvalidStub
|
||||
return
|
||||
}
|
||||
|
||||
rest := stub[3:]
|
||||
parts := strings.Split(rest, "$")
|
||||
roundsStr := ""
|
||||
|
||||
switch len(parts) {
|
||||
case 1:
|
||||
// $5$
|
||||
// $5$salt
|
||||
salt = parts[0]
|
||||
case 2:
|
||||
// $5$salt$hash
|
||||
// $5$rounds=1000$salt
|
||||
if strings.HasPrefix(parts[0], "rounds=") {
|
||||
roundsStr = parts[0]
|
||||
salt = parts[1]
|
||||
} else {
|
||||
salt = parts[0]
|
||||
hash = parts[1]
|
||||
}
|
||||
case 3:
|
||||
// $5$rounds=1000$salt$hash
|
||||
roundsStr = parts[0]
|
||||
salt = parts[1]
|
||||
hash = parts[2]
|
||||
default:
|
||||
err = ErrInvalidStub
|
||||
}
|
||||
|
||||
if roundsStr != "" {
|
||||
if !strings.HasPrefix(roundsStr, "rounds=") {
|
||||
err = ErrInvalidStub
|
||||
return
|
||||
}
|
||||
|
||||
roundsStr = roundsStr[7:]
|
||||
var n uint64
|
||||
n, err = strconv.ParseUint(roundsStr, 10, 31)
|
||||
if err != nil {
|
||||
err = ErrInvalidStub
|
||||
return
|
||||
}
|
||||
|
||||
rounds = int(n)
|
||||
|
||||
if rounds < MinimumRounds || rounds > MaximumRounds {
|
||||
err = ErrInvalidRounds
|
||||
return
|
||||
}
|
||||
} else {
|
||||
rounds = DefaultRounds
|
||||
}
|
||||
|
||||
return
|
||||
}
|
187
vendor/gopkg.in/hlandau/passlib.v1/hash/sha2crypt/raw/sha2crypt.go
generated
vendored
Normal file
187
vendor/gopkg.in/hlandau/passlib.v1/hash/sha2crypt/raw/sha2crypt.go
generated
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
// Package raw provides a raw implementation of the sha256-crypt and sha512-crypt primitives.
|
||||
package raw
|
||||
|
||||
import "io"
|
||||
import "fmt"
|
||||
import "hash"
|
||||
import "crypto/sha256"
|
||||
import "crypto/sha512"
|
||||
|
||||
// The minimum number of rounds permissible for sha256-crypt and sha512-crypt.
|
||||
const MinimumRounds = 1000
|
||||
|
||||
// The maximum number of rounds permissible for sha256-crypt and sha512-crypt.
|
||||
// Don't use this!
|
||||
const MaximumRounds = 999999999
|
||||
|
||||
// This is the 'default' number of rounds for sha256-crypt and sha512-crypt. If
|
||||
// this rounds value is used the number of rounds is not explicitly specified
|
||||
// in the modular crypt format, as it is the default.
|
||||
const DefaultRounds = 5000
|
||||
|
||||
// This is the recommended number of rounds for sha256-crypt and sha512-crypt.
|
||||
// This may change with subsequent releases of this package. It is recommended
|
||||
// that you invoke sha256-crypt or sha512-crypt with this value, or a value
|
||||
// proportional to it.
|
||||
const RecommendedRounds = 10000
|
||||
|
||||
// Calculates sha256-crypt. The password must be in plaintext and be a UTF-8
|
||||
// string.
|
||||
//
|
||||
// The salt must be a valid ASCII between 0 and 16 characters in length
|
||||
// inclusive.
|
||||
//
|
||||
// See the constants in this package for suggested values for rounds.
|
||||
//
|
||||
// Rounds must be in the range 1000 <= rounds <= 999999999. The function panics
|
||||
// if this is not the case.
|
||||
//
|
||||
// The output is in modular crypt format.
|
||||
func Crypt256(password, salt string, rounds int) string {
|
||||
return "$5" + shaCrypt(password, salt, rounds, sha256.New, transpose256)
|
||||
}
|
||||
|
||||
// Calculates sha256-crypt. The password must be in plaintext and be a UTF-8
|
||||
// string.
|
||||
//
|
||||
// The salt must be a valid ASCII between 0 and 16 characters in length
|
||||
// inclusive.
|
||||
//
|
||||
// See the constants in this package for suggested values for rounds.
|
||||
//
|
||||
// Rounds must be in the range 1000 <= rounds <= 999999999. The function panics
|
||||
// if this is not the case.
|
||||
//
|
||||
// The output is in modular crypt format.
|
||||
func Crypt512(password, salt string, rounds int) string {
|
||||
return "$6" + shaCrypt(password, salt, rounds, sha512.New, transpose512)
|
||||
}
|
||||
|
||||
func shaCrypt(password, salt string, rounds int, newHash func() hash.Hash, transpose func(b []byte)) string {
|
||||
if rounds < MinimumRounds || rounds > MaximumRounds {
|
||||
panic("sha256-crypt rounds must be in 1000 <= rounds <= 999999999")
|
||||
}
|
||||
|
||||
passwordb := []byte(password)
|
||||
saltb := []byte(salt)
|
||||
if len(saltb) > 16 {
|
||||
panic("salt must not exceed 16 bytes")
|
||||
}
|
||||
|
||||
// B
|
||||
b := newHash()
|
||||
b.Write(passwordb)
|
||||
b.Write(saltb)
|
||||
b.Write(passwordb)
|
||||
bsum := b.Sum(nil)
|
||||
|
||||
// A
|
||||
a := newHash()
|
||||
a.Write(passwordb)
|
||||
a.Write(saltb)
|
||||
repeat(a, bsum, len(passwordb))
|
||||
|
||||
plen := len(passwordb)
|
||||
for plen != 0 {
|
||||
if (plen & 1) != 0 {
|
||||
a.Write(bsum)
|
||||
} else {
|
||||
a.Write(passwordb)
|
||||
}
|
||||
plen = plen >> 1
|
||||
}
|
||||
|
||||
asum := a.Sum(nil)
|
||||
|
||||
// DP
|
||||
dp := newHash()
|
||||
for i := 0; i < len(passwordb); i++ {
|
||||
dp.Write(passwordb)
|
||||
}
|
||||
|
||||
dpsum := dp.Sum(nil)
|
||||
|
||||
// P
|
||||
p := make([]byte, len(passwordb))
|
||||
repeatTo(p, dpsum)
|
||||
|
||||
// DS
|
||||
ds := newHash()
|
||||
for i := 0; i < (16 + int(asum[0])); i++ {
|
||||
ds.Write(saltb)
|
||||
}
|
||||
|
||||
dssum := ds.Sum(nil)[0:len(saltb)]
|
||||
|
||||
// S
|
||||
s := make([]byte, len(saltb))
|
||||
repeatTo(s, dssum)
|
||||
|
||||
// C
|
||||
cur := asum[:]
|
||||
for i := 0; i < rounds; i++ {
|
||||
c := newHash()
|
||||
if (i & 1) != 0 {
|
||||
c.Write(p)
|
||||
} else {
|
||||
c.Write(cur)
|
||||
}
|
||||
if (i % 3) != 0 {
|
||||
c.Write(s)
|
||||
}
|
||||
if (i % 7) != 0 {
|
||||
c.Write(p)
|
||||
}
|
||||
if (i & 1) == 0 {
|
||||
c.Write(p)
|
||||
} else {
|
||||
c.Write(cur)
|
||||
}
|
||||
cur = c.Sum(nil)[:]
|
||||
}
|
||||
|
||||
// Transposition
|
||||
transpose(cur)
|
||||
|
||||
// Hash
|
||||
hstr := EncodeBase64(cur)
|
||||
|
||||
if rounds == DefaultRounds {
|
||||
return fmt.Sprintf("$%s$%s", salt, hstr)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("$rounds=%d$%s$%s", rounds, salt, hstr)
|
||||
}
|
||||
|
||||
func repeat(w io.Writer, b []byte, sz int) {
|
||||
var i int
|
||||
for i = 0; (i + len(b)) <= sz; i += len(b) {
|
||||
w.Write(b)
|
||||
}
|
||||
w.Write(b[0 : sz-i])
|
||||
}
|
||||
|
||||
func repeatTo(out []byte, b []byte) {
|
||||
if len(b) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var i int
|
||||
for i = 0; (i + len(b)) <= len(out); i += len(b) {
|
||||
copy(out[i:], b)
|
||||
}
|
||||
copy(out[i:], b)
|
||||
}
|
||||
|
||||
func transpose256(b []byte) {
|
||||
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19], b[20], b[21], b[22], b[23], b[24], b[25], b[26], b[27], b[28], b[29], b[30], b[31] =
|
||||
b[20], b[10], b[0], b[11], b[1], b[21], b[2], b[22], b[12], b[23], b[13], b[3], b[14], b[4], b[24], b[5], b[25], b[15], b[26], b[16], b[6], b[17], b[7], b[27], b[8], b[28], b[18], b[29], b[19], b[9], b[30], b[31]
|
||||
}
|
||||
|
||||
func transpose512(b []byte) {
|
||||
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19], b[20], b[21], b[22], b[23], b[24], b[25], b[26], b[27], b[28], b[29], b[30], b[31], b[32], b[33], b[34], b[35], b[36], b[37], b[38], b[39], b[40], b[41], b[42], b[43], b[44], b[45], b[46], b[47], b[48], b[49], b[50], b[51], b[52], b[53], b[54], b[55], b[56], b[57], b[58], b[59], b[60], b[61], b[62], b[63] =
|
||||
b[42], b[21], b[0], b[1], b[43], b[22], b[23], b[2], b[44], b[45], b[24], b[3], b[4], b[46], b[25], b[26], b[5], b[47], b[48], b[27], b[6], b[7], b[49], b[28], b[29], b[8], b[50], b[51], b[30], b[9], b[10], b[52], b[31], b[32], b[11], b[53], b[54], b[33], b[12], b[13], b[55], b[34], b[35], b[14], b[56], b[57], b[36], b[15], b[16], b[58], b[37], b[38], b[17], b[59], b[60], b[39], b[18], b[19], b[61], b[40], b[41], b[20], b[62], b[63]
|
||||
}
|
||||
|
||||
// © 2008-2012 Assurance Technologies LLC. (Python passlib) BSD License
|
||||
// © 2014 Hugo Landau <hlandau@devever.net> BSD License
|
147
vendor/gopkg.in/hlandau/passlib.v1/hash/sha2crypt/sha2crypt.go
generated
vendored
Normal file
147
vendor/gopkg.in/hlandau/passlib.v1/hash/sha2crypt/sha2crypt.go
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
// Package sha2crypt implements sha256-crypt and sha512-crypt.
|
||||
package sha2crypt
|
||||
|
||||
import "fmt"
|
||||
import "expvar"
|
||||
import "crypto/rand"
|
||||
import "gopkg.in/hlandau/passlib.v1/hash/sha2crypt/raw"
|
||||
import "gopkg.in/hlandau/passlib.v1/abstract"
|
||||
|
||||
var cSHA2CryptHashCalls = expvar.NewInt("passlib.sha2crypt.hashCalls")
|
||||
var cSHA2CryptVerifyCalls = expvar.NewInt("passlib.sha2crypt.verifyCalls")
|
||||
|
||||
// An implementation of Scheme performing sha256-crypt.
|
||||
//
|
||||
// The number of rounds is raw.RecommendedRounds.
|
||||
var Crypter256 abstract.Scheme
|
||||
|
||||
// An implementation of Scheme performing sha512-crypt.
|
||||
//
|
||||
// The number of rounds is raw.RecommendedRounds.
|
||||
var Crypter512 abstract.Scheme
|
||||
|
||||
func init() {
|
||||
Crypter256 = NewCrypter256(raw.RecommendedRounds)
|
||||
Crypter512 = NewCrypter512(raw.RecommendedRounds)
|
||||
}
|
||||
|
||||
// Returns a Scheme implementing sha256-crypt using the number of rounds
|
||||
// specified.
|
||||
func NewCrypter256(rounds int) abstract.Scheme {
|
||||
return &sha2Crypter{false, rounds}
|
||||
}
|
||||
|
||||
// Returns a Scheme implementing sha512-crypt using the number of rounds
|
||||
// specified.
|
||||
func NewCrypter512(rounds int) abstract.Scheme {
|
||||
return &sha2Crypter{true, rounds}
|
||||
}
|
||||
|
||||
type sha2Crypter struct {
|
||||
sha512 bool
|
||||
rounds int
|
||||
}
|
||||
|
||||
// Changes the default rounds for the crypter. Be warned that this
|
||||
// is a global setting. The default default value is RecommendedRounds.
|
||||
func (c *sha2Crypter) SetRounds(rounds int) error {
|
||||
if rounds < raw.MinimumRounds || rounds > raw.MaximumRounds {
|
||||
return raw.ErrInvalidRounds
|
||||
}
|
||||
|
||||
c.rounds = rounds
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *sha2Crypter) SupportsStub(stub string) bool {
|
||||
if len(stub) < 3 || stub[0] != '$' || stub[2] != '$' {
|
||||
return false
|
||||
}
|
||||
return (stub[1] == '5' && !c.sha512) || (stub[1] == '6' && c.sha512)
|
||||
}
|
||||
|
||||
func (c *sha2Crypter) Hash(password string) (string, error) {
|
||||
cSHA2CryptHashCalls.Add(1)
|
||||
|
||||
stub, err := c.makeStub()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, newHash, _, _, err := c.hash(password, stub)
|
||||
return newHash, err
|
||||
}
|
||||
|
||||
func (c *sha2Crypter) Verify(password, hash string) (err error) {
|
||||
cSHA2CryptVerifyCalls.Add(1)
|
||||
|
||||
_, newHash, _, _, err := c.hash(password, hash)
|
||||
if err == nil && !abstract.SecureCompare(hash, newHash) {
|
||||
err = abstract.ErrInvalidPassword
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *sha2Crypter) NeedsUpdate(stub string) bool {
|
||||
_, salt, _, rounds, err := raw.Parse(stub)
|
||||
if err != nil {
|
||||
return false // ...
|
||||
}
|
||||
|
||||
return c.needsUpdate(salt, rounds)
|
||||
}
|
||||
|
||||
func (c *sha2Crypter) needsUpdate(salt string, rounds int) bool {
|
||||
return rounds < c.rounds || len(salt) < 16
|
||||
}
|
||||
|
||||
var errInvalidStub = fmt.Errorf("invalid sha2 password stub")
|
||||
|
||||
func (c *sha2Crypter) hash(password, stub string) (oldHash, newHash, salt string, rounds int, err error) {
|
||||
isSHA512, salt, oldHash, rounds, err := raw.Parse(stub)
|
||||
if err != nil {
|
||||
return "", "", "", 0, err
|
||||
}
|
||||
|
||||
if isSHA512 != c.sha512 {
|
||||
return "", "", "", 0, errInvalidStub
|
||||
}
|
||||
|
||||
if c.sha512 {
|
||||
return oldHash, raw.Crypt512(password, salt, rounds), salt, rounds, nil
|
||||
}
|
||||
|
||||
return oldHash, raw.Crypt256(password, salt, rounds), salt, rounds, nil
|
||||
}
|
||||
|
||||
func (c *sha2Crypter) makeStub() (string, error) {
|
||||
ch := "5"
|
||||
if c.sha512 {
|
||||
ch = "6"
|
||||
}
|
||||
|
||||
buf := make([]byte, 12)
|
||||
_, err := rand.Read(buf)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
salt := raw.EncodeBase64(buf)[0:16]
|
||||
|
||||
if c.rounds == raw.DefaultRounds {
|
||||
return fmt.Sprintf("$%s$%s", ch, salt), nil
|
||||
}
|
||||
|
||||
return fmt.Sprintf("$%s$rounds=%d$%s", ch, c.rounds, salt), nil
|
||||
}
|
||||
|
||||
func (c *sha2Crypter) String() string {
|
||||
if c.sha512 {
|
||||
return fmt.Sprintf("sha512-crypt(%d)", c.rounds)
|
||||
} else {
|
||||
return fmt.Sprintf("sha256-crypt(%d)", c.rounds)
|
||||
}
|
||||
}
|
||||
|
||||
// © 2014 Hugo Landau <hlandau@devever.net> BSD License
|
Reference in New Issue
Block a user