| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 | 
							- //go:build !windows
 
- // +build !windows
 
- package main
 
- import (
 
- 	"bytes"
 
- 	"crypto/rand"
 
- 	"errors"
 
- 	"io/ioutil"
 
- 	"os"
 
- 	"testing"
 
- 	"time"
 
- 	"github.com/slackhq/nebula/cert"
 
- 	"github.com/stretchr/testify/assert"
 
- 	"golang.org/x/crypto/ed25519"
 
- )
 
- //TODO: test file permissions
 
- func Test_signSummary(t *testing.T) {
 
- 	assert.Equal(t, "sign <flags>: create and sign a certificate", signSummary())
 
- }
 
- func Test_signHelp(t *testing.T) {
 
- 	ob := &bytes.Buffer{}
 
- 	signHelp(ob)
 
- 	assert.Equal(
 
- 		t,
 
- 		"Usage of "+os.Args[0]+" sign <flags>: create and sign a certificate\n"+
 
- 			"  -ca-crt string\n"+
 
- 			"    \tOptional: path to the signing CA cert (default \"ca.crt\")\n"+
 
- 			"  -ca-key string\n"+
 
- 			"    \tOptional: path to the signing CA key (default \"ca.key\")\n"+
 
- 			"  -duration duration\n"+
 
- 			"    \tOptional: how long the cert should be valid for. The default is 1 second before the signing cert expires. Valid time units are seconds: \"s\", minutes: \"m\", hours: \"h\"\n"+
 
- 			"  -groups string\n"+
 
- 			"    \tOptional: comma separated list of groups\n"+
 
- 			"  -in-pub string\n"+
 
- 			"    \tOptional (if out-key not set): path to read a previously generated public key\n"+
 
- 			"  -ip string\n"+
 
- 			"    \tRequired: ipv4 address and network in CIDR notation to assign the cert\n"+
 
- 			"  -name string\n"+
 
- 			"    \tRequired: name of the cert, usually a hostname\n"+
 
- 			"  -out-crt string\n"+
 
- 			"    \tOptional: path to write the certificate to\n"+
 
- 			"  -out-key string\n"+
 
- 			"    \tOptional (if in-pub not set): path to write the private key to\n"+
 
- 			"  -out-qr string\n"+
 
- 			"    \tOptional: output a qr code image (png) of the certificate\n"+
 
- 			"  -subnets string\n"+
 
- 			"    \tOptional: comma separated list of ipv4 address and network in CIDR notation. Subnets this cert can serve for\n",
 
- 		ob.String(),
 
- 	)
 
- }
 
