aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ecdsa.go25
-rw-r--r--private_key_test.go6
-rw-r--r--rsa.go4
-rw-r--r--types.go8
4 files changed, 32 insertions, 11 deletions
diff --git a/ecdsa.go b/ecdsa.go
index f8f51b2..6754ee4 100644
--- a/ecdsa.go
+++ b/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
}
diff --git a/private_key_test.go b/private_key_test.go
index 1d8f5ba..a563f50 100644
--- a/private_key_test.go
+++ b/private_key_test.go
@@ -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) }
}
diff --git a/rsa.go b/rsa.go
index 71acd55..9a4f298 100644
--- a/rsa.go
+++ b/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!")
}
diff --git a/types.go b/types.go
index b05bd40..22c35d4 100644
--- a/types.go
+++ b/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 {