Skip to content

Commit

Permalink
[FAB-4973] Add TLS profile to default config
Browse files Browse the repository at this point in the history
Add a tls profile to the default config to allow the issuance of certs
with the appropriate TLS key usage.
See [FAB-4973] for more info.

Change-Id: Ic96fda8503660d063f7e858af700c8aa6b624fe3
Signed-off-by: Keith Smith <[email protected]>
Signed-off-by: Saad Karim <[email protected]>
  • Loading branch information
Keith Smith committed Aug 8, 2017
1 parent 3ba0088 commit a070182
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 1 deletion.
11 changes: 11 additions & 0 deletions cmd/fabric-ca-server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,9 @@ affiliations:
# A maxpathlen of 0 means that the intermediate CA cannot issue other
# intermediate CA certificates, though it can still issue end entity certificates.
# (See RFC 5280, section 4.2.1.9)
#
# The "tls" profile subsection is used to sign TLS certificate requests;
# the default expiration ("expiry" field) is "8760h", which is 1 year in hours.
#############################################################################
signing:
default:
Expand All @@ -236,6 +239,14 @@ signing:
caconstraint:
isca: true
maxpathlen: 0
tls:
usage:
- signing
- key encipherment
- server auth
- client auth
- key agreement
expiry: 8760h
###########################################################################
# Certificate Signing Request (CSR) section.
Expand Down
85 changes: 85 additions & 0 deletions lib/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,91 @@ func TestMaxEnrollmentLimited(t *testing.T) {
os.RemoveAll(rootDir)
}

// Get certificate using the TLS profile on the server to retrieve a certificate to be used for TLS connection
func TestTLSCertIssuance(t *testing.T) {
testDir := "tlsTestDir"
os.RemoveAll(testDir)
defer os.RemoveAll(testDir)
srv := TestGetServer(rootPort, testDir, "", -1, t)
err := srv.Start()
if err != nil {
t.Fatalf("Root server start failed: %s", err)
}
defer srv.Stop()
client := &Client{
Config: &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", rootPort)},
HomeDir: testDir,
}
eresp, err := client.Enroll(&api.EnrollmentRequest{
Name: "admin",
Secret: "adminpw",
Profile: "tls",
CSR: &api.CSRInfo{Hosts: []string{"localhost"}},
})
if err != nil {
t.Fatalf("Failed to enroll: %s", err)
}
tlsCertBytes := eresp.Identity.GetECert().Cert()
cert, err := util.GetX509CertificateFromPEM(tlsCertBytes)
if err != nil {
t.Fatalf("Failed to get certificate: %s", err)
}
// Check if the certificate has correct key usages
if cert.KeyUsage&x509.KeyUsageDigitalSignature == 0 || cert.KeyUsage&x509.KeyUsageKeyEncipherment == 0 || cert.KeyUsage&x509.KeyUsageKeyAgreement == 0 {
t.Fatal("Certificate does not have correct extended key usage. Should have Digital Signature, Key Encipherment, and Key Agreement")
}
// Check if the certificate has correct extended key usages
clientAuth := false
serverAuth := false
for _, usage := range cert.ExtKeyUsage {
if usage == x509.ExtKeyUsageClientAuth {
clientAuth = true
}
if usage == x509.ExtKeyUsageServerAuth {
serverAuth = true
}
}
if !clientAuth || !serverAuth {
t.Fatal("Certificate does not have correct extended key usage. Should have ExtKeyUsageServerAuth and ExtKeyUsageClientAuth")
}
err = srv.Stop()
if err != nil {
t.Fatalf("Server stop failed: %s", err)
}
// Write the TLS certificate to disk
os.MkdirAll(testDir, 0755)
tlsCertFile := path.Join(testDir, "tls-cert.pem")
err = util.WriteFile(tlsCertFile, tlsCertBytes, 0644)
if err != nil {
t.Fatalf("Failed to write TLS certificate file: %s", err)
}
// Get a new server with TLS enabled
srv = TestGetServer2(false, rootPort, testDir, "", -1, t)
srv.Config.TLS.Enabled = true
srv.Config.TLS.CertFile = "tls-cert.pem"
// Start the server
err = srv.Start()
if err != nil {
t.Fatalf("TLS server start failed: %s", err)
}
// Connect to the server over TLS
cfg := &ClientConfig{URL: fmt.Sprintf("https://localhost:%d", rootPort)}
cfg.TLS.Enabled = true
cfg.TLS.CertFiles = []string{"ca-cert.pem"}
client = &Client{Config: cfg, HomeDir: testDir}
eresp, err = client.Enroll(&api.EnrollmentRequest{
Name: "admin",
Secret: "adminpw",
})
if err != nil {
t.Fatalf("Failed to enroll over TLS: %s", err)
}
err = srv.Stop()
if err != nil {
t.Fatalf("Stop of TLS server failed: %s", err)
}
}

// Configure server to start server with no client authentication required
func testNoClientCert(t *testing.T) {
srv := TestGetServer(rootPort, testdataDir, "", -1, t)
Expand Down
32 changes: 31 additions & 1 deletion lib/test-util.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"path"
"strconv"
"testing"

"github.com/cloudflare/cfssl/config"
)

const (
Expand Down Expand Up @@ -53,7 +55,13 @@ func TestGetIntermediateServer(idx int, t *testing.T) *Server {

// TestGetServer creates and returns a pointer to a server struct
func TestGetServer(port int, home, parentURL string, maxEnroll int, t *testing.T) *Server {
if home != testdataDir {
return TestGetServer2(home != testdataDir, port, home, parentURL, maxEnroll, t)
}

// TestGetServer2 creates and returns a pointer to a server struct, with an option of
// whether or not to remove the home directory first
func TestGetServer2(deleteHome bool, port int, home, parentURL string, maxEnroll int, t *testing.T) *Server {
if deleteHome {
os.RemoveAll(home)
}
affiliations := map[string]interface{}{
Expand All @@ -64,6 +72,24 @@ func TestGetServer(port int, home, parentURL string, maxEnroll int, t *testing.T
},
"org2": nil,
}
profiles := map[string]*config.SigningProfile{
"tls": &config.SigningProfile{
Usage: []string{"signing", "key encipherment", "server auth", "client auth", "key agreement"},
ExpiryString: "8760h",
},
"ca": &config.SigningProfile{
Usage: []string{"cert sign"},
ExpiryString: "8760h",
CAConstraint: config.CAConstraint{
IsCA: true,
MaxPathLen: 0,
},
},
}
defaultProfile := &config.SigningProfile{
Usage: []string{"cert sign"},
ExpiryString: "8760h",
}
srv := &Server{
Config: &ServerConfig{
Port: port,
Expand All @@ -80,6 +106,10 @@ func TestGetServer(port int, home, parentURL string, maxEnroll int, t *testing.T
Registry: CAConfigRegistry{
MaxEnrollments: maxEnroll,
},
Signing: &config.Signing{
Profiles: profiles,
Default: defaultProfile,
},
},
},
HomeDir: home,
Expand Down

0 comments on commit a070182

Please sign in to comment.