Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
gopath
bin
out
/*.exe
5 changes: 1 addition & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
language: go
sudo: false
go:
- 1.5.x
- 1.9.x
deploy:
provider: releases
api_key:
secure: 'kewugKeaEgDvNMaapSbhMTgWXO1tje4sbyF8D77lbceOviTfKZkDKuuwVSwTU1NTKuHk5DnC00Rrfy7d4HP1xPT94P4AnI6oEjUvQvi43U8Ub/YGbrwTAZpqUyZJWwmkHaEikeFRIRuyTnHztM8/IQaEQyOvxtu2NOFnMVCpagQ='
file:
- bin/certstrap-${TRAVIS_TAG}-linux-amd64
- bin/certstrap-${TRAVIS_TAG}-darwin-amd64
Expand All @@ -17,7 +14,7 @@ deploy:
go: 1.9
install:
- go get -d -t -v ./...
- go get github.com/tools/godep
- go get github.com/Masterminds/glide
before_script:
- ./build
script:
Expand Down
22 changes: 0 additions & 22 deletions Godeps/Godeps.json

This file was deleted.

5 changes: 0 additions & 5 deletions Godeps/Readme

This file was deleted.

2 changes: 0 additions & 2 deletions Godeps/_workspace/.gitignore

This file was deleted.

1 change: 1 addition & 0 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Copyright (c) 2018 Marco Stolze (alias mcpride)
Copyright (C) 2015 Square, Inc.

CoreOS Project
Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[![Build Status](https://travis-ci.org/mcpride/certstrap.svg?branch=master)](https://travis-ci.org/mcpride/certstrap) [![license](http://img.shields.io/badge/license-apache_2.0-red.svg?style=flat)](https://raw.githubusercontent.com/mcpride/certstrap/master/LICENSE)

# certstrap
[![build](https://img.shields.io/travis/square/certstrap.svg?style=flat)](https://travis-ci.org/square/certstrap) [![license](http://img.shields.io/badge/license-apache_2.0-red.svg?style=flat)](https://raw.githubusercontent.com/square/certstrap/master/LICENSE)

A simple certificate manager written in Go, to bootstrap your own certificate authority and public key infrastructure. Adapted from etcd-ca.
A simple certificate manager written in Go, to bootstrap your own certificate authority and public key infrastructure. Adapted from etcd-ca and [square certstrap](https://github.com/square/certstrap).

certstrap is a very convenient app if you don't feel like dealing with openssl, its myriad of options or config files.

Expand All @@ -26,13 +27,13 @@ certstrap can init multiple certificate authorities to sign certificates with.
certstrap must be built with Go 1.4+. You can build certstrap from source:

```
$ git clone https://github.com/square/certstrap
$ git clone https://github.com/mcpride/certstrap
$ cd certstrap
$ ./build
```

This will generate a binary called `./bin/certstrap`
Note that certstrap depends on godep, cli, and terminal (godep should
Note that certstrap depends on glide, cli, and terminal (glide should
handle the latter two for you).

### Initialize a new certificate authority:
Expand Down Expand Up @@ -81,12 +82,12 @@ Created out/Alice.crt from out/Alice.csr signed by out/CertAuth.key
```

#### PKCS Format:

If you'd like to convert your certificate and key to PKCS12 format, simply run:

```
$ openssl pkcs12 -export -out outputCert.p12 -inkey inputKey.key -in inputCert.crt -certfile CA.crt
$ certstrap export-pfx Alice --chain "CertAuth"
```
`inputKey.key` and `inputCert.crt` make up the leaf private key and certificate pair of your choosing (generated by a `sign` command), with `CA.crt` being the certificate authority certificate that was used to sign it. The output PKCS12 file is `outputCert.p12`


### Retrieving Files

Expand Down
3 changes: 2 additions & 1 deletion build
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/bin/bash -e
# Copyright (c) 2018 Marco Stolze (alias mcpride)
# Copyright (C) 2015 Square, Inc.
# Copyright (C) 2014 CoreOS

ORG_PATH="github.com/square"
ORG_PATH="github.com/mcpride"
REPO_PATH="${ORG_PATH}/certstrap"
BUILD_TAG="${TRAVIS_TAG:-$(git describe --all | sed -e's/.*\///g')}"

Expand Down
10 changes: 6 additions & 4 deletions certstrap.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*-
* Copyright (c) 2018 Marco Stolze (alias mcpride)
* Copyright 2015 Square Inc.
* Copyright 2014 CoreOS
*
Expand All @@ -20,9 +21,9 @@ package main
import (
"os"

"github.com/square/certstrap/Godeps/_workspace/src/github.com/codegangsta/cli"
"github.com/square/certstrap/cmd"
"github.com/square/certstrap/depot"
"github.com/codegangsta/cli"
"github.com/mcpride/certstrap/cmd"
"github.com/mcpride/certstrap/depot"
)

func main() {
Expand All @@ -38,12 +39,13 @@ func main() {
EnvVar: "",
},
}
app.Author = "Square Inc., CoreOS"
app.Author = "M. Stolze, Square Inc., CoreOS"
app.Email = ""
app.Commands = []cli.Command{
cmd.NewInitCommand(),
cmd.NewCertRequestCommand(),
cmd.NewSignCommand(),
cmd.ExportPfxCommand(),
}
app.Before = func(c *cli.Context) error {
cmd.InitDepot(c.String("depot-path"))
Expand Down
18 changes: 18 additions & 0 deletions cmd/expiry.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
/*-
* Copyright (c) 2018 Marco Stolze (alias mcpride)
* Copyright 2015 Square Inc.
* Copyright 2014 CoreOS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package cmd

import (
Expand Down
17 changes: 17 additions & 0 deletions cmd/expiry_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/*-
* Copyright (c) 2018 Marco Stolze (alias mcpride)
* Copyright 2015 Square Inc.
* Copyright 2014 CoreOS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cmd

import (
Expand Down
103 changes: 103 additions & 0 deletions cmd/export_pfx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*-
* Copyright (c) 2018 Marco Stolze (alias mcpride)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package cmd

import (
"fmt"
"os"
"strings"

"github.com/codegangsta/cli"
"github.com/mcpride/certstrap/depot"
"github.com/mcpride/certstrap/pkix"
)

// ExportPfxCommand sets up a "export-pfx" command to export certificate chain to personal information exchange format
func ExportPfxCommand() cli.Command {
return cli.Command{
Name: "export-pfx",
Usage: "Export certificate chain to personal information exchange format",
Description: "Export certificate chain for host to personal information exchange format, including root certificate and key.",
Flags: []cli.Flag{
cli.StringFlag{"passphrase", "", "Passphrase to de- and encrypt private-key PEM block", ""},
cli.StringFlag{"chain", "", "Names of chained parent certificates; comma delimited", ""},
cli.BoolFlag{"stdout", "Print signing request to stdout in addition to saving file", ""},
},
Action: exportPfxAction,
}
}

func exportPfxAction(c *cli.Context) {
var err error

if len(c.Args()) != 1 {
fmt.Fprintln(os.Stderr, "One name must be provided.")
os.Exit(1)
}

formattedName := strings.Replace(c.Args()[0], " ", "_", -1)

if depot.CheckPersonalInformationExchange(d, formattedName) {
fmt.Fprintln(os.Stderr, "PFX has existed!")
os.Exit(1)
}

passphrase := []byte{}

key, err := depot.GetPrivateKey(d, formattedName)
if err != nil {
passphrase = getPassPhrase(c, "Certificate key")
key, err = depot.GetEncryptedPrivateKey(d, formattedName, passphrase)
if err != nil {
fmt.Fprintln(os.Stderr, "Get certificate key error:", err)
os.Exit(1)
}
}

cert, err := depot.GetCertificate(d, formattedName)
if err != nil {
fmt.Fprintln(os.Stderr, "Get certificate error:", err)
os.Exit(1)
}

caCrts := []*pkix.Certificate{}
if c.IsSet("chain") {
var formattedCAName string
chain := strings.Split(c.String("chain"), ",")
for i := range chain {
formattedCAName = strings.Replace(chain[i], " ", "_", -1)
ca, err := depot.GetCertificate(d, formattedCAName)
if err != nil {
fmt.Fprintln(os.Stderr, "Get chained certificate error:", err)
os.Exit(1)
}
caCrts = append(caCrts, ca)
}
}

pfxBytes, err := depot.PutPersonalInformationExchange(d, formattedName, cert, key, caCrts, passphrase)
if err != nil {
fmt.Fprintln(os.Stderr, "Export certificate chain to personal information exchange format failed:", err)
os.Exit(1)
} else {
fmt.Printf("Created %s/%s.pfx from %s/%s.crt and %s/%s.key\n", depotDir, formattedName, depotDir, formattedName, depotDir, formattedName)
}

if c.Bool("stdout") {
fmt.Printf(string(pfxBytes[:]))
}
}
11 changes: 8 additions & 3 deletions cmd/init.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*-
* Copyright (c) 2018 Marco Stolze (alias mcpride)
* Copyright 2015 Square Inc.
* Copyright 2014 CoreOS
*
Expand All @@ -23,9 +24,9 @@ import (
"os"
"strings"

"github.com/square/certstrap/Godeps/_workspace/src/github.com/codegangsta/cli"
"github.com/square/certstrap/depot"
"github.com/square/certstrap/pkix"
"github.com/codegangsta/cli"
"github.com/mcpride/certstrap/depot"
"github.com/mcpride/certstrap/pkix"
)

// NewInitCommand sets up an "init" command to initialize a new CA
Expand All @@ -46,6 +47,7 @@ func NewInitCommand() cli.Command {
cli.StringFlag{"province, st", "", "CA state/province", ""},
cli.StringFlag{"locality, l", "", "CA locality", ""},
cli.StringFlag{"key", "", "Path to private key PEM file. If blank, will generate new keypair.", ""},
cli.StringFlag{"out-name, on", "", "Name for output files without path and extension. If blank, CA common name will be used.", ""},
cli.BoolFlag{"stdout", "Print CA certificate to stdout in addition to saving file", ""},
},
Action: initAction,
Expand All @@ -60,6 +62,9 @@ func initAction(c *cli.Context) {
}

formattedName := strings.Replace(c.String("common-name"), " ", "_", -1)
if c.IsSet("out-name") {
formattedName = strings.Replace(c.String("out-name"), " ", "_", -1)
}

if depot.CheckCertificate(d, formattedName) || depot.CheckPrivateKey(d, formattedName) {
fmt.Fprintln(os.Stderr, "CA with specified name already exists!")
Expand Down
11 changes: 8 additions & 3 deletions cmd/request_cert.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*-
* Copyright (c) 2018 Marco Stolze (alias mcpride)
* Copyright 2015 Square Inc.
* Copyright 2014 CoreOS
*
Expand All @@ -23,9 +24,9 @@ import (
"os"
"strings"

"github.com/square/certstrap/Godeps/_workspace/src/github.com/codegangsta/cli"
"github.com/square/certstrap/depot"
"github.com/square/certstrap/pkix"
"github.com/codegangsta/cli"
"github.com/mcpride/certstrap/depot"
"github.com/mcpride/certstrap/pkix"
)

// NewCertRequestCommand sets up a "request-cert" command to create a request for a new certificate (CSR)
Expand All @@ -46,6 +47,7 @@ func NewCertRequestCommand() cli.Command {
cli.StringFlag{"ip", "", "IP address entries for subject alt name (comma separated)", ""},
cli.StringFlag{"domain", "", "DNS entries for subject alt name (comma separated)", ""},
cli.StringFlag{"key", "", "Path to private key PEM file. If blank, will generate new keypair.", ""},
cli.StringFlag{"out-name, on", "", "Name for output files without path and extension. If blank, Common name will be used.", ""},
cli.BoolFlag{"stdout", "Print signing request to stdout in addition to saving file", ""},
},
Action: newCertAction,
Expand Down Expand Up @@ -82,6 +84,9 @@ func newCertAction(c *cli.Context) {
}

formattedName := strings.Replace(name, " ", "_", -1)
if c.IsSet("out-name") {
formattedName = strings.Replace(c.String("out-name"), " ", "_", -1)
}

if depot.CheckCertificateSigningRequest(d, formattedName) || depot.CheckPrivateKey(d, formattedName) {
fmt.Fprintln(os.Stderr, "Certificate request has existed!")
Expand Down
7 changes: 4 additions & 3 deletions cmd/sign.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*-
* Copyright (c) 2018 Marco Stolze (alias mcpride)
* Copyright 2015 Square Inc.
* Copyright 2014 CoreOS
*
Expand All @@ -22,9 +23,9 @@ import (
"os"
"strings"

"github.com/square/certstrap/Godeps/_workspace/src/github.com/codegangsta/cli"
"github.com/square/certstrap/depot"
"github.com/square/certstrap/pkix"
"github.com/codegangsta/cli"
"github.com/mcpride/certstrap/depot"
"github.com/mcpride/certstrap/pkix"
)

// NewSignCommand sets up a "sign" command to sign a CSR with a given CA for a new certificate
Expand Down
Loading