Skip to main content

Session

Struct Session 

Source
pub struct Session<S> { /* private fields */ }
Expand description

Secure-channel session state.

The phantom parameter S tracks which step of the Annex D.4 handshake the session is in. Each transition consumes the old Session and yields a new one in the next state — calling methods out of order is therefore a compile error rather than a runtime fault.

stateDiagram-v2
    [*] --> Disconnected: Session::new(scbk)
    Disconnected --> Challenged: challenge(RND.A)
    Challenged --> Cryptogrammed: receive_ccrypt(ccrypt) ✔
    Challenged --> Disconnected: receive_ccrypt(ccrypt) ✘<br/>BadCryptogram
    Cryptogrammed --> Secure: confirm_rmac_i(mac) ✔
    Cryptogrammed --> Disconnected: confirm_rmac_i(mac) ✘<br/>BadCryptogram
    Secure --> Secure: mac() / verify()<br/>seal_data() / open_data()

All fields are zeroized when the session is dropped (regardless of which state it is in), so cancelled or panicking flows do not leave the SCBK or derived material in memory. Note that Clone is preserved for ergonomic fork-and-mirror flows: cloning duplicates the key material, and only the dropped clone is zeroized — the surviving clone still holds keys until it is dropped in turn.

Implementations§

Source§

impl Session<Disconnected>

Source

pub fn new(scbk: [u8; 16]) -> Self

Begin a new session, holding the SCBK we will use.

§Example
use osdp::secure::{SCBK_D, Session};
use osdp::secure::session::Disconnected;
let session = Session::<Disconnected>::new(SCBK_D);
// The next step is `session.challenge(rnd_a)` once we've sent osdp_CHLNG.
Source

pub fn challenge(self, rnd_a: [u8; 8]) -> Session<Challenged>

Move to Challenged by capturing the RND.A we are about to send.

Source§

impl Session<Challenged>

Source

pub fn receive_ccrypt( self, ccrypt: &CCrypt, ) -> Result<Session<Cryptogrammed>, (Session<Disconnected>, SecureSessionError)>

Verify the PD’s CCrypt and move to Cryptogrammed.

Source§

impl Session<Cryptogrammed>

Source

pub fn server_cryptogram(&self) -> [u8; 16]

Compute the server cryptogram to ship in osdp_SCRYPT.

Source

pub fn initial_rmac(&self) -> [u8; 16]

Initial R-MAC, computed from S-MAC1/S-MAC2 over the server cryptogram.

Source

pub fn confirm_rmac_i( self, their_rmac_i: &[u8; 16], ) -> Result<Session<Secure>, (Session<Disconnected>, SecureSessionError)>

PD echoed back our initial R-MAC; advance to fully Secure.

Source§

impl Session<Secure>

Source

pub fn mac(&mut self, bytes: &[u8]) -> [u8; 16]

Compute the MAC trailer for an outgoing packet body.

bytes is the SOM..end-of-DATA region (as per super::mac::cbc_mac).

Source

pub fn verify( &mut self, bytes: &[u8], wire_mac: &[u8; 4], ) -> Result<(), SecureSessionError>

Verify a received MAC against our locally-computed value.

Source

pub fn keys(&self) -> &SessionKeys

Borrow the derived session keys (for AES-CBC DATA encryption).

Source

pub fn last_other_mac(&self) -> &[u8; 16]

Last MAC the other end produced (used as encryption ICV per Annex D).

Source

pub fn seal_data(&self, data: &[u8]) -> Vec<u8>

Encrypt data for an SCS_17/SCS_18 payload using the current ICV (!last_other_mac). Returns the ciphertext (always padded to a 16-byte multiple).

§Spec: Annex D.5
Source

pub fn open_data(&self, ct: &[u8]) -> Result<Vec<u8>, SecureSessionError>

Decrypt a payload received in an SCS_17/SCS_18 packet, validating the 0x80 padding.

§Spec: Annex D.5

Trait Implementations§

Source§

impl<S: Clone> Clone for Session<S>

Source§

fn clone(&self) -> Session<S>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<S: Debug> Debug for Session<S>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<S> Drop for Session<S>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<S> Zeroize for Session<S>

Source§

fn zeroize(&mut self)

Zero out this object from memory using Rust intrinsics which ensure the zeroization operation is not “optimized away” by the compiler.

Auto Trait Implementations§

§

impl<S> Freeze for Session<S>

§

impl<S> RefUnwindSafe for Session<S>
where S: RefUnwindSafe,

§

impl<S> Send for Session<S>
where S: Send,

§

impl<S> Sync for Session<S>
where S: Sync,

§

impl<S> Unpin for Session<S>
where S: Unpin,

§

impl<S> UnsafeUnpin for Session<S>

§

impl<S> UnwindSafe for Session<S>
where S: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.