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/elliptic"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
"encoding/asn1"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -24,6 +26,10 @@ type (
|
||||||
EcdsaPublicKey struct {
|
EcdsaPublicKey struct {
|
||||||
public_key *ecdsa.PublicKey
|
public_key *ecdsa.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signatureEcdsa struct {
|
||||||
|
R, S *big.Int
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// generate a new ecdsa private key
|
// generate a new ecdsa private key
|
||||||
|
@ -46,8 +52,14 @@ func (pr EcdsaPrivateKey) Public() PublicKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
// sign a message with the private key
|
// sign a message with the private key
|
||||||
func (pr EcdsaPrivateKey) Sign(message []byte) ([]byte, error) {
|
func (pr EcdsaPrivateKey) Sign(message []byte, hash crypto.Hash) ([]byte, error) {
|
||||||
return make([]byte, 0), errors.New("not implemented yet!")
|
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
|
// get the private key
|
||||||
|
@ -72,6 +84,11 @@ func (pu *EcdsaPublicKey) MarshalPem() (marshalledPemBlock, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify a message using the ecdsa public key
|
// verify a message using the ecdsa public key
|
||||||
func (pu *EcdsaPublicKey) Verify(message []byte, signature []byte) (bool, error) {
|
func (pu *EcdsaPublicKey) Verify(message []byte, signature_raw []byte, hash crypto.Hash) (bool, error) {
|
||||||
return false, errors.New("not implemented yet!")
|
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
|
package pki
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -8,6 +9,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
SignatureMessage = []byte("foobar")
|
SignatureMessage = []byte("foobar")
|
||||||
|
SignatureHash = crypto.SHA512
|
||||||
)
|
)
|
||||||
|
|
||||||
// run the marshal test
|
// 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)
|
_, err := RunMarshalTest(pk_type + "-public", pu, PemLabelPublic, t)
|
||||||
if err != nil { return }
|
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) }
|
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 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) }
|
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)}
|
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!")
|
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
|
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!")
|
return false, errors.New("not implemented yet!")
|
||||||
}
|
}
|
||||||
|
|
8
types.go
8
types.go
|
@ -14,8 +14,10 @@ type (
|
||||||
PrivateKey interface {
|
PrivateKey interface {
|
||||||
// derive a public key from the private key
|
// derive a public key from the private key
|
||||||
Public() PublicKey
|
Public() PublicKey
|
||||||
// sign a message with the private key
|
// Sign a message using the public key and the given hash method.
|
||||||
Sign(message []byte) ([]byte, error)
|
// To use a hash method, include the package
|
||||||
|
// import _ "crypto/sha512"
|
||||||
|
Sign(message []byte, hash crypto.Hash) ([]byte, error)
|
||||||
|
|
||||||
// return the private key structure
|
// return the private key structure
|
||||||
privateKey() crypto.PrivateKey
|
privateKey() crypto.PrivateKey
|
||||||
|
@ -25,7 +27,7 @@ type (
|
||||||
PublicKey interface {
|
PublicKey interface {
|
||||||
Pemmer
|
Pemmer
|
||||||
// use the public key to verify a message against a signature
|
// 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 {
|
Pemmer interface {
|
||||||
|
|
Loading…
Reference in New Issue