Skip to content

Commit

Permalink
add ecdsa support
Browse files Browse the repository at this point in the history
  • Loading branch information
blacktemplar committed Apr 6, 2020
1 parent 0ef2856 commit 123cce4
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 5 deletions.
92 changes: 89 additions & 3 deletions algorithms.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"crypto/rsa"
"crypto/sha256"
"crypto/sha512"
"crypto/ecdsa"
"crypto/subtle" // Use should trigger great care
"encoding/asn1"
"errors"
"fmt"
"golang.org/x/crypto/blake2b"
Expand All @@ -16,11 +18,13 @@ import (
"hash"
"io"
"strings"
"math/big"
)

const (
hmacPrefix = "hmac"
rsaPrefix = "rsa"
ecdsaPrefix = "ecdsa"
md4String = "md4"
md5String = "md5"
sha1String = "sha1"
Expand Down Expand Up @@ -210,6 +214,76 @@ func (r *rsaAlgorithm) String() string {
return fmt.Sprintf("%s-%s", rsaPrefix, hashToDef[r.kind].name)
}

var _ signer = &ecdsaAlgorithm{}

type ecdsaAlgorithm struct {
hash.Hash
kind crypto.Hash
}

func (r *ecdsaAlgorithm) setSig(b []byte) error {
n, err := r.Write(b)
if err != nil {
r.Reset()
return err
} else if n != len(b) {
r.Reset()
return fmt.Errorf("could only write %d of %d bytes of signature to hash", n, len(b))
}
return nil
}

type ECDSASignature struct {
R, S *big.Int
}

func (r *ecdsaAlgorithm) Sign(rand io.Reader, p crypto.PrivateKey, sig []byte) ([]byte, error) {
defer r.Reset()
if err := r.setSig(sig); err != nil {
return nil, err
}
ecdsaK, ok := p.(*ecdsa.PrivateKey)
if !ok {
return nil, errors.New("crypto.PrivateKey is not *ecdsa.PrivateKey")
}
R, S, err := ecdsa.Sign(rand, ecdsaK, r.Sum(nil))
if err != nil {
return nil, err
}

signature := ECDSASignature {R: R, S: S}
bytes, err := asn1.Marshal(signature)

return bytes, err
}

func (r *ecdsaAlgorithm) Verify(pub crypto.PublicKey, toHash, signature []byte) error {
defer r.Reset()
ecdsaK, ok := pub.(*ecdsa.PublicKey)
if !ok {
return errors.New("crypto.PublicKey is not *ecdsa.PublicKey")
}
if err := r.setSig(toHash); err != nil {
return err
}

sig := new(ECDSASignature)
_, err := asn1.Unmarshal(signature, sig)
if err != nil {
return err
}

if ecdsa.Verify(ecdsaK, r.Sum(nil), sig.R, sig.S) {
return nil
} else {
return errors.New("Invalid signature")
}
}

func (r *ecdsaAlgorithm) String() string {
return fmt.Sprintf("%s-%s", ecdsaPrefix, hashToDef[r.kind].name)
}

var _ macer = &blakeMacAlgorithm{}

type blakeMacAlgorithm struct {
Expand Down Expand Up @@ -315,14 +389,26 @@ func newAlgorithm(algo string, key []byte) (hash.Hash, crypto.Hash, error) {
// signerFromString is an internally public method constructor
func signerFromString(s string) (signer, error) {
s = strings.ToLower(s)
if !strings.HasPrefix(s, rsaPrefix) {
isEcdsa := false
var algo string = ""
if strings.HasPrefix(s, ecdsaPrefix) {
algo = strings.TrimPrefix(s, ecdsaPrefix + "-")
isEcdsa = true
} else if strings.HasPrefix(s, rsaPrefix) {
algo = strings.TrimPrefix(s, rsaPrefix+"-")
} else {
return nil, fmt.Errorf("no signer matching %q", s)
}
algo := strings.TrimPrefix(s, rsaPrefix+"-")
}
hash, cHash, err := newAlgorithm(algo, nil)
if err != nil {
return nil, err
}
if isEcdsa {
return &ecdsaAlgorithm {
Hash: hash,
kind: cHash,
}, nil
}
return &rsaAlgorithm{
Hash: hash,
kind: cHash,
Expand Down
2 changes: 0 additions & 2 deletions go.modverify

This file was deleted.

7 changes: 7 additions & 0 deletions httpsig.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ const (
RSA_SHA384 Algorithm = rsaPrefix + "-" + sha384String
RSA_SHA512 Algorithm = rsaPrefix + "-" + sha512String
RSA_RIPEMD160 Algorithm = rsaPrefix + "-" + ripemd160String
// ECDSA algorithms
ECDSA_SHA224 Algorithm = ecdsaPrefix + "-" + sha224String
ECDSA_SHA256 Algorithm = ecdsaPrefix + "-" + sha256String
ECDSA_SHA384 Algorithm = ecdsaPrefix + "-" + sha384String
ECDSA_SHA512 Algorithm = ecdsaPrefix + "-" + sha512String
ECDSA_RIPEMD160 Algorithm = ecdsaPrefix + "-" + ripemd160String

// Just because you can glue things together, doesn't mean they will
// work. The following options are not supported.
rsa_SHA3_224 Algorithm = rsaPrefix + "-" + sha3_224String
Expand Down

0 comments on commit 123cce4

Please sign in to comment.