Skip to content

Commit

Permalink
Export Fulcio extension OIDs (#761)
Browse files Browse the repository at this point in the history
* Export Fulcio extension OIDs.

Pulls Fulcio OIDs into a global var so that they can be referenced by
other libraries.

Signed-off-by: Billy Lynch <[email protected]>

* Create pkg/certificate

Refactors common certificate behavior into a distinct package.

Adds ability to go to/from Extension type <-> []pkix.Extensions.

Signed-off-by: Billy Lynch <[email protected]>

* Remove pkg/ca/extensions.go.

Replaced with pkg/certificates/extensions.go.

Signed-off-by: Billy Lynch <[email protected]>

Signed-off-by: Billy Lynch <[email protected]>
  • Loading branch information
wlynch authored Aug 25, 2022
1 parent f210224 commit d9086d2
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 41 deletions.
3 changes: 2 additions & 1 deletion pkg/ca/baseca/baseca_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

ct "github.com/google/certificate-transparency-go"
"github.com/sigstore/fulcio/pkg/ca"
"github.com/sigstore/fulcio/pkg/certificate"
"github.com/sigstore/fulcio/pkg/test"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"github.com/sigstore/sigstore/pkg/signature"
Expand Down Expand Up @@ -92,7 +93,7 @@ func (tp testPrincipal) Name(context.Context) string {

func (tp testPrincipal) Embed(ctx context.Context, cert *x509.Certificate) (err error) {
cert.EmailAddresses = []string{"[email protected]"}
cert.ExtraExtensions, err = ca.Extensions{
cert.ExtraExtensions, err = certificate.Extensions{
Issuer: "example.com",
}.Render()
return
Expand Down
17 changes: 17 additions & 0 deletions pkg/certificate/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2022 The Sigstore Authors.
//
// 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 certificate contains helpers for getting data from Fulcio issued
// x509 certificates.
package certificate
48 changes: 41 additions & 7 deletions pkg/ca/extensions.go → pkg/certificate/extensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package ca
package certificate

import (
"crypto/x509/pkix"
"encoding/asn1"
"errors"
)

var (
OIDIssuer = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 1}
OIDGitHubWorkflowTrigger = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 2}
OIDGitHubWorkflowSHA = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 3}
OIDGitHubWorkflowName = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 4}
OIDGitHubWorkflowRepository = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 5}
OIDGitHubWorkflowRef = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 6}
)

// Extensions contains all custom x509 extensions defined by Fulcio
type Extensions struct {
// NB: New extensions must be added here and documented
Expand Down Expand Up @@ -57,41 +66,66 @@ func (e Extensions) Render() ([]pkix.Extension, error) {

if e.Issuer != "" {
exts = append(exts, pkix.Extension{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 1},
Id: OIDIssuer,
Value: []byte(e.Issuer),
})
} else {
return nil, errors.New("extensions must have a non-empty issuer url")
}
if e.GithubWorkflowTrigger != "" {
exts = append(exts, pkix.Extension{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 2},
Id: OIDGitHubWorkflowTrigger,
Value: []byte(e.GithubWorkflowTrigger),
})
}
if e.GithubWorkflowSHA != "" {
exts = append(exts, pkix.Extension{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 3},
Id: OIDGitHubWorkflowSHA,
Value: []byte(e.GithubWorkflowSHA),
})
}
if e.GithubWorkflowName != "" {
exts = append(exts, pkix.Extension{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 4},
Id: OIDGitHubWorkflowName,
Value: []byte(e.GithubWorkflowName),
})
}
if e.GithubWorkflowRepository != "" {
exts = append(exts, pkix.Extension{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 5},
Id: OIDGitHubWorkflowRepository,
Value: []byte(e.GithubWorkflowRepository),
})
}
if e.GithubWorkflowRef != "" {
exts = append(exts, pkix.Extension{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 6},
Id: OIDGitHubWorkflowRef,
Value: []byte(e.GithubWorkflowRef),
})
}
return exts, nil
}

