Skip to content
This repository has been archived by the owner on Jul 16, 2020. It is now read-only.

Commit

Permalink
Merge pull request #852 from bryteise/cert-signer-rename
Browse files Browse the repository at this point in the history
ciao-cert: Rename signer flag for clarity
  • Loading branch information
rbradford authored Nov 22, 2016
2 parents e21c845 + 5695226 commit 43401be
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 92 deletions.
14 changes: 7 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ before_install:
before_script:
- sudo mkdir -p /etc/pki/ciao/
- sudo mkdir -p /var/lib/ciao/logs/scheduler
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -server -role scheduler
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -server-cert /etc/pki/ciao/cert-Scheduler-localhost.pem -role agent
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -server-cert /etc/pki/ciao/cert-Scheduler-localhost.pem -role agent,netagent
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -server-cert /etc/pki/ciao/cert-Scheduler-localhost.pem -role controller
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -server-cert /etc/pki/ciao/cert-Scheduler-localhost.pem -role cnciagent
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -server-cert /etc/pki/ciao/cert-Scheduler-localhost.pem -role netagent
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -server-cert /etc/pki/ciao/cert-Scheduler-localhost.pem -role server
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -anchor -role scheduler
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -anchor-cert /etc/pki/ciao/cert-Scheduler-localhost.pem -role agent
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -anchor-cert /etc/pki/ciao/cert-Scheduler-localhost.pem -role agent,netagent
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -anchor-cert /etc/pki/ciao/cert-Scheduler-localhost.pem -role controller
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -anchor-cert /etc/pki/ciao/cert-Scheduler-localhost.pem -role cnciagent
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -anchor-cert /etc/pki/ciao/cert-Scheduler-localhost.pem -role netagent
- sudo -E $GOPATH/bin/ciao-cert -directory /etc/pki/ciao -host localhost -anchor-cert /etc/pki/ciao/cert-Scheduler-localhost.pem -role server
- sudo cp /etc/pki/ciao/CAcert-localhost.pem /etc/pki/ciao/ca_cert.crt
- sudo cp /etc/pki/ciao/CAcert-localhost.pem /etc/pki/ciao/CAcert-server-localhost.pem
- sudo cp /etc/pki/ciao/cert-Scheduler-localhost.pem /etc/pki/ciao/server.pem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
become: no
connection: local
command: >
{{ ciao_cert }} -server -role scheduler
{{ ciao_cert }} -anchor -role scheduler
-email={{ ciao_admin_email }} -organization="{{ ciao_cert_organization }}"
-ip={{ ciao_controller_ip }} -host={{ ciao_controller_fqdn }} -verify
args:
Expand All @@ -36,7 +36,7 @@
become: no
connection: local
command: >
{{ ciao_cert }} -role {{ item.role }} --server-cert
{{ ciao_cert }} -role {{ item.role }} --anchor-cert
cert-Scheduler-{{ ciao_controller_fqdn }}.pem -email={{ ciao_admin_email }}
--organization="{{ ciao_cert_organization }}" -host=localhost -verify
args:
Expand Down
20 changes: 10 additions & 10 deletions ciao-cert/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ Usage of ciao-cert:
Certificates organization
-role value
Comma separated list of SSNTP role [agent, scheduler, controller, netagent, server, cnciagent]
-server
Whether this cert should be a server one
-server-cert string
Server certificate for signing a client one
-anchor
Whether this cert should be the trust anchor
-anchor-cert string
Trust anchor certificate for signing
-stderrthreshold value
logs at or above this threshold go to stderr
-v value
Expand Down Expand Up @@ -74,23 +74,23 @@ node agent, networking node agent, and CNCI agent).

* Scheduler private key and CA certificate

$GOBIN/ciao-cert -server -role scheduler -email=ciao-devel@lists.clearlinux.org -organization=Intel -ip=192.168.1.118 -host=ciao-ctl.intel.com -verify
$GOBIN/ciao-cert -anchor -role scheduler -email=ciao-devel@lists.clearlinux.org -organization=Intel -ip=192.168.1.118 -host=ciao-ctl.intel.com -verify
That will generate `CAcert-ciao-ctl.intel.com.pem` and `cert-Scheduler-ciao.ctl.intel.com.pem`.
* Controller private key