- func Test_signCert(t *testing.T) {
 
- 	ob := &bytes.Buffer{}
 
- 	eb := &bytes.Buffer{}
 
- 	nopw := &StubPasswordReader{
 
- 		password: []byte(""),
 
- 		err:      nil,
 
- 	}
 
- 	errpw := &StubPasswordReader{
 
- 		password: []byte(""),
 
- 		err:      errors.New("stub error"),
 
- 	}
 
- 	passphrase := []byte("DO NOT USE THIS KEY")
 
- 	testpw := &StubPasswordReader{
 
- 		password: passphrase,
 
- 		err:      nil,
 
- 	}
 
- 	// required args
 
- 	assertHelpError(t, signCert(
 
- 		[]string{"-ca-crt", "./nope", "-ca-key", "./nope", "-ip", "1.1.1.1/24", "-out-key", "nope", "-out-crt", "nope"}, ob, eb, nopw,
 
- 	), "-name is required")
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	assertHelpError(t, signCert(
 
- 		[]string{"-ca-crt", "./nope", "-ca-key", "./nope", "-name", "test", "-out-key", "nope", "-out-crt", "nope"}, ob, eb, nopw,
 
- 	), "-ip is required")
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// cannot set -in-pub and -out-key
 
- 	assertHelpError(t, signCert(
 
- 		[]string{"-ca-crt", "./nope", "-ca-key", "./nope", "-name", "test", "-in-pub", "nope", "-ip", "1.1.1.1/24", "-out-crt", "nope", "-out-key", "nope"}, ob, eb, nopw,
 
- 	), "cannot set both -in-pub and -out-key")
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// failed to read key
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args := []string{"-ca-crt", "./nope", "-ca-key", "./nope", "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", "nope", "-out-key", "nope", "-duration", "100m"}
 
- 	assert.EqualError(t, signCert(args, ob, eb, nopw), "error while reading ca-key: open ./nope: "+NoSuchFileError)
 
- 	// failed to unmarshal key
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	caKeyF, err := ioutil.TempFile("", "sign-cert.key")
 
- 	assert.Nil(t, err)
 
- 	defer os.Remove(caKeyF.Name())
 
- 	args = []string{"-ca-crt", "./nope", "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", "nope", "-out-key", "nope", "-duration", "100m"}
 
- 	assert.EqualError(t, signCert(args, ob, eb, nopw), "error while parsing ca-key: input did not contain a valid PEM encoded block")
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// Write a proper ca key for later
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	caPub, caPriv, _ := ed25519.GenerateKey(rand.Reader)
 
- 	caKeyF.Write(cert.MarshalEd25519PrivateKey(caPriv))
 
- 	// failed to read cert
 
- 	args = []string{"-ca-crt", "./nope", "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", "nope", "-out-key", "nope", "-duration", "100m"}
 
- 	assert.EqualError(t, signCert(args, ob, eb, nopw), "error while reading ca-crt: open ./nope: "+NoSuchFileError)
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// failed to unmarshal cert
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	caCrtF, err := ioutil.TempFile("", "sign-cert.crt")
 
- 	assert.Nil(t, err)
 
- 	defer os.Remove(caCrtF.Name())
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", "nope", "-out-key", "nope", "-duration", "100m"}
 
- 	assert.EqualError(t, signCert(args, ob, eb, nopw), "error while parsing ca-crt: input did not contain a valid PEM encoded block")
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// write a proper ca cert for later
 
- 	ca := cert.NebulaCertificate{
 
- 		Details: cert.NebulaCertificateDetails{
 
- 			Name:      "ca",
 
- 			NotBefore: time.Now(),
 
- 			NotAfter:  time.Now().Add(time.Minute * 200),
 
- 			PublicKey: caPub,
 
- 			IsCA:      true,
 
- 		},
 
- 	}
 
- 	b, _ := ca.MarshalToPEM()
 
- 	caCrtF.Write(b)
 
- 	// failed to read pub
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", "nope", "-in-pub", "./nope", "-duration", "100m"}
 
- 	assert.EqualError(t, signCert(args, ob, eb, nopw), "error while reading in-pub: open ./nope: "+NoSuchFileError)
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// failed to unmarshal pub
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	inPubF, err := ioutil.TempFile("", "in.pub")
 
- 	assert.Nil(t, err)
 
- 	defer os.Remove(inPubF.Name())
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", "nope", "-in-pub", inPubF.Name(), "-duration", "100m"}
 
- 	assert.EqualError(t, signCert(args, ob, eb, nopw), "error while parsing in-pub: input did not contain a valid PEM encoded block")
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// write a proper pub for later
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	inPub, _ := x25519Keypair()
 
- 	inPubF.Write(cert.MarshalX25519PublicKey(inPub))
 
- 	// bad ip cidr
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "a1.1.1.1/24", "-out-crt", "nope", "-out-key", "nope", "-duration", "100m"}
 
- 	assertHelpError(t, signCert(args, ob, eb, nopw), "invalid ip definition: invalid CIDR address: a1.1.1.1/24")
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "100::100/100", "-out-crt", "nope", "-out-key", "nope", "-duration", "100m"}
 
- 	assertHelpError(t, signCert(args, ob, eb, nopw), "invalid ip definition: can only be ipv4, have 100::100/100")
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// bad subnet cidr
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", "nope", "-out-key", "nope", "-duration", "100m", "-subnets", "a"}
 
- 	assertHelpError(t, signCert(args, ob, eb, nopw), "invalid subnet definition: invalid CIDR address: a")
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", "nope", "-out-key", "nope", "-duration", "100m", "-subnets", "100::100/100"}
 
- 	assertHelpError(t, signCert(args, ob, eb, nopw), "invalid subnet definition: can only be ipv4, have 100::100/100")
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// mismatched ca key
 
- 	_, caPriv2, _ := ed25519.GenerateKey(rand.Reader)
 
- 	caKeyF2, err := ioutil.TempFile("", "sign-cert-2.key")
 
- 	assert.Nil(t, err)
 
- 	defer os.Remove(caKeyF2.Name())
 
- 	caKeyF2.Write(cert.MarshalEd25519PrivateKey(caPriv2))
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF2.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", "nope", "-out-key", "nope", "-duration", "100m", "-subnets", "a"}
 
- 	assert.EqualError(t, signCert(args, ob, eb, nopw), "refusing to sign, root certificate does not match private key")
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// failed key write
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", "/do/not/write/pleasecrt", "-out-key", "/do/not/write/pleasekey", "-duration", "100m", "-subnets", "10.1.1.1/32"}
 
- 	assert.EqualError(t, signCert(args, ob, eb, nopw), "error while writing out-key: open /do/not/write/pleasekey: "+NoSuchDirError)
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// create temp key file
 
- 	keyF, err := ioutil.TempFile("", "test.key")
 
- 	assert.Nil(t, err)
 
- 	os.Remove(keyF.Name())
 
