Skip to content

Commit

Permalink
create akv helper
Browse files Browse the repository at this point in the history
  • Loading branch information
akashsinghal committed Apr 22, 2024
1 parent f8c365a commit fe94194
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 47 deletions.
98 changes: 54 additions & 44 deletions pkg/verifier/cosign/cosign.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,50 +251,9 @@ func (v *cosignVerifier) verifyInternal(ctx context.Context, subjectReference co
// default hash type is SHA256 but for AKV scenarios, the hash type is determined by the key size
// TODO: investigate if it's possible to extract hash type from sig directly. This is a workaround for now
if pubKey.ProviderType == azurekeyvault.ProviderName {
switch keyType := pubKey.Key.(type) {
case *rsa.PublicKey:
switch keyType.Size() {
case 256:
hashType = crypto.SHA256
case 384:
hashType = crypto.SHA384
case 512:
hashType = crypto.SHA512
default:
return errorToVerifyResult(v.name, v.verifierType, fmt.Errorf("RSA key check: unsupported key size: %d", keyType.Size())), nil
}

// TODO: remove section after fix for bug in cosign azure key vault implementation
// tracking issue: https://github.com/sigstore/sigstore/issues/1384
// summary: azure keyvault implementation ASN.1 encodes sig after online signing with keyvault
// EC verifiers in cosign have built in ASN.1 decoding, but RSA verifiers do not
base64DecodedBytes, err := base64.StdEncoding.DecodeString(blob.Annotations[static.SignatureAnnotationKey])
if err != nil {
return errorToVerifyResult(v.name, v.verifierType, fmt.Errorf("RSA key check: failed to decode base64 signature: %w", err)), nil
}
// decode ASN.1 signature to raw signature if it is ASN.1 encoded
decodedSigBytes, err := decodeASN1Signature(base64DecodedBytes)
if err != nil {
return errorToVerifyResult(v.name, v.verifierType, fmt.Errorf("RSA key check: failed to decode ASN.1 signature: %w", err)), nil
}
encodedBase64SigBytes := base64.StdEncoding.EncodeToString(decodedSigBytes)
sig, err = static.NewSignature(blobBytes, encodedBase64SigBytes, staticOpts...)
if err != nil {
return errorToVerifyResult(v.name, v.verifierType, fmt.Errorf("RSA key check: failed to generate static signature: %w", err)), nil
}
case *ecdsa.PublicKey:
switch keyType.Curve {
case elliptic.P256():
hashType = crypto.SHA256
case elliptic.P384():
hashType = crypto.SHA384
case elliptic.P521():
hashType = crypto.SHA512
default:
return errorToVerifyResult(v.name, v.verifierType, fmt.Errorf("ECDSA key check: unsupported key curve: %s", keyType.Params().Name)), nil
}
default:
return errorToVerifyResult(v.name, v.verifierType, fmt.Errorf("unsupported public key type: %T", pubKey)), nil
hashType, sig, err = processAKVSignature(blob.Annotations[static.SignatureAnnotationKey], sig, pubKey.Key, blobBytes, staticOpts)
if err != nil {
return errorToVerifyResult(v.name, v.verifierType, fmt.Errorf("failed to process AKV signature: %w", err)), nil
}
}

Expand Down Expand Up @@ -583,3 +542,54 @@ func getKeysMapsDefault(ctx context.Context, trustPolicies *TrustPolicies, refer

return keysMap, cosignOpts, nil
}

// processAKVSignature processes the AKV signature and returns the hash type, signature and error
func processAKVSignature(sigEncoded string, staticSig oci.Signature, publicKey crypto.PublicKey, payloadBytes []byte, staticOpts []static.Option) (crypto.Hash, oci.Signature, error) {
var hashType crypto.Hash
switch keyType := publicKey.(type) {
case *rsa.PublicKey:
switch keyType.Size() {
case 256:
hashType = crypto.SHA256
case 384:
hashType = crypto.SHA384
case 512:
hashType = crypto.SHA512

Check warning on line 557 in pkg/verifier/cosign/cosign.go

View check run for this annotation

Codecov / codecov/patch

pkg/verifier/cosign/cosign.go#L554-L557

Added lines #L554 - L557 were not covered by tests
default:
return crypto.SHA256, nil, fmt.Errorf("RSA key check: unsupported key size: %d", keyType.Size())
}

// TODO: remove section after fix for bug in cosign azure key vault implementation
// tracking issue: https://github.com/sigstore/sigstore/issues/1384
// summary: azure keyvault implementation ASN.1 encodes sig after online signing with keyvault
// EC verifiers in cosign have built in ASN.1 decoding, but RSA verifiers do not
base64DecodedBytes, err := base64.StdEncoding.DecodeString(sigEncoded)
if err != nil {
return crypto.SHA256, nil, fmt.Errorf("RSA key check: failed to decode base64 signature: %w", err)

Check warning on line 568 in pkg/verifier/cosign/cosign.go

View check run for this annotation

Codecov / codecov/patch

pkg/verifier/cosign/cosign.go#L568

Added line #L568 was not covered by tests
}
// decode ASN.1 signature to raw signature if it is ASN.1 encoded
decodedSigBytes, err := decodeASN1Signature(base64DecodedBytes)
if err != nil {
return crypto.SHA256, nil, fmt.Errorf("RSA key check: failed to decode ASN.1 signature: %w", err)

Check warning on line 573 in pkg/verifier/cosign/cosign.go

View check run for this annotation

Codecov / codecov/patch

pkg/verifier/cosign/cosign.go#L573

Added line #L573 was not covered by tests
}
encodedBase64SigBytes := base64.StdEncoding.EncodeToString(decodedSigBytes)
staticSig, err = static.NewSignature(payloadBytes, encodedBase64SigBytes, staticOpts...)
if err != nil {
return crypto.SHA256, nil, fmt.Errorf("RSA key check: failed to generate static signature: %w", err)

Check warning on line 578 in pkg/verifier/cosign/cosign.go

View check run for this annotation

Codecov / codecov/patch

pkg/verifier/cosign/cosign.go#L578

Added line #L578 was not covered by tests
}
case *ecdsa.PublicKey:
switch keyType.Curve {
case elliptic.P256():
hashType = crypto.SHA256
case elliptic.P384():
hashType = crypto.SHA384
case elliptic.P521():
hashType = crypto.SHA512

Check warning on line 587 in pkg/verifier/cosign/cosign.go

View check run for this annotation

Codecov / codecov/patch

pkg/verifier/cosign/cosign.go#L584-L587

Added lines #L584 - L587 were not covered by tests
default:
return crypto.SHA256, nil, fmt.Errorf("ECDSA key check: unsupported key curve: %s", keyType.Params().Name)
}
default:
return crypto.SHA256, nil, fmt.Errorf("unsupported public key type: %T", publicKey)
}
return hashType, staticSig, nil
}
7 changes: 4 additions & 3 deletions pkg/verifier/cosign/cosign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ func TestGetKeysMaps_FailingGetKeys(t *testing.T) {
}

// TestVerifyInternal tests the verifyInternal function of the cosign verifier
// it also tests the processAKVSignature function implicitly
func TestVerifyInternal(t *testing.T) {
cosignMediaType := "application/vnd.dev.cosign.simplesigning.v1+json"
validSignatureBlob := []byte("test")
Expand Down Expand Up @@ -676,7 +677,7 @@ mmBwUAwwW0Uc+Nt3bDOCiB1nUsICv1ry
blobDigest: validSignatureBlob,
},
},
expectedResultMessagePrefix: "cosign verification failed: unsupported public key type",
expectedResultMessagePrefix: "cosign verification failed: failed to process AKV signature: unsupported public key type",
},
{
name: "invalid RSA key size for AKV",
Expand Down Expand Up @@ -707,7 +708,7 @@ mmBwUAwwW0Uc+Nt3bDOCiB1nUsICv1ry
blobDigest: validSignatureBlob,
},
},
expectedResultMessagePrefix: "cosign verification failed: RSA key check: unsupported key size",
expectedResultMessagePrefix: "cosign verification failed: failed to process AKV signature: RSA key check: unsupported key size",
},
{
name: "invalid ECDSA curve type for AKV",
Expand Down Expand Up @@ -738,7 +739,7 @@ mmBwUAwwW0Uc+Nt3bDOCiB1nUsICv1ry
blobDigest: validSignatureBlob,
},
},
expectedResultMessagePrefix: "cosign verification failed: ECDSA key check: unsupported key curve",
expectedResultMessagePrefix: "cosign verification failed: failed to process AKV signature: ECDSA key check: unsupported key curve",
},
{
name: "valid hash: 256 keysize: 2048 RSA key AKV",
Expand Down

0 comments on commit fe94194

Please sign in to comment.