Skip to content

Conversation

mwittie
Copy link

@mwittie mwittie commented Aug 19, 2024

@hf, it looks like you're away from this project. We evolved out fork at https://github.com/blocky/nitrite to support the functionality in this PR and in #3. We also added several other features. If you want to collaborate on nitrite, please reach out.

Overview

This PR adds the Timestamp function to extract the attestation timestamp, which can be used to set VerifyOptions.CurrentTime to Verify if an attestation was valid when it was created.

Why we propose the change

Our application archives AWS Nitro Enclave attestations. We want to be able to verify these attestations at a future time. However, verifying an attestation at a future can fail in nitrite.Verify at

	_, err = cert.Verify(x509.VerifyOptions{
		Intermediates: intermediates,
		Roots:         roots,
		CurrentTime:   currentTime,
		KeyUsages: []x509.ExtKeyUsage{
			x509.ExtKeyUsageAny,
		},
	})

due to certificate expiration if currentTime exceeds an intermediates certificate Not After value.

The nitrite library provides the nitrite.VerifyOptions.CurrentTime to set the currentTime used in certificate validation. We would like to set that time to attestation Document.Timestamp, but nitrite does not currently export the cosePayload to parse our the Timestamp on the client.

We propose to extend nitrite with func Timestamp(data []byte) (time.Time, error) to extract the attestation timestamp on the client.

Why is the proposed change useful in the nitriding library

For the client to extract attestation Document.Timestamp, the client needs to cbor.Unmarshal a nitrite.cosePayload, which is not exported by nitrite. While the client could redefine a cosePayload in its context, that is not very DRY and the client's definition of cosePayload could drift from the library. Alternatively, nitrite could export the COSEPayload, but that is a more significant change to the nitrite library than our proposal. Either of these approaches put a burden on the client for extracting attestation information to feed it back to nitrite, while replicating attestation parsing functionality that is already implemented by nitrite.

Adding the Timestamp function augments the existing nitrite interface and allows it to support the attestation archival use case with the existing options pattern.

func verifyAttestation(attestation []byte) error {
	timestamp, err := nitrite.Timestamp(attestation)
	if nil != err {
		return err
	}
	
	opts := nitrite.VerifyOptions{
		CurrentTime: timestamp,
	})
	res, err := nitrite.Verify(attestation, opts)
	if nil != err {
		return err
	}

	return nil
}

@mwittie mwittie changed the title Feature/bky 5502 upstream nitrite/nitrite Add Timestamp() to extract attestation timestamp Aug 19, 2024
@mwittie mwittie changed the title Add Timestamp() to extract attestation timestamp Add Timestamp() to extract attestation timestamp Aug 19, 2024
// (p. 64) describes Timestamp as "UTC time when document was created,
// in milliseconds"
msec := int64(doc.Timestamp)
return time.Unix(msec/1e3, (msec%1e3)*1e6), nil
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In go1.17 this line could be

return time.UnixMilli(int64(d.Timestamp)), nil

but I didn't want to bump the golang dependency.

Comment on lines +40 to +42
timeToMillis := func(t time.Time) uint64 {
return uint64(t.UnixNano() / 1e6)
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In go1.17 we could use time.UnixMilli, but I didn't want to bump the go version

@hf
Copy link
Owner

hf commented Dec 25, 2024

Yeah sure I'll have some time this weekend and check out this proposal!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants