Merge pull request #14 from Absolut-Ticket/ecdsa

add ECDSA support
このコミットが含まれているのは:
Cory J Slep 2020-05-26 08:16:37 +02:00 committed by GitHub
コミット 3052f08321
この署名に対応する既知のキーがデータベースに存在しません
GPGキーID: 4AEE18F83AFDEB23
3個のファイルの変更96行の追加5行の削除

ファイルの表示

@ -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"
@ -16,11 +18,13 @@ import (
"hash"
"io"
"strings"
"math/big"
)
const (
hmacPrefix = "hmac"
rsaPrefix = "rsa"
ecdsaPrefix = "ecdsa"
md4String = "md4"
md5String = "md5"
sha1String = "sha1"
@ -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 {
@ -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,

ファイルの表示

@ -1,2 +0,0 @@
golang.org/x/crypto v0.0.0-20180527072434-ab813273cd59 h1:hk3yo72LXLapY9EXVttc3Z1rLOxT9IuAPPX3GpY2+jo=
golang.org/x/sys v0.0.0-20180525142821-c11f84a56e43 h1:PvnWIWTbA7gsEBkKjt0HV9hckYfcqYv8s/ju7ArZ0do=

ファイルの表示

@ -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