Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPKI: Add AS and Issuer certificate configuration #3345

Merged
merged 6 commits into from
Nov 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions go/tools/scion-pki/internal/v2/conf/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"as.go",
"issuer.go",
"key.go",
"trc.go",
"validity.go",
Expand All @@ -24,13 +26,21 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"as_test.go",
"issuer_test.go",
"key_test.go",
"main_test.go",
"trc_test.go",
],
data = ["//go/tools/scion-pki/internal/v2/conf/testdata:data"],
data = glob(["testdata/**"]),
embed = [":go_default_library"],
deps = [
"//go/tools/scion-pki/internal/v2/conf/testdata:go_default_library",
"//go/lib/addr:go_default_library",
"//go/lib/scrypto:go_default_library",
"//go/lib/scrypto/cert/v2:go_default_library",
"//go/lib/scrypto/trc/v2:go_default_library",
"//go/lib/util:go_default_library",
"//go/lib/xtest:go_default_library",
"@com_github_stretchr_testify//assert:go_default_library",
"@com_github_stretchr_testify//require:go_default_library",
],
Expand Down
90 changes: 90 additions & 0 deletions go/tools/scion-pki/internal/v2/conf/as.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright 2019 Anapaya Systems
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package conf

import (
"fmt"
"io"
"path/filepath"

"github.com/BurntSushi/toml"

"github.com/scionproto/scion/go/lib/addr"
"github.com/scionproto/scion/go/lib/scrypto"
"github.com/scionproto/scion/go/lib/serrors"
"github.com/scionproto/scion/go/tools/scion-pki/internal/pkicmn"
)

// ASFile returns the file where the AS certificate config is written to.
func ASFile(dir string, ia addr.IA, version scrypto.Version) string {
return filepath.Join(pkicmn.GetAsPath(dir, ia), fmt.Sprintf("as-v%d.toml", version))
}

// AS holds the AS certificate configuration.
type AS struct {
Description string `toml:"description"`
Version scrypto.Version `toml:"version"`
SigningKeyVersion *scrypto.KeyVersion `toml:"signing_key_version"`
EncryptionKeyVersion *scrypto.KeyVersion `toml:"encryption_key_version"`
RevocationKeyVersion *scrypto.KeyVersion `toml:"revocation_key_version"`
IssuerIA addr.IA `toml:"issuer_ia"`
IssuerCertVersion scrypto.Version `toml:"issuer_cert_version"`
OptDistPoints []addr.IA `toml:"optional_distribution_points"`
Validity Validity `toml:"validity"`
}

// LoadAS loads the AS certificate configuration from the provided file. The
// contents are already validated.
func LoadAS(file string) (AS, error) {
var cfg AS
if _, err := toml.DecodeFile(file, &cfg); err != nil {
return AS{}, serrors.WrapStr("unable to load AS certificate config from file", err,
"file", file)
}
if err := cfg.Validate(); err != nil {
return AS{}, serrors.WrapStr("unable to validate AS certificate config", err, "file", file)
}
return cfg, nil
}

// Encode writes the encoded AS certificate config to the writer.
func (cfg AS) Encode(w io.Writer) error {
if err := toml.NewEncoder(w).Encode(cfg); err != nil {
return serrors.WrapStr("unable to encode AS certificate config", err)
}
return nil
}

// Validate checks all values are set.
func (cfg AS) Validate() error {
switch {
case cfg.Description == "":
return serrors.New("description not set")
case cfg.Version == scrypto.LatestVer:
return serrors.New("version not set")
case cfg.SigningKeyVersion == nil:
return serrors.New("signing_key_version not set")
case cfg.EncryptionKeyVersion == nil:
return serrors.New("encryption_key_version not set")
case cfg.IssuerIA.IsWildcard():
return serrors.New("issuer_ia is wildcard", "input", cfg.IssuerIA)
case cfg.IssuerCertVersion == scrypto.LatestVer:
return serrors.New("issuer_cert_version not set")
}
if err := cfg.Validity.Validate(); err != nil {
return serrors.WrapStr("invalid validity", err)
}
return nil
}
78 changes: 78 additions & 0 deletions go/tools/scion-pki/internal/v2/conf/as_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2019 Anapaya Systems
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package conf_test

import (
"bytes"
"io/ioutil"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/scionproto/scion/go/lib/addr"
"github.com/scionproto/scion/go/lib/scrypto"
"github.com/scionproto/scion/go/lib/util"
"github.com/scionproto/scion/go/lib/xtest"
"github.com/scionproto/scion/go/tools/scion-pki/internal/v2/conf"
)

func TestASEncode(t *testing.T) {
rawGolden, err := ioutil.ReadFile("testdata/as-v1.toml")
require.NoError(t, err)

var buf bytes.Buffer
err = AS().Encode(&buf)
require.NoError(t, err)
assert.Equal(t, rawGolden, buf.Bytes())
}

func TestLoadAS(t *testing.T) {
cfg, err := conf.LoadAS("testdata/as-v1.toml")
require.NoError(t, err)
assert.Equal(t, AS(), cfg)
}

// TestUpdateGoldenAS provides an easy way to update the golden file after
// the format has changed.
func TestUpdateGoldenAS(t *testing.T) {
if *update {
var buf bytes.Buffer
err := AS().Encode(&buf)
require.NoError(t, err)
err = ioutil.WriteFile("testdata/as-v1.toml", buf.Bytes(), 0644)
require.NoError(t, err)
}
}