func ParseExtensions(ext []pkix.Extension) (Extensions, error) {
out := Extensions{}

for _, e := range ext {
switch {
case e.Id.Equal(OIDIssuer):
out.Issuer = string(e.Value)
case e.Id.Equal(OIDGitHubWorkflowTrigger):
out.GithubWorkflowTrigger = string(e.Value)
case e.Id.Equal(OIDGitHubWorkflowSHA):
out.GithubWorkflowSHA = string(e.Value)
case e.Id.Equal(OIDGitHubWorkflowName):
out.GithubWorkflowName = string(e.Value)
case e.Id.Equal(OIDGitHubWorkflowRepository):
out.GithubWorkflowRepository = string(e.Value)
case e.Id.Equal(OIDGitHubWorkflowRef):
out.GithubWorkflowRef = string(e.Value)
}
}

// We only ever return nil, but leaving error in place so that we can add
// more complex parsing of fields in a backwards compatible way if needed.
return out, nil
}
41 changes: 20 additions & 21 deletions pkg/ca/extensions_test.go → pkg/certificate/extensions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package ca
package certificate

import (
"bytes"
"crypto/x509/pkix"
"encoding/asn1"

"testing"

"github.com/google/go-cmp/cmp"
)

func TestRenderExtensions(t *testing.T) {
func TestExtensions(t *testing.T) {
tests := map[string]struct {
Extensions Extensions
Expect []pkix.Extension
Expand All @@ -45,27 +45,27 @@ func TestRenderExtensions(t *testing.T) {
},
Expect: []pkix.Extension{
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 1},
Id: OIDIssuer,
Value: []byte(`1`),
},
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 2},
Id: OIDGitHubWorkflowTrigger,
Value: []byte(`2`),
},
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 3},
Id: OIDGitHubWorkflowSHA,
Value: []byte(`3`),
},
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 4},
Id: OIDGitHubWorkflowName,
Value: []byte(`4`),
},
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 5},
Id: OIDGitHubWorkflowRepository,
Value: []byte(`5`),
},
{
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 6},
Id: OIDGitHubWorkflowRef,
Value: []byte(`6`),
},
},
Expand All @@ -75,25 +75,24 @@ func TestRenderExtensions(t *testing.T) {

for name, test := range tests {
t.Run(name, func(t *testing.T) {
got, err := test.Extensions.Render()
render, err := test.Extensions.Render()
if err != nil {
if !test.WantErr {
t.Error("Failed to render with unexpected error", err)
} else {
return
}
}
if len(got) != len(test.Expect) {
t.Errorf("Got %d extensions when rendered and expected %d", len(got), len(test.Expect))
return
if diff := cmp.Diff(test.Expect, render); diff != "" {
t.Errorf("Render: %s", diff)
}
for i, ext := range got {
if !ext.Id.Equal(test.Expect[i].Id) {
t.Errorf("Got OID %v in extension %d and expected %v", ext.Id, i, test.Expect[i].Id)
}
if !bytes.Equal(ext.Value, test.Expect[i].Value) {
t.Errorf("Expected extension value to be %s but got %s", test.Expect[i].Value, ext.Value)
}

parse, err := ParseExtensions(render)
if err != nil {
t.Fatalf("ParseExtensions: err = %v", err)
}
if diff := cmp.Diff(test.Extensions, parse); diff != "" {
t.Errorf("ParseExtensions: %s", diff)
}
})
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/identity/email/principal.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"errors"

"github.com/coreos/go-oidc/v3/oidc"
"github.com/sigstore/fulcio/pkg/ca"
"github.com/sigstore/fulcio/pkg/certificate"
"github.com/sigstore/fulcio/pkg/config"
"github.com/sigstore/fulcio/pkg/identity"
"github.com/sigstore/fulcio/pkg/oauthflow"
Expand Down Expand Up @@ -64,7 +64,7 @@ func (p principal) Embed(ctx context.Context, cert *x509.Certificate) error {
cert.EmailAddresses = []string{p.address}

var err error
cert.ExtraExtensions, err = ca.Extensions{
cert.ExtraExtensions, err = certificate.Extensions{
Issuer: p.issuer,
}.Render()
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/identity/github/principal.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"net/url"

"github.com/coreos/go-oidc/v3/oidc"
"github.com/sigstore/fulcio/pkg/ca"
"github.com/sigstore/fulcio/pkg/certificate"
"github.com/sigstore/fulcio/pkg/identity"
)

Expand Down Expand Up @@ -111,7 +111,7 @@ func (w workflowPrincipal) Embed(ctx context.Context, cert *x509.Certificate) er
cert.URIs = []*url.URL{parsed}

// Embed additional information into custom extensions
cert.ExtraExtensions, err = ca.Extensions{
cert.ExtraExtensions, err = certificate.Extensions{
Issuer: w.issuer,
GithubWorkflowTrigger: w.trigger,
GithubWorkflowSHA: w.sha,
Expand Down
4 changes: 2 additions & 2 deletions pkg/identity/kubernetes/principal.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"net/url"

"github.com/coreos/go-oidc/v3/oidc"
"github.com/sigstore/fulcio/pkg/ca"
"github.com/sigstore/fulcio/pkg/certificate"
"github.com/sigstore/fulcio/pkg/identity"
)

Expand Down Expand Up @@ -59,7 +59,7 @@ func (p principal) Embed(ctx context.Context, cert *x509.Certificate) error {
}
cert.URIs = []*url.URL{parsed}

cert.ExtraExtensions, err = ca.Extensions{
cert.ExtraExtensions, err = certificate.Extensions{
Issuer: p.issuer,
}.Render()
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/identity/spiffe/principal.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"net/url"

"github.com/coreos/go-oidc/v3/oidc"
"github.com/sigstore/fulcio/pkg/ca"
"github.com/sigstore/fulcio/pkg/certificate"
"github.com/sigstore/fulcio/pkg/config"
"github.com/sigstore/fulcio/pkg/identity"
"github.com/spiffe/go-spiffe/v2/spiffeid"
Expand Down Expand Up @@ -82,7 +82,7 @@ func (p principal) Embed(ctx context.Context, cert *x509.Certificate) error {
}
cert.URIs = []*url.URL{parsed}

cert.ExtraExtensions, err = ca.Extensions{
cert.ExtraExtensions, err = certificate.Extensions{
Issuer: p.issuer,
}.Render()
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/identity/uri/principal.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"net/url"

"github.com/coreos/go-oidc/v3/oidc"
"github.com/sigstore/fulcio/pkg/ca"
"github.com/sigstore/fulcio/pkg/certificate"
"github.com/sigstore/fulcio/pkg/config"
"github.com/sigstore/fulcio/pkg/identity"
)
Expand Down Expand Up @@ -73,7 +73,7 @@ func (p principal) Embed(ctx context.Context, cert *x509.Certificate) error {
}
cert.URIs = []*url.URL{subjectURI}

cert.ExtraExtensions, err = ca.Extensions{
cert.ExtraExtensions, err = certificate.Extensions{
Issuer: p.issuer,
}.Render()
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/identity/username/principal.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"strings"

"github.com/coreos/go-oidc/v3/oidc"
"github.com/sigstore/fulcio/pkg/ca"
"github.com/sigstore/fulcio/pkg/certificate"
"github.com/sigstore/fulcio/pkg/config"
"github.com/sigstore/fulcio/pkg/identity"
)
Expand Down Expand Up @@ -62,7 +62,7 @@ func (p principal) Embed(ctx context.Context, cert *x509.Certificate) error {
cert.EmailAddresses = []string{p.emailAddress}

var err error
cert.ExtraExtensions, err = ca.Extensions{
cert.ExtraExtensions, err = certificate.Extensions{
Issuer: p.issuer,
}.Render()
if err != nil {
Expand Down

0 comments on commit d9086d2

Please sign in to comment.