diff options
author | Gibheer <gibheer@gmail.com> | 2015-01-16 11:23:14 +0100 |
---|---|---|
committer | Gibheer <gibheer@gmail.com> | 2015-01-16 11:23:14 +0100 |
commit | 68167a5891e3680331a44ab20fdb198e0447cf88 (patch) | |
tree | e1d07dd2b4dbcb935b2a00c5f3c10c752781434e /verify_signature.go | |
parent | 43384bab59112965e171d217f9b60e00c20659a0 (diff) |
add signing and verifying of messages
With this it is possible to sign a message with a private key and verify
it with a public key.
The only problem is, that it is currently not compatible with openssl
yet.
Diffstat (limited to 'verify_signature.go')
-rw-r--r-- | verify_signature.go | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/verify_signature.go b/verify_signature.go new file mode 100644 index 0000000..76020bb --- /dev/null +++ b/verify_signature.go @@ -0,0 +1,88 @@ +package main + +import ( + "crypto/ecdsa" + "crypto/sha256" + "crypto/x509" + "encoding/asn1" + "encoding/pem" + "errors" + "flag" + "fmt" + "io/ioutil" + "math/big" + "os" +) + +type ( + VerifySignatureFlags struct { + Message string // the message to sign + PublicKeyPath string // path to the private key + Signature string // a path or stream to output the private key to + } + // struct to load the signature into (which is basically two bigint in byte form) + Signature struct { + R, S *big.Int + } +) + +func verify_signature() { + flags := parse_verify_signature_flags() + public_key, err := load_public_key_ecdsa(flags.PublicKeyPath) + if err != nil { + crash_with_help(2, fmt.Sprintf("Error when loading public key: %s", err)) + } + signature, err := load_signature(flags.Signature) + if err != nil { + crash_with_help(2, fmt.Sprintf("Error when loading the signature: %s", err)) + } + hash := sha256.New() + hash.Write([]byte(flags.Message)) + + success := ecdsa.Verify(public_key, hash.Sum(nil), signature.R, signature.S) + fmt.Println(success) +} + +// parse the parameters +func parse_verify_signature_flags() VerifySignatureFlags { + flags := VerifySignatureFlags{} + fs := flag.NewFlagSet("verify-signature", flag.ExitOnError) + fs.StringVar(&flags.PublicKeyPath, "public-key", "", "path to the public key file") + fs.StringVar(&flags.Signature, "signature", "", "path where the signature file can be found") + fs.StringVar(&flags.Message, "message", "", "the message to be validated") + fs.Parse(os.Args[2:]) + + return flags +} + +// load the private key from pem file +func load_public_key_ecdsa(path string) (*ecdsa.PublicKey, error) { + public_key_file, err := os.Open(path) + if err != nil { return nil, err } + public_key_pem, err := ioutil.ReadAll(public_key_file) + if err != nil { return nil, err } + public_key_file.Close() + + block, _ := pem.Decode(public_key_pem) + if block.Type != TypeLabelPubKey { + return nil, errors.New(fmt.Sprintf("No public key found in %s", path)) + } + + public_key, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { return nil, err } + return public_key.(*ecdsa.PublicKey), nil +} + +// parse the signature from asn1 file +func load_signature(path string) (*Signature, error) { + signature_file, err := os.Open(path) + if err != nil { return nil, err } + signature_raw, err := ioutil.ReadAll(signature_file) + if err != nil { return nil, err } + signature_file.Close() + + var signature Signature + _, err = asn1.Unmarshal(signature_raw, &signature) + if err != nil { return nil, err } + return &signature, nil +} |