generated from denpeshkov/go-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
891b2d8
commit cd395a9
Showing
17 changed files
with
878 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
--- | ||
run: | ||
concurrency: 4 | ||
timeout: 2m | ||
issues-exit-code: 1 | ||
|
||
output: | ||
formats: | ||
- format: colored-line-number | ||
print-issued-lines: true | ||
print-linter-name: true | ||
|
||
linters: | ||
# We'll track the golangci-lint default linters manually | ||
# instead of letting them change without our control. | ||
disable-all: true | ||
enable: | ||
# golangci-lint defaults: | ||
- errcheck | ||
- gosimple | ||
- govet | ||
- ineffassign | ||
- staticcheck | ||
- unused | ||
|
||
# Our own extras: | ||
- bodyclose | ||
- exhaustive | ||
- goimports | ||
- gosec | ||
- misspell | ||
- prealloc | ||
- unconvert | ||
- unparam |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# httpsig | ||
|
||
`httpsig` provides utilities for creating, encoding, and verifying signatures within HTTP requests. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package httpsig | ||
|
||
// Signer signs messages. | ||
// It must be safe for concurrent use by multiple goroutines. | ||
type Signer interface { | ||
Sign(message []byte) ([]byte, error) | ||
} | ||
|
||
// Verifier verifies message signatures. | ||
// It must be safe for concurrent use by multiple goroutines. | ||
type Verifier interface { | ||
Verify(message []byte, signature []byte) (bool, error) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Package ecdsa provides utilities for signing and verifying messages using ECDSA. | ||
package ecdsa | ||
|
||
import ( | ||
"crypto" | ||
"crypto/ecdsa" | ||
"crypto/rand" | ||
"errors" | ||
"io" | ||
) | ||
|
||
// ErrHashUnavailable is returned when the hash function is not linked into the binary. | ||
var ErrHashUnavailable = errors.New("ecdsa: requested hash function is unavailable") | ||
|
||
// Signer signs messages using ECDSA. | ||
// It is safe for concurrent use by multiple goroutines. | ||
type Signer struct { | ||
Verifier | ||
Rand io.Reader // Defaults to crypto/rand.Reader if not set. | ||
|
||
priv *ecdsa.PrivateKey | ||
} | ||
|
||
// NewSigner returns a new [Signer] for the provided private key and hash algorithm. | ||
func NewSigner(priv *ecdsa.PrivateKey, hash crypto.Hash) (*Signer, error) { | ||
if !hash.Available() { | ||
return nil, ErrHashUnavailable | ||
} | ||
return &Signer{ | ||
Rand: rand.Reader, | ||
priv: priv, | ||
Verifier: Verifier{pub: &priv.PublicKey, hash: hash}, | ||
}, nil | ||
} | ||
|
||
// Sign signs a message using the private key. | ||
func (s *Signer) Sign(message []byte) ([]byte, error) { | ||
return ecdsa.SignASN1(s.Rand, s.priv, s.digest(message)) | ||
} | ||
|
||
// Verifier verifies ECDSA message signatures. | ||
// It is safe for concurrent use by multiple goroutines. | ||
type Verifier struct { | ||
pub *ecdsa.PublicKey | ||
hash crypto.Hash | ||
} | ||
|
||
// NewVerifier returns a new [Verifier] for the provided public key and hash algorithm. | ||
func NewVerifier(pub *ecdsa.PublicKey, hash crypto.Hash) (*Verifier, error) { | ||
if !hash.Available() { | ||
return nil, ErrHashUnavailable | ||
} | ||
return &Verifier{pub: pub, hash: hash}, nil | ||
} | ||
|
||
// Verify verifies the signature of a message using the public key. | ||
func (v *Verifier) Verify(message []byte, signature []byte) (bool, error) { | ||
return ecdsa.VerifyASN1(v.pub, v.digest(message), signature), nil | ||
} | ||
|
||
func (v *Verifier) digest(msg []byte) []byte { | ||
h := v.hash.New() | ||
_, _ = h.Write(msg) // never returns an error | ||
return h.Sum(nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package ecdsa | ||
|
||
import ( | ||
"crypto" | ||
"crypto/ecdsa" | ||
"crypto/elliptic" | ||
"crypto/rand" | ||
_ "crypto/sha256" | ||
"testing" | ||
) | ||
|
||
func TestSignVerify(t *testing.T) { | ||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) | ||
if err != nil { | ||
t.Fatalf("GenerateKey() error: %v", err) | ||
} | ||
hash := crypto.SHA256 | ||
sig, err := NewSigner(key, hash) | ||
if err != nil { | ||
t.Fatalf("NewSigner() error: %v", err) | ||
} | ||
ver, err := NewVerifier(&key.PublicKey, hash) | ||
if err != nil { | ||
t.Fatalf("NewVerifier() error: %v", err) | ||
} | ||
|
||
msg := []byte("test") | ||
|
||
testf := func() { | ||
for i := range 3 { | ||
t.Logf("Iteration %d", i) | ||
sign, err := sig.Sign(msg) | ||
if err != nil { | ||
t.Fatalf("Signer.Sign(%s) error: %v", msg, err) | ||
} | ||
if ok, err := sig.Verify(msg, sign); err != nil { | ||
t.Fatalf("Signer.Verify(%s, %x) error: %v", msg, sign, err) | ||
} else if !ok { | ||
t.Errorf("Signed message not verified by Signer") | ||
} | ||
|
||
if ok, err := ver.Verify(msg, sign); err != nil { | ||
t.Fatalf("Verifier.Verify(%s, %x) error: %v", msg, sign, err) | ||
} else if !ok { | ||
t.Errorf("Signed message not verified by Verifier") | ||
} | ||
} | ||
} | ||
|
||
// Test for concurrency safety using the -race flag. | ||
t.Run("g1", func(t *testing.T) { | ||
t.Parallel() | ||
testf() | ||
}) | ||
t.Run("g2", func(t *testing.T) { | ||
t.Parallel() | ||
testf() | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// Package ed25519 provides utilities for signing and verifying messages using Ed25519. | ||
package ed25519 | ||
|
||
import ( | ||
"crypto/ed25519" | ||
"errors" | ||
) | ||
|
||
var ErrInvalidKey = errors.New("ed25519: bad key length") | ||
|
||
// Signer signs messages using Ed25519. | ||
// It is safe for concurrent use by multiple goroutines. | ||
type Signer struct { | ||
Verifier | ||
|
||
priv ed25519.PrivateKey | ||
} | ||
|
||
// NewSigner returns a new [Signer] for the provided private key and hash algorithm. | ||
func NewSigner(priv ed25519.PrivateKey) (*Signer, error) { | ||
if len(priv) != ed25519.PrivateKeySize { | ||
return nil, ErrInvalidKey | ||
} | ||
return &Signer{ | ||
priv: priv, | ||
Verifier: Verifier{pub: priv.Public().(ed25519.PublicKey)}, | ||
}, nil | ||
} | ||
|
||
// Sign signs a message using the private key. | ||
func (s *Signer) Sign(message []byte) ([]byte, error) { | ||
return ed25519.Sign(s.priv, message), nil | ||
} | ||
|
||
// Verifier verifies Ed25519 message signatures. | ||
// It is safe for concurrent use by multiple goroutines. | ||
type Verifier struct { | ||
pub ed25519.PublicKey | ||
} | ||
|
||
// NewVerifier returns a new [Verifier] for the provided public key and hash algorithm. | ||
func NewVerifier(pub ed25519.PublicKey) (*Verifier, error) { | ||
if len(pub) != ed25519.PublicKeySize { | ||
return nil, ErrInvalidKey | ||
} | ||
return &Verifier{pub: pub}, nil | ||
} | ||
|
||
// Verify verifies the signature of a message using the public key. | ||
func (v *Verifier) Verify(message []byte, signature []byte) (bool, error) { | ||
return ed25519.Verify(v.pub, message, signature), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package ed25519 | ||
|
||
import ( | ||
"crypto/ed25519" | ||
"crypto/rand" | ||
"testing" | ||
) | ||
|
||
func TestSignVerify(t *testing.T) { | ||
pub, priv, err := ed25519.GenerateKey(rand.Reader) | ||
if err != nil { | ||
t.Fatalf("GenerateKey() error: %v", err) | ||
} | ||
sig, err := NewSigner(priv) | ||
if err != nil { | ||
t.Fatalf("NewSigner() error: %v", err) | ||
} | ||
ver, err := NewVerifier(pub) | ||
if err != nil { | ||
t.Fatalf("NewVerifier() error: %v", err) | ||
} | ||
|
||
msg := []byte("test") | ||
|
||
testf := func() { | ||
for i := range 3 { | ||
t.Logf("Iteration %d", i) | ||
sign, err := sig.Sign(msg) | ||
if err != nil { | ||
t.Fatalf("Signer.Sign(%s) error: %v", msg, err) | ||
} | ||
if ok, err := sig.Verify(msg, sign); err != nil { | ||
t.Fatalf("Signer.Verify(%s, %x) error: %v", msg, sign, err) | ||
} else if !ok { | ||
t.Errorf("Signed message not verified by Signer") | ||
} | ||
|
||
if ok, err := ver.Verify(msg, sign); err != nil { | ||
t.Fatalf("Verifier.Verify(%s, %x) error: %v", msg, sign, err) | ||
} else if !ok { | ||
t.Errorf("Signed message not verified by Verifier") | ||
} | ||
} | ||
} | ||
|
||
// Test for concurrency safety using the -race flag. | ||
t.Run("g1", func(t *testing.T) { | ||
t.Parallel() | ||
testf() | ||
}) | ||
t.Run("g2", func(t *testing.T) { | ||
t.Parallel() | ||
testf() | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Package hmac provides utilities for signing and verifying messages using HMAC. | ||
package hmac | ||
|
||
import ( | ||
"crypto" | ||
"crypto/hmac" | ||
"errors" | ||
) | ||
|
||
// ErrHashUnavailable is returned when the hash function is not linked into the binary. | ||
var ErrHashUnavailable = errors.New("hmac: requested hash function is unavailable") | ||
|
||
// HMAC signs messages and verifies message signatures using HMAC. | ||
// It is safe for concurrent use by multiple goroutines. | ||
type HMAC struct { | ||
key []byte | ||
hash crypto.Hash | ||
} | ||
|
||
// New returns a new [HMAC] for the provided key and hash algorithm. | ||
func New(key []byte, hash crypto.Hash) (*HMAC, error) { | ||
if !hash.Available() { | ||
return nil, ErrHashUnavailable | ||
} | ||
return &HMAC{key: key, hash: hash}, nil | ||
} | ||
|
||
// Sign signs a message using the key. | ||
func (h HMAC) Sign(message []byte) ([]byte, error) { | ||
return h.digest(message), nil | ||
} | ||
|
||
// Verify verifies the signature of a message using the key. | ||
func (h HMAC) Verify(message []byte, signature []byte) (bool, error) { | ||
return hmac.Equal(signature, h.digest(message)), nil | ||
} | ||
|
||
func (h HMAC) digest(msg []byte) []byte { | ||
hash := hmac.New(h.hash.New, h.key) | ||
_, _ = hash.Write(msg) // never returns an error | ||
return hash.Sum(nil) | ||
} |
Oops, something went wrong.