From 68167a5891e3680331a44ab20fdb198e0447cf88 Mon Sep 17 00:00:00 2001 From: Gibheer Date: Fri, 16 Jan 2015 11:23:14 +0100 Subject: 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. --- verify_signature.go | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 verify_signature.go (limited to 'verify_signature.go') 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 +} -- cgit v1.2.3-70-g09d2