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!
This commit is contained in:
parent
52102b0f24
commit
31bf8bc739
|
@ -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
|
|
||||||
}
|
|
52
flags.go
52
flags.go
|
@ -5,11 +5,12 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/pem"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -76,7 +77,9 @@ type (
|
||||||
// private key specific stuff
|
// private key specific stuff
|
||||||
PrivateKeyGenerationFlags privateKeyGenerationFlags
|
PrivateKeyGenerationFlags privateKeyGenerationFlags
|
||||||
// a certificate filled with the parameters
|
// a certificate filled with the parameters
|
||||||
CertificateData certificateData
|
CertificateData *pki.CertificateData
|
||||||
|
// the certificate sign request
|
||||||
|
CertificateSignRequest *pki.CertificateRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
privateKeyGenerationFlags struct {
|
privateKeyGenerationFlags struct {
|
||||||
|
@ -175,6 +178,39 @@ func (f *Flags) parsePublicKey() error {
|
||||||
return nil
|
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
|
// add the output parameter to the checklist
|
||||||
func (f *Flags) AddOutput() {
|
func (f *Flags) AddOutput() {
|
||||||
f.check_list = append(f.check_list, f.parseOutput)
|
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
|
// parse the certificate fields into a raw certificate
|
||||||
func (f *Flags) parseCertificateFields() error {
|
func (f *Flags) parseCertificateFields() error {
|
||||||
f.Flags.CertificateData = certificateData{Subject: pkix.Name{}}
|
f.Flags.CertificateData = pki.NewCertificateData()
|
||||||
// convert the automatic flags
|
// convert the automatic flags
|
||||||
container_type := reflect.ValueOf(&f.flag_container.certificateFlags.automatic).Elem()
|
container_type := reflect.ValueOf(&f.flag_container.certificateFlags.automatic).Elem()
|
||||||
cert_data_type := reflect.ValueOf(&f.Flags.CertificateData.Subject).Elem()
|
cert_data_type := reflect.ValueOf(&f.Flags.CertificateData.Subject).Elem()
|
||||||
|
@ -321,12 +357,12 @@ func (f *Flags) parseCertificateFields() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert the manual flags
|
// convert the manual flags
|
||||||
data := &f.Flags.CertificateData
|
data := f.Flags.CertificateData
|
||||||
raw_data := f.flag_container.certificateFlags.manual
|
raw_data := f.flag_container.certificateFlags.manual
|
||||||
data.Subject.SerialNumber = raw_data.serialNumber
|
data.Subject.SerialNumber = raw_data.serialNumber
|
||||||
data.Subject.CommonName = raw_data.commonName
|
data.Subject.CommonName = raw_data.commonName
|
||||||
if raw_data.dnsNames != "" {
|
if raw_data.dnsNames != "" {
|
||||||
data.DnsNames = strings.Split(raw_data.dnsNames, ",")
|
data.DNSNames = strings.Split(raw_data.dnsNames, ",")
|
||||||
}
|
}
|
||||||
if raw_data.emailAddresses != "" {
|
if raw_data.emailAddresses != "" {
|
||||||
data.EmailAddresses = strings.Split(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 }
|
if raw_data.ipAddresses == "" { return nil }
|
||||||
raw_ips := strings.Split(raw_data.ipAddresses, ",")
|
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 {
|
for i, ip := range raw_ips {
|
||||||
data.IpAddresses[i] = net.ParseIP(ip)
|
data.IPAddresses[i] = net.ParseIP(ip)
|
||||||
if data.IpAddresses[i] == nil {
|
if data.IPAddresses[i] == nil {
|
||||||
return fmt.Errorf("'%s' is not a valid IP", ip)
|
return fmt.Errorf("'%s' is not a valid IP", ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
38
main.go
38
main.go
|
@ -2,13 +2,11 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/rand"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/pem"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
@ -29,7 +27,7 @@ func main() {
|
||||||
case "sign-input": sign_input()
|
case "sign-input": sign_input()
|
||||||
case "verify-signature": verify_input()
|
case "verify-signature": verify_input()
|
||||||
case "create-cert-sign": create_sign_request()
|
case "create-cert-sign": create_sign_request()
|
||||||
// case "sign-request": sign_request()
|
case "create-cert": create_cert()
|
||||||
case "help": print_modules()
|
case "help": print_modules()
|
||||||
// case "info": info_on_file()
|
// case "info": info_on_file()
|
||||||
default: crash_with_help(1, "Command not supported!")
|
default: crash_with_help(1, "Command not supported!")
|
||||||
|
@ -126,14 +124,36 @@ func create_sign_request() {
|
||||||
fs.AddCertificateFields()
|
fs.AddCertificateFields()
|
||||||
fs.Parse(program_args())
|
fs.Parse(program_args())
|
||||||
|
|
||||||
csrt := fs.Flags.CertificateData.GenerateCSR()
|
csr, err := fs.Flags.CertificateData.ToCertificateRequest(fs.Flags.PrivateKey)
|
||||||
csr, err := x509.CreateCertificateRequest(rand.Reader, csrt, fs.Flags.PrivateKey.PrivateKey())
|
|
||||||
if err != nil { crash_with_help(2, "Could not create certificate sign request: %s", err) }
|
if err != nil { crash_with_help(2, "Could not create certificate sign request: %s", err) }
|
||||||
pem_block := &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csr}
|
pem_block, err := csr.MarshalPem()
|
||||||
err = pem.Encode(fs.Flags.Output, pem_block)
|
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) }
|
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
|
// print the module help
|
||||||
func print_modules() {
|
func print_modules() {
|
||||||
fmt.Printf(`Usage: %s command args
|
fmt.Printf(`Usage: %s command args
|
||||||
|
@ -143,7 +163,7 @@ where 'command' is one of:
|
||||||
sign-input sign a message with a private key
|
sign-input sign a message with a private key
|
||||||
verify-signature verify a signature
|
verify-signature verify a signature
|
||||||
create-cert-sign create a new certificate sign request
|
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
|
help show this help
|
||||||
info get info on a file
|
info get info on a file
|
||||||
`, filepath.Base(os.Args[0]))
|
`, filepath.Base(os.Args[0]))
|
||||||
|
|
Loading…
Reference in New Issue