// AS generates a AS certificate configuration for testing.
func AS() conf.AS {
s, e, r := scrypto.KeyVersion(1), scrypto.KeyVersion(1), scrypto.KeyVersion(1)
return conf.AS{
Description: "Testing AS",
Version: 1,
SigningKeyVersion: &s,
EncryptionKeyVersion: &e,
RevocationKeyVersion: &r,
IssuerIA: xtest.MustParseIA("1-ff00:0:110"),
IssuerCertVersion: 1,
OptDistPoints: []addr.IA{xtest.MustParseIA("2-ff00:0:210")},
Validity: conf.Validity{
NotBefore: 42424242,
Validity: util.DurWrap{Duration: 3 * 24 * time.Hour},
},
}
}
85 changes: 85 additions & 0 deletions go/tools/scion-pki/internal/v2/conf/issuer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2019 Anapaya Systems
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package conf

import (
"fmt"
"io"
"path/filepath"

"github.com/BurntSushi/toml"

"github.com/scionproto/scion/go/lib/addr"
"github.com/scionproto/scion/go/lib/scrypto"
"github.com/scionproto/scion/go/lib/serrors"
"github.com/scionproto/scion/go/tools/scion-pki/internal/pkicmn"
)

// IssuerFile returns the file where the issuer certificate config is written to.
func IssuerFile(dir string, ia addr.IA, version scrypto.Version) string {
return filepath.Join(pkicmn.GetAsPath(dir, ia), fmt.Sprintf("issuer-v%d.toml", version))
}

// Issuer holds the issuer certificate configuration.
type Issuer struct {
Description string `toml:"description"`
Version scrypto.Version `toml:"version"`
IssuingKeyVersion *scrypto.KeyVersion `toml:"issuing_key_version"`
RevocationKeyVersion *scrypto.KeyVersion `toml:"revocation_key_version"`
TRCVersion scrypto.Version `toml:"trc_version"`
OptDistPoints []addr.IA `toml:"optional_distribution_points"`
Validity Validity `toml:"validity"`
}

// LoadIssuer loads the issuer certificate configuration from the provided file.
// The contents are already validated.
func LoadIssuer(file string) (Issuer, error) {
var cfg Issuer
if _, err := toml.DecodeFile(file, &cfg); err != nil {
return Issuer{}, serrors.WrapStr("unable to load issuer certificate config from file", err,
"file", file)
}
if err := cfg.Validate(); err != nil {
return Issuer{}, serrors.WrapStr("unable to validate issuer certificate config", err,
"file", file)
}
return cfg, nil
}

// Encode writes the encoded issuer certificate config to the writer.
func (cfg Issuer) Encode(w io.Writer) error {
if err := toml.NewEncoder(w).Encode(cfg); err != nil {
return serrors.WrapStr("unable to encode issuer certificate config", err)
}
return nil
}

// Validate checks all values are set.
func (cfg Issuer) Validate() error {
switch {
case cfg.Description == "":
return serrors.New("description not set")
case cfg.Version == scrypto.LatestVer:
return serrors.New("version not set")
case cfg.IssuingKeyVersion == nil:
return serrors.New("issuing_key_version not set")
case cfg.TRCVersion == scrypto.LatestVer:
return serrors.New("trc_version not set")
}
if err := cfg.Validity.Validate(); err != nil {
return serrors.WrapStr("invalid validity", err)
}
return nil
}
77 changes: 77 additions & 0 deletions go/tools/scion-pki/internal/v2/conf/issuer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2019 Anapaya Systems
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package conf_test

import (
"bytes"
"io/ioutil"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/scionproto/scion/go/lib/addr"
"github.com/scionproto/scion/go/lib/scrypto"
"github.com/scionproto/scion/go/lib/util"
"github.com/scionproto/scion/go/lib/xtest"
"github.com/scionproto/scion/go/tools/scion-pki/internal/v2/conf"
)

func TestIssuerEncode(t *testing.T) {
rawGolden, err := ioutil.ReadFile("testdata/issuer-v1.toml")
require.NoError(t, err)

var buf bytes.Buffer
err = Issuer().Encode(&buf)
require.NoError(t, err)
assert.Equal(t, rawGolden, buf.Bytes())

}

func TestLoadIssuer(t *testing.T) {
cfg, err := conf.LoadIssuer("testdata/issuer-v1.toml")
require.NoError(t, err)
assert.Equal(t, Issuer(), cfg)
}

// TestUpdateGoldenIssuer provides an easy way to update the golden file after
// the format has changed.
func TestUpdateGoldenIssuer(t *testing.T) {
if *update {
var buf bytes.Buffer
err := Issuer().Encode(&buf)
require.NoError(t, err)
err = ioutil.WriteFile("testdata/issuer-v1.toml", buf.Bytes(), 0644)
require.NoError(t, err)
}
}

// Issuer generates a issuer certificate configuration for testing.
func Issuer() conf.Issuer {
i, r := scrypto.KeyVersion(1), scrypto.KeyVersion(1)
return conf.Issuer{
Description: "Testing Issuer",
Version: 1,
IssuingKeyVersion: &i,
RevocationKeyVersion: &r,
TRCVersion: 1,
OptDistPoints: []addr.IA{xtest.MustParseIA("2-ff00:0:210")},
Validity: conf.Validity{
NotBefore: 42424242,
Validity: util.DurWrap{Duration: 3 * 24 * time.Hour},
},
}
}
Loading