0
0
Fork 0

add sign and verification to ecdsa

This commit adds support to sign and verify messages using ecdsa.
This commit is contained in:
Gibheer 2015-02-18 22:55:29 +01:00
parent 577538a5ff
commit 639a5379e9
4 changed files with 32 additions and 11 deletions

View File

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

View File

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

@ -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!")
}

View File

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