func runFinalizeTestCase()

in cmd/conformance/main.go [442:584]


func runFinalizeTestCase(ctx context.Context, t finalizeTest) error {
	// If running a test case where we are trying to generate a complete attestation, just use the
	// EstablishSecureSession() method from the `client` package (since it already has the complete
	// logic for generating attestations, etc).
	if t.fullAttestation {
		token, err := createAuthToken(ctx, unprotectedKey.uri)
		if err != nil {
			return fmt.Errorf("Error generating JWT: %v", err)
		}

		_, err = securesession.EstablishSecureSession(ctx, unprotectedKey.uri, token, securesession.HTTPCertPool(unprotectedKey.certs), securesession.SkipTLSVerify(true))
		return err
	}

	c := newEKMClient(ctx, unprotectedKey)

	req := &sspb.BeginSessionRequest{
		TlsRecords: c.shim.DrainSendBuf(),
	}

	resp, err := c.client.BeginSession(ctx, req)
	if err != nil {
		return err
	}

	c.shim.QueueReceiveBuf(resp.GetTlsRecords())

	req2 := &sspb.HandshakeRequest{
		SessionContext: resp.GetSessionContext(),
		TlsRecords:     c.shim.DrainSendBuf(),
	}

	resp2, err := c.client.Handshake(ctx, req2)
	if err != nil {
		return err
	}

	// If TLS 1.2, enqueue response bytes (TLS 1.3 has none).
	if len(resp.GetTlsRecords()) > 0 {
		c.shim.QueueReceiveBuf(resp2.GetTlsRecords())
	}

	evidenceTypeList := &aepb.AttestationEvidenceTypeList{
		Types:      t.evidenceTypes,
		NonceTypes: t.nonceTypes,
	}

	marshaledEvidenceTypes, err := proto.Marshal(evidenceTypeList)
	if err != nil {
		return fmt.Errorf("error marshalling evidence type list to proto: %v", err)
	}

	if _, err := c.tls.Write(marshaledEvidenceTypes); err != nil {
		return fmt.Errorf("error writing evidence type list to TLS connection: %v", err)
	}

	// Capture the TLS session-protected records and send them over the RPC.
	offeredEvidenceTypeRecords := c.shim.DrainSendBuf()

	req3 := &sspb.NegotiateAttestationRequest{
		SessionContext:              resp.GetSessionContext(),
		OfferedEvidenceTypesRecords: offeredEvidenceTypeRecords,
	}

	resp3, err := c.client.NegotiateAttestation(ctx, req3)
	if err != nil {
		return err
	}

	records := resp3.GetRequiredEvidenceTypesRecords()

	if len(records) == 0 {
		return fmt.Errorf("got no evidence bytes from server response")
	}

	// Attempt to unmarshal the response by passing the serialized bytes to the
	// TLS implementation, and unmarshal the resulting decrypted bytes.
	evidenceRecords := resp3.GetRequiredEvidenceTypesRecords()
	c.shim.QueueReceiveBuf(evidenceRecords)

	readBuf := make([]byte, recordBufferSize)
	n, err := c.tls.Read(readBuf)

	if err != nil {
		return fmt.Errorf("error reading data from TLS connection: %v", err)
	}

	// Unmarshal the response written back from the TLS intercept.
	negotiatedTypes := &aepb.AttestationEvidenceTypeList{}
	if err = proto.Unmarshal(readBuf[:n], negotiatedTypes); err != nil {
		return fmt.Errorf("error parsing attestation types into a proto: %v", err)
	}

	if len(negotiatedTypes.GetTypes()) == 0 {
		return fmt.Errorf("server responded with no attestation types")
	}

	sessionContext := resp.GetSessionContext()
	if t.mutateSessionKey != nil {
		sessionContext = t.mutateSessionKey(sessionContext)
	}

	req4 := &sspb.FinalizeRequest{
		SessionContext: sessionContext,
	}

	if t.mockAttestation != nil {
		evidence := aepb.AttestationEvidence{
			Attestation: t.mockAttestation,
		}

		marshaledEvidence, err := proto.Marshal(&evidence)
		if err != nil {
			return fmt.Errorf("error marshalling attestation evidence to proto: %v", err)
		}

		if _, err := c.tls.Write(marshaledEvidence); err != nil {
			return fmt.Errorf("error writing evidence to TLS connection: %v", err)
		}

		// Wait for TLS session to process, then add session-protected records to request.
		records = c.shim.DrainSendBuf()
		if t.mutateTLSRecords != nil {
			records = t.mutateTLSRecords(records)
		}

		req4.AttestationEvidenceRecords = records
	}

	if t.mutateJWT != nil {
		newToken, err := t.mutateJWT(ctx, c.client.GetJWTToken())
		if err != nil {
			glog.Fatalf("Error mutating JWT: %v", err)
		}
		c.client.SetJWTToken(newToken)
	}

	if _, err := c.client.Finalize(ctx, req4); err != nil {
		return err
	}

	return nil
}