in cmd/conformance/main.go [587:696]
func establishSecureSessionWithNullAttestation(ctx context.Context, key *externalKeyInfo) (*ekmClient, []byte, error) {
c := newEKMClient(ctx, key)
req := &sspb.BeginSessionRequest{
TlsRecords: c.shim.DrainSendBuf(),
}
resp, err := c.client.BeginSession(ctx, req)
if err != nil {
return nil, nil, 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 nil, nil, 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: []aepb.AttestationEvidenceType{aepb.AttestationEvidenceType_NULL_ATTESTATION},
NonceTypes: []aepb.NonceType{aepb.NonceType_NONCE_EKM32},
}
marshaledEvidenceTypes, err := proto.Marshal(evidenceTypeList)
if err != nil {
return nil, nil, fmt.Errorf("error marshalling evidence type list to proto: %v", err)
}
if _, err := c.tls.Write(marshaledEvidenceTypes); err != nil {
return nil, nil, 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 nil, nil, err
}
records := resp3.GetRequiredEvidenceTypesRecords()
if len(records) == 0 {
return nil, nil, 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 nil, nil, 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 nil, nil, fmt.Errorf("error parsing attestation types into a proto: %v", err)
}
if len(negotiatedTypes.GetTypes()) == 0 {
return nil, nil, fmt.Errorf("server responded with no attestation types")
}
req4 := &sspb.FinalizeRequest{
SessionContext: resp.GetSessionContext(),
}
evidence := aepb.AttestationEvidence{
Attestation: &apb.Attestation{},
}
marshaledEvidence, err := proto.Marshal(&evidence)
if err != nil {
return nil, nil, fmt.Errorf("error marshalling attestation evidence to proto: %v", err)
}
if _, err := c.tls.Write(marshaledEvidence); err != nil {
return nil, nil, fmt.Errorf("error writing evidence to TLS connection: %v", err)
}
// Wait for TLS session to process, then add session-protected records to request.
req4.AttestationEvidenceRecords = c.shim.DrainSendBuf()
if _, err := c.client.Finalize(ctx, req4); err != nil {
return nil, nil, err
}
return &c, resp.GetSessionContext(), nil
}