-
Notifications
You must be signed in to change notification settings - Fork 114
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug: 341242090 Change-Id: I65fd086e8a9c2631e54bf8d7b34b5e703b58c0f1
- Loading branch information
Showing
6 changed files
with
266 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// | ||
// Copyright 2024 The Project Oak Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
|
||
use oak_proto_rust::oak::{ | ||
attestation::v1::{AttestationResults, Endorsements, Evidence}, | ||
session::v1::EndorsedEvidence, | ||
}; | ||
|
||
pub trait Attester { | ||
fn get_endorsed_evidence(&self) -> anyhow::Result<EndorsedEvidence>; | ||
} | ||
|
||
pub trait AttestationVerifier { | ||
fn verify( | ||
&self, | ||
evidence: &Evidence, | ||
endorsements: &Endorsements, | ||
) -> anyhow::Result<AttestationResults>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// | ||
// Copyright 2024 The Project Oak Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
|
||
use crate::attestation::{AttestationVerifier, Attester}; | ||
|
||
#[derive(Default)] | ||
pub struct SessionConfig<'a> { | ||
self_attester: Option<&'a dyn Attester>, | ||
peer_verifier: Option<&'a dyn AttestationVerifier>, | ||
} | ||
|
||
impl<'a> SessionConfig<'a> { | ||
pub fn builder() -> SessionConfigBuilder<'a> { | ||
SessionConfigBuilder::default() | ||
} | ||
} | ||
|
||
#[derive(Default)] | ||
pub struct SessionConfigBuilder<'a> { | ||
config: SessionConfig<'a>, | ||
} | ||
|
||
impl<'a> SessionConfigBuilder<'a> { | ||
pub fn set_self_attester(mut self, self_attester: &'a dyn Attester) -> Self { | ||
if self.config.self_attester.is_none() { | ||
self.config.self_attester = Some(self_attester); | ||
} else { | ||
panic!("self attester has already been set"); | ||
} | ||
self | ||
} | ||
|
||
pub fn set_peer_verifier(mut self, peer_verifier: &'a dyn AttestationVerifier) -> Self { | ||
if self.config.peer_verifier.is_none() { | ||
self.config.peer_verifier = Some(peer_verifier); | ||
} else { | ||
panic!("peer verifier has already been set"); | ||
} | ||
self | ||
} | ||
|
||
pub fn build(self) -> SessionConfig<'a> { | ||
self.config | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// | ||
// Copyright 2024 The Project Oak Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
|
||
//! This module provides an SDK for creating secure attested sessions between | ||
//! two parties. | ||
use alloc::vec::Vec; | ||
|
||
use oak_proto_rust::oak::session::v1::{SessionRequest, SessionResponse}; | ||
|
||
use crate::{config::SessionConfig, ProtocolEngine}; | ||
|
||
/// Trait that represents an end-to-end encrypted bidirectional streaming | ||
/// session between two peers. | ||
/// | ||
/// If one of the methods returns an error, it means that there was a protocol | ||
/// error and the session needs to be restarted (because the state-machine is in | ||
/// an incorrect state). | ||
pub trait Session { | ||
/// Checks whether session is ready to send and receive encrypted messages. | ||
/// Session becomes ready once remote attestation and crypto handshake have | ||
/// been successfully finished. | ||
fn is_open(&self) -> bool; | ||
|
||
/// Encrypts `plaintext` and send it to the peer. | ||
/// | ||
/// This function can be called multiple times in a row, which will result | ||
/// in multiple outgoing protocol messages being created. | ||
fn write(&mut self, plaintext: &[u8]) -> anyhow::Result<()>; | ||
|
||
/// Reads an encrypted message from the peer and decrypt it. | ||
/// | ||
/// This function can be called multiple times in a row, if the peer sent | ||
/// multiple protocol messages that need to be decrypted. | ||
/// | ||
/// Method returns `Result<Option<()>>` with the corresponding outcomes: | ||
/// - `Ok(None)`: Nothing to read | ||
/// - `Ok(Some(Vec<u8>))`: Successfully read plaintext bytes | ||
/// - `Err`: Protocol error | ||
fn read(&mut self) -> anyhow::Result<Option<Vec<u8>>>; | ||
} | ||
|
||
// Client-side secure attested session entrypoint. | ||
#[allow(dead_code)] | ||
pub struct ClientSession<'a> { | ||
config: &'a SessionConfig<'a>, | ||
} | ||
|
||
#[allow(dead_code)] | ||
impl<'a> ClientSession<'a> { | ||
pub fn new(config: &'a SessionConfig<'a>) -> Self { | ||
Self { config } | ||
} | ||
} | ||
|
||
impl<'a> Session for ClientSession<'a> { | ||
fn is_open(&self) -> bool { | ||
core::unimplemented!(); | ||
} | ||
|
||
fn write(&mut self, _plaintext: &[u8]) -> anyhow::Result<()> { | ||
core::unimplemented!(); | ||
} | ||
|
||
fn read(&mut self) -> anyhow::Result<Option<Vec<u8>>> { | ||
core::unimplemented!(); | ||
} | ||
} | ||
|
||
impl<'a> ProtocolEngine<SessionResponse, SessionRequest> for ClientSession<'a> { | ||
fn get_outgoing_message(&mut self) -> anyhow::Result<Option<SessionRequest>> { | ||
core::unimplemented!(); | ||
} | ||
|
||
fn put_incoming_message( | ||
&mut self, | ||
_incoming_message: &SessionResponse, | ||
) -> anyhow::Result<Option<()>> { | ||
core::unimplemented!(); | ||
} | ||
} | ||
|
||
// Server-side secure attested session entrypoint. | ||
#[allow(dead_code)] | ||
pub struct ServerSession<'a> { | ||
config: &'a SessionConfig<'a>, | ||
} | ||
|
||
#[allow(dead_code)] | ||
impl<'a> ServerSession<'a> { | ||
pub fn new(config: &'a SessionConfig<'a>) -> Self { | ||
Self { config } | ||
} | ||
} | ||
|
||
impl<'a> Session for ServerSession<'a> { | ||
fn is_open(&self) -> bool { | ||
core::unimplemented!(); | ||
} | ||
|
||
fn write(&mut self, _plaintext: &[u8]) -> anyhow::Result<()> { | ||
core::unimplemented!(); | ||
} | ||
|
||
fn read(&mut self) -> anyhow::Result<Option<Vec<u8>>> { | ||
core::unimplemented!(); | ||
} | ||
} | ||
|
||
impl<'a> ProtocolEngine<SessionRequest, SessionResponse> for ClientSession<'a> { | ||
fn get_outgoing_message(&mut self) -> anyhow::Result<Option<SessionResponse>> { | ||
core::unimplemented!(); | ||
} | ||
|
||
fn put_incoming_message( | ||
&mut self, | ||
_incoming_message: &SessionRequest, | ||
) -> anyhow::Result<Option<()>> { | ||
core::unimplemented!(); | ||
} | ||
} |