aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flags.go35
-rw-r--r--main.go29
-rw-r--r--private_key.go24
3 files changed, 78 insertions, 10 deletions
diff --git a/flags.go b/flags.go
index 9af8371..c825b57 100644
--- a/flags.go
+++ b/flags.go
@@ -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
+}
diff --git a/main.go b/main.go
index 3898417..c509fd7 100644
--- a/main.go
+++ b/main.go
@@ -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)
}
diff --git a/private_key.go b/private_key.go
index 3e6aee3..0591e18 100644
--- a/private_key.go
+++ b/private_key.go
@@ -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
+}