$GOBIN/ciao-cert -role controller -server-cert cert-Scheduler-ciao-ctl.intel.com.pem -email=ciao-devel@lists.clearlinux.org -organization=Intel -host=ciao-ctl.intel.com -verify
$GOBIN/ciao-cert -role controller -anchor-cert cert-Scheduler-ciao-ctl.intel.com.pem -email=ciao-devel@lists.clearlinux.org -organization=Intel -host=ciao-ctl.intel.com -verify
That will generate `cert-Controller-ciao-ctl.intel.com.pem`.
* Compute Node Agent private key

$GOBIN/ciao-cert -role agent -server-cert cert-Scheduler-ciao-ctl.intel.com.pem -email=ciao-devel@lists.clearlinux.org -organization=Intel -host=localhost -verify
$GOBIN/ciao-cert -role agent -anchor-cert cert-Scheduler-ciao-ctl.intel.com.pem -email=ciao-devel@lists.clearlinux.org -organization=Intel -host=localhost -verify
That will generate `cert-CNAgent-localhost.pem`.
* Networking Node Agent private key

$GOBIN/ciao-cert -role netagent -server-cert cert-Scheduler-ciao-ctl.intel.com.pem -email=ciao-devel@lists.clearlinux.org -organization=Intel -host=localhost -verify
$GOBIN/ciao-cert -role netagent -anchor-cert cert-Scheduler-ciao-ctl.intel.com.pem -email=ciao-devel@lists.clearlinux.org -organization=Intel -host=localhost -verify
That will generate `cert-NetworkingAgent-localhost.pem`.
* CNCI Agent private key

$GOBIN/ciao-cert -role cnciagent -server-cert cert-Scheduler-ciao-ctl.intel.com.pem -email=ciao-devel@lists.clearlinux.org -organization=Intel -host=localhost -verify
$GOBIN/ciao-cert -role cnciagent -anchor-cert cert-Scheduler-ciao-ctl.intel.com.pem -email=ciao-devel@lists.clearlinux.org -organization=Intel -host=localhost -verify
That will generate `cert-CNCIAgent-localhost.pem`.

## Multi roles support
Expand All @@ -103,7 +103,7 @@ separated list of roles to ciao-cert. For example a specific testing
focused launcher agent may want to expose both the CN and NN agent roles:

```shell
$GOBIN/ciao-cert -role agent,netagent -server-cert cert-Scheduler-ciao-ctl.intel.com.pem -email=ciao-devel@lists.clearlinux.org -organization=Intel -host=localhost -verify
$GOBIN/ciao-cert -role agent,netagent -anchor-cert cert-Scheduler-ciao-ctl.intel.com.pem -email=ciao-devel@lists.clearlinux.org -organization=Intel -host=localhost -verify
```

## Inspecting certificates
Expand Down
65 changes: 28 additions & 37 deletions ciao-cert/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ import (
var (
host = flag.String("host", "", "Comma-separated hostnames to generate a certificate for")
mgmtIP = flag.String("ip", "", "Comma-separated IPs to generate a certificate for")
serverCert = flag.String("server-cert", "", "Server certificate for signing a client one")
isServer = flag.Bool("server", false, "Whether this cert should be a server one")
verify = flag.Bool("verify", false, "Verify client certificate")
anchorCert = flag.String("anchor-cert", "", "Trust anchor certificate for signing")
isAnchor = flag.Bool("anchor", false, "Whether this cert should be the trust anchor")
verify = flag.Bool("verify", false, "Verify certificate")
isElliptic = flag.Bool("elliptic-key", false, "Use elliptic curve algorithms")
email = flag.String("email", "ciao-devel@lists.clearlinux.org", "Certificate email address")
organization = flag.String("organization", "", "Certificates organization")
Expand All @@ -54,28 +54,28 @@ var (
)

func verifyCert(CACert string, certName string) {
if *isServer == true || *verify == false {
if *isAnchor == true || *verify == false {
return
}

bytesServerCert, err := ioutil.ReadFile(CACert)
bytesAnchorCert, err := ioutil.ReadFile(CACert)
if err != nil {
log.Printf("Could not load [%s] %s", CACert, err)
}

bytesClientCert, err := ioutil.ReadFile(certName)
bytesCert, err := ioutil.ReadFile(certName)
if err != nil {
log.Printf("Could not load [%s] %s", certName, err)
}

blockClient, _ := pem.Decode(bytesClientCert)
certClient, err := x509.ParseCertificate(blockClient.Bytes)
blockCert, _ := pem.Decode(bytesCert)
cert, err := x509.ParseCertificate(blockCert.Bytes)
if err != nil {
log.Printf("Could not parse [%s] %s", certName, err)
}

roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM(bytesServerCert)
ok := roots.AppendCertsFromPEM(bytesAnchorCert)
if !ok {
log.Printf("Could not add CA cert to poll")
}
Expand All @@ -84,29 +84,20 @@ func verifyCert(CACert string, certName string) {
Roots: roots,
}

if _, err = certClient.Verify(opts); err != nil {
if _, err = cert.Verify(opts); err != nil {
log.Printf("Failed to verify certificate: %s", err)
}
}

func instructionDisplay(server bool, CAcert string, Cert string) {
if server {
fmt.Printf("--------------------------------------------------------\n")
fmt.Printf("CA certificate: [%s]\n", CAcert)
fmt.Printf("Server certificate: [%s]\n", Cert)
fmt.Printf("--------------------------------------------------------\n")
fmt.Printf("You should now copy \"%s\" and \"%s\" ", CAcert, Cert)
fmt.Printf("to a safe location of your choice, and pass them to your ")
fmt.Printf("SSNTP server through its Config CAcert and Cert fields.\n")
} else {
fmt.Printf("--------------------------------------------------------\n")
fmt.Printf("CA certificate: [%s]\n", CAcert)
fmt.Printf("Client certificate: [%s]\n", Cert)
fmt.Printf("--------------------------------------------------------\n")
fmt.Printf("You should now copy \"%s\" and \"%s\" ", CAcert, Cert)
fmt.Printf("to a safe location of your choice, and pass them to your ")
fmt.Printf("SSNTP client through its Config CAcert and Cert fields.\n")
}
func instructionDisplay(CAcert string, Cert string) {
fmt.Printf("--------------------------------------------------------\n")
fmt.Printf("CA certificate: [%s]\n", CAcert)
fmt.Printf("Certificate: [%s]\n", Cert)
fmt.Printf("--------------------------------------------------------\n")
fmt.Printf("You should now copy \"%s\" and \"%s\" ", CAcert, Cert)
fmt.Printf("to a safe location of your choice, and pass them to your ")
fmt.Printf("SSNTP client or server through its Config CAcert and Cert ")
fmt.Printf("fields.\n")
}

func getFirstHost() string {
Expand All @@ -119,8 +110,8 @@ func checkCompulsoryOptions() {
log.Fatalf("Missing required --host parameter")
}

if *isServer == false && *serverCert == "" {
log.Fatalf("Missing required --server-cert parameter")
if *isAnchor == false && *anchorCert == "" {
log.Fatalf("Missing required --anchor-cert parameter")
}
}

Expand All @@ -136,7 +127,7 @@ func createCertificates(role ssntp.Role) {
firstHost := getFirstHost()
CAcertName := fmt.Sprintf("%s/CAcert-%s.pem", *installDir, firstHost)
certName := fmt.Sprintf("%s/cert-%s-%s.pem", *installDir, role.String(), firstHost)
if *isServer == true {
if *isAnchor == true {
CAcertOut, err := os.Create(CAcertName)
if err != nil {
log.Fatalf("Failed to open %s for writing: %s", CAcertName, err)
Expand All @@ -145,7 +136,7 @@ func createCertificates(role ssntp.Role) {
if err != nil {
log.Fatalf("Failed to open %s for writing: %s", certName, err)
}
err = certs.CreateServerCert(template, *isElliptic, certOut, CAcertOut)
err = certs.CreateAnchorCert(template, *isElliptic, certOut, CAcertOut)
if err != nil {
log.Fatalf("Failed to create certificate: %v", err)
}
Expand All @@ -159,9 +150,9 @@ func createCertificates(role ssntp.Role) {
}
} else {
// Need to fetch the public and private key from the signer
bytesCert, err := ioutil.ReadFile(*serverCert)
bytesCert, err := ioutil.ReadFile(*anchorCert)
if err != nil {
log.Fatalf("Could not load %s", *serverCert)
log.Fatalf("Could not load %s", *anchorCert)
}

// Create certificate: Concatenate public and private key
Expand All @@ -170,7 +161,7 @@ func createCertificates(role ssntp.Role) {
log.Fatalf("Failed to open %s for writing: %s", certName, err)
}

err = certs.CreateClientCert(template, *isElliptic, bytesCert, certOut)
err = certs.CreateCert(template, *isElliptic, bytesCert, certOut)
if err != nil {
log.Fatalf("Failed to create certificate: %v", err)
}
Expand All @@ -180,8 +171,8 @@ func createCertificates(role ssntp.Role) {
}
}

verifyCert(*serverCert, certName)
instructionDisplay(*isServer, CAcertName, certName)
verifyCert(*anchorCert, certName)
instructionDisplay(CAcertName, certName)
}

func dumpCertificate(certName string) {
Expand Down
26 changes: 13 additions & 13 deletions ssntp/certs/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func addDNSNames(hosts []string, names []string) []string {
return names
}

// CreateCertTemplate provides the certificate template from which client or server certificated can be derived.
// CreateCertTemplate provides the certificate template from which trust anchor or derivative certificates can be derived.
func CreateCertTemplate(role ssntp.Role, organization string, email string, hosts []string, mgmtIPs []string) (*x509.Certificate, error) {
notBefore := time.Now()
notAfter := notBefore.Add(365 * 24 * time.Hour)
Expand Down Expand Up @@ -164,8 +164,8 @@ func CreateCertTemplate(role ssntp.Role, organization string, email string, host
return &template, nil
}

// CreateServerCert creates the server certificate and the CA certificate. Both are written out PEM encoded.
func CreateServerCert(template *x509.Certificate, useElliptic bool, certOutput io.Writer, caCertOutput io.Writer) error {
// CreateAnchorCert creates the trust anchor certificate and the CA certificate. Both are written out PEM encoded.
func CreateAnchorCert(template *x509.Certificate, useElliptic bool, certOutput io.Writer, caCertOutput io.Writer) error {
priv, err := generatePrivateKey(useElliptic)
if err != nil {
return fmt.Errorf("Unable to create private key: %v", err)
Expand Down Expand Up @@ -202,8 +202,8 @@ func CreateServerCert(template *x509.Certificate, useElliptic bool, certOutput i
return nil
}

// CreateClientCert creates the client certificate signed by the giver server certificate. It is written PEM encoded.
func CreateClientCert(template *x509.Certificate, useElliptic bool, serverCert []byte, certOutput io.Writer) error {
// CreateCert creates the certificate signed by the giver trust anchor certificate. It is written PEM encoded.
func CreateCert(template *x509.Certificate, useElliptic bool, anchorCert []byte, certOutput io.Writer) error {
priv, err := generatePrivateKey(useElliptic)
if err != nil {
return fmt.Errorf("Unable to create private key: %v", err)
Expand All @@ -212,27 +212,27 @@ func CreateClientCert(template *x509.Certificate, useElliptic bool, serverCert [
template.IsCA = false

// Parent public key first
certBlock, rest := pem.Decode(serverCert)
certBlock, rest := pem.Decode(anchorCert)
parentCert, err := x509.ParseCertificate(certBlock.Bytes)
if err != nil {
return fmt.Errorf("Unable to parse server cert: %v", err)
return fmt.Errorf("Unable to parse anchor cert: %v", err)
}

// Parent private key
privKeyBlock, _ := pem.Decode(rest)
if privKeyBlock == nil {
return fmt.Errorf("Unable to extract private key from server cert: %v", err)
return fmt.Errorf("Unable to extract private key from anchor cert: %v", err)
}

serverPrivKey, err := keyFromPemBlock(privKeyBlock)
anchorPrivKey, err := keyFromPemBlock(privKeyBlock)
if err != nil {
return fmt.Errorf("Unable to parse private key from server cert: %v", err)
return fmt.Errorf("Unable to parse private key from anchor cert: %v", err)
}

// Create certificate signed by private key from serverCert
derBytes, err := x509.CreateCertificate(rand.Reader, template, parentCert, publicKey(priv), serverPrivKey)
// Create certificate signed by private key from anchorCert
derBytes, err := x509.CreateCertificate(rand.Reader, template, parentCert, publicKey(priv), anchorPrivKey)
if err != nil {
return fmt.Errorf("Unable to create client certificate: %v", err)
return fmt.Errorf("Unable to create certificate: %v", err)
}

// Write out certificate (including private key)
Expand Down
38 changes: 19 additions & 19 deletions ssntp/certs/certs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func TestCreateCertTemplateRoles(t *testing.T) {
}
}

func TestCreateServerCert(t *testing.T) {
func TestCreateAnchorCert(t *testing.T) {
var certOutput, caCertOutput bytes.Buffer

hosts := []string{"test.example.com", "test2.example.com"}
Expand All @@ -177,9 +177,9 @@ func TestCreateServerCert(t *testing.T) {
t.Errorf("Unexpected error when creating cert template: %v", err)
}

err = CreateServerCert(template, false, &certOutput, &caCertOutput)
err = CreateAnchorCert(template, false, &certOutput, &caCertOutput)
if err != nil {
t.Errorf("Unexpected error when creating server cert: %v", err)
t.Errorf("Unexpected error when creating anchor cert: %v", err)
}

// Decode server cert & private key
Expand All @@ -195,15 +195,15 @@ func TestCreateServerCert(t *testing.T) {

privKeyBlock, _ := pem.Decode(rest)
if privKeyBlock == nil {
t.Errorf("Unable to extract private key from server cert")
t.Errorf("Unable to extract private key from anchor cert")
}

serverPrivKey, err := keyFromPemBlock(privKeyBlock)
anchorPrivKey, err := keyFromPemBlock(privKeyBlock)
if err != nil {
t.Errorf("Unable to parse private key from server cert: %v", err)
t.Errorf("Unable to parse private key from anchor cert: %v", err)
}

_, ok := serverPrivKey.(*rsa.PrivateKey)
_, ok := anchorPrivKey.(*rsa.PrivateKey)
if !ok || err != nil {
t.Errorf("Expected RSA private key: %v", err)
}
Expand All @@ -224,8 +224,8 @@ func TestCreateServerCert(t *testing.T) {
}
}

func TestCreateClientCert(t *testing.T) {
var certOutput, caCertOutput, clientCertOutput bytes.Buffer
func TestCreateCert(t *testing.T) {
var anchorCertOutput, caCertOutput, certOutput bytes.Buffer

hosts := []string{"test.example.com", "test2.example.com"}
mgmtIPs := []string{}
Expand All @@ -235,29 +235,29 @@ func TestCreateClientCert(t *testing.T) {
t.Errorf("Unexpected error when creating cert template: %v", err)
}

err = CreateServerCert(template, false, &certOutput, &caCertOutput)
err = CreateAnchorCert(template, false, &anchorCertOutput, &caCertOutput)
if err != nil {
t.Errorf("Unexpected error when creating server cert: %v", err)
t.Errorf("Unexpected error when creating anchor cert: %v", err)
}

err = CreateClientCert(template, false, certOutput.Bytes(), &clientCertOutput)
err = CreateCert(template, false, anchorCertOutput.Bytes(), &certOutput)
if err != nil {
t.Errorf("Unexpected error when creating client cert: %v", err)
t.Errorf("Unexpected error when creating signed cert: %v", err)
}

// Decode client cert & private key
certBlock, rest := pem.Decode(clientCertOutput.Bytes())
// Decode signed cert & private key
certBlock, rest := pem.Decode(certOutput.Bytes())
privKeyBlock, _ := pem.Decode(rest)
if privKeyBlock == nil {
t.Errorf("Unable to extract private key from server cert")
t.Errorf("Unable to extract private key from anchor cert")
}

serverPrivKey, err := keyFromPemBlock(privKeyBlock)
anchorPrivKey, err := keyFromPemBlock(privKeyBlock)
if err != nil {
t.Errorf("Unable to parse private key from server cert: %v", err)
t.Errorf("Unable to parse private key from anchor cert: %v", err)
}

_, ok := serverPrivKey.(*rsa.PrivateKey)
_, ok := anchorPrivKey.(*rsa.PrivateKey)
if !ok || err != nil {
t.Errorf("Expected RSA private key: %v", err)
}
Expand Down
Loading

0 comments on commit 43401be

Please sign in to comment.