コミット
3052f08321
|
@ -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
|
||||
|
|
読み込み中…
新しいイシューから参照