#![no_std]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
)]
#![forbid(unsafe_code)]
#![warn(
clippy::mod_module_files,
clippy::unwrap_used,
missing_docs,
rust_2018_idioms,
unused_qualifications
)]
extern crate alloc;
use der::{
AnyRef, DecodeValue, Encode, EncodeValue, FixedTag, Length, Reader, Tag, TagNumber, Writer,
};
use spki::ObjectIdentifier;
pub mod negotiation;
pub type MechType = ObjectIdentifier;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct InitialContextToken<'a> {
pub this_mech: MechType,
pub inner_context_token: AnyRef<'a>,
}
impl<'a> FixedTag for InitialContextToken<'a> {
const TAG: Tag = Tag::Application {
constructed: true,
number: TagNumber::new(0),
};
}
impl<'a> DecodeValue<'a> for InitialContextToken<'a> {
fn decode_value<R: Reader<'a>>(reader: &mut R, _header: der::Header) -> der::Result<Self> {
Ok(Self {
this_mech: reader.decode()?,
inner_context_token: reader.decode()?,
})
}
}
impl<'a> EncodeValue for InitialContextToken<'a> {
fn value_len(&self) -> der::Result<Length> {
self.this_mech.encoded_len()? + self.inner_context_token.encoded_len()?
}
fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
self.this_mech.encode(writer)?;
self.inner_context_token.encode(writer)?;
Ok(())
}
}
pub type SubsequentContextToken<'a> = AnyRef<'a>;
pub type PerMsgToken<'a> = AnyRef<'a>;
pub type SealedMessage<'a> = AnyRef<'a>;
#[cfg(test)]
mod tests {
use hex_literal::hex;
use spki::ObjectIdentifier;
use super::*;
use der::Decode;
#[test]
fn initial_context_token() {
let gss_bytes = hex!("604806062b0601050502a03e303ca00e300c060a2b06010401823702020aa22a04284e544c4d535350000100000005028862000000000000000000000000000000000601b01d0000000f");
let inner_bytes = hex!("303ca00e300c060a2b06010401823702020aa22a04284e544c4d535350000100000005028862000000000000000000000000000000000601b01d0000000f");
let gss = InitialContextToken::from_der(&gss_bytes).unwrap();
assert_eq!(ObjectIdentifier::new_unwrap("1.3.6.1.5.5.2"), gss.this_mech);
assert_eq!(
AnyRef::new(
Tag::ContextSpecific {
constructed: true,
number: TagNumber::N0
},
&inner_bytes
)
.unwrap(),
gss.inner_context_token
);
let output = InitialContextToken {
this_mech: MechType::new_unwrap("1.3.6.1.5.5.2"),
inner_context_token: AnyRef::new(
Tag::ContextSpecific {
constructed: true,
number: TagNumber::N0,
},
&inner_bytes,
)
.unwrap(),
};
let output_bytes = output.to_der().unwrap();
assert_eq!(&gss_bytes[..], &output_bytes);
}
}