0
0
mirror of https://github.com/signalapp/libsignal.git synced 2024-09-20 20:03:07 +02:00

Generalize Handshake type for different enclaves

This commit is contained in:
moiseev-signal 2023-12-22 13:10:24 -08:00 committed by GitHub
parent d394f30644
commit c86c74c288
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 251 additions and 194 deletions

View File

@ -7,12 +7,11 @@ use std::collections::HashMap;
use hex_literal::hex;
use prost::Message;
use sgx_session::Result;
use crate::dcap::MREnclave;
use crate::dcap::{self, MREnclave};
use crate::enclave::{Handshake, Result};
use crate::proto::cds2;
use crate::util::SmallMap;
use crate::{dcap, sgx_session};
/// Map from MREnclave to intel SW advisories that are known to be mitigated in the
/// build with that MREnclave value.
@ -36,10 +35,10 @@ pub fn new_handshake(
mrenclave: &[u8],
attestation_msg: &[u8],
current_time: std::time::SystemTime,
) -> Result<sgx_session::Handshake> {
) -> Result<Handshake> {
// Deserialize attestation handshake start.
let handshake_start = cds2::ClientHandshakeStart::decode(attestation_msg)?;
sgx_session::Handshake::new(
Handshake::for_sgx(
mrenclave,
&handshake_start.evidence,
&handshake_start.endorsement,
@ -61,9 +60,10 @@ pub fn extract_metrics(attestation_msg: &[u8]) -> Result<HashMap<String, i64>> {
#[cfg(test)]
mod test {
use super::*;
use std::time::{Duration, SystemTime};
use super::*;
#[test]
fn attest_cds2() {
// Read test data files, de-hex-stringing as necessary.

View File

@ -47,6 +47,7 @@ use crate::dcap::evidence::Evidence;
pub use crate::dcap::sgx_report_body::MREnclave;
use crate::dcap::sgx_report_body::SgxFlags;
use crate::dcap::sgx_x509::SgxPckExtension;
use crate::enclave::AttestationError;
use crate::error::{Context, ContextError};
pub(crate) mod cert_chain;
@ -61,27 +62,6 @@ mod sgx_x509;
#[cfg(test)]
mod fakes;
#[derive(Debug)]
pub struct AttestationError {
message: String,
}
impl std::fmt::Display for AttestationError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.message.fmt(f)
}
}
impl std::error::Error for AttestationError {}
impl From<Error> for AttestationError {
fn from(e: Error) -> Self {
Self {
message: e.to_string(),
}
}
}
pub(crate) struct DcapErrorDomain;
pub(crate) type Error = ContextError<DcapErrorDomain>;

180
rust/attest/src/enclave.rs Normal file
View File

@ -0,0 +1,180 @@
//
// Copyright 2023 Signal Messenger, LLC.
// SPDX-License-Identifier: AGPL-3.0-only
//
use std::collections::HashMap;
use displaydoc::Display;
use crate::client_connection::ClientConnection;
use crate::{client_connection, dcap, nitro, snow_resolver};
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub struct AttestationError {
message: String,
}
impl std::fmt::Display for AttestationError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.message.fmt(f)
}
}
impl std::error::Error for AttestationError {}
impl From<dcap::Error> for AttestationError {
fn from(e: dcap::Error) -> Self {
Self {
message: e.to_string(),
}
}
}
/// Error types for an enclave noise session.
#[derive(Display, Debug)]
pub enum Error {
/// failure to attest remote enclave: {0:?}
AttestationError(AttestationError),
/// failure to communicate on established Noise channel to the enclave: {0}
NoiseError(client_connection::Error),
/// failure to complete Noise handshake to the enclave: {0}
NoiseHandshakeError(snow::Error),
/// attestation data invalid: {reason}
AttestationDataError { reason: String },
/// invalid bridge state
InvalidBridgeStateError,
}
impl From<snow::Error> for Error {
fn from(e: snow::Error) -> Self {
Error::NoiseHandshakeError(e)
}
}
impl From<AttestationError> for Error {
fn from(err: AttestationError) -> Error {
Error::AttestationError(err)
}
}
impl From<client_connection::Error> for Error {
fn from(err: client_connection::Error) -> Self {
Error::NoiseError(err)
}
}
impl From<prost::DecodeError> for Error {
fn from(err: prost::DecodeError) -> Self {
Error::AttestationDataError {
reason: err.to_string(),
}
}
}
impl From<nitro::NitroError> for AttestationError {
fn from(err: nitro::NitroError) -> Self {
AttestationError {
message: err.to_string(),
}
}
}
impl From<nitro::NitroError> for Error {
fn from(err: nitro::NitroError) -> Self {
Self::AttestationError(err.into())
}
}
/// A noise handshaker that can be used to build a [client_connection::ClientConnection]
///
/// Callers provide an attestation that must contain the remote enclave's public key. If the
/// attestation is valid, this public key will be used to generate a noise NK handshake (with
/// the caller acting as the initiator) via [Handshake::initial_request]. When
/// a handshake response is received the handshake can be completed with
/// [Handshake::complete] to build a [client_connection::ClientConnection] that
/// can be used to exchange arbitrary encrypted payloads with the remote enclave.
///
/// ```pseudocode
/// let websocket = ... open websocket ...
/// let attestation_msg = websocket.recv();
/// let (evidence, endoresments) = parse(attestation_msg);
/// let mut handshake = Handshake::new(
/// mrenclave, evidence, endorsements, acceptable_sw_advisories, current_time)?;
/// websocket.send(handshaker.initial_request());
/// let initial_response = websocket.recv(...);
/// let conn = handshaker.complete(initial_response);
/// ```
pub struct Handshake {
pub(crate) handshake: snow::HandshakeState,
pub(crate) initial_request: Vec<u8>,
pub(crate) claims: Claims,
}
impl Handshake {
/// Initial message from client for noise handshake.
pub fn initial_request(&self) -> &[u8] {
&self.initial_request
}
/// custom claims extracted from the attestation
pub fn custom_claims(&self) -> &HashMap<String, Vec<u8>> {
&self.claims.custom
}
/// Completes client connection initiation, returns a valid client connection.
pub fn complete(mut self, initial_received: &[u8]) -> Result<ClientConnection> {
self.handshake.read_message(initial_received, &mut [])?;
let transport = self.handshake.into_transport_mode()?;
log::info!("Successfully completed attested connection");
Ok(ClientConnection { transport })
}
pub(crate) fn with_claims(claims: Claims) -> Result<Self> {
let mut handshake = snow::Builder::with_resolver(
client_connection::NOISE_PATTERN.parse().expect("valid"),
Box::new(snow_resolver::Resolver),
)
.remote_public_key(&claims.public_key)
.build_initiator()?;
let mut initial_request = vec![0u8; client_connection::NOISE_HANDSHAKE_OVERHEAD];
// We send an empty message, but the round-trip to the server and back is still required
// in order to complete the noise handshake. If we needed some initial payload we could
// add it here in future.
let size = handshake.write_message(&[], &mut initial_request)?;
initial_request.truncate(size);
Ok(Self {
handshake,
initial_request,
claims,
})
}
}
pub struct Claims {
public_key: Vec<u8>,
custom: HashMap<String, Vec<u8>>,
}
impl Claims {
pub fn from_custom_claims(mut claims: HashMap<String, Vec<u8>>) -> Result<Self> {
let public_key = claims
.remove("pk")
.ok_or_else(|| Error::AttestationDataError {
reason: "pk field is missing from the claims".to_string(),
})?;
Ok(Self {
public_key,
custom: claims,
})
}
pub fn from_public_key(public_key: Vec<u8>) -> Result<Self> {
Ok(Self {
public_key,
custom: HashMap::default(),
})
}
}

View File

@ -6,6 +6,7 @@
pub mod cds2;
pub mod client_connection;
pub mod dcap;
pub mod enclave;
pub mod hsm_enclave;
pub mod ias;
pub mod nitro;

View File

@ -2,6 +2,9 @@
// Copyright 2023 Signal Messenger, LLC.
// SPDX-License-Identifier: AGPL-3.0-only
//
use std::collections::HashMap;
use std::time::SystemTime;
use boring::bn::BigNum;
use boring::ecdsa::EcdsaSig;
use boring::stack;
@ -9,10 +12,11 @@ use boring::x509::store::X509StoreBuilder;
use boring::x509::{X509StoreContext, X509};
use ciborium::value::{Integer, Value};
use sha2::{Digest, Sha384};
use std::collections::HashMap;
use std::time::SystemTime;
use subtle::ConstantTimeEq;
use crate::enclave;
use crate::enclave::{Claims, Handshake};
pub const PUBLIC_KEY_LENGTH: usize = 32;
pub type PublicKeyBytes = [u8; PUBLIC_KEY_LENGTH];
@ -27,6 +31,20 @@ pub fn attest(
doc.extract_public_key(expected_pcrs)
}
impl Handshake {
#[allow(unused)]
pub(crate) fn for_nitro(
evidence: &[u8],
expected_pcrs: &HashMap<usize, Vec<u8>>,
now: SystemTime,
) -> Result<Self, enclave::Error> {
let cose_sign1 = CoseSign1::from_bytes(evidence)?;
let doc = cose_sign1.extract_attestation_doc(now)?;
let public_key_material = doc.extract_public_key(expected_pcrs)?;
Self::with_claims(Claims::from_public_key(public_key_material.to_vec())?)
}
}
#[derive(Debug, displaydoc::Display, PartialEq, Eq)]
pub enum NitroError {
/// Invalid CBOR
@ -366,10 +384,12 @@ impl AttestationDoc {
#[cfg(test)]
mod test {
use super::*;
use hex_literal::hex;
use std::time::Duration;
use hex_literal::hex;
use super::*;
#[test]
fn test_extract_attestation_doc() {
let timestamp = SystemTime::UNIX_EPOCH + Duration::from_secs(1684362463);

View File

@ -10,94 +10,21 @@
//! [Handshake] to construct a noise encrypted session with the enclave. The attestation
//! must contain a custom claim with the key name "pk" that represents the enclave's
//! public key.
use std::collections::HashMap;
use std::time::Duration;
use displaydoc::Display;
use crate::dcap::MREnclave;
use crate::{client_connection, dcap, snow_resolver};
/// Error types for an SGX session.
#[derive(Display, Debug)]
pub enum Error {
/// failure to attest remote SGX enclave: {0:?}
DcapError(dcap::AttestationError),
/// failure to communicate on established Noise channel to SGX service: {0}
NoiseError(client_connection::Error),
/// failure to complete Noise handshake to SGX service: {0}
NoiseHandshakeError(snow::Error),
/// attestation data invalid: {reason}
AttestationDataError { reason: String },
/// invalid bridge state
InvalidBridgeStateError,
}
use crate::dcap::{self, MREnclave};
use crate::enclave::{Claims, Error, Handshake, Result};
const INVALID_EVIDENCE: &str = "Evidence does not fit expected format";
const INVALID_ENDORSEMENT: &str = "Endorsement does not fit expected format";
const INVALID_MRENCLAVE: &str = "MREnclave value does not fit expected format";
const INVALID_CLAIMS: &str = "Claims do not fit expected format";
pub type Result<T> = std::result::Result<T, Error>;
impl From<snow::Error> for Error {
fn from(e: snow::Error) -> Self {
Error::NoiseHandshakeError(e)
}
}
impl From<dcap::AttestationError> for Error {
fn from(err: dcap::AttestationError) -> Error {
Error::DcapError(err)
}
}
impl From<client_connection::Error> for Error {
fn from(err: client_connection::Error) -> Self {
Error::NoiseError(err)
}
}
impl From<prost::DecodeError> for Error {
fn from(err: prost::DecodeError) -> Self {
Error::AttestationDataError {
reason: err.to_string(),
}
}
}
/// A noise handshaker that can be used to build a [client_connection::ClientConnection]
///
/// Callers provide an attestation that must contain the remote enclave's public key. If the
/// attestation is valid, this public key will be used to generate a noise NK handshake (with
/// the caller acting as the initiator) via [Handshake::initial_request]. When
/// a handshake response is received the handshake can be completed with
/// [Handshake::complete] to build a [client_connection::ClientConnection] that
/// can be used to exchange arbitrary encrypted payloads with the remote enclave.
///
/// ```pseudocode
/// let websocket = ... open websocket ...
/// let attestation_msg = websocket.recv();
/// let (evidence, endoresments) = parse(attestation_msg);
/// let mut handshake = Handshake::new(
/// mrenclave, evidence, endorsements, acceptable_sw_advisories, current_time)?;
/// websocket.send(handshaker.initial_request());
/// let initial_response = websocket.recv(...);
/// let conn = handshaker.complete(initial_response);
/// ```
pub struct Handshake {
handshake: snow::HandshakeState,
initial_request: Vec<u8>,
claims: HashMap<String, Vec<u8>>,
}
/// How much to offset when checking for time-based validity checks
/// to adjust for clock skew on clients
const SKEW_ADJUSTMENT: Duration = Duration::from_secs(24 * 60 * 60);
impl Handshake {
pub(crate) fn new(
pub(crate) fn for_sgx(
mrenclave: &[u8],
evidence: &[u8],
endorsements: &[u8],
@ -131,48 +58,7 @@ impl Handshake {
current_time + SKEW_ADJUSTMENT,
)?;
let unwrapped_public_key = claims.get("pk").ok_or(Error::AttestationDataError {
reason: String::from(INVALID_CLAIMS),
})?;
let mut handshake = snow::Builder::with_resolver(
client_connection::NOISE_PATTERN.parse().expect("valid"),
Box::new(snow_resolver::Resolver),
)
.remote_public_key(unwrapped_public_key)
.build_initiator()?;
let mut initial_request = vec![0u8; client_connection::NOISE_HANDSHAKE_OVERHEAD];
// We send an empty message, but the roundtrip to the server and back is still required
// in order to complete the noise handshake. If we needed some initial payload we could
// add it here in future.
let size = handshake.write_message(&[], &mut initial_request)?;
initial_request.truncate(size);
Ok(Self {
handshake,
initial_request,
claims,
})
}
/// Initial message from client for noise handshake.
pub fn initial_request(&self) -> &[u8] {
&self.initial_request
}
/// custom claims extracted from the attestation
pub fn custom_claims(&self) -> &HashMap<String, Vec<u8>> {
&self.claims
}
/// Completes client connection initiation, returns a valid client connection.
pub fn complete(
mut self,
initial_received: &[u8],
) -> Result<client_connection::ClientConnection> {
self.handshake.read_message(initial_received, &mut [])?;
let transport = self.handshake.into_transport_mode()?;
log::info!("Successfully completed attested connection");
Ok(client_connection::ClientConnection { transport })
Self::with_claims(Claims::from_custom_claims(claims)?)
}
}
@ -209,7 +95,7 @@ pub mod testutil {
// Read test data files, de-hex-stringing as necessary.
let mrenclave_bytes = mrenclave_bytes();
let current_time = SystemTime::UNIX_EPOCH + Duration::from_millis(1655857680000);
Handshake::new(
Handshake::for_sgx(
&mrenclave_bytes,
EVIDENCE_BYTES,
ENDORSEMENT_BYTES,
@ -223,6 +109,8 @@ pub mod testutil {
mod tests {
use std::time::{Duration, SystemTime};
use crate::client_connection;
use super::*;
#[test]
@ -230,7 +118,7 @@ mod tests {
let mrenclave_bytes = testutil::mrenclave_bytes();
let test = |time: SystemTime, expect_success: bool| {
let result = Handshake::new(
let result = Handshake::for_sgx(
&mrenclave_bytes,
testutil::EVIDENCE_BYTES,
testutil::ENDORSEMENT_BYTES,

View File

@ -8,9 +8,8 @@ use hex_literal::hex;
use prost::Message;
use crate::dcap::MREnclave;
use crate::enclave::{Error, Handshake, Result};
use crate::proto::svr2;
use crate::sgx_session;
use crate::sgx_session::{Error, Result};
use crate::util::SmallMap;
/// Map from MREnclave to intel SW advisories that are known to be mitigated in the
@ -97,14 +96,6 @@ static EXPECTED_RAFT_CONFIG: SmallMap<MREnclave, &'static RaftConfig, 4> = Small
),
]);
pub struct Svr2Handshake {
/// The attested handshake that can be used to establish a noise connection
pub handshake: sgx_session::Handshake,
/// The group_id of the SVR2 raft group we are handshaking with
pub group_id: u64,
}
/// Lookup the group id constant associated with the `mrenclave`
pub fn lookup_groupid(mrenclave: &[u8]) -> Option<u64> {
EXPECTED_RAFT_CONFIG
@ -116,7 +107,7 @@ pub fn new_handshake(
mrenclave: &[u8],
attestation_msg: &[u8],
current_time: std::time::SystemTime,
) -> Result<sgx_session::Handshake> {
) -> Result<Handshake> {
new_handshake_with_constants(
mrenclave,
attestation_msg,
@ -138,10 +129,10 @@ fn new_handshake_with_constants(
current_time: std::time::SystemTime,
acceptable_sw_advisories: &[&str],
expected_raft_config: &RaftConfig,
) -> Result<sgx_session::Handshake> {
) -> Result<Handshake> {
// Deserialize attestation handshake start.
let handshake_start = svr2::ClientHandshakeStart::decode(attestation_msg)?;
let handshake = sgx_session::Handshake::new(
let handshake = Handshake::for_sgx(
mrenclave,
&handshake_start.evidence,
&handshake_start.endorsement,

View File

@ -3,8 +3,8 @@
// SPDX-License-Identifier: AGPL-3.0-only
//
use attest::enclave::Error as SgxError;
use attest::hsm_enclave::Error as HsmEnclaveError;
use attest::sgx_session::Error as SgxError;
use device_transfer::Error as DeviceTransferError;
use libsignal_bridge::ffi::*;
use libsignal_protocol::*;
@ -163,7 +163,7 @@ impl From<&SignalFfiError> for SignalErrorCode {
| SignalFfiError::Signal(SignalProtocolError::InvalidSealedSenderMessage(_))
| SignalFfiError::Signal(SignalProtocolError::BadKEMCiphertextLength(_, _))
| SignalFfiError::SignalCrypto(SignalCryptoError::InvalidTag)
| SignalFfiError::Sgx(SgxError::DcapError(_))
| SignalFfiError::Sgx(SgxError::AttestationError(_))
| SignalFfiError::Sgx(SgxError::NoiseError(_))
| SignalFfiError::Sgx(SgxError::NoiseHandshakeError(_))
| SignalFfiError::HsmEnclave(HsmEnclaveError::HSMHandshakeError(_))

View File

@ -7,7 +7,7 @@
use std::collections::HashMap;
use ::attest::cds2;
use ::attest::sgx_session::Result;
use ::attest::enclave::Result;
use libsignal_bridge_macros::*;
use crate::protocol::Timestamp;

View File

@ -6,8 +6,8 @@
use std::fmt;
use std::io::{Error as IoError, ErrorKind as IoErrorKind};
use attest::enclave::Error as SgxError;
use attest::hsm_enclave::Error as HsmEnclaveError;
use attest::sgx_session::Error as SgxError;
use device_transfer::Error as DeviceTransferError;
use libsignal_protocol::*;
use signal_crypto::Error as SignalCryptoError;

View File

@ -6,8 +6,8 @@
use jni::objects::{GlobalRef, JThrowable, JValue, JValueOwned};
use jni::JavaVM;
use attest::enclave::Error as SgxError;
use attest::hsm_enclave::Error as HsmEnclaveError;
use attest::sgx_session::Error as SgxError;
use device_transfer::Error as DeviceTransferError;
use libsignal_protocol::*;
use signal_crypto::Error as SignalCryptoError;
@ -364,7 +364,7 @@ where
| SignalJniError::Sgx(SgxError::NoiseError(_)) => {
jni_class_name!(org.signal.libsignal.attest.SgxCommunicationFailureException)
}
SignalJniError::Sgx(SgxError::DcapError(_)) => {
SignalJniError::Sgx(SgxError::AttestationError(_)) => {
jni_class_name!(org.signal.libsignal.attest.DcapException)
}
SignalJniError::Sgx(SgxError::AttestationDataError { .. }) => {

View File

@ -190,7 +190,7 @@ impl SignalNodeError for device_transfer::Error {}
impl SignalNodeError for attest::hsm_enclave::Error {}
impl SignalNodeError for attest::sgx_session::Error {}
impl SignalNodeError for attest::enclave::Error {}
impl SignalNodeError for signal_crypto::Error {}

View File

@ -5,18 +5,18 @@
use std::panic::RefUnwindSafe;
use ::attest::{client_connection, sgx_session};
use ::attest::enclave::Result;
use ::attest::{client_connection, enclave};
use libsignal_bridge_macros::*;
use crate::support::*;
use crate::*;
use ::attest::sgx_session::Result;
// It's okay to have a large enum because this type will be boxed for bridging after it's been
// created.
#[allow(clippy::large_enum_variant)]
pub enum SgxClientState {
ConnectionEstablishment(sgx_session::Handshake),
ConnectionEstablishment(enclave::Handshake),
Connection(client_connection::ClientConnection),
InvalidConnectionState,
}
@ -24,14 +24,14 @@ pub enum SgxClientState {
impl RefUnwindSafe for SgxClientState {}
impl SgxClientState {
pub fn new(handshake: sgx_session::Handshake) -> Result<Self> {
pub fn new(handshake: enclave::Handshake) -> Result<Self> {
Ok(SgxClientState::ConnectionEstablishment(handshake))
}
pub fn initial_request(&self) -> Result<&[u8]> {
match self {
SgxClientState::ConnectionEstablishment(c) => Ok(c.initial_request()),
_ => Err(sgx_session::Error::InvalidBridgeStateError),
_ => Err(enclave::Error::InvalidBridgeStateError),
}
}
@ -41,7 +41,7 @@ impl SgxClientState {
*self = SgxClientState::Connection(c.complete(initial_received)?);
Ok(())
}
_ => Err(sgx_session::Error::InvalidBridgeStateError),
_ => Err(enclave::Error::InvalidBridgeStateError),
}
}
@ -49,9 +49,9 @@ impl SgxClientState {
match self {
SgxClientState::Connection(c) => match c.send(plaintext_to_send) {
Ok(v) => Ok(v),
Err(e) => Err(sgx_session::Error::NoiseError(e)),
Err(e) => Err(enclave::Error::NoiseError(e)),
},
_ => Err(sgx_session::Error::InvalidBridgeStateError),
_ => Err(enclave::Error::InvalidBridgeStateError),
}
}
@ -59,9 +59,9 @@ impl SgxClientState {
match self {
SgxClientState::Connection(c) => match c.recv(received_ciphertext) {
Ok(v) => Ok(v),
Err(e) => Err(sgx_session::Error::NoiseError(e)),
Err(e) => Err(enclave::Error::NoiseError(e)),
},
_ => Err(sgx_session::Error::InvalidBridgeStateError),
_ => Err(enclave::Error::InvalidBridgeStateError),
}
}
}

View File

@ -3,7 +3,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
//
use ::attest::sgx_session::Result;
use ::attest::enclave::Result;
use ::attest::svr2;
use libsignal_bridge_macros::*;

View File

@ -20,13 +20,12 @@ use tungstenite::handshake::client::generate_key;
use tungstenite::protocol::CloseFrame;
use tungstenite::{http, Message};
use attest::client_connection::ClientConnection;
use attest::sgx_session::Handshake;
use crate::infra::errors::NetError;
use crate::infra::reconnect::{ServiceConnector, ServiceStatus};
use crate::infra::{AsyncDuplexStream, ConnectionParams, TransportConnector};
use crate::utils::timeout;
use attest::client_connection::ClientConnection;
use attest::enclave;
pub mod error;
pub use error::Error;
@ -344,12 +343,12 @@ impl<S: AsyncDuplexStream> WebSocketClient<S> {
pub enum AttestedConnectionError {
Protocol,
ClientConnection(attest::client_connection::Error),
Sgx(attest::sgx_session::Error),
Sgx(attest::enclave::Error),
Net(NetError),
}
impl From<attest::sgx_session::Error> for AttestedConnectionError {
fn from(value: attest::sgx_session::Error) -> Self {
impl From<enclave::Error> for AttestedConnectionError {
fn from(value: attest::enclave::Error) -> Self {
Self::Sgx(value)
}
}
@ -396,7 +395,7 @@ where
/// Connect to remote host and verify remote attestation.
pub(crate) async fn connect(
mut websocket: WebSocketClient<S>,
new_handshake: impl FnOnce(&[u8]) -> Result<Handshake, attest::sgx_session::Error>,
new_handshake: impl FnOnce(&[u8]) -> enclave::Result<enclave::Handshake>,
) -> Result<Self, AttestedConnectionError> {
let client_connection = authenticate(&mut websocket, new_handshake).await?;
@ -456,7 +455,7 @@ impl TextOrBinary {
async fn authenticate<S: AsyncDuplexStream>(
websocket: &mut WebSocketClient<S>,
new_handshake: impl FnOnce(&[u8]) -> Result<Handshake, attest::sgx_session::Error>,
new_handshake: impl FnOnce(&[u8]) -> enclave::Result<enclave::Handshake>,
) -> Result<ClientConnection, AttestedConnectionError> {
let attestation_msg = websocket
.receive()
@ -680,10 +679,8 @@ mod test {
attest::sgx_session::testutil::private_key(),
));
fn fail_to_handshake(
_attestation: &[u8],
) -> attest::sgx_session::Result<attest::sgx_session::Handshake> {
Err(attest::sgx_session::Error::AttestationDataError {
fn fail_to_handshake(_attestation: &[u8]) -> attest::enclave::Result<enclave::Handshake> {
Err(attest::enclave::Error::AttestationDataError {
reason: "invalid".to_string(),
})
}