Skip to content

Commit

Permalink
added error handler for custom cert loading #11
Browse files Browse the repository at this point in the history
When user try use own certificates and try loading them for registry token, loadCerts can get an error, but it doesn't display. If error exist registry-admin try creates new certs. The createCerts throw an error because user certs already exist in a destination folder.
  • Loading branch information
zebox committed Feb 3, 2023
1 parent 1a3554e commit f0b7124
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 4 deletions.
45 changes: 42 additions & 3 deletions app/registry/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ const (
privateKeyName = "/registry_auth.key"
publicKeyName = "/registry_auth.pub"
caName = "/registry_auth_ca.crt"

errPrefixCertsNotFound = "cert file not found"
)

var errTemplateCertFileAlreadyExist = "cert file '%s' already exist"
Expand Down Expand Up @@ -92,7 +94,7 @@ type ClientToken struct {
AccessToken string `json:"access_token"`
}

// AccessToken is a token instance using for authorization in registry
// AccessToken is a token instance using for authorization in registryal
type AccessToken struct {
Certs

Expand Down Expand Up @@ -187,6 +189,12 @@ func NewRegistryToken(opts ...TokenOption) (*AccessToken, error) {
}

if err = rt.loadCerts(); err != nil {

// throw error when certs files exist but load is fail, otherwise tries to generate new certs
if !strings.HasPrefix(err.Error(), errPrefixCertsNotFound) {
return nil, err
}

err = rt.createCerts()
if err != nil {
return nil, err
Expand Down Expand Up @@ -285,10 +293,36 @@ func (rt *AccessToken) createCerts() (err error) {
return rt.saveKeys()
}

// statCerts - checks files defined in certs option for exist
func (rt *AccessToken) statCerts() error {
var (
errExist error
errString []string
)

if _, err := os.Stat(rt.KeyPath); err != nil {
errString = append(errString, rt.KeyPath)
}

if _, err := os.Stat(rt.PublicKeyPath); err != nil {
errString = append(errString, rt.PublicKeyPath)
}

if _, err := os.Stat(rt.CARootPath); err != nil {
errString = append(errString, rt.CARootPath)
}

if len(errString) > 0 {
errExist = fmt.Errorf("%s: %s", errPrefixCertsNotFound, strings.Join(errString, ", "))
}

return errExist
}

func (rt *AccessToken) loadCerts() (err error) {

if _, err = os.Stat(rt.Certs.RootPath); err != nil {
return err
if errStat := rt.statCerts(); errStat != nil {
return errStat
}

rt.privateKey, err = libtrust.LoadKeyFile(rt.Certs.KeyPath)
Expand All @@ -303,8 +337,13 @@ func (rt *AccessToken) loadCerts() (err error) {

bundle, errCaLoad := libtrust.LoadCertificateBundle(rt.Certs.CARootPath)
if errCaLoad != nil {

return errCaLoad
}

if len(bundle) == 0 {
return errors.New("certificates bundle not found in CA file")
}
rt.caRoot = bundle[0]

return nil
Expand Down
41 changes: 40 additions & 1 deletion app/registry/token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestNewRegistryToken(t *testing.T) {
assert.NoError(t, os.RemoveAll(path))
}()

// test with defaults with generate
// test with defaults certs by auto create
rt, err := NewRegistryToken()
require.NoError(t, err)
assert.Equal(t, int64(defaultTokenExpiration), rt.tokenExpiration)
Expand Down Expand Up @@ -117,6 +117,45 @@ func TestNewRegistryToken(t *testing.T) {
assert.Error(t, err)
}

// Test for create registry token with a custom certificates, which created with an external tool
func TestNewRegistryTokenWithCustomCerts(t *testing.T) {
tmpDir, errDir := os.MkdirTemp(os.TempDir(), "test_cert")
require.NoError(t, errDir)
defer func() {
assert.NoError(t, os.RemoveAll(tmpDir))
}()

// for emit error when file loadings with empty content
clearFileContentFn := func(path string) {
f, errOpen := os.OpenFile(path, os.O_CREATE, 0o755)
require.NoError(t, errOpen)
require.NoError(t, f.Truncate(0))
assert.NoError(t, f.Close())
}
testToken := AccessToken{
Certs: Certs{
RootPath: tmpDir,
KeyPath: tmpDir + "/test_private.key",
PublicKeyPath: tmpDir + "/test_public.pub",
CARootPath: tmpDir + "/CA_test_public.pub.crt",
},
}
require.NoError(t, testToken.createCerts())

err := testToken.loadCerts()
assert.NoError(t, err)

// test for errors when certs files loads
clearFileContentFn(testToken.Certs.CARootPath)
assert.Error(t, testToken.loadCerts())

clearFileContentFn(testToken.Certs.PublicKeyPath)
assert.Error(t, testToken.loadCerts())

clearFileContentFn(testToken.Certs.KeyPath)
assert.Error(t, testToken.loadCerts())
}

func TestRegistryToken_Generate(t *testing.T) {
tmpDir, errDir := os.MkdirTemp(os.TempDir(), "test_cert")
require.NoError(t, errDir)
Expand Down

0 comments on commit f0b7124

Please sign in to comment.