Skip to content

Commit

Permalink
trim DOD certs
Browse files Browse the repository at this point in the history
  • Loading branch information
pjdufour-truss committed Jan 15, 2019
1 parent 64ceedd commit 524cc39
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 22 deletions.
14 changes: 8 additions & 6 deletions Makefile
Expand Up @@ -176,14 +176,16 @@ webserver_test: server_generate
ifndef TEST_ACC_ENV
@echo "Running acceptance tests for webserver using local environment."
@echo "* Use environment XYZ by setting environment variable to TEST_ACC_ENV=XYZ."
TEST_ACC_DATABASE=0 TEST_ACC_DOD_CERTIFICATES=0 TEST_ACC_HONEYCOMB=0 \
go test -p 1 -count 1 -short $$(go list ./... | grep \\/cmd\\/webserver) 2> /dev/null
TEST_ACC_DATABASE=0 TEST_ACC_HONEYCOMB=0 \
go test -v -p 1 -count 1 -short $$(go list ./... | grep \\/cmd\\/webserver)
else
@echo "Running acceptance tests for webserver with environment $$TEST_ACC_ENV."
TEST_ACC_DATABASE=0 TEST_ACC_DOD_CERTIFICATES=0 TEST_ACC_HONEYCOMB=0 TEST_ACC_CWD=$$(PWD) \
aws-vault exec $$AWS_PROFILE -- \
chamber exec app-$$TEST_ACC_ENV -- \
go test -p 1 -count 1 -short $$(go list ./... | grep \\/cmd\\/webserver) 2> /dev/null
TEST_ACC_DATABASE=0 TEST_ACC_HONEYCOMB=0 \
TEST_ACC_CWD=$$(PWD) \
DISABLE_AWS_VAULT_WRAPPER=1 \
aws-vault exec $(AWS_PROFILE) -- \
chamber exec app-$(TEST_ACC_ENV) -- \
go test -v -p 1 -count 1 -short $$(go list ./... | grep \\/cmd\\/webserver)
endif