- 	// failed cert write
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", "/do/not/write/pleasecrt", "-out-key", keyF.Name(), "-duration", "100m", "-subnets", "10.1.1.1/32"}
 
- 	assert.EqualError(t, signCert(args, ob, eb, nopw), "error while writing out-crt: open /do/not/write/pleasecrt: "+NoSuchDirError)
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	os.Remove(keyF.Name())
 
- 	// create temp cert file
 
- 	crtF, err := ioutil.TempFile("", "test.crt")
 
- 	assert.Nil(t, err)
 
- 	os.Remove(crtF.Name())
 
- 	// test proper cert with removed empty groups and subnets
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-out-key", keyF.Name(), "-duration", "100m", "-subnets", "10.1.1.1/32, ,   10.2.2.2/32   ,   ,  ,, 10.5.5.5/32", "-groups", "1,,   2    ,        ,,,3,4,5"}
 
- 	assert.Nil(t, signCert(args, ob, eb, nopw))
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// read cert and key files
 
- 	rb, _ := ioutil.ReadFile(keyF.Name())
 
- 	lKey, b, err := cert.UnmarshalX25519PrivateKey(rb)
 
- 	assert.Len(t, b, 0)
 
- 	assert.Nil(t, err)
 
- 	assert.Len(t, lKey, 32)
 
- 	rb, _ = ioutil.ReadFile(crtF.Name())
 
- 	lCrt, b, err := cert.UnmarshalNebulaCertificateFromPEM(rb)
 
- 	assert.Len(t, b, 0)
 
- 	assert.Nil(t, err)
 
- 	assert.Equal(t, "test", lCrt.Details.Name)
 
- 	assert.Equal(t, "1.1.1.1/24", lCrt.Details.Ips[0].String())
 
- 	assert.Len(t, lCrt.Details.Ips, 1)
 
- 	assert.False(t, lCrt.Details.IsCA)
 
- 	assert.Equal(t, []string{"1", "2", "3", "4", "5"}, lCrt.Details.Groups)
 
- 	assert.Len(t, lCrt.Details.Subnets, 3)
 
- 	assert.Len(t, lCrt.Details.PublicKey, 32)
 
- 	assert.Equal(t, time.Duration(time.Minute*100), lCrt.Details.NotAfter.Sub(lCrt.Details.NotBefore))
 
- 	sns := []string{}
 
- 	for _, sn := range lCrt.Details.Subnets {
 
- 		sns = append(sns, sn.String())
 
- 	}
 
- 	assert.Equal(t, []string{"10.1.1.1/32", "10.2.2.2/32", "10.5.5.5/32"}, sns)
 
- 	issuer, _ := ca.Sha256Sum()
 
- 	assert.Equal(t, issuer, lCrt.Details.Issuer)
 
- 	assert.True(t, lCrt.CheckSignature(caPub))
 
- 	// test proper cert with in-pub
 
- 	os.Remove(keyF.Name())
 
- 	os.Remove(crtF.Name())
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-in-pub", inPubF.Name(), "-duration", "100m", "-groups", "1"}
 
- 	assert.Nil(t, signCert(args, ob, eb, nopw))
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// read cert file and check pub key matches in-pub
 
- 	rb, _ = ioutil.ReadFile(crtF.Name())
 
- 	lCrt, b, err = cert.UnmarshalNebulaCertificateFromPEM(rb)
 
- 	assert.Len(t, b, 0)
 
- 	assert.Nil(t, err)
 
- 	assert.Equal(t, lCrt.Details.PublicKey, inPub)
 
- 	// test refuse to sign cert with duration beyond root
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-out-key", keyF.Name(), "-duration", "1000m", "-subnets", "10.1.1.1/32, ,   10.2.2.2/32   ,   ,  ,, 10.5.5.5/32", "-groups", "1,,   2    ,        ,,,3,4,5"}
 
- 	assert.EqualError(t, signCert(args, ob, eb, nopw), "refusing to sign, root certificate constraints violated: certificate expires after signing certificate")
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// create valid cert/key for overwrite tests
 
- 	os.Remove(keyF.Name())
 
- 	os.Remove(crtF.Name())
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-out-key", keyF.Name(), "-duration", "100m", "-subnets", "10.1.1.1/32, ,   10.2.2.2/32   ,   ,  ,, 10.5.5.5/32", "-groups", "1,,   2    ,        ,,,3,4,5"}
 
- 	assert.Nil(t, signCert(args, ob, eb, nopw))
 
- 	// test that we won't overwrite existing key file
 
- 	os.Remove(crtF.Name())
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-out-key", keyF.Name(), "-duration", "100m", "-subnets", "10.1.1.1/32, ,   10.2.2.2/32   ,   ,  ,, 10.5.5.5/32", "-groups", "1,,   2    ,        ,,,3,4,5"}
 
