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:
parent
d394f30644
commit
c86c74c288
@ -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.
|
||||
|
@ -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
180
rust/attest/src/enclave.rs
Normal 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(),
|
||||
})
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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(_))
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 { .. }) => {
|
||||
|
@ -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 {}
|
||||
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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::*;
|
||||
|
||||
|
@ -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(),
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user