Skip to content

Commit

Permalink
chore: bump golang-ci lint and fix int overflows
Browse files Browse the repository at this point in the history
  • Loading branch information
zepatrik committed Oct 18, 2024
1 parent f03ffe0 commit e870867
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 38 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,9 @@ jobs:
with:
go-version: "1.23.2"
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
uses: golangci/golangci-lint-action@v6
with:
version: v1.59.1
skip-go-installation: true
version: v1.61.0
args: --timeout 5m
- name: Install cockroach DB
run: |
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ licenses: .bin/licenses node_modules # checks open-source licenses
GOBIN=$(shell pwd)/.bin go install golang.org/x/tools/cmd/goimports@latest

.bin/golangci-lint: Makefile
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b .bin v1.59.1
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b .bin v1.61.0

.bin/licenses: Makefile
curl https://raw.githubusercontent.com/ory/ci/master/licenses/install | sh
Expand Down
39 changes: 33 additions & 6 deletions hasherx/hash_comparator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/subtle"
"encoding/base64"
"fmt"
"math"
"regexp"
"strings"

Expand Down Expand Up @@ -53,8 +54,13 @@ func CompareArgon2id(_ context.Context, password []byte, hash []byte) error {
return err
}

mem := uint64(p.Memory)
if mem > math.MaxUint32 {
return errors.WithStack(ErrInvalidHash)
}

// Derive the key from the other password using the same parameters.
otherHash := argon2.IDKey([]byte(password), salt, p.Iterations, uint32(p.Memory), p.Parallelism, p.KeyLength)
otherHash := argon2.IDKey(password, salt, p.Iterations, uint32(mem), p.Parallelism, p.KeyLength)

// Check that the contents of the hashed passwords are identical. Note
// that we are using the subtle.ConstantTimeCompare() function for this
Expand All @@ -73,8 +79,13 @@ func CompareArgon2i(_ context.Context, password []byte, hash []byte) error {
return err
}

mem := uint64(p.Memory)
if mem > math.MaxUint32 {
return errors.WithStack(ErrInvalidHash)
}

// Derive the key from the other password using the same parameters.
otherHash := argon2.Key([]byte(password), salt, p.Iterations, uint32(p.Memory), p.Parallelism, p.KeyLength)
otherHash := argon2.Key(password, salt, p.Iterations, uint32(mem), p.Parallelism, p.KeyLength)

