add sign and verification to ecdsa
This commit adds support to sign and verify messages using ecdsa.
This commit is contained in:
parent
577538a5ff
commit
639a5379e9
25
ecdsa.go
25
ecdsa.go
|
@ -6,8 +6,10 @@ import (
|
|||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"encoding/asn1"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -24,6 +26,10 @@ type (
|
|||
EcdsaPublicKey struct {
|
||||
public_key *ecdsa.PublicKey
|
||||
}
|
||||
|
||||
signatureEcdsa struct {
|
||||
R, S *big.Int
|
||||
}
|
||||
)
|
||||
|
||||
// generate a new ecdsa private key
|
||||
|
@ -46,8 +52,14 @@ func (pr EcdsaPrivateKey) Public() PublicKey {
|
|||
}
|
||||
|
||||
// sign a message with the private key
|
||||
func (pr EcdsaPrivateKey) Sign(message []byte) ([]byte, error) {
|
||||
return make([]byte, 0), errors.New("not implemented yet!")
|
||||
func (pr EcdsaPrivateKey) Sign(message []byte, hash crypto.Hash) ([]byte, error) {
|
||||
empty := make([]byte, 0)
|
||||
if !hash.Available() {
|
||||
return empty, errors.New("Hash method is not available!")
|
||||
}
|
||||
hashed_message := hash.New()
|
||||
hashed_message.Write(message)
|
||||
return pr.private_key.Sign(rand.Reader, hashed_message.Sum(nil), hash)
|
||||
}
|
||||
|
||||
// get the private key
|
||||
|
@ -72,6 +84,11 @@ func (pu *EcdsaPublicKey) MarshalPem() (marshalledPemBlock, error) {
|
|||
}
|
||||
|
||||
// verify a message using the ecdsa public key
|
||||
func (pu *EcdsaPublicKey) Verify(message []byte, signature []byte) (bool, error) {
|
||||
return false, errors.New("not implemented yet!")
|
||||
func (pu *EcdsaPublicKey) Verify(message []byte, signature_raw []byte, hash crypto.Hash) (bool, error) {
|
||||
var sig signatureEcdsa
|
||||
_, err := asn1.Unmarshal(signature_raw, &sig)
|
||||
if err != nil { return false, err }
|
||||
hashed_message := hash.New()
|
||||
hashed_message.Write(message)
|
||||
return ecdsa.Verify(pu.public_key, hashed_message.Sum(nil), sig.R, sig.S), nil
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package pki
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/elliptic"
|
||||
"encoding/pem"
|
||||
"testing"
|
||||
|
@ -8,6 +9,7 @@ import (
|
|||
|
||||
var (
|
||||
SignatureMessage = []byte("foobar")
|
||||
SignatureHash = crypto.SHA512
|
||||
)
|
||||
|
||||
// run the marshal test
|
||||
|
@ -34,10 +36,10 @@ func RunPrivateKeyTests(pk_type string, pk PrivateKey, t *testing.T) {
|
|||
_, err := RunMarshalTest(pk_type + "-public", pu, PemLabelPublic, t)
|
||||
if err != nil { return }
|
||||
|
||||
signature, err := pk.Sign(SignatureMessage)
|
||||
signature, err := pk.Sign(SignatureMessage, SignatureHash)
|
||||
if err != nil { t.Errorf("%s: error creating a signature: %s", pk_type, err) }
|
||||
|
||||
valid, err := pu.Verify(SignatureMessage, signature)
|
||||
valid, err := pu.Verify(SignatureMessage, signature, SignatureHash)
|
||||
if err != nil { t.Errorf("%s: could not verify message: %s", pk_type, err) }
|
||||
if !valid { t.Errorf("%s: signature invalid, but should be valid!", pk_type) }
|
||||
}
|
||||
|
|
4
rsa.go
4
rsa.go
|
@ -41,7 +41,7 @@ func (pr *RsaPrivateKey) Public() PublicKey {
|
|||
return &RsaPublicKey{pr.private_key.Public().(*rsa.PublicKey)}
|
||||
}
|
||||
|
||||
func (pr RsaPrivateKey) Sign(message []byte) ([]byte, error) {
|
||||
func (pr RsaPrivateKey) Sign(message []byte, hash crypto.Hash) ([]byte, error) {
|
||||
return make([]byte, 0), errors.New("not implemented yet!")
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,6 @@ func (pu *RsaPublicKey) MarshalPem() (marshalledPemBlock, error) {
|
|||
return pem.EncodeToMemory(&pem_block), nil
|
||||
}
|
||||
|
||||
func (pu *RsaPublicKey) Verify(message []byte, signature []byte) (bool, error) {
|
||||
func (pu *RsaPublicKey) Verify(message []byte, signature []byte, hash crypto.Hash) (bool, error) {
|
||||
return false, errors.New("not implemented yet!")
|
||||
}
|
||||
|
|
8
types.go
8
types.go
|
@ -14,8 +14,10 @@ type (
|
|||
PrivateKey interface {
|
||||
// derive a public key from the private key
|
||||
Public() PublicKey
|
||||
// sign a message with the private key
|
||||
Sign(message []byte) ([]byte, error)
|
||||
// Sign a message using the public key and the given hash method.
|
||||
// To use a hash method, include the package
|
||||
// import _ "crypto/sha512"
|
||||
Sign(message []byte, hash crypto.Hash) ([]byte, error)
|
||||
|
||||
// return the private key structure
|
||||
privateKey() crypto.PrivateKey
|
||||
|
@ -25,7 +27,7 @@ type (
|
|||
PublicKey interface {
|
||||
Pemmer
|
||||
// use the public key to verify a message against a signature
|
||||
Verify(message []byte, signature []byte) (bool, error)
|
||||
Verify(message []byte, signature []byte, hash crypto.Hash) (bool, error)
|
||||
}
|
||||
|
||||
Pemmer interface {
|
||||
|
|
Loading…
Reference in New Issue