aboutsummaryrefslogtreecommitdiff
path: root/main.go
blob: b1e43ab0562a53271426dc89efe6589fd786c3a5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// This package builds a binary which helps to generate
// private keys, public keys, certificates and also
// includes functionality to sign and verify messages.
package main

import (
	"crypto"
	"encoding/base64"
	"fmt"
	"io"
	"io/ioutil"
	"os"

	"github.com/gibheer/pki"
)

const (
	ErrorProgram int = iota
	ErrorFlagInput
	ErrorInput
)

var (
	EmptyByteArray = make([]byte, 0)
)

func main() {
	InitFlags()
	CmdRoot.Execute()
}

// create a public key derived from a private key
func create_public_key(cmd *Command, args []string) {
	err := checkFlags(checkPrivateKey, checkOutput)
	if err != nil {
		crash_with_help(cmd, ErrorFlagInput, "Flags invalid: %s", err)
	}

	var pub_key pki.Pemmer
	pub_key = FlagPrivateKey.Public()
	marsh_pem, err := pub_key.MarshalPem()
	if err != nil {
		crash_with_help(cmd, ErrorProgram, "Error when marshalling to pem: %s", err)
	}
	_, err = marsh_pem.WriteTo(FlagOutput)
	if err != nil {
		crash_with_help(cmd, ErrorProgram, "Error when writing output: %s", err)
	}
}

// sign a message using he private key
func sign_input(cmd *Command, args []string) {
	err := checkFlags(checkPrivateKey, checkInput, checkOutput)
	if err != nil {
		crash_with_help(cmd, ErrorFlagInput, "Flags invalid: %s", err)
	}

	message, err := ioutil.ReadAll(FlagInput)
	if err != nil {
		crash_with_help(cmd, ErrorProgram, "Error reading input: %s", err)
	}
	signature, err := FlagPrivateKey.Sign(message, crypto.SHA256)
	if err != nil {
		crash_with_help(cmd, ErrorProgram, "Could not compute signature: %s", err)
	}
	_, err = io.WriteString(FlagOutput, base64.StdEncoding.EncodeToString(signature))
	if err != nil {
		crash_with_help(cmd, ErrorProgram, "Could not write to output: %s", err)
	}

	// if we print to stderr, send a final line break to make the output nice
	if FlagOutput == os.Stdout {
		// we can ignore the result, as either Stdout did work or not
		_, _ = io.WriteString(FlagOutput, "\n")
	}
}

// verify a message using a signature and a public key
func verify_input(cmd *Command, args []string) {
	err := checkFlags(checkPublicKey, checkInput, checkOutput, checkSignature)
	if err != nil {
		crash_with_help(cmd, ErrorFlagInput, "Flags invalid: %s", err)
	}

	signature := FlagSignature
	message, err := ioutil.ReadAll(FlagInput)
	if err != nil {
		crash_with_help(cmd, ErrorProgram, "Error reading input: %s", err)
	}
	valid, err := FlagPublicKey.Verify(message, signature, crypto.SHA256)
	if err != nil {
		crash_with_help(cmd, ErrorProgram, "Could not verify message using signature: %s", err)
	}
	if valid {
		fmt.Println("valid")
		os.Exit(0)
	}
	fmt.Println("invalid")
	os.Exit(1)
}

// create a certificate sign request
func create_sign_request(cmd *Command, args []string) {
	err := checkFlags(checkPrivateKey, checkOutput, checkCertificateFields)
	if err != nil {
		crash_with_help(cmd, ErrorFlagInput, "Flags invalid: %s", err)
	}

	csr, err := FlagCertificateRequestData.ToCertificateRequest(FlagPrivateKey)
	if err != nil {
		crash_with_help(cmd, ErrorProgram, "Could not create certificate sign request: %s", err)
	}
	pem_block, err := csr.MarshalPem()
	if err != nil {
		crash_with_help(cmd, ErrorProgram, "Error when marshalling to pem: %s", err)
	}
	_, err = pem_block.WriteTo(FlagOutput)
	if err != nil {
		crash_with_help(cmd, ErrorProgram, "Could not write to output: %s", err)
	}
}

// crash and provide a helpful message
func crash_with_help(cmd *Command, code int, message string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, message+"\n", args...)
	cmd.Usage()
	os.Exit(code)
}

// return the arguments to the program
func program_args() []string {
	return os.Args[2:]
}