server_test: server_deps server_generate db_test_reset db_test_migrate
Expand Down
52 changes: 41 additions & 11 deletions cmd/webserver/main.go
Expand Up @@ -12,6 +12,7 @@ import (
"net/http"
"os"
"path"
"regexp"
"strconv"
"strings"

Expand Down Expand Up @@ -250,35 +251,64 @@ func initFlags(flag *pflag.FlagSet) {

func initDODCertificates(v *viper.Viper, logger *zap.Logger) ([]tls.Certificate, *x509.CertPool, error) {

// https://tools.ietf.org/html/rfc7468#section-2
// - https://stackoverflow.com/questions/20173472/does-go-regexps-any-charcter-match-newline
re := regexp.MustCompile("(?s)([-]{5}BEGIN CERTIFICATE[-]{5})(\\s*)(.+?)(\\s*)([-]{5}END CERTIFICATE[-]{5})")

certFormat := "-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----"

tlsCert := v.GetString("move-mil-dod-tls-cert")
if len(tlsCert) == 0 {
return make([]tls.Certificate, 0), nil, errors.Errorf("%s is missing", "move-mil-dod-tls-cert")
}

tlsCertMatches := re.FindAllStringSubmatch(tlsCert, -1)
if len(tlsCertMatches) == 0 {
return make([]tls.Certificate, 0), nil, errors.Errorf("%s is missing certificate PEM block", "move-mil-dod-tls-cert")
}
if len(tlsCertMatches) > 1 {
return make([]tls.Certificate, 0), nil, errors.Errorf("%s has too many certificate PEM blocks", "move-mil-dod-tls-cert")
}

tlsCerts := make([]string, 0, len(tlsCertMatches))
for _, m := range tlsCertMatches {
tlsCerts = append(tlsCerts, fmt.Sprintf(certFormat, m[3]))
}

logger.Info("certitficate chain from move-mil-dod-tls-cert parsed", zap.Any("count", len(tlsCerts)))

caCert := v.GetString("move-mil-dod-ca-cert")
if len(caCert) == 0 {
return make([]tls.Certificate, 0), nil, errors.Errorf("%s is missing", "move-mil-dod-ca-cert")
}

//Append move.mil cert with CA certificate chain
cert := bytes.Join(
[][]byte{
[]byte(tlsCert),
[]byte(caCert),
},
[]byte("\n"),
)
caCertMatches := re.FindAllStringSubmatch(caCert, -1)
if len(caCertMatches) == 0 {
return make([]tls.Certificate, 0), nil, errors.Errorf("%s is missing certificate PEM block", "move-mil-dod-tls-cert")
}

caCerts := make([]string, 0, len(caCertMatches))
for _, m := range caCertMatches {
caCerts = append(caCerts, fmt.Sprintf(certFormat, m[3]))
}

logger.Info("certitficate chain from move-mil-dod-ca-cert parsed", zap.Any("count", len(caCerts)))

key := []byte(v.GetString("move-mil-dod-tls-key"))
//Append move.mil cert with intermediate CA to create a validate certificate chain
cert := strings.Join(append(append(make([]string, 0), tlsCerts...), caCerts...), "\n")

key := v.GetString("move-mil-dod-tls-key")
if len(key) == 0 {
return make([]tls.Certificate, 0), nil, errors.Errorf("%s is missing", "move-mil-dod-tls-key")
}

keyPair, err := tls.X509KeyPair(cert, key)
keyPair, err := tls.X509KeyPair([]byte(cert), []byte(key))
if err != nil {
return make([]tls.Certificate, 0), nil, errors.Wrap(err, "failed to parse DOD keypair for server")
return make([]tls.Certificate, 0), nil, errors.Wrap(err, "failed to parse DOD x509 keypair for server")
}

logger.Info("DOD keypair", zap.Any("certificates", len(keyPair.Certificate)))

pathToPackage := v.GetString("dod-ca-package")
if len(pathToPackage) == 0 {
return make([]tls.Certificate, 0), nil, errors.Wrap(&errInvalidPKCS7{Path: pathToPackage}, fmt.Sprintf("%s is missing", "dod-ca-package"))
Expand Down
8 changes: 4 additions & 4 deletions cmd/webserver/main_test.go
Expand Up @@ -76,7 +76,7 @@ func (suite *webServerSuite) loadContext(variablesFile string) map[string]string

func (suite *webServerSuite) applyContext(ctx map[string]string) {
for k, v := range ctx {
suite.logger.Info("Overriding " + k)
suite.logger.Info("overriding " + k)
suite.viper.Set(strings.Replace(strings.ToLower(k), "_", "-", -1), v)
}
}
Expand Down Expand Up @@ -108,7 +108,7 @@ func (suite *webServerSuite) TestConfigStorage() {
func (suite *webServerSuite) TestDODCertificates() {

if os.Getenv("TEST_ACC_DOD_CERTIFICATES") != "1" {
suite.logger.Info("Skipping TestDODCertificates")
suite.logger.Info("skipping TestDODCertificates")
return
}

Expand All @@ -119,7 +119,7 @@ func (suite *webServerSuite) TestDODCertificates() {
func (suite *webServerSuite) TestHoneycomb() {

if os.Getenv("TEST_ACC_HONEYCOMB") != "1" {
suite.logger.Info("Skipping TestHoneycomb")
suite.logger.Info("skipping TestHoneycomb")
return
}

Expand All @@ -130,7 +130,7 @@ func (suite *webServerSuite) TestHoneycomb() {
func (suite *webServerSuite) TestDatabase() {

if os.Getenv("TEST_ACC_DATABASE") != "1" {
suite.logger.Info("Skipping TestDatabase")
suite.logger.Info("skipping TestDatabase")
return
}

Expand Down
8 changes: 7 additions & 1 deletion docs/how-to/run-go-tests.md
Expand Up @@ -22,7 +22,13 @@ If you're adding a feature that requires new or modified configuration, it's a g
$ TEST_ACC_ENV=experimental make webserver_test
```

This command will first load the variables from the `config/env/*.env` file and then run `chamber exec` to pull the environments from AWS. You can run acceptance tests for the database, DOD certificates, honeycomb through environment variables with `TEST_ACC_DATABASE=1`, `TEST_ACC_DOD_CERTIFICATES=1`, and `TEST_ACC_HONEYCOMB=1`, respectively.
This command will first load the variables from the `config/env/*.env` file and then run `chamber exec` to pull the environments from AWS. You can run acceptance tests for the database, DOD certificates, and Honeycomb through environment variables with `TEST_ACC_DATABASE=1`, `TEST_ACC_DOD_CERTIFICATES=1`, and `TEST_ACC_HONEYCOMB=1`, respectively.

For example to run acceptance tests against staging, including DOD certificate parsing, use:

```console
$ TEST_ACC_ENV=staging TEST_ACC_DOD_CERTIFICATES=1 make webserver_test
```

### Run All Tests in a Single Package

Expand Down

0 comments on commit 524cc39

Please sign in to comment.