@ -1,8 +1,13 @@
package authority
import (
"crypto"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"io/ioutil"
"net"
"reflect"
"testing"
@ -10,6 +15,7 @@ import (
"github.com/smallstep/assert"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/db"
"github.com/smallstep/cli/crypto/pemutil"
stepJOSE "github.com/smallstep/cli/jose"
)
@ -182,3 +188,121 @@ func TestAuthority_GetDatabase(t *testing.T) {
} )
}
}
func TestNewEmbeddedAuthority ( t * testing . T ) {
caPEM , err := ioutil . ReadFile ( "testdata/certs/root_ca.crt" )
assert . FatalError ( t , err )
crt , err := pemutil . ReadCertificate ( "testdata/certs/intermediate_ca.crt" )
assert . FatalError ( t , err )
key , err := pemutil . Read ( "testdata/secrets/intermediate_ca_key" , pemutil . WithPassword ( [ ] byte ( "pass" ) ) )
assert . FatalError ( t , err )
type args struct {
opts [ ] Option
}
tests := [ ] struct {
name string
args args
wantErr bool
} {
{ "ok" , args { [ ] Option { WithX509RootBundle ( caPEM ) , WithX509Signer ( crt , key . ( crypto . Signer ) ) } } , false } ,
{ "ok config file" , args { [ ] Option { WithConfigFile ( "../ca/testdata/ca.json" ) } } , false } ,
{ "ok config" , args { [ ] Option { WithConfig ( & Config {
Root : [ ] string { "testdata/certs/root_ca.crt" } ,
IntermediateCert : "testdata/certs/intermediate_ca.crt" ,
IntermediateKey : "testdata/secrets/intermediate_ca_key" ,
Password : "pass" ,
AuthorityConfig : & AuthConfig { } ,
} ) } } , false } ,
{ "fail options" , args { [ ] Option { WithX509RootBundle ( [ ] byte ( "bad data" ) ) } } , true } ,
{ "fail missing root" , args { [ ] Option { WithX509Signer ( crt , key . ( crypto . Signer ) ) } } , true } ,
{ "fail missing signer" , args { [ ] Option { WithX509RootBundle ( caPEM ) } } , true } ,
{ "fail missing root file" , args { [ ] Option { WithConfig ( & Config {
IntermediateCert : "testdata/certs/intermediate_ca.crt" ,
IntermediateKey : "testdata/secrets/intermediate_ca_key" ,
Password : "pass" ,
AuthorityConfig : & AuthConfig { } ,
} ) } } , true } ,
{ "fail missing issuer" , args { [ ] Option { WithConfig ( & Config {
Root : [ ] string { "testdata/certs/root_ca.crt" } ,
IntermediateKey : "testdata/secrets/intermediate_ca_key" ,
Password : "pass" ,
AuthorityConfig : & AuthConfig { } ,
} ) } } , true } ,
{ "fail missing signer" , args { [ ] Option { WithConfig ( & Config {
Root : [ ] string { "testdata/certs/root_ca.crt" } ,
IntermediateCert : "testdata/certs/intermediate_ca.crt" ,
Password : "pass" ,
AuthorityConfig : & AuthConfig { } ,
} ) } } , true } ,
{ "fail bad password" , args { [ ] Option { WithConfig ( & Config {
Root : [ ] string { "testdata/certs/root_ca.crt" } ,
IntermediateCert : "testdata/certs/intermediate_ca.crt" ,
IntermediateKey : "testdata/secrets/intermediate_ca_key" ,
Password : "bad" ,
AuthorityConfig : & AuthConfig { } ,
} ) } } , true } ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
got , err := NewEmbeddedAuthority ( tt . args . opts ... )
if ( err != nil ) != tt . wantErr {
t . Errorf ( "NewEmbeddedAuthority() error = %v, wantErr %v" , err , tt . wantErr )
return
}
if err == nil {
assert . True ( t , got . initOnce )
assert . NotNil ( t , got . rootX509Certs )
assert . NotNil ( t , got . x509Signer )
assert . NotNil ( t , got . x509Issuer )
}
} )
}
}
func TestNewEmbeddedAuthority_Sign ( t * testing . T ) {
caPEM , err := ioutil . ReadFile ( "testdata/certs/root_ca.crt" )
assert . FatalError ( t , err )
crt , err := pemutil . ReadCertificate ( "testdata/certs/intermediate_ca.crt" )
assert . FatalError ( t , err )
key , err := pemutil . Read ( "testdata/secrets/intermediate_ca_key" , pemutil . WithPassword ( [ ] byte ( "pass" ) ) )
assert . FatalError ( t , err )
a , err := NewEmbeddedAuthority ( WithX509RootBundle ( caPEM ) , WithX509Signer ( crt , key . ( crypto . Signer ) ) )
assert . FatalError ( t , err )
// Sign
cr , err := x509 . CreateCertificateRequest ( rand . Reader , & x509 . CertificateRequest {
DNSNames : [ ] string { "foo.bar.zar" } ,
} , key )
assert . FatalError ( t , err )
csr , err := x509 . ParseCertificateRequest ( cr )
assert . FatalError ( t , err )
cert , err := a . Sign ( csr , provisioner . Options { } )
assert . FatalError ( t , err )
assert . Equals ( t , [ ] string { "foo.bar.zar" } , cert [ 0 ] . DNSNames )
assert . Equals ( t , crt , cert [ 1 ] )
}
func TestNewEmbeddedAuthority_GetTLSCertificate ( t * testing . T ) {
caPEM , err := ioutil . ReadFile ( "testdata/certs/root_ca.crt" )
assert . FatalError ( t , err )
crt , err := pemutil . ReadCertificate ( "testdata/certs/intermediate_ca.crt" )
assert . FatalError ( t , err )
key , err := pemutil . Read ( "testdata/secrets/intermediate_ca_key" , pemutil . WithPassword ( [ ] byte ( "pass" ) ) )
assert . FatalError ( t , err )
a , err := NewEmbeddedAuthority ( WithX509RootBundle ( caPEM ) , WithX509Signer ( crt , key . ( crypto . Signer ) ) )
assert . FatalError ( t , err )
// GetTLSCertificate
cert , err := a . GetTLSCertificate ( )
assert . FatalError ( t , err )
assert . Equals ( t , [ ] string { "localhost" } , cert . Leaf . DNSNames )
assert . True ( t , cert . Leaf . IPAddresses [ 0 ] . Equal ( net . ParseIP ( "127.0.0.1" ) ) )
assert . True ( t , cert . Leaf . IPAddresses [ 1 ] . Equal ( net . ParseIP ( "::1" ) ) )
}