// Check that the contents of the hashed passwords are identical. Note
// that we are using the subtle.ConstantTimeCompare() function for this
Expand Down Expand Up @@ -153,13 +164,21 @@ func decodeArgon2idHash(encodedHash string) (p *Argon2Config, salt, hash []byte,
if err != nil {
return nil, nil, nil, err
}
p.SaltLength = uint32(len(salt))
saltLength := len(salt)
if saltLength > math.MaxUint32 {
return nil, nil, nil, ErrInvalidHash
}
p.SaltLength = uint32(saltLength)

hash, err = base64.RawStdEncoding.Strict().DecodeString(parts[5])
if err != nil {
return nil, nil, nil, err
}
p.KeyLength = uint32(len(hash))
keyLength := len(hash)
if keyLength > math.MaxUint32 {
return nil, nil, nil, ErrInvalidHash
}
p.KeyLength = uint32(keyLength)

return p, salt, hash, nil
}
Expand Down Expand Up @@ -188,13 +207,21 @@ func decodePbkdf2Hash(encodedHash string) (p *PBKDF2Config, salt, hash []byte, e
if err != nil {
return nil, nil, nil, err
}
p.SaltLength = uint32(len(salt))
saltLength := len(salt)
if saltLength > math.MaxUint32 {
return nil, nil, nil, ErrInvalidHash
}
p.SaltLength = uint32(saltLength)

hash, err = base64.RawStdEncoding.Strict().DecodeString(parts[4])
if err != nil {
return nil, nil, nil, err
}
p.KeyLength = uint32(len(hash))
keyLength := len(hash)
if keyLength > math.MaxUint32 {
return nil, nil, nil, ErrInvalidHash
}
p.KeyLength = uint32(keyLength)

return p, salt, hash, nil
}
23 changes: 17 additions & 6 deletions hasherx/hasher_argon2.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import (
"crypto/rand"
"encoding/base64"
"fmt"
"math"
"time"

"github.com/ory/x/otelx"

"github.com/inhies/go-bytesize"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
Expand Down Expand Up @@ -64,14 +67,18 @@ func NewHasherArgon2(c Argon2Configurator) *Argon2 {
return &Argon2{c: c}
}

func toKB(mem bytesize.ByteSize) uint32 {
return uint32(mem / bytesize.KB)
func toKB(mem bytesize.ByteSize) (uint32, error) {
kb := uint64(mem / bytesize.KB)
if kb > math.MaxUint32 {
return 0, errors.Errorf("memory %v is too large", mem)
}
return uint32(kb), nil
}

// Generate generates a hash for the given password.
func (h *Argon2) Generate(ctx context.Context, password []byte) ([]byte, error) {
func (h *Argon2) Generate(ctx context.Context, password []byte) (_ []byte, err error) {
ctx, span := otel.GetTracerProvider().Tracer(tracingComponent).Start(ctx, "hash.Argon2.Generate")
defer span.End()
defer otelx.End(span, &err)
p := h.c.HasherArgon2Config(ctx)
span.SetAttributes(attribute.String("argon2.config", fmt.Sprintf("#%v", p)))

Expand All @@ -80,16 +87,20 @@ func (h *Argon2) Generate(ctx context.Context, password []byte) ([]byte, error)
return nil, err
}

mem, err := toKB(p.Memory)
if err != nil {
return nil, err
}
// Pass the plaintext password, salt and parameters to the argon2.IDKey
// function. This will generate a hash of the password using the Argon2id
// variant.
hash := argon2.IDKey([]byte(password), salt, p.Iterations, toKB(p.Memory), p.Parallelism, p.KeyLength)
hash := argon2.IDKey(password, salt, p.Iterations, mem, p.Parallelism, p.KeyLength)

var b bytes.Buffer
if _, err := fmt.Fprintf(
&b,
"$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s",
argon2.Version, toKB(p.Memory), p.Iterations, p.Parallelism,
argon2.Version, mem, p.Iterations, p.Parallelism,
base64.RawStdEncoding.EncodeToString(salt),
base64.RawStdEncoding.EncodeToString(hash),
); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion jsonnetsecure/jsonnet_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ var (
func NewProcessPool(size int) Pool {
size = max(5, min(size, math.MaxInt32))
pud, err := puddle.NewPool(&puddle.Config[worker]{
MaxSize: int32(size),
MaxSize: int32(size), //nolint:gosec // disable G115 // because of the previous min/max, 5 <= size <= math.MaxInt32
Constructor: newWorker,
Destructor: worker.destroy,
})
Expand Down
36 changes: 15 additions & 21 deletions mapx/type_assert.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"encoding/json"
"errors"
"fmt"
"math"
"time"
)

Expand Down Expand Up @@ -103,17 +104,14 @@ func GetInt32Default(values map[interface{}]interface{}, key interface{}, defaul

// GetInt32 returns an int32 for a given key in values.
func GetInt32(values map[interface{}]interface{}, key interface{}) (int32, error) {
if v, ok := values[key]; !ok {
return 0, ErrKeyDoesNotExist
} else if sv, ok := v.(int32); ok {
return sv, nil
} else if sv, ok := v.(int); ok {
return int32(sv), nil
} else if j, ok := v.(json.Number); ok {
v, err := j.Int64()
return int32(v), err
v, err := GetInt64(values, key)
if err != nil {
return 0, err
}
return 0, ErrKeyCanNotBeTypeAsserted
if v > math.MaxInt32 || v < math.MinInt32 {
return 0, errors.New("value is out of range")
}
return int32(v), nil
}

// GetIntDefault returns a int or the default value for a given key in values.
Expand All @@ -127,18 +125,14 @@ func GetIntDefault(values map[interface{}]interface{}, key interface{}, defaultV

// GetInt returns an int for a given key in values.
func GetInt(values map[interface{}]interface{}, key interface{}) (int, error) {
if v, ok := values[key]; !ok {
return 0, ErrKeyDoesNotExist
} else if sv, ok := v.(int32); ok {
return int(sv), nil
} else if sv, ok := v.(int); ok {
return sv, nil
} else if j, ok := v.(json.Number); ok {
v, err := j.Int64()
return int(v), err
v, err := GetInt64(values, key)
if err != nil {
return 0, err
}
return 0, ErrKeyCanNotBeTypeAsserted

if v > math.MaxInt || v < math.MinInt {
return 0, errors.New("value is out of range")
}
return int(v), nil
}

// GetFloat32Default returns a float32 or the default value for a given key in values.
Expand Down

0 comments on commit e870867

Please sign in to comment.