- 	assert.EqualError(t, signCert(args, ob, eb, nopw), "refusing to overwrite existing key: "+keyF.Name())
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// create valid cert/key for overwrite tests
 
- 	os.Remove(keyF.Name())
 
- 	os.Remove(crtF.Name())
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-out-key", keyF.Name(), "-duration", "100m", "-subnets", "10.1.1.1/32, ,   10.2.2.2/32   ,   ,  ,, 10.5.5.5/32", "-groups", "1,,   2    ,        ,,,3,4,5"}
 
- 	assert.Nil(t, signCert(args, ob, eb, nopw))
 
- 	// test that we won't overwrite existing certificate file
 
- 	os.Remove(keyF.Name())
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-out-key", keyF.Name(), "-duration", "100m", "-subnets", "10.1.1.1/32, ,   10.2.2.2/32   ,   ,  ,, 10.5.5.5/32", "-groups", "1,,   2    ,        ,,,3,4,5"}
 
- 	assert.EqualError(t, signCert(args, ob, eb, nopw), "refusing to overwrite existing cert: "+crtF.Name())
 
- 	assert.Empty(t, ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// create valid cert/key using encrypted CA key
 
- 	os.Remove(caKeyF.Name())
 
- 	os.Remove(caCrtF.Name())
 
- 	os.Remove(keyF.Name())
 
- 	os.Remove(crtF.Name())
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	caKeyF, err = ioutil.TempFile("", "sign-cert.key")
 
- 	assert.Nil(t, err)
 
- 	defer os.Remove(caKeyF.Name())
 
- 	caCrtF, err = ioutil.TempFile("", "sign-cert.crt")
 
- 	assert.Nil(t, err)
 
- 	defer os.Remove(caCrtF.Name())
 
- 	// generate the encrypted key
 
- 	caPub, caPriv, _ = ed25519.GenerateKey(rand.Reader)
 
- 	kdfParams := cert.NewArgon2Parameters(64*1024, 4, 3)
 
- 	b, _ = cert.EncryptAndMarshalEd25519PrivateKey(caPriv, passphrase, kdfParams)
 
- 	caKeyF.Write(b)
 
- 	ca = cert.NebulaCertificate{
 
- 		Details: cert.NebulaCertificateDetails{
 
- 			Name:      "ca",
 
- 			NotBefore: time.Now(),
 
- 			NotAfter:  time.Now().Add(time.Minute * 200),
 
- 			PublicKey: caPub,
 
- 			IsCA:      true,
 
- 		},
 
- 	}
 
- 	b, _ = ca.MarshalToPEM()
 
- 	caCrtF.Write(b)
 
- 	// test with the proper password
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-out-key", keyF.Name(), "-duration", "100m", "-subnets", "10.1.1.1/32, ,   10.2.2.2/32   ,   ,  ,, 10.5.5.5/32", "-groups", "1,,   2    ,        ,,,3,4,5"}
 
- 	assert.Nil(t, signCert(args, ob, eb, testpw))
 
- 	assert.Equal(t, "Enter passphrase: ", ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// test with the wrong password
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	testpw.password = []byte("invalid password")
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-out-key", keyF.Name(), "-duration", "100m", "-subnets", "10.1.1.1/32, ,   10.2.2.2/32   ,   ,  ,, 10.5.5.5/32", "-groups", "1,,   2    ,        ,,,3,4,5"}
 
- 	assert.Error(t, signCert(args, ob, eb, testpw))
 
- 	assert.Equal(t, "Enter passphrase: ", ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// test with the user not entering a password
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-out-key", keyF.Name(), "-duration", "100m", "-subnets", "10.1.1.1/32, ,   10.2.2.2/32   ,   ,  ,, 10.5.5.5/32", "-groups", "1,,   2    ,        ,,,3,4,5"}
 
- 	assert.Error(t, signCert(args, ob, eb, nopw))
 
- 	// normally the user hitting enter on the prompt would add newlines between these
 
- 	assert.Equal(t, "Enter passphrase: Enter passphrase: Enter passphrase: Enter passphrase: Enter passphrase: ", ob.String())
 
- 	assert.Empty(t, eb.String())
 
- 	// test an error condition
 
- 	ob.Reset()
 
- 	eb.Reset()
 
- 	args = []string{"-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-out-key", keyF.Name(), "-duration", "100m", "-subnets", "10.1.1.1/32, ,   10.2.2.2/32   ,   ,  ,, 10.5.5.5/32", "-groups", "1,,   2    ,        ,,,3,4,5"}
 
- 	assert.Error(t, signCert(args, ob, eb, errpw))
 
- 	assert.Equal(t, "Enter passphrase: ", ob.String())
 
- 	assert.Empty(t, eb.String())
 
- }
 
 
  |