use serde::{Deserialize, Serialize};
use speedy::{Readable, Writable};
use ring::digest;
use crate::{
create_security_error_and_log,
security::{types::DataHolder, SecurityError, SecurityResult},
};
pub const GMCLASSID_SECURITY_AUTH_HANDSHAKE: &str = "dds.sec.auth";
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ValidationOutcome {
Ok,
PendingHandshakeRequest,
PendingHandshakeMessage,
OkFinalMessage,
}
pub type IdentityHandle = u32;
pub type HandshakeHandle = u32;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Sha256([u8; 32]);
impl Sha256 {
pub fn dummy() -> Self {
Sha256(<[u8; 32]>::default())
}
pub const fn len() -> usize {
32
}
pub fn hash(input: &[u8]) -> Self {
Sha256(
digest::digest(&digest::SHA256, input)
.as_ref()
.try_into()
.unwrap(),
)
}
}
static_assertions::const_assert!(Sha256::len() == digest::SHA256_OUTPUT_LEN);
impl AsRef<[u8]> for Sha256 {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl From<[u8; 32]> for Sha256 {
fn from(s: [u8; 32]) -> Sha256 {
Sha256(s)
}
}
impl From<Sha256> for [u8; 32] {
fn from(s: Sha256) -> [u8; 32] {
s.0
}
}
impl TryFrom<&[u8]> for Sha256 {
type Error = SecurityError;
fn try_from(v: &[u8]) -> SecurityResult<Sha256> {
v.try_into()
.map_err(|e| create_security_error_and_log!("Cannot read SHA-256 hash: {e:?}"))
.map(Sha256)
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct SharedSecret([u8; 32]);
impl SharedSecret {
pub fn dummy() -> Self {
SharedSecret(<[u8; 32]>::default())
}
}
impl AsRef<[u8]> for SharedSecret {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl From<[u8; 32]> for SharedSecret {
fn from(s: [u8; 32]) -> SharedSecret {
SharedSecret(s)
}
}
impl From<Sha256> for SharedSecret {
fn from(s: Sha256) -> SharedSecret {
SharedSecret(s.into())
}
}
impl From<SharedSecret> for [u8; 32] {
fn from(s: SharedSecret) -> [u8; 32] {
s.0
}
}
impl TryFrom<&[u8]> for SharedSecret {
type Error = SecurityError;
fn try_from(v: &[u8]) -> SecurityResult<SharedSecret> {
v.try_into()
.map_err(|e| create_security_error_and_log!("Cannot read SharedSecret: {e:?}"))
.map(SharedSecret)
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Challenge([u8; 32]);
impl Challenge {
pub fn dummy() -> Self {
Challenge(<[u8; 32]>::default())
}
}
impl AsRef<[u8]> for Challenge {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl From<[u8; 32]> for Challenge {
fn from(s: [u8; 32]) -> Challenge {
Challenge(s)
}
}
impl From<Challenge> for [u8; 32] {
fn from(s: Challenge) -> [u8; 32] {
s.0
}
}
impl TryFrom<&[u8]> for Challenge {
type Error = SecurityError;
fn try_from(v: &[u8]) -> SecurityResult<Challenge> {
v.try_into()
.map_err(|e| create_security_error_and_log!("Cannot read Challenge: {e:?}"))
.map(Challenge)
}
}
pub struct SharedSecretHandle {
pub shared_secret: SharedSecret,
pub challenge1: Challenge, pub challenge2: Challenge, }
#[derive(Debug, Clone, PartialEq, Eq, Readable, Writable)]
pub struct IdentityToken {
pub data_holder: DataHolder,
}
impl From<DataHolder> for IdentityToken {
fn from(value: DataHolder) -> Self {
Self { data_holder: value }
}
}
impl IdentityToken {
pub fn class_id(&self) -> String {
self.data_holder.class_id.clone()
}
pub fn dummy() -> Self {
Self {
data_holder: DataHolder::dummy(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Readable, Writable)]
pub struct IdentityStatusToken {
pub data_holder: DataHolder,
}
impl From<DataHolder> for IdentityStatusToken {
fn from(value: DataHolder) -> Self {
Self { data_holder: value }
}
}
impl IdentityStatusToken {
pub fn dummy() -> Self {
Self {
data_holder: DataHolder::dummy(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AuthRequestMessageToken {
pub data_holder: DataHolder,
}
impl From<DataHolder> for AuthRequestMessageToken {
fn from(value: DataHolder) -> Self {
Self { data_holder: value }
}
}
impl AuthRequestMessageToken {
pub fn dummy() -> Self {
Self {
data_holder: DataHolder::dummy(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct HandshakeMessageToken {
pub data_holder: DataHolder,
}
impl From<DataHolder> for HandshakeMessageToken {
fn from(value: DataHolder) -> Self {
Self { data_holder: value }
}
}
impl HandshakeMessageToken {
pub fn dummy() -> Self {
Self {
data_holder: DataHolder::dummy(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AuthenticatedPeerCredentialToken {
pub data_holder: DataHolder,
}
impl From<DataHolder> for AuthenticatedPeerCredentialToken {
fn from(value: DataHolder) -> Self {
Self { data_holder: value }
}
}
impl AuthenticatedPeerCredentialToken {
pub fn dummy() -> Self {
Self {
data_holder: DataHolder::dummy(),
}
}
}