aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGibheer <gibheer@gmail.com>2015-03-16 17:15:29 +0100
committerGibheer <gibheer@gmail.com>2015-03-16 17:15:29 +0100
commit31bf8bc739b5066eaaf25294a202170ffede4bc2 (patch)
tree2317a331b7172a9a75584a8698f1db818f653826
parent52102b0f24b03be251efa863c3b7cd657f09d5d9 (diff)
certificate generation is in
The hole certificate sign request and certificate creation process was pulled into pki, which made pkictl a bit smaller in code. There are still some things missing, but the initial support for certificates is done!
-rw-r--r--certificate_data.go28
-rw-r--r--flags.go52
-rw-r--r--main.go38
3 files changed, 73 insertions, 45 deletions
diff --git a/certificate_data.go b/certificate_data.go
deleted file mode 100644
index 76f3323..0000000
--- a/certificate_data.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package main
-
-import (
- "crypto/x509"
- "crypto/x509/pkix"
- "net"
-)
-
-type (
- certificateData struct {
- Subject pkix.Name
-
- DnsNames []string
- EmailAddresses []string
- IpAddresses []net.IP
- }
-)
-
-func (c *certificateData) GenerateCSR() *x509.CertificateRequest {
- csr := &x509.CertificateRequest{}
-
- csr.Subject = c.Subject
- csr.DNSNames = c.DnsNames
- csr.IPAddresses = c.IpAddresses
- csr.EmailAddresses = c.EmailAddresses
-
- return csr
-}
diff --git a/flags.go b/flags.go
index 7aee688..d70120b 100644
--- a/flags.go
+++ b/flags.go
@@ -5,11 +5,12 @@ package main
import (
"crypto/elliptic"
- "crypto/x509/pkix"
"encoding/base64"
+ "encoding/pem"
"flag"
"fmt"
"io"
+ "io/ioutil"
"net"
"os"
"reflect"
@@ -76,7 +77,9 @@ type (
// private key specific stuff
PrivateKeyGenerationFlags privateKeyGenerationFlags
// a certificate filled with the parameters
- CertificateData certificateData
+ CertificateData *pki.CertificateData
+ // the certificate sign request
+ CertificateSignRequest *pki.CertificateRequest
}
privateKeyGenerationFlags struct {
@@ -175,6 +178,39 @@ func (f *Flags) parsePublicKey() error {
return nil
}
+// add flag to load certificate sign request
+func (f *Flags) AddCSR() {
+ f.check_list = append(f.check_list, f.parseCSR)
+ f.flagset.StringVar(&f.flag_container.signRequestPath, "csr-path", "", "path to the certificate sign request")
+}
+
+// parse the certificate sign request
+func (f *Flags) parseCSR() error {
+ rest, err := ioutil.ReadFile(f.flag_container.signRequestPath)
+ if err != nil { return fmt.Errorf("Error reading certificate sign request: %s", err) }
+
+ var csr_asn1 []byte
+ var block *pem.Block
+ for len(rest) > 0 {
+ block, rest = pem.Decode(rest)
+ if block.Type == "CERTIFICATE REQUEST" {
+ csr_asn1 = block.Bytes
+ break
+ }
+ }
+ if len(csr_asn1) == 0 {
+ return fmt.Errorf(
+ "No certificate sign request found in %s",
+ f.flag_container.signRequestPath,
+ )
+ }
+
+ csr, err := pki.LoadCertificateSignRequest(csr_asn1)
+ if err != nil { return fmt.Errorf("Invalid certificate sign request: %s", err) }
+ f.Flags.CertificateSignRequest = csr
+ return nil
+}
+
// add the output parameter to the checklist
func (f *Flags) AddOutput() {
f.check_list = append(f.check_list, f.parseOutput)
@@ -307,7 +343,7 @@ func (f *Flags) AddCertificateFields() {
// parse the certificate fields into a raw certificate
func (f *Flags) parseCertificateFields() error {
- f.Flags.CertificateData = certificateData{Subject: pkix.Name{}}
+ f.Flags.CertificateData = pki.NewCertificateData()
// convert the automatic flags
container_type := reflect.ValueOf(&f.flag_container.certificateFlags.automatic).Elem()
cert_data_type := reflect.ValueOf(&f.Flags.CertificateData.Subject).Elem()
@@ -321,12 +357,12 @@ func (f *Flags) parseCertificateFields() error {
}
// convert the manual flags
- data := &f.Flags.CertificateData
+ data := f.Flags.CertificateData
raw_data := f.flag_container.certificateFlags.manual
data.Subject.SerialNumber = raw_data.serialNumber
data.Subject.CommonName = raw_data.commonName
if raw_data.dnsNames != "" {
- data.DnsNames = strings.Split(raw_data.dnsNames, ",")
+ data.DNSNames = strings.Split(raw_data.dnsNames, ",")
}
if raw_data.emailAddresses != "" {
data.EmailAddresses = strings.Split(raw_data.emailAddresses, ",")
@@ -334,10 +370,10 @@ func (f *Flags) parseCertificateFields() error {
if raw_data.ipAddresses == "" { return nil }
raw_ips := strings.Split(raw_data.ipAddresses, ",")
- data.IpAddresses = make([]net.IP, len(raw_ips))
+ data.IPAddresses = make([]net.IP, len(raw_ips))
for i, ip := range raw_ips {
- data.IpAddresses[i] = net.ParseIP(ip)
- if data.IpAddresses[i] == nil {
+ data.IPAddresses[i] = net.ParseIP(ip)
+ if data.IPAddresses[i] == nil {
return fmt.Errorf("'%s' is not a valid IP", ip)
}
}
diff --git a/main.go b/main.go
index b33ced9..7e3d0b6 100644
--- a/main.go
+++ b/main.go
@@ -2,13 +2,11 @@ package main
import (
"crypto"
- "crypto/rand"
- "crypto/x509"
"encoding/base64"
- "encoding/pem"
"fmt"
"io"
"io/ioutil"
+ "math/big"
"os"
"path/filepath"
@@ -29,7 +27,7 @@ func main() {
case "sign-input": sign_input()
case "verify-signature": verify_input()
case "create-cert-sign": create_sign_request()
-// case "sign-request": sign_request()
+ case "create-cert": create_cert()
case "help": print_modules()
// case "info": info_on_file()
default: crash_with_help(1, "Command not supported!")
@@ -126,14 +124,36 @@ func create_sign_request() {
fs.AddCertificateFields()
fs.Parse(program_args())
- csrt := fs.Flags.CertificateData.GenerateCSR()
- csr, err := x509.CreateCertificateRequest(rand.Reader, csrt, fs.Flags.PrivateKey.PrivateKey())
+ csr, err := fs.Flags.CertificateData.ToCertificateRequest(fs.Flags.PrivateKey)
if err != nil { crash_with_help(2, "Could not create certificate sign request: %s", err) }
- pem_block := &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csr}
- err = pem.Encode(fs.Flags.Output, pem_block)
+ pem_block, err := csr.MarshalPem()
+ if err != nil { crash_with_help(2, "Could not covnert to pem: %s", err) }
+ _, err = pem_block.WriteTo(fs.Flags.Output)
if err != nil { crash_with_help(2, "Encoding didn't work: %s", err) }
}
+func create_cert() {
+ fs := NewFlags("create-cert")
+ fs.AddPrivateKey()
+ fs.AddCSR()
+ fs.AddOutput()
+ fs.Parse(program_args())
+
+ // TODO implement flags for all certificate options
+ cert_opts := pki.CertificateOptions{}
+ cert_opts.SerialNumber = big.NewInt(1)
+ cert, err := fs.Flags.CertificateSignRequest.ToCertificate(
+ fs.Flags.PrivateKey,
+ cert_opts,
+ nil,
+ )
+ if err != nil { crash_with_help(2, "Error generating certificate: %s", err) }
+ pem_block, err := cert.MarshalPem()
+ if err != nil { crash_with_help(2, "Error converting to pem: %s", err) }
+ _, err = pem_block.WriteTo(fs.Flags.Output)
+ if err != nil { crash_with_help(2, "Output didn't work: %s", err) }
+}
+
// print the module help
func print_modules() {
fmt.Printf(`Usage: %s command args
@@ -143,7 +163,7 @@ where 'command' is one of:
sign-input sign a message with a private key
verify-signature verify a signature
create-cert-sign create a new certificate sign request
- sign-request sign a certificate request
+ create-cert sign a certificate request
help show this help
info get info on a file
`, filepath.Base(os.Args[0]))