Skip to content

Commit

Permalink
fulcio-server -> fulcio-url, pkg/fulcio refactoring (#471)
Browse files Browse the repository at this point in the history
Signed-off-by: Jake Sanders <[email protected]>
  • Loading branch information
Jake Sanders authored Jul 22, 2021
1 parent 5bb088d commit d401496
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 44 deletions.
22 changes: 12 additions & 10 deletions cmd/cosign/cli/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func Sign() *ffcli.Command {
payloadPath = flagset.String("payload", "", "path to a payload file to use rather than generating one.")
force = flagset.Bool("f", false, "skip warnings and confirmations")
recursive = flagset.Bool("r", false, "if a multi-arch image is specified, additionally sign each discrete image")
fulcioURL = flagset.String("fulcio-server", "https://fulcio.sigstore.dev", "[EXPERIMENTAL] address of sigstore PKI server")
fulcioURL = flagset.String("fulcio-url", "https://fulcio.sigstore.dev", "[EXPERIMENTAL] address of sigstore PKI server")
rekorURL = flagset.String("rekor-url", "https://rekor.sigstore.dev", "[EXPERIMENTAL] address of rekor STL server")
idToken = flagset.String("identity-token", "", "[EXPERIMENTAL] identity token to use for certificate from fulcio")
oidcIssuer = flagset.String("oidc-issuer", "https://oauth2.sigstore.dev/auth", "[EXPERIMENTAL] OIDC provider to be used to issue ID token")
Expand Down Expand Up @@ -258,9 +258,8 @@ func SignCmd(ctx context.Context, ko KeyOpts, annotations map[string]interface{}
var rekorBytes []byte
if uploadTLog {
// Upload the cert or the public key, depending on what we have
if sv.Cert != "" {
rekorBytes = []byte(sv.Cert)
} else {
rekorBytes = sv.Cert
if rekorBytes == nil {
pemBytes, err := cosign.PublicKeyPem(sv, options.WithContext(ctx))
if err != nil {
return err
Expand Down Expand Up @@ -398,9 +397,8 @@ func signerFromKeyOpts(ctx context.Context, certPath string, ko KeyOpts) (*certS
if err != nil {
return nil, err
}
cert := string(pemBytes)
return &certSignVerifier{
Cert: cert,
Cert: pemBytes,
SignerVerifier: sv,
}, nil

Expand Down Expand Up @@ -454,12 +452,16 @@ func signerFromKeyOpts(ctx context.Context, certPath string, ko KeyOpts) (*certS
if err != nil {
return nil, errors.Wrap(err, "marshaling certificate to PEM")
}
certSigner.Cert = string(pemBytes)
certSigner.Cert = pemBytes
return certSigner, nil
}
// Default Keyless!
fmt.Fprintln(os.Stderr, "Generating ephemeral keys...")
k, err := fulcio.NewSigner(ctx, ko.IDToken, ko.OIDCIssuer, ko.OIDCClientID, ko.FulcioURL)
fClient, err := fulcio.NewClient(ko.FulcioURL)
if err != nil {
return nil, errors.Wrap(err, "creating Fulcio client")
}
k, err := fulcio.NewSigner(ctx, ko.IDToken, ko.OIDCIssuer, ko.OIDCClientID, fClient)
if err != nil {
return nil, errors.Wrap(err, "getting key from Fulcio")
}
Expand All @@ -471,7 +473,7 @@ func signerFromKeyOpts(ctx context.Context, certPath string, ko KeyOpts) (*certS
}

type certSignVerifier struct {
Cert string
Chain string
Cert []byte
Chain []byte
signature.SignerVerifier
}
8 changes: 3 additions & 5 deletions cmd/cosign/cli/sign_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func SignBlob() *ffcli.Command {
b64 = flagset.Bool("b64", true, "whether to base64 encode the output")
sk = flagset.Bool("sk", false, "whether to use a hardware security key")
slot = flagset.String("slot", "", "security key slot to use for generated key (default: signature) (authentication|signature|card-authentication|key-management)")
fulcioURL = flagset.String("fulcio-server", "https://fulcio.sigstore.dev", "[EXPERIMENTAL] address of sigstore PKI server")
fulcioURL = flagset.String("fulcio-url", "https://fulcio.sigstore.dev", "[EXPERIMENTAL] address of sigstore PKI server")
rekorURL = flagset.String("rekor-url", "https://rekor.sigstore.dev", "[EXPERIMENTAL] address of rekor STL server")
idToken = flagset.String("identity-token", "", "[EXPERIMENTAL] identity token to use for certificate from fulcio")
oidcIssuer = flagset.String("oidc-issuer", "https://oauth2.sigstore.dev/auth", "[EXPERIMENTAL] OIDC provider to be used to issue ID token")
Expand Down Expand Up @@ -146,10 +146,8 @@ func SignBlobCmd(ctx context.Context, ko KeyOpts, payloadPath string, b64 bool,

if EnableExperimental() {
// TODO: Refactor with sign.go
var rekorBytes []byte
if sv.Cert != "" {
rekorBytes = []byte(sv.Cert)
} else {
rekorBytes := sv.Cert
if rekorBytes == nil {
pemBytes, err := cosign.PublicKeyPem(sv, options.WithContext(ctx))
if err != nil {
return nil, err
Expand Down
35 changes: 15 additions & 20 deletions pkg/cosign/fulcio/fulcio.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,22 +68,22 @@ type signingCertProvider interface {
SigningCert(params *operations.SigningCertParams, authInfo runtime.ClientAuthInfoWriter, opts ...operations.ClientOption) (*operations.SigningCertCreated, error)
}

func getCertForOauthID(priv *ecdsa.PrivateKey, scp signingCertProvider, connector oidcConnector, oidcIssuer string, oidcClientID string) (string, string, error) {
func getCertForOauthID(priv *ecdsa.PrivateKey, scp signingCertProvider, connector oidcConnector, oidcIssuer string, oidcClientID string) (certPem, chainPem []byte, err error) {
pubBytes, err := x509.MarshalPKIXPublicKey(&priv.PublicKey)
if err != nil {
return "", "", err
return nil, nil, err
}

tok, err := connector.OIDConnect(oidcIssuer, oidcClientID, "")
if err != nil {
return "", "", err
return nil, nil, err
}

// Sign the email address as part of the request
h := sha256.Sum256([]byte(tok.Subject))
proof, err := ecdsa.SignASN1(rand.Reader, priv, h[:])
if err != nil {
return "", "", err
return nil, nil, err
}

bearerAuth := httptransport.BearerToken(tok.RawString)
Expand All @@ -103,16 +103,16 @@ func getCertForOauthID(priv *ecdsa.PrivateKey, scp signingCertProvider, connecto

resp, err := scp.SigningCert(params, bearerAuth)
if err != nil {
return "", "", err
return nil, nil, err
}

// split the cert and the chain
certBlock, chainPem := pem.Decode([]byte(resp.Payload))
certPem := pem.EncodeToMemory(certBlock)
return string(certPem), string(chainPem), nil
certPem = pem.EncodeToMemory(certBlock)
return certPem, chainPem, nil
}

func getFulcioClient(addr string) (*fulcioClient.Fulcio, error) {
func NewClient(addr string) (*fulcioClient.Fulcio, error) {
url, err := url.Parse(addr)
if err != nil {
return nil, err
Expand All @@ -124,12 +124,7 @@ func getFulcioClient(addr string) (*fulcioClient.Fulcio, error) {
}

// GetCert returns the PEM-encoded signature of the OIDC identity returned as part of an interactive oauth2 flow plus the PEM-encoded cert chain.
func GetCert(ctx context.Context, priv *ecdsa.PrivateKey, idToken, flow string, oidcIssuer string, oidcClientID string, fulcioClient string) (string, string, error) {
fcli, err := getFulcioClient(fulcioClient)
if err != nil {
return "", "", err
}

func GetCert(ctx context.Context, priv *ecdsa.PrivateKey, idToken, flow, oidcIssuer, oidcClientID string, fClient *fulcioClient.Fulcio) (certPemBytes, chainPemBytes []byte, err error) {
c := &realConnector{}
switch flow {
case FlowDevice:
Expand All @@ -140,20 +135,20 @@ func GetCert(ctx context.Context, priv *ecdsa.PrivateKey, idToken, flow string,
case FlowToken:
c.flow = &oauthflow.StaticTokenGetter{RawToken: idToken}
default:
return "", "", fmt.Errorf("unsupported oauth flow: %s", flow)
return nil, nil, fmt.Errorf("unsupported oauth flow: %s", flow)
}

return getCertForOauthID(priv, fcli.Operations, c, oidcIssuer, oidcClientID)
return getCertForOauthID(priv, fClient.Operations, c, oidcIssuer, oidcClientID)
}

type Signer struct {
Cert string
Chain string
Cert []byte
Chain []byte
pub *ecdsa.PublicKey
*signature.ECDSASignerVerifier
}

func NewSigner(ctx context.Context, idToken, oidcIssuer, oidcClientID, fulcioClient string) (*Signer, error) {
func NewSigner(ctx context.Context, idToken, oidcIssuer, oidcClientID string, fClient *fulcioClient.Fulcio) (*Signer, error) {
priv, err := cosign.GeneratePrivateKey()
if err != nil {
return nil, errors.Wrap(err, "generating cert")
Expand All @@ -174,7 +169,7 @@ func NewSigner(ctx context.Context, idToken, oidcIssuer, oidcClientID, fulcioCli
default:
flow = FlowNormal
}
cert, chain, err := GetCert(ctx, priv, idToken, flow, oidcIssuer, oidcClientID, fulcioClient) // TODO, use the chain.
cert, chain, err := GetCert(ctx, priv, idToken, flow, oidcIssuer, oidcClientID, fClient) // TODO, use the chain.
if err != nil {
return nil, errors.Wrap(err, "retrieving cert")
}
Expand Down
10 changes: 6 additions & 4 deletions pkg/cosign/fulcio/fulcio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,14 @@ func TestGetCertForOauthID(t *testing.T) {
}

expectedCert := string(expectedCertBytes)
if cert != expectedCert {
t.Errorf("getCertForOauthID returned cert %q, wanted %q", cert, expectedCert)
actualCert := string(cert)
if actualCert != expectedCert {
t.Errorf("getCertForOauthID returned cert %q, wanted %q", actualCert, expectedCert)
}
expectedChain := string(expectedExtraBytes)
if chain != expectedChain {
t.Errorf("getCertForOauthID returned chain %q, wanted %q", chain, expectedChain)
actualChain := string(chain)
if actualChain != expectedChain {
t.Errorf("getCertForOauthID returned chain %q, wanted %q", actualChain, expectedChain)
}
})
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/cosign/remote/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ type Bundle struct {
}

type UploadOpts struct {
Cert string
Chain string
Cert []byte
Chain []byte
DupeDetector signature.Verifier
Bundle *Bundle
AdditionalAnnotations map[string]string
Expand All @@ -169,9 +169,9 @@ func UploadSignature(signature, payload []byte, dst name.Reference, opts UploadO
annotations := map[string]string{
sigkey: base64.StdEncoding.EncodeToString(signature),
}
if opts.Cert != "" {
annotations[certkey] = opts.Cert
annotations[chainkey] = opts.Chain
if opts.Cert != nil {
annotations[certkey] = string(opts.Cert)
annotations[chainkey] = string(opts.Chain)
}
if opts.Bundle != nil {
b, err := swag.WriteJSON(opts.Bundle)
Expand Down

0 comments on commit d401496

Please sign in to comment.