veraison / services

Attestation verification services based on Veraison components
Apache License 2.0
24 stars 13 forks source link

BUG: Trusted Services errors when there are no softwareIds in the evidence context #42

Open dreemkiller opened 1 year ago

dreemkiller commented 1 year ago

What version of the package are you using?

latest

Does this issue reproduce with the latest release?

Yes

What OS and CPU architecture are you using (go env)?

irrelevant

What did you do?

Set up a TrustAnchor (using the provisioning process) with no CoSWIDs. Thus, there is not SoftwareID. The system is set up for the Endorsement Store to use the memory back end.

What did you expect to see?

Calls to GRPC.GetAttestation with a token for that TrustAnchor to gracefully handle the case, and not produce an error.

What did you see instead?

When GRPC.GetAttestation is called with a token for that TrustAnchor, it calls GRPC.extractEvidence, and extractEvidence returns a proto.EvidenceContext with SoftwareID set to "". Then, back in GetAttestation, the call to o.EnStore.Get, with key set to "" returns error "The supplied key is empty".

This causes GetAttestation to return the error.

It appears that santizeK is not prepared to handle the case when the key is empty. Possible solutions are to change that behavior in santizeK, or to add a check in GetAttestation for an empty ec.SoftwareID before calling o.EnStore.Get().

setrofim commented 1 year ago

Hi Derek. Apologies for the delay in addressing this.

Please could you confirm which Scheme plugin you are using?

SoftwareID on the verification path is obtained from the token, and so should not be impacted by the fact that no CoSWIDs where provisioned. Regardless of whether or not any endorsements actually exist, it should still be possible to synthesize a valid (as described here) SoftwareID, which would then result a ErrKeyNotFoundError on o.EnStore.Get(), which should be handled gracefully. As far as I can confirm, all three schemes we have on main should always be generating non-empty SoftwareIDs?

An empty value for the SoftwareID implies that something went wrong earlier on, and it was never set, hence the error you're seeing. (Since in golang, string is a non-nullable type, there is no way to tell the difference between one that has not been initialized, and one that has been initilized to ""; hence our treatment of all empty strings as uninitialized.) Admittedly, the error message could be more informative, and we should probably validate that SoftwareID is not empty earlier, rather than relying on kvstore.

yogeshbdeshpande commented 1 year ago

@dreemkiller One cannot form a valid psa evidence token by skipping the Software Components. Hence wanted to know, the setup if this is reproducible? Else we can close this.

dreemkiller commented 1 year ago

One cannot create a valid PSA evidence token by skipping the software components. However, my setup does not require the Veraison service to check the software component - we place that information in a certificate, and the relying party checks it against their workload-specific policy when they receive the certificate.

Put simply, that part of the enforcement happens at the client, not in the service.

Thus, our Veraison service does not care about the software components, so when we provision, we want to provision without a CoSWID.

yogeshbdeshpande commented 1 year ago

So is your evidence just a certificate or something else?

dreemkiller commented 1 year ago

I'm not sure what you mean by evidence here, but I'll give it a try.

Our veraison-based service authenticates that the token is correctly signed by a valid platform, regardless of the software measurements in the token. It then embeds the relevant contents of the token (In our case, the application hash - but it really should include all of the software measurements) in a certificate, which is returned to the platform that generated the token. This certificate is then presented to its clients (so in RATS parlance, it acts as a passport). The client authenticates the certificate, then checks the application hash from the certificate with a value from its own policy. This allows our veraison-based service to be agnostic to the specific policy that the clients care about - policy enforcement happens at the client, so the service can work for any number of different computations that may have differing policy requirements.

yogeshbdeshpande commented 1 year ago

Thanks for the explanation. What I meant as Evidence is Attestation Token.

I would like to understand which Attestation scheme is used by your plugins? Is your scheme PSA, DICE, CCA or something else (self written new scheme)? Can you please elaborate?

Also, if application hash is the only thing which you are comparing between "what is received from the token" and what exists in your data base, then ideally that is your reference value endorsements and your scheme should then set the key for the same as "referenceID/softwareID(old code)" for the scenario to proceed.

dreemkiller commented 1 year ago

Our veraison-based service uses PSA and CCA attestation for the most part. The token itself contains software measurements - but our service does not care. It just creates a certificate, puts those software measurements in an extension of the certificate, and then sends it back as a passport. Thus, back to the core of the issue: Our provisioning data contains no CoSWID, and the code as it exists does not handle that without an error (the error occurs when the token is authenticated and the code attempts to retrieve CoSWID data when there is not.

yogeshbdeshpande commented 1 year ago

I guess, we do not have policy fully baked into this so we have sort of made the sw measurements matching compulsory, where you are hitting this road-block.. Will discuss internally our timelines and see when we can make a proper change regarding this within Veraison.

I am sure by now you must have figured out how to bypass the issue locally for Appraisal to proceed to completion?