Skip to content

Commit

Permalink
Expose all service-account keys through OIDC
Browse files Browse the repository at this point in the history
  • Loading branch information
johngmyers committed Apr 12, 2021
1 parent 699a02f commit 53db93b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 46 deletions.
43 changes: 18 additions & 25 deletions pkg/model/awsmodel/oidc_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import (
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"fmt"
"io"
"sort"

"gopkg.in/square/go-jose.v2"
"k8s.io/kops/pkg/featureflag"
Expand Down Expand Up @@ -153,39 +153,32 @@ func (o *OIDCKeys) GetDependencies(tasks map[string]fi.Task) []fi.Task {
}
}
func (o *OIDCKeys) Open() (io.Reader, error) {
keyset := o.SigningKey.Keyset()
var keys []jose.JSONWebKey

certBytes, err := fi.ResourceAsBytes(o.SigningKey.Certificate())
if err != nil {
return nil, fmt.Errorf("failed to get cert: %w", err)
}
block, _ := pem.Decode(certBytes)
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, fmt.Errorf("failed to parse cert: %w", err)
}

publicKey := cert.PublicKey
for _, item := range keyset.Items {
publicKey := item.Certificate.PublicKey
publicKeyDERBytes, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
return nil, fmt.Errorf("failed to serialize public key to DER format: %v", err)
}

publicKeyDERBytes, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
return nil, fmt.Errorf("failed to serialize public key to DER format: %v", err)
}

hasher := crypto.SHA256.New()
hasher.Write(publicKeyDERBytes)
publicKeyDERHash := hasher.Sum(nil)
hasher := crypto.SHA256.New()
hasher.Write(publicKeyDERBytes)
publicKeyDERHash := hasher.Sum(nil)

keyID := base64.RawURLEncoding.EncodeToString(publicKeyDERHash)
keyID := base64.RawURLEncoding.EncodeToString(publicKeyDERHash)

keys := []jose.JSONWebKey{
{
keys = append(keys, jose.JSONWebKey{
Key: publicKey,
KeyID: keyID,
Algorithm: string(jose.RS256),
Use: "sig",
},
})
}

sort.Slice(keys, func(i, j int) bool {
return keys[i].KeyID < keys[j].KeyID
})
keyResponse := KeyResponse{Keys: keys}
jsonBytes, err := json.MarshalIndent(keyResponse, "", "")
if err != nil {
Expand Down
33 changes: 12 additions & 21 deletions upup/pkg/fi/fitasks/keypair.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package fitasks

import (
"crypto/sha1"
"crypto/x509/pkix"
"fmt"
"sort"
Expand Down Expand Up @@ -48,8 +47,8 @@ type Keypair struct {
// Rotatable is whether the keypair has a "next" version.
Rotatable bool `json:"rotatable,omitempty"`

certificate *fi.TaskDependentResource
certificateSHA1Fingerprint *fi.TaskDependentResource
certificate *fi.TaskDependentResource
keyset *fi.Keyset
}

var _ fi.HasCheckExisting = &Keypair{}
Expand Down Expand Up @@ -111,7 +110,7 @@ func (e *Keypair) Find(c *fi.Context) (*Keypair, error) {
}
}

if err := e.setResources(cert); err != nil {
if err := e.setResources(keyset); err != nil {
return nil, fmt.Errorf("error setting resources: %v", err)
}

Expand Down Expand Up @@ -249,11 +248,6 @@ func (_ *Keypair) Render(c *fi.Context, a, e, changes *Keypair) error {
},
Primary: ki,
}

// TODO: expose all certs in keyset
if err := e.setResources(cert); err != nil {
return fmt.Errorf("error setting resources: %v", err)
}
}

if e.Rotatable {
Expand All @@ -273,6 +267,10 @@ func (_ *Keypair) Render(c *fi.Context, a, e, changes *Keypair) error {
}
}

if err := e.setResources(keyset); err != nil {
return fmt.Errorf("error setting resources: %v", err)
}

err = c.Keystore.StoreKeypair(name, keyset)
if err != nil {
return err
Expand Down Expand Up @@ -342,32 +340,25 @@ func (e *Keypair) ensureResources() {
if e.certificate == nil {
e.certificate = &fi.TaskDependentResource{Task: e}
}
if e.certificateSHA1Fingerprint == nil {
e.certificateSHA1Fingerprint = &fi.TaskDependentResource{Task: e}
}
}

func (e *Keypair) setResources(cert *pki.Certificate) error {
func (e *Keypair) setResources(keyset *fi.Keyset) error {
e.ensureResources()

s, err := cert.AsString()
s, err := keyset.Primary.Certificate.AsString()
if err != nil {
return err
}
e.certificate.Resource = fi.NewStringResource(s)

fingerprint := sha1.Sum(cert.Certificate.Raw)
hex := fmt.Sprintf("%x", fingerprint)
e.certificateSHA1Fingerprint.Resource = fi.NewStringResource(hex)

return nil
}

func (e *Keypair) CertificateSHA1Fingerprint() fi.Resource {
e.ensureResources()
return e.certificateSHA1Fingerprint
func (e *Keypair) Keyset() *fi.Keyset {
return e.keyset
}

// Deprecated: Use Keyset() and use the full set of certificates.
func (e *Keypair) Certificate() fi.Resource {
e.ensureResources()
return e.certificate
Expand Down

0 comments on commit 53db93b

Please sign in to comment.