aboutsummaryrefslogblamecommitdiff
path: root/verify_signature.go
blob: 76020bb1a9723ac7147077f65e7d5988e5567a2c (plain) (tree)























































































                                                                                               
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
}