0
0
Fork 0

add verification of messages

This commit adds back the possibility to verify a message through a
public key and a signature. It works a little bit different than before
as it always prints the base64 version, but it makes it easier to use.
This commit is contained in:
Gibheer 2015-02-20 10:45:42 +01:00
parent 1c621c063c
commit 075865c417
3 changed files with 78 additions and 10 deletions

View File

@ -5,6 +5,7 @@ package main
import (
"crypto/elliptic"
"encoding/base64"
"flag"
"fmt"
"io"
@ -48,13 +49,17 @@ type (
publicKeyPath string // path to the public key
signRequestPath string // path to the certificate sign request
certificateFlags *certFlagsContainer // container for certificate related flags
signature string // a base64 encoded signature
}
// a container for the refined flags
flagSet struct {
PrivateKey pki.PrivateKey
PublicKey pki.PublicKey
Output io.WriteCloser
Input io.ReadCloser
// an asn1 encoded signature of a signage process
Signature []byte
// private key specific stuff
PrivateKeyGenerationFlags privateKeyGenerationFlags
@ -140,6 +145,22 @@ func (f *Flags) parsePrivateKey() error {
return nil
}
// add the public key flag
func (f *Flags) AddPublicKey() {
f.check_list = append(f.check_list, f.parsePublicKey)
f.flagset.StringVar(&f.flag_container.publicKeyPath, "public-key", "", "path to the public key")
}
// parse public key flag
func (f *Flags) parsePublicKey() error {
if f.flag_container.publicKeyPath == "" { return fmt.Errorf("No public key given!") }
pu, err := ReadPublicKeyFile(f.flag_container.publicKeyPath)
if err != nil { return fmt.Errorf("Error reading public key: %s", err) }
f.Flags.PublicKey = pu
return nil
}
// add the output parameter to the checklist
func (f *Flags) AddOutput() {
f.check_list = append(f.check_list, f.parseOutput)
@ -214,3 +235,17 @@ func (f *Flags) parsePrivateKeyGenerationFlags() error {
}
return nil
}
// add the signature flag to load a signature from a signing process
func (f *Flags) AddSignature() {
f.check_list = append(f.check_list, f.parseSignature)
f.flagset.StringVar(&f.flag_container.signature, "signature", "", "the base64 encoded signature to use for verification")
}
// parse the signature flag
func (f *Flags) parseSignature() error {
var err error
f.Flags.Signature, err = base64.StdEncoding.DecodeString(f.flag_container.signature)
if err != nil { return err }
return nil
}

29
main.go
View File

@ -24,7 +24,7 @@ func main() {
case "create-private": create_private_key()
case "create-public": create_public_key()
case "sign-input": sign_input()
// case "verify-signature": verify_signature()
case "verify-signature": verify_input()
// case "create-cert-sign": create_sign_request()
// case "sign-request": sign_request()
case "help": print_modules()
@ -73,8 +73,8 @@ func create_public_key() {
func sign_input() {
fs := NewFlags("sign-input")
fs.AddPrivateKey()
fs.AddOutput()
fs.AddInput()
fs.AddOutput()
err := fs.Parse(program_args())
if err != nil { os.Exit(2) }
@ -92,6 +92,29 @@ func sign_input() {
}
}
// verify a message using a signature and a public key
func verify_input() {
fs := NewFlags("sign-input")
fs.AddPublicKey()
fs.AddInput()
fs.AddOutput()
fs.AddSignature()
err := fs.Parse(program_args())
if err != nil { os.Exit(2) }
signature := fs.Flags.Signature
message, err := ioutil.ReadAll(fs.Flags.Input)
if err != nil { crash_with_help(2, "Error reading input: %s", err) }
valid, err := fs.Flags.PublicKey.Verify(message, signature, crypto.SHA256)
if err != nil { crash_with_help(2, "Could not verify message with signature: %s", err) }
if valid {
fmt.Println("valid")
os.Exit(0)
}
fmt.Println("invalid")
os.Exit(1)
}
// print the module help
func print_modules() {
fmt.Printf(`Usage: %s command args
@ -110,7 +133,7 @@ where 'command' is one of:
// crash and provide a helpful message
func crash_with_help(code int, message string, args ...interface{}) {
fmt.Fprintln(os.Stderr, message)
fmt.Fprintf(os.Stderr, message + "\n", args...)
print_modules()
os.Exit(code)
}

View File

@ -5,25 +5,22 @@ import (
"github.com/gibheer/pki"
)
const (
TypeLabelRSA = "RSA PRIVATE KEY"
TypeLabelECDSA = "EC PRIVATE KEY"
)
var (
ErrNoPKFound = errors.New("no private key found")
ErrNoPUFound = errors.New("no public key found")
ErrUnknownFormat = errors.New("key is an unknown format")
)
// Read the private key from the path and try to figure out which type of key it
// might be.
func ReadPrivateKeyFile(path string) (pki.PrivateKey, error) {
raw_pk, err := readSectionFromFile(path, TypeLabelECDSA)
raw_pk, err := readSectionFromFile(path, pki.PemLabelEcdsa)
if err == nil {
pk, err := pki.LoadPrivateKeyEcdsa(raw_pk)
if err != nil { return nil, err }
return pk, nil
}
raw_pk, err = readSectionFromFile(path, TypeLabelRSA)
raw_pk, err = readSectionFromFile(path, pki.PemLabelRsa)
if err == nil {
pk, err := pki.LoadPrivateKeyRsa(raw_pk)
if err != nil { return nil, err }
@ -31,3 +28,16 @@ func ReadPrivateKeyFile(path string) (pki.PrivateKey, error) {
}
return nil, ErrNoPKFound
}
// read the public key and try to figure out what kind of key it might be
func ReadPublicKeyFile(path string) (pki.PublicKey, error) {
raw_pu, err := readSectionFromFile(path, pki.PemLabelPublic)
if err != nil { return nil, ErrNoPUFound }
var public pki.PublicKey
public, err = pki.LoadPublicKeyEcdsa(raw_pu)
if err == nil { return public, nil }
public, err = pki.LoadPublicKeyRsa(raw_pu)
if err == nil { return public, nil }
return nil, ErrUnknownFormat
}