Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make session transcript more flexible #74

Merged
merged 3 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions src/definitions/device_signed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::definitions::{
};
use cose_rs::sign1::CoseSign1;
use serde::{Deserialize, Serialize};
use serde_cbor::Value as CborValue;
use serde_cbor::{Error as CborError, Value as CborValue};
use std::collections::BTreeMap;

#[derive(Clone, Debug, Deserialize, Serialize)]
Expand All @@ -28,22 +28,19 @@ pub enum DeviceAuth {
Mac { device_mac: CborValue },
}

pub type DeviceAuthenticationBytes = Tag24<DeviceAuthentication>;
pub type DeviceAuthenticationBytes<S> = Tag24<DeviceAuthentication<S>>;

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DeviceAuthentication(
pub struct DeviceAuthentication<S: SessionTranscript>(
&'static str,
pub SessionTranscript,
pub String,
pub DeviceNamespacesBytes,
// See https://github.com/serde-rs/serde/issues/1296.
#[serde(bound = "")] S,
String,
DeviceNamespacesBytes,
);

impl DeviceAuthentication {
pub fn new(
transcript: SessionTranscript,
doc_type: String,
namespaces_bytes: DeviceNamespacesBytes,
) -> Self {
impl<S: SessionTranscript> DeviceAuthentication<S> {
pub fn new(transcript: S, doc_type: String, namespaces_bytes: DeviceNamespacesBytes) -> Self {
Self(
"DeviceAuthentication",
transcript,
Expand All @@ -52,3 +49,9 @@ impl DeviceAuthentication {
)
}
}

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Unable to encode value as CBOR: {0}")]
UnableToEncode(CborError),
}
3 changes: 1 addition & 2 deletions src/definitions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ pub mod helpers;
pub mod issuer_signed;
pub mod mso;
pub mod namespaces;
pub mod oid4vp;
pub mod session;
pub mod traits;
pub mod validity_info;
Expand All @@ -22,5 +21,5 @@ pub use device_response::{DeviceResponse, Document};
pub use device_signed::{DeviceAuth, DeviceSigned};
pub use issuer_signed::{IssuerSigned, IssuerSignedItem};
pub use mso::{DigestAlgorithm, DigestId, DigestIds, Mso};
pub use session::{SessionData, SessionEstablishment, SessionTranscript};
pub use session::{SessionData, SessionEstablishment, SessionTranscript180135};
pub use validity_info::ValidityInfo;
42 changes: 0 additions & 42 deletions src/definitions/oid4vp.rs

This file was deleted.

14 changes: 9 additions & 5 deletions src/definitions/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use sha2::{Digest, Sha256};
pub type EReaderKey = CoseKey;
pub type EDeviceKey = CoseKey;
pub type DeviceEngagementBytes = Tag24<DeviceEngagement>;
pub type SessionTranscriptBytes = Tag24<SessionTranscript>;
pub type SessionTranscriptBytes = Tag24<SessionTranscript180135>;
pub type NfcHandover = (ByteStr, Option<ByteStr>);

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -78,13 +78,17 @@ impl TryFrom<u64> for Status {
}
}

pub trait SessionTranscript: Serialize + for<'a> Deserialize<'a> {}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionTranscript(
pub struct SessionTranscript180135(
pub DeviceEngagementBytes,
pub Tag24<EReaderKey>,
pub Handover,
);

impl SessionTranscript for SessionTranscript180135 {}

#[derive(Debug, Clone, thiserror::Error)]
pub enum Error {
#[error("Curve not supported for DH exchange")]
Expand Down Expand Up @@ -164,7 +168,7 @@ pub fn get_shared_secret(

pub fn derive_session_key(
shared_secret: &SharedSecret<NistP256>,
session_transcript: &Tag24<SessionTranscript>,
session_transcript: &SessionTranscriptBytes,
reader: bool,
) -> Result<GenericArray<u8, U32>> {
let salt = Sha256::digest(serde_cbor::to_vec(session_transcript)?);
Expand Down Expand Up @@ -400,7 +404,7 @@ mod test {
};

let device_engagement_bytes = Tag24::new(device_engagement).unwrap();
let session_transcript = Tag24::new(SessionTranscript(
let session_transcript = Tag24::new(SessionTranscript180135(
device_engagement_bytes,
reader_key_bytes,
Handover::QR,
Expand Down Expand Up @@ -456,7 +460,7 @@ mod test {
assert_eq!(shared_secret_hex, SHARED_SECRET);

let session_transcript_bytes = hex::decode(SESSION_TRANSCRIPT).unwrap();
let session_transcript: Tag24<SessionTranscript> =
let session_transcript: SessionTranscriptBytes =
serde_cbor::from_slice(&session_transcript_bytes).unwrap();

let session_key = derive_session_key(&shared_secret, &session_transcript, true).unwrap();
Expand Down
38 changes: 21 additions & 17 deletions src/presentation/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,22 @@ use crate::{
device_signed::{DeviceAuth, DeviceAuthentication, DeviceNamespacesBytes, DeviceSigned},
helpers::{tag24, NonEmptyMap, NonEmptyVec, Tag24},
issuer_signed::{IssuerSigned, IssuerSignedItemBytes},
session::{self, derive_session_key, get_shared_secret, Handover, SessionData},
CoseKey, DeviceEngagement, DeviceResponse, Mso, SessionEstablishment, SessionTranscript,
session::{
self, derive_session_key, get_shared_secret, Handover, SessionData, SessionTranscript,
},
CoseKey, DeviceEngagement, DeviceResponse, Mso, SessionEstablishment,
},
issuance::Mdoc,
};
use cose_rs::sign1::{CoseSign1, PreparedCoseSign1};
use p256::FieldBytes;
use serde::{Deserialize, Serialize};
use serde_cbor::Value as CborValue;
use session::SessionTranscript180135;
use std::collections::BTreeMap;
use std::num::ParseIntError;
use uuid::Uuid;

pub mod oid4vp;

#[derive(Serialize, Deserialize)]
pub struct SessionManagerInit {
documents: Documents,
Expand All @@ -43,7 +44,7 @@ pub struct SessionManagerEngaged {
#[derive(Serialize, Deserialize)]
pub struct SessionManager {
documents: Documents,
session_transcript: Tag24<SessionTranscript>,
session_transcript: SessionTranscript180135,
sk_device: [u8; 32],
device_message_counter: u32,
sk_reader: [u8; 32],
Expand Down Expand Up @@ -168,20 +169,19 @@ impl SessionManagerEngaged {
session_establishment: SessionEstablishment,
) -> anyhow::Result<(SessionManager, RequestedItems)> {
let e_reader_key = session_establishment.e_reader_key;
let session_transcript = Tag24::new(SessionTranscript(
self.device_engagement,
e_reader_key.clone(),
self.handover,
))
.map_err(Error::Tag24CborEncoding)?;
let session_transcript =
SessionTranscript180135(self.device_engagement, e_reader_key.clone(), self.handover);
let session_transcript_bytes =
Tag24::new(session_transcript.clone()).map_err(Error::Tag24CborEncoding)?;

let e_device_key = p256::SecretKey::from_bytes(FieldBytes::from_slice(&self.e_device_key))?;

let shared_secret = get_shared_secret(e_reader_key.into_inner(), &e_device_key.into())
.map_err(Error::SharedSecretGeneration)?;

let sk_reader = derive_session_key(&shared_secret, &session_transcript, true)?.into();
let sk_device = derive_session_key(&shared_secret, &session_transcript, false)?.into();
let sk_reader = derive_session_key(&shared_secret, &session_transcript_bytes, true)?.into();
let sk_device =
derive_session_key(&shared_secret, &session_transcript_bytes, false)?.into();

let mut sm = SessionManager {
documents: self.documents,
Expand Down Expand Up @@ -418,8 +418,10 @@ impl PreparedDocument {
}

pub trait DeviceSession {
type ST: SessionTranscript;

fn documents(&self) -> &Documents;
fn session_transcript(&self) -> &Tag24<SessionTranscript>;
fn session_transcript(&self) -> Self::ST;
fn prepare_response(
&self,
requests: &RequestedItems,
Expand Down Expand Up @@ -516,7 +518,7 @@ pub trait DeviceSession {
}
};
let device_auth = DeviceAuthentication::new(
self.session_transcript().as_ref().clone(),
self.session_transcript(),
doc_type.clone(),
device_namespaces.clone(),
);
Expand Down Expand Up @@ -579,12 +581,14 @@ pub trait DeviceSession {
}

impl DeviceSession for SessionManager {
type ST = SessionTranscript180135;

fn documents(&self) -> &Documents {
&self.documents
}

fn session_transcript(&self) -> &Tag24<SessionTranscript> {
&self.session_transcript
fn session_transcript(&self) -> SessionTranscript180135 {
self.session_transcript.clone()
}
}

Expand Down
Loading
Loading